QGIS API Documentation  3.17.0-Master (a035f434f4)
qgsattributetableview.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  QgsAttributeTableView.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 <QKeyEvent>
17 #include <QHeaderView>
18 #include <QMenu>
19 #include <QToolButton>
20 #include <QHBoxLayout>
21 
22 #include "qgssettings.h"
23 #include "qgsactionmanager.h"
24 #include "qgsattributetableview.h"
25 #include "qgsattributetablemodel.h"
28 #include "qgsvectorlayer.h"
29 #include "qgsvectorlayercache.h"
31 #include "qgsvectordataprovider.h"
32 #include "qgslogger.h"
33 #include "qgsmapcanvas.h"
36 #include "qgsfeatureiterator.h"
37 #include "qgsgui.h"
38 
40  : QTableView( parent )
41 {
42  QgsSettings settings;
43  restoreGeometry( settings.value( QStringLiteral( "BetterAttributeTable/geometry" ) ).toByteArray() );
44 
45  //verticalHeader()->setDefaultSectionSize( 20 );
46  horizontalHeader()->setHighlightSections( false );
47 
48  // We need mouse move events to create the action button on hover
49  mTableDelegate = new QgsAttributeTableDelegate( this );
50  setItemDelegate( mTableDelegate );
51 
52  setEditTriggers( QAbstractItemView::AllEditTriggers );
53 
54  setSelectionBehavior( QAbstractItemView::SelectRows );
55  setSelectionMode( QAbstractItemView::ExtendedSelection );
56  setSortingEnabled( true ); // At this point no data is in the model yet, so actually nothing is sorted.
57  horizontalHeader()->setSortIndicatorShown( false ); // So hide the indicator to avoid confusion.
58 
59  setHorizontalScrollMode( QAbstractItemView::ScrollPerPixel );
60 
61  verticalHeader()->viewport()->installEventFilter( this );
62 
63  connect( verticalHeader(), &QHeaderView::sectionPressed, this, [ = ]( int row ) { selectRow( row, true ); } );
64  connect( verticalHeader(), &QHeaderView::sectionEntered, this, &QgsAttributeTableView::_q_selectRow );
65  connect( horizontalHeader(), &QHeaderView::sectionResized, this, &QgsAttributeTableView::columnSizeChanged );
66  connect( horizontalHeader(), &QHeaderView::sortIndicatorChanged, this, &QgsAttributeTableView::showHorizontalSortIndicator );
67  connect( QgsGui::mapLayerActionRegistry(), &QgsMapLayerActionRegistry::changed, this, &QgsAttributeTableView::recreateActionWidgets );
68 }
69 
70 bool QgsAttributeTableView::eventFilter( QObject *object, QEvent *event )
71 {
72  if ( object == verticalHeader()->viewport() )
73  {
74  switch ( event->type() )
75  {
76  case QEvent::MouseButtonPress:
77  mFeatureSelectionModel->enableSync( false );
78  break;
79 
80  case QEvent::MouseButtonRelease:
81  mFeatureSelectionModel->enableSync( true );
82  break;
83 
84  default:
85  break;
86  }
87  }
88  return QTableView::eventFilter( object, event );
89 }
90 
92 {
93  int i = 0;
94  const auto constColumns = config.columns();
95  for ( const QgsAttributeTableConfig::ColumnConfig &columnConfig : constColumns )
96  {
97  if ( columnConfig.hidden )
98  continue;
99 
100  if ( columnConfig.width >= 0 )
101  {
102  setColumnWidth( i, columnConfig.width );
103  }
104  else
105  {
106  setColumnWidth( i, horizontalHeader()->defaultSectionSize() );
107  }
108  i++;
109  }
110  mConfig = config;
111  if ( config.sortExpression().isEmpty() )
112  horizontalHeader()->setSortIndicatorShown( false );
113 }
114 
116 {
117  // In order to get the ids in the right sorted order based on the view we have to get the feature ids first
118  // from the selection manager which is in the order the user selected them when clicking
119  // then get the model index, sort that, and finally return the new sorted features ids.
120  const QgsFeatureIds featureIds = mFeatureSelectionManager->selectedFeatureIds();
121  QModelIndexList indexList;
122  for ( const QgsFeatureId &id : featureIds )
123  {
124  QModelIndex index = mFilterModel->fidToIndex( id );
125  indexList << index;
126  }
127 
128  std::sort( indexList.begin(), indexList.end() );
129  QList<QgsFeatureId> ids;
130  for ( const QModelIndex &index : indexList )
131  {
132  QgsFeatureId id = mFilterModel->data( index, QgsAttributeTableModel::FeatureIdRole ).toLongLong();
133  ids.append( id );
134  }
135  return ids;
136 }
137 
139 {
140  mFilterModel = filterModel;
141  QTableView::setModel( mFilterModel );
142 
143  if ( mFilterModel )
144  {
145  connect( mFilterModel, &QObject::destroyed, this, &QgsAttributeTableView::modelDeleted );
146  connect( mTableDelegate, &QgsAttributeTableDelegate::actionColumnItemPainted, this, &QgsAttributeTableView::onActionColumnItemPainted );
147  }
148 
149  delete mFeatureSelectionModel;
150  mFeatureSelectionModel = nullptr;
151 
152  if ( mFilterModel )
153  {
154  if ( !mFeatureSelectionManager )
155  {
156  mOwnedFeatureSelectionManager = new QgsVectorLayerSelectionManager( mFilterModel->layer(), this );
157  mFeatureSelectionManager = mOwnedFeatureSelectionManager;
158  }
159 
160  mFeatureSelectionModel = new QgsFeatureSelectionModel( mFilterModel, mFilterModel, mFeatureSelectionManager, mFilterModel );
161  setSelectionModel( mFeatureSelectionModel );
162  mTableDelegate->setFeatureSelectionModel( mFeatureSelectionModel );
163  connect( mFeatureSelectionModel, static_cast<void ( QgsFeatureSelectionModel::* )( const QModelIndexList &indexes )>( &QgsFeatureSelectionModel::requestRepaint ),
164  this, static_cast<void ( QgsAttributeTableView::* )( const QModelIndexList &indexes )>( &QgsAttributeTableView::repaintRequested ) );
165  connect( mFeatureSelectionModel, static_cast<void ( QgsFeatureSelectionModel::* )()>( &QgsFeatureSelectionModel::requestRepaint ),
166  this, static_cast<void ( QgsAttributeTableView::* )()>( &QgsAttributeTableView::repaintRequested ) );
167 
168  connect( mFilterModel->layer(), &QgsVectorLayer::editingStarted, this, &QgsAttributeTableView::recreateActionWidgets );
169  connect( mFilterModel->layer(), &QgsVectorLayer::editingStopped, this, &QgsAttributeTableView::recreateActionWidgets );
170  connect( mFilterModel->layer(), &QgsVectorLayer::readOnlyChanged, this, &QgsAttributeTableView::recreateActionWidgets );
171  }
172 }
173 
175 {
176  mFeatureSelectionManager = featureSelectionManager;
177 
178  if ( mFeatureSelectionModel )
179  mFeatureSelectionModel->setFeatureSelectionManager( mFeatureSelectionManager );
180 
181  // only delete the owner selection manager and not one created from outside
182  if ( mOwnedFeatureSelectionManager )
183  {
184  mOwnedFeatureSelectionManager->deleteLater();
185  mOwnedFeatureSelectionManager = nullptr;
186  }
187 }
188 
189 QWidget *QgsAttributeTableView::createActionWidget( QgsFeatureId fid )
190 {
191  QgsAttributeTableConfig attributeTableConfig = mConfig;
192 
193  QToolButton *toolButton = nullptr;
194  QWidget *container = nullptr;
195 
196  if ( attributeTableConfig.actionWidgetStyle() == QgsAttributeTableConfig::DropDown )
197  {
198  toolButton = new QToolButton();
199  toolButton->setToolButtonStyle( Qt::ToolButtonTextBesideIcon );
200  toolButton->setPopupMode( QToolButton::MenuButtonPopup );
201  container = toolButton;
202  }
203  else
204  {
205  container = new QWidget();
206  container->setLayout( new QHBoxLayout() );
207  container->layout()->setContentsMargins( 0, 0, 0, 0 );
208  }
209 
210  QList< QAction * > actionList;
211  QAction *defaultAction = nullptr;
212 
213  // first add user created layer actions
214  QList<QgsAction> actions = mFilterModel->layer()->actions()->actions( QStringLiteral( "Feature" ) );
215  const auto constActions = actions;
216  for ( const QgsAction &action : constActions )
217  {
218  if ( !mFilterModel->layer()->isEditable() && action.isEnabledOnlyWhenEditable() )
219  continue;
220 
221  QString actionTitle = !action.shortTitle().isEmpty() ? action.shortTitle() : action.icon().isNull() ? action.name() : QString();
222  QAction *act = new QAction( action.icon(), actionTitle, container );
223  act->setToolTip( action.name() );
224  act->setData( "user_action" );
225  act->setProperty( "fid", fid );
226  act->setProperty( "action_id", action.id() );
227  connect( act, &QAction::triggered, this, &QgsAttributeTableView::actionTriggered );
228  actionList << act;
229 
230  if ( mFilterModel->layer()->actions()->defaultAction( QStringLiteral( "Feature" ) ).id() == action.id() )
231  defaultAction = act;
232  }
233 
234  const auto mapLayerActions {QgsGui::mapLayerActionRegistry()->mapLayerActions( mFilterModel->layer(), QgsMapLayerAction::SingleFeature ) };
235  // next add any registered actions for this layer
236  for ( QgsMapLayerAction *mapLayerAction : mapLayerActions )
237  {
238  QAction *action = new QAction( mapLayerAction->icon(), mapLayerAction->text(), container );
239  action->setData( "map_layer_action" );
240  action->setToolTip( mapLayerAction->text() );
241  action->setProperty( "fid", fid );
242  action->setProperty( "action", QVariant::fromValue( qobject_cast<QObject *>( mapLayerAction ) ) );
243  connect( action, &QAction::triggered, this, &QgsAttributeTableView::actionTriggered );
244  actionList << action;
245 
246  if ( !defaultAction &&
247  QgsGui::mapLayerActionRegistry()->defaultActionForLayer( mFilterModel->layer() ) == mapLayerAction )
248  defaultAction = action;
249  }
250 
251  if ( !defaultAction && !actionList.isEmpty() )
252  defaultAction = actionList.at( 0 );
253 
254  const auto constActionList = actionList;
255  for ( QAction *act : constActionList )
256  {
257  if ( attributeTableConfig.actionWidgetStyle() == QgsAttributeTableConfig::DropDown )
258  {
259  toolButton->addAction( act );
260 
261  if ( act == defaultAction )
262  toolButton->setDefaultAction( act );
263 
264  container = toolButton;
265  }
266  else
267  {
268  QToolButton *btn = new QToolButton;
269  btn->setDefaultAction( act );
270  container->layout()->addWidget( btn );
271  }
272  }
273 
274  if ( attributeTableConfig.actionWidgetStyle() == QgsAttributeTableConfig::ButtonList )
275  {
276  static_cast< QHBoxLayout * >( container->layout() )->addStretch();
277  }
278 
279  // TODO: Rethink default actions
280 #if 0
281  if ( toolButton && !toolButton->actions().isEmpty() && actions->defaultAction() == -1 )
282  toolButton->setDefaultAction( toolButton->actions().at( 0 ) );
283 #endif
284 
285  return container;
286 }
287 
288 void QgsAttributeTableView::closeEvent( QCloseEvent *e )
289 {
290  Q_UNUSED( e )
291  QgsSettings settings;
292  settings.setValue( QStringLiteral( "BetterAttributeTable/geometry" ), QVariant( saveGeometry() ) );
293 }
294 
295 void QgsAttributeTableView::mousePressEvent( QMouseEvent *event )
296 {
297  setSelectionMode( QAbstractItemView::NoSelection );
298  QTableView::mousePressEvent( event );
299  setSelectionMode( QAbstractItemView::ExtendedSelection );
300 }
301 
303 {
304  setSelectionMode( QAbstractItemView::NoSelection );
305  QTableView::mouseReleaseEvent( event );
306  setSelectionMode( QAbstractItemView::ExtendedSelection );
307 }
308 
309 void QgsAttributeTableView::mouseMoveEvent( QMouseEvent *event )
310 {
311  setSelectionMode( QAbstractItemView::NoSelection );
312  QTableView::mouseMoveEvent( event );
313  setSelectionMode( QAbstractItemView::ExtendedSelection );
314 }
315 
316 void QgsAttributeTableView::keyPressEvent( QKeyEvent *event )
317 {
318  switch ( event->key() )
319  {
320 
321  // Default Qt behavior would be to change the selection.
322  // We don't make it that easy for the user to trash his selection.
323  case Qt::Key_Up:
324  case Qt::Key_Down:
325  case Qt::Key_Left:
326  case Qt::Key_Right:
327  setSelectionMode( QAbstractItemView::NoSelection );
328  QTableView::keyPressEvent( event );
329  setSelectionMode( QAbstractItemView::ExtendedSelection );
330  break;
331 
332  default:
333  QTableView::keyPressEvent( event );
334  break;
335  }
336 }
337 
338 void QgsAttributeTableView::repaintRequested( const QModelIndexList &indexes )
339 {
340  const auto constIndexes = indexes;
341  for ( const QModelIndex &index : constIndexes )
342  {
343  update( index );
344  }
345 }
346 
348 {
349  setDirtyRegion( viewport()->rect() );
350 }
351 
353 {
354  QItemSelection selection;
355  selection.append( QItemSelectionRange( mFilterModel->index( 0, 0 ), mFilterModel->index( mFilterModel->rowCount() - 1, 0 ) ) );
356  mFeatureSelectionModel->selectFeatures( selection, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows );
357 }
358 
359 void QgsAttributeTableView::contextMenuEvent( QContextMenuEvent *event )
360 {
361  delete mActionPopup;
362  mActionPopup = nullptr;
363 
364  const QModelIndex idx = mFilterModel->mapToMaster( indexAt( event->pos() ) );
365  if ( !idx.isValid() )
366  {
367  return;
368  }
369 
370  QgsVectorLayer *vlayer = mFilterModel->layer();
371  if ( !vlayer )
372  return;
373 
374  mActionPopup = new QMenu( this );
375 
376  QAction *selectAllAction = mActionPopup->addAction( tr( "Select All" ) );
377  selectAllAction->setShortcut( QKeySequence::SelectAll );
378  connect( selectAllAction, &QAction::triggered, this, &QgsAttributeTableView::selectAll );
379 
380  // let some other parts of the application add some actions
381  emit willShowContextMenu( mActionPopup, idx );
382 
383  if ( !mActionPopup->actions().isEmpty() )
384  {
385  mActionPopup->popup( event->globalPos() );
386  }
387 }
388 
390 {
391  selectRow( row, true );
392 }
393 
395 {
396  selectRow( row, false );
397 }
398 
399 void QgsAttributeTableView::modelDeleted()
400 {
401  mFilterModel = nullptr;
402  mFeatureSelectionManager = nullptr;
403  mFeatureSelectionModel = nullptr;
404 }
405 
406 void QgsAttributeTableView::selectRow( int row, bool anchor )
407 {
408  if ( selectionBehavior() == QTableView::SelectColumns
409  || ( selectionMode() == QTableView::SingleSelection
410  && selectionBehavior() == QTableView::SelectItems ) )
411  return;
412 
413  if ( row >= 0 && row < model()->rowCount() )
414  {
415  int column = horizontalHeader()->logicalIndexAt( isRightToLeft() ? viewport()->width() : 0 );
416  QModelIndex index = model()->index( row, column );
417  QItemSelectionModel::SelectionFlags command = selectionCommand( index );
418  selectionModel()->setCurrentIndex( index, QItemSelectionModel::NoUpdate );
419  if ( ( anchor && !( command & QItemSelectionModel::Current ) )
420  || ( selectionMode() == QTableView::SingleSelection ) )
421  mRowSectionAnchor = row;
422 
423  if ( selectionMode() != QTableView::SingleSelection
424  && command.testFlag( QItemSelectionModel::Toggle ) )
425  {
426  if ( anchor )
427  mCtrlDragSelectionFlag = mFeatureSelectionModel->isSelected( index )
428  ? QItemSelectionModel::Deselect : QItemSelectionModel::Select;
429  command &= ~QItemSelectionModel::Toggle;
430  command |= mCtrlDragSelectionFlag;
431  if ( !anchor )
432  command |= QItemSelectionModel::Current;
433  }
434 
435  QModelIndex tl = model()->index( std::min( mRowSectionAnchor, row ), 0 );
436  QModelIndex br = model()->index( std::max( mRowSectionAnchor, row ), model()->columnCount() - 1 );
437  if ( verticalHeader()->sectionsMoved() && tl.row() != br.row() )
438  setSelection( visualRect( tl ) | visualRect( br ), command );
439  else
440  mFeatureSelectionModel->selectFeatures( QItemSelection( tl, br ), command );
441  }
442 }
443 
444 void QgsAttributeTableView::showHorizontalSortIndicator()
445 {
446  horizontalHeader()->setSortIndicatorShown( true );
447 }
448 
449 void QgsAttributeTableView::actionTriggered()
450 {
451  QAction *action = qobject_cast<QAction *>( sender() );
452  QgsFeatureId fid = action->property( "fid" ).toLongLong();
453 
454  QgsFeature f;
455  mFilterModel->layerCache()->getFeatures( QgsFeatureRequest( fid ) ).nextFeature( f );
456 
457  if ( action->data().toString() == QLatin1String( "user_action" ) )
458  {
459  mFilterModel->layer()->actions()->doAction( action->property( "action_id" ).toString(), f );
460  }
461  else if ( action->data().toString() == QLatin1String( "map_layer_action" ) )
462  {
463  QObject *object = action->property( "action" ).value<QObject *>();
464  QgsMapLayerAction *layerAction = qobject_cast<QgsMapLayerAction *>( object );
465  if ( layerAction )
466  {
467  layerAction->triggerForFeature( mFilterModel->layer(), f );
468  }
469  }
470 }
471 
472 void QgsAttributeTableView::columnSizeChanged( int index, int oldWidth, int newWidth )
473 {
474  Q_UNUSED( oldWidth )
475  emit columnResized( index, newWidth );
476 }
477 
478 void QgsAttributeTableView::onActionColumnItemPainted( const QModelIndex &index )
479 {
480  if ( !indexWidget( index ) )
481  {
482  QWidget *widget = createActionWidget( mFilterModel->data( index, QgsAttributeTableModel::FeatureIdRole ).toLongLong() );
483  mActionWidgets.insert( index, widget );
484  setIndexWidget( index, widget );
485  }
486 }
487 
488 void QgsAttributeTableView::recreateActionWidgets()
489 {
490  QMap< QModelIndex, QWidget * >::const_iterator it = mActionWidgets.constBegin();
491  for ( ; it != mActionWidgets.constEnd(); ++it )
492  {
493  // ownership of widget was transferred by initial call to setIndexWidget - clearing
494  // the index widget will delete the old widget safely
495  // they should then be recreated by onActionColumnItemPainted
496  setIndexWidget( it.key(), nullptr );
497  }
498  mActionWidgets.clear();
499 }
500 
502 {
503  QModelIndex index = mFilterModel->fidToIndex( fid );
504 
505  if ( !index.isValid() )
506  return;
507 
508  scrollTo( index );
509 
510  QModelIndex selectionIndex = index.sibling( index.row(), col );
511 
512  if ( !selectionIndex.isValid() )
513  return;
514 
515  selectionModel()->setCurrentIndex( index, QItemSelectionModel::SelectCurrent );
516 }
QgsActionManager * actions()
Returns all layer actions defined on this layer.
QgsVectorLayer * layer() const
Returns the layer this filter acts on.
QVariant data(const QModelIndex &index, int role) const override
Provides a table view of features of a QgsVectorLayer.
virtual bool isSelected(QgsFeatureId fid)
Returns the selection status of a given feature id.
void doAction(QUuid actionId, const QgsFeature &feature, int defaultValueIndex=0, const QgsExpressionContextScope &scope=QgsExpressionContextScope())
Does the given action.
void triggerForFeature(QgsMapLayer *layer, const QgsFeature &feature)
Triggers the action with the specified layer and feature.
QSet< QgsFeatureId > QgsFeatureIds
Definition: qgsfeatureid.h:37
void willShowContextMenu(QMenu *menu, const QModelIndex &atIndex)
Emitted in order to provide a hook to add additional* menu entries to the context menu...
QgsAttributeTableView(QWidget *parent=nullptr)
Constructor for QgsAttributeTableView.
This class is a composition of two QSettings instances:
Definition: qgssettings.h:61
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
void readOnlyChanged()
Emitted when the read only state of this layer is changed.
qint64 QgsFeatureId
64 bit feature ids negative numbers are used for uncommitted/newly added features ...
Definition: qgsfeatureid.h:28
virtual void selectFeatures(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command)
Select features on this table.
QList< QgsAction > actions(const QString &actionScope=QString()) const
Returns a list of actions that are available in the given action scope.
void columnResized(int column, int width)
Emitted when a column in the view has been resized.
bool eventFilter(QObject *object, QEvent *event) override
This event filter is installed on the verticalHeader to intercept mouse press and release events...
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:55
void actionColumnItemPainted(const QModelIndex &index) const
Emitted when an action column item is painted.
void enableSync(bool enable)
Enables or disables synchronisation to the QgsVectorLayer When synchronisation is disabled...
void setFeatureSelectionModel(QgsFeatureSelectionModel *featureSelectionModel)
void mouseReleaseEvent(QMouseEvent *event) override
Called for mouse release events on a table cell.
void saveGeometry(QWidget *widget, const QString &keyName)
Save the wigget geometry into settings.
Get the feature id of the feature in this row.
bool isEditable() const FINAL
Returns true if the provider is in editing mode.
bool restoreGeometry(QWidget *widget, const QString &keyName)
Restore the wigget geometry from settings.
ActionWidgetStyle actionWidgetStyle() const
Gets the style of the action widget.
void requestRepaint()
Request a repaint of the visible items of connected views.
Utility class that encapsulates an action based on vector attributes.
Definition: qgsaction.h:35
virtual const QgsFeatureIds & selectedFeatureIds() const =0
Returns reference to identifiers of selected features.
void editingStopped()
Emitted when edited changes have been successfully written to the data provider.
void mousePressEvent(QMouseEvent *event) override
Called for mouse press events on a table cell.
This class wraps a request for features to a vector layer (or directly its vector data provider)...
virtual void setFeatureSelectionManager(QgsIFeatureSelectionManager *featureSelectionManager)
void changed()
Triggered when an action is added or removed from the registry.
QgsAction defaultAction(const QString &actionScope)
Each scope can have a default action.
virtual void setModel(QgsAttributeTableFilterModel *filterModel)
void editingStarted()
Emitted when editing on this layer has started.
void mouseMoveEvent(QMouseEvent *event) override
Called for mouse move events on a table cell.
QVector< QgsAttributeTableConfig::ColumnConfig > columns() const
Gets the list with all columns and their configuration.
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
A tool button with a drop-down to select the current action.
void setFeatureSelectionManager(QgsIFeatureSelectionManager *featureSelectionManager)
setFeatureSelectionManager
A delegate item class for QgsAttributeTable (see Qt documentation for QItemDelegate).
void setAttributeTableConfig(const QgsAttributeTableConfig &config)
Set the attribute table config which should be used to control the appearance of the attribute table...
QList< QgsMapLayerAction * > mapLayerActions(QgsMapLayer *layer, QgsMapLayerAction::Targets targets=QgsMapLayerAction::AllActions)
Returns the map layer actions which can run on the specified layer.
Defines the configuration of a column in the attribute table.
virtual void selectRow(int row)
QUuid id() const
Returns a unique id for this action.
Definition: qgsaction.h:134
virtual void _q_selectRow(int row)
bool nextFeature(QgsFeature &f)
This is a container for configuration of the attribute table.
Is an interface class to abstract feature selection handling.
void closeEvent(QCloseEvent *event) override
Saves geometry to the settings on close.
void scrollToFeature(const QgsFeatureId &fid, int column=-1)
Scroll to a feature with a given fid.
Represents a vector layer which manages a vector based data sets.
QString sortExpression() const
Gets the expression used for sorting.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &featureRequest=QgsFeatureRequest())
Query this VectorLayerCache for features.
static QgsMapLayerActionRegistry * mapLayerActionRegistry()
Returns the global map layer action registry, used for registering map layer actions.
Definition: qgsgui.cpp:99
An action which can run on map layers.
QList< QgsFeatureId > selectedFeaturesIds() const
Returns the selected features in the attribute table in table sorted order.
void keyPressEvent(QKeyEvent *event) override
Called for key press events Disables selection change by only pressing an arrow key.
void contextMenuEvent(QContextMenuEvent *event) override
Is called when the context menu will be shown.
QgsVectorLayerCache * layerCache() const
Returns the layerCache this filter acts on.
QModelIndex mapToMaster(const QModelIndex &proxyIndex) const
QModelIndex fidToIndex(QgsFeatureId fid) override