19#include "moc_qgsprovidersublayermodel.cpp" 
   30QgsProviderSublayerModelNode::~QgsProviderSublayerModelNode() = 
default;
 
   32void QgsProviderSublayerModelGroup::populateFromSublayers( 
const QList<QgsProviderSublayerDetails> &sublayers )
 
   36    if ( !sublayer.path().isEmpty() )
 
   38      QStringList currentPath;
 
   39      QStringList remainingPaths = sublayer.path();
 
   40      QgsProviderSublayerModelGroup *groupNode = 
this;
 
   42      while ( !remainingPaths.empty() )
 
   44        currentPath << remainingPaths.takeAt( 0 );
 
   46        QgsProviderSublayerModelGroup *nextChild = groupNode->findGroup( currentPath.constLast() );
 
   49          auto newNode = std::make_unique< QgsProviderSublayerModelGroup >( currentPath.constLast() );
 
   50          groupNode = qgis::down_cast< QgsProviderSublayerModelGroup * >( groupNode->addChild( std::move( newNode ) ) );
 
   54          groupNode = nextChild;
 
   58      groupNode->addChild( std::make_unique< QgsProviderSublayerModelSublayerNode >( sublayer ) );
 
   62      addChild( std::make_unique< QgsProviderSublayerModelSublayerNode >( sublayer ) );
 
   67QgsProviderSublayerModelGroup::QgsProviderSublayerModelGroup( 
const QString &title )
 
   68  : mGroupTitle( title )
 
   73QgsProviderSublayerModelNode *QgsProviderSublayerModelGroup::addChild( std::unique_ptr<QgsProviderSublayerModelNode> child )
 
   78  Q_ASSERT( !child->mParent );
 
   79  child->mParent = 
