QGIS API Documentation  3.4.15-Madeira (e83d02e274)
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
6  Email : [email protected]
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 
16 #include "qgsmaplayerproxymodel.h"
17 #include "qgsmaplayermodel.h"
18 #include "qgsmaplayer.h"
19 #include "qgsproject.h"
20 #include "qgsvectorlayer.h"
21 #include "qgsrasterlayer.h"
22 #include "qgsvectordataprovider.h"
23 #include "qgsrasterdataprovider.h"
24 
26  : QSortFilterProxyModel( parent )
27  , mFilters( All )
28  , mModel( new QgsMapLayerModel( parent ) )
29 {
30  setSourceModel( mModel );
31  setDynamicSortFilter( true );
32  setSortLocaleAware( true );
33  setFilterCaseSensitivity( Qt::CaseInsensitive );
34  sort( 0 );
35 }
36 
38 {
39  mFilters = filters;
40  invalidateFilter();
41  return this;
42 }
43 
44 void QgsMapLayerProxyModel::setLayerWhitelist( const QList<QgsMapLayer *> &layers )
45 {
46  if ( mLayerWhitelist == layers )
47  return;
48 
49  mLayerWhitelist = layers;
50  invalidateFilter();
51 }
52 
53 void QgsMapLayerProxyModel::setExceptedLayerList( const QList<QgsMapLayer *> &exceptList )
54 {
55  if ( mExceptList == exceptList )
56  return;
57 
58  mExceptList = exceptList;
59  invalidateFilter();
60 }
61 
62 void QgsMapLayerProxyModel::setExceptedLayerIds( const QStringList &ids )
63 {
64  mExceptList.clear();
65 
66  Q_FOREACH ( const QString &id, ids )
67  {
69  if ( l )
70  mExceptList << l;
71  }
72  invalidateFilter();
73 }
74 
76 {
77  QStringList lst;
78 
79  Q_FOREACH ( QgsMapLayer *l, mExceptList )
80  lst << l->id();
81 
82  return lst;
83 }
84 
85 void QgsMapLayerProxyModel::setExcludedProviders( const QStringList &providers )
86 {
87  mExcludedProviders = providers;
88  invalidateFilter();
89 }
90 
91 void QgsMapLayerProxyModel::setFilterString( const QString &filter )
92 {
93  mFilterString = filter;
94  invalidateFilter();
95 }
96 
97 bool QgsMapLayerProxyModel::filterAcceptsRow( int source_row, const QModelIndex &source_parent ) const
98 {
99  if ( mFilters.testFlag( All ) && mExceptList.isEmpty() && mLayerWhitelist.isEmpty() && mExcludedProviders.isEmpty() && mFilterString.isEmpty() )
100  return true;
101 
102  QModelIndex index = sourceModel()->index( source_row, 0, source_parent );
103 
104  if ( sourceModel()->data( index, QgsMapLayerModel::EmptyRole ).toBool()
105  || sourceModel()->data( index, QgsMapLayerModel::AdditionalRole ).toBool() )
106  return true;
107 
108  QgsMapLayer *layer = static_cast<QgsMapLayer *>( index.internalPointer() );
109  if ( !layer )
110  return false;
111 
112  if ( !mLayerWhitelist.isEmpty() && !mLayerWhitelist.contains( layer ) )
113  return false;
114 
115  if ( mExceptList.contains( layer ) )
116  return false;
117 
118  if ( mExcludedProviders.contains( layer->dataProvider()->name() ) )
119  return false;
120 
121  if ( mFilters.testFlag( WritableLayer ) && layer->readOnly() )
122  return false;
123 
124  if ( !layer->name().contains( mFilterString, Qt::CaseInsensitive ) )
125  return false;
126 
127  // layer type
128  if ( ( mFilters.testFlag( RasterLayer ) && layer->type() == QgsMapLayer::RasterLayer ) ||
129  ( mFilters.testFlag( VectorLayer ) && layer->type() == QgsMapLayer::VectorLayer ) ||
130  ( mFilters.testFlag( PluginLayer ) && layer->type() == QgsMapLayer::PluginLayer ) )
131  return true;
132 
133  // geometry type
134  bool detectGeometry = mFilters.testFlag( NoGeometry ) ||
135  mFilters.testFlag( PointLayer ) ||
136  mFilters.testFlag( LineLayer ) ||
137  mFilters.testFlag( PolygonLayer ) ||
138  mFilters.testFlag( HasGeometry );
139  if ( detectGeometry && layer->type() == QgsMapLayer::VectorLayer )
140  {
141  if ( QgsVectorLayer *vl = qobject_cast< QgsVectorLayer *>( layer ) )
142  {
143  if ( mFilters.testFlag( HasGeometry ) && vl->isSpatial() )
144  return true;
145  if ( mFilters.testFlag( NoGeometry ) && vl->geometryType() == QgsWkbTypes::NullGeometry )
146  return true;
147  if ( mFilters.testFlag( PointLayer ) && vl->geometryType() == QgsWkbTypes::PointGeometry )
148  return true;
149  if ( mFilters.testFlag( LineLayer ) && vl->geometryType() == QgsWkbTypes::LineGeometry )
150  return true;
151  if ( mFilters.testFlag( PolygonLayer ) && vl->geometryType() == QgsWkbTypes::PolygonGeometry )
152  return true;
153  }
154  }
155 
156  return false;
157 }
158 
159 bool QgsMapLayerProxyModel::lessThan( const QModelIndex &left, const QModelIndex &right ) const
160 {
161  // empty row is always first
162  if ( sourceModel()->data( left, QgsMapLayerModel::EmptyRole ).toBool() )
163  return true;
164  else if ( sourceModel()->data( right, QgsMapLayerModel::EmptyRole ).toBool() )
165  return false;
166 
167  // additional rows are always last
168  bool leftAdditional = sourceModel()->data( left, QgsMapLayerModel::AdditionalRole ).toBool();
169  bool rightAdditional = sourceModel()->data( right, QgsMapLayerModel::AdditionalRole ).toBool();
170 
171  if ( leftAdditional && !rightAdditional )
172  return false;
173  else if ( rightAdditional && !leftAdditional )
174  return true;
175 
176  // default mode is alphabetical order
177  QString leftStr = sourceModel()->data( left ).toString();
178  QString rightStr = sourceModel()->data( right ).toString();
179  return QString::localeAwareCompare( leftStr, rightStr ) < 0;
180 }
QgsMapLayerProxyModel(QObject *parent=nullptr)
QgsMapLayerProxModel creates a proxy model with a QgsMapLayerModel as source model.
Base class for all map layer types.
Definition: qgsmaplayer.h:63
QgsMapLayer::LayerType type() const
Returns the type of the layer.
virtual QgsDataProvider * dataProvider()
Returns the layer&#39;s data provider.
void setExceptedLayerIds(const QStringList &ids)
Sets a blacklist of layers (by layer ID) to exclude from the model.
virtual QString name() const =0
Returns a provider name.
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override
True if index corresponds to an additional (non map layer) item.
bool readOnly() const
Returns if this layer is read only.
Definition: qgsmaplayer.h:452
void setExceptedLayerList(const QList< QgsMapLayer * > &exceptList)
Sets a blacklist of layers to exclude from the model.
The QgsMapLayerModel class is a model to display layers in widgets.
The QgsMapLayerProxyModel class provides an easy to use model to display the list of layers in widget...
QString id() const
Returns the layer&#39;s unique ID, which is used to access this layer from QgsProject.
bool lessThan(const QModelIndex &left, const QModelIndex &right) const override
QStringList exceptedLayerIds() const
Returns the blacklist of layer IDs which are excluded from the model.
void setLayerWhitelist(const QList< QgsMapLayer * > &layers)
Sets a whitelist of layers to include within the model.
void setExcludedProviders(const QStringList &providers)
Sets a blacklist of data providers which should be excluded from the model.
QgsMapLayer * mapLayer(const QString &layerId) const
Retrieve a pointer to a registered layer by layer ID.
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:411
QgsMapLayerProxyModel * setFilters(QgsMapLayerProxyModel::Filters filters)
Sets filter flags which affect how layers are filtered within the model.
QString name
Definition: qgsmaplayer.h:67
Represents a vector layer which manages a vector based data sets.
void setFilterString(const QString &filter)
Sets a filter string, such that only layers with names matching the specified string will be shown...
const Filters & filters() const
Returns the filter flags which affect how layers are filtered within the model.
True if index corresponds to the empty (not set) value.