diff --git a/src/Mod/TechDraw/App/DrawProjGroupItem.cpp b/src/Mod/TechDraw/App/DrawProjGroupItem.cpp index f51d9669b4..c88be8e089 100644 --- a/src/Mod/TechDraw/App/DrawProjGroupItem.cpp +++ b/src/Mod/TechDraw/App/DrawProjGroupItem.cpp @@ -349,6 +349,38 @@ void DrawProjGroupItem::unsetupObject() DrawViewPart::unsetupObject(); } +//DPGIs have DPG as parent, not Page, so we need to ask the DPG how many Pages own it. +int DrawProjGroupItem::countParentPages() const +{ + DrawProjGroup* dpg = getPGroup(); + if (dpg != nullptr) { + int count = dpg->countParentPages(); + return count; + } + return 0; +} + +DrawPage* DrawProjGroupItem::findParentPage() const +{ + DrawProjGroup* dpg = getPGroup(); + if (dpg != nullptr) { + DrawPage* dp = dpg->findParentPage(); + return dp; + } + return nullptr; +} + +std::vector DrawProjGroupItem::findAllParentPages() const +{ + DrawProjGroup* dpg = getPGroup(); + if (dpg != nullptr) { + std::vector dps = dpg->findAllParentPages(); + return dps; + } + std::vector empty; + return empty; +} + PyObject *DrawProjGroupItem::getPyObject(void) { if (PythonObject.is(Py::_None())) { diff --git a/src/Mod/TechDraw/App/DrawProjGroupItem.h b/src/Mod/TechDraw/App/DrawProjGroupItem.h index 54ad7e0c4e..4cd00fd198 100644 --- a/src/Mod/TechDraw/App/DrawProjGroupItem.h +++ b/src/Mod/TechDraw/App/DrawProjGroupItem.h @@ -89,6 +89,10 @@ public: virtual bool checkFit(void) const override { return true; } virtual bool checkFit(DrawPage*) const override { return true; } + virtual int countParentPages() const override; + virtual DrawPage* findParentPage() const override; + virtual std::vector findAllParentPages() const override; + protected: void onChanged(const App::Property* prop) override; virtual bool isLocked(void) const override; diff --git a/src/Mod/TechDraw/App/DrawView.cpp b/src/Mod/TechDraw/App/DrawView.cpp index 3386511412..08bc499512 100644 --- a/src/Mod/TechDraw/App/DrawView.cpp +++ b/src/Mod/TechDraw/App/DrawView.cpp @@ -246,6 +246,7 @@ void DrawView::onDocumentRestored() * in case it is also a child of another duplicate page * @return */ +//note this won't find parent pages for DrawProjItem since their parent is DrawProjGroup! int DrawView::countParentPages() const { int count = 0; @@ -260,6 +261,9 @@ int DrawView::countParentPages() const return count; } +//finds the first DrawPage in this Document that claims to own this DrawView +//note that it is possible to manipulate the Views property of DrawPage so that +//more than 1 DrawPage claims a DrawView. DrawPage* DrawView::findParentPage() const { // Get Feature Page @@ -283,6 +287,33 @@ DrawPage* DrawView::findParentPage() const return page; } + +std::vector DrawView::findAllParentPages() const +{ + // Get Feature Page + std::vector result; + DrawPage *page = 0; + DrawViewCollection *collection = 0; + std::vector parent = getInList(); + for (std::vector::iterator it = parent.begin(); it != parent.end(); ++it) { + if ((*it)->getTypeId().isDerivedFrom(DrawPage::getClassTypeId())) { + page = static_cast(*it); + } + + if ((*it)->getTypeId().isDerivedFrom(DrawViewCollection::getClassTypeId())) { + collection = static_cast(*it); + page = collection->findParentPage(); + } + + if(page) { + result.emplace_back(page); + } + } + + return result; +} + + bool DrawView::isInClip() { std::vector parent = getInList(); diff --git a/src/Mod/TechDraw/App/DrawView.h b/src/Mod/TechDraw/App/DrawView.h index 83c26e4576..629bd7e4a9 100644 --- a/src/Mod/TechDraw/App/DrawView.h +++ b/src/Mod/TechDraw/App/DrawView.h @@ -23,6 +23,8 @@ #ifndef _DrawView_h_ #define _DrawView_h_ +#include + #include #include @@ -85,6 +87,7 @@ public: virtual PyObject *getPyObject(void) override; virtual DrawPage* findParentPage() const; + virtual std::vector findAllParentPages() const; virtual int countParentPages() const; virtual QRectF getRect() const; //must be overridden by derived class virtual double autoScale(void) const; diff --git a/src/Mod/TechDraw/Gui/MDIViewPage.cpp b/src/Mod/TechDraw/Gui/MDIViewPage.cpp index 8d143d5932..a5c58b462e 100644 --- a/src/Mod/TechDraw/Gui/MDIViewPage.cpp +++ b/src/Mod/TechDraw/Gui/MDIViewPage.cpp @@ -444,6 +444,10 @@ void MDIViewPage::updateTemplate(bool forceUpdate) } //this is time consuming. should only be used when there is a problem. +//Solve the situation where a DrawView belonging to this DrawPage has no QGraphicsItem in +//the QGScene for the DrawPage -or- +//a QGraphics item exists in the DrawPage's QGScene, but there is no corresponding DrawView +//in the DrawPage. void MDIViewPage::fixOrphans(bool force) { if(!force) { @@ -471,7 +475,6 @@ void MDIViewPage::fixOrphans(bool force) attachView(dv); } } - // if qView doesn't have a Feature on this Page, delete it std::vector qvss = m_view->getViews(); // qvss may contain an item and its child item(s) and to avoid to access a deleted item a QPointer is needed @@ -485,15 +488,41 @@ void MDIViewPage::fixOrphans(bool force) continue; // already deleted? App::DocumentObject* obj = doc->getObject(qv->getViewName()); if (obj == nullptr) { + //no DrawView anywhere in Document m_view->removeQView(qv); } else { - TechDraw::DrawPage* pp = qv->getViewObject()->findParentPage(); - /** avoid crash where a view might have more than one parent page - * if the user duplicated the page without duplicating dependencies - */ + //DrawView exists in Document. Does it belong to this DrawPage? int numParentPages = qv->getViewObject()->countParentPages(); - if (thisPage != pp && numParentPages == 0) { - m_view->removeQView(qv); + if (numParentPages == 0) { + //DrawView does not belong to any DrawPage + //remove QGItem from QGScene + m_view->removeQView(qv); + } else if (numParentPages == 1) { + //Does DrawView belong to this DrawPage? + TechDraw::DrawPage* pp = qv->getViewObject()->findParentPage(); + if (thisPage != pp) { + //DrawView does not belong to this DrawPage + //remove QGItem from QGScene + m_view->removeQView(qv); + } + } else if (numParentPages > 1) { + //DrawView belongs to multiple DrawPages + //this is a problem - not supposed to happen + //check if this MDIViewPage corresponds to any parent DrawPage + //if not, delete the QGItem + Base::Console().Warning("%s belongs to multiple Pages\n", obj->getNameInDocument()); + std::vector pPages = qv->getViewObject()->findAllParentPages(); + bool found = false; + for (auto p: pPages) { + if (thisPage == p) { + found = true; + break; + } + } + if (!found) { + //none of the parent Pages for View coorespond to this Page + m_view->removeQView(qv); + } } } }