34 mLayers.insert( layer );
52 if ( layer->isModified() )
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 success = ( *orderedLayersIterator )->editBuffer()->commitChangesCheckGeometryTypeCompatibility( commitErrors );
190 QSet<QgsVectorLayer *> modifiedLayersOnProviderSide;
195 for ( orderedLayersIterator = orderedLayers.constBegin(); orderedLayersIterator != orderedLayers.constEnd(); ++orderedLayersIterator )
197 QgsFields oldFields = ( *orderedLayersIterator )->fields();
199 bool attributesDeleted =
false;
200 success = ( *orderedLayersIterator )->editBuffer()->commitChangesDeleteAttributes( attributesDeleted, commitErrors );
204 bool attributesRenamed =
false;
205 success = ( *orderedLayersIterator )->editBuffer()->commitChangesRenameAttributes( attributesRenamed, commitErrors );
209 bool attributesAdded =
false;
210 success = ( *orderedLayersIterator )->editBuffer()->commitChangesAddAttributes( attributesAdded, commitErrors );
214 if ( attributesDeleted || attributesRenamed || attributesAdded )
216 if ( ! transactionLayers.contains( ( *orderedLayersIterator ) ) )
217 modifiedLayersOnProviderSide.insert( ( *orderedLayersIterator ) );
219 success = ( *orderedLayersIterator )->editBuffer()->commitChangesCheckAttributesModifications( oldFields, commitErrors );
229 orderedLayersIterator = orderedLayers.
constEnd();
230 while ( orderedLayersIterator != orderedLayers.constBegin() )
232 --orderedLayersIterator;
233 bool featuresDeleted;
234 success = ( *orderedLayersIterator )->editBuffer()->commitChangesDeleteFeatures( featuresDeleted, commitErrors );
238 if ( featuresDeleted && transactionLayers.contains( ( *orderedLayersIterator ) ) )
239 modifiedLayersOnProviderSide.insert( ( *orderedLayersIterator ) );
246 for ( orderedLayersIterator = orderedLayers.constBegin(); orderedLayersIterator != orderedLayers.constEnd(); ++orderedLayersIterator )
249 ( *orderedLayersIterator )->editBuffer()->commitChangesAddFeatures( featuresAdded, commitErrors );
253 if ( featuresAdded && transactionLayers.contains( ( *orderedLayersIterator ) ) )
254 modifiedLayersOnProviderSide.insert( ( *orderedLayersIterator ) );
261 orderedLayersIterator = orderedLayers.constEnd();
262 while ( orderedLayersIterator != orderedLayers.constBegin() )
264 --orderedLayersIterator;
266 bool attributesChanged;
267 success = ( *orderedLayersIterator )->editBuffer()->commitChangesChangeAttributes( attributesChanged, commitErrors );
271 if ( attributesChanged && transactionLayers.contains( ( *orderedLayersIterator ) ) )
272 modifiedLayersOnProviderSide.insert( ( *orderedLayersIterator ) );
279 QList<std::shared_ptr<QgsTransaction> >::iterator openTransactionsIterator = openTransactions.begin();
280 while ( openTransactionsIterator != openTransactions.end() )
283 if ( !( *openTransactionsIterator )->commit( errorMsg ) )
286 commitErrors << tr(
"ERROR: could not commit a transaction, detailed error: '%1'." ).arg( errorMsg );
290 modifiedLayersOnProviderSide += connectionStringsLayers.value( ( *openTransactionsIterator )->connectionString() );
291 openTransactionsIterator = openTransactions.erase( openTransactionsIterator );
299 if ( ! modifiedLayersOnProviderSide.isEmpty() )
301 if ( modifiedLayersOnProviderSide.size() == 1 )
302 commitErrors << tr(
"WARNING: changes to layer '%1' where already sent to data provider and cannot be rolled back." ).arg( ( *modifiedLayersOnProviderSide.begin() )->name() );
305 commitErrors << tr(
"WARNING: changes to following layers where already sent to data provider and cannot be rolled back:" );
306 for (
QgsVectorLayer *layer : std::as_const( modifiedLayersOnProviderSide ) )
307 commitErrors << tr(
"- '%1'" ).arg( layer->name() );
311 QString rollbackError;
312 for (
const std::shared_ptr<QgsTransaction> &transaction : openTransactions )
313 transaction->rollback( rollbackError );
318 editingFinished( stopEditing );
320 if ( success && stopEditing )
330 if ( ! layer->editBuffer() )
333 if ( !layer->dataProvider() )
335 rollbackErrors << tr(
"Layer '%1' doesn't have a valid data provider" ).arg( layer->name() );
339 bool rollbackExtent = !layer->editBuffer()->deletedFeatureIds().isEmpty() ||
340 !layer->editBuffer()->addedFeatures().isEmpty() ||
341 !layer->editBuffer()->changedGeometries().isEmpty();
343 emit layer->beforeRollBack();
345 layer->editBuffer()->rollBack();
347 emit layer->afterRollBack();
349 if ( layer->isModified() )
353 layer->undoStack()->setIndex( 0 );
356 layer->updateFields();
360 layer->clearEditBuffer();
361 layer->undoStack()->clear();
362 emit layer->editingStopped();
365 if ( rollbackExtent )
366 layer->updateExtents();
369 layer->dataProvider()->leaveUpdateMode();
371 layer->triggerRepaint();
374 mIsEditing = ! stopEditing;
383 QList<QgsVectorLayer *> QgsVectorLayerEditBufferGroup::orderLayersParentsToChildren( QSet<QgsVectorLayer *>
layers )
385 QSet<QgsVectorLayer *> referencingLayers;
386 QSet<QgsVectorLayer *> referencedLayers;
392 referencingLayers.insert( relation.referencingLayer() );
393 referencedLayers.insert( relation.referencedLayer() );
397 QList<QgsVectorLayer *> orderedLayers;
401 QSet<QgsVectorLayer *> onlyParents = referencedLayers - referencingLayers;
402 orderedLayers.append( onlyParents.values() );
407 QSet<QgsVectorLayer *> intersection = referencedLayers;
408 intersection.intersect( referencingLayers );
410 QQueue<QgsVectorLayer *> otherLayersQueue;
411 otherLayersQueue.append( intersection.values() );
412 while ( ! otherLayersQueue.isEmpty() )
416 int insertIndex = -1;
421 int index = orderedLayers.indexOf( referencedLayer );
424 insertIndex = std::max( insertIndex, index + 1 );
429 bool circularRelation =
false;
431 for (
const QgsRelation &backRelation : backRelations )
433 if ( backRelation.referencedLayer() == layer )
435 QgsLogger::warning( tr(
"Circular relation between layers '%1' and '%2'. Correct saving order of layers can't be guaranteed" ).arg( layer->
name(), referencedLayer->
name() ) );
436 insertIndex = orderedLayers.size();
437 circularRelation =
true;
442 if ( !circularRelation )
451 if ( insertIndex == -1 )
453 otherLayersQueue.enqueue( layer );
457 orderedLayers.insert( insertIndex, layer );
463 QSet<QgsVectorLayer *> onlyChildren = referencingLayers - referencedLayers;
464 orderedLayers.append( onlyChildren.values() );
469 QSet<QgsVectorLayer *> layersWithoutRelations =
layers - referencedLayers;
470 layersWithoutRelations -= referencingLayers;
471 orderedLayers.append( layersWithoutRelations.values() );
474 return orderedLayers;
477 void QgsVectorLayerEditBufferGroup::editingFinished(
bool stopEditing )
481 if ( !layer->mDeletedFids.empty() )
484 layer->mDeletedFids.clear();
488 layer->clearEditBuffer();