diff --git a/src/Mod/TechDraw/Gui/MDIViewPage.cpp b/src/Mod/TechDraw/Gui/MDIViewPage.cpp index bfd1ea5fe0..6049aafcc7 100644 --- a/src/Mod/TechDraw/Gui/MDIViewPage.cpp +++ b/src/Mod/TechDraw/Gui/MDIViewPage.cpp @@ -76,7 +76,6 @@ #include "Rez.h" #include "ViewProviderPage.h" - using namespace TechDrawGui; using namespace TechDraw; namespace bp = boost::placeholders; @@ -194,6 +193,7 @@ bool MDIViewPage::onMsg(const char* pMsg, const char**) else if (strcmp("Undo", pMsg) == 0) { doc->undo(1); Gui::Command::updateActive(); + fixSceneDependencies(); // check QGraphicsScene item parenting return true; } else if (strcmp("Redo", pMsg) == 0) { @@ -246,6 +246,14 @@ void MDIViewPage::setTabText(std::string tabText) } } +// advise the page to check QGraphicsScene parent/child relationships after undo +void MDIViewPage::fixSceneDependencies() +{ + if (getViewProviderPage()) { + getViewProviderPage()->fixSceneDependencies(); + } +} + //**** printing routines void MDIViewPage::getPaperAttributes() diff --git a/src/Mod/TechDraw/Gui/MDIViewPage.h b/src/Mod/TechDraw/Gui/MDIViewPage.h index 0757aafb93..d44fdfc9b6 100644 --- a/src/Mod/TechDraw/Gui/MDIViewPage.h +++ b/src/Mod/TechDraw/Gui/MDIViewPage.h @@ -116,6 +116,7 @@ public: void contextMenuEvent(QContextMenuEvent *event) override; void setScene(QGSPage* scene, QGVPage* view); + void fixSceneDependencies(); public Q_SLOTS: void viewAll() override; diff --git a/src/Mod/TechDraw/Gui/ViewProviderPage.cpp b/src/Mod/TechDraw/Gui/ViewProviderPage.cpp index faf8b89b5d..f2eb236e1c 100644 --- a/src/Mod/TechDraw/Gui/ViewProviderPage.cpp +++ b/src/Mod/TechDraw/Gui/ViewProviderPage.cpp @@ -60,6 +60,7 @@ #include "QGVPage.h" #include "ViewProviderPageExtension.h" #include "ViewProviderTemplate.h" +#include "ViewProviderViewPart.h" using namespace TechDrawGui; @@ -557,3 +558,23 @@ ViewProviderPageExtension* ViewProviderPage::getVPPExtension() const } const char* ViewProviderPage::whoAmI() const { return m_pageName.c_str(); } + + +void ViewProviderPage::fixSceneDependencies() +{ + App::Document* doc = getDrawPage()->getDocument(); + std::vector docObjs = + doc->getObjectsOfType(TechDraw::DrawViewPart::getClassTypeId()); + for (auto& obj : docObjs) { + Gui::ViewProvider* vp = Gui::Application::Instance->getViewProvider(obj); + if (!vp) { + continue;// can't fix this one + } + TechDrawGui::ViewProviderViewPart* vpvp = dynamic_cast(vp); + if (!vpvp) { + continue;// can't fix this one + } + vpvp->fixSceneDependencies(); + } + +} diff --git a/src/Mod/TechDraw/Gui/ViewProviderPage.h b/src/Mod/TechDraw/Gui/ViewProviderPage.h index 7ac7764a34..34dbb27d42 100644 --- a/src/Mod/TechDraw/Gui/ViewProviderPage.h +++ b/src/Mod/TechDraw/Gui/ViewProviderPage.h @@ -126,6 +126,9 @@ public: const char* whoAmI() const; + void fixSceneDependencies(); + + protected: bool setEdit(int ModNum) override; void createMDIViewPage(); diff --git a/src/Mod/TechDraw/Gui/ViewProviderViewPart.cpp b/src/Mod/TechDraw/Gui/ViewProviderViewPart.cpp index 1d2e4d0346..7c4e55d0b0 100644 --- a/src/Mod/TechDraw/Gui/ViewProviderViewPart.cpp +++ b/src/Mod/TechDraw/Gui/ViewProviderViewPart.cpp @@ -52,6 +52,10 @@ #include "QGIView.h" #include "TaskDetail.h" #include "ViewProviderViewPart.h" +#include "ViewProviderPage.h" +#include "QGIViewDimension.h" +#include "QGIViewBalloon.h" +#include "QGSPage.h" using namespace TechDrawGui; using namespace TechDraw; @@ -167,6 +171,7 @@ void ViewProviderViewPart::onChanged(const App::Property* prop) void ViewProviderViewPart::attach(App::DocumentObject *pcFeat) { +// Base::Console().Message("VPVP::attach(%s)\n", pcFeat->getNameInDocument()); TechDraw::DrawViewMulti* dvm = dynamic_cast(pcFeat); TechDraw::DrawViewDetail* dvd = dynamic_cast(pcFeat); if (dvm) { @@ -222,6 +227,7 @@ std::vector ViewProviderViewPart::claimChildren() const return std::vector(); } } + bool ViewProviderViewPart::setEdit(int ModNum) { if (ModNum != ViewProvider::Default ) { @@ -309,26 +315,16 @@ bool ViewProviderViewPart::onDelete(const std::vector &) auto viewSection = getViewObject()->getSectionRefs(); auto viewDetail = getViewObject()->getDetailRefs(); auto viewLeader = getViewObject()->getLeaders(); + auto viewDimension = getViewObject()->getDimensions(); + auto viewBalloon = getViewObject()->getBalloons(); - if (!viewSection.empty()) { + if (!viewDimension.empty() || + !viewBalloon.empty() || + !viewSection.empty() || + !viewDetail.empty() || + !viewLeader.empty()) { bodyMessageStream << qApp->translate("Std_Delete", - "You cannot delete this view because it has a section view that would become broken."); - QMessageBox::warning(Gui::getMainWindow(), - qApp->translate("Std_Delete", "Object dependencies"), bodyMessage, - QMessageBox::Ok); - return false; - } - else if (!viewDetail.empty()) { - bodyMessageStream << qApp->translate("Std_Delete", - "You cannot delete this view because it has a detail view that would become broken."); - QMessageBox::warning(Gui::getMainWindow(), - qApp->translate("Std_Delete", "Object dependencies"), bodyMessage, - QMessageBox::Ok); - return false; - } - else if (!viewLeader.empty()) { - bodyMessageStream << qApp->translate("Std_Delete", - "You cannot delete this view because it has a leader line that would become broken."); + "You cannot delete this view because it has one or more dependent objects that would become broken."); QMessageBox::warning(Gui::getMainWindow(), qApp->translate("Std_Delete", "Object dependencies"), bodyMessage, QMessageBox::Ok); @@ -364,4 +360,31 @@ int ViewProviderViewPart::prefHighlightStyle() return Preferences::getPreferenceGroup("Decorations")->GetInt("HighlightStyle", 2); } +// it can happen that Dimensions/Balloons/etc can lose their parent item if the +// the parent is deleted, then undo is invoked. The linkages on the App side are +// handled by the undo mechanism, but the QGraphicsScene parentage is not reset. +// TODO: does this need to be implemented for Leaderlines and ???? others? +void ViewProviderViewPart::fixSceneDependencies() +{ +// Base::Console().Message("VPVP::fixSceneDependencies()\n"); + auto scene = getViewProviderPage()->getQGSPage(); + auto partQView = getQView(); + auto dimensions = getViewPart()->getDimensions(); + for (auto& dim : dimensions) { + auto dimQView = dynamic_cast(scene->findQViewForDocObj(dim)); + if (dimQView && dimQView->parentItem() != partQView) { + // need to add the dim QView to this QGIViewPart + scene->addDimToParent(dimQView, partQView); + } + } + + auto balloons = getViewPart()->getBalloons(); + for (auto& bal : balloons) { + auto balQView = dynamic_cast(scene->findQViewForDocObj(bal)); + if (balQView && balQView->parentItem() != partQView) { + // need to add the balloon QView to this QGIViewPart + scene->addBalloonToParent(balQView, partQView); + } + } +} diff --git a/src/Mod/TechDraw/Gui/ViewProviderViewPart.h b/src/Mod/TechDraw/Gui/ViewProviderViewPart.h index 69bfa031c0..27dc8fa10b 100644 --- a/src/Mod/TechDraw/Gui/ViewProviderViewPart.h +++ b/src/Mod/TechDraw/Gui/ViewProviderViewPart.h @@ -69,16 +69,14 @@ public: bool canDelete(App::DocumentObject* obj) const override; bool setEdit(int ModNum) override; bool doubleClicked(void) override; - -public: void onChanged(const App::Property *prop) override; void handleChangedPropertyType(Base::XMLReader &reader, const char *TypeName, App::Property * prop) override; App::Color prefSectionColor(void); App::Color prefHighlightColor(void); int prefHighlightStyle(void); - std::vector claimChildren(void) const override; + void fixSceneDependencies(); TechDraw::DrawViewPart* getViewObject() const override; TechDraw::DrawViewPart* getViewPart() const;