QGIS API Documentation  3.20.0-Odense (decaadbb31)
qgsvectorlayerundopassthroughcommand.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsvectorlayerundopassthroughcommand.cpp
3  ---------------------
4  begin : June 2017
5  copyright : (C) 2017 by Vincent Mora
6  email : vincent dot mora at oslandia dot 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 "qgsfeatureiterator.h"
19 #include "qgsgeometry.h"
20 #include "qgsfeature.h"
21 #include "qgsvectorlayer.h"
23 
24 #include "qgslogger.h"
25 #include "qgstransaction.h"
26 
27 #include <QUuid>
28 
29 // TODO use setObsolete instead of mHasError when upgrading qt version, this will allow auto removal of the command
30 // for the moment a errored command is left on the stack
31 
33  : QgsVectorLayerUndoCommand( buffer )
34  , mSavePointId( ( mBuffer->L->isEditCommandActive() && !mBuffer->L->dataProvider()->transaction()->savePoints().isEmpty() )
35  || !autocreate
36  ? mBuffer->L->dataProvider()->transaction()->savePoints().last()
37  : mBuffer->L->dataProvider()->transaction()->createSavepoint( mError ) )
38  , mHasError( !mError.isEmpty() )
39  , mRecreateSavePoint( mBuffer->L->isEditCommandActive()
40  ? !mBuffer->L->dataProvider()->transaction()->lastSavePointIsDirty()
41  : true )
42 {
43  // the first command in the undo stack macro will have a clean save point
44  // the first command is responsible to re-create the savepoint after undo
45  setText( text );
46 }
47 
48 
50 {
51  if ( !mHasError )
52  {
53  setText( text() + " " + QObject::tr( "failed" ) );
54  mHasError = true;
55  }
56 }
57 
58 void QgsVectorLayerUndoPassthroughCommand::setErrorMessage( const QString &errorMessage )
59 {
60  mError = errorMessage;
61 }
62 
64 {
65  return mError;
66 }
67 
68 bool QgsVectorLayerUndoPassthroughCommand::setSavePoint( const QString &savePointId )
69 {
70  if ( !hasError() )
71  {
72  if ( savePointId.isEmpty() )
73  {
74  // re-create savepoint only if mRecreateSavePoint and rollBackToSavePoint as occurred
75  if ( mRecreateSavePoint && mBuffer->L->dataProvider()->transaction()->savePoints().indexOf( mSavePointId ) == -1 )
76  {
77  mSavePointId = mBuffer->L->dataProvider()->transaction()->createSavepoint( mSavePointId, mError );
78  if ( mSavePointId.isEmpty() )
79  {
80  setError();
81  }
82  }
83  }
84  else
85  {
86  mSavePointId = savePointId;
87  }
88  }
89  return !hasError();
90 }
91 
93 {
94  // rollback only occurs for the last command in undo macro
95  if ( !hasError() && mBuffer->L->dataProvider()->transaction()->savePoints().indexOf( mSavePointId ) != -1 )
96  {
97  if ( !mBuffer->L->dataProvider()->transaction()->rollbackToSavepoint( mSavePointId, mError ) )
98  {
99  setError();
100  }
101  }
102  return !hasError();
103 }
104 
105 
107  : QgsVectorLayerUndoPassthroughCommand( buffer, QObject::tr( "add features" ) )
108 {
109  static int sAddedIdLowWaterMark = -1;
110  for ( const QgsFeature &f : std::as_const( features ) )
111  {
112  mInitialFeatures << f;
113  //assign a temporary id to the feature (use negative numbers)
114  sAddedIdLowWaterMark--;
115  mInitialFeatures.last().setId( sAddedIdLowWaterMark );
116  }
117  mFeatures = mInitialFeatures;
118 
119 }
120 
122 {
123  if ( rollBackToSavePoint() )
124  {
125  for ( const QgsFeature &f : std::as_const( mFeatures ) )
126  {
127  mBuffer->mAddedFeatures.remove( f.id() );
128  emit mBuffer->featureDeleted( f.id() );
129  }
130  mFeatures = mInitialFeatures;
131  }
132 }
133 
135 {
136  mFeatures = mInitialFeatures;
138  if ( setSavePoint() && mBuffer->L->dataProvider()->addFeatures( mFeatures ) && ! mBuffer->L->dataProvider()->hasErrors() )
139  {
140  for ( const QgsFeature &f : std::as_const( mFeatures ) )
141  {
142  mBuffer->mAddedFeatures.insert( f.id(), f );
143  emit mBuffer->featureAdded( f.id() );
144  }
145  }
146  else
147  {
148  setError();
149  }
150 }
151 
153  : QgsVectorLayerUndoPassthroughCommand( buffer, QObject::tr( "delete features" ) )
154  , mFids( fids )
155 {
156 }
157 
159 {
160  if ( rollBackToSavePoint() )
161  {
162  for ( const QgsFeatureId &fid : mFids )
163  {
164  mBuffer->mDeletedFeatureIds.remove( fid );
165  if ( mDeletedNewFeatures.contains( fid ) )
166  {
167  mBuffer->mAddedFeatures.insert( fid, mDeletedNewFeatures.value( fid ) );
168  }
169  emit mBuffer->featureAdded( fid );
170  }
171  }
172 }
173 
175 {
177  if ( setSavePoint() && mBuffer->L->dataProvider()->deleteFeatures( mFids ) && ! mBuffer->L->dataProvider()->hasErrors() )
178  {
179  mDeletedNewFeatures.clear();
180  for ( const QgsFeatureId &fid : mFids )
181  {
182  if ( mBuffer->mAddedFeatures.contains( fid ) )
183  {
184  mDeletedNewFeatures.insert( fid, mBuffer->mAddedFeatures[ fid ] );
185  mBuffer->mAddedFeatures.remove( fid );
186  }
187  else
188  {
189  mBuffer->mDeletedFeatureIds.insert( fid );
190  }
191  emit mBuffer->featureDeleted( fid );
192  }
193  }
194  else
195  {
196  setError();
197  }
198 }
199 
201  : QgsVectorLayerUndoPassthroughCommand( buffer, QObject::tr( "change geometry" ) )
202  , mFid( fid )
203  , mNewGeom( geom )
204  , mOldGeom( mBuffer->L->getFeature( mFid ).geometry() )
205  , mFirstChange( true )
206 {
207  if ( mBuffer->mAddedFeatures.contains( mFid ) )
208  {
209  mFirstChange = false;
210  }
211  else if ( mBuffer->mChangedGeometries.contains( mFid ) )
212  {
213  mFirstChange = false;
214  mOldGeom = mBuffer->mChangedGeometries[mFid];
215  }
216 }
217 
219 {
220  if ( rollBackToSavePoint() )
221  {
222  if ( mBuffer->mAddedFeatures.contains( mFid ) )
223  {
224  mBuffer->mAddedFeatures[ mFid ].setGeometry( mOldGeom );
225  }
226  else if ( mFirstChange )
227  {
228  mBuffer->mChangedGeometries.remove( mFid );
229  }
230  else
231  {
232  mBuffer->mChangedGeometries[mFid] = mOldGeom;
233  }
234  emit mBuffer->geometryChanged( mFid, mOldGeom );
235  }
236 }
237 
239 {
240  QgsGeometryMap geomMap;
241  geomMap.insert( mFid, mNewGeom );
243  if ( setSavePoint() && mBuffer->L->dataProvider()->changeGeometryValues( geomMap ) && ! mBuffer->L->dataProvider()->hasErrors() )
244  {
245  if ( mBuffer->mAddedFeatures.contains( mFid ) )
246  {
247  mBuffer->mAddedFeatures[ mFid ].setGeometry( mNewGeom );
248  }
249  else
250  {
251  mBuffer->mChangedGeometries[ mFid ] = mNewGeom;
252  }
253  emit mBuffer->geometryChanged( mFid, mNewGeom );
254  }
255  else
256  {
257  setError();
258  }
259 }
260 
262 {
263  if ( other->id() != id() )
264  return false;
265 
267  if ( !merge )
268  return false;
269 
270  if ( merge->mFid != mFid )
271  return false;
272 
273  mNewGeom = merge->mNewGeom;
274  merge->mNewGeom = QgsGeometry();
275 
276  return true;
277 }
278 
279 
280 
282  : QgsVectorLayerUndoPassthroughCommand( buffer, QObject::tr( "change attribute value" ) )
283  , mFid( fid )
284  , mFieldIndex( field )
285  , mNewValue( newValue )
286  , mOldValue( mBuffer->L->getFeature( mFid ).attribute( field ) )
287  , mFirstChange( true )
288 {
289 
290  if ( mBuffer->mAddedFeatures.contains( mFid ) )
291  {
292  // work with added feature
293  QgsFeatureMap::const_iterator it = mBuffer->mAddedFeatures.constFind( mFid );
294  Q_ASSERT( it != mBuffer->mAddedFeatures.constEnd() );
295  if ( it.value().attribute( mFieldIndex ).isValid() )
296  {
297  mOldValue = it.value().attribute( mFieldIndex );
298  mFirstChange = false;
299  }
300  }
301  else if ( mBuffer->mChangedAttributeValues.contains( mFid ) && mBuffer->mChangedAttributeValues[mFid].contains( mFieldIndex ) )
302  {
303  mOldValue = mBuffer->mChangedAttributeValues[mFid][mFieldIndex];
304  mFirstChange = false;
305  }
306 }
307 
309 {
310  if ( rollBackToSavePoint() )
311  {
312  QVariant original = mOldValue;
313 
314  if ( mBuffer->mAddedFeatures.contains( mFid ) )
315  {
316  // added feature
317  QgsFeatureMap::iterator it = mBuffer->mAddedFeatures.find( mFid );
318  Q_ASSERT( it != mBuffer->mAddedFeatures.end() );
319  it.value().setAttribute( mFieldIndex, mOldValue );
320  }
321  else if ( mFirstChange )
322  {
323  // existing feature
324  mBuffer->mChangedAttributeValues[mFid].remove( mFieldIndex );
325  if ( mBuffer->mChangedAttributeValues[mFid].isEmpty() )
326  mBuffer->mChangedAttributeValues.remove( mFid );
327 
328  if ( !mOldValue.isValid() )
329  {
330  // get old value from provider
331  QgsFeature tmp;
332  QgsFeatureRequest request;
333  request.setFilterFid( mFid );
335  request.setSubsetOfAttributes( QgsAttributeList() << mFieldIndex );
336  std::unique_ptr<QgsVectorLayer> layerClone( layer()->clone() );
337  QgsFeatureIterator fi = layerClone->getFeatures( request );
338  if ( fi.nextFeature( tmp ) )
339  original = tmp.attribute( mFieldIndex );
340  }
341  }
342  else
343  {
344  mBuffer->mChangedAttributeValues[mFid][mFieldIndex] = mOldValue;
345  }
346  emit mBuffer->attributeValueChanged( mFid, mFieldIndex, original );
347  }
348 }
349 
351 {
352  QgsAttributeMap map;
353  map.insert( mFieldIndex, mNewValue );
354  QgsChangedAttributesMap attribMap;
355  attribMap.insert( mFid, map );
357  if ( setSavePoint() && mBuffer->L->dataProvider()->changeAttributeValues( attribMap ) && ! mBuffer->L->dataProvider()->hasErrors() )
358  {
359  // Update existing feature
360  QgsFeatureMap::iterator it = mBuffer->mAddedFeatures.find( mFid );
361  if ( it != mBuffer->mAddedFeatures.end() )
362  {
363  it.value().setAttribute( mFieldIndex, mNewValue );
364  }
365  else
366  {
367  // changed attribute of existing feature
368  if ( !mBuffer->mChangedAttributeValues.contains( mFid ) )
369  {
371  }
372 
373  mBuffer->mChangedAttributeValues[mFid].insert( mFieldIndex, mNewValue );
374  }
375  emit mBuffer->attributeValueChanged( mFid, mFieldIndex, mNewValue );
376  }
377  else
378  {
379  setError();
380  }
381 }
382 
384  : QgsVectorLayerUndoPassthroughCommand( buffer, QObject::tr( "add attribute" ) + " " + field.name() )
385  , mField( field )
386 {
387 }
388 
390 {
391  // note that the deleteAttribute here is only necessary to inform the provider that
392  // an attribute is removed after the rollBackToSavePoint
393  const int attr = mBuffer->L->dataProvider()->fieldNameIndex( mField.name() );
394  if ( rollBackToSavePoint() )
395  {
397  mBuffer->mAddedAttributes.removeAll( mField );
399  emit mBuffer->attributeDeleted( attr );
400  }
401  else
402  {
403  setError();
404  }
405 }
406 
408 {
410  if ( setSavePoint() && mBuffer->L->dataProvider()->addAttributes( QList<QgsField>() << mField ) && ! mBuffer->L->dataProvider()->hasErrors() )
411  {
413  const int attr = mBuffer->L->dataProvider()->fieldNameIndex( mField.name() );
414  mBuffer->mAddedAttributes.append( mField );
415  emit mBuffer->attributeAdded( attr );
416  }
417  else
418  {
419  setError();
420  }
421 }
422 
424  : QgsVectorLayerUndoPassthroughCommand( buffer, QObject::tr( "delete attribute" ) )
425  , mField( mBuffer->L->fields()[ attr ] )
426  , mOriginalFieldIndex( attr )
427 {
428 }
429 
431 {
432  // note that the addAttributes here is only necessary to inform the provider that
433  // an attribute is added back after the rollBackToSavePoint
435  if ( mBuffer->L->dataProvider()->addAttributes( QList<QgsField>() << mField ) && rollBackToSavePoint() && ! mBuffer->L->dataProvider()->hasErrors() )
436  {
437  mBuffer->mDeletedAttributeIds.removeOne( mOriginalFieldIndex );
439  emit mBuffer->attributeAdded( mOriginalFieldIndex );
440  }
441  else
442  {
443  setError();
444  }
445 }
446 
448 {
450  if ( setSavePoint() && mBuffer->L->dataProvider()->deleteAttributes( QgsAttributeIds() << mOriginalFieldIndex ) && ! mBuffer->L->dataProvider()->hasErrors() )
451  {
452  mBuffer->mDeletedAttributeIds.append( mOriginalFieldIndex );
454  emit mBuffer->attributeDeleted( mOriginalFieldIndex );
455  }
456  else
457  {
458  setError();
459  }
460 }
461 
463  : QgsVectorLayerUndoPassthroughCommand( buffer, QObject::tr( "rename attribute" ) + " " + newName )
464  , mAttr( attr )
465  , mNewName( newName )
466  , mOldName( mBuffer->L->fields()[ mAttr ].name() )
467 {
468 }
469 
471 {
472  // note that the renameAttributes here is only necessary to inform the provider that
473  // an attribute is renamed after the rollBackToSavePoint
474  QgsFieldNameMap map;
475  map[ mAttr ] = mOldName;
478  {
480  emit mBuffer->attributeRenamed( mAttr, mOldName );
481  }
482  else
483  {
484  setError();
485  }
486 }
487 
489 {
490  QgsFieldNameMap map;
491  map[ mAttr ] = mNewName;
494  {
496  emit mBuffer->attributeRenamed( mAttr, mNewName );
497  }
498  else
499  {
500  setError();
501  }
502 }
503 
505  : QgsVectorLayerUndoPassthroughCommand( buffer, name.isEmpty() ? QObject::tr( "custom transaction" ) : name, false )
506  , mTransaction( transaction )
507  , mSql( sql )
508 {
509 }
510 
512 {
513  if ( rollBackToSavePoint() )
514  {
515  mUndone = true;
516  emit mBuffer->L->layerModified();
517  }
518  else
519  {
520  setError();
521  }
522 }
523 
525 {
526  // the first time that the sql query is execute is within QgsTransaction
527  // itself. So the redo has to be executed only after an undo action.
528  if ( mUndone )
529  {
530  QString errorMessage;
531 
532  QString savePointId = mTransaction->createSavepoint( errorMessage );
533 
534  if ( errorMessage.isEmpty() )
535  {
536  setSavePoint( savePointId );
537 
538  if ( mTransaction->executeSql( mSql, errorMessage ) )
539  {
540  mUndone = false;
541  }
542  else
543  {
545  setError();
546  }
547  }
548  else
549  {
551  setError();
552  }
553  }
554 }
555 
557  : QgsVectorLayerUndoPassthroughCommand( buffer, QObject::tr( "change attribute value" ) )
558  , mFid( fid )
559  , mNewValues( newValues )
560  , mOldValues( oldValues )
561 {
562  if ( mOldValues.isEmpty() )
563  {
564  const auto oldAttrs( mBuffer->L->getFeature( mFid ).attributes() );
565  for ( auto it = mNewValues.constBegin(); it != mNewValues.constEnd(); ++it )
566  {
567  mOldValues[ it.key() ] = oldAttrs[ it.key() ];
568  }
569  }
570  const bool isAdded { mBuffer->mAddedFeatures.contains( mFid ) };
571  for ( auto it = mNewValues.constBegin(); it != mNewValues.constEnd(); ++it )
572  {
573  if ( isAdded && mBuffer->mAddedFeatures[ mFid ].attribute( it.key() ).isValid() )
574  {
575  mFirstChanges[ it.key() ] = false;
576  }
577  else if ( mBuffer->mChangedAttributeValues.contains( mFid ) && mBuffer->mChangedAttributeValues[mFid].contains( it.key() ) )
578  {
579  mFirstChanges[ it.key() ] = false;
580  }
581  else
582  {
583  mFirstChanges[ it.key() ] = true;
584  }
585  }
586 }
587 
589 {
590  if ( rollBackToSavePoint() )
591  {
592  QgsFeatureMap::iterator addedIt = mBuffer->mAddedFeatures.find( mFid );
593  for ( auto it = mNewValues.constBegin(); it != mNewValues.constEnd(); ++it )
594  {
595  const auto fieldIndex { it.key() };
596  if ( addedIt != mBuffer->mAddedFeatures.end() )
597  {
598  addedIt.value().setAttribute( fieldIndex, mOldValues[ it.key() ] );
599  }
600  else if ( mFirstChanges.contains( fieldIndex ) && mFirstChanges[ fieldIndex ] )
601  {
602  // existing feature
603  mBuffer->mChangedAttributeValues[mFid].remove( fieldIndex );
604  }
605  else
606  {
607  // changed attribute of existing feature
608  if ( !mBuffer->mChangedAttributeValues.contains( mFid ) )
609  {
611  }
612  mBuffer->mChangedAttributeValues[mFid].insert( fieldIndex, mOldValues[ it.key() ] );
613  }
614  emit mBuffer->attributeValueChanged( mFid, it.key(), mOldValues[ it.key() ] );
615  }
616  if ( mBuffer->mChangedAttributeValues[mFid].isEmpty() )
617  mBuffer->mChangedAttributeValues.remove( mFid );
618  }
619 }
620 
622 {
623  QgsChangedAttributesMap attribMap;
624  attribMap.insert( mFid, mNewValues );
626  if ( setSavePoint() && mBuffer->L->dataProvider()->changeAttributeValues( attribMap ) && ! mBuffer->L->dataProvider()->hasErrors() )
627  {
628  QgsFeatureMap::iterator addedIt = mBuffer->mAddedFeatures.find( mFid );
629  for ( auto it = mNewValues.constBegin(); it != mNewValues.constEnd(); ++it )
630  {
631  const auto fieldIndex { it.key() };
632  // Update existing feature
633  if ( addedIt != mBuffer->mAddedFeatures.end() )
634  {
635  addedIt.value().setAttribute( fieldIndex, it.value() );
636  }
637  else
638  {
639  // changed attribute of existing feature
640  if ( !mBuffer->mChangedAttributeValues.contains( mFid ) )
641  {
643  }
644  mBuffer->mChangedAttributeValues[mFid].insert( fieldIndex, it.value() );
645  }
646  emit mBuffer->attributeValueChanged( mFid, it.key(), it.value() );
647  }
648  }
649 }
Wrapper for iterator of features from vector data provider or vector layer.
bool nextFeature(QgsFeature &f)
This class wraps a request for features to a vector layer (or directly its vector data provider).
QgsFeatureRequest & setFlags(QgsFeatureRequest::Flags flags)
Sets flags that affect how features will be fetched.
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
@ NoGeometry
Geometry is not required. It may still be returned if e.g. required for a filter condition.
QgsFeatureRequest & setFilterFid(QgsFeatureId fid)
Sets feature ID that should be fetched.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition: qgsfeature.h:56
QgsAttributes attributes
Definition: qgsfeature.h:65
QVariant attribute(const QString &name) const
Lookup attribute value by attribute name.
Definition: qgsfeature.cpp:302
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:51
QString name
Definition: qgsfield.h:60
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:124
This class allows including a set of layers in a database-side transaction, provided the layer data p...
QList< QString > savePoints() const
returns savepoints
bool rollbackToSavepoint(const QString &name, QString &error)
rollback to save point, the save point is maintained and is "undertied"
virtual bool executeSql(const QString &sql, QString &error, bool isDirty=false, const QString &name=QString())=0
Execute the sql string.
QString createSavepoint(QString &error)
creates a save point returns empty string on error returns the last created savepoint if it's not dir...
virtual bool changeGeometryValues(const QgsGeometryMap &geometry_map)
Changes geometries of existing features.
void clearErrors()
Clear recorded errors.
int fieldNameIndex(const QString &fieldName) const
Returns the index of a field name or -1 if the field does not exist.
virtual bool changeAttributeValues(const QgsChangedAttributesMap &attr_map)
Changes attribute values of existing features.
virtual bool deleteFeatures(const QgsFeatureIds &id)
Deletes one or more features from the provider.
bool addFeatures(QgsFeatureList &flist, QgsFeatureSink::Flags flags=QgsFeatureSink::Flags()) override
Adds a list of features to the sink.
virtual bool addAttributes(const QList< QgsField > &attributes)
Adds new attributes to the provider.
virtual QgsTransaction * transaction() const
Returns the transaction this data provider is included in, if any.
virtual bool renameAttributes(const QgsFieldNameMap &renamedAttributes)
Renames existing attributes.
virtual bool deleteAttributes(const QgsAttributeIds &attributes)
Deletes existing attributes from the provider.
bool hasErrors() const
Provider has errors to report.
void attributeRenamed(int idx, const QString &newName)
Emitted when an attribute has been renamed.
QgsFeatureMap mAddedFeatures
New features which are not committed.
void geometryChanged(QgsFeatureId fid, const QgsGeometry &geom)
Emitted when a feature's geometry is changed.
QgsGeometryMap mChangedGeometries
Changed geometries which are not committed.
QgsAttributeList mDeletedAttributeIds
Deleted attributes fields which are not committed. The list is kept sorted.
QgsFeatureIds mDeletedFeatureIds
Deleted feature IDs which are not committed.
void featureDeleted(QgsFeatureId fid)
void attributeAdded(int idx)
void attributeDeleted(int idx)
void featureAdded(QgsFeatureId fid)
void attributeValueChanged(QgsFeatureId fid, int idx, const QVariant &)
QgsChangedAttributesMap mChangedAttributeValues
Changed attributes values which are not committed.
QList< QgsField > mAddedAttributes
Added attributes fields which are not committed.
Base class for undo commands within a QgsVectorLayerEditBuffer.
QgsVectorLayer * layer()
Returns the layer associated with the undo command.
QgsVectorLayerEditBuffer * mBuffer
Associated edit buffer.
QgsVectorLayerUndoPassthroughCommandAddAttribute(QgsVectorLayerEditBuffer *buffer, const QgsField &field)
Constructor for QgsVectorLayerUndoPassthroughCommandAddAttribute.
QgsFeatureList features() const
List of features (added feaures can be modified by default values from database)
QgsVectorLayerUndoPassthroughCommandAddFeatures(QgsVectorLayerEditBuffer *buffer, QgsFeatureList &features)
Constructor for QgsVectorLayerUndoPassthroughCommandAddFeatures.
QgsVectorLayerUndoPassthroughCommandChangeAttribute(QgsVectorLayerEditBuffer *buffer, QgsFeatureId fid, int field, const QVariant &newValue)
Constructor for QgsVectorLayerUndoPassthroughCommandChangeAttribute.
QgsVectorLayerUndoPassthroughCommandChangeAttributes(QgsVectorLayerEditBuffer *buffer, QgsFeatureId fid, const QgsAttributeMap &newValues, const QgsAttributeMap &oldValues=QgsAttributeMap())
Constructor for QgsVectorLayerUndoPassthroughCommandChangeAttributes.
Undo command for changing feature geometry from a vector layer in transaction group.
QgsVectorLayerUndoPassthroughCommandChangeGeometry(QgsVectorLayerEditBuffer *buffer, QgsFeatureId fid, const QgsGeometry &geom)
Constructor for QgsVectorLayerUndoPassthroughCommandChangeGeometry.
QgsVectorLayerUndoPassthroughCommandDeleteAttribute(QgsVectorLayerEditBuffer *buffer, int attr)
Constructor for QgsVectorLayerUndoCommandDeleteAttribute.
QgsVectorLayerUndoPassthroughCommandDeleteFeatures(QgsVectorLayerEditBuffer *buffer, const QgsFeatureIds &fids)
Constructor for QgsVectorLayerUndoPassthroughCommandDeleteFeatures.
QgsVectorLayerUndoPassthroughCommandRenameAttribute(QgsVectorLayerEditBuffer *buffer, int attr, const QString &newName)
Constructor for QgsVectorLayerUndoCommandRenameAttribute.
QgsVectorLayerUndoPassthroughCommandUpdate(QgsVectorLayerEditBuffer *buffer, QgsTransaction *transaction, const QString &sql, const QString &name)
Constructor for QgsVectorLayerUndoCommandUpdate.
Undo command for vector layer in transaction group mode.
QgsVectorLayerUndoPassthroughCommand(QgsVectorLayerEditBuffer *buffer, const QString &text, bool autocreate=true)
Constructor for QgsVectorLayerUndoPassthroughCommand.
QString errorMessage() const
Returns the error message or an empty string if there's none.
void setErrorMessage(const QString &errorMessage)
Sets the error message.
void setError()
Set error flag and append "failed" to text.
bool setSavePoint(const QString &savePointId=QString())
Set the command savepoint or set error status.
bool rollBackToSavePoint()
Rollback command, release savepoint or set error status save point must be set prior to call error sa...
void layerModified()
Emitted when modifications has been done on layer.
QgsVectorDataProvider * dataProvider() FINAL
Returns the layer's data provider, it may be nullptr.
QgsFeature getFeature(QgsFeatureId fid) const
Queries the layer for the feature with the given id.
QMap< int, QString > QgsFieldNameMap
Definition: qgsattributes.h:44
QMap< int, QVariant > QgsAttributeMap
Definition: qgsattributes.h:38
QMap< QgsFeatureId, QgsGeometry > QgsGeometryMap
Definition: qgsfeature.h:731
QMap< QgsFeatureId, QgsAttributeMap > QgsChangedAttributesMap
Definition: qgsfeature.h:722
QList< QgsFeature > QgsFeatureList
Definition: qgsfeature.h:736
QSet< QgsFeatureId > QgsFeatureIds
Definition: qgsfeatureid.h:37
qint64 QgsFeatureId
64 bit feature ids negative numbers are used for uncommitted/newly added features
Definition: qgsfeatureid.h:28
QList< int > QgsAttributeList
Definition: qgsfield.h:26
const QgsField & field
Definition: qgsfield.h:463
QSet< int > QgsAttributeIds