|
33 | 33 |
|
34 | 34 | #include <QHBoxLayout>
|
35 | 35 | #include <QLabel>
|
| 36 | +#include <QMessageBox> |
36 | 37 |
|
37 | 38 | QgsRelationEditorWidget::QgsRelationEditorWidget( QWidget *parent )
|
38 | 39 | : QgsCollapsibleGroupBox( parent )
|
@@ -492,9 +493,84 @@ void QgsRelationEditorWidget::deleteSelectedFeatures()
|
492 | 493 |
|
493 | 494 | void QgsRelationEditorWidget::deleteFeatures( const QgsFeatureIds &featureids )
|
494 | 495 | {
|
495 |
| - QgsVectorLayer *layer = mNmRelation.isValid() ? mNmRelation.referencedLayer() : mRelation.referencingLayer(); |
496 |
| - layer->deleteFeatures( featureids ); |
497 |
| - updateUi(); |
| 496 | + bool deleteFeatures = true; |
| 497 | + |
| 498 | + QgsVectorLayer *layer; |
| 499 | + if ( mNmRelation.isValid() ) |
| 500 | + { |
| 501 | + layer = mNmRelation.referencedLayer(); |
| 502 | + |
| 503 | + // When deleting a linked feature within an N:M relation, |
| 504 | + // check if the feature is linked to more than just one feature. |
| 505 | + // In case it is linked more than just once, ask the user for confirmation |
| 506 | + // as it is likely he was not aware of the implications and might either |
| 507 | + // leave the dataset in a corrupted state (referential integrity) or if |
| 508 | + // the fk constraint is ON CASCADE DELETE, there may be several linking |
| 509 | + // entries deleted along. |
| 510 | + |
| 511 | + QgsFeatureRequest deletedFeaturesRequest; |
| 512 | + deletedFeaturesRequest.setFilterFids( featureids ); |
| 513 | + deletedFeaturesRequest.setFlags( QgsFeatureRequest::NoGeometry ); |
| 514 | + deletedFeaturesRequest.setSubsetOfAttributes( QgsAttributeList() << mNmRelation.referencedFields().first() ); |
| 515 | + |
| 516 | + QgsFeatureIterator deletedFeatures = layer->getFeatures( deletedFeaturesRequest ); |
| 517 | + QStringList deletedFeaturesPks; |
| 518 | + QgsFeature feature; |
| 519 | + while ( deletedFeatures.nextFeature( feature ) ) |
| 520 | + { |
| 521 | + deletedFeaturesPks.append( QgsExpression::quotedValue( feature.attribute( mNmRelation.referencedFields().first() ) ) ); |
| 522 | + } |
| 523 | + |
| 524 | + QgsFeatureRequest linkingFeaturesRequest; |
| 525 | + linkingFeaturesRequest.setFlags( QgsFeatureRequest::NoGeometry ); |
| 526 | + linkingFeaturesRequest.setSubsetOfAttributes( QgsAttributeList() ); |
| 527 | + |
| 528 | + QString linkingFeaturesRequestExpression; |
| 529 | + if ( !deletedFeaturesPks.empty() ) |
| 530 | + { |
| 531 | + linkingFeaturesRequestExpression = QStringLiteral( "%1 IN (%2)" ).arg( QgsExpression::quotedColumnRef( mNmRelation.fieldPairs().first().first ), deletedFeaturesPks.join( ',' ) ); |
| 532 | + linkingFeaturesRequest.setFilterExpression( linkingFeaturesRequestExpression ); |
| 533 | + |
| 534 | + QgsFeatureIterator relatedLinkingFeatures = mNmRelation.referencingLayer()->getFeatures( linkingFeaturesRequest ); |
| 535 | + |
| 536 | + int relatedLinkingFeaturesCount = 0; |
| 537 | + while ( relatedLinkingFeatures.nextFeature( feature ) ) |
| 538 | + { |
| 539 | + relatedLinkingFeaturesCount++; |
| 540 | + } |
| 541 | + |
| 542 | + if ( deletedFeaturesPks.size() == 1 && relatedLinkingFeaturesCount > 1 ) |
| 543 | + { |
| 544 | + QMessageBox messageBox( QMessageBox::Question, tr( "Really delete entry?" ), tr( "The entry on %1 is still linked to %2 features on %3. Do you want to delete it?" ).arg( mNmRelation.referencedLayer()->name(), QString::number( relatedLinkingFeaturesCount ), mRelation.referencedLayer()->name() ), QMessageBox::NoButton, this ); |
| 545 | + messageBox.addButton( QMessageBox::Cancel ); |
| 546 | + QAbstractButton *deleteButton = messageBox.addButton( tr( "Delete" ), QMessageBox::AcceptRole ); |
| 547 | + |
| 548 | + messageBox.exec(); |
| 549 | + if ( messageBox.clickedButton() != deleteButton ) |
| 550 | + deleteFeatures = false; |
| 551 | + } |
| 552 | + else if ( deletedFeaturesPks.size() > 1 && relatedLinkingFeaturesCount > deletedFeaturesPks.size() ) |
| 553 | + { |
| 554 | + QMessageBox messageBox( QMessageBox::Question, tr( "Really delete entries?" ), tr( "The %1 entries on %2 are still linked to %3 features on %4. Do you want to delete them?" ).arg( QString::number( deletedFeaturesPks.size() ), mNmRelation.referencedLayer()->name(), QString::number( relatedLinkingFeaturesCount ), mRelation.referencedLayer()->name() ), QMessageBox::NoButton, this ); |
| 555 | + messageBox.addButton( QMessageBox::Cancel ); |
| 556 | + QAbstractButton *deleteButton = messageBox.addButton( tr( "Delete" ), QMessageBox::AcceptRole ); |
| 557 | + |
| 558 | + messageBox.exec(); |
| 559 | + if ( messageBox.clickedButton() != deleteButton ) |
| 560 | + deleteFeatures = false; |
| 561 | + } |
| 562 | + } |
| 563 | + } |
| 564 | + else |
| 565 | + { |
| 566 | + layer = mRelation.referencingLayer(); |
| 567 | + } |
| 568 | + |
| 569 | + if ( deleteFeatures ) |
| 570 | + { |
| 571 | + layer->deleteFeatures( featureids ); |
| 572 | + updateUi(); |
| 573 | + } |
498 | 574 | }
|
499 | 575 |
|
500 | 576 | void QgsRelationEditorWidget::unlinkFeature( const QgsFeatureId featureid )
|
|
0 commit comments