QGIS API Documentation 4.1.0-Master (0cdd3ae6384)
Loading...
Searching...
No Matches
qgssourcefieldsproperties.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgssourcefieldsproperties.cpp
3 ---------------------
4 begin : July 2017
5 copyright : (C) 2017 by David Signer
6 email : david at opengis dot ch
7
8 ***************************************************************************
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 ***************************************************************************/
16
18
20#include "qgsaddattrdialog.h"
21#include "qgsapplication.h"
24#include "qgsgui.h"
25#include "qgsnative.h"
26#include "qgsproject.h"
27#include "qgsprovidermetadata.h"
28#include "qgsproviderregistry.h"
29#include "qgsvectorlayer.h"
30
31#include <QString>
32
33#include "moc_qgssourcefieldsproperties.cpp"
34
35using namespace Qt::StringLiterals;
36
38 : QWidget( parent )
39 , mLayer( layer )
40{
41 if ( !layer )
42 return;
43
44 setupUi( this );
45 layout()->setContentsMargins( 0, 0, 0, 0 );
46
47 //button appearance
48 mAddAttributeButton->setIcon( QgsApplication::getThemeIcon( u"/mActionNewAttribute.svg"_s ) );
49 mDeleteAttributeButton->setIcon( QgsApplication::getThemeIcon( u"/mActionDeleteAttribute.svg"_s ) );
50 mToggleEditingButton->setIcon( QgsApplication::getThemeIcon( u"/mActionToggleEditing.svg"_s ) );
51 mCalculateFieldButton->setIcon( QgsApplication::getThemeIcon( u"/mActionCalculateField.svg"_s ) );
52 mSaveLayerEditsButton->setIcon( QgsApplication::getThemeIcon( u"/mActionSaveAllEdits.svg"_s ) );
53
54 //button signals
55 connect( mToggleEditingButton, &QAbstractButton::clicked, this, &QgsSourceFieldsProperties::toggleEditing );
56 connect( mAddAttributeButton, &QAbstractButton::clicked, this, &QgsSourceFieldsProperties::addAttributeClicked );
57 connect( mDeleteAttributeButton, &QAbstractButton::clicked, this, &QgsSourceFieldsProperties::deleteAttributeClicked );
58 connect( mCalculateFieldButton, &QAbstractButton::clicked, this, &QgsSourceFieldsProperties::calculateFieldClicked );
59 connect( mSaveLayerEditsButton, &QAbstractButton::clicked, this, &QgsSourceFieldsProperties::saveLayerEditsClicked );
60
61 //slots
62 connect( mLayer, &QgsVectorLayer::editingStarted, this, &QgsSourceFieldsProperties::editingToggled );
63 connect( mLayer, &QgsVectorLayer::editingStopped, this, &QgsSourceFieldsProperties::editingToggled );
64 connect( mLayer, &QgsVectorLayer::attributeAdded, this, &QgsSourceFieldsProperties::attributeAdded );
65 connect( mLayer, &QgsVectorLayer::attributeDeleted, this, &QgsSourceFieldsProperties::attributeDeleted );
66
67 //field list appearance
68 mFieldsList->setColumnCount( AttrColCount );
69 mFieldsList->setSelectionBehavior( QAbstractItemView::SelectRows );
70 mFieldsList->setDragDropMode( QAbstractItemView::DragOnly );
71 mFieldsList->setHorizontalHeaderItem( AttrIdCol, new QTableWidgetItem( tr( "Id" ) ) );
72 mFieldsList->setHorizontalHeaderItem( AttrNameCol, new QTableWidgetItem( tr( "Name" ) ) );
73 mFieldsList->setHorizontalHeaderItem( AttrTypeCol, new QTableWidgetItem( tr( "Type" ) ) );
74 mFieldsList->setHorizontalHeaderItem( AttrTypeNameCol, new QTableWidgetItem( tr( "Type name" ) ) );
75 mFieldsList->setHorizontalHeaderItem( AttrLengthCol, new QTableWidgetItem( tr( "Length" ) ) );
76 mFieldsList->setHorizontalHeaderItem( AttrPrecCol, new QTableWidgetItem( tr( "Precision" ) ) );
77 mFieldsList->setHorizontalHeaderItem( AttrCommentCol, new QTableWidgetItem( tr( "Comment" ) ) );
78 const auto configurationFlagsWi = new QTableWidgetItem( tr( "Configuration" ) );
79 configurationFlagsWi->setToolTip( tr( "Configures the field" ) );
80 mFieldsList->setHorizontalHeaderItem( AttrConfigurationFlagsCol, configurationFlagsWi );
81 mFieldsList->setHorizontalHeaderItem( AttrAliasCol, new QTableWidgetItem( tr( "Alias" ) ) );
82 const auto fieldDomainWidget = new QTableWidgetItem( tr( "Field Domain" ) );
83 fieldDomainWidget->setToolTip( tr( "Field domain associated with the field" ) );
84 mFieldsList->setHorizontalHeaderItem( AttrFieldDomainCol, fieldDomainWidget );
85
86 mFieldsList->setSortingEnabled( true );
87 mFieldsList->sortByColumn( 0, Qt::AscendingOrder );
88 mFieldsList->setSelectionBehavior( QAbstractItemView::SelectRows );
89 mFieldsList->setSelectionMode( QAbstractItemView::ExtendedSelection );
90 mFieldsList->horizontalHeader()->setStretchLastSection( true );
91 mFieldsList->verticalHeader()->hide();
92
93 //load buttons and field list
95}
96
101
103{
104 disconnect( mFieldsList, &QTableWidget::cellChanged, this, &QgsSourceFieldsProperties::attributesListCellChanged );
105 const QgsFields &fields = mLayer->fields();
106
107 mIndexedWidgets.clear();
108 mFieldsList->setRowCount( 0 );
109
110 for ( int i = 0; i < fields.count(); ++i )
111 attributeAdded( i );
112
113 if ( mLayer->dataProvider() )
114 {
115 mFieldsList->setColumnHidden( AttrFieldDomainCol, !mLayer->dataProvider()->capabilities().testFlag( Qgis::VectorProviderCapability::ReadFieldDomains ) );
116 }
117
118 mFieldsList->resizeColumnsToContents();
119 connect( mFieldsList, &QTableWidget::cellChanged, this, &QgsSourceFieldsProperties::attributesListCellChanged );
120
121 connect( mFieldsList, &QTableWidget::cellPressed, this, &QgsSourceFieldsProperties::attributesListCellPressed );
122
124 updateFieldRenamingStatus();
125}
126
127void QgsSourceFieldsProperties::updateFieldRenamingStatus()
128{
129 const bool canRenameFields = mLayer->isEditable() && ( mLayer->dataProvider()->capabilities() & Qgis::VectorProviderCapability::RenameAttributes ) && !mLayer->readOnly();
130
131 for ( int row = 0; row < mFieldsList->rowCount(); ++row )
132 {
133 if ( canRenameFields )
134 mFieldsList->item( row, AttrNameCol )->setFlags( mFieldsList->item( row, AttrNameCol )->flags() | Qt::ItemIsEditable );
135 else
136 mFieldsList->item( row, AttrNameCol )->setFlags( mFieldsList->item( row, AttrNameCol )->flags() & ~Qt::ItemIsEditable );
137 }
138}
139
140void QgsSourceFieldsProperties::updateExpression()
141{
142 QToolButton *btn = qobject_cast<QToolButton *>( sender() );
143 Q_ASSERT( btn );
144
145 const int index = btn->property( "Index" ).toInt();
146
147 const QString exp = mLayer->expressionField( index );
148
149 QgsExpressionContext context;
151
152 QgsExpressionBuilderDialog dlg( mLayer, exp, nullptr, u"generic"_s, context );
153
154 if ( dlg.exec() )
155 {
156 mLayer->updateExpressionField( index, dlg.expressionText() );
157 loadRows();
158 }
159}
160
161void QgsSourceFieldsProperties::attributeAdded( int idx )
162{
163 const bool sorted = mFieldsList->isSortingEnabled();
164 if ( sorted )
165 mFieldsList->setSortingEnabled( false );
166
167 const QgsFields &fields = mLayer->fields();
168 const int row = mFieldsList->rowCount();
169 mFieldsList->insertRow( row );
170 setRow( row, idx, fields.at( idx ) );
171 mFieldsList->setCurrentCell( row, idx );
172
173 const QColor expressionColor = QColor( 103, 0, 243, 44 );
174 const QColor joinColor = QColor( 0, 243, 79, 44 );
175 const QColor defaultColor = QColor( 252, 255, 79, 44 );
176
177 for ( int i = 0; i < mFieldsList->columnCount(); i++ )
178 {
179 if ( i == AttrConfigurationFlagsCol )
180 continue;
181
182 switch ( mLayer->fields().fieldOrigin( idx ) )
183 {
185 if ( i == AttrCommentCol )
186 continue;
187 mFieldsList->item( row, i )->setBackground( expressionColor );
188 break;
189
191 mFieldsList->item( row, i )->setBackground( joinColor );
192 break;
193
194 default:
195 if ( defaultColor.isValid() )
196 mFieldsList->item( row, i )->setBackground( defaultColor );
197 break;
198 }
199 }
200
201 if ( sorted )
202 mFieldsList->setSortingEnabled( true );
203
204 if ( mLayer->dataProvider() )
205 {
206 mFieldsList->setColumnHidden( AttrFieldDomainCol, !mLayer->dataProvider()->capabilities().testFlag( Qgis::VectorProviderCapability::ReadFieldDomains ) );
207 }
208}
209
210
211void QgsSourceFieldsProperties::attributeDeleted( int idx )
212{
213 mFieldsList->removeRow( mIndexedWidgets.at( idx )->row() );
214 mIndexedWidgets.removeAt( idx );
215 for ( int i = idx; i < mIndexedWidgets.count(); i++ )
216 {
217 mIndexedWidgets.at( i )->setData( Qt::DisplayRole, i );
218 }
219}
220
221void QgsSourceFieldsProperties::setRow( int row, int idx, const QgsField &field )
222{
223 QTableWidgetItem *dataItem = new QTableWidgetItem();
224 dataItem->setData( Qt::DisplayRole, idx );
225 dataItem->setIcon( mLayer->fields().iconForField( idx, true ) );
226 mFieldsList->setItem( row, AttrIdCol, dataItem );
227
228 // in case we insert and not append reindex remaining widgets by 1
229 for ( int i = idx + 1; i < mIndexedWidgets.count(); i++ )
230 mIndexedWidgets.at( i )->setData( Qt::DisplayRole, i );
231 mIndexedWidgets.insert( idx, mFieldsList->item( row, 0 ) );
232
233 mFieldsList->setItem( row, AttrNameCol, new QTableWidgetItem( field.name() ) );
234 mFieldsList->setItem( row, AttrAliasCol, new QTableWidgetItem( field.alias() ) );
235 mFieldsList->setItem( row, AttrTypeCol, new QTableWidgetItem( field.friendlyTypeString() ) );
236 mFieldsList->setItem( row, AttrTypeNameCol, new QTableWidgetItem( field.typeName() ) );
237 mFieldsList->setItem( row, AttrLengthCol, new QTableWidgetItem( QString::number( field.length() ) ) );
238 mFieldsList->setItem( row, AttrPrecCol, new QTableWidgetItem( QString::number( field.precision() ) ) );
239
240 if ( mLayer->fields().fieldOrigin( idx ) == Qgis::FieldOrigin::Expression )
241 {
242 QWidget *expressionWidget = new QWidget;
243 expressionWidget->setLayout( new QHBoxLayout );
244 QToolButton *editExpressionButton = new QToolButton;
245 editExpressionButton->setProperty( "Index", idx );
246 editExpressionButton->setIcon( QgsApplication::getThemeIcon( u"/mIconExpression.svg"_s ) );
247 connect( editExpressionButton, &QAbstractButton::clicked, this, &QgsSourceFieldsProperties::updateExpression );
248 expressionWidget->layout()->setContentsMargins( 0, 0, 0, 0 );
249 expressionWidget->layout()->addWidget( editExpressionButton );
250 expressionWidget->layout()->addWidget( new QLabel( mLayer->expressionField( idx ) ) );
251 expressionWidget->setStyleSheet( "*[class~=\"QWidget\"] { background-color: rgba( 103, 0, 243, 0.12 ); } QToolButton { background-color: rgba( 203, 100, 243, 0.6 ); }" );
252 mFieldsList->setCellWidget( row, AttrCommentCol, expressionWidget );
253 }
254 else
255 {
256 mFieldsList->setItem( row, AttrCommentCol, new QTableWidgetItem( field.comment() ) );
257 }
258
259 mFieldsList->setItem( row, AttrFieldDomainCol, new QTableWidgetItem( field.constraints().domainName() ) );
260
262 {
263 if ( i != AttrCommentCol || mLayer->fields().fieldOrigin( idx ) != Qgis::FieldOrigin::Expression )
264 mFieldsList->item( row, i )->setFlags( mFieldsList->item( row, i )->flags() & ~Qt::ItemIsEditable );
265 if ( i == AttrAliasCol )
266 mFieldsList->item( row, i )->setToolTip( tr( "Edit alias in the Form config tab" ) );
267 }
268 const bool canRenameFields = mLayer->isEditable() && ( mLayer->dataProvider()->capabilities() & Qgis::VectorProviderCapability::RenameAttributes ) && !mLayer->readOnly();
269 if ( canRenameFields )
270 mFieldsList->item( row, AttrNameCol )->setFlags( mFieldsList->item( row, AttrNameCol )->flags() | Qt::ItemIsEditable );
271 else
272 mFieldsList->item( row, AttrNameCol )->setFlags( mFieldsList->item( row, AttrNameCol )->flags() & ~Qt::ItemIsEditable );
273
274 // Flags
275 QgsCheckableComboBox *cb = new QgsCheckableComboBox( mFieldsList );
276 const QList<Qgis::FieldConfigurationFlag> flagList = qgsEnumList<Qgis::FieldConfigurationFlag>();
277 for ( const Qgis::FieldConfigurationFlag flag : flagList )
278 {
280 continue;
281
282 cb->addItemWithCheckState( QgsField::readableConfigurationFlag( flag ), mLayer->fieldConfigurationFlags( idx ).testFlag( flag ) ? Qt::Checked : Qt::Unchecked, QVariant::fromValue( flag ) );
283 }
284 mFieldsList->setCellWidget( row, AttrConfigurationFlagsCol, cb );
285}
286
288{
289 QgsDebugMsgLevel( "inserting attribute " + field.name() + " of type " + field.typeName(), 2 );
290 mLayer->beginEditCommand( tr( "Added attribute" ) );
291 if ( mLayer->addAttribute( field ) )
292 {
293 mLayer->endEditCommand();
294 return true;
295 }
296 else
297 {
298 mLayer->destroyEditCommand();
299 QMessageBox::critical( this, tr( "Add Field" ), tr( "Failed to add field '%1' of type '%2'. Is the field name unique?" ).arg( field.name(), field.typeName() ) );
300 return false;
301 }
302}
303
305{
306 applyToLayer( mLayer );
307}
308
309void QgsSourceFieldsProperties::applyToLayer( QgsVectorLayer *layer )
310{
311 for ( int i = 0; i < mFieldsList->rowCount(); i++ )
312 {
313 const int idx = mFieldsList->item( i, AttrIdCol )->data( Qt::DisplayRole ).toInt();
315
316 QgsCheckableComboBox *cb = qobject_cast<QgsCheckableComboBox *>( mFieldsList->cellWidget( i, AttrConfigurationFlagsCol ) );
317 if ( cb )
318 {
319 QgsCheckableItemModel *model = cb->model();
320 for ( int r = 0; r < model->rowCount(); ++r )
321 {
322 const QModelIndex index = model->index( r, 0 );
323 const Qgis::FieldConfigurationFlag flag = model->data( index, Qt::UserRole ).value<Qgis::FieldConfigurationFlag>();
324 const bool active = model->data( index, Qt::CheckStateRole ).value<Qt::CheckState>() == Qt::Checked ? true : false;
325 flags.setFlag( flag, active );
326 }
327 layer->setFieldConfigurationFlags( idx, flags );
328 }
329 }
330}
331
332// slots
333
334void QgsSourceFieldsProperties::editingToggled()
335{
337 updateFieldRenamingStatus();
338}
339
340void QgsSourceFieldsProperties::addAttributeClicked()
341{
342 if ( !mLayer || !mLayer->dataProvider() )
343 {
344 return;
345 }
346
347 QgsAddAttrDialog dialog( mLayer, this );
348 if ( dialog.exec() == QDialog::Accepted )
349 {
350 addAttribute( dialog.field() );
351 loadRows();
352 }
353}
354
355void QgsSourceFieldsProperties::deleteAttributeClicked()
356{
357 QSet<int> providerFields;
358 QSet<int> expressionFields;
359 const auto constSelectedItems = mFieldsList->selectedItems();
360 for ( QTableWidgetItem *item : constSelectedItems )
361 {
362 if ( item->column() == 0 )
363 {
364 const int idx = mIndexedWidgets.indexOf( item );
365 if ( idx < 0 )
366 continue;
367
368 if ( mLayer->fields().fieldOrigin( idx ) == Qgis::FieldOrigin::Expression )
369 expressionFields << idx;
370 else
371 providerFields << idx;
372 }
373 }
374
375 if ( !expressionFields.isEmpty() )
376 mLayer->deleteAttributes( expressionFields.values() );
377
378 if ( !providerFields.isEmpty() )
379 {
380 mLayer->beginEditCommand( tr( "Deleted attributes" ) );
381 if ( mLayer->deleteAttributes( providerFields.values() ) )
382 mLayer->endEditCommand();
383 else
384 mLayer->destroyEditCommand();
385 }
386}
387
388void QgsSourceFieldsProperties::calculateFieldClicked()
389{
390 if ( !mLayer || !mLayer->dataProvider() )
391 {
392 return;
393 }
394
395 QgsFieldCalculator calc( mLayer, this );
396 if ( calc.exec() == QDialog::Accepted )
397 {
398 loadRows();
399 }
400}
401
402void QgsSourceFieldsProperties::saveLayerEditsClicked()
403{
404 mLayer->commitChanges( false );
405}
406
407void QgsSourceFieldsProperties::attributesListCellChanged( int row, int column )
408{
409 if ( column == AttrNameCol && mLayer && mLayer->isEditable() )
410 {
411 const int idx = mIndexedWidgets.indexOf( mFieldsList->item( row, AttrIdCol ) );
412
413 QTableWidgetItem *nameItem = mFieldsList->item( row, column );
414 //avoiding that something will be changed, just because this is triggered by simple re-sorting
415 if ( !nameItem || nameItem->text().isEmpty() || !mLayer->fields().exists( idx ) || mLayer->fields().at( idx ).name() == nameItem->text() )
416 return;
417
418 mLayer->beginEditCommand( tr( "Rename attribute" ) );
419 if ( mLayer->renameAttribute( idx, nameItem->text() ) )
420 {
421 mLayer->endEditCommand();
422 }
423 else
424 {
425 mLayer->destroyEditCommand();
426 QMessageBox::critical( this, tr( "Rename Field" ), tr( "Failed to rename field to '%1'. Is the field name unique?" ).arg( nameItem->text() ) );
427 }
428 }
429}
430
431void QgsSourceFieldsProperties::attributesListCellPressed( int /*row*/, int /*column*/ )
432{
434}
435
436//NICE FUNCTIONS
438{
439 QgsVectorDataProvider *provider = mLayer->dataProvider();
440 if ( !provider )
441 return;
442 const Qgis::VectorProviderCapabilities cap = provider->capabilities();
443
444 mToggleEditingButton->setEnabled( ( cap & Qgis::VectorProviderCapability::ChangeAttributeValues ) && !mLayer->readOnly() );
445
446 if ( mLayer->isEditable() )
447 {
448 mDeleteAttributeButton->setEnabled( cap & Qgis::VectorProviderCapability::DeleteAttributes );
449 mAddAttributeButton->setEnabled( cap & Qgis::VectorProviderCapability::AddAttributes );
450 mToggleEditingButton->setChecked( true );
451 mSaveLayerEditsButton->setEnabled( true );
452 mSaveLayerEditsButton->setChecked( true );
453 }
454 else
455 {
456 mToggleEditingButton->setChecked( false );
457 mAddAttributeButton->setEnabled( false );
458 mSaveLayerEditsButton->setEnabled( false );
459
460 // Enable delete button if items are selected
461 mDeleteAttributeButton->setEnabled( !mFieldsList->selectedItems().isEmpty() );
462 // and only if all selected items have their origin in an expression
463 const auto constSelectedItems = mFieldsList->selectedItems();
464 for ( QTableWidgetItem *item : constSelectedItems )
465 {
466 if ( item->column() == 0 )
467 {
468 const int idx = mIndexedWidgets.indexOf( item );
469 if ( mLayer->fields().fieldOrigin( idx ) != Qgis::FieldOrigin::Expression )
470 {
471 mDeleteAttributeButton->setEnabled( false );
472 break;
473 }
474 }
475 }
476 }
477}
@ AddAttributes
Allows addition of new attributes (fields).
Definition qgis.h:530
@ ReadFieldDomains
Provider can read field domains and their properties.
Definition qgis.h:552
@ RenameAttributes
Supports renaming attributes (fields).
Definition qgis.h:542
@ DeleteAttributes
Allows deletion of attributes (fields).
Definition qgis.h:531
@ ChangeAttributeValues
Allows modification of attribute values.
Definition qgis.h:529
QFlags< VectorProviderCapability > VectorProviderCapabilities
Vector data provider capabilities.
Definition qgis.h:564
@ Expression
Field is calculated from an expression.
Definition qgis.h:1830
@ Join
Field originates from a joined layer.
Definition qgis.h:1828
FieldConfigurationFlag
Configuration flags for fields These flags are meant to be user-configurable and are not describing a...
Definition qgis.h:1842
@ NoFlag
No flag is defined.
Definition qgis.h:1843
QFlags< FieldConfigurationFlag > FieldConfigurationFlags
Configuration flags for fields These flags are meant to be user-configurable and are not describing a...
Definition qgis.h:1857
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
QComboBox subclass which allows selecting multiple items.
QgsCheckableItemModel * model() const
Returns the custom item model which handles checking the items.
void addItemWithCheckState(const QString &text, Qt::CheckState state, const QVariant &userData=QVariant())
Adds an item to the combobox with the given text, check state (stored in the Qt::CheckStateRole) and ...
QStandardItemModel subclass which makes all items checkable by default.
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override
Returns the data stored under the given role for the item referred to by the index.
static QgsExpressionContextScope * projectScope(const QgsProject *project)
Creates a new scope which contains variables and functions relating to a QGIS project.
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context.
QString domainName() const
Returns the associated field domain name, for providers which support field domains.
Encapsulate a field in an attribute table or data source.
Definition qgsfield.h:56
QString typeName() const
Gets the field type.
Definition qgsfield.cpp:158
QString name
Definition qgsfield.h:65
int precision
Definition qgsfield.h:62
int length
Definition qgsfield.h:61
QString friendlyTypeString() const
Returns a user friendly, translated representation of the field type.
Definition qgsfield.cpp:136
static QString readableConfigurationFlag(Qgis::FieldConfigurationFlag flag)
Returns the readable and translated value of the configuration flag.
Definition qgsfield.cpp:463
QString alias
Definition qgsfield.h:66
QString comment
Definition qgsfield.h:64
QgsFieldConstraints constraints
Definition qgsfield.h:68
Container of fields for a vector layer.
Definition qgsfields.h:46
int count
Definition qgsfields.h:50
QgsField at(int i) const
Returns the field at particular index (must be in range 0..N-1).
void editingStopped()
Emitted when edited changes have been successfully written to the data provider.
void editingStarted()
Emitted when editing on this layer has started.
static QgsProject * instance()
Returns the QgsProject singleton instance.
QList< QTableWidgetItem * > mIndexedWidgets
QgsSourceFieldsProperties(QgsVectorLayer *layer, QWidget *parent=nullptr)
bool addAttribute(const QgsField &field)
Adds an attribute to the table (but does not commit it yet).
void setRow(int row, int idx, const QgsField &field)
Base class for vector data providers.
virtual Q_INVOKABLE Qgis::VectorProviderCapabilities capabilities() const
Returns flags containing the supported capabilities.
Represents a vector layer which manages a vector based dataset.
bool isEditable() const final
Returns true if the provider is in editing mode.
void setFieldConfigurationFlags(int index, Qgis::FieldConfigurationFlags flags)
Sets the configuration flags of the field at given index.
void attributeAdded(int idx)
Will be emitted, when a new attribute has been added to this vector layer.
void attributeDeleted(int idx)
Will be emitted, when an attribute has been deleted from this vector layer.
Qgis::FieldConfigurationFlags fieldConfigurationFlags(int index) const
Returns the configuration flags of the field at given index.
QgsVectorDataProvider * dataProvider() final
Returns the layer's data provider, it may be nullptr.
const QList< T > qgsEnumList()
Returns a list all enum entries.
Definition qgis.h:7542
#define QgsDebugMsgLevel(str, level)
Definition qgslogger.h:80