Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
On a delete, check for possiblity that features of a referencing or j…
…oining layer could be impacted and print warning.

It's a general warning, and not depending on what features should be deleted. This to avoid long time for checking all features in the relations.
  • Loading branch information
signedav committed May 8, 2020
1 parent aa82247 commit 342521e
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 0 deletions.
10 changes: 10 additions & 0 deletions src/app/qgisapp.cpp
Expand Up @@ -9001,6 +9001,16 @@ void QgisApp::deleteSelected( QgsMapLayer *layer, QWidget *parent, bool checkFea
}
}

if ( QgsVectorLayerUtils::impactsCascadeFeatures(vlayer, QgsProject::instance() ) )
{
// for extra safety to make sure we know that the delete can have impact on children and joins
int res = QMessageBox::warning( mMapCanvas, tr( "Possible impact on descendants of layer \"%1\"").arg( vlayer->name() ),
tr( "A delete on this layer could have an impact on referencing or joined layers and their descendants. Would you still like to continue?" ),
QMessageBox::Yes | QMessageBox::No );
if ( res != QMessageBox::Yes )
return;
}

vlayer->beginEditCommand( tr( "Features deleted" ) );
int deletedCount = 0;
QgsVectorLayer::DeleteContext context { true };
Expand Down
10 changes: 10 additions & 0 deletions src/app/qgsattributetabledialog.cpp
Expand Up @@ -864,6 +864,16 @@ void QgsAttributeTableDialog::setFilterExpression( const QString &filterString,
void QgsAttributeTableDialog::deleteFeature( const QgsFeatureId fid )
{
QgsDebugMsg( QStringLiteral( "Delete %1" ).arg( fid ) );
if ( QgsVectorLayerUtils::impactsCascadeFeatures(mLayer, QgsProject::instance() ) )
{
// for extra safety to make sure we know that the delete can have impact on children and joins
int res = QMessageBox::warning( this, tr( "Possible impact on descendants of layer \"%1\"").arg( mLayer->name() ),
tr( "A delete on this layer could have an impact on referencing or joined layers and their descendants. Would you still like to continue?" ),
QMessageBox::Yes | QMessageBox::No );
if ( res != QMessageBox::Yes )
return;
}

QgsVectorLayer::DeleteContext context { true };
mLayer->deleteFeature( fid, &context );
//if it effected more than one layer, print feedback for all descendants
Expand Down
27 changes: 27 additions & 0 deletions src/core/qgsvectorlayerutils.cpp
Expand Up @@ -934,3 +934,30 @@ QString QgsVectorLayerUtils::getFeatureDisplayString( const QgsVectorLayer *laye

return displayString;
}

bool QgsVectorLayerUtils::impactsCascadeFeatures(const QgsVectorLayer *layer, const QgsProject *project)
{
if ( !layer )
return false;

const QList<QgsRelation> relations = project->relationManager()->referencedRelations( layer );
for ( const QgsRelation &relation : relations )
{
if ( relation.strength() == QgsRelation::Composition )
{
return true;
}
}

layer->joinBuffer()->containsJoins();
const auto constVectorJoins = layer->joinBuffer()->vectorJoins();
for ( const QgsVectorLayerJoinInfo &info : constVectorJoins )
{
if ( info.isEditable() && info.hasCascadedDelete() )
{
return true;
}
}

return false;
}
9 changes: 9 additions & 0 deletions src/core/qgsvectorlayerutils.h
Expand Up @@ -319,6 +319,15 @@ class CORE_EXPORT QgsVectorLayerUtils
* \since QGIS 3.12
*/
static QString getFeatureDisplayString( const QgsVectorLayer *layer, const QgsFeature &feature );

/**
* \returns true if the \a is connected as parent in at least one composition relation of the \a project
* or contains joins, where cascade delete is set.
*
* \since QGIS 3.14
*/
static bool impactsCascadeFeatures(const QgsVectorLayer *layer, const QgsProject *project);

};


Expand Down
10 changes: 10 additions & 0 deletions src/gui/qgsrelationeditorwidget.cpp
Expand Up @@ -728,6 +728,16 @@ void QgsRelationEditorWidget::deleteFeatures( const QgsFeatureIds &featureids )
layer = mRelation.referencingLayer();
}

if ( QgsVectorLayerUtils::impactsCascadeFeatures(layer, QgsProject::instance() ) )
{
// for extra safety to make sure we know that the delete can have impact on children and joins
int res = QMessageBox::warning( this, tr( "Possible impact on descendants of layer \"%1\"").arg( layer->name() ),
tr( "A delete on this layer could have an impact on referencing or joined layers and their descendants. Would you still like to continue?" ),
QMessageBox::Yes | QMessageBox::No );
if ( res == QMessageBox::No )
deleteFeatures = false;
}

if ( deleteFeatures )
{
QgsVectorLayer::DeleteContext context { true };
Expand Down

0 comments on commit 342521e

Please sign in to comment.