QGIS API Documentation 4.1.0-Master (5bf3c20f3c9)
Loading...
Searching...
No Matches
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
17
18#include "qgsactionmanager.h"
22#include "qgsfeatureiterator.h"
24#include "qgsgui.h"
25#include "qgsmaplayeraction.h"
27#include "qgsstringutils.h"
28#include "qgsvectorlayer.h"
29#include "qgsvectorlayercache.h"
31
32#include <QDesktopServices>
33#include <QHBoxLayout>
34#include <QHeaderView>
35#include <QKeyEvent>
36#include <QMenu>
37#include <QString>
38#include <QToolButton>
39
40#include "moc_qgsattributetableview.cpp"
41
42using namespace Qt::StringLiterals;
43
45 : QgsTableView( parent )
46{
47 const QgsSettings settings;
48 restoreGeometry( settings.value( u"BetterAttributeTable/geometry"_s ).toByteArray() );
49
50 //verticalHeader()->setDefaultSectionSize( 20 );
51 horizontalHeader()->setHighlightSections( false );
52
53 // We need mouse move events to create the action button on hover
54 mTableDelegate = new QgsAttributeTableDelegate( this );
55 setItemDelegate( mTableDelegate );
56
57 setEditTriggers( QAbstractItemView::AllEditTriggers );
58
59 setSelectionBehavior( QAbstractItemView::SelectRows );
60 setSelectionMode( QAbstractItemView::ExtendedSelection );
61 setSortingEnabled( true ); // At this point no data is in the model yet, so actually nothing is sorted.
62 horizontalHeader()->setSortIndicatorShown( false ); // So hide the indicator to avoid confusion.
63
64 setHorizontalScrollMode( QAbstractItemView::ScrollPerPixel );
65
66 verticalHeader()->viewport()->installEventFilter( this );
67
68 connect( verticalHeader(), &QHeaderView::sectionPressed, this, [this]( int row ) { selectRow( row, true ); } );
69 connect( verticalHeader(), &QHeaderView::sectionEntered, this, &QgsAttributeTableView::_q_selectRow );
70 connect( horizontalHeader(), &QHeaderView::sectionResized, this, &QgsAttributeTableView::columnSizeChanged );
71 connect( horizontalHeader(), &QHeaderView::sortIndicatorChanged, this, &QgsAttributeTableView::showHorizontalSortIndicator );
72 connect( QgsGui::mapLayerActionRegistry(), &QgsMapLayerActionRegistry::changed, this, &QgsAttributeTableView::recreateActionWidgets );
73}
74
75bool QgsAttributeTableView::eventFilter( QObject *object, QEvent *event )
76{
77 if ( object == verticalHeader()->viewport() )
78 {
79 switch ( event->type() )
80 {
81 case QEvent::MouseButtonPress:
82 mFeatureSelectionModel->enableSync( false );
83 break;
84
85 case QEvent::MouseButtonRelease:
86 mFeatureSelectionModel->enableSync( true );
87 break;
88
89 case QEvent::MouseButtonDblClick:
90 {
91 QMouseEvent *mouseEvent = static_cast<QMouseEvent *>( event );
92 if ( mouseEvent->button() == Qt::LeftButton )
93 {
94 const int row = verticalHeader()->logicalIndexAt( mouseEvent->pos() );
95 if ( row >= 0 && mFilterModel )
96 {
97 const QModelIndex index = mFilterModel->index( row, 0 );
98 if ( index.isValid() )
99 {
100 const QgsFeatureId fid = mFilterModel->rowToId( index );
101 emit rowHeaderDoubleClicked( fid );
102 }
103 }
104 }
105 break;
106 }
107
108 default:
109 break;
110 }
111 }
112 return QTableView::eventFilter( object, event );
113}
114
116{
117 int i = 0;
118 const auto constColumns = config.columns();
119 QMap<QString, int> columns;
120 for ( const QgsAttributeTableConfig::ColumnConfig &columnConfig : constColumns )
121 {
122 if ( columnConfig.hidden )
123 continue;
124
125 if ( columnConfig.width >= 0 )
126 {
127 setColumnWidth( i, columnConfig.width );
128 }
129 else
130 {
131 setColumnWidth( i, horizontalHeader()->defaultSectionSize() );
132 }
133 columns.insert( columnConfig.name, i );
134 i++;
135 }
136 mConfig = config;
137 if ( config.sortExpression().isEmpty() )
138 {
139 horizontalHeader()->setSortIndicatorShown( false );
140 }
141 else
142 {
143 if ( mSortExpression != config.sortExpression() )
144 {
145 const QgsExpression sortExp { config.sortExpression() };
146 if ( sortExp.isField() )
147 {
148 const QStringList refCols { sortExp.referencedColumns().values() };
149 horizontalHeader()->setSortIndicatorShown( true );
150 horizontalHeader()->setSortIndicator( columns.value( refCols.constFirst() ), config.sortOrder() );
151 }
152 else
153 {
154 horizontalHeader()->setSortIndicatorShown( false );
155 }
156 }
157 }
158 mSortExpression = config.sortExpression();
159}
160
162{
163 // In order to get the ids in the right sorted order based on the view we have to get the feature ids first
164 // from the selection manager which is in the order the user selected them when clicking
165 // then get the model index, sort that, and finally return the new sorted features ids.
166 const QgsFeatureIds featureIds = mFeatureSelectionManager->selectedFeatureIds();
167 QModelIndexList indexList;
168 for ( const QgsFeatureId &id : featureIds )
169 {
170 const QModelIndex index = mFilterModel->fidToIndex( id );
171 indexList << index;
172 }
173
174 std::sort( indexList.begin(), indexList.end() );
175 QList<QgsFeatureId> ids;
176 for ( const QModelIndex &index : indexList )
177 {
178 const QgsFeatureId id = mFilterModel->data( index, static_cast<int>( QgsAttributeTableModel::CustomRole::FeatureId ) ).toLongLong();
179 ids.append( id );
180 }
181 return ids;
182}
183
185{
186 mFilterModel = filterModel;
187 QTableView::setModel( mFilterModel );
188
189 if ( mFilterModel )
190 {
191 connect( mFilterModel, &QObject::destroyed, this, &QgsAttributeTableView::modelDeleted );
192 connect( mTableDelegate, &QgsAttributeTableDelegate::actionColumnItemPainted, this, &QgsAttributeTableView::onActionColumnItemPainted );
193 }
194
195 delete mFeatureSelectionModel;
196 mFeatureSelectionModel = nullptr;
197
198 if ( mFilterModel )
199 {
200 if ( !mFeatureSelectionManager )
201 {
202 mOwnedFeatureSelectionManager = new QgsVectorLayerSelectionManager( mFilterModel->layer(), this );
203 mFeatureSelectionManager = mOwnedFeatureSelectionManager;
204 }
205
206 mFeatureSelectionModel = new QgsFeatureSelectionModel( mFilterModel, mFilterModel, mFeatureSelectionManager, mFilterModel );
207 setSelectionModel( mFeatureSelectionModel );
208 mTableDelegate->setFeatureSelectionModel( mFeatureSelectionModel );
209 connect(
210 mFeatureSelectionModel,
211 static_cast<void ( QgsFeatureSelectionModel::* )( const QModelIndexList &indexes )>( &QgsFeatureSelectionModel::requestRepaint ),
212 this,
213 static_cast<void ( QgsAttributeTableView::* )( const QModelIndexList &indexes )>( &QgsAttributeTableView::repaintRequested )
214 );
215 connect( mFeatureSelectionModel, static_cast<void ( QgsFeatureSelectionModel::* )()>( &QgsFeatureSelectionModel::requestRepaint ), this, static_cast<void ( QgsAttributeTableView::* )()>( &QgsAttributeTableView::repaintRequested ) );
216
217 connect( mFilterModel->layer(), &QgsVectorLayer::editingStarted, this, &QgsAttributeTableView::recreateActionWidgets );
218 connect( mFilterModel->layer(), &QgsVectorLayer::editingStopped, this, &QgsAttributeTableView::recreateActionWidgets );
219 connect( mFilterModel->layer(), &QgsVectorLayer::readOnlyChanged, this, &QgsAttributeTableView::recreateActionWidgets );
220 }
221}
222
224{
225 mFeatureSelectionManager = featureSelectionManager;
226
227 if ( mFeatureSelectionModel )
228 mFeatureSelectionModel->setFeatureSelectionManager( mFeatureSelectionManager );
229
230 // only delete the owner selection manager and not one created from outside
231 if ( mOwnedFeatureSelectionManager )
232 {
233 mOwnedFeatureSelectionManager->deleteLater();
234 mOwnedFeatureSelectionManager = nullptr;
235 }
236}
237
238QWidget *QgsAttributeTableView::createActionWidget( QgsFeatureId fid )
239{
240 const QgsAttributeTableConfig attributeTableConfig = mConfig;
241
242 QToolButton *toolButton = nullptr;
243 QWidget *container = nullptr;
244
245 if ( attributeTableConfig.actionWidgetStyle() == QgsAttributeTableConfig::DropDown )
246 {
247 toolButton = new QToolButton();
248 toolButton->setToolButtonStyle( Qt::ToolButtonTextBesideIcon );
249 toolButton->setPopupMode( QToolButton::MenuButtonPopup );
250 container = toolButton;
251 }
252 else
253 {
254 container = new QWidget();
255 container->setLayout( new QHBoxLayout() );
256 container->layout()->setContentsMargins( 0, 0, 0, 0 );
257 }
258
259 QList<QAction *> actionList;
260 QAction *defaultAction = nullptr;
261
262 // first add user created layer actions
263 const QList<QgsAction> actions = mFilterModel->layer()->actions()->actions( u"Feature"_s );
264 const auto constActions = actions;
265 for ( const QgsAction &action : constActions )
266 {
267 if ( !mFilterModel->layer()->isEditable() && action.isEnabledOnlyWhenEditable() )
268 continue;
269
270 const QString actionTitle = !action.shortTitle().isEmpty() ? action.shortTitle() : action.icon().isNull() ? action.name() : QString();
271 QAction *act = new QAction( action.icon(), actionTitle, container );
272 act->setToolTip( action.name() );
273 act->setData( "user_action" );
274 act->setProperty( "fid", fid );
275 act->setProperty( "action_id", action.id() );
276 connect( act, &QAction::triggered, this, &QgsAttributeTableView::actionTriggered );
277 actionList << act;
278
279 if ( mFilterModel->layer()->actions()->defaultAction( u"Feature"_s ).id() == action.id() )
280 defaultAction = act;
281 }
282
283 QgsMapLayerActionContext context;
284 const QList<QgsMapLayerAction *> mapLayerActions = QgsGui::mapLayerActionRegistry()->mapLayerActions( mFilterModel->layer(), Qgis::MapLayerActionTarget::SingleFeature, context );
285 // next add any registered actions for this layer
286 for ( QgsMapLayerAction *mapLayerAction : mapLayerActions )
287 {
288 QAction *action = new QAction( mapLayerAction->icon(), mapLayerAction->text(), container );
289 action->setData( "map_layer_action" );
290 action->setToolTip( mapLayerAction->text() );
291 action->setProperty( "fid", fid );
292 action->setProperty( "action", QVariant::fromValue( qobject_cast<QObject *>( mapLayerAction ) ) );
293 connect( action, &QAction::triggered, this, &QgsAttributeTableView::actionTriggered );
294 actionList << action;
295
296 if ( !defaultAction && QgsGui::mapLayerActionRegistry()->defaultActionForLayer( mFilterModel->layer() ) == mapLayerAction )
297 defaultAction = action;
298 }
299
300 if ( !defaultAction && !actionList.isEmpty() )
301 defaultAction = actionList.at( 0 );
302
303 const auto constActionList = actionList;
304 for ( QAction *act : constActionList )
305 {
306 if ( attributeTableConfig.actionWidgetStyle() == QgsAttributeTableConfig::DropDown )
307 {
308 toolButton->addAction( act );
309
310 if ( act == defaultAction )
311 toolButton->setDefaultAction( act );
312
313 container = toolButton;
314 }
315 else
316 {
317 QToolButton *btn = new QToolButton;
318 btn->setDefaultAction( act );
319 container->layout()->addWidget( btn );
320 }
321 }
322
323 if ( attributeTableConfig.actionWidgetStyle() == QgsAttributeTableConfig::ButtonList )
324 {
325 static_cast<QHBoxLayout *>( container->layout() )->addStretch();
326 }
327
328 // TODO: Rethink default actions
329#if 0
330 if ( toolButton && !toolButton->actions().isEmpty() && actions->defaultAction() == -1 )
331 toolButton->setDefaultAction( toolButton->actions().at( 0 ) );
332#endif
333
334 return container;
335}
336
338{
339 Q_UNUSED( e )
340 QgsSettings settings;
341 settings.setValue( u"BetterAttributeTable/geometry"_s, QVariant( saveGeometry() ) );
342}
343
345{
346 setSelectionMode( QAbstractItemView::NoSelection );
347 QTableView::mousePressEvent( event );
348 setSelectionMode( QAbstractItemView::ExtendedSelection );
349}
350
352{
353 setSelectionMode( QAbstractItemView::NoSelection );
354 QTableView::mouseReleaseEvent( event );
355 setSelectionMode( QAbstractItemView::ExtendedSelection );
356 if ( event->modifiers() == Qt::ControlModifier )
357 {
358 const QModelIndex index = indexAt( event->pos() );
359 const QVariant data = model()->data( index, Qt::DisplayRole );
360 if ( data.userType() == QMetaType::Type::QString )
361 {
362 const QString textVal = data.toString();
363 if ( QgsStringUtils::isUrl( textVal ) )
364 {
365 QDesktopServices::openUrl( QUrl( textVal ) );
366 }
367 }
368 }
369}
370
372{
373 setSelectionMode( QAbstractItemView::NoSelection );
374 QTableView::mouseMoveEvent( event );
375 setSelectionMode( QAbstractItemView::ExtendedSelection );
376}
377
379{
380 switch ( event->key() )
381 {
382 // Default Qt behavior would be to change the selection.
383 // We don't make it that easy for the user to trash his selection.
384 case Qt::Key_Up:
385 case Qt::Key_Down:
386 case Qt::Key_Left:
387 case Qt::Key_Right:
388 setSelectionMode( QAbstractItemView::NoSelection );
389 QTableView::keyPressEvent( event );
390 setSelectionMode( QAbstractItemView::ExtendedSelection );
391 break;
392
393 default:
394 QTableView::keyPressEvent( event );
395 break;
396 }
397}
398
399void QgsAttributeTableView::repaintRequested( const QModelIndexList &indexes )
400{
401 const auto constIndexes = indexes;
402 for ( const QModelIndex &index : constIndexes )
403 {
404 update( index );
405 }
406}
407
409{
410 setDirtyRegion( viewport()->rect() );
411}
412
414{
415 QItemSelection selection;
416 selection.append( QItemSelectionRange( mFilterModel->index( 0, 0 ), mFilterModel->index( mFilterModel->rowCount() - 1, 0 ) ) );
417 mFeatureSelectionModel->selectFeatures( selection, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows );
418}
419
420void QgsAttributeTableView::contextMenuEvent( QContextMenuEvent *event )
421{
422 delete mActionPopup;
423 mActionPopup = nullptr;
424
425 const QModelIndex idx = mFilterModel->mapToMaster( indexAt( event->pos() ) );
426 if ( !idx.isValid() )
427 {
428 return;
429 }
430
431 QgsVectorLayer *vlayer = mFilterModel->layer();
432 if ( !vlayer )
433 return;
434
435 mActionPopup = new QMenu( this );
436
437 QAction *selectAllAction = mActionPopup->addAction( tr( "Select All" ) );
438 selectAllAction->setShortcut( QKeySequence::SelectAll );
439 connect( selectAllAction, &QAction::triggered, this, &QgsAttributeTableView::selectAll );
440
441 // let some other parts of the application add some actions
442 emit willShowContextMenu( mActionPopup, idx );
443
444 if ( !mActionPopup->actions().isEmpty() )
445 {
446 mActionPopup->popup( event->globalPos() );
447 }
448}
449
451{
452 selectRow( row, true );
453}
454
456{
457 selectRow( row, false );
458}
459
460void QgsAttributeTableView::modelDeleted()
461{
462 mFilterModel = nullptr;
463 mFeatureSelectionManager = nullptr;
464 mFeatureSelectionModel = nullptr;
465}
466
467void QgsAttributeTableView::selectRow( int row, bool anchor )
468{
469 if ( selectionBehavior() == QTableView::SelectColumns || ( selectionMode() == QTableView::SingleSelection && selectionBehavior() == QTableView::SelectItems ) )
470 return;
471
472 if ( row >= 0 && row < model()->rowCount() )
473 {
474 const int column = horizontalHeader()->logicalIndexAt( isRightToLeft() ? viewport()->width() : 0 );
475 const QModelIndex index = model()->index( row, column );
476 QItemSelectionModel::SelectionFlags command = selectionCommand( index );
477 selectionModel()->setCurrentIndex( index, QItemSelectionModel::NoUpdate );
478 if ( ( anchor && !( command & QItemSelectionModel::Current ) ) || ( selectionMode() == QTableView::SingleSelection ) )
479 mRowSectionAnchor = row;
480
481 if ( selectionMode() != QTableView::SingleSelection && command.testFlag( QItemSelectionModel::Toggle ) )
482 {
483 if ( anchor )
484 mCtrlDragSelectionFlag = mFeatureSelectionModel->isSelected( index ) ? QItemSelectionModel::Deselect : QItemSelectionModel::Select;
485 command &= ~QItemSelectionModel::Toggle;
486 command |= mCtrlDragSelectionFlag;
487 if ( !anchor )
488 command |= QItemSelectionModel::Current;
489 }
490
491 const QModelIndex tl = model()->index( std::min( mRowSectionAnchor, row ), 0 );
492 const QModelIndex br = model()->index( std::max( mRowSectionAnchor, row ), model()->columnCount() - 1 );
493 if ( verticalHeader()->sectionsMoved() && tl.row() != br.row() )
494 setSelection( visualRect( tl ) | visualRect( br ), command );
495 else
496 mFeatureSelectionModel->selectFeatures( QItemSelection( tl, br ), command );
497 }
498}
499
500void QgsAttributeTableView::showHorizontalSortIndicator()
501{
502 horizontalHeader()->setSortIndicatorShown( true );
503}
504
505void QgsAttributeTableView::actionTriggered()
506{
507 QAction *action = qobject_cast<QAction *>( sender() );
508 const QgsFeatureId fid = action->property( "fid" ).toLongLong();
509
510 QgsFeature f;
511 mFilterModel->layerCache()->getFeatures( QgsFeatureRequest( fid ) ).nextFeature( f );
512
513 if ( action->data().toString() == "user_action"_L1 )
514 {
515 mFilterModel->layer()->actions()->doAction( action->property( "action_id" ).toUuid(), f );
516 }
517 else if ( action->data().toString() == "map_layer_action"_L1 )
518 {
519 QObject *object = action->property( "action" ).value<QObject *>();
520 QgsMapLayerAction *layerAction = qobject_cast<QgsMapLayerAction *>( object );
521 if ( layerAction )
522 {
523 QgsMapLayerActionContext context;
525 layerAction->triggerForFeature( mFilterModel->layer(), f );
527 layerAction->triggerForFeature( mFilterModel->layer(), f, context );
528 }
529 }
530}
531
532void QgsAttributeTableView::columnSizeChanged( int index, int oldWidth, int newWidth )
533{
534 Q_UNUSED( oldWidth )
535 emit columnResized( index, newWidth );
536}
537
538void QgsAttributeTableView::onActionColumnItemPainted( const QModelIndex &index )
539{
540 if ( !indexWidget( index ) )
541 {
542 QWidget *widget = createActionWidget( mFilterModel->data( index, static_cast<int>( QgsAttributeTableModel::CustomRole::FeatureId ) ).toLongLong() );
543 mActionWidgets.insert( index, widget );
544 setIndexWidget( index, widget );
545 }
546}
547
548void QgsAttributeTableView::recreateActionWidgets()
549{
550 QMap<QModelIndex, QWidget *>::const_iterator it = mActionWidgets.constBegin();
551 for ( ; it != mActionWidgets.constEnd(); ++it )
552 {
553 // ownership of widget was transferred by initial call to setIndexWidget - clearing
554 // the index widget will delete the old widget safely
555 // they should then be recreated by onActionColumnItemPainted
556 setIndexWidget( it.key(), nullptr );
557 }
558 mActionWidgets.clear();
559}
560
562{
563 const QModelIndex index = mFilterModel->fidToIndex( fid );
564
565 if ( !index.isValid() )
566 return;
567
568 scrollTo( index );
569
570 const QModelIndex selectionIndex = index.sibling( index.row(), col );
571
572 if ( !selectionIndex.isValid() )
573 return;
574
575 selectionModel()->setCurrentIndex( index, QItemSelectionModel::SelectCurrent );
576}
577
579{
580 QWidget *editor = indexWidget( currentIndex() );
581 commitData( editor );
582 closeEditor( editor, QAbstractItemDelegate::NoHint );
583}
@ SingleFeature
Action targets a single feature from a layer.
Definition qgis.h:4784
A container for configuration of the attribute table.
Qt::SortOrder sortOrder() const
Gets the sort order.
QVector< QgsAttributeTableConfig::ColumnConfig > columns() const
Gets the list with all columns and their configuration.
@ DropDown
A tool button with a drop-down to select the current action.
ActionWidgetStyle actionWidgetStyle() const
Gets the style of the action widget.
QString sortExpression() const
Gets the expression used for sorting.
A delegate item class for QgsAttributeTable (see Qt documentation for QItemDelegate).
void actionColumnItemPainted(const QModelIndex &index) const
Emitted when an action column item is painted.
A proxy model for filtering an attribute table model.
@ FeatureId
Get the feature id of the feature in this row.
void willShowContextMenu(QMenu *menu, const QModelIndex &atIndex)
Emitted in order to provide a hook to add additional* menu entries to the context menu.
QList< QgsFeatureId > selectedFeaturesIds() const
Returns the selected features in the attribute table in table sorted order.
void setFeatureSelectionManager(QgsIFeatureSelectionManager *featureSelectionManager)
setFeatureSelectionManager
void mouseMoveEvent(QMouseEvent *event) override
Called for mouse move events on a table cell.
virtual void selectRow(int row)
QgsAttributeTableView(QWidget *parent=nullptr)
Constructor for QgsAttributeTableView.
void rowHeaderDoubleClicked(QgsFeatureId fid)
Emitted when a row header is double-clicked.
void scrollToFeature(const QgsFeatureId &fid, int column=-1)
Scroll to a feature with a given fid.
void mouseReleaseEvent(QMouseEvent *event) override
Called for mouse release events on a table cell.
void contextMenuEvent(QContextMenuEvent *event) override
Is called when the context menu will be shown.
virtual void _q_selectRow(int row)
void closeEvent(QCloseEvent *event) override
Saves geometry to the settings on close.
void mousePressEvent(QMouseEvent *event) override
Called for mouse press events on a table cell.
void closeCurrentEditor()
Closes the editor delegate for the current item, committing its changes to the model.
void keyPressEvent(QKeyEvent *event) override
Called for key press events Disables selection change by only pressing an arrow key.
void setAttributeTableConfig(const QgsAttributeTableConfig &config)
Set the attribute table config which should be used to control the appearance of the attribute table.
void columnResized(int column, int width)
Emitted when a column in the view has been resized.
void repaintRequested(const QModelIndexList &indexes)
bool eventFilter(QObject *object, QEvent *event) override
This event filter is installed on the verticalHeader to intercept mouse press and release events.
virtual void setModel(QgsAttributeTableFilterModel *filterModel)
Handles parsing and evaluation of expressions (formerly called "search strings").
bool isField() const
Checks whether an expression consists only of a single field reference.
QSet< QString > referencedColumns() const
Gets list of columns referenced by the expression.
Item selection model for selecting features.
void requestRepaint(const QModelIndexList &indexes)
Request a repaint of a list of model indexes.
static QgsMapLayerActionRegistry * mapLayerActionRegistry()
Returns the global map layer action registry, used for registering map layer actions.
Definition qgsgui.cpp:149
Is an interface class to abstract feature selection handling.
void changed()
Triggered when an action is added or removed from the registry.
QList< QgsMapLayerAction * > mapLayerActions(QgsMapLayer *layer, Qgis::MapLayerActionTargets targets=Qgis::MapLayerActionTarget::AllActions, const QgsMapLayerActionContext &context=QgsMapLayerActionContext())
Returns the map layer actions which can run on the specified layer.
void editingStopped()
Emitted when edited changes have been successfully written to the data provider.
void editingStarted()
Emitted when editing on this layer has started.
Stores settings for use within QGIS.
Definition qgssettings.h:68
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
static bool isUrl(const QString &string)
Returns whether the string is a URL (http,https,ftp,file).
QgsTableView(QWidget *parent=nullptr)
Constructor for QgsTableView.
Represents a vector layer which manages a vector based dataset.
void readOnlyChanged()
Emitted when the read only state of this layer is changed.
#define Q_NOWARN_DEPRECATED_POP
Definition qgis.h:7504
#define Q_NOWARN_DEPRECATED_PUSH
Definition qgis.h:7503
QSet< QgsFeatureId > QgsFeatureIds
qint64 QgsFeatureId
64 bit feature ids negative numbers are used for uncommitted/newly added features
Defines the configuration of a column in the attribute table.