QGIS API Documentation  3.2.0-Bonn (bc43194)
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 {
36  setSourceModel( sourceModel );
37  setDynamicSortFilter( true );
38  setSortRole( QgsAttributeTableModel::SortRole );
39  connect( layer(), &QgsVectorLayer::selectionChanged, this, &QgsAttributeTableFilterModel::selectionChanged );
40 }
41 
42 bool QgsAttributeTableFilterModel::lessThan( const QModelIndex &left, const QModelIndex &right ) const
43 {
44  if ( mSelectedOnTop )
45  {
46  bool leftSelected = layer()->selectedFeatureIds().contains( masterModel()->rowToId( left.row() ) );
47  bool rightSelected = layer()->selectedFeatureIds().contains( masterModel()->rowToId( right.row() ) );
48 
49  if ( leftSelected && !rightSelected )
50  {
51  return sortOrder() == Qt::AscendingOrder;
52  }
53  else if ( rightSelected && !leftSelected )
54  {
55  return sortOrder() == Qt::DescendingOrder;
56  }
57  }
58 
59  if ( mTableModel->sortCacheExpression().isEmpty() )
60  {
61  //shortcut when no sort order set
62  return false;
63  }
64 
66  right.data( QgsAttributeTableModel::SortRole ) );
67 }
68 
69 void QgsAttributeTableFilterModel::sort( int column, Qt::SortOrder order )
70 {
71  if ( order != Qt::AscendingOrder && order != Qt::DescendingOrder )
72  order = Qt::AscendingOrder;
73 
74  int myColumn = mColumnMapping.at( column );
75  masterModel()->prefetchColumnData( myColumn );
76  QSortFilterProxyModel::sort( myColumn, order );
77  emit sortColumnChanged( column, order );
78 }
79 
80 QVariant QgsAttributeTableFilterModel::data( const QModelIndex &index, int role ) const
81 {
82  if ( mapColumnToSource( index.column() ) == -1 ) // actions
83  {
84  if ( role == TypeRole )
86  else if ( role == QgsAttributeTableModel::FeatureIdRole )
87  {
88  QModelIndex fieldIndex = QSortFilterProxyModel::mapToSource( QSortFilterProxyModel::index( index.row(), 0, index.parent() ) );
89  return sourceModel()->data( fieldIndex, QgsAttributeTableModel::FeatureIdRole );
90  }
91  }
92  else if ( role == TypeRole )
93  return ColumnTypeField;
94 
95  return QSortFilterProxyModel::data( index, role );
96 }
97 
98 QVariant QgsAttributeTableFilterModel::headerData( int section, Qt::Orientation orientation, int role ) const
99 {
100  if ( orientation == Qt::Horizontal )
101  {
102  if ( mColumnMapping.at( section ) == -1 && role == Qt::DisplayRole )
103  return tr( "Actions" );
104  else
105  return QSortFilterProxyModel::headerData( section, orientation, role );
106  }
107  else
108  {
109  if ( role == Qt::DisplayRole )
110  return section + 1;
111  else
112  {
113  int sourceSection = mapToSource( index( section, ( !mColumnMapping.isEmpty() && mColumnMapping.at( 0 ) == -1 ) ? 1 : 0 ) ).row();
114  return sourceModel()->headerData( sourceSection, orientation, role );
115  }
116  }
117 }
118 
120 {
121  return mColumnMapping.indexOf( -1 );
122 }
123 
124 int QgsAttributeTableFilterModel::columnCount( const QModelIndex &parent ) const
125 {
126  Q_UNUSED( parent );
127  return mColumnMapping.count();
128 }
129 
131 {
132  QgsAttributeTableConfig oldConfig = mConfig;
133  mConfig = config;
134  mConfig.update( layer()->fields() );
135 
136  if ( mConfig.hasSameColumns( oldConfig ) )
137  {
138  return;
139  }
140 
141  QVector<int> newColumnMapping;
142  Q_FOREACH ( const QgsAttributeTableConfig::ColumnConfig &columnConfig, mConfig.columns() )
143  {
144  // Hidden? Forget about this column
145  if ( columnConfig.hidden )
146  continue;
147 
148  // The new value for the mapping (field index or -1 for action column)
149  int newValue = ( columnConfig.type == QgsAttributeTableConfig::Action ) ? -1 : layer()->fields().lookupField( columnConfig.name );
150  newColumnMapping << newValue;
151  }
152 
153  if ( newColumnMapping != mColumnMapping )
154  {
155  bool requiresReset = false;
156  int firstRemovedColumn = -1;
157  int removedColumnCount = 0;
158 
159  // Check if there have a contiguous set of columns have been removed or if we require a full reset
160  for ( int i = 0; i < std::min( newColumnMapping.size(), mColumnMapping.size() - removedColumnCount ); ++i )
161  {
162  if ( newColumnMapping.at( i ) == mColumnMapping.at( i + removedColumnCount ) )
163  continue;
164 
165  if ( firstRemovedColumn == -1 )
166  {
167  firstRemovedColumn = i;
168 
169  while ( i < mColumnMapping.size() - removedColumnCount && mColumnMapping.at( i + removedColumnCount ) != newColumnMapping.at( i ) )
170  {
171  ++removedColumnCount;
172  }
173  }
174  else
175  {
176  requiresReset = true;
177  break;
178  }
179  }
180 
181  // No difference found so far
182  if ( firstRemovedColumn == -1 )
183  {
184  if ( newColumnMapping.size() > mColumnMapping.size() )
185  {
186  // More columns: appended to the end
187  beginInsertColumns( QModelIndex(), mColumnMapping.size(), newColumnMapping.size() - 1 );
188  mColumnMapping = newColumnMapping;
189  endInsertColumns();
190  }
191  else
192  {
193  // Less columns: removed from the end
194  beginRemoveColumns( QModelIndex(), newColumnMapping.size(), mColumnMapping.size() - 1 );
195  mColumnMapping = newColumnMapping;
196  endRemoveColumns();
197  }
198  }
199  else
200  {
201  if ( newColumnMapping.size() == mColumnMapping.size() - removedColumnCount )
202  {
203  //the amount of removed column in the model need to be equal removedColumnCount
204  beginRemoveColumns( QModelIndex(), firstRemovedColumn, firstRemovedColumn + removedColumnCount - 1 );
205  mColumnMapping = newColumnMapping;
206  endRemoveColumns();
207  }
208  else
209  {
210  requiresReset = true;
211  }
212  }
213 
214  if ( requiresReset )
215  {
216  beginResetModel();
217  mColumnMapping = newColumnMapping;
218  endResetModel();
219  }
220  }
221 
222  if ( !config.sortExpression().isEmpty() )
223  sort( config.sortExpression(), config.sortOrder() );
224 }
225 
226 void QgsAttributeTableFilterModel::sort( const QString &expression, Qt::SortOrder order )
227 {
228  if ( order != Qt::AscendingOrder && order != Qt::DescendingOrder )
229  order = Qt::AscendingOrder;
230 
231  QSortFilterProxyModel::sort( -1 );
232  masterModel()->prefetchSortData( expression );
233  QSortFilterProxyModel::sort( 0, order );
234 }
235 
237 {
238  return masterModel()->sortCacheExpression();
239 }
240 
242 {
243  if ( mSelectedOnTop != selectedOnTop )
244  {
245  mSelectedOnTop = selectedOnTop;
246  int column = sortColumn();
247  Qt::SortOrder order = sortOrder();
248 
249  // set default sort values if they are not correctly set
250  if ( column < 0 )
251  column = 0;
252 
253  if ( order != Qt::AscendingOrder && order != Qt::DescendingOrder )
254  order = Qt::AscendingOrder;
255 
256  sort( column, order );
257  invalidate();
258  }
259 }
260 
262 {
263  mTableModel = sourceModel;
264 
265  for ( int i = 0; i < mTableModel->columnCount() - mTableModel->extraColumns(); ++i )
266  {
267  mColumnMapping.append( i );
268  }
269 
270  QSortFilterProxyModel::setSourceModel( sourceModel );
271 
272  // Disconnect any code to update columns in the parent, we handle this manually
273  disconnect( mTableModel, SIGNAL( columnsAboutToBeInserted( QModelIndex, int, int ) ), this, SLOT( _q_sourceColumnsAboutToBeInserted( QModelIndex, int, int ) ) );
274  disconnect( mTableModel, SIGNAL( columnsInserted( QModelIndex, int, int ) ), this, SLOT( _q_sourceColumnsInserted( QModelIndex, int, int ) ) );
275  disconnect( mTableModel, SIGNAL( columnsAboutToBeRemoved( QModelIndex, int, int ) ), this, SLOT( _q_sourceColumnsAboutToBeRemoved( QModelIndex, int, int ) ) );
276  disconnect( mTableModel, SIGNAL( columnsRemoved( QModelIndex, int, int ) ), this, SLOT( _q_sourceColumnsRemoved( QModelIndex, int, int ) ) );
277  // The following connections are needed in order to keep the filter model in sync, see: regression #15974
278  connect( mTableModel, &QAbstractItemModel::columnsAboutToBeInserted, this, &QgsAttributeTableFilterModel::onColumnsChanged );
279  connect( mTableModel, &QAbstractItemModel::columnsAboutToBeRemoved, this, &QgsAttributeTableFilterModel::onColumnsChanged );
280 
281 }
282 
284 {
285  return mSelectedOnTop;
286 }
287 
289 {
290  mFilteredFeatures = ids;
292  invalidateFilter();
293 }
294 
296 {
297  QgsFeatureIds ids;
298  ids.reserve( rowCount() );
299  for ( int i = 0; i < rowCount(); ++i )
300  {
301  QModelIndex row = index( i, 0 );
302  ids << rowToId( row );
303  }
304  return ids;
305 }
306 
308 {
309  if ( filterMode != mFilterMode )
310  {
311  if ( filterMode == ShowVisible )
312  {
315  }
316  else
317  {
319  }
320 
321  mFilterMode = filterMode;
322  invalidateFilter();
323  }
324 }
325 
326 bool QgsAttributeTableFilterModel::filterAcceptsRow( int sourceRow, const QModelIndex &sourceParent ) const
327 {
328  Q_UNUSED( sourceParent );
329  switch ( mFilterMode )
330  {
331  case ShowAll:
332  return true;
333 
334  case ShowFilteredList:
335  return mFilteredFeatures.contains( masterModel()->rowToId( sourceRow ) );
336 
337  case ShowSelected:
338  return layer()->selectedFeatureIds().contains( masterModel()->rowToId( sourceRow ) );
339 
340  case ShowVisible:
341  return mFilteredFeatures.contains( masterModel()->rowToId( sourceRow ) );
342 
343  case ShowEdited:
344  {
345  QgsVectorLayerEditBuffer *editBuffer = layer()->editBuffer();
346  if ( editBuffer )
347  {
348  QgsFeatureId fid = masterModel()->rowToId( sourceRow );
349 
350  if ( editBuffer->isFeatureAdded( fid ) )
351  return true;
352 
353  if ( editBuffer->isFeatureAttributesChanged( fid ) )
354  return true;
355 
356  if ( editBuffer->isFeatureGeometryChanged( fid ) )
357  return true;
358 
359  return false;
360  }
361  return false;
362  }
363 
364  default:
365  Q_ASSERT( false ); // In debug mode complain
366  return true; // In release mode accept row
367  }
368  // returns are handled in their respective case statement above
369 }
370 
372 {
374  invalidateFilter();
375 }
376 
377 void QgsAttributeTableFilterModel::selectionChanged()
378 {
379  if ( ShowSelected == mFilterMode )
380  {
381  invalidateFilter();
382  }
383  else if ( mSelectedOnTop )
384  {
385  sort( sortColumn(), sortOrder() );
386  invalidate();
387  }
388 }
389 
390 void QgsAttributeTableFilterModel::onColumnsChanged()
391 {
392  setAttributeTableConfig( mConfig );
393 }
394 
395 int QgsAttributeTableFilterModel::mapColumnToSource( int column ) const
396 {
397  if ( mColumnMapping.isEmpty() )
398  return column;
399  if ( column < 0 || column >= mColumnMapping.size() )
400  return -1;
401  else
402  return mColumnMapping.at( column );
403 }
404 
406 {
407  if ( !layer() )
408  return;
409 
410  bool filter = false;
411  QgsRectangle rect = mCanvas->mapSettings().mapToLayerCoordinates( layer(), mCanvas->extent() );
412  QgsRenderContext renderContext;
414 
415  mFilteredFeatures.clear();
416  if ( !layer()->renderer() )
417  {
418  QgsDebugMsg( "Cannot get renderer" );
419  return;
420  }
421 
422  std::unique_ptr< QgsFeatureRenderer > renderer( layer()->renderer()->clone() );
423 
424  const QgsMapSettings &ms = mCanvas->mapSettings();
425  if ( !layer()->isInScaleRange( ms.scale() ) )
426  {
427  QgsDebugMsg( "Out of scale limits" );
428  }
429  else
430  {
431  if ( renderer->capabilities() & QgsFeatureRenderer::ScaleDependent )
432  {
433  // setup scale
434  // mapRenderer()->renderContext()->scale is not automatically updated when
435  // render extent changes (because it's scale is used to identify if changed
436  // since last render) -> use local context
437  renderContext.setExtent( ms.visibleExtent() );
438  renderContext.setMapToPixel( ms.mapToPixel() );
439  renderContext.setRendererScale( ms.scale() );
440  }
441 
442  filter = renderer->capabilities() & QgsFeatureRenderer::Filter;
443  }
444 
445  renderer->startRender( renderContext, layer()->fields() );
446 
447  QgsFeatureRequest r( masterModel()->request() );
448  if ( !r.filterRect().isNull() )
449  {
450  r.setFilterRect( r.filterRect().intersect( rect ) );
451  }
452  else
453  {
454  r.setFilterRect( rect );
455  }
457 
458  QgsFeature f;
459 
460  while ( features.nextFeature( f ) )
461  {
462  renderContext.expressionContext().setFeature( f );
463  if ( !filter || renderer->willRenderFeature( f, renderContext ) )
464  {
465  mFilteredFeatures << f.id();
466  }
467 #if 0
468  if ( t.elapsed() > 5000 )
469  {
470  bool cancel = false;
471  emit progress( i, cancel );
472  if ( cancel )
473  break;
474 
475  t.restart();
476  }
477 #endif
478  }
479 
480  features.close();
481 
482  if ( renderer->capabilities() & QgsFeatureRenderer::ScaleDependent )
483  {
484  renderer->stopRender( renderContext );
485  }
486 }
487 
489 {
490  return masterModel()->rowToId( mapToSource( row ).row() );
491 }
492 
494 {
495  return mapFromMaster( masterModel()->idToIndex( fid ) );
496 }
497 
499 {
500  QModelIndexList indexes;
501  Q_FOREACH ( const QModelIndex &idx, masterModel()->idToIndexList( fid ) )
502  {
503  indexes.append( mapFromMaster( idx ) );
504  }
505 
506  return indexes;
507 }
508 
509 QModelIndex QgsAttributeTableFilterModel::mapToSource( const QModelIndex &proxyIndex ) const
510 {
511  if ( !proxyIndex.isValid() )
512  return QModelIndex();
513 
514  int sourceColumn = mapColumnToSource( proxyIndex.column() );
515 
516  // For the action column there is no matching column in the source model, just return the first one
517  // so we are still able to query for the feature id, the feature...
518  if ( sourceColumn == -1 )
519  sourceColumn = 0;
520 
521  return QSortFilterProxyModel::mapToSource( index( proxyIndex.row(), sourceColumn, proxyIndex.parent() ) );
522 }
523 
524 QModelIndex QgsAttributeTableFilterModel::mapFromSource( const QModelIndex &sourceIndex ) const
525 {
526  QModelIndex proxyIndex = QSortFilterProxyModel::mapFromSource( sourceIndex );
527 
528  if ( proxyIndex.column() < 0 )
529  return QModelIndex();
530 
531  int col = mapColumnToSource( proxyIndex.column() );
532  if ( col == -1 )
533  col = 0;
534 
535  return index( proxyIndex.row(), col, proxyIndex.parent() );
536 }
537 
538 Qt::ItemFlags QgsAttributeTableFilterModel::flags( const QModelIndex &index ) const
539 {
540  // Handle the action column flags here, the master model doesn't know it
541  if ( mapColumnToSource( index.column() ) == -1 )
542  return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
543 
544  QModelIndex source_index = mapToSource( index );
545  return masterModel()->flags( source_index );
546 }
547 
int lookupField(const QString &fieldName) const
Look up field&#39;s index from the field name.
Definition: qgsfields.cpp:299
void generateListOfVisibleFeatures()
Updates the list of currently visible features on the map canvas.
QgsFeatureId id
Definition: qgsfeature.h:71
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.
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:40
Depends on scale if feature will be rendered (rule based )
Definition: qgsrenderer.h:245
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:38
QSet< QgsFeatureId > QgsFeatureIds
Definition: qgsfeature.h:544
Features may be filtered, i.e. some features may not be rendered (categorized, rule based ...
Definition: qgsrenderer.h:244
QString sortCacheExpression(unsigned long cacheIndex=0) const
The expression which was used to fill the sorting cache at index cacheIndex.
void setRendererScale(double scale)
Sets the renderer map scale.
void prefetchSortData(const QString &expression, unsigned long cacheIndex=0)
Prefetches the entire data for an expression.
bool lessThan(const QModelIndex &left, const QModelIndex &right) const override
Used by the sorting algorithm.
QModelIndex mapToSource(const QModelIndex &proxyIndex) const override
This column represents an action widget.
bool isFeatureAdded(QgsFeatureId id) const
Returns true if the specified feature ID has been added but not committed.
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:62
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
Returns the actual extent derived from requested extent that takes takes output image size into accou...
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:74
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:146
QgsAttributeTableFilterModel(QgsMapCanvas *canvas, QgsAttributeTableModel *sourceModel, QObject *parent=nullptr)
Make sure, the master model is already loaded, so the selection will get synchronized.
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
Gets the index of the first column that contains an action widget.
Roles used for sorting start here.
QgsVectorLayerEditBuffer * editBuffer()
Buffer with uncommitted editing operations. Only valid after editing has been turned on...
FilterMode filterMode()
The current filterModel.
const QgsFeatureIds & selectedFeatureIds() const
Returns a list of the selected features IDs in this layer.
QgsFields fields() const override
Returns the list of fields of this layer.
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.
QgsRectangle intersect(const QgsRectangle &rect) const
Returns the intersection with the given rectangle.
Definition: qgsrectangle.h:305
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.
void selectionChanged(const QgsFeatureIds &selected, const QgsFeatureIds &deselected, bool clearAndSelect)
This signal is emitted when selection was changed.
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
Gets the list with all columns and their configuration.
const QgsMapSettings & mapSettings() const
Gets access to properties used for map rendering.
Contains information about the context of a rendering operation.
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()).
Definition: qgsrectangle.h:429
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
QgsFeatureIds filteredFeatures()
Gets 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
Gets 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
Gets 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.
bool hasSameColumns(const QgsAttributeTableConfig &other) const
Compare this configuration&#39;s columns name, type, and order to other.
void prefetchColumnData(int column)
Caches the entire data for one column.
Qt::ItemFlags flags(const QModelIndex &index) const override
Returns item flags for the index.
QModelIndex fidToIndex(QgsFeatureId fid) override
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.