29QgsProviderSublayerModelNode::~QgsProviderSublayerModelNode() =
default;
31void QgsProviderSublayerModelGroup::populateFromSublayers(
const QList<QgsProviderSublayerDetails> &sublayers )
35 if ( !sublayer.path().isEmpty() )
37 QStringList currentPath;
38 QStringList remainingPaths = sublayer.path();
39 QgsProviderSublayerModelGroup *groupNode =
this;
41 while ( !remainingPaths.empty() )
43 currentPath << remainingPaths.takeAt( 0 );
45 QgsProviderSublayerModelGroup *nextChild = groupNode->findGroup( currentPath.constLast() );
48 std::unique_ptr< QgsProviderSublayerModelGroup > newNode = std::make_unique< QgsProviderSublayerModelGroup >( currentPath.constLast() );
49 groupNode = qgis::down_cast< QgsProviderSublayerModelGroup * >( groupNode->addChild( std::move( newNode ) ) );
53 groupNode = nextChild;
57 groupNode->addChild( std::make_unique< QgsProviderSublayerModelSublayerNode >( sublayer ) );
61 addChild( std::make_unique< QgsProviderSublayerModelSublayerNode >( sublayer ) );
66QgsProviderSublayerModelGroup::QgsProviderSublayerModelGroup(
const QString &title )
67 : mGroupTitle( title )
72QgsProviderSublayerModelNode *QgsProviderSublayerModelGroup::addChild( std::unique_ptr<QgsProviderSublayerModelNode> child )
77 Q_ASSERT( !child->mParent );
78 child->mParent =
this;
80 QgsProviderSublayerModelNode *res = child.get();
81 mChildren.emplace_back( std::move( child ) );
85int QgsProviderSublayerModelGroup::indexOf( QgsProviderSublayerModelNode *child )
const
87 Q_ASSERT( child->mParent ==
this );
88 auto it = std::find_if( mChildren.begin(), mChildren.end(), [&](
const std::unique_ptr<QgsProviderSublayerModelNode> &p )
90 return p.get() == child;
92 if ( it != mChildren.end() )
93 return std::distance( mChildren.begin(), it );
97QgsProviderSublayerModelNode *QgsProviderSublayerModelGroup::childAt(
int index )
99 if (
static_cast< std::size_t
>( index ) < mChildren.size() )
100 return mChildren[ index ].get();
105void QgsProviderSublayerModelGroup::removeChildAt(
int index )
107 mChildren.erase( mChildren.begin() + index );
110QgsProviderSublayerModelGroup *QgsProviderSublayerModelGroup::findGroup(
const QString &name )
const
112 for (
const auto &node : mChildren )
114 if ( QgsProviderSublayerModelGroup *group =
dynamic_cast< QgsProviderSublayerModelGroup *
>( node.get() ) )
116 if ( group->name() == name )
123QgsProviderSublayerModelGroup *QgsProviderSublayerModelGroup::findGroupForPath(
const QStringList &path )
const
125 const QgsProviderSublayerModelGroup *currentGroup =
this;
126 for (
const QString &part : path )
128 currentGroup = currentGroup->findGroup( part );
130 return const_cast< QgsProviderSublayerModelGroup *
>( currentGroup );
133QgsProviderSublayerModelSublayerNode *QgsProviderSublayerModelGroup::findSublayer(
const QgsProviderSublayerDetails &sublayer )
135 for (
const auto &node : mChildren )
137 if ( QgsProviderSublayerModelGroup *group =
dynamic_cast< QgsProviderSublayerModelGroup *
>( node.get() ) )
139 if ( QgsProviderSublayerModelSublayerNode *node = group->findSublayer( sublayer ) )
142 else if ( QgsProviderSublayerModelSublayerNode *sublayerNode =
dynamic_cast< QgsProviderSublayerModelSublayerNode *
>( node.get() ) )
144 if ( sublayerNode->sublayer() == sublayer )
151QVariant QgsProviderSublayerModelGroup::data(
int role,
int column )
const
155 case Qt::DisplayRole:
156 case Qt::ToolTipRole:
170 case Qt::DecorationRole:
184 : mSublayer( sublayer )
188QVariant QgsProviderSublayerModelSublayerNode::data(
int role,
int column )
const
192 case Qt::DisplayRole:
193 case Qt::ToolTipRole:
199 return mSublayer.name();
202 switch ( mSublayer.type() )
209 count = QObject::tr(
"Uncounted" );
211 count = QLocale().toString( mSublayer.featureCount() );
213 if ( !mSublayer.description().isEmpty() )
214 return QStringLiteral(
"%1 - %2 (%3)" ).arg( mSublayer.description(),
218 return QStringLiteral(
"%2 (%3)" ).arg(
231 return mSublayer.description();
237 return mSublayer.name();
241 case Qt::DecorationRole:
255 return mSublayer.providerKey();
258 return static_cast< int >( mSublayer.type() );
261 return mSublayer.uri();
264 return mSublayer.name();
267 return mSublayer.description();
270 return mSublayer.path();
273 return mSublayer.featureCount();
276 return static_cast< quint32>( mSublayer.wkbType() );
279 return mSublayer.geometryColumnName();
282 return mSublayer.layerNumber();
285 return static_cast< int >( mSublayer.flags() );
297QVariant QgsProviderSublayerModelNonLayerItemNode::data(
int role,
int column )
const
301 case Qt::DisplayRole:
302 case Qt::ToolTipRole:
310 return mItem.description();
315 case Qt::DecorationRole:
333 return mItem.description();
350 : QAbstractItemModel( parent )
351 , mRootNode( std::make_unique< QgsProviderSublayerModelGroup >( QString() ) )
362 mRootNode->populateFromSublayers( details );
371 for (
int i =
mSublayers.count() - 1; i >= 0; --i )
373 if ( !details.contains(
mSublayers.at( i ) ) )
375 QgsProviderSublayerModelSublayerNode *sublayerNode =
mRootNode->findSublayer(
mSublayers.at( i ) );
376 Q_ASSERT( sublayerNode );
377 Q_ASSERT( sublayerNode->parent() );
378 const int row = sublayerNode->parent()->indexOf( sublayerNode );
380 beginRemoveRows( node2index( sublayerNode->parent() ), row, row );
381 sublayerNode->parent()->removeChildAt( row );
393 QgsProviderSublayerModelGroup *group =
mRootNode->findGroupForPath( sublayer.
path() );
394 beginInsertRows( node2index( group ), group->childCount(), group->childCount() );
395 group->addChild( std::make_unique< QgsProviderSublayerModelSublayerNode >( sublayer ) );
410 if ( QgsProviderSublayerModelSublayerNode *n =
dynamic_cast< QgsProviderSublayerModelSublayerNode *
>( index2node(
index ) ) )
411 return n->sublayer();
418 if ( QgsProviderSublayerModelNonLayerItemNode *n =
dynamic_cast< QgsProviderSublayerModelNonLayerItemNode *
>( index2node(
index ) ) )
427 mRootNode->addChild( std::make_unique< QgsProviderSublayerModelNonLayerItemNode >( item ) );
437 return QModelIndex();
440 QgsProviderSublayerModelGroup *n =
dynamic_cast< QgsProviderSublayerModelGroup *
>( index2node(
parent ) );
442 return QModelIndex();
444 return createIndex( row, column, n->childAt( row ) );
449 if ( !child.isValid() )
450 return QModelIndex();
452 if ( QgsProviderSublayerModelNode *n = index2node( child ) )
454 return indexOfParentNode( n->parent() );
459 return QModelIndex();
471 QgsProviderSublayerModelNode *n = index2node(
parent );
475 return n->childCount();
480 if ( !
index.isValid() )
482 Qt::ItemFlags rootFlags = Qt::ItemFlags();
486 Qt::ItemFlags f = Qt::ItemIsEnabled;
489 if ( !
dynamic_cast< QgsProviderSublayerModelGroup *
>( index2node(
index ) ) )
491 f |= Qt::ItemIsSelectable;
498 if ( !
index.isValid() )
502 QgsProviderSublayerModelNode *node = index2node(
index );
506 return node->data( role,
index.column() );
511 switch ( orientation )
519 case Qt::DisplayRole:
520 case Qt::ToolTipRole:
522 switch (
static_cast< Column>( section ) )
527 return tr(
"Description" );
539QgsProviderSublayerModelNode *QgsProviderSublayerModel::index2node(
const QModelIndex &index )
const
541 if ( !
index.isValid() )
544 return reinterpret_cast<QgsProviderSublayerModelNode *
>(
index.internalPointer() );
547QModelIndex QgsProviderSublayerModel::indexOfParentNode( QgsProviderSublayerModelNode *parentNode )
const
549 Q_ASSERT( parentNode );
551 QgsProviderSublayerModelGroup *grandParentNode = parentNode->parent();
552 if ( !grandParentNode )
553 return QModelIndex();
555 int row = grandParentNode->indexOf( parentNode );
556 Q_ASSERT( row >= 0 );
558 return createIndex( row, 0, parentNode );
561QModelIndex QgsProviderSublayerModel::node2index( QgsProviderSublayerModelNode *node )
const
563 if ( !node || !node->parent() )
564 return QModelIndex();
566 QModelIndex parentIndex = node2index( node->parent() );
568 int row = node->parent()->indexOf( node );
569 Q_ASSERT( row >= 0 );
570 return index( row, 0, parentIndex );
605 mDescription = description;
630 return mType == other.mType
631 && mName == other.mName
632 && mDescription == other.mDescription
633 && mUri == other.mUri;
638 return !( *
this == other );
646 : QSortFilterProxyModel(
parent )
648 setRecursiveFilteringEnabled(
true );
649 setDynamicSortFilter(
true );
655 const QModelIndex sourceIndex = sourceModel()->index( source_row, 0, source_parent );
663 if ( mFilterString.trimmed().isEmpty() )
670 const QModelIndex descriptionColumnIndex = sourceModel()->index( source_row, 1, source_parent );
671 if ( sourceModel()->data( descriptionColumnIndex,
static_cast< int >( Qt::DisplayRole ) ).toString().contains( mFilterString, Qt::CaseInsensitive ) )
675 if ( wkbTypeVariant.isValid() )
690 if ( leftIsNonLayer && !rightIsNonLayer )
692 else if ( rightIsNonLayer && !leftIsNonLayer )
698 return QString::localeAwareCompare( leftName, rightName ) < 0;
703 return mIncludeSystemTables;
708 mIncludeSystemTables = include;
714 return mIncludeEmptyLayers;
719 mIncludeEmptyLayers = include;
725 return mFilterString;
730 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 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.