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();