QGIS API Documentation 3.99.0-Master (d270888f95f)
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( mFeatureSelectionModel, static_cast<void ( QgsFeatureSelectionModel::* )( const QModelIndexList &indexes )>( &QgsFeatureSelectionModel::requestRepaint ), this, static_cast<void ( QgsAttributeTableView::* )( const QModelIndexList &indexes )>( &QgsAttributeTableView::repaintRequested ) );
210 connect( mFeatureSelectionModel, static_cast<void ( QgsFeatureSelectionModel::* )()>( &QgsFeatureSelectionModel::requestRepaint ), this, static_cast<void ( QgsAttributeTableView::* )()>( &QgsAttributeTableView::repaintRequested ) );
211
212 connect( mFilterModel->layer(), &QgsVectorLayer::editingStarted, this, &QgsAttributeTableView::recreateActionWidgets );
213 connect( mFilterModel->layer(), &QgsVectorLayer::editingStopped, this, &QgsAttributeTableView::recreateActionWidgets );
214 connect( mFilterModel->layer(), &QgsVectorLayer::readOnlyChanged, this, &QgsAttributeTableView::recreateActionWidgets );
215 }
216}
217
219{
220 mFeatureSelectionManager = featureSelectionManager;
221
222 if ( mFeatureSelectionModel )
223 mFeatureSelectionModel->setFeatureSelectionManager( mFeatureSelectionManager );
224
225 // only delete the owner selection manager and not one created from outside
226 if ( mOwnedFeatureSelectionManager )
227 {
228 mOwnedFeatureSelectionManager->deleteLater();
229 mOwnedFeatureSelectionManager = nullptr;
230 }
231}
232
233QWidget *QgsAttributeTableView::createActionWidget( QgsFeatureId fid )
234{
235 const QgsAttributeTableConfig attributeTableConfig = mConfig;
236
237 QToolButton *toolButton = nullptr;
238 QWidget *container = nullptr;
239
240 if ( attributeTableConfig.actionWidgetStyle() == QgsAttributeTableConfig::DropDown )
241 {
242 toolButton = new QToolButton();
243 toolButton->setToolButtonStyle( Qt::ToolButtonTextBesideIcon );
244 toolButton->setPopupMode( QToolButton::MenuButtonPopup );
245 container = toolButton;
246 }
247 else
248 {
249 container = new QWidget();
250 container->setLayout( new QHBoxLayout() );
251 container->layout()->setContentsMargins( 0, 0, 0, 0 );
252 }
253
254 QList<QAction *> actionList;
255 QAction *defaultAction = nullptr;
256
257 // first add user created layer actions
258 const QList<QgsAction> actions = mFilterModel->layer()->actions()->actions( u"Feature"_s );
259 const auto constActions = actions;
260 for ( const QgsAction &action : constActions )
261 {
262 if ( !mFilterModel->layer()->isEditable() && action.isEnabledOnlyWhenEditable() )
263 continue;
264
265 const QString actionTitle = !action.shortTitle().isEmpty() ? action.shortTitle() : action.icon().isNull() ? action.name()
266 : QString();
267 QAction *act = new QAction( action.icon(), actionTitle, container );
268 act->setToolTip( action.name() );
269 act->setData( "user_action" );
270 act->setProperty( "fid", fid );
271 act->setProperty( "action_id", action.id() );
272 connect( act, &QAction::triggered, this, &QgsAttributeTableView::actionTriggered );
273 actionList << act;
274
275 if ( mFilterModel->layer()->actions()->defaultAction( u"Feature"_s ).id() == action.id() )
276 defaultAction = act;
277 }
278
279 QgsMapLayerActionContext context;
280 const QList<QgsMapLayerAction *> mapLayerActions = QgsGui::mapLayerActionRegistry()->mapLayerActions( mFilterModel->layer(), Qgis::MapLayerActionTarget::SingleFeature, context );
281 // next add any registered actions for this layer
282 for ( QgsMapLayerAction *mapLayerAction : mapLayerActions )
283 {
284 QAction *action = new QAction( mapLayerAction->icon(), mapLayerAction->text(), container );
285 action->setData( "map_layer_action" );
286 action->setToolTip( mapLayerAction->text() );
287 action->setProperty( "fid", fid );
288 action->setProperty( "action", QVariant::fromValue( qobject_cast<QObject *>( mapLayerAction ) ) );
289 connect( action, &QAction::triggered, this, &QgsAttributeTableView::actionTriggered );
290 actionList << action;
291
292 if ( !defaultAction && QgsGui::mapLayerActionRegistry()->defaultActionForLayer( mFilterModel->layer() ) == mapLayerAction )
293 defaultAction = action;
294 }
295
296 if ( !defaultAction && !actionList.isEmpty() )
297 defaultAction = actionList.at( 0 );
298
299 const auto constActionList = actionList;
300 for ( QAction *act : constActionList )
301 {
302 if ( attributeTableConfig.actionWidgetStyle() == QgsAttributeTableConfig::DropDown )
303 {
304 toolButton->addAction( act );
305
306 if ( act == defaultAction )
307 toolButton->setDefaultAction( act );
308
309 container = toolButton;
310 }
311 else
312 {
313 QToolButton *btn = new QToolButton;
314 btn->setDefaultAction( act );
315 container->layout()->addWidget( btn );
316 }
317 }
318
319 if ( attributeTableConfig.actionWidgetStyle() == QgsAttributeTableConfig::ButtonList )
320 {
321 static_cast<QHBoxLayout *>( container->layout() )->addStretch();
322 }
323
324 // TODO: Rethink default actions
325#if 0
326 if ( toolButton && !toolButton->actions().isEmpty() && actions->defaultAction() == -1 )
327 toolButton->setDefaultAction( toolButton->actions().at( 0 ) );
328#endif
329
330 return container;
331}
332
334{
335 Q_UNUSED( e )
336 QgsSettings settings;
337 settings.setValue( u"BetterAttributeTable/geometry"_s, QVariant( saveGeometry() ) );
338}
339
341{
342 setSelectionMode( QAbstractItemView::NoSelection );
343 QTableView::mousePressEvent( event );
344 setSelectionMode( QAbstractItemView::ExtendedSelection );
345}
346
348{
349 setSelectionMode( QAbstractItemView::NoSelection );
350 QTableView::mouseReleaseEvent( event );
351 setSelectionMode( QAbstractItemView::ExtendedSelection );
352 if ( event->modifiers() == Qt::ControlModifier )
353 {
354 const QModelIndex index = indexAt( event->pos() );
355 const QVariant data = model()->data( index, Qt::DisplayRole );
356 if ( data.userType() == QMetaType::Type::QString )
357 {
358 const QString textVal = data.toString();
359 if ( QgsStringUtils::isUrl( textVal ) )
360 {
361 QDesktopServices::openUrl( QUrl( textVal ) );
362 }
363 }
364 }
365}
366
368{
369 setSelectionMode( QAbstractItemView::NoSelection );
370 QTableView::mouseMoveEvent( event );
371 setSelectionMode( QAbstractItemView::ExtendedSelection );
372}
373
375{
376 switch ( event->key() )
377 {
378 // Default Qt behavior would be to change the selection.
379 // We don't make it that easy for the user to trash his selection.
380 case Qt::Key_Up:
381 case Qt::Key_Down:
382 case Qt::Key_Left:
383 case Qt::Key_Right:
384 setSelectionMode( QAbstractItemView::NoSelection );
385 QTableView::keyPressEvent( event );
386 setSelectionMode( QAbstractItemView::ExtendedSelection );
387 break;
388
389 default:
390 QTableView::keyPressEvent( event );
391 break;
392 }
393}
394
395void QgsAttributeTableView::repaintRequested( const QModelIndexList &indexes )
396{
397 const auto constIndexes = indexes;
398 for ( const QModelIndex &index : constIndexes )
399 {
400 update( index );
401 }
402}
403
405{
406 setDirtyRegion( viewport()->rect() );
407}
408
410{
411 QItemSelection selection;
412 selection.append( QItemSelectionRange( mFilterModel->index( 0, 0 ), mFilterModel->index( mFilterModel->rowCount() - 1, 0 ) ) );
413 mFeatureSelectionModel->selectFeatures( selection, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows );
414}
415
416void QgsAttributeTableView::contextMenuEvent( QContextMenuEvent *event )
417{
418 delete mActionPopup;
419 mActionPopup = nullptr;
420
421 const QModelIndex idx = mFilterModel->mapToMaster( indexAt( event->pos() ) );
422 if ( !idx.isValid() )
423 {
424 return;
425 }
426
427 QgsVectorLayer *vlayer = mFilterModel->layer();
428 if ( !vlayer )
429 return;
430
431 mActionPopup = new QMenu( this );
432
433 QAction *selectAllAction = mActionPopup->addAction( tr( "Select All" ) );
434 selectAllAction->setShortcut( QKeySequence::SelectAll );
435 connect( selectAllAction, &QAction::triggered, this, &QgsAttributeTableView::selectAll );
436
437 // let some other parts of the application add some actions
438 emit willShowContextMenu( mActionPopup, idx );
439
440 if ( !mActionPopup->actions().isEmpty() )
441 {
442 mActionPopup->popup( event->globalPos() );
443 }
444}
445
447{
448 selectRow( row, true );
449}
450
452{
453 selectRow( row, false );
454}
455
456void QgsAttributeTableView::modelDeleted()
457{
458 mFilterModel = nullptr;
459 mFeatureSelectionManager = nullptr;
460 mFeatureSelectionModel = nullptr;
461}
462
463void QgsAttributeTableView::selectRow( int row, bool anchor )
464{
465 if ( selectionBehavior() == QTableView::SelectColumns
466 || ( selectionMode() == QTableView::SingleSelection && selectionBehavior() == QTableView::SelectItems ) )
467 return;
468
469 if ( row >= 0 && row < model()->rowCount() )
470 {
471 const int column = horizontalHeader()->logicalIndexAt( isRightToLeft() ? viewport()->width() : 0 );
472 const QModelIndex index = model()->index( row, column );
473 QItemSelectionModel::SelectionFlags command = selectionCommand( index );
474 selectionModel()->setCurrentIndex( index, QItemSelectionModel::NoUpdate );
475 if ( ( anchor && !( command & QItemSelectionModel::Current ) )
476 || ( selectionMode() == QTableView::SingleSelection ) )
477 mRowSectionAnchor = row;
478
479 if ( selectionMode() != QTableView::SingleSelection
480 && command.testFlag( QItemSelectionModel::Toggle ) )
481 {
482 if ( anchor )
483 mCtrlDragSelectionFlag = mFeatureSelectionModel->isSelected( index )
484 ? QItemSelectionModel::Deselect
485 : QItemSelectionModel::Select;
486 command &= ~QItemSelectionModel::Toggle;
487 command |= mCtrlDragSelectionFlag;
488 if ( !anchor )
489 command |= QItemSelectionModel::Current;
490 }
491
492 const QModelIndex tl = model()->index( std::min( mRowSectionAnchor, row ), 0 );
493 const QModelIndex br = model()->index( std::max( mRowSectionAnchor, row ), model()->columnCount() - 1 );
494 if ( verticalHeader()->sectionsMoved() && tl.row() != br.row() )
495 setSelection( visualRect( tl ) | visualRect( br ), command );
496 else
497 mFeatureSelectionModel->selectFeatures( QItemSelection( tl, br ), command );
498 }
499}
500
501void QgsAttributeTableView::showHorizontalSortIndicator()
502{
503 horizontalHeader()->setSortIndicatorShown( true );
504}
505
506void QgsAttributeTableView::actionTriggered()
507{
508 QAction *action = qobject_cast<QAction *>( sender() );
509 const QgsFeatureId fid = action->property( "fid" ).toLongLong();
510
511 QgsFeature f;
512 mFilterModel->layerCache()->getFeatures( QgsFeatureRequest( fid ) ).nextFeature( f );
513
514 if ( action->data().toString() == "user_action"_L1 )
515 {
516 mFilterModel->layer()->actions()->doAction( action->property( "action_id" ).toUuid(), f );
517 }
518 else if ( action->data().toString() == "map_layer_action"_L1 )
519 {
520 QObject *object = action->property( "action" ).value<QObject *>();
521 QgsMapLayerAction *layerAction = qobject_cast<QgsMapLayerAction *>( object );
522 if ( layerAction )
523 {
524 QgsMapLayerActionContext context;
526 layerAction->triggerForFeature( mFilterModel->layer(), f );
528 layerAction->triggerForFeature( mFilterModel->layer(), f, context );
529 }
530 }
531}
532
533void QgsAttributeTableView::columnSizeChanged( int index, int oldWidth, int newWidth )
534{
535 Q_UNUSED( oldWidth )
536 emit columnResized( index, newWidth );
537}
538
539void QgsAttributeTableView::onActionColumnItemPainted( const QModelIndex &index )
540{
541 if ( !indexWidget( index ) )
542 {
543 QWidget *widget = createActionWidget( mFilterModel->data( index, static_cast<int>( QgsAttributeTableModel::CustomRole::FeatureId ) ).toLongLong() );
544 mActionWidgets.insert( index, widget );
545 setIndexWidget( index, widget );
546 }
547}
548
549void QgsAttributeTableView::recreateActionWidgets()
550{
551 QMap<QModelIndex, QWidget *>::const_iterator it = mActionWidgets.constBegin();
552 for ( ; it != mActionWidgets.constEnd(); ++it )
553 {
554 // ownership of widget was transferred by initial call to setIndexWidget - clearing
555 // the index widget will delete the old widget safely
556 // they should then be recreated by onActionColumnItemPainted
557 setIndexWidget( it.key(), nullptr );
558 }
559 mActionWidgets.clear();
560}
561
563{
564 const QModelIndex index = mFilterModel->fidToIndex( fid );
565
566 if ( !index.isValid() )
567 return;
568
569 scrollTo( index );
570
571 const QModelIndex selectionIndex = index.sibling( index.row(), col );
572
573 if ( !selectionIndex.isValid() )
574 return;
575
576 selectionModel()->setCurrentIndex( index, QItemSelectionModel::SelectCurrent );
577}
578
580{
581 QWidget *editor = indexWidget( currentIndex() );
582 commitData( editor );
583 closeEditor( editor, QAbstractItemDelegate::NoHint );
584}
@ SingleFeature
Action targets a single feature from a layer.
Definition qgis.h:4699
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:7451
#define Q_NOWARN_DEPRECATED_PUSH
Definition qgis.h:7450
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.