29#include <QDesktopServices> 
   40  if ( !
index.isValid() )
 
   43  QgsProviderSublayerModelNode *node = index2node( 
index );
 
   47  if ( QgsProviderSublayerModelSublayerNode *sublayerNode = 
dynamic_cast<QgsProviderSublayerModelSublayerNode *
>( node ) )
 
   59            return tr( 
"Scanning…" );
 
   90  if ( !
index.isValid() )
 
  103      return Qt::ItemFlags();
 
  111  mGeometryTypesResolved = resolved;
 
  116  : QDialog( parent, fl )
 
  121  const QFileInfo fileInfo( filePathIn );
 
  122  const QString filePath = ( fileInfo.isFile() || fileInfo.isDir() ) && fileInfo.exists() ? filePathIn : QString();
 
  125  if ( !fileName.isEmpty() )
 
  130  setWindowTitle( fileName.isEmpty() ? tr( 
"Select Items to Add" ) : QStringLiteral( 
"%1 | %2" ).arg( tr( 
"Select Items to Add" ), fileName ) );
 
  132  mLblFilePath->setText( QStringLiteral( 
"<a href=\"%1\">%2</a>" )
 
  133                         .arg( QUrl::fromLocalFile( filePath ).toString(), QDir::toNativeSeparators( QFileInfo( filePath ).canonicalFilePath() ) ) );
 
  134  mLblFilePath->setVisible( !filePath.isEmpty() );
 
  135  mLblFilePath->setWordWrap( 
true );
 
  136  mLblFilePath->setTextInteractionFlags( Qt::TextBrowserInteraction );
 
  137  connect( mLblFilePath, &QLabel::linkActivated, 
this, [ = ]( 
const QString & link )
 
  139    const QUrl url( link );
 
  140    const QFileInfo file( url.toLocalFile() );
 
  141    if ( file.exists() && !file.isDir() )
 
  144      QDesktopServices::openUrl( url );
 
  148  mModel->setSublayerDetails( initialDetails );
 
  150  mProxyModel->setSourceModel( mModel );
 
  151  mLayersTree->setModel( mProxyModel );
 
  153  mLayersTree->expandAll();
 
  156  const bool addToGroup = settings.
value( QStringLiteral( 
"/qgis/openSublayersInGroup" ), 
false ).toBool();
 
  157  mCbxAddToGroup->setChecked( addToGroup );
 
  158  mCbxAddToGroup->setVisible( !fileName.isEmpty() );
 
  161  const QByteArray ba = settings.
value( 
"/Windows/SubLayers/headerState" ).toByteArray();
 
  164    mLayersTree->header()->restoreState( ba );
 
  168    for ( 
int i = 0; i < mModel->columnCount(); i++ )
 
  169      mLayersTree->resizeColumnToContents( i );
 
  170    mLayersTree->setColumnWidth( 1, mLayersTree->columnWidth( 1 ) + 10 );
 
  179      QList< QgsProviderSublayerDetails > res = mTask->results();
 
  180      res.erase( std::remove_if( res.begin(), res.end(), [acceptableTypes]( const QgsProviderSublayerDetails & sublayer )
 
  182        return !acceptableTypes.empty() && !acceptableTypes.contains( sublayer.type() );
 
  185      mModel->setSublayerDetails( res );
 
  186      mModel->setGeometryTypesResolved( 
true );
 
  188      mLayersTree->expandAll();
 
  194  connect( mBtnSelectAll, &QAbstractButton::pressed, 
this, &QgsProviderSublayersDialog::selectAll );
 
  195  connect( mBtnDeselectAll, &QAbstractButton::pressed, 
this, [ = ] { mLayersTree->selectionModel()->clear(); } );
 
  196  connect( mLayersTree->selectionModel(), &QItemSelectionModel::selectionChanged, 
this, &QgsProviderSublayersDialog::treeSelectionChanged );
 
  200  connect( mLayersTree, &QTreeView::doubleClicked, 
this, [ = ]( 
const QModelIndex & index )
 
  202    const QModelIndex left = mLayersTree->model()->index( index.row(), 0, index.parent() );
 
  203    if ( !( left.flags() & Qt::ItemIsSelectable ) )
 
  206    mLayersTree->selectionModel()->select( QItemSelection( left,
 
  207                                           mLayersTree->model()->index( index.row(), mLayersTree->model()->columnCount() - 1, index.parent() ) ),
 
  208                                           QItemSelectionModel::ClearAndSelect );
 
  209    emit layersAdded( selectedLayers() );
 
  212  connect( mButtonBox, &QDialogButtonBox::rejected, 
this, &QDialog::reject );
 
  213  connect( mButtonBox, &QDialogButtonBox::accepted, 
this, [ = ]
 
  215    emit layersAdded( selectedLayers() );
 
  218  mButtonBox->button( QDialogButtonBox::Ok )->setEnabled( 
false );
 
  219  mButtonBox->button( QDialogButtonBox::Ok )->setText( tr( 
"Add Layers" ) );
 
  235  settings.
setValue( 
"/Windows/SubLayers/headerState", mLayersTree->header()->saveState() );
 
  236  settings.
setValue( QStringLiteral( 
"/qgis/openSublayersInGroup" ), mCbxAddToGroup->isChecked() );
 
  244  const QModelIndexList selection = mLayersTree->selectionModel()->selectedRows();
 
  245  QList< QgsProviderSublayerDetails > selectedSublayers;
 
  246  for ( 
const QModelIndex &index : selection )
 
  248    const QModelIndex sourceIndex = mProxyModel->mapToSource( index );
 
  254  return selectedSublayers;
 
  259  const QModelIndexList selection = mLayersTree->selectionModel()->selectedRows();
 
  260  QList< QgsProviderSublayerModel::NonLayerItem > selectedItems;
 
  261  for ( 
const QModelIndex &index : selection )
 
  263    const QModelIndex sourceIndex = mProxyModel->mapToSource( index );
 
  269  return selectedItems;
 
  274  mGroupName = groupNameIn;
 
  276  if ( settings.
value( QStringLiteral( 
"qgis/formatLayerName" ), 
false ).toBool() )
 
  281  mCbxAddToGroup->setVisible( !mGroupName.isEmpty() );
 
  286  if ( !mCbxAddToGroup->isChecked() )
 
  291void QgsProviderSublayersDialog::treeSelectionChanged( 
const QItemSelection &selected, 
const QItemSelection & )
 
  293  if ( mBlockSelectionChanges )
 
  296  mBlockSelectionChanges = 
true;
 
  297  bool selectedANonLayerItem = 
false;
 
  298  QModelIndex firstSelectedNonLayerItem;
 
  299  bool selectedALayerItem = 
false;
 
  300  for ( 
const QModelIndex &index : selected.indexes() )
 
  302    if ( index.column() != 0 )
 
  307      if ( !selectedANonLayerItem )
 
  309        selectedANonLayerItem = 
true;
 
  310        firstSelectedNonLayerItem = index;
 
  315        mLayersTree->selectionModel()->select( QItemSelection( mLayersTree->model()->index( index.row(), 0, index.parent() ),
 
  316                                               mLayersTree->model()->index( index.row(), mLayersTree->model()->columnCount() - 1, index.parent() ) ),
 
  317                                               QItemSelectionModel::Deselect );
 
  322      selectedALayerItem = 
true;
 
  326  for ( 
int row = 0; row < mProxyModel->rowCount(); ++row )
 
  328    const QModelIndex index = mProxyModel->index( row, 0 );
 
  331      if ( ( selectedANonLayerItem && index != firstSelectedNonLayerItem ) || selectedALayerItem )
 
  333        mLayersTree->selectionModel()->select( QItemSelection( mLayersTree->model()->index( index.row(), 0, index.parent() ),
 
  334                                               mLayersTree->model()->index( index.row(), mLayersTree->model()->columnCount() - 1, index.parent() ) ),
 
  335                                               QItemSelectionModel::Deselect );
 
  340      if ( selectedANonLayerItem )
 
  342        mLayersTree->selectionModel()->select( QItemSelection( mLayersTree->model()->index( index.row(), 0, index.parent() ),
 
  343                                               mLayersTree->model()->index( index.row(), mLayersTree->model()->columnCount() - 1, index.parent() ) ),
 
  344                                               QItemSelectionModel::Deselect );
 
  348  mBlockSelectionChanges = 
false;
 
  350  mButtonBox->button( QDialogButtonBox::Ok )->setEnabled( !mLayersTree->selectionModel()->selectedRows().empty() );
 
  352  mCbxAddToGroup->setEnabled( !selectedANonLayerItem );
 
  353  mButtonBox->button( QDialogButtonBox::Ok )->setText( selectedANonLayerItem ? tr( 
"Open" ) : tr( 
"Add Layers" ) );
 
  356void QgsProviderSublayersDialog::selectAll()
 
  358  mLayersTree->selectionModel()->clear();
 
  360  std::function< void( 
const QModelIndex & ) > selectAllInParent;
 
  362  selectAllInParent = [
this, &selectAllInParent]( 
const QModelIndex & parent )
 
  364    for ( 
int row = 0; row < mProxyModel->rowCount( parent ); ++row )
 
  366      const QModelIndex index = mProxyModel->index( row, 0, parent );
 
  369        mLayersTree->selectionModel()->select( QItemSelection( mLayersTree->model()->index( index.row(), 0, index.parent() ),
 
  370                                               mLayersTree->model()->index( index.row(), mLayersTree->model()->columnCount() - 1, index.parent() ) ),
 
  371                                               QItemSelectionModel::Select );
 
  373      selectAllInParent( index );
 
  376  selectAllInParent( QModelIndex() );
 
  378  mButtonBox->button( QDialogButtonBox::Ok )->setFocus();
 
@ SystemTable
Sublayer is a system or internal table, which should be hidden by default.
 
static QgsTaskManager * taskManager()
Returns the application's task manager, used for managing application wide background task handling.
 
static void enableAutoGeometryRestore(QWidget *widget, const QString &key=QString())
Register the widget to allow its position to be automatically saved and restored when open and closed...
 
static QgsNative * nativePlatformInterface()
Returns the global native interface, which offers abstraction to the host OS's underlying public inte...
 
static QString formatLayerName(const QString &name)
A convenience function to capitalize and format a layer name.
 
Contains details about a sub layer available from a dataset.
 
Qgis::LayerType type() const
Returns the layer type.
 
Qgis::WkbType wkbType() const
Returns the layer's WKB type, or QgsWkbTypes::Unknown if the WKB type is not application or unknown.
 
Qgis::SublayerFlags flags() const
Returns the layer's flags, which indicate properties of the layer.
 
A model for representing the sublayers present in a URI for the QgsProviderSublayersDialog.
 
QVariant data(const QModelIndex &index, int role) const override
 
QgsProviderSublayerDialogModel(QObject *parent=nullptr)
Constructor.
 
void setGeometryTypesResolved(bool resolved)
Sets whether geometry types are resolved.
 
Qt::ItemFlags flags(const QModelIndex &index) const override
 
Contains details for a non-sublayer item to include in a QgsProviderSublayerModel.
 
A model for representing the sublayers present in a URI.
 
QList< QgsProviderSublayerDetails > mSublayers
Sublayer list.
 
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
 
QVariant data(const QModelIndex &index, int role) const override
 
QgsProviderSublayerDetails indexToSublayer(const QModelIndex &index) const
Returns the sublayer corresponding to the given index.
 
@ IsNonLayerItem
true if item is a non-sublayer item (e.g. an embedded project)
 
QgsProviderSublayerModel::NonLayerItem indexToNonLayerItem(const QModelIndex &index) const
Returns the non layer item corresponding to the given index.
 
void addNonLayerItem(const QgsProviderSublayerModel::NonLayerItem &item)
Adds a non-layer item (e.g.
 
int columnCount(const QModelIndex &parent=QModelIndex()) const override
 
int rowCount(const QModelIndex &parent) const override
 
Qt::ItemFlags flags(const QModelIndex &index) const override
 
@ Description
Layer description.
 
A QSortFilterProxyModel for filtering and sorting a QgsProviderSublayerModel.
 
void setIncludeSystemTables(bool include)
Sets whether system and internal tables will be shown in the model.
 
void setFilterString(const QString &filter)
Sets the filter string used for filtering items in the model.
 
void setIncludeEmptyLayers(bool include)
Sets whether empty tables will be shown in the model.
 
A QgsTask which retrieves sublayer details for a URI.
 
void setGroupName(const QString &groupNameIn)
Sets an appropriate name for the layer group.
 
~QgsProviderSublayersDialog() override
 
QString groupName() const
Returns an appropriate name for the layer group.
 
void setNonLayerItems(const QList< QgsProviderSublayerModel::NonLayerItem > &items)
Set list of non-layer items (e.g.
 
QList< QgsProviderSublayerModel::NonLayerItem > selectedNonLayerItems() const
Returns the list of selected non-layer items (e.g.
 
QList< QgsProviderSublayerDetails > selectedLayers() const
Returns the list of selected layers.
 
QgsProviderSublayersDialog(const QString &uri, const QString &providerKey, const QString &filePath, const QList< QgsProviderSublayerDetails > initialDetails=QList< QgsProviderSublayerDetails >(), const QList< Qgis::LayerType > &acceptableTypes=QList< Qgis::LayerType >(), QWidget *parent SIP_TRANSFERTHIS=nullptr, Qt::WindowFlags fl=Qt::WindowFlags())
Constructor.
 
static bool sublayerDetailsAreIncomplete(const QList< QgsProviderSublayerDetails > &details, QgsProviderUtils::SublayerCompletenessFlags flags=QgsProviderUtils::SublayerCompletenessFlags())
Returns true if the sublayer details are incomplete, and require a more in-depth scan.
 
static QString suggestLayerNameFromFilePath(const QString &path)
Suggests a suitable layer name given only a file path.
 
This class is a composition of two QSettings instances:
 
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
 
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
 
long addTask(QgsTask *task, int priority=0)
Adds a task to the manager.
 
void taskCompleted()
Will be emitted by task to indicate its successful completion.