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 std::unique_ptr< QgsProviderSublayerModelGroup > 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 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.