QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
qgsprovidersublayermodel.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsprovidersublayermodel.cpp
3  ----------------------
4  begin : June 2021
5  copyright : (C) 2021 by Nyall Dawson
6  email : nyall dot dawson at gmail dot com
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
20 #include "qgsiconutils.h"
21 #include <QLocale>
22 
24  : QAbstractItemModel( parent )
25 {
26 
27 }
28 
29 void QgsProviderSublayerModel::setSublayerDetails( const QList<QgsProviderSublayerDetails> &details )
30 {
31  // remove layers which don't exist in new list
32  for ( int i = mSublayers.count() - 1; i >= 0; --i )
33  {
34  if ( !details.contains( mSublayers.at( i ) ) )
35  {
36  beginRemoveRows( QModelIndex(), i, i );
37  mSublayers.removeAt( i );
38  endRemoveRows();
39  }
40  }
41 
42  // and add new layers which exist only in new list
43  for ( const QgsProviderSublayerDetails &layer : details )
44  {
45  if ( !mSublayers.contains( layer ) )
46  {
47  beginInsertRows( QModelIndex(), mSublayers.count(), mSublayers.count() );
48  mSublayers.append( layer );
49  endInsertRows();
50  }
51  }
52 }
53 
54 QList<QgsProviderSublayerDetails> QgsProviderSublayerModel::sublayerDetails() const
55 {
56  return mSublayers;
57 }
58 
60 {
61  if ( index.isValid() && index.row() < mSublayers.count() )
62  {
63  return mSublayers.at( index.row() );
64  }
65 
67 }
68 
70 {
71  if ( index.isValid() && index.row() >= mSublayers.count() && index.row() < mSublayers.count() + mNonLayerItems.count() )
72  {
73  return mNonLayerItems.at( index.row() - mSublayers.count() );
74  }
75 
77 }
78 
80 {
81  beginInsertRows( QModelIndex(), mSublayers.count() + mNonLayerItems.count(), mSublayers.count() + mNonLayerItems.count() );
82  mNonLayerItems.append( item );
83  endInsertRows();
84 }
85 
86 QModelIndex QgsProviderSublayerModel::index( int row, int column, const QModelIndex &parent ) const
87 {
88  if ( column < 0 || column >= columnCount() )
89  {
90  //column out of bounds
91  return QModelIndex();
92  }
93 
94  if ( !parent.isValid() && row >= 0 && row < mSublayers.size() + mNonLayerItems.size() )
95  {
96  //return an index for the sublayer at this position
97  return createIndex( row, column );
98  }
99 
100  //only top level supported for now
101  return QModelIndex();
102 }
103 
104 QModelIndex QgsProviderSublayerModel::parent( const QModelIndex &index ) const
105 {
106  Q_UNUSED( index )
107 
108  //all items are top level for now
109  return QModelIndex();
110 }
111 
112 int QgsProviderSublayerModel::columnCount( const QModelIndex &parent ) const
113 {
114  Q_UNUSED( parent )
115  return static_cast< int >( Column::Description ) + 1;
116 }
117 
118 int QgsProviderSublayerModel::rowCount( const QModelIndex &parent ) const
119 {
120  if ( !parent.isValid() )
121  {
122  return mSublayers.size() + mNonLayerItems.size();
123  }
124  else
125  {
126  //no children for now
127  return 0;
128  }
129 }
130 
131 QVariant QgsProviderSublayerModel::data( const QModelIndex &index, int role ) const
132 {
133  if ( !index.isValid() )
134  return QVariant();
135 
136  if ( index.row() < 0 || index.row() >= rowCount( QModelIndex() ) )
137  return QVariant();
138 
139  if ( index.row() < mSublayers.count() )
140  {
141  const QgsProviderSublayerDetails details = mSublayers.at( index.row() );
142 
143  switch ( role )
144  {
145  case Qt::DisplayRole:
146  case Qt::ToolTipRole:
147  case Qt::EditRole:
148  {
149  switch ( static_cast< Column >( index.column() ) )
150  {
152  return details.name();
154  {
155  switch ( details.type() )
156  {
158  {
159  QString count;
160  if ( details.featureCount() == static_cast< long long >( Qgis::FeatureCountState::Uncounted )
161  || details.featureCount() == static_cast< long long >( Qgis::FeatureCountState::UnknownCount ) )
162  count = tr( "Uncounted" );
163  else
164  count = QLocale().toString( details.featureCount() );
165 
166  if ( !details.description().isEmpty() )
167  return QStringLiteral( "%1 - %2 (%3)" ).arg( details.description(),
168  QgsWkbTypes::displayString( details.wkbType() ),
169  count );
170  else
171  return QStringLiteral( "%2 (%3)" ).arg(
172  QgsWkbTypes::displayString( details.wkbType() ),
173  count );
174  }
175 
183  return details.description();
184  }
185  break;
186 
187  }
188  }
189  return details.name();
190 
191  }
192 
193  case Qt::DecorationRole:
194  {
195  if ( index.column() == 0 )
196  return details.type() == QgsMapLayerType::VectorLayer
197  ? ( details.wkbType() != QgsWkbTypes::Unknown ? QgsIconUtils::iconForWkbType( details.wkbType() ) : QVariant() )
198  : QgsIconUtils::iconForLayerType( details.type() );
199  else
200  return QVariant();
201  }
202 
203  case static_cast< int >( Role::IsNonLayerItem ):
204  return false;
205 
206  case static_cast< int >( Role::ProviderKey ):
207  return details.providerKey();
208 
209  case static_cast< int >( Role::LayerType ):
210  return static_cast< int >( details.type() );
211 
212  case static_cast< int >( Role::Uri ):
213  return details.uri();
214 
215  case static_cast< int >( Role::Name ):
216  return details.name();
217 
218  case static_cast< int >( Role::Description ):
219  return details.description();
220 
221  case static_cast< int >( Role::Path ):
222  return details.path();
223 
224  case static_cast< int >( Role::FeatureCount ):
225  return details.featureCount();
226 
227  case static_cast< int >( Role::WkbType ):
228  return details.wkbType();
229 
230  case static_cast< int >( Role::GeometryColumnName ):
231  return details.geometryColumnName();
232 
233  case static_cast< int >( Role::LayerNumber ):
234  return details.layerNumber();
235 
236  case static_cast< int >( Role::Flags ):
237  return static_cast< int >( details.flags() );
238 
239  default:
240  return QVariant();
241  }
242  }
243  else
244  {
245  const NonLayerItem details = mNonLayerItems.at( index.row() - mSublayers.count() );
246 
247  switch ( role )
248  {
249  case Qt::DisplayRole:
250  case Qt::ToolTipRole:
251  case Qt::EditRole:
252  {
253  switch ( static_cast< Column >( index.column() ) )
254  {
256  return details.name();
258  return details.description();
259  }
260  return QVariant();
261  }
262 
263  case Qt::DecorationRole:
264  {
265  if ( index.column() == 0 )
266  return details.icon();
267  else
268  return QVariant();
269  }
270 
271  case static_cast< int >( Role::IsNonLayerItem ):
272  return true;
273 
274  case static_cast< int >( Role::Uri ):
275  return details.uri();
276 
277  case static_cast< int >( Role::Name ):
278  return details.name();
279 
280  case static_cast< int >( Role::Description ):
281  return details.description();
282 
283  case static_cast< int >( Role::NonLayerItemType ):
284  return details.type();
285 
286  default:
287  return QVariant();
288  }
289  }
290 }
291 
292 QVariant QgsProviderSublayerModel::headerData( int section, Qt::Orientation orientation, int role ) const
293 {
294  switch ( orientation )
295  {
296  case Qt::Vertical:
297  break;
298  case Qt::Horizontal:
299  {
300  switch ( role )
301  {
302  case Qt::DisplayRole:
303  case Qt::ToolTipRole:
304  {
305  switch ( static_cast< Column>( section ) )
306  {
308  return tr( "Item" );
310  return tr( "Description" );
311  }
312  break;
313  }
314  }
315  break;
316  }
317  }
318  return QVariant();
319 }
320 
321 
322 //
323 // QgsProviderSublayerModel::NonLayerItem
324 //
325 
327 {
328  return mType;
329 }
330 
332 {
333  mType = type;
334 }
335 
337 {
338  return mName;
339 }
340 
342 {
343  mName = name;
344 }
345 
347 {
348  return mDescription;
349 }
350 
352 {
353  mDescription = description;
354 }
355 
357 {
358  return mUri;
359 }
360 
362 {
363  mUri = uri;
364 }
365 
367 {
368  return mIcon;
369 }
370 
372 {
373  mIcon = icon;
374 }
375 
377 {
378  return mType == other.mType
379  && mName == other.mName
380  && mDescription == other.mDescription
381  && mUri == other.mUri;
382 }
383 
385 {
386  return !( *this == other );
387 }
388 
389 //
390 // QgsProviderSublayerProxyModel
391 //
392 
394  : QSortFilterProxyModel( parent )
395 {
396  setDynamicSortFilter( true );
397  sort( 0 );
398 }
399 
400 bool QgsProviderSublayerProxyModel::filterAcceptsRow( int source_row, const QModelIndex &source_parent ) const
401 {
402  const QModelIndex sourceIndex = sourceModel()->index( source_row, 0, source_parent );
403 
404  if ( !mIncludeSystemTables && static_cast< Qgis::SublayerFlags >( sourceModel()->data( sourceIndex, static_cast< int >( QgsProviderSublayerModel::Role::Flags ) ).toInt() ) & Qgis::SublayerFlag::SystemTable )
405  return false;
406 
407  if ( mFilterString.trimmed().isEmpty() )
408  return true;
409 
410  if ( sourceModel()->data( sourceIndex, static_cast< int >( QgsProviderSublayerModel::Role::Name ) ).toString().contains( mFilterString, Qt::CaseInsensitive ) )
411  return true;
412 
413  if ( sourceModel()->data( sourceIndex, static_cast< int >( QgsProviderSublayerModel::Role::Description ) ).toString().contains( mFilterString, Qt::CaseInsensitive ) )
414  return true;
415 
416  const QVariant wkbTypeVariant = sourceModel()->data( sourceIndex, static_cast< int >( QgsProviderSublayerModel::Role::WkbType ) );
417  if ( wkbTypeVariant.isValid() )
418  {
419  const QgsWkbTypes::Type wkbType = static_cast< QgsWkbTypes::Type >( wkbTypeVariant.toInt() );
420  if ( QgsWkbTypes::displayString( wkbType ).contains( mFilterString, Qt::CaseInsensitive ) )
421  return true;
422  }
423 
424  return false;
425 }
426 
427 bool QgsProviderSublayerProxyModel::lessThan( const QModelIndex &source_left, const QModelIndex &source_right ) const
428 {
429  const bool leftIsNonLayer = sourceModel()->data( source_left, static_cast< int >( QgsProviderSublayerModel::Role::IsNonLayerItem ) ).toBool();
430  const bool rightIsNonLayer = sourceModel()->data( source_right, static_cast< int >( QgsProviderSublayerModel::Role::IsNonLayerItem ) ).toBool();
431 
432  if ( leftIsNonLayer && !rightIsNonLayer )
433  return true;
434  else if ( rightIsNonLayer && !leftIsNonLayer )
435  return false;
436 
437  const QString leftName = sourceModel()->data( source_left, static_cast< int >( QgsProviderSublayerModel::Role::Name ) ).toString();
438  const QString rightName = sourceModel()->data( source_right, static_cast< int >( QgsProviderSublayerModel::Role::Name ) ).toString();
439 
440  return QString::localeAwareCompare( leftName, rightName ) < 0;
441 }
442 
444 {
445  return mIncludeSystemTables;
446 }
447 
449 {
450  mIncludeSystemTables = include;
451  invalidateFilter();
452 }
453 
455 {
456  return mFilterString;
457 }
458 
460 {
461  mFilterString = filter;
462  invalidateFilter();
463 }
Qgis::FeatureCountState::UnknownCount
@ UnknownCount
Provider returned an unknown feature count.
QgsProviderSublayerModel::NonLayerItem::name
QString name() const
Returns the item's name.
Definition: qgsprovidersublayermodel.cpp:336
QgsWkbTypes::displayString
static QString displayString(Type type) SIP_HOLDGIL
Returns a non-translated display string type for a WKB type, e.g., the geometry name used in WKT geom...
Definition: qgswkbtypes.cpp:145
QgsProviderSublayerProxyModel::filterAcceptsRow
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override
Definition: qgsprovidersublayermodel.cpp:400
QgsMapLayerType::MeshLayer
@ MeshLayer
Mesh layer. Added in QGIS 3.2.
QgsMapLayerType::VectorLayer
@ VectorLayer
Vector layer.
QgsProviderSublayerModel::NonLayerItem::operator==
bool operator==(const QgsProviderSublayerModel::NonLayerItem &other) const
Definition: qgsprovidersublayermodel.cpp:376
QgsProviderSublayerModel::sublayerDetails
QList< QgsProviderSublayerDetails > sublayerDetails() const
Returns the sublayer details shown in the model.
Definition: qgsprovidersublayermodel.cpp:54
QgsProviderSublayerDetails::uri
QString uri() const
Returns the layer's URI.
Definition: qgsprovidersublayerdetails.h:81
QgsProviderSublayerModel::mNonLayerItems
QList< NonLayerItem > mNonLayerItems
Non layer item list.
Definition: qgsprovidersublayermodel.h:212
QgsProviderSublayerModel::Role::GeometryColumnName
@ GeometryColumnName
Geometry column name (for vector sublayers)
QgsProviderSublayerModel::Role::IsNonLayerItem
@ IsNonLayerItem
true if item is a non-sublayer item (e.g. an embedded project)
QgsMapLayerType::AnnotationLayer
@ AnnotationLayer
Contains freeform, georeferenced annotations. Added in QGIS 3.16.
QgsProviderSublayerDetails::path
QStringList path() const
Returns the path to the sublayer.
Definition: qgsprovidersublayerdetails.h:183
QgsProviderSublayerModel::Role::LayerType
@ LayerType
Layer type.
QgsProviderSublayerModel::indexToNonLayerItem
QgsProviderSublayerModel::NonLayerItem indexToNonLayerItem(const QModelIndex &index) const
Returns the non layer item corresponding to the given index.
Definition: qgsprovidersublayermodel.cpp:69
QgsProviderSublayerModel::mSublayers
QList< QgsProviderSublayerDetails > mSublayers
Sublayer list.
Definition: qgsprovidersublayermodel.h:209
QgsWkbTypes::Type
Type
The WKB type describes the number of dimensions a geometry has.
Definition: qgswkbtypes.h:69
QgsProviderSublayerProxyModel::setFilterString
void setFilterString(const QString &filter)
Sets the filter string used for filtering items in the model.
Definition: qgsprovidersublayermodel.cpp:459
QgsIconUtils::iconForLayerType
static QIcon iconForLayerType(QgsMapLayerType type)
Returns the default icon for the specified layer type.
Definition: qgsiconutils.cpp:145
QgsProviderSublayerModel::NonLayerItem::operator!=
bool operator!=(const QgsProviderSublayerModel::NonLayerItem &other) const
Definition: qgsprovidersublayermodel.cpp:384
QgsProviderSublayerProxyModel::includeSystemTables
bool includeSystemTables() const
Returns true if system and internal tables will be shown in the model.
Definition: qgsprovidersublayermodel.cpp:443
QgsProviderSublayerModel::Role::ProviderKey
@ ProviderKey
Provider key.
qgsprovidersublayermodel.h
QgsProviderSublayerModel::NonLayerItem::uri
QString uri() const
Returns the item's URI.
Definition: qgsprovidersublayermodel.cpp:356
QgsProviderSublayerDetails::featureCount
long long featureCount() const
Returns the layer's feature count.
Definition: qgsprovidersublayerdetails.h:202
QgsProviderSublayerModel::Column
Column
Model columns.
Definition: qgsprovidersublayermodel.h:67
QgsWkbTypes::Unknown
@ Unknown
Definition: qgswkbtypes.h:71
QgsProviderSublayerModel::QgsProviderSublayerModel
QgsProviderSublayerModel(QObject *parent=nullptr)
Constructor for QgsProviderSublayerModel, with the specified parent object.
Definition: qgsprovidersublayermodel.cpp:23
QgsProviderSublayerModel::Role::WkbType
@ WkbType
WKB geometry type (for vector sublayers)
QgsMapLayerType::GroupLayer
@ GroupLayer
Composite group layer. Added in QGIS 3.24.
QgsProviderSublayerProxyModel::filterString
QString filterString() const
Returns the filter string used for filtering items in the model.
Definition: qgsprovidersublayermodel.cpp:454
QgsProviderSublayerModel::NonLayerItem::setUri
void setUri(const QString &uri)
Set the item's uri.
Definition: qgsprovidersublayermodel.cpp:361
QgsMapLayerType::RasterLayer
@ RasterLayer
Raster layer.
QgsProviderSublayerModel::Role::NonLayerItemType
@ NonLayerItemType
Item type (for non-sublayer items)
QgsProviderSublayerModel::Column::Description
@ Description
Layer description.
QgsProviderSublayerDetails::providerKey
QString providerKey() const
Returns the associated data provider key.
Definition: qgsprovidersublayerdetails.h:53
QgsProviderSublayerDetails
Contains details about a sub layer available from a dataset.
Definition: qgsprovidersublayerdetails.h:44
QgsProviderSublayerModel::rowCount
int rowCount(const QModelIndex &parent) const override
Definition: qgsprovidersublayermodel.cpp:118
QgsProviderSublayerModel::NonLayerItem
Contains details for a non-sublayer item to include in a QgsProviderSublayerModel.
Definition: qgsprovidersublayermodel.h:80
QgsProviderSublayerProxyModel::lessThan
bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const override
Definition: qgsprovidersublayermodel.cpp:427
QgsProviderSublayerModel::Role::Name
@ Name
Layer name.
QgsProviderSublayerModel::NonLayerItem::type
QString type() const
Returns the item's type.
Definition: qgsprovidersublayermodel.cpp:326
QgsProviderSublayerModel::addNonLayerItem
void addNonLayerItem(const QgsProviderSublayerModel::NonLayerItem &item)
Adds a non-layer item (e.g.
Definition: qgsprovidersublayermodel.cpp:79
QgsProviderSublayerModel::NonLayerItem::icon
QIcon icon() const
Returns the item's icon.
Definition: qgsprovidersublayermodel.cpp:366
QgsProviderSublayerDetails::name
QString name() const
Returns the layer's name.
Definition: qgsprovidersublayerdetails.h:122
QgsProviderSublayerModel::index
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
Definition: qgsprovidersublayermodel.cpp:86
QgsProviderSublayerDetails::geometryColumnName
QString geometryColumnName() const
Returns the layer's geometry column name, or an empty string if not applicable.
Definition: qgsprovidersublayerdetails.h:234
QgsProviderSublayerModel::Column::Name
@ Name
Layer name.
QgsProviderSublayerModel::NonLayerItem::description
QString description() const
Returns the item's description.
Definition: qgsprovidersublayermodel.cpp:346
QgsProviderSublayerModel::data
QVariant data(const QModelIndex &index, int role) const override
Definition: qgsprovidersublayermodel.cpp:131
QgsProviderSublayerModel::Role::Description
@ Description
Layer description.
QgsProviderSublayerProxyModel::QgsProviderSublayerProxyModel
QgsProviderSublayerProxyModel(QObject *parent=nullptr)
Constructor for QgsProviderSublayerProxyModel, with the specified parent object.
Definition: qgsprovidersublayermodel.cpp:393
QgsProviderSublayerModel::Role::Uri
@ Uri
Layer URI.
QgsProviderSublayerModel::indexToSublayer
QgsProviderSublayerDetails indexToSublayer(const QModelIndex &index) const
Returns the sublayer corresponding to the given index.
Definition: qgsprovidersublayermodel.cpp:59
QgsProviderSublayerModel::NonLayerItem::setType
void setType(const QString &type)
Sets the item's type.
Definition: qgsprovidersublayermodel.cpp:331
QgsProviderSublayerDetails::layerNumber
int layerNumber() const
Returns the associated layer number, for providers which order sublayers.
Definition: qgsprovidersublayerdetails.h:258
QgsProviderSublayerModel::NonLayerItem::setDescription
void setDescription(const QString &description)
Sets the item's description.
Definition: qgsprovidersublayermodel.cpp:351
QgsIconUtils::iconForWkbType
static QIcon iconForWkbType(QgsWkbTypes::Type type)
Returns the icon for a vector layer whose geometry type is provided.
Definition: qgsiconutils.cpp:25
QgsProviderSublayerModel::Role::FeatureCount
@ FeatureCount
Feature count (for vector sublayers)
QgsMapLayerType::VectorTileLayer
@ VectorTileLayer
Vector tile layer. Added in QGIS 3.14.
QgsProviderSublayerModel::NonLayerItem::setName
void setName(const QString &name)
Sets the item's name.
Definition: qgsprovidersublayermodel.cpp:341
qgsiconutils.h
QgsProviderSublayerDetails::type
QgsMapLayerType type() const
Returns the layer type.
Definition: qgsprovidersublayerdetails.h:67
QgsProviderSublayerDetails::wkbType
QgsWkbTypes::Type wkbType() const
Returns the layer's WKB type, or QgsWkbTypes::Unknown if the WKB type is not application or unknown.
Definition: qgsprovidersublayerdetails.h:218
Qgis::FeatureCountState::Uncounted
@ Uncounted
Feature count not yet computed.
Qgis::SublayerFlag::SystemTable
@ SystemTable
Sublayer is a system or internal table, which should be hidden by default.
QgsProviderSublayerProxyModel::setIncludeSystemTables
void setIncludeSystemTables(bool include)
Sets whether system and internal tables will be shown in the model.
Definition: qgsprovidersublayermodel.cpp:448
QgsProviderSublayerDetails::description
QString description() const
Returns the layer's description.
Definition: qgsprovidersublayerdetails.h:136
QgsProviderSublayerModel::Role::LayerNumber
@ LayerNumber
Layer number.
QgsProviderSublayerModel::columnCount
int columnCount(const QModelIndex &parent=QModelIndex()) const override
Definition: qgsprovidersublayermodel.cpp:112
QgsProviderSublayerModel::NonLayerItem::setIcon
void setIcon(const QIcon &icon)
Sets the item's icon.
Definition: qgsprovidersublayermodel.cpp:371
qgsprovidersublayerdetails.h
QgsProviderSublayerModel::Role::Flags
@ Flags
Sublayer flags.
QgsProviderSublayerModel::Role::Path
@ Path
Layer path.
QgsMapLayerType::PointCloudLayer
@ PointCloudLayer
Point cloud layer. Added in QGIS 3.18.
QgsProviderSublayerModel::headerData
QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const override
Definition: qgsprovidersublayermodel.cpp:292
QgsProviderSublayerModel::setSublayerDetails
void setSublayerDetails(const QList< QgsProviderSublayerDetails > &details)
Sets the sublayer details to show in the model.
Definition: qgsprovidersublayermodel.cpp:29
QgsProviderSublayerModel::parent
QModelIndex parent(const QModelIndex &index) const override
Definition: qgsprovidersublayermodel.cpp:104
QgsMapLayerType::PluginLayer
@ PluginLayer
Plugin based layer.
QgsProviderSublayerDetails::flags
Qgis::SublayerFlags flags() const
Returns the layer's flags, which indicate properties of the layer.
Definition: qgsprovidersublayerdetails.h:150