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 ) );
86int QgsProviderSublayerModelGroup::indexOf( QgsProviderSublayerModelNode *child )
const
88 Q_ASSERT( child->mParent ==
this );
89 auto it = std::find_if( mChildren.begin(), mChildren.end(), [&](
const std::unique_ptr<QgsProviderSublayerModelNode> &p )
91 return p.get() == child;
93 if ( it != mChildren.end() )
94 return std::distance( mChildren.begin(), it );
98QgsProviderSublayerModelNode *QgsProviderSublayerModelGroup::childAt(
int index )
100 if (
static_cast< std::size_t
>( index ) < mChildren.size() )
101 return mChildren[ index ].get();
106void QgsProviderSublayerModelGroup::removeChildAt(
int index )
108 mChildren.erase( mChildren.begin() + index );
111QgsProviderSublayerModelGroup *QgsProviderSublayerModelGroup::findGroup(
const QString &name )
const
113 for (
const auto &node : mChildren )
115 if ( QgsProviderSublayerModelGroup *group =
dynamic_cast< QgsProviderSublayerModelGroup *
>( node.get() ) )
117 if ( group->name() == name )
124QgsProviderSublayerModelGroup *QgsProviderSublayerModelGroup::findGroupForPath(
const QStringList &path )
const
126 const QgsProviderSublayerModelGroup *currentGroup =
this;
127 for (
const QString &part : path )
129 currentGroup = currentGroup->findGroup( part );
131 return const_cast< QgsProviderSublayerModelGroup *
>( currentGroup );
134QgsProviderSublayerModelSublayerNode *QgsProviderSublayerModelGroup::findSublayer(
const QgsProviderSublayerDetails &sublayer )
136 for (
const auto &node : mChildren )
138 if ( QgsProviderSublayerModelGroup *group =
dynamic_cast< QgsProviderSublayerModelGroup *
>( node.get() ) )
140 if ( QgsProviderSublayerModelSublayerNode *node = group->findSublayer( sublayer ) )
143 else if ( QgsProviderSublayerModelSublayerNode *sublayerNode =
dynamic_cast< QgsProviderSublayerModelSublayerNode *
>( node.get() ) )
145 if ( sublayerNode->sublayer() == sublayer )
152QVariant QgsProviderSublayerModelGroup::data(
int role,
int column )
const
156 case Qt::DisplayRole:
157 case Qt::ToolTipRole:
171 case Qt::DecorationRole:
185 : mSublayer( sublayer )
189QVariant QgsProviderSublayerModelSublayerNode::data(
int role,
int column )
const
193 case Qt::DisplayRole:
194 case Qt::ToolTipRole:
200 return mSublayer.name();
203 switch ( mSublayer.type() )
210 count = QObject::tr(
"Uncounted" );
212 count = QLocale().toString( mSublayer.featureCount() );
214 if ( !mSublayer.description().isEmpty() )
215 return QStringLiteral(
"%1 - %2 (%3)" ).arg( mSublayer.description(),
219 return QStringLiteral(
"%2 (%3)" ).arg(
232 return mSublayer.description();
238 return mSublayer.name();
242 case Qt::DecorationRole:
256 return mSublayer.providerKey();
259 return static_cast< int >( mSublayer.type() );
262 return mSublayer.uri();
265 return mSublayer.name();
268 return mSublayer.description();
271 return mSublayer.path();
274 return mSublayer.featureCount();
277 return static_cast< quint32>( mSublayer.wkbType() );
280 return mSublayer.geometryColumnName();
283 return mSublayer.layerNumber();
286 return static_cast< int >( mSublayer.flags() );
298QVariant QgsProviderSublayerModelNonLayerItemNode::data(
int role,
int column )
const
302 case Qt::DisplayRole:
303 case Qt::ToolTipRole:
311 return mItem.description();
316 case Qt::DecorationRole:
334 return mItem.description();
351 : QAbstractItemModel( parent )
352 , mRootNode( std::make_unique< QgsProviderSublayerModelGroup >( QString() ) )
363 mRootNode->populateFromSublayers( details );
372 for (
int i =
mSublayers.count() - 1; i >= 0; --i )
374 if ( !details.contains(
mSublayers.at( i ) ) )
376 QgsProviderSublayerModelSublayerNode *sublayerNode =
mRootNode->findSublayer(
mSublayers.at( i ) );
377 Q_ASSERT( sublayerNode );
378 Q_ASSERT( sublayerNode->parent() );
379 const int row = sublayerNode->parent()->indexOf( sublayerNode );
381 beginRemoveRows( node2index( sublayerNode->parent() ), row, row );
382 sublayerNode->parent()->removeChildAt( row );
394 QgsProviderSublayerModelGroup *group =
mRootNode->findGroupForPath( sublayer.
path() );
395 beginInsertRows( node2index( group ), group->childCount(), group->childCount() );
396 group->addChild( std::make_unique< QgsProviderSublayerModelSublayerNode >( sublayer ) );
411 if ( QgsProviderSublayerModelSublayerNode *n =
dynamic_cast< QgsProviderSublayerModelSublayerNode *
>( index2node(
index ) ) )
412 return n->sublayer();
419 if ( QgsProviderSublayerModelNonLayerItemNode *n =
dynamic_cast< QgsProviderSublayerModelNonLayerItemNode *
>( index2node(
index ) ) )
428 mRootNode->addChild( std::make_unique< QgsProviderSublayerModelNonLayerItemNode >( item ) );
438 return QModelIndex();
441 QgsProviderSublayerModelGroup *n =
dynamic_cast< QgsProviderSublayerModelGroup *
>( index2node(
parent ) );
443 return QModelIndex();
445 return createIndex( row, column, n->childAt( row ) );
450 if ( !child.isValid() )
451 return QModelIndex();
453 if ( QgsProviderSublayerModelNode *n = index2node( child ) )
455 return indexOfParentNode( n->parent() );
460 return QModelIndex();
472 QgsProviderSublayerModelNode *n = index2node(
parent );
476 return n->childCount();
481 if ( !
index.isValid() )
483 Qt::ItemFlags rootFlags = Qt::ItemFlags();
487 Qt::ItemFlags f = Qt::ItemIsEnabled;
490 if ( !
dynamic_cast< QgsProviderSublayerModelGroup *
>( index2node(
index ) ) )
492 f |= Qt::ItemIsSelectable;
499 if ( !
index.isValid() )
503 QgsProviderSublayerModelNode *node = index2node(
index );
507 return node->data( role,
index.column() );
512 switch ( orientation )
520 case Qt::DisplayRole:
521 case Qt::ToolTipRole:
523 switch (
static_cast< Column>( section ) )
528 return tr(
"Description" );
540QgsProviderSublayerModelNode *QgsProviderSublayerModel::index2node(
const QModelIndex &index )
const
542 if ( !
index.isValid() )
545 return reinterpret_cast<QgsProviderSublayerModelNode *
>(
index.internalPointer() );
548QModelIndex QgsProviderSublayerModel::indexOfParentNode( QgsProviderSublayerModelNode *parentNode )
const
550 Q_ASSERT( parentNode );
552 QgsProviderSublayerModelGroup *grandParentNode = parentNode->parent();
553 if ( !grandParentNode )
554 return QModelIndex();
556 int row = grandParentNode->indexOf( parentNode );
557 Q_ASSERT( row >= 0 );
559 return createIndex( row, 0, parentNode );
562QModelIndex QgsProviderSublayerModel::node2index( QgsProviderSublayerModelNode *node )
const
564 if ( !node || !node->parent() )
565 return QModelIndex();
567 QModelIndex parentIndex = node2index( node->parent() );
569 int row = node->parent()->indexOf( node );
570 Q_ASSERT( row >= 0 );
571 return index( row, 0, parentIndex );
606 mDescription = description;
631 return mType == other.mType
632 && mName == other.mName
633 && mDescription == other.mDescription
634 && mUri == other.mUri;
639 return !( *
this == other );
647 : QSortFilterProxyModel(
parent )
649 setRecursiveFilteringEnabled(
true );
650 setDynamicSortFilter(
true );
656 const QModelIndex sourceIndex = sourceModel()->index( source_row, 0, source_parent );
664 if ( mFilterString.trimmed().isEmpty() )
671 const QModelIndex descriptionColumnIndex = sourceModel()->index( source_row, 1, source_parent );
672 if ( sourceModel()->data( descriptionColumnIndex,
static_cast< int >( Qt::DisplayRole ) ).toString().contains( mFilterString, Qt::CaseInsensitive ) )
676 if ( wkbTypeVariant.isValid() )
691 if ( leftIsNonLayer && !rightIsNonLayer )
693 else if ( rightIsNonLayer && !leftIsNonLayer )
699 return QString::localeAwareCompare( leftName, rightName ) < 0;
704 return mIncludeSystemTables;
709 mIncludeSystemTables = include;
715 return mIncludeEmptyLayers;
720 mIncludeEmptyLayers = include;
726 return mFilterString;
731 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.