this;
 
   81  QgsProviderSublayerModelNode *res = child.get();
 
   82  mChildren.emplace_back( std::move( child ) );
 
   87int QgsProviderSublayerModelGroup::indexOf( QgsProviderSublayerModelNode *child )
 const 
   89  Q_ASSERT( child->mParent == 
this );
 
   90  auto it = std::find_if( mChildren.begin(), mChildren.end(), [&]( 
const std::unique_ptr<QgsProviderSublayerModelNode> &p )
 
   92    return p.get() == child;
 
   94  if ( it != mChildren.end() )
 
   95    return std::distance( mChildren.begin(), it );
 
   99QgsProviderSublayerModelNode *QgsProviderSublayerModelGroup::childAt( 
int index )
 
  101  if ( 
static_cast< std::size_t 
>( index ) < mChildren.size() )
 
  102    return mChildren[ index ].get();
 
  107void QgsProviderSublayerModelGroup::removeChildAt( 
int index )
 
  109  mChildren.erase( mChildren.begin() + index );
 
  112QgsProviderSublayerModelGroup *QgsProviderSublayerModelGroup::findGroup( 
const QString &name )
 const 
  114  for ( 
const auto &node : mChildren )
 
  116    if ( QgsProviderSublayerModelGroup *group = 
dynamic_cast< QgsProviderSublayerModelGroup * 
>( node.get() ) )
 
  118      if ( group->name() == name )
 
  125QgsProviderSublayerModelGroup *QgsProviderSublayerModelGroup::findGroupForPath( 
const QStringList &path )
 const 
  127  const QgsProviderSublayerModelGroup *currentGroup = 
this;
 
  128  for ( 
const QString &part : path )
 
  130    currentGroup = currentGroup->findGroup( part );
 
  132  return const_cast< QgsProviderSublayerModelGroup * 
>( currentGroup );
 
  135QgsProviderSublayerModelSublayerNode *QgsProviderSublayerModelGroup::findSublayer( 
const QgsProviderSublayerDetails &sublayer )
 
  137  for ( 
const auto &node : mChildren )
 
  139    if ( QgsProviderSublayerModelGroup *group = 
dynamic_cast< QgsProviderSublayerModelGroup * 
>( node.get() ) )
 
  141      if ( QgsProviderSublayerModelSublayerNode *node = group->findSublayer( sublayer ) )
 
  144    else if ( QgsProviderSublayerModelSublayerNode *sublayerNode = 
dynamic_cast< QgsProviderSublayerModelSublayerNode * 
>( node.get() ) )
 
  146      if ( sublayerNode->sublayer() == sublayer )
 
  153QVariant QgsProviderSublayerModelGroup::data( 
int role, 
int column )
 const 
  157    case Qt::DisplayRole:
 
  158    case Qt::ToolTipRole:
 
  172    case Qt::DecorationRole:
 
  186  : mSublayer( sublayer )
 
  190QVariant QgsProviderSublayerModelSublayerNode::data( 
int role, 
int column )
 const 
  194    case Qt::DisplayRole:
 
  195    case Qt::ToolTipRole:
 
  201          return mSublayer.name();
 
  204          switch ( mSublayer.type() )
 
  211                count = QObject::tr( 
"Uncounted" );
 
  213                count = QLocale().toString( mSublayer.featureCount() );
 
  215              if ( !mSublayer.description().isEmpty() )
 
  216                return QStringLiteral( 
"%1 - %2 (%3)" ).arg( mSublayer.description(),
 
  220                return QStringLiteral( 
"%2 (%3)" ).arg(
 
  233              return mSublayer.description();
 
  239      return mSublayer.name();
 
  243    case Qt::DecorationRole:
 
  257      return mSublayer.providerKey();
 
  260      return static_cast< int >( mSublayer.type() );
 
  263      return mSublayer.uri();
 
  266      return mSublayer.name();
 
  269      return mSublayer.description();
 
  272      return mSublayer.path();
 
  275      return mSublayer.featureCount();
 
  278      return static_cast< quint32>( mSublayer.wkbType() );
 
  281      return mSublayer.geometryColumnName();
 
  284      return mSublayer.layerNumber();
 
  287      return static_cast< int >( mSublayer.flags() );
 
  299QVariant QgsProviderSublayerModelNonLayerItemNode::data( 
int role, 
int column )
 const 
  303    case Qt::DisplayRole:
 
  304    case Qt::ToolTipRole:
 
  312          return mItem.description();
 
  317    case Qt::DecorationRole:
 
  335      return mItem.description();
 
  352  : QAbstractItemModel( parent )
 
  353  , mRootNode( std::make_unique< QgsProviderSublayerModelGroup >( QString() ) )
 
 
  364    mRootNode->populateFromSublayers( details );
 
  373    for ( 
int i = 
mSublayers.count() - 1; i >= 0; --i )
 
  375      if ( !details.contains( 
mSublayers.at( i ) ) )
 
  377        QgsProviderSublayerModelSublayerNode *sublayerNode = 
mRootNode->findSublayer( 
mSublayers.at( i ) );
 
  378        Q_ASSERT( sublayerNode );
 
  379        Q_ASSERT( sublayerNode->parent() );
 
  380        const int row = sublayerNode->parent()->indexOf( sublayerNode );
 
  382        beginRemoveRows( node2index( sublayerNode->parent() ), row, row );
 
  383        sublayerNode->parent()->removeChildAt( row );
 
  395        QgsProviderSublayerModelGroup *group = 
mRootNode->findGroupForPath( sublayer.
path() );
 
  396        beginInsertRows( node2index( group ), group->childCount(), group->childCount() );
 
  397        group->addChild( std::make_unique< QgsProviderSublayerModelSublayerNode >( sublayer ) );
 
 
  412  if ( QgsProviderSublayerModelSublayerNode *n = 
dynamic_cast< QgsProviderSublayerModelSublayerNode *
>( index2node( 
index ) ) )
 
  413    return n->sublayer();
 
 
  420  if ( QgsProviderSublayerModelNonLayerItemNode *n = 
dynamic_cast< QgsProviderSublayerModelNonLayerItemNode *
>( index2node( 
index ) ) )
 
 
  429  mRootNode->addChild( std::make_unique< QgsProviderSublayerModelNonLayerItemNode >( item ) );
 
 
  439    return QModelIndex();
 
  442  QgsProviderSublayerModelGroup *n = 
dynamic_cast< QgsProviderSublayerModelGroup *
>( index2node( 
parent ) );
 
  444    return QModelIndex(); 
 
  446  return createIndex( row, column, n->childAt( row ) );
 
 
  451  if ( !child.isValid() )
 
  452    return QModelIndex();
 
  454  if ( QgsProviderSublayerModelNode *n = index2node( child ) )
 
  456    return indexOfParentNode( n->parent() ); 
 
  461    return QModelIndex();
 
 
  473  QgsProviderSublayerModelNode *n = index2node( 
parent );
 
  477  return n->childCount();
 
 
  482  if ( !
index.isValid() )
 
  484    Qt::ItemFlags rootFlags = Qt::ItemFlags();
 
  488  Qt::ItemFlags f = Qt::ItemIsEnabled;
 
  491  if ( !
dynamic_cast< QgsProviderSublayerModelGroup * 
>( index2node( 
index ) ) )
 
  493    f |= Qt::ItemIsSelectable;
 
 
  500  if ( !
index.isValid() )
 
  504  QgsProviderSublayerModelNode *node = index2node( 
index );
 
  508  return node->data( role, 
index.column() );
 
 
  513  switch ( orientation )
 
  521        case Qt::DisplayRole:
 
  522        case Qt::ToolTipRole:
 
  524          switch ( 
static_cast< Column>( section ) )
 
  529              return tr( 
"Description" );
 
 
  541QgsProviderSublayerModelNode *QgsProviderSublayerModel::index2node( 
const QModelIndex &index )
 const 
  543  if ( !
index.isValid() )
 
  546  return reinterpret_cast<QgsProviderSublayerModelNode *
>( 
index.internalPointer() );
 
  549QModelIndex QgsProviderSublayerModel::indexOfParentNode( QgsProviderSublayerModelNode *parentNode )
 const 
  551  Q_ASSERT( parentNode );
 
  553  QgsProviderSublayerModelGroup *grandParentNode = parentNode->parent();
 
  554  if ( !grandParentNode )
 
  555    return QModelIndex();  
 
  557  int row = grandParentNode->indexOf( parentNode );
 
  558  Q_ASSERT( row >= 0 );
 
  560  return createIndex( row, 0, parentNode );
 
  563QModelIndex QgsProviderSublayerModel::node2index( QgsProviderSublayerModelNode *node )
 const 
  565  if ( !node || !node->parent() )
 
  566    return QModelIndex(); 
 
  568  QModelIndex parentIndex = node2index( node->parent() );
 
  570  int row = node->parent()->indexOf( node );
 
  571  Q_ASSERT( row >= 0 );
 
  572  return index( row, 0, parentIndex );
 
  607  mDescription = description;
 
 
  632  return mType == other.mType
 
  633         && mName == other.mName
 
  634         && mDescription == other.mDescription
 
  635         && mUri == other.mUri;
 
 
  640  return !( *
this == other );
 
 
  648  : QSortFilterProxyModel( 
parent )
 
  650  setRecursiveFilteringEnabled( 
true );
 
  651  setDynamicSortFilter( 
true );
 
 
  657  const QModelIndex sourceIndex = sourceModel()->index( source_row, 0, source_parent );
 
  665  if ( mFilterString.trimmed().isEmpty() )
 
  672  const QModelIndex descriptionColumnIndex = sourceModel()->index( source_row, 1, source_parent );
 
  673  if ( sourceModel()->data( descriptionColumnIndex, 
static_cast< int >( Qt::DisplayRole ) ).toString().contains( mFilterString, Qt::CaseInsensitive ) )
 
  677  if ( wkbTypeVariant.isValid() )
 
 
  692  if ( leftIsNonLayer && !rightIsNonLayer )
 
  694  else if ( rightIsNonLayer && !leftIsNonLayer )
 
  700  return QString::localeAwareCompare( leftName, rightName ) < 0;
 
 
  705  return mIncludeSystemTables;
 
 
  710  mIncludeSystemTables = include;
 
 
  716  return mIncludeEmptyLayers;
 
 
  721  mIncludeEmptyLayers = include;
 
 
  727  return mFilterString;
 
 
  732  mFilterString = filter;
 
 
@ SystemTable
Sublayer is a system or internal table, which should be hidden by default.
 
QFlags< SublayerFlag > SublayerFlags
Sublayer flags.
 
@ Group
Composite group layer. Added in QGIS 3.24.
 
@ Plugin
Plugin based layer.
 
@ TiledScene
Tiled scene layer. Added in QGIS 3.34.
 
@ Annotation
Contains freeform, georeferenced annotations. Added in QGIS 3.16.
 
@ VectorTile
Vector tile layer. Added in QGIS 3.14.
 
@ Mesh
Mesh layer. Added in QGIS 3.2.
 
@ PointCloud
Point cloud layer. Added in QGIS 3.18.
 
WkbType
The WKB type describes the number of dimensions a geometry has.
 
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
 
Contains utility functions for working with icons.
 
static QIcon iconForWkbType(Qgis::WkbType type)
Returns the icon for a vector layer whose geometry type is provided.
 
Contains details about a sub layer available from a dataset.
 
QStringList path() const
Returns the path to the sublayer.
 
Contains details for a non-sublayer item to include in a QgsProviderSublayerModel.
 
void setName(const QString &name)
Sets the item's name.
 
void setDescription(const QString &description)
Sets the item's description.
 
void setType(const QString &type)
Sets the item's type.
 
QString type() const
Returns the item's type.
 
QString uri() const
Returns the item's URI.
 
QString name() const
Returns the item's name.
 
QIcon icon() const
Returns the item's icon.
 
bool operator!=(const QgsProviderSublayerModel::NonLayerItem &other) const
 
void setUri(const QString &uri)
Set the item's uri.
 
bool operator==(const QgsProviderSublayerModel::NonLayerItem &other) const
 
QString description() const
Returns the item's description.
 
void setIcon(const QIcon &icon)
Sets the item's icon.
 
QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const override
 
QList< QgsProviderSublayerDetails > mSublayers
Sublayer list.
 
QList< QgsProviderSublayerDetails > sublayerDetails() const
Returns the sublayer details shown in the model.
 
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
 
QVariant data(const QModelIndex &index, int role) const override
 
QgsProviderSublayerModel(QObject *parent=nullptr)
Constructor for QgsProviderSublayerModel, with the specified parent object.
 
QgsProviderSublayerDetails indexToSublayer(const QModelIndex &index) const
Returns the sublayer corresponding to the given index.
 
std::unique_ptr< QgsProviderSublayerModelGroup > mRootNode
 
@ NonLayerItemType
Item type (for non-sublayer items)
 
@ IsNonLayerItem
true if item is a non-sublayer item (e.g. an embedded project)
 
@ FeatureCount
Feature count (for vector sublayers)
 
@ GeometryColumnName
Geometry column name (for vector sublayers)
 
@ Description
Layer description.
 
@ WkbType
WKB geometry type (for vector sublayers)
 
@ ProviderKey
Provider key.
 
@ LayerNumber
Layer number.
 
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.
 
void setSublayerDetails(const QList< QgsProviderSublayerDetails > &details)
Sets the sublayer details to show in the model.
 
QModelIndex parent(const QModelIndex &index) const override
 
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.
 
bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const override
 
bool includeSystemTables() const
Returns true if system and internal tables will be shown in the model.
 
void setIncludeSystemTables(bool include)
Sets whether system and internal tables will be shown in the model.
 
QgsProviderSublayerProxyModel(QObject *parent=nullptr)
Constructor for QgsProviderSublayerProxyModel, with the specified parent object.
 
QString filterString() const
Returns the filter string used for filtering items in the model.
 
bool includeEmptyLayers() const
Returns true if empty tables will be shown in the model.
 
void setFilterString(const QString &filter)
Sets the filter string used for filtering items in the model.
 
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override
 
void setIncludeEmptyLayers(bool include)
Sets whether empty tables will be shown in the model.
 
static Q_INVOKABLE QString displayString(Qgis::WkbType type)
Returns a non-translated display string type for a WKB type, e.g., the geometry name used in WKT geom...
 
@ Uncounted
Feature count not yet computed.
 
@ UnknownCount
Provider returned an unknown feature count.