QGIS API Documentation 3.99.0-Master (26c88405ac0)
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 , mFirstChange( true )
205{
206 if ( mBuffer->mAddedFeatures.contains( mFid ) )
207 {
208 mFirstChange = false;
209 }
210 else if ( mBuffer->mChangedGeometries.contains( mFid ) )
211 {
212 mFirstChange = false;
213 mOldGeom = mBuffer->mChangedGeometries[mFid];
214 }
215}
216
218{
219 if ( rollBackToSavePoint() )
220 {
221 if ( mBuffer->mAddedFeatures.contains( mFid ) )
222 {
223 mBuffer->mAddedFeatures[ mFid ].setGeometry( mOldGeom );
224 }
225 else if ( mFirstChange )
226 {
227 mBuffer->mChangedGeometries.remove( mFid );
228 }
229 else
230 {
231 mBuffer->mChangedGeometries[mFid] = mOldGeom;
232 }
233 emit mBuffer->geometryChanged( mFid, mOldGeom );
234 }
235}
236
238{
239 QgsGeometryMap geomMap;
240 geomMap.insert( mFid, mNewGeom );
241 mBuffer->L->dataProvider()->clearErrors();
242 if ( setSavePoint() && mBuffer->L->dataProvider()->changeGeometryValues( geomMap ) && ! mBuffer->L->dataProvider()->hasErrors() )
243 {
244 if ( mBuffer->mAddedFeatures.contains( mFid ) )
245 {
246 mBuffer->mAddedFeatures[ mFid ].setGeometry( mNewGeom );
247 }
248 else
249 {
250 mBuffer->mChangedGeometries[ mFid ] = mNewGeom;
251 }
252 emit mBuffer->geometryChanged( mFid, mNewGeom );
253 }
254 else
255 {
256 setError();
257 }
258}
259
261{
262 if ( other->id() != id() )
263 return false;
264
266 if ( !merge )
267 return false;
268
269 if ( merge->mFid != mFid )
270 return false;
271
272 mNewGeom = merge->mNewGeom;
273 merge->mNewGeom = QgsGeometry();
274
275 return true;
276}
277
278
279
281 : QgsVectorLayerUndoPassthroughCommand( buffer, QObject::tr( "change attribute value" ) )
282 , mFid( fid )
283 , mFieldIndex( field )
284 , mNewValue( newValue )
285 , mOldValue( mBuffer->L->getFeature( mFid ).attribute( field ) )
286 , mFirstChange( true )
287{
288
289 if ( mBuffer->mAddedFeatures.contains( mFid ) )
290 {
291 // work with added feature
292 QgsFeatureMap::const_iterator it = mBuffer->mAddedFeatures.constFind( mFid );
293 Q_ASSERT( it != mBuffer->mAddedFeatures.constEnd() );
294 if ( it.value().attribute( mFieldIndex ).isValid() )
295 {
296 mOldValue = it.value().attribute( mFieldIndex );
297 mFirstChange = false;
298 }
299 }
300 else if ( mBuffer->mChangedAttributeValues.contains( mFid ) && mBuffer->mChangedAttributeValues[mFid].contains( mFieldIndex ) )
301 {
302 mOldValue = mBuffer->mChangedAttributeValues[mFid][mFieldIndex];
303 mFirstChange = false;
304 }
305}
306
308{
309 if ( rollBackToSavePoint() )
310 {
311 QVariant original = mOldValue;
312
313 if ( mBuffer->mAddedFeatures.contains( mFid ) )
314 {
315 // added feature
316 QgsFeatureMap::iterator it = mBuffer->mAddedFeatures.find( mFid );
317 Q_ASSERT( it != mBuffer->mAddedFeatures.end() );
318 it.value().setAttribute( mFieldIndex, mOldValue );
319 }
320 else if ( mFirstChange )
321 {
322 // existing feature
323 mBuffer->mChangedAttributeValues[mFid].remove( mFieldIndex );
324 if ( mBuffer->mChangedAttributeValues[mFid].isEmpty() )
325 mBuffer->mChangedAttributeValues.remove( mFid );
326
327 if ( !mOldValue.isValid() )
328 {
329 // get old value from provider
330 QgsFeature tmp;
331 QgsFeatureRequest request;
332 request.setFilterFid( mFid );
334 request.setSubsetOfAttributes( QgsAttributeList() << mFieldIndex );
335 std::unique_ptr<QgsVectorLayer> layerClone( layer()->clone() );
336 QgsFeatureIterator fi = layerClone->getFeatures( request );
337 if ( fi.nextFeature( tmp ) )
338 original = tmp.attribute( mFieldIndex );
339 }
340 }
341 else
342 {
343 mBuffer->mChangedAttributeValues[mFid][mFieldIndex] = mOldValue;
344 }
345 emit mBuffer->attributeValueChanged( mFid, mFieldIndex, original );
346 }
347}
348
350{
351 QgsAttributeMap map;
352 map.insert( mFieldIndex, mNewValue );
353 QgsChangedAttributesMap attribMap;
354 attribMap.insert( mFid, map );
355 mBuffer->L->dataProvider()->clearErrors();
356 if ( setSavePoint() && mBuffer->L->dataProvider()->changeAttributeValues( attribMap ) && ! mBuffer->L->dataProvider()->hasErrors() )
357 {
358 // Update existing feature
359 QgsFeatureMap::iterator it = mBuffer->mAddedFeatures.find( mFid );
360 if ( it != mBuffer->mAddedFeatures.end() )
361 {
362 it.value().setAttribute( mFieldIndex, mNewValue );
363 }
364 else
365 {
366 // changed attribute of existing feature
367 if ( !mBuffer->mChangedAttributeValues.contains( mFid ) )
368 {
369 mBuffer->mChangedAttributeValues.insert( mFid, QgsAttributeMap() );
370 }
371
372 mBuffer->mChangedAttributeValues[mFid].insert( mFieldIndex, mNewValue );
373 }
374 emit mBuffer->attributeValueChanged( mFid, mFieldIndex, mNewValue );
375 }
376 else
377 {
378 setError();
379 }
380}
381
383 : QgsVectorLayerUndoPassthroughCommand( buffer, QObject::tr( "add attribute" ) + " " + field.name() )
384 , mField( field )
385{
386}
387
389{
390 // note that the deleteAttribute here is only necessary to inform the provider that
391 // an attribute is removed after the rollBackToSavePoint
392 const int attr = mBuffer->L->dataProvider()->fieldNameIndex( mField.name() );
393 if ( rollBackToSavePoint() )
394 {
395 // GDAL SQLite-based drivers (since version 3.11) keep the fields in sync with
396 // the backend after a rollback, to stay on the safe side check if the field
397 // isn't already gone
398 if ( mBuffer->L->dataProvider()->fieldNameIndex( mField.name() ) != -1 )
399 {
400 ( void )mBuffer->L->dataProvider()->deleteAttributes( QgsAttributeIds() << attr );
401 }
402 mBuffer->mAddedAttributes.removeAll( mField );
403 mBuffer->updateLayerFields();
404 emit mBuffer->attributeDeleted( attr );
405 }
406 else
407 {
408 setError();
409 }
410}
411
413{
414 mBuffer->L->dataProvider()->clearErrors();
415 if ( setSavePoint() && mBuffer->L->dataProvider()->addAttributes( QList<QgsField>() << mField ) && ! mBuffer->L->dataProvider()->hasErrors() )
416 {
417 mBuffer->updateLayerFields();
418 const int attr = mBuffer->L->dataProvider()->fieldNameIndex( mField.name() );
419 mBuffer->mAddedAttributes.append( mField );
420 emit mBuffer->attributeAdded( attr );
421 }
422 else
423 {
424 setError();
425 }
426}
427
429 : QgsVectorLayerUndoPassthroughCommand( buffer, QObject::tr( "delete attribute" ) )
430 , mField( mBuffer->L->fields()[ attr ] )
431 , mOriginalFieldIndex( attr )
432{
433}
434
436{
437 // note that the addAttributes here is only necessary to inform the provider that
438 // an attribute is added back after the rollBackToSavePoint
439 mBuffer->L->dataProvider()->clearErrors();
440 if ( rollBackToSavePoint() )
441 {
442 // GDA SQLite-based drivers (since version 3.11) keep the fields in sync with
443 // the backend after a rollback, to stay on the safe side check if the field
444 // isn't already there
445 bool ok = true;
446 if ( mBuffer->L->dataProvider()->fields().indexFromName( mField.name() ) == -1 )
447 {
448 ok = mBuffer->L->dataProvider()->addAttributes( QList<QgsField>() << mField );
449 }
450 if ( ok && ! mBuffer->L->dataProvider()->hasErrors() )
451 {
452 mBuffer->mDeletedAttributeIds.removeOne( mOriginalFieldIndex );
453 mBuffer->updateLayerFields();
454 emit mBuffer->attributeAdded( mOriginalFieldIndex );
455 }
456 else
457 {
458 setError();
459 }
460 }
461 else
462 {
463 setError();
464 }
465}
466
468{
469 mBuffer->L->dataProvider()->clearErrors();
470 if ( setSavePoint() && mBuffer->L->dataProvider()->deleteAttributes( QgsAttributeIds() << mOriginalFieldIndex ) && ! mBuffer->L->dataProvider()->hasErrors() )
471 {
472 mBuffer->mDeletedAttributeIds.append( mOriginalFieldIndex );
473 mBuffer->updateLayerFields();
474 emit mBuffer->attributeDeleted( mOriginalFieldIndex );
475 }
476 else
477 {
478 setError();
479 }
480}
481
483 : QgsVectorLayerUndoPassthroughCommand( buffer, QObject::tr( "rename attribute" ) + " " + newName )
484 , mAttr( attr )
485 , mNewName( newName )
486 , mOldName( mBuffer->L->fields()[ mAttr ].name() )
487{
488}
489
491{
492 // note that the renameAttributes here is only necessary to inform the provider that
493 // an attribute is renamed after the rollBackToSavePoint
494 QgsFieldNameMap map;
495 map[ mAttr ] = mOldName;
496 mBuffer->L->dataProvider()->clearErrors();
497 if ( rollBackToSavePoint() )
498 {
499 // GDAL SQLite-based drivers (since version 3.11) keep the fields in sync with
500 // the backend after a rollback, to stay on the safe side check if the field
501 // isn't already renamed
502 bool ok = true;
503 if ( mBuffer->L->dataProvider()->fields().indexFromName( mOldName ) == -1 )
504 {
505 ok = mBuffer->L->dataProvider()->renameAttributes( map );
506 }
507 if ( ok && ! mBuffer->L->dataProvider()->hasErrors() )
508 {
509 mBuffer->updateLayerFields();
510 emit mBuffer->attributeRenamed( mAttr, mOldName );
511 }
512 else
513 {
514 setError();
515 }
516 }
517 else
518 {
519 setError();
520 }
521}
522
524{
525 QgsFieldNameMap map;
526 map[ mAttr ] = mNewName;
527 mBuffer->L->dataProvider()->clearErrors();
528 if ( setSavePoint() && mBuffer->L->dataProvider()->renameAttributes( map ) && ! mBuffer->L->dataProvider()->hasErrors() )
529 {
530 mBuffer->updateLayerFields();
531 emit mBuffer->attributeRenamed( mAttr, mNewName );
532 }
533 else
534 {
535 setError();
536 }
537}
538
540 : QgsVectorLayerUndoPassthroughCommand( buffer, name.isEmpty() ? QObject::tr( "custom transaction" ) : name, false )
541 , mTransaction( transaction )
542 , mSql( sql )
543{
544}
545
547{
548 if ( rollBackToSavePoint() )
549 {
550 mUndone = true;
551 emit mBuffer->L->layerModified();
552 }
553 else
554 {
555 setError();
556 }
557}
558
560{
561 // the first time that the sql query is execute is within QgsTransaction
562 // itself. So the redo has to be executed only after an undo action.
563 if ( mUndone )
564 {
565 QString errorMessage;
566
567 QString savePointId = mTransaction->createSavepoint( errorMessage );
568
569 if ( errorMessage.isEmpty() )
570 {
571 setSavePoint( savePointId );
572
573 if ( mTransaction->executeSql( mSql, errorMessage ) )
574 {
575 mUndone = false;
576 }
577 else
578 {
580 setError();
581 }
582 }
583 else
584 {
586 setError();
587 }
588 }
589}
590
592 : QgsVectorLayerUndoPassthroughCommand( buffer, QObject::tr( "change attribute value" ) )
593 , mFid( fid )
594 , mNewValues( newValues )
595 , mOldValues( oldValues )
596{
597 if ( mOldValues.isEmpty() )
598 {
599 const auto oldAttrs( mBuffer->L->getFeature( mFid ).attributes() );
600 for ( auto it = mNewValues.constBegin(); it != mNewValues.constEnd(); ++it )
601 {
602 mOldValues[ it.key() ] = oldAttrs[ it.key() ];
603 }
604 }
605 const bool isAdded { mBuffer->mAddedFeatures.contains( mFid ) };
606 for ( auto it = mNewValues.constBegin(); it != mNewValues.constEnd(); ++it )
607 {
608 if ( isAdded && mBuffer->mAddedFeatures[ mFid ].attribute( it.key() ).isValid() )
609 {
610 mFirstChanges[ it.key() ] = false;
611 }
612 else if ( mBuffer->mChangedAttributeValues.contains( mFid ) && mBuffer->mChangedAttributeValues[mFid].contains( it.key() ) )
613 {
614 mFirstChanges[ it.key() ] = false;
615 }
616 else
617 {
618 mFirstChanges[ it.key() ] = true;
619 }
620 }
621}
622
624{
625 if ( rollBackToSavePoint() )
626 {
627 QgsFeatureMap::iterator addedIt = mBuffer->mAddedFeatures.find( mFid );
628 for ( auto it = mNewValues.constBegin(); it != mNewValues.constEnd(); ++it )
629 {
630 const auto fieldIndex { it.key() };
631 if ( addedIt != mBuffer->mAddedFeatures.end() )
632 {
633 addedIt.value().setAttribute( fieldIndex, mOldValues[ it.key() ] );
634 }
635 else if ( mFirstChanges.contains( fieldIndex ) && mFirstChanges[ fieldIndex ] )
636 {
637 // existing feature
638 mBuffer->mChangedAttributeValues[mFid].remove( fieldIndex );
639 }
640 else
641 {
642 // changed attribute of existing feature
643 if ( !mBuffer->mChangedAttributeValues.contains( mFid ) )
644 {
645 mBuffer->mChangedAttributeValues.insert( mFid, QgsAttributeMap() );
646 }
647 mBuffer->mChangedAttributeValues[mFid].insert( fieldIndex, mOldValues[ it.key() ] );
648 }
649 emit mBuffer->attributeValueChanged( mFid, it.key(), mOldValues[ it.key() ] );
650 }
651 if ( mBuffer->mChangedAttributeValues[mFid].isEmpty() )
652 mBuffer->mChangedAttributeValues.remove( mFid );
653 }
654}
655
657{
658 QgsChangedAttributesMap attribMap;
659 attribMap.insert( mFid, mNewValues );
660 mBuffer->L->dataProvider()->clearErrors();
661 if ( setSavePoint() && mBuffer->L->dataProvider()->changeAttributeValues( attribMap ) && ! mBuffer->L->dataProvider()->hasErrors() )
662 {
663 QgsFeatureMap::iterator addedIt = mBuffer->mAddedFeatures.find( mFid );
664 for ( auto it = mNewValues.constBegin(); it != mNewValues.constEnd(); ++it )
665 {
666 const auto fieldIndex { it.key() };
667 // Update existing feature
668 if ( addedIt != mBuffer->mAddedFeatures.end() )
669 {
670 addedIt.value().setAttribute( fieldIndex, it.value() );
671 }
672 else
673 {
674 // changed attribute of existing feature
675 if ( !mBuffer->mChangedAttributeValues.contains( mFid ) )
676 {
677 mBuffer->mChangedAttributeValues.insert( mFid, QgsAttributeMap() );
678 }
679 mBuffer->mChangedAttributeValues[mFid].insert( fieldIndex, it.value() );
680 }
681 emit mBuffer->attributeValueChanged( mFid, it.key(), it.value() );
682 }
683 }
684}
@ 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