From 27ef8a598d9c3b491123b0a5eb9087a89f100471 Mon Sep 17 00:00:00 2001 From: wandererfan Date: Sun, 21 May 2023 20:12:15 -0400 Subject: [PATCH] [TD]fix fail on object deleted during dialog (#9626) --- src/Mod/TechDraw/Gui/TaskBalloon.cpp | 47 +++++++++++++++----- src/Mod/TechDraw/Gui/TaskBalloon.h | 12 +++++ src/Mod/TechDraw/Gui/ViewProviderBalloon.cpp | 1 + 3 files changed, 50 insertions(+), 10 deletions(-) diff --git a/src/Mod/TechDraw/Gui/TaskBalloon.cpp b/src/Mod/TechDraw/Gui/TaskBalloon.cpp index 3a775abbd7..2b0e37f0d7 100644 --- a/src/Mod/TechDraw/Gui/TaskBalloon.cpp +++ b/src/Mod/TechDraw/Gui/TaskBalloon.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include "TaskBalloon.h" #include "ui_TaskBalloon.h" @@ -49,6 +50,9 @@ TaskBalloon::TaskBalloon(QGIViewBalloon *parent, ViewProviderBalloon *balloonVP) int i = 0; m_parent = parent; m_balloonVP = balloonVP; + m_guiDocument = balloonVP->getDocument(); + m_appDocument = parent->getBalloonFeat()->getDocument(); + m_balloonName = parent->getBalloonFeat()->getNameInDocument(); ui->setupUi(this); @@ -98,6 +102,7 @@ TaskBalloon::TaskBalloon(QGIViewBalloon *parent, ViewProviderBalloon *balloonVP) connect(ui->comboLineVisible, qOverload(&QComboBox::currentIndexChanged), this, &TaskBalloon::onLineVisibleChanged); connect(ui->qsbLineWidth, qOverload(&QuantitySpinBox::valueChanged), this, &TaskBalloon::onLineWidthChanged); connect(ui->qsbKinkLength, qOverload(&QuantitySpinBox::valueChanged), this, &TaskBalloon::onKinkLengthChanged); + } TaskBalloon::~TaskBalloon() @@ -106,22 +111,44 @@ TaskBalloon::~TaskBalloon() bool TaskBalloon::accept() { - Gui::Document* doc = m_balloonVP->getDocument(); - m_balloonVP->getObject()->purgeTouched(); - doc->commitCommand(); - doc->resetEdit(); + // re issue #9626 if the balloon is deleted while the task dialog is in progress we will fail + // trying to access the feature object or the viewprovider. This should be prevented by + // change to ViewProviderBalloon + // see also reject() + App::DocumentObject* balloonFeature = m_appDocument->getObject(m_balloonName.c_str()); + if(balloonFeature) { + // an object with our name still exists in the document + balloonFeature->purgeTouched(); + m_guiDocument->commitCommand(); + } else { + // see comment in reject(). this may not do what we want. + Gui::Command::abortCommand(); + } + + m_guiDocument->resetEdit(); return true; } bool TaskBalloon::reject() { - Gui::Document* doc = m_balloonVP->getDocument(); - doc->abortCommand(); - recomputeFeature(); - m_parent->updateView(true); - m_balloonVP->getObject()->purgeTouched(); - doc->resetEdit(); + // re issue #9626 - if the balloon is deleted while the dialog is in progress + // the delete transaction is still active and ?locked? so our "abortCommand" + // doesn't work properly and a pending transaction is still in place. This + // causes a warning message from App::AutoTransaction (??) that can't be + // cleared. Even closing the document will not clear the warning. + // A change to ViewProviderBalloon::onDelete should prevent this from + // happening from the Gui. It is possible(?) that the balloon could be + // deleted by a script. + m_guiDocument->abortCommand(); + App::DocumentObject* balloonFeature = m_appDocument->getObject(m_balloonName.c_str()); + if(balloonFeature) { + // an object with our name still exists in the document + balloonFeature->recomputeFeature(); + balloonFeature->purgeTouched(); + } + m_guiDocument->resetEdit(); + Gui::Command::updateActive(); return true; } diff --git a/src/Mod/TechDraw/Gui/TaskBalloon.h b/src/Mod/TechDraw/Gui/TaskBalloon.h index 29b0b3cf79..3ce1768c7b 100644 --- a/src/Mod/TechDraw/Gui/TaskBalloon.h +++ b/src/Mod/TechDraw/Gui/TaskBalloon.h @@ -28,6 +28,14 @@ #include #include +namespace Gui +{ +class Document; +} +namespace App +{ +class Document; +} namespace TechDrawGui { @@ -64,6 +72,10 @@ private: std::unique_ptr ui; QGIViewBalloon *m_parent; ViewProviderBalloon* m_balloonVP; + + std::string m_balloonName; + App::Document* m_appDocument; + Gui::Document* m_guiDocument; }; class TaskDlgBalloon : public Gui::TaskView::TaskDialog diff --git a/src/Mod/TechDraw/Gui/ViewProviderBalloon.cpp b/src/Mod/TechDraw/Gui/ViewProviderBalloon.cpp index 8f323ded17..4459bceeec 100644 --- a/src/Mod/TechDraw/Gui/ViewProviderBalloon.cpp +++ b/src/Mod/TechDraw/Gui/ViewProviderBalloon.cpp @@ -162,5 +162,6 @@ bool ViewProviderBalloon::canDelete(App::DocumentObject *obj) const // deletions of a balloon object doesn't destroy anything // thus we can pass this action Q_UNUSED(obj) + Base::Console().Message("VPB::canDelete()\n"); return true; }