[TD]improve handling of View in multiple Pages

This commit is contained in:
Wanderer Fan
2022-01-10 10:08:53 -05:00
committed by WandererFan
parent 37ac9f4d24
commit f6653d44af
5 changed files with 106 additions and 7 deletions

View File

@@ -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<DrawPage*> DrawProjGroupItem::findAllParentPages() const
{
DrawProjGroup* dpg = getPGroup();
if (dpg != nullptr) {
std::vector<DrawPage*> dps = dpg->findAllParentPages();
return dps;
}
std::vector<DrawPage*> empty;
return empty;
}
PyObject *DrawProjGroupItem::getPyObject(void)
{
if (PythonObject.is(Py::_None())) {

View File

@@ -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<DrawPage*> findAllParentPages() const override;
protected:
void onChanged(const App::Property* prop) override;
virtual bool isLocked(void) const override;

View File

@@ -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<DrawPage*> DrawView::findAllParentPages() const
{
// Get Feature Page
std::vector<DrawPage*> result;
DrawPage *page = 0;
DrawViewCollection *collection = 0;
std::vector<App::DocumentObject*> parent = getInList();
for (std::vector<App::DocumentObject*>::iterator it = parent.begin(); it != parent.end(); ++it) {
if ((*it)->getTypeId().isDerivedFrom(DrawPage::getClassTypeId())) {
page = static_cast<TechDraw::DrawPage *>(*it);
}
if ((*it)->getTypeId().isDerivedFrom(DrawViewCollection::getClassTypeId())) {
collection = static_cast<TechDraw::DrawViewCollection *>(*it);
page = collection->findParentPage();
}
if(page) {
result.emplace_back(page);
}
}
return result;
}
bool DrawView::isInClip()
{
std::vector<App::DocumentObject*> parent = getInList();

View File

@@ -23,6 +23,8 @@
#ifndef _DrawView_h_
#define _DrawView_h_
#include <Mod/TechDraw/TechDrawGlobal.h>
#include <boost_signals2.hpp>
#include <QCoreApplication>
@@ -85,6 +87,7 @@ public:
virtual PyObject *getPyObject(void) override;
virtual DrawPage* findParentPage() const;
virtual std::vector<DrawPage*> findAllParentPages() const;
virtual int countParentPages() const;
virtual QRectF getRect() const; //must be overridden by derived class
virtual double autoScale(void) const;

View File

@@ -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<QGIView*> 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<TechDraw::DrawPage*> 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);
}
}
}
}