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