QGIS API Documentation 3.30.0-'s-Hertogenbosch (f186b8efe0)
qgsmaplayerproxymodel.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsmaplayerproxymodel.cpp
3 --------------------------------------
4 Date : 01.04.2014
5 Copyright : (C) 2014 Denis Rouzaud
7***************************************************************************
8* *
9* This program is free software; you can redistribute it and/or modify *
10* it under the terms of the GNU General Public License as published by *
11* the Free Software Foundation; either version 2 of the License, or *
12* (at your option) any later version. *
13* *
14***************************************************************************/
15
17#include "qgsmaplayermodel.h"
18#include "qgsmaplayer.h"
19#include "qgsproject.h"
20#include "qgsvectorlayer.h"
21
23 : QSortFilterProxyModel( parent )
24 , mFilters( All )
25 , mModel( new QgsMapLayerModel( parent ) )
26{
27 setSourceModel( mModel );
28 setDynamicSortFilter( true );
29 setSortLocaleAware( true );
30 setFilterCaseSensitivity( Qt::CaseInsensitive );
31 sort( 0 );
32}
33
35{
36 mFilters = filters;
37 invalidateFilter();
38 return this;
39}
40
41bool QgsMapLayerProxyModel::layerMatchesFilters( const QgsMapLayer *layer, const Filters &filters )
42{
43 if ( filters.testFlag( All ) )
44 return true;
45
46 // layer type
47 if ( ( filters.testFlag( RasterLayer ) && layer->type() == Qgis::LayerType::Raster ) ||
48 ( filters.testFlag( VectorLayer ) && layer->type() == Qgis::LayerType::Vector ) ||
49 ( filters.testFlag( MeshLayer ) && layer->type() == Qgis::LayerType::Mesh ) ||
50 ( filters.testFlag( VectorTileLayer ) && layer->type() == Qgis::LayerType::VectorTile ) ||
51 ( filters.testFlag( PointCloudLayer ) && layer->type() == Qgis::LayerType::PointCloud ) ||
52 ( filters.testFlag( AnnotationLayer ) && layer->type() == Qgis::LayerType::Annotation ) ||
53 ( filters.testFlag( PluginLayer ) && layer->type() == Qgis::LayerType::Plugin ) )
54 return true;
55
56 // geometry type
57 const bool detectGeometry = filters.testFlag( NoGeometry ) ||
58 filters.testFlag( PointLayer ) ||
59 filters.testFlag( LineLayer ) ||
60 filters.testFlag( PolygonLayer ) ||
61 filters.testFlag( HasGeometry );
62 if ( detectGeometry && layer->type() == Qgis::LayerType::Vector )
63 {
64 if ( const QgsVectorLayer *vl = qobject_cast<const QgsVectorLayer *>( layer ) )
65 {
66 if ( filters.testFlag( HasGeometry ) && vl->isSpatial() )
67 return true;
68 if ( filters.testFlag( NoGeometry ) && vl->geometryType() == Qgis::GeometryType::Null )
69 return true;
70 if ( filters.testFlag( PointLayer ) && vl->geometryType() == Qgis::GeometryType::Point )
71 return true;
72 if ( filters.testFlag( LineLayer ) && vl->geometryType() == Qgis::GeometryType::Line )
73 return true;
74 if ( filters.testFlag( PolygonLayer ) && vl->geometryType() == Qgis::GeometryType::Polygon )
75 return true;
76 }
77 }
78
79 return false;
80}
81
82void QgsMapLayerProxyModel::setLayerWhitelist( const QList<QgsMapLayer *> &layers )
83{
84 setLayerAllowlist( layers );
85}
86
87void QgsMapLayerProxyModel::setLayerAllowlist( const QList<QgsMapLayer *> &layers )
88{
89 if ( mLayerAllowlist == layers )
90 return;
91
92 mLayerAllowlist = layers;
93 invalidateFilter();
94}
95
96void QgsMapLayerProxyModel::setExceptedLayerList( const QList<QgsMapLayer *> &exceptList )
97{
98 if ( mExceptList == exceptList )
99 return;
100
101 mExceptList = exceptList;
102 invalidateFilter();
103}
104
106{
107 mModel->setProject( project );
108}
109
110void QgsMapLayerProxyModel::setExceptedLayerIds( const QStringList &ids )
111{
112 mExceptList.clear();
113
114 const auto constIds = ids;
115 for ( const QString &id : constIds )
116 {
118 if ( l )
119 mExceptList << l;
120 }
121 invalidateFilter();
122}
123
125{
126 QStringList lst;
127
128 const auto constMExceptList = mExceptList;
129 for ( QgsMapLayer *l : constMExceptList )
130 lst << l->id();
131
132 return lst;
133}
134
135void QgsMapLayerProxyModel::setExcludedProviders( const QStringList &providers )
136{
137 mExcludedProviders = providers;
138 invalidateFilter();
139}
140
142{
143 if ( !layer )
144 return false;
145
146 if ( !mLayerAllowlist.isEmpty() && !mLayerAllowlist.contains( layer ) )
147 return false;
148
149 if ( mExceptList.contains( layer ) )
150 return false;
151
152 if ( layer->dataProvider() && mExcludedProviders.contains( layer->providerType() ) )
153 return false;
154
155 if ( mFilters.testFlag( WritableLayer ) && layer->readOnly() )
156 return false;
157
158 if ( !layer->name().contains( mFilterString, Qt::CaseInsensitive ) )
159 return false;
160
161 return layerMatchesFilters( layer, mFilters );
162}
163
164void QgsMapLayerProxyModel::setFilterString( const QString &filter )
165{
166 mFilterString = filter;
167 invalidateFilter();
168}
169
170bool QgsMapLayerProxyModel::filterAcceptsRow( int source_row, const QModelIndex &source_parent ) const
171{
172 if ( mFilters.testFlag( All ) && mExceptList.isEmpty() && mLayerAllowlist.isEmpty() && mExcludedProviders.isEmpty() && mFilterString.isEmpty() )
173 return true;
174
175 const QModelIndex index = sourceModel()->index( source_row, 0, source_parent );
176
177 if ( sourceModel()->data( index, QgsMapLayerModel::EmptyRole ).toBool()
178 || sourceModel()->data( index, QgsMapLayerModel::AdditionalRole ).toBool() )
179 return true;
180
181 return acceptsLayer( static_cast<QgsMapLayer *>( index.internalPointer() ) );
182}
183
184bool QgsMapLayerProxyModel::lessThan( const QModelIndex &left, const QModelIndex &right ) const
185{
186 // empty row is always first
187 if ( sourceModel()->data( left, QgsMapLayerModel::EmptyRole ).toBool() )
188 return true;
189 else if ( sourceModel()->data( right, QgsMapLayerModel::EmptyRole ).toBool() )
190 return false;
191
192 // additional rows are always last
193 const bool leftAdditional = sourceModel()->data( left, QgsMapLayerModel::AdditionalRole ).toBool();
194 const bool rightAdditional = sourceModel()->data( right, QgsMapLayerModel::AdditionalRole ).toBool();
195
196 if ( leftAdditional && !rightAdditional )
197 return false;
198 else if ( rightAdditional && !leftAdditional )
199 return true;
200
201 // default mode is alphabetical order
202 const QString leftStr = sourceModel()->data( left ).toString();
203 const QString rightStr = sourceModel()->data( right ).toString();
204 return QString::localeAwareCompare( leftStr, rightStr ) < 0;
205}
The QgsMapLayerModel class is a model to display layers in widgets.
void setProject(QgsProject *project)
Sets the QgsProject from which map layers are shown.
@ EmptyRole
True if index corresponds to the empty (not set) value.
@ AdditionalRole
True if index corresponds to an additional (non map layer) item.
The QgsMapLayerProxyModel class provides an easy to use model to display the list of layers in widget...
QgsMapLayerProxyModel::Filters filters
static bool layerMatchesFilters(const QgsMapLayer *layer, const Filters &filters)
Returns if the layer matches the given filters.
QgsMapLayerProxyModel * setFilters(QgsMapLayerProxyModel::Filters filters)
Sets filter flags which affect how layers are filtered within the model.
void setExceptedLayerIds(const QStringList &ids)
Sets a blocklist of layers (by layer ID) to exclude from the model.
bool lessThan(const QModelIndex &left, const QModelIndex &right) const override
void setFilterString(const QString &filter)
Sets a filter string, such that only layers with names matching the specified string will be shown.
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override
QgsMapLayerProxyModel(QObject *parent=nullptr)
QgsMapLayerProxModel creates a proxy model with a QgsMapLayerModel as source model.
bool acceptsLayer(QgsMapLayer *layer) const
Returns true if the proxy model accepts the specified map layer.
void setExcludedProviders(const QStringList &providers)
Sets a blocklist of data providers which should be excluded from the model.
void setLayerAllowlist(const QList< QgsMapLayer * > &layers)
Sets an allowlist of layers to include within the model.
@ AnnotationLayer
QgsAnnotationLayer.
@ VectorTileLayer
QgsVectorTileLayer.
@ PointCloudLayer
QgsPointCloudLayer.
void setProject(QgsProject *project)
Sets the project from which map layers are shown.
Q_DECL_DEPRECATED void setLayerWhitelist(const QList< QgsMapLayer * > &layers)
Sets an allowlist of layers to include within the model.
void setExceptedLayerList(const QList< QgsMapLayer * > &exceptList)
Sets a blocklist of layers to exclude from the model.
Base class for all map layer types.
Definition: qgsmaplayer.h:73
QString name
Definition: qgsmaplayer.h:76
QString providerType() const
Returns the provider type (provider key) for this layer.
Qgis::LayerType type
Definition: qgsmaplayer.h:80
bool readOnly() const
Returns if this layer is read only.
Definition: qgsmaplayer.h:525
virtual Q_INVOKABLE QgsDataProvider * dataProvider()
Returns the layer's data provider, it may be nullptr.
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Definition: qgsproject.h:105
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:477
Q_INVOKABLE QgsMapLayer * mapLayer(const QString &layerId) const
Retrieve a pointer to a registered layer by layer ID.
Represents a vector layer which manages a vector based data sets.