QGIS API Documentation 3.99.0-Master (2fe06baccd8)
Loading...
Searching...
No Matches
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 "qgsfeature.h"
19#include "qgsfeatureiterator.h"
20#include "qgsgeometry.h"
21#include "qgslogger.h"
22#include "qgstransaction.h"
23#include "qgsvectorlayer.h"
25
26#include <QUuid>
27
28// TODO use setObsolete instead of mHasError when upgrading qt version, this will allow auto removal of the command
29// for the moment a errored command is left on the stack
30
33 , mSavePointId( ( mBuffer->L->isEditCommandActive() && !mBuffer->L->dataProvider()->transaction()->savePoints().isEmpty() )
34 || !autocreate
35 ? mBuffer->L->dataProvider()->transaction()->savePoints().last()
36 : mBuffer->L->dataProvider()->transaction()->createSavepoint( mError ) )
37 , mHasError( !mError.isEmpty() )
38 , mRecreateSavePoint( mBuffer->L->isEditCommandActive()
39 ? !mBuffer->L->dataProvider()->transaction()->lastSavePointIsDirty()
40 : true )
41{
42 // the first command in the undo stack macro will have a clean save point
43 // the first command is responsible to re-create the savepoint after undo
44 setText( text );
45}
46
47
49{
50 if ( !mHasError )
51 {
52 setText( text() + " " + QObject::tr( "failed" ) );
53 mHasError = true;
54 }
55}
56
61
63{
64 return mError;
65}
66
68{
69 if ( !hasError() )
70 {
71 if ( savePointId.isEmpty() )
72 {
73 // re-create savepoint only if mRecreateSavePoint and rollBackToSavePoint as occurred
74 if ( mRecreateSavePoint && mBuffer->L->dataProvider()->transaction()->savePoints().indexOf( mSavePointId ) == -1 )
75 {
76 mSavePointId = mBuffer->L->dataProvider()->transaction()->createSavepoint( mSavePointId, mError );
77 if ( mSavePointId.isEmpty() )
78 {
79 setError();
80 }
81 }
82 }
83 else
84 {
85 mSavePointId = savePointId;
86 }
87 }
88 return !hasError();
89}
90
92{
93 // rollback only occurs for the last command in undo macro
94 if ( !hasError() && mBuffer->L->dataProvider()->transaction()->savePoints().indexOf( mSavePointId ) != -1 )
95 {
96 if ( !mBuffer->L->dataProvider()->transaction()->rollbackToSavepoint( mSavePointId, mError ) )
97 {
98 setError();
99 }
100 }
101 return !hasError();
102}
103
104
106 : QgsVectorLayerUndoPassthroughCommand( buffer, QObject::tr( "add features" ) )
107{
108 static int sAddedIdLowWaterMark = -1;
109 for ( const QgsFeature &f : std::as_const( features ) )
110 {
111 mInitialFeatures << f;
112 //assign a temporary id to the feature (use negative numbers)
113 sAddedIdLowWaterMark--;
114 mInitialFeatures.last().setId( sAddedIdLowWaterMark );
115 }
116 mFeatures = mInitialFeatures;
117
118}
119
121{
122 if ( rollBackToSavePoint() )
123 {
124 for ( const QgsFeature &f : std::as_const( mFeatures ) )
125 {
126 mBuffer->mAddedFeatures.remove( f.id() );
127 emit mBuffer->featureDeleted( f.id() );
128 }
129 mFeatures = mInitialFeatures;
130 }
131}
132
134{
135 mFeatures = mInitialFeatures;
136 mBuffer->L->dataProvider()->clearErrors();
137 if ( setSavePoint() && mBuffer->L->dataProvider()->addFeatures( mFeatures ) && ! mBuffer->L->dataProvider()->hasErrors() )
138 {
139 for ( const QgsFeature &f : std::as_const( mFeatures ) )
140 {
141 mBuffer->mAddedFeatures.insert( f.id(), f );
142 emit mBuffer->featureAdded( f.id() );
143 }
144 }
145 else
146 {
147 setError();
148 }
149}
150
156
158{
159 if ( rollBackToSavePoint() )
160 {
161 for ( const QgsFeatureId &fid : mFids )
162 {
163 mBuffer->mDeletedFeatureIds.remove( fid );
164 if ( mDeletedNewFeatures.contains( fid ) )
165 {
166 mBuffer->mAddedFeatures.insert( fid, mDeletedNewFeatures.value( fid ) );
167 }
168 emit mBuffer->featureAdded( fid );
169 }
170 }
171}
172
174{
175 mBuffer->L->dataProvider()->clearErrors();
176 if ( setSavePoint() && mBuffer->L->dataProvider()->deleteFeatures( mFids ) && ! mBuffer->L->dataProvider()->hasErrors() )
177 {
178 mDeletedNewFeatures.clear();
179 for ( const QgsFeatureId &fid : mFids )
180 {
181 if ( mBuffer->mAddedFeatures.contains( fid ) )
182 {
183 mDeletedNewFeatures.insert( fid, mBuffer->mAddedFeatures[ fid ] );
184 mBuffer->mAddedFeatures.remove( fid );
185 }
186 else
187 {
188 mBuffer->mDeletedFeatureIds.insert( fid );
189 }
190 emit mBuffer->featureDeleted( fid );
191 }
192 }
193 else
194 {
195 setError();
196 }
197}
198
200 : QgsVectorLayerUndoPassthroughCommand( buffer, QObject::tr( "change geometry" ) )
201 , mFid( fid )
202 , mNewGeom( geom )
203 , mOldGeom( mBuffer->L->getFeature( mFid ).geometry() )
204{
205 if ( mBuffer->mAddedFeatures.contains( mFid ) )
206 {
207 mFirstChange = false;
208 }
209 else if ( mBuffer->mChangedGeometries.contains( mFid ) )
210 {
211 mFirstChange = false;
212 mOldGeom = mBuffer->mChangedGeometries[mFid];
213 }
214}
215
217{
218 if ( rollBackToSavePoint() )
219 {
220 if ( mBuffer->mAddedFeatures.contains( mFid ) )
221 {
222 mBuffer->mAddedFeatures[ mFid ].setGeometry( mOldGeom );
223 }
224 else if ( mFirstChange )
225 {
226 mBuffer->mChangedGeometries.remove( mFid );
227 }
228 else
229 {
230 mBuffer->mChangedGeometries[mFid] = mOldGeom;
231 }
232 emit mBuffer->geometryChanged( mFid, mOldGeom );
233 }
234}
235
237{
238 QgsGeometryMap geomMap;
239 geomMap.insert( mFid, mNewGeom );
240 mBuffer->L->dataProvider()->clearErrors();
241 if ( setSavePoint() && mBuffer->L->dataProvider()->changeGeometryValues( geomMap ) && ! mBuffer->L->dataProvider()->hasErrors() )
242 {
243 if ( mBuffer->mAddedFeatures.contains( mFid ) )
244 {
245 mBuffer->mAddedFeatures[ mFid ].setGeometry( mNewGeom );
246 }
247 else
248 {
249 mBuffer->mChangedGeometries[ mFid ] = mNewGeom;
250 }
251 emit mBuffer->geometryChanged( mFid, mNewGeom );
252 }
253 else
254 {
255 setError();
256 }
257}
258
260{
261 if ( other->id() != id() )
262 return false;
263
265 if ( !merge )
266 return false;
267
268 if ( merge->mFid != mFid )
269 return false;
270
271 mNewGeom = merge->mNewGeom;
272 merge->mNewGeom = QgsGeometry();
273
274 return true;
275}
276
277
278
280 : QgsVectorLayerUndoPassthroughCommand( buffer, QObject::tr( "change attribute value" ) )
281 , mFid( fid )
282 , mFieldIndex( field )
283 , mNewValue( newValue )
284 , mOldValue( mBuffer->L->getFeature( mFid ).attribute( field ) )
285{
286
287 if ( mBuffer->mAddedFeatures.contains( mFid ) )
288 {
289 // work with added feature
290 QgsFeatureMap::const_iterator it = mBuffer->mAddedFeatures.constFind( mFid );
291 Q_ASSERT( it != mBuffer->mAddedFeatures.constEnd() );
292 if ( it.value().attribute( mFieldIndex ).isValid() )
293 {
294 mOldValue = it.value().attribute( mFieldIndex );
295 mFirstChange = false;
296 }
297 }
298 else if ( mBuffer->mChangedAttributeValues.contains( mFid ) && mBuffer->mChangedAttributeValues[mFid].contains( mFieldIndex ) )
299 {
300 mOldValue = mBuffer->mChangedAttributeValues[mFid][mFieldIndex];
301 mFirstChange = false;
302 }
303}
304
306{
307 if ( rollBackToSavePoint() )
308 {
309 QVariant original = mOldValue;
310
311 if ( mBuffer->mAddedFeatures.contains( mFid ) )
312 {
313 // added feature
314 QgsFeatureMap::iterator it = mBuffer->mAddedFeatures.find( mFid );
315 Q_ASSERT( it != mBuffer->mAddedFeatures.end() );
316 it.value().setAttribute( mFieldIndex, mOldValue );
317 }
318 else if ( mFirstChange )
319 {
320 // existing feature
321 mBuffer->mChangedAttributeValues[mFid].remove( mFieldIndex );
322 if ( mBuffer->mChangedAttributeValues[mFid].isEmpty() )
323 mBuffer->mChangedAttributeValues.remove( mFid );
324
325 if ( !mOldValue.isValid() )
326 {
327 // get old value from provider
328 QgsFeature tmp;
329 QgsFeatureRequest request;
330 request.setFilterFid( mFid );
332 request.setSubsetOfAttributes( QgsAttributeList() << mFieldIndex );
333 std::unique_ptr<QgsVectorLayer> layerClone( layer()->clone() );
334 QgsFeatureIterator fi = layerClone->getFeatures( request );
335 if ( fi.nextFeature( tmp ) )
336 original = tmp.attribute( mFieldIndex );
337 }
338 }
339 else
340 {
341 mBuffer->mChangedAttributeValues[mFid][mFieldIndex] = mOldValue;
342 }
343 emit mBuffer->attributeValueChanged( mFid, mFieldIndex, original );
344 }
345}
346
348{
349 QgsAttributeMap map;
350 map.insert( mFieldIndex, mNewValue );
351 QgsChangedAttributesMap attribMap;
352 attribMap.insert( mFid, map );
353 mBuffer->L->dataProvider()->clearErrors();
354 if ( setSavePoint() && mBuffer->L->dataProvider()->changeAttributeValues( attribMap ) && ! mBuffer->L->dataProvider()->hasErrors() )
355 {
356 // Update existing feature
357 QgsFeatureMap::iterator it = mBuffer->mAddedFeatures.find( mFid );
358 if ( it != mBuffer->mAddedFeatures.end() )
359 {
360 it.value().setAttribute( mFieldIndex, mNewValue );
361 }
362 else
363 {
364 // changed attribute of existing feature
365 if ( !mBuffer->mChangedAttributeValues.contains( mFid ) )
366 {
367 mBuffer->mChangedAttributeValues.insert( mFid, QgsAttributeMap() );
368 }
369
370 mBuffer->mChangedAttributeValues[mFid].insert( mFieldIndex, mNewValue );
371 }
372 emit mBuffer->attributeValueChanged( mFid, mFieldIndex, mNewValue );
373 }
374 else
375 {
376 setError();
377 }
378}
379
381 : QgsVectorLayerUndoPassthroughCommand( buffer, QObject::tr( "add attribute" ) + " " + field.name() )
382 , mField( field )
383{
384}
385
387{
388 // note that the deleteAttribute here is only necessary to inform the provider that
389 // an attribute is removed after the rollBackToSavePoint
390 const int attr = mBuffer->L->dataProvider()->fieldNameIndex( mField.name() );
391 if ( rollBackToSavePoint() )
392 {
393 // GDAL SQLite-based drivers (since version 3.11) keep the fields in sync with
394 // the backend after a rollback, to stay on the safe side check if the field
395 // isn't already gone
396 if ( mBuffer->L->dataProvider()->fieldNameIndex( mField.name() ) != -1 )
397 {
398 ( void )mBuffer->L->dataProvider()->deleteAttributes( QgsAttributeIds() << attr );
399 }
400 mBuffer->mAddedAttributes.removeAll( mField );
401 mBuffer->updateLayerFields();
402 emit mBuffer->attributeDeleted( attr );
403 }
404 else
405 {
406 setError();
407 }
408}
409
411{
412 mBuffer->L->dataProvider()->clearErrors();
413 if ( setSavePoint() && mBuffer->L->dataProvider()->addAttributes( QList<QgsField>() << mField ) && ! mBuffer->L->dataProvider()->hasErrors() )
414 {
415 mBuffer->updateLayerFields();
416 const int attr = mBuffer->L->dataProvider()->fieldNameIndex( mField.name() );
417 mBuffer->mAddedAttributes.append( mField );
418 emit mBuffer->attributeAdded( attr );
419 }
420 else
421 {
422 setError();
423 }
424}
425
427 : QgsVectorLayerUndoPassthroughCommand( buffer, QObject::tr( "delete attribute" ) )
428 , mField( mBuffer->L->fields()[ attr ] )
429 , mOriginalFieldIndex( attr )
430{
431}
432
434{
435 // note that the addAttributes here is only necessary to inform the provider that
436 // an attribute is added back after the rollBackToSavePoint
437 mBuffer->L->dataProvider()->clearErrors();
438 if ( rollBackToSavePoint() )
439 {
440 // GDA SQLite-based drivers (since version 3.11) keep the fields in sync with
441 // the backend after a rollback, to stay on the safe side check if the field
442 // isn't already there
443 bool ok = true;
444 if ( mBuffer->L->dataProvider()->fields().indexFromName( mField.name() ) == -1 )
445 {
446 ok = mBuffer->L->dataProvider()->addAttributes( QList<QgsField>() << mField );
447 }
448 if ( ok && ! mBuffer->L->dataProvider()->hasErrors() )
449 {
450 mBuffer->mDeletedAttributeIds.removeOne( mOriginalFieldIndex );
451 mBuffer->updateLayerFields();
452 emit mBuffer->attributeAdded( mOriginalFieldIndex );
453 }
454 else
455 {
456 setError();
457 }
458 }
459 else
460 {
461 setError();
462 }
463}
464
466{
467 mBuffer->L->dataProvider()->clearErrors();
468 if ( setSavePoint() && mBuffer->L->dataProvider()->deleteAttributes( QgsAttributeIds() << mOriginalFieldIndex ) && ! mBuffer->L->dataProvider()->hasErrors() )
469 {
470 mBuffer->mDeletedAttributeIds.append( mOriginalFieldIndex );
471 mBuffer->updateLayerFields();
472 emit mBuffer->attributeDeleted( mOriginalFieldIndex );
473 }
474 else
475 {
476 setError();
477 }
478}
479
481 : QgsVectorLayerUndoPassthroughCommand( buffer, QObject::tr( "rename attribute" ) + " " + newName )
482 , mAttr( attr )
483 , mNewName( newName )
484 , mOldName( mBuffer->L->fields()[ mAttr ].name() )
485{
486}
487
489{
490 // note that the renameAttributes here is only necessary to inform the provider that
491 // an attribute is renamed after the rollBackToSavePoint
492 QgsFieldNameMap map;
493 map[ mAttr ] = mOldName;
494 mBuffer->L->dataProvider()->clearErrors();
495 if ( rollBackToSavePoint() )
496 {
497 // GDAL SQLite-based drivers (since version 3.11) keep the fields in sync with
498 // the backend after a rollback, to stay on the safe side check if the field
499 // isn't already renamed
500 bool ok = true;
501 if ( mBuffer->L->dataProvider()->fields().indexFromName( mOldName ) == -1 )
502 {
503 ok = mBuffer->L->dataProvider()->renameAttributes( map );
504 }
505 if ( ok && ! mBuffer->L->dataProvider()->hasErrors() )
506 {
507 mBuffer->updateLayerFields();
508 emit mBuffer->attributeRenamed( mAttr, mOldName );
509 }
510 else
511 {
512 setError();
513 }
514 }
515 else
516 {
517 setError();
518 }
519}
520
522{
523 QgsFieldNameMap map;
524 map[ mAttr ] = mNewName;
525 mBuffer->L->dataProvider()->clearErrors();
526 if ( setSavePoint() && mBuffer->L->dataProvider()->renameAttributes( map ) && ! mBuffer->L->dataProvider()->hasErrors() )
527 {
528 mBuffer->updateLayerFields();
529 emit mBuffer->attributeRenamed( mAttr, mNewName );
530 }
531 else
532 {
533 setError();
534 }
535}
536
538 : QgsVectorLayerUndoPassthroughCommand( buffer, name.isEmpty() ? QObject::tr( "custom transaction" ) : name, false )
539 , mTransaction( transaction )
540 , mSql( sql )
541{
542}
543
545{
546 if ( rollBackToSavePoint() )
547 {
548 mUndone = true;
549 emit mBuffer->L->layerModified();
550 }
551 else
552 {
553 setError();
554 }
555}
556
558{
559 // the first time that the sql query is execute is within QgsTransaction
560 // itself. So the redo has to be executed only after an undo action.
561 if ( mUndone )
562 {
563 QString errorMessage;
564
565 QString savePointId = mTransaction->createSavepoint( errorMessage );
566
567 if ( errorMessage.isEmpty() )
568 {
569 setSavePoint( savePointId );
570
571 if ( mTransaction->executeSql( mSql, errorMessage ) )
572 {
573 mUndone = false;
574 }
575 else
576 {
578 setError();
579 }
580 }
581 else
582 {
584 setError();
585 }
586 }
587}
588
590 : QgsVectorLayerUndoPassthroughCommand( buffer, QObject::tr( "change attribute value" ) )
591 , mFid( fid )
592 , mNewValues( newValues )
593 , mOldValues( oldValues )
594{
595 if ( mOldValues.isEmpty() )
596 {
597 const auto oldAttrs( mBuffer->L->getFeature( mFid ).attributes() );
598 for ( auto it = mNewValues.constBegin(); it != mNewValues.constEnd(); ++it )
599 {
600 mOldValues[ it.key() ] = oldAttrs[ it.key() ];
601 }
602 }
603 const bool isAdded { mBuffer->mAddedFeatures.contains( mFid ) };
604 for ( auto it = mNewValues.constBegin(); it != mNewValues.constEnd(); ++it )
605 {
606 if ( isAdded && mBuffer->mAddedFeatures[ mFid ].attribute( it.key() ).isValid() )
607 {
608 mFirstChanges[ it.key() ] = false;
609 }
610 else if ( mBuffer->mChangedAttributeValues.contains( mFid ) && mBuffer->mChangedAttributeValues[mFid].contains( it.key() ) )
611 {
612 mFirstChanges[ it.key() ] = false;
613 }
614 else
615 {
616 mFirstChanges[ it.key() ] = true;
617 }
618 }
619}
620
622{
623 if ( rollBackToSavePoint() )
624 {
625 QgsFeatureMap::iterator addedIt = mBuffer->mAddedFeatures.find( mFid );
626 for ( auto it = mNewValues.constBegin(); it != mNewValues.constEnd(); ++it )
627 {
628 const auto fieldIndex { it.key() };
629 if ( addedIt != mBuffer->mAddedFeatures.end() )
630 {
631 addedIt.value().setAttribute( fieldIndex, mOldValues[ it.key() ] );
632 }
633 else if ( mFirstChanges.contains( fieldIndex ) && mFirstChanges[ fieldIndex ] )
634 {
635 // existing feature
636 mBuffer->mChangedAttributeValues[mFid].remove( fieldIndex );
637 }
638 else
639 {
640 // changed attribute of existing feature
641 if ( !mBuffer->mChangedAttributeValues.contains( mFid ) )
642 {
643 mBuffer->mChangedAttributeValues.insert( mFid, QgsAttributeMap() );
644 }
645 mBuffer->mChangedAttributeValues[mFid].insert( fieldIndex, mOldValues[ it.key() ] );
646 }
647 emit mBuffer->attributeValueChanged( mFid, it.key(), mOldValues[ it.key() ] );
648 }
649 if ( mBuffer->mChangedAttributeValues[mFid].isEmpty() )
650 mBuffer->mChangedAttributeValues.remove( mFid );
651 }
652}
653
655{
656 QgsChangedAttributesMap attribMap;
657 attribMap.insert( mFid, mNewValues );
658 mBuffer->L->dataProvider()->clearErrors();
659 if ( setSavePoint() && mBuffer->L->dataProvider()->changeAttributeValues( attribMap ) && ! mBuffer->L->dataProvider()->hasErrors() )
660 {
661 QgsFeatureMap::iterator addedIt = mBuffer->mAddedFeatures.find( mFid );
662 for ( auto it = mNewValues.constBegin(); it != mNewValues.constEnd(); ++it )
663 {
664 const auto fieldIndex { it.key() };
665 // Update existing feature
666 if ( addedIt != mBuffer->mAddedFeatures.end() )
667 {
668 addedIt.value().setAttribute( fieldIndex, it.value() );
669 }
670 else
671 {
672 // changed attribute of existing feature
673 if ( !mBuffer->mChangedAttributeValues.contains( mFid ) )
674 {
675 mBuffer->mChangedAttributeValues.insert( mFid, QgsAttributeMap() );
676 }
677 mBuffer->mChangedAttributeValues[mFid].insert( fieldIndex, it.value() );
678 }
679 emit mBuffer->attributeValueChanged( mFid, it.key(), it.value() );
680 }
681 }
682}
@ NoGeometry
Geometry is not required. It may still be returned if e.g. required for a filter condition.
Definition qgis.h:2196
Wrapper for iterator of features from vector data provider or vector layer.
bool nextFeature(QgsFeature &f)
Fetch next feature and stores in f, returns true on success.
Wraps a request for features to a vector layer (or directly its vector data provider).
QgsFeatureRequest & setFlags(Qgis::FeatureRequestFlags flags)
Sets flags that affect how features will be fetched.
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
QgsFeatureRequest & setFilterFid(QgsFeatureId fid)
Sets the 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:58
Q_INVOKABLE QVariant attribute(const QString &name) const
Lookup attribute value by attribute name.
Encapsulate a field in an attribute table or data source.
Definition qgsfield.h:54
A geometry is the spatial representation of a feature.
Allows creation of a multi-layer database-side transaction.
Stores queued vector layer edit operations prior to committing changes to the layer's data provider.
QgsVectorLayer * layer()
Returns the layer associated with the undo command.
QgsVectorLayerUndoCommand(QgsVectorLayerEditBuffer *buffer)
Constructor for QgsVectorLayerUndoCommand.
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.
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.
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...
QMap< int, QString > QgsFieldNameMap
QMap< int, QVariant > QgsAttributeMap
QMap< QgsFeatureId, QgsGeometry > QgsGeometryMap
QMap< QgsFeatureId, QgsAttributeMap > QgsChangedAttributesMap
QList< QgsFeature > QgsFeatureList
QSet< QgsFeatureId > QgsFeatureIds
qint64 QgsFeatureId
64 bit feature ids negative numbers are used for uncommitted/newly added features
QList< int > QgsAttributeList
Definition qgsfield.h:28
QSet< int > QgsAttributeIds