68 bool editingStarted =
true;
71 if ( !layer->isValid() )
73 editingStarted =
false;
74 QgsLogger::debug( tr(
"Can't start editing invalid layer '%1'." ).arg( layer->name() ) );
78 if ( !layer->dataProvider() )
80 editingStarted =
false;
81 QgsLogger::debug( tr(
"Can't start editing layer '%1' with invalid data provider." ).arg( layer->name() ) );
86 if ( !layer->supportsEditing() )
88 editingStarted =
false;
89 QgsLogger::debug( tr(
"Can't start editing. Layer '%1' doesn't support editing." ).arg( layer->name() ) );
93 if ( layer->editBuffer() )
96 layer->editBuffer()->setEditBufferGroup(
this );
101 emit layer->beforeEditingStarted();
102 layer->dataProvider()->enterUpdateMode();
103 layer->createEditBuffer();
104 layer->editBuffer()->setEditBufferGroup(
this );
105 layer->updateFields();
106 emit layer->editingStarted();
109 if ( !editingStarted )
111 QStringList rollbackErrors;
112 if ( !
rollBack( rollbackErrors,
true ) )
113 QgsLogger::debug( tr(
"Can't rollback after start editing failure. Roll back detailed errors: %1" ).arg( rollbackErrors.join(
" / " ) ) );
116 mIsEditing = editingStarted;
124 const QSet<QgsVectorLayer *> constModifiedLayers =
modifiedLayers();
125 if ( constModifiedLayers.isEmpty() )
127 editingFinished( stopEditing );
128 mIsEditing = !stopEditing;
132 QMap<QString, QSet<QgsVectorLayer *> > connectionStringsLayers;
137 QList<QgsVectorLayer *> transactionLayers;
138 QList<std::shared_ptr<QgsTransaction> > openTransactions;
139 const QStringList connectionStrings = connectionStringsLayers.keys();
140 for (
const QString &connectionString : connectionStrings )
142 const QString providerKey = ( *connectionStringsLayers.value( connectionString ).begin() )->providerType();
144 std::shared_ptr<QgsTransaction> transaction;
148 commitErrors << tr(
"ERROR: data source '%1', is not available for transactions." ).arg( connectionString );
154 if ( !transaction->begin( errorMsg ) )
156 commitErrors << tr(
"ERROR: could not start a transaction on data provider '%1', detailed error: '%2'." ).arg( providerKey, errorMsg );
161 const auto constLayers = connectionStringsLayers.value( connectionString );
164 if ( !transaction->addLayer( layer,
true ) )
166 commitErrors << tr(
"ERROR: could not add layer '%1' to transaction on data provider '%2'." ).arg( layer->name(), providerKey );
171 transactionLayers.append( layer );
174 openTransactions.append( transaction );
181 const QList<QgsVectorLayer *> orderedLayers = orderLayersParentsToChildren( constModifiedLayers );
182 QList<QgsVectorLayer *>::const_iterator orderedLayersIterator;
187 for ( orderedLayersIterator = orderedLayers.constBegin(); orderedLayersIterator != orderedLayers.constEnd(); ++orderedLayersIterator )
189 if ( !( *orderedLayersIterator )->editBuffer() )
191 commitErrors << tr(
"ERROR: edit buffer of layer '%1' is not valid." ).arg( ( *orderedLayersIterator )->name() );
196 success = ( *orderedLayersIterator )->editBuffer()->commitChangesCheckGeometryTypeCompatibility( commitErrors );
202 QSet<QgsVectorLayer *> modifiedLayersOnProviderSide;
207 for ( orderedLayersIterator = orderedLayers.constBegin(); orderedLayersIterator != orderedLayers.constEnd(); ++orderedLayersIterator )
209 QgsFields oldFields = ( *orderedLayersIterator )->fields();
211 bool attributesDeleted =
false;
212 success = ( *orderedLayersIterator )->editBuffer()->commitChangesDeleteAttributes( attributesDeleted, commitErrors );
216 bool attributesRenamed =
false;
217 success = ( *orderedLayersIterator )->editBuffer()->commitChangesRenameAttributes( attributesRenamed, commitErrors );
221 bool attributesAdded =
false;
222 success = ( *orderedLayersIterator )->editBuffer()->commitChangesAddAttributes( attributesAdded, commitErrors );
226 if ( attributesDeleted || attributesRenamed || attributesAdded )
228 if ( !transactionLayers.contains( ( *orderedLayersIterator ) ) )
229 modifiedLayersOnProviderSide.insert( ( *orderedLayersIterator ) );
231 success = ( *orderedLayersIterator )->editBuffer()->commitChangesCheckAttributesModifications( oldFields, commitErrors );
241 orderedLayersIterator = orderedLayers.constEnd();
242 while ( orderedLayersIterator != orderedLayers.constBegin() )
244 --orderedLayersIterator;
245 bool featuresDeleted;
246 success = ( *orderedLayersIterator )->editBuffer()->commitChangesDeleteFeatures( featuresDeleted, commitErrors );
250 if ( featuresDeleted && transactionLayers.contains( ( *orderedLayersIterator ) ) )
251 modifiedLayersOnProviderSide.insert( ( *orderedLayersIterator ) );
258 for ( orderedLayersIterator = orderedLayers.constBegin(); orderedLayersIterator != orderedLayers.constEnd(); ++orderedLayersIterator )
261 ( *orderedLayersIterator )->editBuffer()->commitChangesAddFeatures( featuresAdded, commitErrors );
265 if ( featuresAdded && transactionLayers.contains( ( *orderedLayersIterator ) ) )
266 modifiedLayersOnProviderSide.insert( ( *orderedLayersIterator ) );
273 orderedLayersIterator = orderedLayers.constEnd();
274 while ( orderedLayersIterator != orderedLayers.constBegin() )
276 --orderedLayersIterator;
278 bool attributesChanged;
279 success = ( *orderedLayersIterator )->editBuffer()->commitChangesChangeAttributes( attributesChanged, commitErrors );
283 if ( attributesChanged && transactionLayers.contains( ( *orderedLayersIterator ) ) )
284 modifiedLayersOnProviderSide.insert( ( *orderedLayersIterator ) );
291 QList<std::shared_ptr<QgsTransaction> >::iterator openTransactionsIterator = openTransactions.begin();
292 while ( openTransactionsIterator != openTransactions.end() )
295 if ( !( *openTransactionsIterator )->commit( errorMsg ) )
298 commitErrors << tr(
"ERROR: could not commit a transaction, detailed error: '%1'." ).arg( errorMsg );
302 modifiedLayersOnProviderSide += connectionStringsLayers.value( ( *openTransactionsIterator )->connectionString() );
303 openTransactionsIterator = openTransactions.erase( openTransactionsIterator );
311 if ( !modifiedLayersOnProviderSide.isEmpty() )
313 if ( modifiedLayersOnProviderSide.size() == 1 )
314 commitErrors << tr(
"WARNING: changes to layer '%1' were already sent to data provider and cannot be rolled back." ).arg( ( *modifiedLayersOnProviderSide.begin() )->name() );
317 commitErrors << tr(
"WARNING: changes to following layers were already sent to data provider and cannot be rolled back:" );
318 for (
QgsVectorLayer *layer : std::as_const( modifiedLayersOnProviderSide ) )
319 commitErrors << tr(
"- '%1'" ).arg( layer->name() );
323 QString rollbackError;
324 for (
const std::shared_ptr<QgsTransaction> &transaction : openTransactions )
325 transaction->rollback( rollbackError );
330 editingFinished( stopEditing );
332 if ( success && stopEditing )
342 if ( !layer->editBuffer() )
345 if ( !layer->dataProvider() )
347 rollbackErrors << tr(
"Layer '%1' doesn't have a valid data provider" ).arg( layer->name() );
351 bool rollbackExtent = !layer->editBuffer()->deletedFeatureIds().isEmpty() || !layer->editBuffer()->addedFeatures().isEmpty() || !layer->editBuffer()->changedGeometries().isEmpty();
353 emit layer->beforeRollBack();
355 layer->editBuffer()->rollBack();
357 emit layer->afterRollBack();
359 if ( layer->isModified() )
363 layer->undoStack()->setIndex( 0 );
366 layer->updateFields();
370 layer->clearEditBuffer();
371 layer->undoStack()->clear();
372 emit layer->editingStopped();
375 if ( rollbackExtent )
376 layer->updateExtents();
379 layer->dataProvider()->leaveUpdateMode();
381 layer->triggerRepaint();
384 mIsEditing = !stopEditing;