QGIS API Documentation  2.99.0-Master (5b186ae)
qgsattributetablefiltermodel.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  QgsAttributeTableFilterModel.cpp
3  --------------------------------------
4  Date : Feb 2009
5  Copyright : (C) 2009 Vita Cizek
6  Email : weetya (at) gmail.com
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 <QItemSelectionModel>
17 
18 #include "qgis.h"
20 #include "qgsattributetablemodel.h"
21 #include "qgsfeatureiterator.h"
22 #include "qgsvectorlayer.h"
23 #include "qgsfeature.h"
24 #include "qgsmapcanvas.h"
25 #include "qgslogger.h"
26 #include "qgsrenderer.h"
29 // Filter Model //
31 
33  : QSortFilterProxyModel( parent )
34  , mCanvas( canvas )
35  , mFilterMode( ShowAll )
36  , mSelectedOnTop( false )
37 {
38  setSourceModel( sourceModel );
39  setDynamicSortFilter( true );
40  setSortRole( QgsAttributeTableModel::SortRole );
41  connect( layer(), &QgsVectorLayer::selectionChanged, this, &QgsAttributeTableFilterModel::selectionChanged );
42 }
43 
44 bool QgsAttributeTableFilterModel::lessThan( const QModelIndex &left, const QModelIndex &right ) const
45 {
46  if ( mSelectedOnTop )
47  {
48  bool leftSelected = layer()->selectedFeatureIds().contains( masterModel()->rowToId( left.row() ) );
49  bool rightSelected = layer()->selectedFeatureIds().contains( masterModel()->rowToId( right.row() ) );
50 
51  if ( leftSelected && !rightSelected )
52  {
53  return sortOrder() == Qt::AscendingOrder;
54  }
55  else if ( rightSelected && !leftSelected )
56  {
57  return sortOrder() == Qt::DescendingOrder;
58  }
59  }
60 
61  if ( mTableModel->sortCacheExpression().isEmpty() )
62  {
63  //shortcut when no sort order set
64  return false;
65  }
66 
68  right.data( QgsAttributeTableModel::SortRole ) );
69 }
70 
71 void QgsAttributeTableFilterModel::sort( int column, Qt::SortOrder order )
72 {
73  if ( order != Qt::AscendingOrder && order != Qt::DescendingOrder )
74  order = Qt::AscendingOrder;
75 
76  int myColumn = mColumnMapping.at( column );
77  masterModel()->prefetchColumnData( myColumn );
78  QSortFilterProxyModel::sort( myColumn, order );
79  emit sortColumnChanged( column, order );
80 }
81 
82 QVariant QgsAttributeTableFilterModel::data( const QModelIndex &index, int role ) const
83 {
84  if ( mapColumnToSource( index.column() ) == -1 ) // actions
85  {
86  if ( role == TypeRole )
88  else if ( role == QgsAttributeTableModel::FeatureIdRole )
89  {
90  QModelIndex fieldIndex = QSortFilterProxyModel::mapToSource( QSortFilterProxyModel::index( index.row(), 0, index.parent() ) );
91  return sourceModel()->data( fieldIndex, QgsAttributeTableModel::FeatureIdRole );
92  }
93  }
94  else if ( role == TypeRole )
95  return ColumnTypeField;
96 
97  return QSortFilterProxyModel::data( index, role );
98 }
99 
100 QVariant QgsAttributeTableFilterModel::headerData( int section, Qt::Orientation orientation, int role ) const
101 {
102  if ( orientation == Qt::Horizontal )
103  {
104  if ( mColumnMapping.at( section ) == -1 && role == Qt::DisplayRole )
105  return tr( "Actions" );
106  else
107  return QSortFilterProxyModel::headerData( section, orientation, role );
108  }
109  else
110  {
111  if ( role == Qt::DisplayRole )
112  return section + 1;
113  else
114  {
115  int sourceSection = mapToSource( index( section, ( !mColumnMapping.isEmpty() && mColumnMapping.at( 0 ) == -1 ) ? 1 : 0 ) ).row();
116  return sourceModel()->headerData( sourceSection, orientation, role );
117  }
118  }
119 }
120 
122 {
123  return mColumnMapping.indexOf( -1 );
124 }
125 
126 int QgsAttributeTableFilterModel::columnCount( const QModelIndex &parent ) const
127 {
128  Q_UNUSED( parent );
129  return mColumnMapping.count();
130 }
131 
133 {
134  mConfig = config;
135  mConfig.update( layer()->fields() );
136 
137  QVector<int> newColumnMapping;
138 
139  Q_FOREACH ( const QgsAttributeTableConfig::ColumnConfig &columnConfig, mConfig.columns() )
140  {
141  // Hidden? Forget about this column
142  if ( columnConfig.hidden )
143  continue;
144 
145  // The new value for the mapping (field index or -1 for action column)
146  int newValue = ( columnConfig.type == QgsAttributeTableConfig::Action ) ? -1 : layer()->fields().lookupField( columnConfig.name );
147  newColumnMapping << newValue;
148  }
149 
150  if ( newColumnMapping != mColumnMapping )
151  {
152  bool requiresReset = false;
153  int firstRemovedColumn = -1;
154  int removedColumnCount = 0;
155 
156  // Check if there have a contiguous set of columns have been removed or if we require a full reset
157  for ( int i = 0; i < qMin( newColumnMapping.size(), mColumnMapping.size() - removedColumnCount ); ++i )
158  {
159  if ( newColumnMapping.at( i ) == mColumnMapping.at( i + removedColumnCount ) )
160  continue;
161 
162  if ( firstRemovedColumn == -1 )
163  {
164  firstRemovedColumn = i;
165 
166  while ( i < mColumnMapping.size() - removedColumnCount && mColumnMapping.at( i + removedColumnCount ) != newColumnMapping.at( i ) )
167  {
168  ++removedColumnCount;
169  }
170  }
171  else
172  {
173  requiresReset = true;
174  break;
175  }
176  }
177 
178  // No difference found so far
179  if ( firstRemovedColumn == -1 )
180  {
181  if ( newColumnMapping.size() > mColumnMapping.size() )
182  {
183  // More columns: appended to the end
184  beginInsertColumns( QModelIndex(), mColumnMapping.size(), newColumnMapping.size() - 1 );
185  mColumnMapping = newColumnMapping;
186  endInsertColumns();
187  }
188  else
189  {
190  // Less columns: removed from the end
191  beginRemoveColumns( QModelIndex(), newColumnMapping.size(), mColumnMapping.size() - 1 );
192  mColumnMapping = newColumnMapping;
193  endRemoveColumns();
194  }
195  }
196  else
197  {
198  if ( newColumnMapping.size() == mColumnMapping.size() - removedColumnCount )
199  {
200  //the amount of removed column in the model need to be equal removedColumnCount
201  beginRemoveColumns( QModelIndex(), firstRemovedColumn, firstRemovedColumn + removedColumnCount - 1 );
202  mColumnMapping = newColumnMapping;
203  endRemoveColumns();
204  }
205  else
206  {
207  requiresReset = true;
208  }
209  }
210 
211  if ( requiresReset )
212  {
213  beginResetModel();
214  mColumnMapping = newColumnMapping;
215  endResetModel();
216  }
217  }
218 
219  if ( !config.sortExpression().isEmpty() )
220  sort( config.sortExpression(), config.sortOrder() );
221 }
222 
223 void QgsAttributeTableFilterModel::sort( const QString &expression, Qt::SortOrder order )
224 {
225  if ( order != Qt::AscendingOrder && order != Qt::DescendingOrder )
226  order = Qt::AscendingOrder;
227 
228  QSortFilterProxyModel::sort( -1 );
229  masterModel()->prefetchSortData( expression );
230  QSortFilterProxyModel::sort( 0, order ) ;
231 }
232 
234 {
235  return masterModel()->sortCacheExpression();
236 }
237 
239 {
240  if ( mSelectedOnTop != selectedOnTop )
241  {
242  mSelectedOnTop = selectedOnTop;
243  int column = sortColumn();
244  Qt::SortOrder order = sortOrder();
245 
246  // set default sort values if they are not correctly set
247  if ( column < 0 )
248  column = 0;
249 
250  if ( order != Qt::AscendingOrder && order != Qt::DescendingOrder )
251  order = Qt::AscendingOrder;
252 
253  sort( column, order );
254  invalidate();
255  }
256 }
257 
259 {
260  mTableModel = sourceModel;
261 
262  for ( int i = 0; i < mTableModel->columnCount() - mTableModel->extraColumns(); ++i )
263  {
264  mColumnMapping.append( i );
265  }
266 
267  QSortFilterProxyModel::setSourceModel( sourceModel );
268 
269  // Disconnect any code to update columns in the parent, we handle this manually
270  disconnect( mTableModel, SIGNAL( columnsAboutToBeInserted( QModelIndex, int, int ) ), this, SLOT( _q_sourceColumnsAboutToBeInserted( QModelIndex, int, int ) ) );
271  disconnect( mTableModel, SIGNAL( columnsInserted( QModelIndex, int, int ) ), this, SLOT( _q_sourceColumnsInserted( QModelIndex, int, int ) ) );
272  disconnect( mTableModel, SIGNAL( columnsAboutToBeRemoved( QModelIndex, int, int ) ), this, SLOT( _q_sourceColumnsAboutToBeRemoved( QModelIndex, int, int ) ) );
273  disconnect( mTableModel, SIGNAL( columnsRemoved( QModelIndex, int, int ) ), this, SLOT( _q_sourceColumnsRemoved( QModelIndex, int, int ) ) );
274  // The following connections are needed in order to keep the filter model in sync, see: regression #15974
275  connect( mTableModel, &QAbstractItemModel::columnsAboutToBeInserted, this, &QgsAttributeTableFilterModel::onColumnsChanged );
276  connect( mTableModel, &QAbstractItemModel::columnsAboutToBeRemoved, this, &QgsAttributeTableFilterModel::onColumnsChanged );
277 
278 }
279 
281 {
282  return mSelectedOnTop;
283 }
284 
286 {
287  mFilteredFeatures = ids;
289  invalidateFilter();
290 }
291 
293 {
294  QgsFeatureIds ids;
295  ids.reserve( rowCount() );
296  for ( int i = 0; i < rowCount(); ++i )
297  {
298  QModelIndex row = index( i, 0 );
299  ids << rowToId( row );
300  }
301  return ids;
302 }
303 
305 {
306  if ( filterMode != mFilterMode )
307  {
308  if ( filterMode == ShowVisible )
309  {
312  }
313  else
314  {
316  }
317 
318  mFilterMode = filterMode;
319  invalidateFilter();
320  }
321 }
322 
323 bool QgsAttributeTableFilterModel::filterAcceptsRow( int sourceRow, const QModelIndex &sourceParent ) const
324 {
325  Q_UNUSED( sourceParent );
326  switch ( mFilterMode )
327  {
328  case ShowAll:
329  return true;
330 
331  case ShowFilteredList:
332  return mFilteredFeatures.contains( masterModel()->rowToId( sourceRow ) );
333 
334  case ShowSelected:
335  return layer()->selectedFeatureIds().contains( masterModel()->rowToId( sourceRow ) );
336 
337  case ShowVisible:
338  return mFilteredFeatures.contains( masterModel()->rowToId( sourceRow ) );
339 
340  case ShowEdited:
341  {
342  QgsVectorLayerEditBuffer *editBuffer = layer()->editBuffer();
343  if ( editBuffer )
344  {
345  QgsFeatureId fid = masterModel()->rowToId( sourceRow );
346 
347  if ( editBuffer->isFeatureAdded( fid ) )
348  return true;
349 
350  if ( editBuffer->isFeatureAttributesChanged( fid ) )
351  return true;
352 
353  if ( editBuffer->isFeatureGeometryChanged( fid ) )
354  return true;
355 
356  return false;
357  }
358  return false;
359  }
360 
361  default:
362  Q_ASSERT( false ); // In debug mode complain
363  return true; // In release mode accept row
364  }
365  // returns are handled in their respective case statement above
366 }
367 
369 {
371  invalidateFilter();
372 }
373 
374 void QgsAttributeTableFilterModel::selectionChanged()
375 {
376  if ( ShowSelected == mFilterMode )
377  {
378  invalidateFilter();
379  }
380  else if ( mSelectedOnTop )
381  {
382  sort( sortColumn(), sortOrder() );
383  invalidate();
384  }
385 }
386 
387 void QgsAttributeTableFilterModel::onColumnsChanged()
388 {
389  setAttributeTableConfig( mConfig );
390 }
391 
392 int QgsAttributeTableFilterModel::mapColumnToSource( int column ) const
393 {
394  if ( mColumnMapping.isEmpty() )
395  return column;
396  if ( column < 0 || column >= mColumnMapping.size() )
397  return -1;
398  else
399  return mColumnMapping.at( column );
400 }
401 
403 {
404  if ( !layer() )
405  return;
406 
407  bool filter = false;
408  QgsRectangle rect = mCanvas->mapSettings().mapToLayerCoordinates( layer(), mCanvas->extent() );
409  QgsRenderContext renderContext;
411  QgsFeatureRenderer *renderer = layer()->renderer();
412 
413  mFilteredFeatures.clear();
414 
415  if ( !renderer )
416  {
417  QgsDebugMsg( "Cannot get renderer" );
418  return;
419  }
420 
421  const QgsMapSettings &ms = mCanvas->mapSettings();
422  if ( !layer()->isInScaleRange( ms.scale() ) )
423  {
424  QgsDebugMsg( "Out of scale limits" );
425  }
426  else
427  {
428  if ( renderer && renderer->capabilities() & QgsFeatureRenderer::ScaleDependent )
429  {
430  // setup scale
431  // mapRenderer()->renderContext()->scale is not automatically updated when
432  // render extent changes (because it's scale is used to identify if changed
433  // since last render) -> use local context
434  renderContext.setExtent( ms.visibleExtent() );
435  renderContext.setMapToPixel( ms.mapToPixel() );
436  renderContext.setRendererScale( ms.scale() );
437  }
438 
439  filter = renderer && renderer->capabilities() & QgsFeatureRenderer::Filter;
440  }
441 
442  renderer->startRender( renderContext, layer()->fields() );
443 
444  QgsFeatureRequest r( masterModel()->request() );
445  if ( !r.filterRect().isNull() )
446  {
447  r.setFilterRect( r.filterRect().intersect( &rect ) );
448  }
449  else
450  {
451  r.setFilterRect( rect );
452  }
454 
455  QgsFeature f;
456 
457  while ( features.nextFeature( f ) )
458  {
459  renderContext.expressionContext().setFeature( f );
460  if ( !filter || renderer->willRenderFeature( f, renderContext ) )
461  {
462  mFilteredFeatures << f.id();
463  }
464 #if 0
465  if ( t.elapsed() > 5000 )
466  {
467  bool cancel = false;
468  emit progress( i, cancel );
469  if ( cancel )
470  break;
471 
472  t.restart();
473  }
474 #endif
475  }
476 
477  features.close();
478 
479  if ( renderer && renderer->capabilities() & QgsFeatureRenderer::ScaleDependent )
480  {
481  renderer->stopRender( renderContext );
482  }
483 }
484 
486 {
487  return masterModel()->rowToId( mapToSource( row ).row() );
488 }
489 
491 {
492  return mapFromMaster( masterModel()->idToIndex( fid ) );
493 }
494 
496 {
497  QModelIndexList indexes;
498  Q_FOREACH ( const QModelIndex &idx, masterModel()->idToIndexList( fid ) )
499  {
500  indexes.append( mapFromMaster( idx ) );
501  }
502 
503  return indexes;
504 }
505 
506 QModelIndex QgsAttributeTableFilterModel::mapToSource( const QModelIndex &proxyIndex ) const
507 {
508  if ( !proxyIndex.isValid() )
509  return QModelIndex();
510 
511  int sourceColumn = mapColumnToSource( proxyIndex.column() );
512 
513  // For the action column there is no matching column in the source model, just return the first one
514  // so we are still able to query for the feature id, the feature...
515  if ( sourceColumn == -1 )
516  sourceColumn = 0;
517 
518  return QSortFilterProxyModel::mapToSource( index( proxyIndex.row(), sourceColumn, proxyIndex.parent() ) );
519 }
520 
521 QModelIndex QgsAttributeTableFilterModel::mapFromSource( const QModelIndex &sourceIndex ) const
522 {
523  QModelIndex proxyIndex = QSortFilterProxyModel::mapFromSource( sourceIndex );
524 
525  if ( proxyIndex.column() < 0 )
526  return QModelIndex();
527 
528  int col = mapColumnToSource( proxyIndex.column() );
529  if ( col == -1 )
530  col = 0;
531 
532  return index( proxyIndex.row(), col, proxyIndex.parent() );
533 }
534 
535 Qt::ItemFlags QgsAttributeTableFilterModel::flags( const QModelIndex &index ) const
536 {
537  // Handle the action column flags here, the master model doesn't know it
538  if ( mapColumnToSource( index.column() ) == -1 )
539  return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
540 
541  QModelIndex source_index = mapToSource( index );
542  return masterModel()->flags( source_index );
543 }
544 
int lookupField(const QString &fieldName) const
Look up field&#39;s index from the field name.
Definition: qgsfields.cpp:289
virtual bool willRenderFeature(QgsFeature &feat, QgsRenderContext &context)
Returns whether the renderer will render a feature or not.
void generateListOfVisibleFeatures()
Updates the list of currently visible features on the map canvas.
QgsFeatureId id
Definition: qgsfeature.h:70
QgsFeatureId rowToId(const QModelIndex &row)
Returns the feature id for a given model index.
QgsVectorLayer * layer() const
Returns the layer this filter acts on.
Wrapper for iterator of features from vector data provider or vector layer.
virtual QVariant data(const QModelIndex &index, int role) const override
QgsAttributeTableConfig::Type type
The type of this column.
int extraColumns() const
Empty extra columns to announce from this model.
A rectangle specified with double values.
Definition: qgsrectangle.h:38
Depends on scale if feature will be rendered (rule based )
Definition: qgsrenderer.h:224
void update(const QgsFields &fields)
Update the configuration with the given fields.
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override
Returns true if the source row will be accepted.
bool selectedOnTop()
Returns if selected features are currently shown on top.
void setAttributeTableConfig(const QgsAttributeTableConfig &config)
Set the attribute table configuration to control which fields are shown, in which order they are show...
QgsAttributeTableModel * masterModel() const
Returns the table model this filter is using.
void setSelectedOnTop(bool selectedOnTop)
Changes the sort order of the features.
void setFilterMode(FilterMode filterMode)
Set the filter mode the filter will use.
QModelIndex mapFromMaster(const QModelIndex &sourceIndex) const
QVariant headerData(int section, Qt::Orientation orientation, int role) const override
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
#define QgsDebugMsg(str)
Definition: qgslogger.h:37
QSet< QgsFeatureId > QgsFeatureIds
Definition: qgsfeature.h:519
Features may be filtered, i.e. some features may not be rendered (categorized, rule based ...
Definition: qgsrenderer.h:223
void setRendererScale(double scale)
Sets the renderer map scale.
bool lessThan(const QModelIndex &left, const QModelIndex &right) const override
Used by the sorting algorithm.
virtual QModelIndex mapToSource(const QModelIndex &proxyIndex) const override
QgsRectangle intersect(const QgsRectangle *rect) const
Return the intersection with the given rectangle.
This column represents an action widget.
bool isFeatureAdded(QgsFeatureId id) const
Returns true if the specified feature ID has been added but not committed.
virtual QModelIndex mapFromSource(const QModelIndex &sourceIndex) const override
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:61
A model backed by a QgsVectorLayerCache which is able to provide feature/attribute information to a Q...
Show only visible features (depends on the map canvas)
const QgsRectangle & filterRect() const
Returns the rectangle from which features will be taken.
void setExtent(const QgsRectangle &extent)
QgsRectangle visibleExtent() const
Return the actual extent derived from requested extent that takes takes output image size into accoun...
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:73
bool qgsVariantLessThan(const QVariant &lhs, const QVariant &rhs)
Compares two QVariant values and returns whether the first is less than the second.
Definition: qgis.cpp:136
virtual void setFilteredFeatures(const QgsFeatureIds &ids)
Specify a list of features, which the filter will accept.
The QgsMapSettings class contains configuration for rendering of the map.
Get the feature id of the feature in this row.
int actionColumnIndex() const
Get the index of the first column that contains an action widget.
virtual void startRender(QgsRenderContext &context, const QgsFields &fields)=0
Needs to be called when a new render cycle is started.
QgsVectorLayerEditBuffer * editBuffer()
Buffer with uncommitted editing operations. Only valid after editing has been turned on...
FilterMode filterMode()
The current filterModel.
const QgsFeatureIds & selectedFeatureIds() const
Return reference to identifiers of selected features.
QgsFields fields() const override
Returns the list of fields of this layer.
QgsAttributeTableFilterModel(QgsMapCanvas *canvas, QgsAttributeTableModel *sourceModel, QObject *parent=0)
Make sure, the master model is already loaded, so the selection will get synchronized.
int columnCount(const QModelIndex &parent=QModelIndex()) const override
Returns the number of columns.
FilterMode
The filter mode defines how the rows should be filtered.
double scale() const
Returns the calculated map scale.
void selectionChanged(const QgsFeatureIds &selected, const QgsFeatureIds &deselected, const bool clearAndSelect)
This signal is emitted when selection was changed.
QgsRectangle extent() const
Returns the current zoom extent of the map canvas.
bool hidden
Flag that controls if the column is hidden.
This class wraps a request for features to a vector layer (or directly its vector data provider)...
QgsVectorLayerCache * layerCache() const
Returns the layer cache this model uses as backend.
QgsFeatureRequest & setFilterRect(const QgsRectangle &rectangle)
Sets the rectangle from which features will be taken.
QgsFeatureRenderer * renderer()
Return renderer.
Show only features which have unsaved changes.
static QList< QgsExpressionContextScope * > globalProjectLayerScopes(const QgsMapLayer *layer)
Creates a list of three scopes: global, layer&#39;s project and layer.
bool isFeatureAttributesChanged(QgsFeatureId id) const
Returns true if the specified feature ID has had an attribute changed but not committed.
const QgsMapToPixel & mapToPixel() const
QString name
The name of the attribute if this column represents a field.
void setSourceModel(QgsAttributeTableModel *sourceModel)
Set the attribute table model that backs this model.
void extentsChanged()
Is called upon every change of the visible extents on the map canvas.
QString sortExpression() const
The expression which is used to sort the attribute table.
QgsExpressionContext & expressionContext()
Gets the expression context.
Show only features whose ids are on the filter list. {.
QVector< QgsAttributeTableConfig::ColumnConfig > columns() const
Get the list with all columns and their configuration.
const QgsMapSettings & mapSettings() const
Get access to properties used for map rendering.
Contains information about the context of a rendering operation.
virtual void stopRender(QgsRenderContext &context)=0
Needs to be called when a render cycle has finished to clean up.
virtual void sort(int column, Qt::SortOrder order=Qt::AscendingOrder) override
Sort by the given column using the given order.
int columnCount(const QModelIndex &parent) const override
void setMapToPixel(const QgsMapToPixel &mtp)
bool isNull() const
Test if the rectangle is null (all coordinates zero or after call to setMinimal()).
Defines the configuration of a column in the attribute table.
QgsFeatureId rowToId(int row) const
Maps row to feature id.
qint64 QgsFeatureId
Definition: qgsfeature.h:37
QString sortCacheExpression() const
The expression which was used to fill the sorting cache.
QgsFeatureIds filteredFeatures()
Get a list of currently filtered feature ids.
void appendScopes(const QList< QgsExpressionContextScope *> &scopes)
Appends a list of scopes to the end of the context.
bool nextFeature(QgsFeature &f)
This is a container for configuration of the attribute table.
Qt::SortOrder sortOrder() const
Get the sort order.
QgsPointXY mapToLayerCoordinates(const QgsMapLayer *layer, QgsPointXY point) const
transform point coordinates from output CRS to layer&#39;s CRS
QString sortExpression() const
Get the expression used for sorting.
void sortColumnChanged(int column, Qt::SortOrder order)
Is emitted whenever the sort column is changed.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &featureRequest=QgsFeatureRequest())
Query this VectorLayerCache for features.
QModelIndexList fidToIndexList(QgsFeatureId fid)
void extentsChanged()
Emitted when the extents of the map change.
void prefetchColumnData(int column)
Caches the entire data for one column.
virtual QgsFeatureRenderer::Capabilities capabilities()
Returns details about internals of this renderer.
Definition: qgsrenderer.h:241
void prefetchSortData(const QString &expression)
Prefetches the entire data for one expression.
Qt::ItemFlags flags(const QModelIndex &index) const override
Returns item flags for the index.
QModelIndex fidToIndex(QgsFeatureId fid) override
virtual Qt::ItemFlags flags(const QModelIndex &index) const override
bool isFeatureGeometryChanged(QgsFeatureId id) const
Returns true if the specified feature ID has had its geometry changed but not committed.