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() )
204 case Qgis::LayerType::Vector:
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(
223 case Qgis::LayerType::Raster:
224 case Qgis::LayerType::Plugin:
225 case Qgis::LayerType::Mesh:
226 case Qgis::LayerType::VectorTile:
227 case Qgis::LayerType::Annotation:
228 case Qgis::LayerType::PointCloud:
229 case Qgis::LayerType::Group:
230 return mSublayer.description();
236 return mSublayer.name();
240 case Qt::DecorationRole:
243 return mSublayer.type() == Qgis::LayerType::Vector
254 return mSublayer.providerKey();
257 return static_cast< int >( mSublayer.type() );
260 return mSublayer.uri();
263 return mSublayer.name();
266 return mSublayer.description();
269 return mSublayer.path();
272 return mSublayer.featureCount();
275 return static_cast< quint32
>( mSublayer.wkbType() );
278 return mSublayer.geometryColumnName();
281 return mSublayer.layerNumber();
284 return static_cast< int >( mSublayer.flags() );
296QVariant QgsProviderSublayerModelNonLayerItemNode::data(
int role,
int column )
const
300 case Qt::DisplayRole:
301 case Qt::ToolTipRole:
309 return mItem.description();
314 case Qt::DecorationRole:
332 return mItem.description();
349 : QAbstractItemModel( parent )
350 , mRootNode( std::make_unique< QgsProviderSublayerModelGroup >( QString() ) )
361 mRootNode->populateFromSublayers( details );
370 for (
int i =
mSublayers.count() - 1; i >= 0; --i )
372 if ( !details.contains(
mSublayers.at( i ) ) )
374 QgsProviderSublayerModelSublayerNode *sublayerNode =
mRootNode->findSublayer(
mSublayers.at( i ) );
375 Q_ASSERT( sublayerNode );
376 Q_ASSERT( sublayerNode->parent() );
377 const int row = sublayerNode->parent()->indexOf( sublayerNode );
379 beginRemoveRows( node2index( sublayerNode->parent() ), row, row );
380 sublayerNode->parent()->removeChildAt( row );
392 QgsProviderSublayerModelGroup *group =
mRootNode->findGroupForPath( sublayer.
path() );
393 beginInsertRows( node2index( group ), group->childCount(), group->childCount() );
394 group->addChild( std::make_unique< QgsProviderSublayerModelSublayerNode >( sublayer ) );
409 if ( QgsProviderSublayerModelSublayerNode *n =
dynamic_cast< QgsProviderSublayerModelSublayerNode *
>( index2node(
index ) ) )
410 return n->sublayer();
417 if ( QgsProviderSublayerModelNonLayerItemNode *n =
dynamic_cast< QgsProviderSublayerModelNonLayerItemNode *
>( index2node(
index ) ) )
426 mRootNode->addChild( std::make_unique< QgsProviderSublayerModelNonLayerItemNode >( item ) );
436 return QModelIndex();
439 QgsProviderSublayerModelGroup *n =
dynamic_cast< QgsProviderSublayerModelGroup *
>( index2node(
parent ) );
441 return QModelIndex();
443 return createIndex( row, column, n->childAt( row ) );
448 if ( !child.isValid() )
449 return QModelIndex();
451 if ( QgsProviderSublayerModelNode *n = index2node( child ) )
453 return indexOfParentNode( n->parent() );
458 return QModelIndex();
470 QgsProviderSublayerModelNode *n = index2node(
parent );
474 return n->childCount();
479 if ( !
index.isValid() )
481 Qt::ItemFlags rootFlags = Qt::ItemFlags();
485 Qt::ItemFlags f = Qt::ItemIsEnabled;
488 if ( !
dynamic_cast< QgsProviderSublayerModelGroup *
>( index2node(
index ) ) )
490 f |= Qt::ItemIsSelectable;
497 if ( !
index.isValid() )
501 QgsProviderSublayerModelNode *node = index2node(
index );
505 return node->data( role,
index.column() );
510 switch ( orientation )
518 case Qt::DisplayRole:
519 case Qt::ToolTipRole:
521 switch (
static_cast< Column>( section ) )
526 return tr(
"Description" );
538QgsProviderSublayerModelNode *QgsProviderSublayerModel::index2node(
const QModelIndex &index )
const
540 if ( !
index.isValid() )
543 return reinterpret_cast<QgsProviderSublayerModelNode *
>(
index.internalPointer() );
546QModelIndex QgsProviderSublayerModel::indexOfParentNode( QgsProviderSublayerModelNode *parentNode )
const
548 Q_ASSERT( parentNode );
550 QgsProviderSublayerModelGroup *grandParentNode = parentNode->parent();
551 if ( !grandParentNode )
552 return QModelIndex();
554 int row = grandParentNode->indexOf( parentNode );
555 Q_ASSERT( row >= 0 );
557 return createIndex( row, 0, parentNode );
560QModelIndex QgsProviderSublayerModel::node2index( QgsProviderSublayerModelNode *node )
const
562 if ( !node || !node->parent() )
563 return QModelIndex();
565 QModelIndex parentIndex = node2index( node->parent() );
567 int row = node->parent()->indexOf( node );
568 Q_ASSERT( row >= 0 );
569 return index( row, 0, parentIndex );
604 mDescription = description;
629 return mType == other.mType
630 && mName == other.mName
631 && mDescription == other.mDescription
632 && mUri == other.mUri;
637 return !( *
this == other );
645 : QSortFilterProxyModel(
parent )
647 setRecursiveFilteringEnabled(
true );
648 setDynamicSortFilter(
true );
654 const QModelIndex sourceIndex = sourceModel()->index( source_row, 0, source_parent );
662 if ( mFilterString.trimmed().isEmpty() )
669 const QModelIndex descriptionColumnIndex = sourceModel()->index( source_row, 1, source_parent );
670 if ( sourceModel()->data( descriptionColumnIndex,
static_cast< int >( Qt::DisplayRole ) ).toString().contains( mFilterString, Qt::CaseInsensitive ) )
674 if ( wkbTypeVariant.isValid() )
689 if ( leftIsNonLayer && !rightIsNonLayer )
691 else if ( rightIsNonLayer && !leftIsNonLayer )
697 return QString::localeAwareCompare( leftName, rightName ) < 0;
702 return mIncludeSystemTables;
707 mIncludeSystemTables = include;
713 return mIncludeEmptyLayers;
718 mIncludeEmptyLayers = include;
724 return mFilterString;
729 mFilterString = filter;
@ SystemTable
Sublayer is a system or internal table, which should be hidden by default.
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) SIP_HOLDGIL
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.