63 bool editingStarted =
true;
66 if ( !layer->isValid() )
68 editingStarted =
false;
69 QgsLogger::debug( tr(
"Can't start editing invalid layer '%1'." ).arg( layer->name() ) );
73 if ( !layer->dataProvider() )
75 editingStarted =
false;
76 QgsLogger::debug( tr(
"Can't start editing layer '%1' with invalid data provider." ).arg( layer->name() ) );
81 if ( !layer->supportsEditing() )
83 editingStarted =
false;
84 QgsLogger::debug( tr(
"Can't start editing. Layer '%1' doesn't support editing." ).arg( layer->name() ) );
88 if ( layer->editBuffer() )
91 layer->editBuffer()->setEditBufferGroup(
this );
96 emit layer->beforeEditingStarted();
97 layer->dataProvider()->enterUpdateMode();
98 layer->createEditBuffer();
99 layer->editBuffer()->setEditBufferGroup(
this );
100 layer->updateFields();
101 emit layer->editingStarted();
104 if ( ! editingStarted )
106 QStringList rollbackErrors;
107 if ( !
rollBack( rollbackErrors,
true ) )
108 QgsLogger::debug( tr(
"Can't rollback after start editing failure. Roll back detailed errors: %1" ).arg( rollbackErrors.join(
" / " ) ) );
111 mIsEditing = editingStarted;
119 const QSet<QgsVectorLayer *> constModifiedLayers =
modifiedLayers();
120 if ( constModifiedLayers.isEmpty() )
122 editingFinished( stopEditing );
123 mIsEditing = !stopEditing;
127 QMap<QString, QSet<QgsVectorLayer *> > connectionStringsLayers;
132 QList<QgsVectorLayer *> transactionLayers;
133 QList<std::shared_ptr<QgsTransaction> > openTransactions;
134 const QStringList connectionStrings = connectionStringsLayers.keys();
135 for (
const QString &connectionString : connectionStrings )
137 const QString providerKey = ( *connectionStringsLayers.value( connectionString ).begin() )->providerType();
139 std::shared_ptr<QgsTransaction> transaction;
143 commitErrors << tr(
"ERROR: data source '%1', is not available for transactions." ).arg( connectionString );
149 if ( ! transaction->begin( errorMsg ) )
151 commitErrors << tr(
"ERROR: could not start a transaction on data provider '%1', detailed error: '%2'." ).arg( providerKey, errorMsg );
156 const auto constLayers = connectionStringsLayers.value( connectionString );
159 if ( ! transaction->addLayer( layer,
true ) )
161 commitErrors << tr(
"ERROR: could not add layer '%1' to transaction on data provider '%2'." ).arg( layer->name(), providerKey );
166 transactionLayers.append( layer );
169 openTransactions.append( transaction );
176 const QList<QgsVectorLayer *> orderedLayers = orderLayersParentsToChildren( constModifiedLayers );
177 QList<QgsVectorLayer *>::const_iterator orderedLayersIterator;
182 for ( orderedLayersIterator = orderedLayers.constBegin(); orderedLayersIterator != orderedLayers.constEnd(); ++orderedLayersIterator )
184 if ( ( *orderedLayersIterator )->editBuffer() == nullptr )
186 commitErrors << tr(
"ERROR: edit buffer of layer '%1' is not valid." ).arg( ( *orderedLayersIterator )->name() );
191 success = ( *orderedLayersIterator )->editBuffer()->commitChangesCheckGeometryTypeCompatibility( commitErrors );
197 QSet<QgsVectorLayer *> modifiedLayersOnProviderSide;
202 for ( orderedLayersIterator = orderedLayers.constBegin(); orderedLayersIterator != orderedLayers.constEnd(); ++orderedLayersIterator )
204 QgsFields oldFields = ( *orderedLayersIterator )->fields();
206 bool attributesDeleted =
false;
207 success = ( *orderedLayersIterator )->editBuffer()->commitChangesDeleteAttributes( attributesDeleted, commitErrors );
211 bool attributesRenamed =
false;
212 success = ( *orderedLayersIterator )->editBuffer()->commitChangesRenameAttributes( attributesRenamed, commitErrors );
216 bool attributesAdded =
false;
217 success = ( *orderedLayersIterator )->editBuffer()->commitChangesAddAttributes( attributesAdded, commitErrors );
221 if ( attributesDeleted || attributesRenamed || attributesAdded )
223 if ( ! transactionLayers.contains( ( *orderedLayersIterator ) ) )
224 modifiedLayersOnProviderSide.insert( ( *orderedLayersIterator ) );
226 success = ( *orderedLayersIterator )->editBuffer()->commitChangesCheckAttributesModifications( oldFields, commitErrors );
236 orderedLayersIterator = orderedLayers.
constEnd();
237 while ( orderedLayersIterator != orderedLayers.constBegin() )
239 --orderedLayersIterator;
240 bool featuresDeleted;
241 success = ( *orderedLayersIterator )->editBuffer()->commitChangesDeleteFeatures( featuresDeleted, commitErrors );
245 if ( featuresDeleted && transactionLayers.contains( ( *orderedLayersIterator ) ) )
246 modifiedLayersOnProviderSide.insert( ( *orderedLayersIterator ) );
253 for ( orderedLayersIterator = orderedLayers.constBegin(); orderedLayersIterator != orderedLayers.constEnd(); ++orderedLayersIterator )
256 ( *orderedLayersIterator )->editBuffer()->commitChangesAddFeatures( featuresAdded, commitErrors );
260 if ( featuresAdded && transactionLayers.contains( ( *orderedLayersIterator ) ) )
261 modifiedLayersOnProviderSide.insert( ( *orderedLayersIterator ) );
268 orderedLayersIterator = orderedLayers.constEnd();
269 while ( orderedLayersIterator != orderedLayers.constBegin() )
271 --orderedLayersIterator;
273 bool attributesChanged;
274 success = ( *orderedLayersIterator )->editBuffer()->commitChangesChangeAttributes( attributesChanged, commitErrors );
278 if ( attributesChanged && transactionLayers.contains( ( *orderedLayersIterator ) ) )
279 modifiedLayersOnProviderSide.insert( ( *orderedLayersIterator ) );
286 QList<std::shared_ptr<QgsTransaction> >::iterator openTransactionsIterator = openTransactions.begin();
287 while ( openTransactionsIterator != openTransactions.end() )
290 if ( !( *openTransactionsIterator )->commit( errorMsg ) )
293 commitErrors << tr(
"ERROR: could not commit a transaction, detailed error: '%1'." ).arg( errorMsg );
297 modifiedLayersOnProviderSide += connectionStringsLayers.value( ( *openTransactionsIterator )->connectionString() );
298 openTransactionsIterator = openTransactions.erase( openTransactionsIterator );
306 if ( ! modifiedLayersOnProviderSide.isEmpty() )
308 if ( modifiedLayersOnProviderSide.size() == 1 )
309 commitErrors << tr(
"WARNING: changes to layer '%1' where already sent to data provider and cannot be rolled back." ).arg( ( *modifiedLayersOnProviderSide.begin() )->name() );
312 commitErrors << tr(
"WARNING: changes to following layers where already sent to data provider and cannot be rolled back:" );
313 for (
QgsVectorLayer *layer : std::as_const( modifiedLayersOnProviderSide ) )
314 commitErrors << tr(
"- '%1'" ).arg( layer->name() );
318 QString rollbackError;
319 for (
const std::shared_ptr<QgsTransaction> &transaction : openTransactions )
320 transaction->rollback( rollbackError );
325 editingFinished( stopEditing );
327 if ( success && stopEditing )
337 if ( ! layer->editBuffer() )
340 if ( !layer->dataProvider() )
342 rollbackErrors << tr(
"Layer '%1' doesn't have a valid data provider" ).arg( layer->name() );
346 bool rollbackExtent = !layer->editBuffer()->deletedFeatureIds().isEmpty() ||
347 !layer->editBuffer()->addedFeatures().isEmpty() ||
348 !layer->editBuffer()->changedGeometries().isEmpty();
350 emit layer->beforeRollBack();
352 layer->editBuffer()->rollBack();
354 emit layer->afterRollBack();
356 if ( layer->isModified() )
360 layer->undoStack()->setIndex( 0 );
363 layer->updateFields();
367 layer->clearEditBuffer();
368 layer->undoStack()->clear();
369 emit layer->editingStopped();
372 if ( rollbackExtent )
373 layer->updateExtents();
376 layer->dataProvider()->leaveUpdateMode();
378 layer->triggerRepaint();
381 mIsEditing = ! stopEditing;