diff --git a/src/Mod/TechDraw/App/DrawRichAnno.cpp b/src/Mod/TechDraw/App/DrawRichAnno.cpp index eecd162d40..84a242e390 100644 --- a/src/Mod/TechDraw/App/DrawRichAnno.cpp +++ b/src/Mod/TechDraw/App/DrawRichAnno.cpp @@ -79,8 +79,11 @@ void DrawRichAnno::onChanged(const App::Property* prop) //NOTE: DocumentObject::mustExecute returns 1/0 and not true/false short DrawRichAnno::mustExecute() const { - if (!isRestoring() && AnnoText.isTouched()) { - return 1; + if (!isRestoring()) { + if (AnnoText.isTouched() || + AnnoParent.isTouched()) { + return 1; + } } return DrawView::mustExecute(); @@ -101,6 +104,22 @@ DrawView* DrawRichAnno::getBaseView() const return dynamic_cast(AnnoParent.getValue()); } +//finds the first DrawPage in this Document that claims to own this DrawRichAnno +//note that it is possible to manipulate the Views property of DrawPage so that +//more than 1 DrawPage claims a DrawRichAnno. +DrawPage* DrawRichAnno::findParentPage() const +{ +// Base::Console().Message("DRA::findParentPage()\n"); + DrawPage *page = nullptr; + if (AnnoParent.getValue() != nullptr) { + DrawView* parent = dynamic_cast(AnnoParent.getValue()); + page = parent->findParentPage(); + } else { + page = DrawView::findParentPage(); + } + + return page; +} PyObject *DrawRichAnno::getPyObject() { diff --git a/src/Mod/TechDraw/App/DrawRichAnno.h b/src/Mod/TechDraw/App/DrawRichAnno.h index 9857a528f2..aeb11ba5a4 100644 --- a/src/Mod/TechDraw/App/DrawRichAnno.h +++ b/src/Mod/TechDraw/App/DrawRichAnno.h @@ -23,12 +23,13 @@ #ifndef _TechDraw_DrawRichAnno_h_ #define _TechDraw_DrawRichAnno_h_ +#include + # include # include #include "DrawView.h" - namespace TechDraw { @@ -55,6 +56,8 @@ public: QRectF getRect() const override { return QRectF(0,0,1,1);} DrawView* getBaseView() const; + DrawPage* findParentPage() const override; + protected: void onChanged(const App::Property* prop) override; diff --git a/src/Mod/TechDraw/Gui/DrawGuiUtil.cpp b/src/Mod/TechDraw/Gui/DrawGuiUtil.cpp index cc6ddcae86..87ff93d72b 100644 --- a/src/Mod/TechDraw/Gui/DrawGuiUtil.cpp +++ b/src/Mod/TechDraw/Gui/DrawGuiUtil.cpp @@ -128,7 +128,8 @@ TechDraw::DrawPage* DrawGuiUtil::findPage(Gui::Command* cmd) Gui::MDIView* mv = w->activeWindow(); MDIViewPage* mvp = dynamic_cast(mv); if (mvp) { - QGSPage* qp = mvp->getQGSPage(); + QString windowTitle = mvp->windowTitle(); + QGSPage* qp = mvp->getViewProviderPage()->getGraphicsScene(); page = qp->getDrawPage(); } else { diff --git a/src/Mod/TechDraw/Gui/MDIViewPage.cpp b/src/Mod/TechDraw/Gui/MDIViewPage.cpp index 6156e2d455..b4cbfad5ed 100644 --- a/src/Mod/TechDraw/Gui/MDIViewPage.cpp +++ b/src/Mod/TechDraw/Gui/MDIViewPage.cpp @@ -68,27 +68,9 @@ #include #include -#include #include #include -#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include "Rez.h" #include "QGIDrawingTemplate.h" @@ -119,20 +101,13 @@ TYPESYSTEM_SOURCE_ABSTRACT(TechDrawGui::MDIViewPage, Gui::MDIView) MDIViewPage::MDIViewPage(ViewProviderPage *pageVp, Gui::Document* doc, QWidget* parent) : Gui::MDIView(doc, parent), + m_vpPage(pageVp), m_orientation(QPageLayout::Landscape), m_paperSize(QPageSize::A4), - pagewidth(0.0), - pageheight(0.0), - m_vpPage(pageVp) + m_pagewidth(0.0), + m_pageheight(0.0) { - setMouseTracking(true); - m_scene = new QGSPage(pageVp, this); - m_scene->setItemIndexMethod(QGraphicsScene::NoIndex); //this prevents crash when deleting dims. - //scene(view?) indices of dirty regions gets - //out of sync. missing prepareGeometryChange - //somewhere???? QTBUG-18021??? - m_view = new QGVPage(pageVp,m_scene,this); m_toggleKeepUpdatedAction = new QAction(tr("Toggle &Keep Updated"), this); connect(m_toggleKeepUpdatedAction, SIGNAL(triggered()), this, SLOT(toggleKeepUpdated())); @@ -154,129 +129,25 @@ MDIViewPage::MDIViewPage(ViewProviderPage *pageVp, Gui::Document* doc, QWidget* QString tabText = QString::fromUtf8(pageVp->getDrawPage()->getNameInDocument()); tabText += QString::fromUtf8("[*]"); setWindowTitle(tabText); - setCentralWidget(m_view); //this makes m_view a Qt child of MDIViewPage - - m_timer = new QTimer(this); - m_timer->setSingleShot(true); - QObject::connect(m_timer,SIGNAL(timeout()),this,SLOT(onTimer())); - - // Connect Signals and Slots - QObject::connect( - m_scene, SIGNAL(selectionChanged()), - this , SLOT (sceneSelectionChanged()) - ); //get informed by App side about deleted DocumentObjects App::Document* appDoc = m_vpPage->getDocument()->getDocument(); auto bnd = boost::bind(&MDIViewPage::onDeleteObject, this, bp::_1); connectDeletedObject = appDoc->signalDeletedObject.connect(bnd); - -// setContextMenuPolicy(Qt::NoContextMenu); } - MDIViewPage::~MDIViewPage() { connectDeletedObject.disconnect(); } -void MDIViewPage::addChildrenToPage() +void MDIViewPage::setScene(QGSPage* scene, QGVPage* viewWidget) { - // A fresh page is added and we iterate through its collected children and add these to Canvas View -MLP - // if docobj is a featureviewcollection (ex orthogroup), add its child views. if there are ever children that have children, - // we'll have to make this recursive. -WF - const std::vector &grp = m_vpPage->getDrawPage()->Views.getValues(); - std::vector childViews; - for (std::vector::const_iterator it = grp.begin();it != grp.end(); ++it) { - attachView(*it); - TechDraw::DrawViewCollection* collect = dynamic_cast(*it); - if (collect) { - childViews = collect->Views.getValues(); - for (std::vector::iterator itChild = childViews.begin();itChild != childViews.end(); ++itChild) { - attachView(*itChild); - } - } - } - //when restoring, it is possible for a Dimension to be loaded before the ViewPart it applies to - //therefore we need to make sure parentage of the graphics representation is set properly. bit of a kludge. - setDimensionGroups(); - setBalloonGroups(); - setLeaderGroups(); - - App::DocumentObject *obj = m_vpPage->getDrawPage()->Template.getValue(); - auto pageTemplate( dynamic_cast(obj) ); - if( pageTemplate ) { - attachTemplate(pageTemplate); - matchSceneRectToTemplate(); - } - - viewAll(); -} - -void MDIViewPage::matchSceneRectToTemplate() -{ - App::DocumentObject *obj = m_vpPage->getDrawPage()->Template.getValue(); - auto pageTemplate( dynamic_cast(obj) ); - if( pageTemplate ) { - //make sceneRect 1 pagesize bigger in every direction - double width = Rez::guiX(pageTemplate->Width.getValue()); - double height = Rez::guiX(pageTemplate->Height.getValue()); - m_scene->setSceneRect(QRectF(-width,-2.0 * height,3.0*width,3.0*height)); - } -} - -void MDIViewPage::setDimensionGroups() -{ - const std::vector &allItems = m_scene->getViews(); - std::vector::const_iterator itInspect; - int dimItemType = QGraphicsItem::UserType + 106; - - for (itInspect = allItems.begin(); itInspect != allItems.end(); itInspect++) { - if (((*itInspect)->type() == dimItemType) && (!(*itInspect)->group())) { - QGIView* parent = m_scene->findParent((*itInspect)); - if (parent) { - QGIViewDimension* dim = dynamic_cast((*itInspect)); - m_scene->addDimToParent(dim,parent); - } - } - } -} - -void MDIViewPage::setBalloonGroups() -{ - const std::vector &allItems = m_scene->getViews(); - std::vector::const_iterator itInspect; - int balloonItemType = QGraphicsItem::UserType + 140; - - for (itInspect = allItems.begin(); itInspect != allItems.end(); itInspect++) { - if (((*itInspect)->type() == balloonItemType) && (!(*itInspect)->group())) { - QGIView* parent = m_scene->findParent((*itInspect)); - if (parent) { - QGIViewBalloon* balloon = dynamic_cast((*itInspect)); - m_scene->addBalloonToParent(balloon,parent); - } - } - } -} - -void MDIViewPage::setLeaderGroups() -{ -// Base::Console().Message("MDIVP::setLeaderGroups()\n"); - const std::vector &allItems = m_scene->getViews(); - std::vector::const_iterator itInspect; - int leadItemType = QGraphicsItem::UserType + 232; - - //make sure that qgileader belongs to correct parent. - //quite possibly redundant - for (itInspect = allItems.begin(); itInspect != allItems.end(); itInspect++) { - if (((*itInspect)->type() == leadItemType) && (!(*itInspect)->group())) { - QGIView* parent = m_scene->findParent((*itInspect)); - if (parent) { - QGILeaderLine* lead = dynamic_cast((*itInspect)); - m_scene->addLeaderToParent(lead,parent); - } - } - } + m_scene = scene; + m_view = viewWidget; + setCentralWidget(m_view); //this makes m_view a Qt child of MDIViewPage + QObject::connect(m_scene, SIGNAL(selectionChanged()), + this, SLOT (sceneSelectionChanged())); } void MDIViewPage::setDocumentObject(const std::string& name) @@ -310,102 +181,6 @@ void MDIViewPage::closeEvent(QCloseEvent* ev) blockSceneSelection(false); } -void MDIViewPage::attachTemplate(TechDraw::DrawTemplate *obj) -{ - m_scene->setPageTemplate(obj); - pagewidth = obj->Width.getValue(); - pageheight = obj->Height.getValue(); - m_paperSize = QPageSize::id(QSizeF(pagewidth, pageheight), QPageSize::Millimeter, QPageSize::FuzzyOrientationMatch); - if (pagewidth > pageheight) { - m_orientation = QPageLayout::Landscape; - } else { - m_orientation = QPageLayout::Portrait; - } -} - -QPointF MDIViewPage::getTemplateCenter(TechDraw::DrawTemplate *obj) -{ - double cx = Rez::guiX(obj->Width.getValue())/2.0; - double cy = -Rez::guiX(obj->Height.getValue())/2.0; - QPointF result(cx,cy); - return result; -} - -void MDIViewPage::centerOnPage() -{ - App::DocumentObject *obj = m_vpPage->getDrawPage()->Template.getValue(); - auto pageTemplate( dynamic_cast(obj) ); - if( pageTemplate ) { - QPointF viewCenter = getTemplateCenter(pageTemplate); - m_view->centerOn(viewCenter); - } -} - -bool MDIViewPage::addView(const App::DocumentObject *obj) -{ - return attachView(const_cast(obj)); -} - -bool MDIViewPage::attachView(App::DocumentObject *obj) -{ - auto typeId(obj->getTypeId()); - - QGIView *qview(nullptr); - - if (typeId.isDerivedFrom(TechDraw::DrawViewSection::getClassTypeId()) ) { - qview = m_scene->addViewSection( static_cast(obj) ); - - } else if (typeId.isDerivedFrom(TechDraw::DrawViewPart::getClassTypeId()) ) { - qview = m_scene->addViewPart( static_cast(obj) ); - - } else if (typeId.isDerivedFrom(TechDraw::DrawProjGroup::getClassTypeId()) ) { - qview = m_scene->addProjectionGroup( static_cast(obj) ); - - } else if (typeId.isDerivedFrom(TechDraw::DrawViewCollection::getClassTypeId()) ) { - qview = m_scene->addDrawView( static_cast(obj) ); - - } else if (typeId.isDerivedFrom(TechDraw::DrawViewDimension::getClassTypeId()) ) { - qview = m_scene->addViewDimension( static_cast(obj) ); - - } else if (typeId.isDerivedFrom(TechDraw::DrawViewBalloon::getClassTypeId()) ) { - qview = m_scene->addViewBalloon( static_cast(obj) ); - - } else if (typeId.isDerivedFrom(TechDraw::DrawViewAnnotation::getClassTypeId()) ) { - qview = m_scene->addDrawViewAnnotation( static_cast(obj) ); - - } else if (typeId.isDerivedFrom(TechDraw::DrawViewSymbol::getClassTypeId()) ) { - qview = m_scene->addDrawViewSymbol( static_cast(obj) ); - - } else if (typeId.isDerivedFrom(TechDraw::DrawViewClip::getClassTypeId()) ) { - qview = m_scene->addDrawViewClip( static_cast(obj) ); - - } else if (typeId.isDerivedFrom(TechDraw::DrawViewSpreadsheet::getClassTypeId()) ) { - qview = m_scene->addDrawViewSpreadsheet( static_cast(obj) ); - - } else if (typeId.isDerivedFrom(TechDraw::DrawViewImage::getClassTypeId()) ) { - qview = m_scene->addDrawViewImage( static_cast(obj) ); - - } else if (typeId.isDerivedFrom(TechDraw::DrawLeaderLine::getClassTypeId()) ) { - qview = m_scene->addViewLeader( static_cast(obj) ); - - } else if (typeId.isDerivedFrom(TechDraw::DrawRichAnno::getClassTypeId()) ) { - qview = m_scene->addRichAnno( static_cast(obj) ); - - } else if (typeId.isDerivedFrom(TechDraw::DrawWeldSymbol::getClassTypeId()) ) { - qview = m_scene->addWeldSymbol( static_cast(obj) ); - - } else if (typeId.isDerivedFrom(TechDraw::DrawHatch::getClassTypeId()) ) { - //Hatch is not attached like other Views (since it isn't really a View) - return true; - //DrawGeomHatch?? - - } else { - Base::Console().Log("Logic Error - Unknown view type in MDIViewPage::attachView\n"); - } - - return (qview != nullptr); -} - void MDIViewPage::onDeleteObject(const App::DocumentObject& obj) { //if this page has a QView for this obj, delete it. @@ -416,201 +191,6 @@ void MDIViewPage::onDeleteObject(const App::DocumentObject& obj) blockSceneSelection(false); } -void MDIViewPage::onTimer() { - fixOrphans(true); -} - -void MDIViewPage::updateTemplate(bool forceUpdate) -{ - App::DocumentObject *templObj = m_vpPage->getDrawPage()->Template.getValue(); - // TODO: what if template has been deleted? templObj will be NULL. segfault? - if (!templObj) { - Base::Console().Log("INFO - MDIViewPage::updateTemplate - Page: %s has NO template!!\n",m_vpPage->getDrawPage()->getNameInDocument()); - return; - } - - if(m_vpPage->getDrawPage()->Template.isTouched() || templObj->isTouched()) { - // Template is touched so update - - if(forceUpdate || - (templObj && templObj->isTouched() && templObj->isDerivedFrom(TechDraw::DrawTemplate::getClassTypeId())) ) { - - QGITemplate *qItemTemplate = m_scene->getTemplate(); - - if(qItemTemplate) { - TechDraw::DrawTemplate *pageTemplate = dynamic_cast(templObj); - qItemTemplate->setTemplate(pageTemplate); - qItemTemplate->updateView(); - } - } - } -} - -//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) { - m_timer->start(100); - return; - } - m_timer->stop(); - - // get all the DrawViews for this page, including the second level ones - // if we ever have collections of collections, we'll need to revisit this - TechDraw::DrawPage* thisPage = m_vpPage->getDrawPage(); - - if(!thisPage->getNameInDocument()) - return; - - std::vector pChildren = thisPage->getAllViews(); - - // if dv doesn't have a graphic, make one - for (auto& dv: pChildren) { - if (dv->isRemoving()) { - continue; - } - QGIView* qv = m_scene->findQViewForDocObj(dv); - if (!qv) { - attachView(dv); - } - } - // if qView doesn't have a Feature on this Page, delete it - std::vector qvss = m_scene->getViews(); - // qvss may contain an item and its child item(s) and to avoid to access a deleted item a QPointer is needed - std::vector> qvs; - std::for_each(qvss.begin(), qvss.end(), [&qvs](QGIView* v) { - qvs.emplace_back(v); - }); - App::Document* doc = getAppDocument(); - for (auto& qv: qvs) { - if (!qv) - continue; // already deleted? - App::DocumentObject* obj = doc->getObject(qv->getViewName()); - if (!obj) { - //no DrawView anywhere in Document - m_scene->removeQView(qv); - } else { - //DrawView exists in Document. Does it belong to this DrawPage? - int numParentPages = qv->getViewObject()->countParentPages(); - if (numParentPages == 0) { - //DrawView does not belong to any DrawPage - //remove QGItem from QGScene - m_scene->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_scene->removeQView(qv); - } - } else if (numParentPages > 1) { - //DrawView belongs to multiple DrawPages - //check if this MDIViewPage corresponds to any parent DrawPage - //if not, delete the QGItem - 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 correspond to this Page - m_scene->removeQView(qv); - } - } - } - } -} - -//NOTE: this doesn't add missing views. see fixOrphans() -void MDIViewPage::redrawAllViews() -{ - const std::vector &upviews = m_scene->getViews(); - for(std::vector::const_iterator it = upviews.begin(); it != upviews.end(); ++it) { - (*it)->updateView(true); - } -} - -//NOTE: this doesn't add missing views. see fixOrphans() -void MDIViewPage::redraw1View(TechDraw::DrawView* dv) -{ - std::string dvName = dv->getNameInDocument(); - const std::vector &upviews = m_scene->getViews(); - for(std::vector::const_iterator it = upviews.begin(); it != upviews.end(); ++it) { - std::string qgivName = (*it)->getViewName(); - if(dvName == qgivName) { - (*it)->updateView(true); - } - } -} - -void MDIViewPage::findMissingViews(const std::vector &list, std::vector &missing) -{ - for(std::vector::const_iterator it = list.begin(); it != list.end(); ++it) { - - if(!hasQView(*it)) - missing.push_back(*it); - - if((*it)->getTypeId().isDerivedFrom(TechDraw::DrawViewCollection::getClassTypeId())) { - std::vector missingChildViews; - TechDraw::DrawViewCollection *collection = dynamic_cast(*it); - // Find Child Views recursively - findMissingViews(collection->Views.getValues(), missingChildViews); - - // Append the views to current missing list - for(std::vector::const_iterator it = missingChildViews.begin(); it != missingChildViews.end(); ++it) { - missing.push_back(*it); - } - } - } -} - -/// Helper function -bool MDIViewPage::hasQView(App::DocumentObject *obj) -{ - const std::vector &views = m_scene->getViews(); - std::vector::const_iterator qview = views.begin(); - - while(qview != views.end()) { - // Unsure if we can compare pointers so rely on name - if(strcmp((*qview)->getViewName(), obj->getNameInDocument()) == 0) { - return true; - } - qview++; - } - - return false; -} - - -/// Helper function -bool MDIViewPage::orphanExists(const char *viewName, const std::vector &list) -{ - for(std::vector::const_iterator it = list.begin(); it != list.end(); ++it) { - - //Check child objects too recursively - if((*it)->isDerivedFrom(TechDraw::DrawViewCollection::getClassTypeId())) { - TechDraw::DrawViewCollection *collection = dynamic_cast(*it); - if(orphanExists(viewName, collection->Views.getValues())) - return true; - } - - // Unsure if we can compare pointers so rely on name - if(strcmp(viewName, (*it)->getNameInDocument()) == 0) { - return true; - } - } - return false; -} - - bool MDIViewPage::onMsg(const char *pMsg, const char **) { Gui::Document *doc(getGuiDocument()); @@ -639,7 +219,6 @@ bool MDIViewPage::onMsg(const char *pMsg, const char **) return false; } - bool MDIViewPage::onHasMsg(const char* pMsg) const { if (strcmp("ViewFit",pMsg) == 0) @@ -671,6 +250,24 @@ void MDIViewPage::setTabText(std::string t) } } +//**** printing routines + +void MDIViewPage::getPaperAttributes(void) +{ + App::DocumentObject *obj = m_vpPage->getDrawPage()->Template.getValue(); + auto pageTemplate( dynamic_cast(obj) ); + if( pageTemplate ) { + m_pagewidth = Rez::guiX(pageTemplate->Width.getValue()); + m_pageheight = Rez::guiX(pageTemplate->Height.getValue()); + } + m_paperSize = QPageSize::id(QSizeF(m_pagewidth, m_pageheight), QPageSize::Millimeter, QPageSize::FuzzyOrientationMatch); + if (m_pagewidth > m_pageheight) { + m_orientation = QPageLayout::Landscape; + } else { + m_orientation = QPageLayout::Portrait; + } +} + void MDIViewPage::printPdf() { QStringList filter; @@ -693,6 +290,8 @@ void MDIViewPage::printPdf(std::string file) Base::Console().Warning("MDIViewPage - no file specified\n"); return; } + getPaperAttributes(); + QString filename = QString::fromUtf8(file.data(),file.size()); QPrinter printer(QPrinter::HighResolution); printer.setFullPage(true); @@ -704,7 +303,7 @@ void MDIViewPage::printPdf(std::string file) printer.setPageOrientation(m_orientation); } if (m_paperSize == QPageSize::Custom) { - printer.setPageSize(QPageSize(QSizeF(pagewidth, pageheight), QPageSize::Millimeter)); + printer.setPageSize(QPageSize(QSizeF(m_pagewidth, m_pageheight), QPageSize::Millimeter)); } else { printer.setPageSize(QPageSize(m_paperSize)); } @@ -713,10 +312,12 @@ void MDIViewPage::printPdf(std::string file) void MDIViewPage::print() { + getPaperAttributes(); + QPrinter printer(QPrinter::HighResolution); printer.setFullPage(true); if (m_paperSize == QPageSize::Custom) { - printer.setPageSize(QPageSize(QSizeF(pagewidth, pageheight), QPageSize::Millimeter)); + printer.setPageSize(QPageSize(QSizeF(m_pagewidth, m_pageheight), QPageSize::Millimeter)); } else { printer.setPageSize(QPageSize(m_paperSize)); } @@ -730,10 +331,12 @@ void MDIViewPage::print() void MDIViewPage::printPreview() { + getPaperAttributes(); + QPrinter printer(QPrinter::HighResolution); printer.setFullPage(true); if (m_paperSize == QPageSize::Custom) { - printer.setPageSize(QPageSize(QSizeF(pagewidth, pageheight), QPageSize::Millimeter)); + printer.setPageSize(QPageSize(QSizeF(m_pagewidth, m_pageheight), QPageSize::Millimeter)); } else { printer.setPageSize(QPageSize(m_paperSize)); } @@ -748,6 +351,8 @@ void MDIViewPage::printPreview() void MDIViewPage::print(QPrinter* printer) { + getPaperAttributes(); + // As size of the render area paperRect() should be used. When performing a real // print pageRect() may also work but the output is cropped at the bottom part. // So, independent whether pageRect() or paperRect() is used there is no scaling effect. diff --git a/src/Mod/TechDraw/Gui/MDIViewPage.h b/src/Mod/TechDraw/Gui/MDIViewPage.h index 33da9a0c98..2c0f6de395 100644 --- a/src/Mod/TechDraw/Gui/MDIViewPage.h +++ b/src/Mod/TechDraw/Gui/MDIViewPage.h @@ -39,7 +39,6 @@ QT_BEGIN_NAMESPACE class QAction; class QGraphicsItem; class QGraphicsScene; -class QTimer; QT_END_NAMESPACE namespace TechDraw { @@ -77,11 +76,6 @@ public: void clearSceneSelection(); void blockSceneSelection(bool isBlocked); - void attachTemplate(TechDraw::DrawTemplate *obj); - void updateTemplate(bool force = false); - void fixOrphans(bool force = false); - void matchSceneRectToTemplate(); - bool onMsg(const char* pMsg,const char** ppReturn) override; bool onHasMsg(const char* pMsg) const override; @@ -100,23 +94,15 @@ public: PyObject* getPyObject() override; TechDraw::DrawPage * getPage() { return m_vpPage->getDrawPage(); } - QGVPage* getQGVPage() {return m_view;} - QGSPage* getQGSPage() {return m_scene;} ViewProviderPage* getViewProviderPage() {return m_vpPage;} - QPointF getTemplateCenter(TechDraw::DrawTemplate *obj); - void centerOnPage(); - - void redrawAllViews(); - void redraw1View(TechDraw::DrawView* dv); - void setTabText(std::string t); - bool addView(const App::DocumentObject *obj); - static MDIViewPage *getFromScene(const QGSPage *scene); void contextMenuEvent(QContextMenuEvent *event) override; + void setScene(QGSPage* scene, QGVPage* view); + public Q_SLOTS: void viewAll() override; void saveSVG(); @@ -126,21 +112,10 @@ public Q_SLOTS: void toggleKeepUpdated(); // void testAction(void); void sceneSelectionChanged(); - void onTimer(); protected: - void findMissingViews( const std::vector &list, std::vector &missing); - bool hasQView(App::DocumentObject *obj); - bool orphanExists(const char *viewName, const std::vector &list); - - /// Attaches view of obj to m_scene. Returns true on success, false otherwise - bool attachView(App::DocumentObject *obj); - void closeEvent(QCloseEvent*) override; - void setDimensionGroups(); - void setBalloonGroups(); - void setLeaderGroups(); void showStatusMsg(const char* s1, const char* s2, const char* s3) const; void onDeleteObject(const App::DocumentObject& obj); @@ -152,7 +127,6 @@ protected: void setTreeToSceneSelect(); void sceneSelectionManager(); - private: QAction *m_toggleFrameAction; QAction *m_toggleKeepUpdatedAction; @@ -166,16 +140,17 @@ private: bool isSelectionBlocked; QGSPage* m_scene; QGVPage *m_view; - QTimer *m_timer; QString m_currentPath; - QPageLayout::Orientation m_orientation; - QPageSize::PageSizeId m_paperSize; - qreal pagewidth, pageheight; ViewProviderPage *m_vpPage; QList m_qgSceneSelected; //items in selection order -// QList deleteItems; + + void getPaperAttributes(void); + QPageLayout::Orientation m_orientation; + QPageSize::PageSizeId m_paperSize; + double m_pagewidth, m_pageheight; + }; class MDIViewPagePy : public Py::PythonExtension diff --git a/src/Mod/TechDraw/Gui/QGIRichAnno.cpp b/src/Mod/TechDraw/Gui/QGIRichAnno.cpp index e0d847651b..b6f06e2fa8 100644 --- a/src/Mod/TechDraw/Gui/QGIRichAnno.cpp +++ b/src/Mod/TechDraw/Gui/QGIRichAnno.cpp @@ -76,7 +76,6 @@ #include "QGIPrimPath.h" #include "QGEPath.h" #include "QGMText.h" -#include "QGIView.h" #include "QGCustomText.h" #include "QGCustomRect.h" @@ -88,8 +87,7 @@ using namespace TechDrawGui; //************************************************************** -QGIRichAnno::QGIRichAnno(QGraphicsItem* myParent, - TechDraw::DrawRichAnno* anno) : +QGIRichAnno::QGIRichAnno() : m_isExporting(false), m_hasHover(false) { setHandlesChildEvents(false); @@ -99,12 +97,6 @@ QGIRichAnno::QGIRichAnno(QGraphicsItem* myParent, setFlag(QGraphicsItem::ItemSendsScenePositionChanges, true); setFlag(QGraphicsItem::ItemSendsGeometryChanges,true); - if (myParent) { - setParentItem(myParent); - } - - setViewFeature(anno); - m_text = new QGCustomText(); m_text->setTextInteractionFlags(Qt::NoTextInteraction); addToGroup(m_text); @@ -176,15 +168,14 @@ void QGIRichAnno::draw() return; auto vp = static_cast(getViewProvider(getFeature())); - if (!vp) + if (!vp) { // Base::Console().Message("QGIRA::draw - no viewprovider\n"); return; -// double appX = Rez::guiX(annoFeat->X.getValue()); -// double appY = Rez::guiX(annoFeat->Y.getValue()); - - QGIView::draw(); + } setTextItem(); + + QGIView::draw(); } void QGIRichAnno::setTextItem() diff --git a/src/Mod/TechDraw/Gui/QGIRichAnno.h b/src/Mod/TechDraw/Gui/QGIRichAnno.h index aab1710e24..ddc9491dd4 100644 --- a/src/Mod/TechDraw/Gui/QGIRichAnno.h +++ b/src/Mod/TechDraw/Gui/QGIRichAnno.h @@ -32,6 +32,7 @@ #include #include +#include "QGIView.h" namespace TechDraw { class DrawRichAnno; @@ -57,8 +58,7 @@ class TechDrawGuiExport QGIRichAnno : public QGIView public: enum {Type = QGraphicsItem::UserType + 233}; - explicit QGIRichAnno(QGraphicsItem* myParent = nullptr, - TechDraw::DrawRichAnno* lead = nullptr); + explicit QGIRichAnno(); ~QGIRichAnno() = default; int type() const override { return Type;} diff --git a/src/Mod/TechDraw/Gui/QGIView.cpp b/src/Mod/TechDraw/Gui/QGIView.cpp index da05e0a1f0..d34daebbb4 100644 --- a/src/Mod/TechDraw/Gui/QGIView.cpp +++ b/src/Mod/TechDraw/Gui/QGIView.cpp @@ -617,12 +617,15 @@ Gui::ViewProvider* QGIView::getViewProvider(App::DocumentObject* obj) QGVPage* QGIView::getGraphicsView(TechDraw::DrawView* dv) { QGVPage* graphicsView = nullptr; - Gui::ViewProvider* vp = getViewProvider(dv); - ViewProviderDrawingView* vpdv = dynamic_cast(vp); - if (vpdv) { - MDIViewPage* mdi = vpdv->getMDIViewPage(); - if (mdi) { - graphicsView = mdi->getQGVPage(); + if (dv != nullptr) { + TechDraw::DrawPage* page = dv->findParentPage(); + if (page != nullptr) { + Gui::Document* activeGui = Gui::Application::Instance->getDocument(page->getDocument()); + Gui::ViewProvider* vp = activeGui->getViewProvider(page); + ViewProviderPage* vpp = dynamic_cast(vp); + if (vpp != nullptr) { + graphicsView = vpp->getGraphicsView(); + } } } return graphicsView; @@ -631,12 +634,15 @@ QGVPage* QGIView::getGraphicsView(TechDraw::DrawView* dv) QGSPage* QGIView::getGraphicsScene(TechDraw::DrawView* dv) { QGSPage* graphicsScene = nullptr; - Gui::ViewProvider* vp = getViewProvider(dv); - ViewProviderDrawingView* vpdv = dynamic_cast(vp); - if (vpdv) { - MDIViewPage* mdi = vpdv->getMDIViewPage(); - if (mdi) { - graphicsScene = mdi->getQGSPage(); + if (dv != nullptr) { + TechDraw::DrawPage* page = dv->findParentPage(); + if (page != nullptr) { + Gui::Document* activeGui = Gui::Application::Instance->getDocument(page->getDocument()); + Gui::ViewProvider* vp = activeGui->getViewProvider(page); + ViewProviderPage* vpp = dynamic_cast(vp); + if (vpp != nullptr) { + graphicsScene = vpp->getGraphicsScene(); + } } } return graphicsScene; @@ -644,8 +650,19 @@ QGSPage* QGIView::getGraphicsScene(TechDraw::DrawView* dv) MDIViewPage* QGIView::getMDIViewPage() const { - QGSPage* qgsp = static_cast(scene()); - return MDIViewPage::getFromScene(qgsp); + MDIViewPage* mdi = nullptr; + if (getViewObject() != nullptr) { + TechDraw::DrawPage* page = getViewObject()->findParentPage(); + if (page != nullptr) { + Gui::Document* activeGui = Gui::Application::Instance->getDocument(page->getDocument()); + Gui::ViewProvider* vp = activeGui->getViewProvider(page); + ViewProviderPage* vpp = dynamic_cast(vp); + if (vpp != nullptr) { + mdi = vpp->getMDIViewPage(); + } + } + } + return mdi; } //remove a child of this from scene while keeping scene indexes valid diff --git a/src/Mod/TechDraw/Gui/QGSPage.cpp b/src/Mod/TechDraw/Gui/QGSPage.cpp index 26d732af96..1f2766fa24 100644 --- a/src/Mod/TechDraw/Gui/QGSPage.cpp +++ b/src/Mod/TechDraw/Gui/QGSPage.cpp @@ -61,29 +61,31 @@ #include #include -#include -#include -#include -#include -#include -#include -#include -#include -//#include -#include -#include -#include -#include -#include #include -#include -#include #include +#include +#include +#include #include -#include +#include +#include #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + #include "Rez.h" #include "PreferencesGui.h" @@ -109,6 +111,7 @@ #include "QGITile.h" #include "ZVALUE.h" +#include "DrawGuiUtil.h" #include "ViewProviderPage.h" #include "QGSPage.h" #include "MDIViewPage.h" @@ -131,9 +134,6 @@ QGSPage::QGSPage(ViewProviderPage *vp, QWidget *parent) { assert(vp); m_vpPage = vp; - const char* name = vp->getDrawPage()->getNameInDocument(); - setObjectName(QString::fromLocal8Bit(name)); - m_vpPage->setGraphicsScene(this); } QGSPage::~QGSPage() @@ -141,6 +141,132 @@ QGSPage::~QGSPage() } +void QGSPage::addChildrenToPage(void) +{ +// Base::Console().Message("QGSP::addChildrenToPage()\n"); + // A fresh page is added and we iterate through its collected children and add these to Canvas View -MLP + // if docobj is a featureviewcollection (ex orthogroup), add its child views. if there are ever children that have children, + // we'll have to make this recursive. -WF + const std::vector &grp = m_vpPage->getDrawPage()->Views.getValues(); + std::vector childViews; + for (std::vector::const_iterator it = grp.begin();it != grp.end(); ++it) { + attachView(*it); + TechDraw::DrawViewCollection* collect = dynamic_cast(*it); + if (collect) { + childViews = collect->Views.getValues(); + for (std::vector::iterator itChild = childViews.begin();itChild != childViews.end(); ++itChild) { + attachView(*itChild); + } + } + } + //when restoring, it is possible for a Dimension to be loaded before the ViewPart it applies to + //therefore we need to make sure parentage of the graphics representation is set properly. bit of a kludge. + setDimensionGroups(); + setBalloonGroups(); + setLeaderGroups(); + setRichAnnoGroups(); + + App::DocumentObject *obj = m_vpPage->getDrawPage()->Template.getValue(); + auto pageTemplate( dynamic_cast(obj) ); + if( pageTemplate ) { + attachTemplate(pageTemplate); + matchSceneRectToTemplate(); + } + +// viewAll(); +} + +//********** template related routines ********* + +void QGSPage::attachTemplate(TechDraw::DrawTemplate *obj) +{ +// Base::Console().Message("QGSP::attachTemplate()\n"); + setPageTemplate(obj); +} + +void QGSPage::updateTemplate(bool forceUpdate) +{ +// Base::Console().Message("QGSP::updateTemplate()\n"); + App::DocumentObject *templObj = m_vpPage->getDrawPage()->Template.getValue(); + // TODO: what if template has been deleted? templObj will be NULL. segfault? + if (!templObj) { + Base::Console().Log("INFO - QGSPage::updateTemplate - Page: %s has NO template!!\n",m_vpPage->getDrawPage()->getNameInDocument()); + return; + } + + if(m_vpPage->getDrawPage()->Template.isTouched() || templObj->isTouched()) { + // Template is touched so update + + if(forceUpdate || + (templObj && templObj->isTouched() && templObj->isDerivedFrom(TechDraw::DrawTemplate::getClassTypeId())) ) { + + QGITemplate *qItemTemplate = getTemplate(); + + if(qItemTemplate) { + TechDraw::DrawTemplate *pageTemplate = dynamic_cast(templObj); + qItemTemplate->setTemplate(pageTemplate); + qItemTemplate->updateView(); + } + } + } +} + +QPointF QGSPage::getTemplateCenter() +{ + QPointF result(0.0, 0.0); + App::DocumentObject *obj = m_vpPage->getDrawPage()->Template.getValue(); + auto pageTemplate( dynamic_cast(obj) ); + if( pageTemplate != nullptr ) { + double cx = Rez::guiX(pageTemplate->Width.getValue())/2.0; + double cy = -Rez::guiX(pageTemplate->Height.getValue())/2.0; + result = QPointF(cx,cy); + } + return result; +} + +void QGSPage::matchSceneRectToTemplate(void) +{ +// Base::Console().Message("QGSP::matchSceneRectToTemplate()\n"); + App::DocumentObject *obj = m_vpPage->getDrawPage()->Template.getValue(); + auto pageTemplate( dynamic_cast(obj) ); + if( pageTemplate ) { + //make sceneRect 1 pagesize bigger in every direction + double width = Rez::guiX(pageTemplate->Width.getValue()); + double height = Rez::guiX(pageTemplate->Height.getValue()); + setSceneRect(QRectF(-width,-2.0 * height,3.0*width,3.0*height)); + } +} + +void QGSPage::setPageTemplate(TechDraw::DrawTemplate *obj) +{ +// Base::Console().Message("QGSP::setPageTemplate()\n"); + removeTemplate(); + + if(obj->isDerivedFrom(TechDraw::DrawParametricTemplate::getClassTypeId())) { + pageTemplate = new QGIDrawingTemplate(this); + } else if(obj->isDerivedFrom(TechDraw::DrawSVGTemplate::getClassTypeId())) { + pageTemplate = new QGISVGTemplate(this); + } + pageTemplate->setTemplate(obj); + pageTemplate->updateView(); +} + +QGITemplate* QGSPage::getTemplate() const +{ + return pageTemplate; +} + +void QGSPage::removeTemplate() +{ + if(pageTemplate) { + removeItem(pageTemplate); + pageTemplate->deleteLater(); + pageTemplate = nullptr; + } +} + +//******* QGIView related routines + //! retrieve the QGIView objects currently in the scene std::vector QGSPage::getViews() const { @@ -231,15 +357,79 @@ void QGSPage::removeQViewFromScene(QGIView *view) } } +bool QGSPage::addView(const App::DocumentObject *obj) +{ + return attachView(const_cast(obj)); +} + +bool QGSPage::attachView(App::DocumentObject *obj) +{ +// Base::Console().Message("QGSP::attachView(%s)\n", obj->getNameInDocument()); + QGIView* existing = findQViewForDocObj(obj); + if (existing != nullptr) { + return true; + } + + auto typeId(obj->getTypeId()); + + QGIView *qview(nullptr); + + if (typeId.isDerivedFrom(TechDraw::DrawViewSection::getClassTypeId()) ) { + qview = addViewSection( static_cast(obj) ); + + } else if (typeId.isDerivedFrom(TechDraw::DrawViewPart::getClassTypeId()) ) { + qview = addViewPart( static_cast(obj) ); + + } else if (typeId.isDerivedFrom(TechDraw::DrawProjGroup::getClassTypeId()) ) { + qview = addProjectionGroup( static_cast(obj) ); + + } else if (typeId.isDerivedFrom(TechDraw::DrawViewCollection::getClassTypeId()) ) { + qview = addDrawView( static_cast(obj) ); + + } else if (typeId.isDerivedFrom(TechDraw::DrawViewDimension::getClassTypeId()) ) { + qview = addViewDimension( static_cast(obj) ); + + } else if (typeId.isDerivedFrom(TechDraw::DrawViewBalloon::getClassTypeId()) ) { + qview = addViewBalloon( static_cast(obj) ); + + } else if (typeId.isDerivedFrom(TechDraw::DrawViewAnnotation::getClassTypeId()) ) { + qview = addDrawViewAnnotation( static_cast(obj) ); + + } else if (typeId.isDerivedFrom(TechDraw::DrawViewSymbol::getClassTypeId()) ) { + qview = addDrawViewSymbol( static_cast(obj) ); + + } else if (typeId.isDerivedFrom(TechDraw::DrawViewClip::getClassTypeId()) ) { + qview = addDrawViewClip( static_cast(obj) ); + + } else if (typeId.isDerivedFrom(TechDraw::DrawViewSpreadsheet::getClassTypeId()) ) { + qview = addDrawViewSpreadsheet( static_cast(obj) ); + + } else if (typeId.isDerivedFrom(TechDraw::DrawViewImage::getClassTypeId()) ) { + qview = addDrawViewImage( static_cast(obj) ); + + } else if (typeId.isDerivedFrom(TechDraw::DrawLeaderLine::getClassTypeId()) ) { + qview = addViewLeader( static_cast(obj) ); + + } else if (typeId.isDerivedFrom(TechDraw::DrawRichAnno::getClassTypeId()) ) { + qview = addRichAnno( static_cast(obj) ); + + } else if (typeId.isDerivedFrom(TechDraw::DrawWeldSymbol::getClassTypeId()) ) { + qview = addWeldSymbol( static_cast(obj) ); + + } else if (typeId.isDerivedFrom(TechDraw::DrawHatch::getClassTypeId()) ) { + //Hatch is not attached like other Views (since it isn't really a View) + return true; + + } else { + Base::Console().Log("Logic Error - Unknown view type in QGSPage::attachView\n"); + } + + return (qview != nullptr); +} QGIView * QGSPage::addViewPart(TechDraw::DrawViewPart *part) { // Base::Console().Message("QGSP::addViewPart(%s)\n", part->getNameInDocument()); - QGIView* existing = findQViewForDocObj(part); - if (existing) { - return existing; - } - auto viewPart( new QGIViewPart ); viewPart->setViewPartFeature(part); @@ -258,7 +448,8 @@ QGIView * QGSPage::addViewSection(TechDraw::DrawViewPart *part) return viewSection; } -QGIView * QGSPage::addProjectionGroup(TechDraw::DrawProjGroup *view) { +QGIView * QGSPage::addProjectionGroup(TechDraw::DrawProjGroup *view) +{ auto qview( new QGIProjGroup ); qview->setViewFeature(view); @@ -426,7 +617,7 @@ QGIView * QGSPage::addViewDimension(TechDraw::DrawViewDimension *dim) void QGSPage::addDimToParent(QGIViewDimension* dim, QGIView* parent) { -// Base::Console().Message("QGVP::addDimToParent()\n"); +// Base::Console().Message("QGSP::addDimToParent()\n"); assert(dim); assert(parent); //blow up if we don't have Dimension or Parent QPointF posRef(0.,0.); @@ -438,7 +629,7 @@ void QGSPage::addDimToParent(QGIViewDimension* dim, QGIView* parent) QGIView * QGSPage::addViewLeader(TechDraw::DrawLeaderLine *leader) { -// Base::Console().Message("QGVP::addViewLeader(%s)\n",leader->getNameInDocument()); +// Base::Console().Message("QGSP::addViewLeader(%s)\n",leader->getNameInDocument()); QGILeaderLine* leaderGroup = new QGILeaderLine(); addItem(leaderGroup); @@ -458,35 +649,38 @@ QGIView * QGSPage::addViewLeader(TechDraw::DrawLeaderLine *leader) void QGSPage::addLeaderToParent(QGILeaderLine* lead, QGIView* parent) { -// Base::Console().Message("QGVP::addLeaderToParent()\n"); +// Base::Console().Message("QGSP::addLeaderToParent()\n"); parent->addToGroup(lead); lead->setZValue(ZVALUE::DIMENSION); } QGIView * QGSPage::addRichAnno(TechDraw::DrawRichAnno* anno) { - QGIRichAnno* annoGroup = nullptr; - TechDraw::DrawView* parentDV = nullptr; - - App::DocumentObject* parentObj = anno->AnnoParent.getValue(); - if (parentObj) { - parentDV = dynamic_cast(parentObj); - } - if (parentDV) { - QGIView* parentQV = findQViewForDocObj(parentObj); - annoGroup = new QGIRichAnno(parentQV, anno); - annoGroup->updateView(true); - } else { - annoGroup = new QGIRichAnno(nullptr, anno); - addItem(annoGroup); - annoGroup->updateView(true); + QGIRichAnno* annoGroup = new QGIRichAnno(); + addItem(annoGroup); + annoGroup->setViewFeature(anno); + + QGIView *parent = findParent(annoGroup); + if (parent != nullptr) { + addAnnoToParent(annoGroup, parent); } + + annoGroup->updateView(true); + return annoGroup; } +void QGSPage::addAnnoToParent(QGIRichAnno* anno, QGIView* parent) +{ +// Base::Console().Message("QGSP::addAnnoToParent()\n"); + parent->addToGroup(anno); + anno->setZValue(ZVALUE::DIMENSION); +} + + QGIView * QGSPage::addWeldSymbol(TechDraw::DrawWeldSymbol* weld) { -// Base::Console().Message("QGVP::addWeldSymbol()\n"); +// Base::Console().Message("QGSP::addWeldSymbol()\n"); QGIWeldSymbol* weldGroup = nullptr; TechDraw::DrawView* parentDV = nullptr; @@ -494,7 +688,7 @@ QGIView * QGSPage::addWeldSymbol(TechDraw::DrawWeldSymbol* weld) if (parentObj) { parentDV = dynamic_cast(parentObj); } else { -// Base::Console().Message("QGVP::addWeldSymbol - no parent doc obj\n"); +// Base::Console().Message("QGSP::addWeldSymbol - no parent doc obj\n"); } if (parentDV) { QGIView* parentQV = findQViewForDocObj(parentObj); @@ -504,26 +698,95 @@ QGIView * QGSPage::addWeldSymbol(TechDraw::DrawWeldSymbol* weld) weldGroup->setFeature(weld); //for QGIWS weldGroup->setViewFeature(weld); //for QGIV weldGroup->updateView(true); - } else { - Base::Console().Error("QGVP::addWeldSymbol - no parent QGILL\n"); } - } else { - Base::Console().Error("QGVP::addWeldSymbol - parent is not DV!\n"); } return weldGroup; } +void QGSPage::setDimensionGroups(void) +{ + const std::vector &allItems = getViews(); + std::vector::const_iterator itInspect; + int dimItemType = QGraphicsItem::UserType + 106; + + for (itInspect = allItems.begin(); itInspect != allItems.end(); itInspect++) { + if (((*itInspect)->type() == dimItemType) && (!(*itInspect)->group())) { + QGIView* parent = findParent((*itInspect)); + if (parent) { + QGIViewDimension* dim = dynamic_cast((*itInspect)); + addDimToParent(dim,parent); + } + } + } +} + +void QGSPage::setBalloonGroups(void) +{ + const std::vector &allItems = getViews(); + std::vector::const_iterator itInspect; + int balloonItemType = QGraphicsItem::UserType + 140; + + for (itInspect = allItems.begin(); itInspect != allItems.end(); itInspect++) { + if (((*itInspect)->type() == balloonItemType) && (!(*itInspect)->group())) { + QGIView* parent = findParent((*itInspect)); + if (parent) { + QGIViewBalloon* balloon = dynamic_cast((*itInspect)); + addBalloonToParent(balloon,parent); + } + } + } +} + +void QGSPage::setLeaderGroups(void) +{ +// Base::Console().Message("QGSP::setLeaderGroups()\n"); + const std::vector &allItems = getViews(); + std::vector::const_iterator itInspect; + int leadItemType = QGraphicsItem::UserType + 232; + + //make sure that qgileader belongs to correct parent. + //quite possibly redundant + for (itInspect = allItems.begin(); itInspect != allItems.end(); itInspect++) { + if (((*itInspect)->type() == leadItemType) && (!(*itInspect)->group())) { + QGIView* parent = findParent((*itInspect)); + if (parent) { + QGILeaderLine* lead = dynamic_cast((*itInspect)); + addLeaderToParent(lead,parent); + } + } + } +} + +void QGSPage::setRichAnnoGroups(void) +{ +// Base::Console().Message("QGSP::setRichAnnoGroups()\n"); + const std::vector &allItems = getViews(); + std::vector::const_iterator itInspect; + int annoItemType = QGraphicsItem::UserType + 233; + + //make sure that qgirichanno belongs to correct parent. + for (itInspect = allItems.begin(); itInspect != allItems.end(); itInspect++) { + if (((*itInspect)->type() == annoItemType) && (!(*itInspect)->group())) { + QGIView* parent = findParent((*itInspect)); + if (parent) { + QGIRichAnno* anno = dynamic_cast((*itInspect)); + addAnnoToParent(anno,parent); + } + } + } +} //! find the graphic for a DocumentObject QGIView * QGSPage::findQViewForDocObj(App::DocumentObject *obj) const { - if(obj) { - const std::vector qviews = getViews(); - for(std::vector::const_iterator it = qviews.begin(); it != qviews.end(); ++it) { - if(strcmp(obj->getNameInDocument(), (*it)->getViewName()) == 0) - return *it; - } - } +// Base::Console().Message("QGSP::findQViewForDocObj(%s)\n", obj->getNameInDocument()); + if(obj) { + const std::vector qviews = getViews(); + for(std::vector::const_iterator it = qviews.begin(); it != qviews.end(); ++it) { + if(strcmp(obj->getNameInDocument(), (*it)->getViewName()) == 0) + return *it; + } + } return nullptr; } @@ -547,6 +810,7 @@ QGIView* QGSPage::getQGIVByName(std::string name) //find the parent of a QGIV based on the corresponding feature's parentage QGIView *QGSPage::findParent(QGIView *view) const { +// Base::Console().Message("QGSP::findParent(%s)\n", view->getViewName()); const std::vector qviews = getViews(); TechDraw::DrawView *myFeat = view->getViewObject(); @@ -584,6 +848,36 @@ QGIView *QGSPage::findParent(QGIView *view) const } } + //If type is LeaderLine we check LeaderParent + TechDraw::DrawLeaderLine *lead = nullptr; + lead = dynamic_cast(myFeat); + + if(lead != nullptr) { + App::DocumentObject* obj = lead->LeaderParent.getValue(); + if(obj != nullptr) { + std::string parentName = obj->getNameInDocument(); + for(std::vector::const_iterator it = qviews.begin(); it != qviews.end(); ++it) { + if(strcmp((*it)->getViewName(), parentName.c_str()) == 0) { + return *it; + } + } + } + } + + //if type is a RichTextAnno we check AnnoParent + TechDraw::DrawRichAnno* anno = dynamic_cast(myFeat); + if (anno != nullptr) { + App::DocumentObject* obj = anno->AnnoParent.getValue(); + if (obj != nullptr) { + std::string parentName = obj->getNameInDocument(); + for(std::vector::const_iterator it = qviews.begin(); it != qviews.end(); ++it) { + if(strcmp((*it)->getViewName(), parentName.c_str()) == 0) { + return *it; + } + } + } + } + // Check if part of view collection for (std::vector::const_iterator it = qviews.begin(); it != qviews.end(); ++it) { QGIViewCollection *grp = nullptr; @@ -601,57 +895,29 @@ QGIView *QGSPage::findParent(QGIView *view) const } } } - - //If type is LeaderLine we check LeaderParent - TechDraw::DrawLeaderLine *lead = nullptr; - lead = dynamic_cast(myFeat); - - if (lead) { - App::DocumentObject *obj = lead->LeaderParent.getValue(); - if (obj) { - std::string parentName = obj->getNameInDocument(); - for (std::vector::const_iterator it = qviews.begin(); it != qviews.end(); ++it) { - if (strcmp((*it)->getViewName(), parentName.c_str()) == 0) { - return *it; - } - } - } - } // Not found a parent return nullptr; } -void QGSPage::setPageTemplate(TechDraw::DrawTemplate *obj) +bool QGSPage::hasQView(App::DocumentObject *obj) { - removeTemplate(); + const std::vector &views = getViews(); + std::vector::const_iterator qview = views.begin(); - if (obj->isDerivedFrom(TechDraw::DrawParametricTemplate::getClassTypeId())) { - pageTemplate = new QGIDrawingTemplate(this); + while(qview != views.end()) { + // Unsure if we can compare pointers so rely on name + if(strcmp((*qview)->getViewName(), obj->getNameInDocument()) == 0) { + return true; + } + qview++; } - else if (obj->isDerivedFrom(TechDraw::DrawSVGTemplate::getClassTypeId())) { - pageTemplate = new QGISVGTemplate(this); - } - pageTemplate->setTemplate(obj); - pageTemplate->updateView(); -} -QGITemplate* QGSPage::getTemplate() const -{ - return pageTemplate; -} - -void QGSPage::removeTemplate() -{ - if(pageTemplate) { - removeItem(pageTemplate); - pageTemplate->deleteLater(); - pageTemplate = nullptr; - } + return false; } void QGSPage::refreshViews() { -// Base::Console().Message("QGVP::refreshViews()\n"); +// Base::Console().Message("QGSP::refreshViews()\n"); QList list = items(); QList qgiv; //find only QGIV's @@ -669,6 +935,156 @@ void QGSPage::refreshViews() } } +void QGSPage::findMissingViews(const std::vector &list, std::vector &missing) +{ + for(std::vector::const_iterator it = list.begin(); it != list.end(); ++it) { + + if(!hasQView(*it)) + missing.push_back(*it); + + if((*it)->getTypeId().isDerivedFrom(TechDraw::DrawViewCollection::getClassTypeId())) { + std::vector missingChildViews; + TechDraw::DrawViewCollection *collection = dynamic_cast(*it); + // Find Child Views recursively + findMissingViews(collection->Views.getValues(), missingChildViews); + + // Append the views to current missing list + for(std::vector::const_iterator it = missingChildViews.begin(); it != missingChildViews.end(); ++it) { + missing.push_back(*it); + } + } + } +} + +//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 QGSPage::fixOrphans(bool force) +{ + Q_UNUSED(force) +// Base::Console().Message("QGSP::fixOrphans()\n"); +// if(!force) { +// m_timer->start(100); +// return; +// } +// m_timer->stop(); + + // get all the DrawViews for this page, including the second level ones + // if we ever have collections of collections, we'll need to revisit this + TechDraw::DrawPage* thisPage = m_vpPage->getDrawPage(); + + if(!thisPage->getNameInDocument()) + return; + + std::vector pChildren = thisPage->getAllViews(); + + // if dv doesn't have a graphic, make one + for (auto& dv: pChildren) { + if (dv->isRemoving()) { + continue; + } + QGIView* qv = findQViewForDocObj(dv); + if (qv == nullptr) { + attachView(dv); + } + } + // if qView doesn't have a Feature on this Page, delete it + std::vector qvss = getViews(); + // qvss may contain an item and its child item(s) and to avoid to access a deleted item a QPointer is needed + std::vector> qvs; + std::for_each(qvss.begin(), qvss.end(), [&qvs](QGIView* v) { + qvs.emplace_back(v); + }); + App::Document* doc = m_vpPage->getDrawPage()->getDocument(); + for (auto& qv: qvs) { + if (!qv) + continue; // already deleted? + App::DocumentObject* obj = doc->getObject(qv->getViewName()); + if (obj == nullptr) { + //no DrawView anywhere in Document + removeQView(qv); + } else { + //DrawView exists in Document. Does it belong to this DrawPage? + int numParentPages = qv->getViewObject()->countParentPages(); + if (numParentPages == 0) { + //DrawView does not belong to any DrawPage + //remove QGItem from QGScene + 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 + removeQView(qv); + } + } else if (numParentPages > 1) { + //DrawView belongs to multiple DrawPages + //check if this MDIViewPage corresponds to any parent DrawPage + //if not, delete the QGItem + 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 correspond to this Page + removeQView(qv); + } + } + } + } + + setRichAnnoGroups(); //hack to fix QGIRA parentage; +} + +bool QGSPage::orphanExists(const char *viewName, const std::vector &list) +{ + for(std::vector::const_iterator it = list.begin(); it != list.end(); ++it) { + + //Check child objects too recursively + if((*it)->isDerivedFrom(TechDraw::DrawViewCollection::getClassTypeId())) { + TechDraw::DrawViewCollection *collection = dynamic_cast(*it); + if(orphanExists(viewName, collection->Views.getValues())) + return true; + } + + // Unsure if we can compare pointers so rely on name + if(strcmp(viewName, (*it)->getNameInDocument()) == 0) { + return true; + } + } + return false; +} + +//NOTE: this doesn't add missing views. see fixOrphans() +void QGSPage::redrawAllViews() +{ +// Base::Console().Message("QGSP::redrawAllViews() - views: %d\n", getViews().size()); + const std::vector &upviews = getViews(); + for(std::vector::const_iterator it = upviews.begin(); it != upviews.end(); ++it) { + (*it)->updateView(true); + } +} + +//NOTE: this doesn't add missing views. see fixOrphans() +void QGSPage::redraw1View(TechDraw::DrawView* dv) +{ + std::string dvName = dv->getNameInDocument(); + const std::vector &upviews = getViews(); + for(std::vector::const_iterator it = upviews.begin(); it != upviews.end(); ++it) { + std::string qgivName = (*it)->getViewName(); + if(dvName == qgivName) { + (*it)->updateView(true); + } + } +} + void QGSPage::setExporting(bool enable) { QList sceneItems = items(); @@ -875,7 +1291,7 @@ void QGSPage::postProcessXml(QTemporaryFile& temporaryFile, QString fileName, QS // Time to save our product QFile outFile( fileName ); if( !outFile.open( QIODevice::WriteOnly | QIODevice::Text ) ) { - Base::Console().Message("QGVP::ppxml - failed to open file for writing: %s\n",qPrintable(fileName) ); + Base::Console().Error("QGSP::ppxml - failed to open file for writing: %s\n",qPrintable(fileName) ); } QTextStream stream( &outFile ); diff --git a/src/Mod/TechDraw/Gui/QGSPage.h b/src/Mod/TechDraw/Gui/QGSPage.h index 7c7dece416..a67bcfac18 100644 --- a/src/Mod/TechDraw/Gui/QGSPage.h +++ b/src/Mod/TechDraw/Gui/QGSPage.h @@ -26,6 +26,7 @@ #include #include +#include class QTemporaryFile; class QLabel; @@ -72,6 +73,8 @@ public: QGSPage(ViewProviderPage *vp, QWidget *parent = nullptr); ~QGSPage() override; + bool addView(const App::DocumentObject *obj); + bool attachView(App::DocumentObject *obj); QGIView * addViewDimension(TechDraw::DrawViewDimension *dim); QGIView * addViewBalloon(TechDraw::DrawViewBalloon *balloon); QGIView * addProjectionGroup(TechDraw::DrawProjGroup *view); @@ -88,15 +91,24 @@ public: QGIView * addRichAnno(TechDraw::DrawRichAnno* anno); QGIView * addWeldSymbol(TechDraw::DrawWeldSymbol* weld); + void addChildrenToPage(void); + void fixOrphans(bool force = false); + + void redrawAllViews(void); + void redraw1View(TechDraw::DrawView* dv); + QGIView* findQViewForDocObj(App::DocumentObject *obj) const; QGIView* getQGIVByName(std::string name); QGIView* findParent(QGIView *) const; + void findMissingViews( const std::vector &list, std::vector &missing); + bool hasQView(App::DocumentObject *obj); void addBalloonToParent(QGIViewBalloon* balloon, QGIView* parent); void createBalloon(QPointF origin, TechDraw::DrawViewPart *parent); void addDimToParent(QGIViewDimension* dim, QGIView* parent); void addLeaderToParent(QGILeaderLine* lead, QGIView* parent); + void addAnnoToParent(QGIRichAnno* anno, QGIView* parent); std::vector getViews() const; @@ -106,9 +118,12 @@ public: void removeQViewFromScene(QGIView *view); void setPageTemplate(TechDraw::DrawTemplate *pageTemplate); - QGITemplate * getTemplate() const; void removeTemplate(); + void matchSceneRectToTemplate(void); + void attachTemplate(TechDraw::DrawTemplate *obj); + void updateTemplate(bool force = false); + QPointF getTemplateCenter(); TechDraw::DrawPage * getDrawPage(); @@ -119,6 +134,11 @@ public: void saveSvg(QString filename); void postProcessXml(QTemporaryFile& tempFile, QString filename, QString pagename); + void setDimensionGroups(void); + void setBalloonGroups(void); + void setLeaderGroups(void); + void setRichAnnoGroups(void); + public Q_SLOTS: protected: @@ -129,9 +149,15 @@ protected: QGITemplate *pageTemplate; + bool orphanExists(const char *viewName, const std::vector &list); + private: ViewProviderPage *m_vpPage; + QPageLayout::Orientation m_orientation; + QPageSize::PageSizeId m_paperSize; + qreal pagewidth, pageheight; + }; } // namespace diff --git a/src/Mod/TechDraw/Gui/QGVPage.cpp b/src/Mod/TechDraw/Gui/QGVPage.cpp index 3af7be5d29..815939cf90 100644 --- a/src/Mod/TechDraw/Gui/QGVPage.cpp +++ b/src/Mod/TechDraw/Gui/QGVPage.cpp @@ -90,6 +90,7 @@ #include "Rez.h" #include "PreferencesGui.h" +#include "DrawGuiUtil.h" #include "QGIDrawingTemplate.h" #include "QGITemplate.h" #include "QGISVGTemplate.h" @@ -242,7 +243,6 @@ QGVPage::QGVPage(ViewProviderPage *vp, QGSPage* s, QWidget *parent) m_vpPage = vp; const char* name = vp->getDrawPage()->getNameInDocument(); setObjectName(QString::fromLocal8Bit(name)); - m_vpPage->setGraphicsView(this); setScene(s); setMouseTracking(true); @@ -270,6 +270,7 @@ QGVPage::QGVPage(ViewProviderPage *vp, QGSPage* s, QWidget *parent) // setDragMode(ScrollHandDrag); setDragMode(QGraphicsView::NoDrag); resetCursor(); + setRenderer(Native); setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform); bkgBrush = new QBrush(getBackgroundColor()); @@ -291,6 +292,12 @@ QGVPage::~QGVPage() delete m_navStyle; } +void QGVPage::centerOnPage(void) +{ +// Base::Console().Message("QGVP::centerOnPage()\n"); + centerOn(m_scene->getTemplateCenter()); +} + void QGVPage::initNavigationStyle() { std::string navParm = getNavStyleParameter(); @@ -368,13 +375,14 @@ void QGVPage::drawBackground(QPainter *p, const QRectF &) } if (!m_vpPage->getDrawPage()) { - //Base::Console().Log("TROUBLE - QGVP::drawBackground - no Page Object!\n"); +// Base::Console().Message("QGVP::drawBackground - no Page Feature!\n"); return; } p->save(); p->resetTransform(); + resetCachedContent(); p->setBrush(*bkgBrush); p->drawRect(viewport()->rect().adjusted(-2,-2,2,2)); //just bigger than viewport to prevent artifacts @@ -397,11 +405,11 @@ void QGVPage::drawBackground(QPainter *p, const QRectF &) p->setBrush(pageBrush); p->drawRect(poly.boundingRect()); + resetCachedContent(); p->restore(); } - void QGVPage::setRenderer(RendererType type) { m_renderer = type; diff --git a/src/Mod/TechDraw/Gui/QGVPage.h b/src/Mod/TechDraw/Gui/QGVPage.h index 8692355b93..d7672f7a51 100644 --- a/src/Mod/TechDraw/Gui/QGVPage.h +++ b/src/Mod/TechDraw/Gui/QGVPage.h @@ -112,6 +112,8 @@ public: void pseudoContextEvent(); + void centerOnPage(void); + public Q_SLOTS: void setHighQualityAntialiasing(bool highQualityAntialiasing); diff --git a/src/Mod/TechDraw/Gui/TaskCosVertex.cpp b/src/Mod/TechDraw/Gui/TaskCosVertex.cpp index ebf5fccfd2..761093ee6c 100644 --- a/src/Mod/TechDraw/Gui/TaskCosVertex.cpp +++ b/src/Mod/TechDraw/Gui/TaskCosVertex.cpp @@ -74,9 +74,6 @@ TaskCosVertex::TaskCosVertex(TechDraw::DrawViewPart* baseFeat, ui(new Ui_TaskCosVertex), blockUpdate(false), m_tracker(nullptr), - m_mdi(nullptr), - m_scene(nullptr), - m_view(nullptr), m_baseFeat(baseFeat), m_basePage(page), m_qgParent(nullptr), @@ -94,10 +91,7 @@ TaskCosVertex::TaskCosVertex(TechDraw::DrawViewPart* baseFeat, Gui::Document* activeGui = Gui::Application::Instance->getDocument(m_basePage->getDocument()); Gui::ViewProvider* vp = activeGui->getViewProvider(m_basePage); - ViewProviderPage* vpp = static_cast(vp); - m_mdi = vpp->getMDIViewPage(); - m_scene = m_mdi->getQGSPage(); - m_view = m_mdi->getQGVPage(); + m_vpp = static_cast(vp); setUiPrimary(); @@ -186,8 +180,8 @@ void TaskCosVertex::onTrackerClicked(bool b) } m_inProgressLock = true; - m_saveContextPolicy = m_mdi->contextMenuPolicy(); - m_mdi->setContextMenuPolicy(Qt::PreventContextMenu); + m_saveContextPolicy = m_vpp->getMDIViewPage()->contextMenuPolicy(); + m_vpp->getMDIViewPage()->setContextMenuPolicy(Qt::PreventContextMenu); m_trackerMode = QGTracker::TrackerMode::Point; setEditCursor(Qt::CrossCursor); startTracker(); @@ -209,7 +203,7 @@ void TaskCosVertex::startTracker() } if (!m_tracker) { - m_tracker = new QGTracker(m_scene, m_trackerMode); + m_tracker = new QGTracker(m_vpp->getQGSPage(), m_trackerMode); QObject::connect( m_tracker, &QGTracker::drawingFinished, this, &TaskCosVertex::onTrackerFinished @@ -268,7 +262,7 @@ void TaskCosVertex::onTrackerFinished(std::vector pts, QGIView* qgParen ui->pbTracker->setEnabled(true); enableTaskButtons(true); setEditCursor(Qt::ArrowCursor); - m_mdi->setContextMenuPolicy(m_saveContextPolicy); + m_vpp->getMDIViewPage()->setContextMenuPolicy(m_saveContextPolicy); } @@ -276,7 +270,7 @@ void TaskCosVertex::removeTracker() { // Base::Console().Message("TCV::removeTracker()\n"); if (m_tracker && m_tracker->scene()) { - m_scene->removeItem(m_tracker); + m_vpp->getQGSPage()->removeItem(m_tracker); delete m_tracker; m_tracker = nullptr; } @@ -285,7 +279,7 @@ void TaskCosVertex::removeTracker() void TaskCosVertex::setEditCursor(QCursor c) { if (m_baseFeat) { - QGIView* qgivBase = m_scene->findQViewForDocObj(m_baseFeat); + QGIView* qgivBase = m_vpp->getQGSPage()->findQViewForDocObj(m_baseFeat); qgivBase->setCursor(c); } } @@ -329,7 +323,7 @@ bool TaskCosVertex::accept() m_baseFeat->recomputeFeature(); m_baseFeat->requestPaint(); - m_mdi->setContextMenuPolicy(m_saveContextPolicy); + m_vpp->getMDIViewPage()->setContextMenuPolicy(m_saveContextPolicy); m_trackerMode = QGTracker::TrackerMode::None; Gui::Command::doCommand(Gui::Command::Gui, "Gui.ActiveDocument.resetEdit()"); @@ -344,8 +338,8 @@ bool TaskCosVertex::reject() removeTracker(); m_trackerMode = QGTracker::TrackerMode::None; - if (m_mdi) { - m_mdi->setContextMenuPolicy(m_saveContextPolicy); + if (m_vpp->getMDIViewPage()) { + m_vpp->getMDIViewPage()->setContextMenuPolicy(m_saveContextPolicy); } //make sure any dangling objects are cleaned up diff --git a/src/Mod/TechDraw/Gui/TaskCosVertex.h b/src/Mod/TechDraw/Gui/TaskCosVertex.h index ba34236639..c176e5dcb1 100644 --- a/src/Mod/TechDraw/Gui/TaskCosVertex.h +++ b/src/Mod/TechDraw/Gui/TaskCosVertex.h @@ -46,14 +46,13 @@ class DrawCosVertex; namespace TechDrawGui { class QGSPage; -class QGVPage; class QGIView; class QGIPrimPath; -class MDIViewPage; class QGTracker; class QGEPath; class QGMText; class QGICosVertex; +class ViewProviderPage; class ViewProviderLeader; class Ui_TaskCosVertex; @@ -99,9 +98,6 @@ private: QGTracker* m_tracker; - MDIViewPage* m_mdi; - QGSPage* m_scene; - QGVPage* m_view; TechDraw::DrawViewPart* m_baseFeat; TechDraw::DrawPage* m_basePage; QGIView* m_qgParent; @@ -117,6 +113,8 @@ private: int m_pbTrackerState; QPointF m_savePoint; bool pointFromTracker; + + ViewProviderPage* m_vpp; }; class TaskDlgCosVertex : public Gui::TaskView::TaskDialog diff --git a/src/Mod/TechDraw/Gui/TaskDetail.cpp b/src/Mod/TechDraw/Gui/TaskDetail.cpp index 42f4ce7f59..101a7b06ee 100644 --- a/src/Mod/TechDraw/Gui/TaskDetail.cpp +++ b/src/Mod/TechDraw/Gui/TaskDetail.cpp @@ -55,7 +55,6 @@ #include #include "QGSPage.h" -#include "QGVPage.h" #include "QGIView.h" #include "QGIPrimPath.h" #include "QGIGhostHighlight.h" @@ -78,9 +77,6 @@ TaskDetail::TaskDetail(TechDraw::DrawViewPart* baseFeat): ui(new Ui_TaskDetail), blockUpdate(false), m_ghost(nullptr), - m_mdi(nullptr), - m_scene(nullptr), - m_view(nullptr), m_detailFeat(nullptr), m_baseFeat(baseFeat), m_basePage(nullptr), @@ -115,10 +111,7 @@ TaskDetail::TaskDetail(TechDraw::DrawViewPart* baseFeat): Gui::Document* activeGui = Gui::Application::Instance->getDocument(m_doc); Gui::ViewProvider* vp = activeGui->getViewProvider(m_basePage); - ViewProviderPage* vpp = static_cast(vp); - m_mdi = vpp->getMDIViewPage(); - m_scene = m_mdi->getQGSPage(); - m_view = m_mdi->getQGVPage(); + m_vpp = static_cast(vp); createDetail(); setUiFromFeat(); @@ -143,7 +136,7 @@ TaskDetail::TaskDetail(TechDraw::DrawViewPart* baseFeat): this, SLOT(onReferenceEdit())); m_ghost = new QGIGhostHighlight(); - m_scene->addItem(m_ghost); + m_vpp->getQGSPage()->addItem(m_ghost); m_ghost->hide(); connect(m_ghost, SIGNAL(positionChange(QPointF)), this, SLOT(onHighlightMoved(QPointF))); @@ -154,9 +147,6 @@ TaskDetail::TaskDetail(TechDraw::DrawViewDetail* detailFeat): ui(new Ui_TaskDetail), blockUpdate(false), m_ghost(nullptr), - m_mdi(nullptr), - m_scene(nullptr), - m_view(nullptr), m_detailFeat(detailFeat), m_baseFeat(nullptr), m_basePage(nullptr), @@ -201,10 +191,7 @@ TaskDetail::TaskDetail(TechDraw::DrawViewDetail* detailFeat): Gui::Document* activeGui = Gui::Application::Instance->getDocument(m_basePage->getDocument()); Gui::ViewProvider* vp = activeGui->getViewProvider(m_basePage); - ViewProviderPage* vpp = static_cast(vp); - m_mdi = vpp->getMDIViewPage(); - m_scene = m_mdi->getQGSPage(); - m_view = m_mdi->getQGVPage(); + m_vpp = static_cast(vp); saveDetailState(); setUiFromFeat(); @@ -229,7 +216,7 @@ TaskDetail::TaskDetail(TechDraw::DrawViewDetail* detailFeat): this, SLOT(onReferenceEdit())); m_ghost = new QGIGhostHighlight(); - m_scene->addItem(m_ghost); + m_vpp->getQGSPage()->addItem(m_ghost); m_ghost->hide(); connect(m_ghost, SIGNAL(positionChange(QPointF)), this, SLOT(onHighlightMoved(QPointF))); @@ -408,7 +395,7 @@ void TaskDetail::editByHighlight() } double scale = getBaseFeat()->getScale(); - m_scene->clearSelection(); + m_vpp->getQGSPage()->clearSelection(); m_ghost->setSelected(true); m_ghost->setRadius(ui->qsbRadius->rawValue() * scale); m_ghost->setPos(getAnchorScene()); diff --git a/src/Mod/TechDraw/Gui/TaskDetail.h b/src/Mod/TechDraw/Gui/TaskDetail.h index dfd26e8fda..863169c653 100644 --- a/src/Mod/TechDraw/Gui/TaskDetail.h +++ b/src/Mod/TechDraw/Gui/TaskDetail.h @@ -45,14 +45,12 @@ class DrawViewPart; namespace TechDrawGui { class QGSPage; -class QGVPage; class QGIView; class QGIPrimPath; -class MDIViewPage; class QGEPath; class QGIDetail; class QGIGhostHighlight; -class ViewProviderLeader; +class ViewProviderPage; class Ui_TaskDetail; class TaskDetail : public QWidget @@ -109,9 +107,7 @@ private: QGIGhostHighlight* m_ghost; - MDIViewPage* m_mdi; - QGSPage* m_scene; - QGVPage* m_view; + ViewProviderPage* m_vpp; TechDraw::DrawViewDetail* m_detailFeat; TechDraw::DrawViewPart* m_baseFeat; TechDraw::DrawPage* m_basePage; diff --git a/src/Mod/TechDraw/Gui/TaskLeaderLine.cpp b/src/Mod/TechDraw/Gui/TaskLeaderLine.cpp index 4b52b76e8f..f10f4113c4 100644 --- a/src/Mod/TechDraw/Gui/TaskLeaderLine.cpp +++ b/src/Mod/TechDraw/Gui/TaskLeaderLine.cpp @@ -77,9 +77,6 @@ TaskLeaderLine::TaskLeaderLine(TechDrawGui::ViewProviderLeader* leadVP) : ui(new Ui_TaskLeaderLine), blockUpdate(false), m_tracker(nullptr), - m_mdi(nullptr), - m_scene(nullptr), - m_view(nullptr), m_lineVP(leadVP), m_baseFeat(nullptr), m_basePage(nullptr), @@ -95,8 +92,7 @@ TaskLeaderLine::TaskLeaderLine(TechDrawGui::ViewProviderLeader* leadVP) : m_btnCancel(nullptr), m_pbTrackerState(TRACKEREDIT), m_saveX(0.0), - m_saveY(0.0), - m_haveMdi(false) + m_saveY(0.0) { //existence of leadVP is guaranteed by caller being ViewProviderLeaderLine.setEdit @@ -116,19 +112,11 @@ TaskLeaderLine::TaskLeaderLine(TechDrawGui::ViewProviderLeader* leadVP) : Gui::Document* activeGui = Gui::Application::Instance->getDocument(m_basePage->getDocument()); Gui::ViewProvider* vp = activeGui->getViewProvider(m_basePage); - ViewProviderPage* vpp = static_cast(vp); + m_vpp = static_cast(vp); m_qgParent = nullptr; - m_haveMdi = true; - m_mdi = vpp->getMDIViewPage(); - if (m_mdi) { - m_scene = m_mdi->getQGSPage(); - m_view = m_mdi->getQGVPage(); - if (m_baseFeat) { - m_qgParent = m_scene->findQViewForDocObj(m_baseFeat); - } - } else { - m_haveMdi = false; + if (m_baseFeat) { + m_qgParent = m_vpp->getQGSPage()->findQViewForDocObj(m_baseFeat); } //TODO: when/if leaders are allowed to be parented to Page, check for m_baseFeat will be removed @@ -154,8 +142,8 @@ TaskLeaderLine::TaskLeaderLine(TechDrawGui::ViewProviderLeader* leadVP) : saveState(); m_trackerMode = QGTracker::TrackerMode::Line; - if (m_haveMdi) { - m_saveContextPolicy = m_mdi->contextMenuPolicy(); + if (m_vpp->getMDIViewPage() != nullptr) { + m_saveContextPolicy = m_vpp->getMDIViewPage()->contextMenuPolicy(); } } @@ -165,9 +153,6 @@ TaskLeaderLine::TaskLeaderLine(TechDraw::DrawView* baseFeat, ui(new Ui_TaskLeaderLine), blockUpdate(false), m_tracker(nullptr), - m_mdi(nullptr), - m_scene(nullptr), - m_view(nullptr), m_lineVP(nullptr), m_baseFeat(baseFeat), m_basePage(page), @@ -183,27 +168,17 @@ TaskLeaderLine::TaskLeaderLine(TechDraw::DrawView* baseFeat, m_btnCancel(nullptr), m_pbTrackerState(TRACKERPICK), m_saveX(0.0), - m_saveY(0.0), - m_haveMdi(false) + m_saveY(0.0) { //existence of basePage and baseFeat is checked in CmdTechDrawLeaderLine (CommandAnnotate.cpp) Gui::Document* activeGui = Gui::Application::Instance->getDocument(m_basePage->getDocument()); Gui::ViewProvider* vp = activeGui->getViewProvider(m_basePage); - ViewProviderPage* vpp = static_cast(vp); -// vpp->show(); + m_vpp = static_cast(vp); m_qgParent = nullptr; - m_haveMdi = true; - m_mdi = vpp->getMDIViewPage(); - if (m_mdi) { - m_scene = m_mdi->getQGSPage(); - m_view = m_mdi->getQGVPage(); - if (baseFeat) { - m_qgParent = m_scene->findQViewForDocObj(baseFeat); - } - } else { - m_haveMdi = false; + if (m_baseFeat) { + m_qgParent = m_vpp->getQGSPage()->findQViewForDocObj(baseFeat); } ui->setupUi(this); @@ -217,8 +192,8 @@ TaskLeaderLine::TaskLeaderLine(TechDraw::DrawView* baseFeat, ui->pbCancelEdit->setEnabled(false); m_trackerMode = QGTracker::TrackerMode::Line; - if (m_haveMdi) { - m_saveContextPolicy = m_mdi->contextMenuPolicy(); + if (m_vpp->getMDIViewPage() != nullptr) { + m_saveContextPolicy = m_vpp->getMDIViewPage()->contextMenuPolicy(); } } @@ -271,7 +246,7 @@ void TaskLeaderLine::setUiPrimary() } ui->pbTracker->setText(tr("Pick points")); - if (m_haveMdi) { + if (m_vpp->getMDIViewPage() != nullptr) { ui->pbTracker->setEnabled(true); ui->pbCancelEdit->setEnabled(true); } else { @@ -320,7 +295,7 @@ void TaskLeaderLine::setUiEdit() connect(ui->cboxEndSym, SIGNAL(currentIndexChanged(int)), this, SLOT(onEndSymbolChanged())); ui->pbTracker->setText(tr("Edit points")); - if (m_haveMdi) { + if (m_vpp->getMDIViewPage() != nullptr) { ui->pbTracker->setEnabled(true); ui->pbCancelEdit->setEnabled(true); } else { @@ -504,7 +479,7 @@ void TaskLeaderLine::onTrackerClicked(bool b) Q_UNUSED(b); // Base::Console().Message("TTL::onTrackerClicked() m_pbTrackerState: %d\n", // m_pbTrackerState); - if (!m_haveMdi) { + if (m_vpp->getMDIViewPage() == nullptr) { Base::Console().Message("TLL::onTrackerClicked - no Mdi, no Tracker!\n"); return; } @@ -538,8 +513,8 @@ void TaskLeaderLine::onTrackerClicked(bool b) //TRACKERPICK or TRACKEREDIT if (getCreateMode()) { m_inProgressLock = true; - m_saveContextPolicy = m_mdi->contextMenuPolicy(); - m_mdi->setContextMenuPolicy(Qt::PreventContextMenu); + m_saveContextPolicy = m_vpp->getMDIViewPage()->contextMenuPolicy(); + m_vpp->getMDIViewPage()->setContextMenuPolicy(Qt::PreventContextMenu); m_trackerMode = QGTracker::TrackerMode::Line; setEditCursor(Qt::CrossCursor); startTracker(); @@ -556,10 +531,9 @@ void TaskLeaderLine::onTrackerClicked(bool b) m_trackerPoints = m_lineFeat->WayPoints.getValues(); if (!m_trackerPoints.empty()) { //regular edit session m_inProgressLock = true; - m_saveContextPolicy = m_mdi->contextMenuPolicy(); - m_mdi->setContextMenuPolicy(Qt::PreventContextMenu); - QGSPage* qgsp = m_mdi->getQGSPage(); - QGIView* qgiv = qgsp->findQViewForDocObj(m_lineFeat); + m_saveContextPolicy = m_vpp->getMDIViewPage()->contextMenuPolicy(); + m_vpp->getMDIViewPage()->setContextMenuPolicy(Qt::PreventContextMenu); + QGIView* qgiv = m_vpp->getQGSPage()->findQViewForDocObj(m_lineFeat); QGILeaderLine* qgLead = dynamic_cast(qgiv); if (!qgLead) { @@ -582,8 +556,8 @@ void TaskLeaderLine::onTrackerClicked(bool b) } } else { // need to recreate leaderline m_inProgressLock = true; - m_saveContextPolicy = m_mdi->contextMenuPolicy(); - m_mdi->setContextMenuPolicy(Qt::PreventContextMenu); + m_saveContextPolicy = m_vpp->getMDIViewPage()->contextMenuPolicy(); + m_vpp->getMDIViewPage()->setContextMenuPolicy(Qt::PreventContextMenu); m_trackerMode = QGTracker::TrackerMode::Line; setEditCursor(Qt::CrossCursor); startTracker(); @@ -603,7 +577,7 @@ void TaskLeaderLine::onTrackerClicked(bool b) void TaskLeaderLine::startTracker() { // Base::Console().Message("TTL::startTracker()\n"); - if (!m_haveMdi) { + if (m_vpp->getQGSPage() == nullptr) { return; } if (m_trackerMode == QGTracker::TrackerMode::None) { @@ -611,7 +585,7 @@ void TaskLeaderLine::startTracker() } if (!m_tracker) { - m_tracker = new QGTracker(m_scene, m_trackerMode); + m_tracker = new QGTracker(m_vpp->getQGSPage(), m_trackerMode); QObject::connect( m_tracker, &QGTracker::drawingFinished, this , &TaskLeaderLine::onTrackerFinished @@ -663,11 +637,11 @@ void TaskLeaderLine::onTrackerFinished(std::vector pts, QGIView* qgPare void TaskLeaderLine::removeTracker() { // Base::Console().Message("TTL::removeTracker()\n"); - if (!m_haveMdi) { + if (m_vpp->getQGSPage() == nullptr) { return; } if (m_tracker && m_tracker->scene()) { - m_scene->removeItem(m_tracker); + m_vpp->getQGSPage()->removeItem(m_tracker); delete m_tracker; m_tracker = nullptr; } @@ -707,10 +681,13 @@ QGIView* TaskLeaderLine::findParentQGIV() void TaskLeaderLine::setEditCursor(QCursor c) { - if (!m_haveMdi || !m_baseFeat) + if (!m_vpp->getQGSPage()) { return; - QGIView* qgivBase = m_scene->findQViewForDocObj(m_baseFeat); - qgivBase->setCursor(c); + } + if (m_baseFeat) { + QGIView* qgivBase = m_vpp->getQGSPage()->findQViewForDocObj(m_baseFeat); + qgivBase->setCursor(c); + } } //from 1:1 scale scene QPointF to zero origin Vector3d points @@ -814,8 +791,8 @@ bool TaskLeaderLine::accept() Gui::Command::doCommand(Gui::Command::Gui,"Gui.ActiveDocument.resetEdit()"); - if (m_haveMdi) { - m_mdi->setContextMenuPolicy(m_saveContextPolicy); + if (m_vpp->getMDIViewPage() != nullptr) { + m_vpp->getMDIViewPage()->setContextMenuPolicy(m_saveContextPolicy); } return true; } @@ -848,8 +825,8 @@ bool TaskLeaderLine::reject() Gui::Command::doCommand(Gui::Command::Gui,"App.activeDocument().recompute()"); Gui::Command::doCommand(Gui::Command::Gui,"Gui.ActiveDocument.resetEdit()"); - if (m_mdi) { - m_mdi->setContextMenuPolicy(m_saveContextPolicy); + if (m_vpp->getMDIViewPage()) { + m_vpp->getMDIViewPage()->setContextMenuPolicy(m_saveContextPolicy); } return false; diff --git a/src/Mod/TechDraw/Gui/TaskLeaderLine.h b/src/Mod/TechDraw/Gui/TaskLeaderLine.h index 3b7b8cdb90..14d9d0027a 100644 --- a/src/Mod/TechDraw/Gui/TaskLeaderLine.h +++ b/src/Mod/TechDraw/Gui/TaskLeaderLine.h @@ -46,15 +46,13 @@ class DrawLeaderLine; namespace TechDrawGui { -class QGSPage; -class QGVPage; class QGIView; class QGIPrimPath; -class MDIViewPage; class QGTracker; class QGEPath; class QGMText; class QGILeaderLine; +class ViewProviderPage; class ViewProviderLeader; class Ui_TaskLeaderLine; @@ -128,9 +126,7 @@ private: QGTracker* m_tracker; - MDIViewPage* m_mdi; - QGSPage* m_scene; - QGVPage* m_view; + ViewProviderPage* m_vpp; ViewProviderLeader* m_lineVP; TechDraw::DrawView* m_baseFeat; TechDraw::DrawPage* m_basePage; diff --git a/src/Mod/TechDraw/Gui/TaskRichAnno.cpp b/src/Mod/TechDraw/Gui/TaskRichAnno.cpp index a752a19fe7..eac5e0194b 100644 --- a/src/Mod/TechDraw/Gui/TaskRichAnno.cpp +++ b/src/Mod/TechDraw/Gui/TaskRichAnno.cpp @@ -77,8 +77,6 @@ using namespace TechDrawGui; TaskRichAnno::TaskRichAnno(TechDrawGui::ViewProviderRichAnno* annoVP) : ui(new Ui_TaskRichAnno), blockUpdate(false), - m_mdi(nullptr), - m_view(nullptr), m_annoVP(annoVP), m_baseFeat(nullptr), m_basePage(nullptr), @@ -92,8 +90,7 @@ TaskRichAnno::TaskRichAnno(TechDrawGui::ViewProviderRichAnno* annoVP) : m_btnOK(nullptr), m_btnCancel(nullptr), m_textDialog(nullptr), - m_rte(nullptr), - m_haveMdi(false) + m_rte(nullptr) { //existence of annoVP is guaranteed by caller being ViewProviderRichAnno.setEdit @@ -115,21 +112,13 @@ TaskRichAnno::TaskRichAnno(TechDrawGui::ViewProviderRichAnno* annoVP) : Gui::Document* activeGui = Gui::Application::Instance->getDocument(m_basePage->getDocument()); Gui::ViewProvider* vp = activeGui->getViewProvider(m_basePage); - ViewProviderPage* dvp = static_cast(vp); + m_vpp = static_cast(vp); - m_mdi = dvp->getMDIViewPage(); m_qgParent = nullptr; - m_haveMdi = true; - if (m_mdi) { - m_scene = m_mdi->getQGSPage(); - if (m_baseFeat) { - m_qgParent = m_scene->findQViewForDocObj(m_baseFeat); - } - } else { - m_haveMdi = false; + if (m_baseFeat) { + m_qgParent = m_vpp->getGraphicsScene()->findQViewForDocObj(m_baseFeat); } - ui->setupUi(this); m_title = QObject::tr("Rich text editor"); @@ -148,8 +137,6 @@ TaskRichAnno::TaskRichAnno(TechDraw::DrawView* baseFeat, TechDraw::DrawPage* page) : ui(new Ui_TaskRichAnno), blockUpdate(false), - m_mdi(nullptr), - m_view(nullptr), m_annoVP(nullptr), m_baseFeat(baseFeat), m_basePage(page), @@ -163,24 +150,18 @@ TaskRichAnno::TaskRichAnno(TechDraw::DrawView* baseFeat, m_btnOK(nullptr), m_btnCancel(nullptr), m_textDialog(nullptr), - m_rte(nullptr), - m_haveMdi(false) + m_rte(nullptr) { //existence of baseFeat and page guaranteed by CmdTechDrawRichTextAnnotation (CommandAnnotate.cpp) - Gui::Document* activeGui = Gui::Application::Instance->getDocument(m_basePage->getDocument()); Gui::ViewProvider* vp = activeGui->getViewProvider(m_basePage); - ViewProviderPage* dvp = static_cast(vp); + m_vpp = static_cast(vp); m_qgParent = nullptr; - m_haveMdi = true; - m_mdi = dvp->getMDIViewPage(); - if (m_mdi) { - m_scene= m_mdi->getQGSPage(); - m_qgParent = m_scene->findQViewForDocObj(baseFeat); - } else { - m_haveMdi = false; + if (m_vpp->getGraphicsScene()) { + m_qgParent = m_vpp->getGraphicsScene()->findQViewForDocObj(baseFeat); } + ui->setupUi(this); m_title = QObject::tr("Rich text creator"); @@ -295,8 +276,8 @@ void TaskRichAnno::onEditorClicked(bool b) connect(m_rte, SIGNAL(saveText(QString)), this, SLOT(onSaveAndExit(QString))); - connect(m_rte, SIGNAL(editorFinished(void)), - this, SLOT(onEditorExit(void))); + connect(m_rte, SIGNAL(editorFinished()), + this, SLOT(onEditorExit())); m_textDialog->show(); } @@ -354,13 +335,13 @@ void TaskRichAnno::createAnnoFeature() if (obj->isDerivedFrom(TechDraw::DrawRichAnno::getClassTypeId())) { m_annoFeat = static_cast(obj); commonFeatureUpdate(); - if (m_haveMdi) { + if (m_baseFeat != nullptr) { QPointF qTemp = calcTextStartPos(m_annoFeat->getScale()); Base::Vector3d vTemp(qTemp.x(), qTemp.y()); m_annoFeat->X.setValue(Rez::appX(vTemp.x)); m_annoFeat->Y.setValue(Rez::appX(vTemp.y)); } else { - //if we don't have a mdi, we can't calculate start position, so just put it mid-page + //if we don't have a base featrue, we can't calculate start position, so just put it mid-page m_annoFeat->X.setValue(m_basePage->getPageWidth()/2.0); m_annoFeat->Y.setValue(m_basePage->getPageHeight()/2.0); } @@ -378,10 +359,10 @@ void TaskRichAnno::createAnnoFeature() } } - Gui::Command::updateActive(); Gui::Command::commitCommand(); + Gui::Command::updateActive(); - //trigger collectChildren in tree + //trigger claimChildren in tree if (m_baseFeat) { m_baseFeat->touch(); } @@ -405,7 +386,7 @@ void TaskRichAnno::updateAnnoFeature() m_annoVP->LineStyle.setValue(ui->cFrameStyle->currentIndex()); Gui::Command::commitCommand(); - m_annoFeat->requestPaint(); + Gui::Command::updateActive(); } void TaskRichAnno::commonFeatureUpdate() @@ -450,6 +431,7 @@ void TaskRichAnno::removeFeature() //guess at the size of the text block. QPointF TaskRichAnno::calcTextStartPos(double scale) { + Q_UNUSED(scale) // Base::Console().Message("TRA::calcTextStartPos(%.3f)\n", scale); double textWidth = 100.0; double textHeight = 20.0; @@ -485,9 +467,7 @@ QPointF TaskRichAnno::calcTextStartPos(double scale) if (!points.empty()) { QPointF lastPoint(points.back().x, points.back().y); QPointF firstPoint(points.front().x, points.front().y); - QPointF lastOffset = lastPoint; - lastPoint = m_qgParent->mapFromScene(lastPoint) * scale; - firstPoint = m_qgParent->mapFromScene(firstPoint) * scale; + QPointF lastOffset = lastPoint - firstPoint; if (lastPoint.x() < firstPoint.x()) { //last is left of first tPosX = lastOffset.x() - horizGap - textWidth; //left of last @@ -533,7 +513,9 @@ bool TaskRichAnno::accept() } else { updateAnnoFeature(); } -// m_mdi->setContextMenuPolicy(m_saveContextPolicy); + + m_annoFeat->requestPaint(); + Gui::Command::doCommand(Gui::Command::Gui,"Gui.ActiveDocument.resetEdit()"); return true; diff --git a/src/Mod/TechDraw/Gui/TaskRichAnno.h b/src/Mod/TechDraw/Gui/TaskRichAnno.h index b0aa16b0f3..534c37c470 100644 --- a/src/Mod/TechDraw/Gui/TaskRichAnno.h +++ b/src/Mod/TechDraw/Gui/TaskRichAnno.h @@ -41,14 +41,13 @@ class DrawRichAnno; namespace TechDrawGui { -class QGSPage; -class QGVPage; class QGIView; class QGIPrimPath; class MDIViewPage; class QGMText; class QGIRichAnno; class ViewProviderRichAnno; +class ViewProviderPage; class TaskRichAnno : public QWidget { @@ -101,9 +100,7 @@ private: std::unique_ptr ui; bool blockUpdate; - MDIViewPage* m_mdi; - QGSPage* m_scene; - QGVPage* m_view; + ViewProviderPage* m_vpp; ViewProviderRichAnno* m_annoVP; TechDraw::DrawView* m_baseFeat; TechDraw::DrawPage* m_basePage; @@ -126,7 +123,6 @@ private: QDialog* m_textDialog; MRichTextEdit* m_rte; QString m_title; - bool m_haveMdi; }; class TaskDlgRichAnno : public Gui::TaskView::TaskDialog diff --git a/src/Mod/TechDraw/Gui/ViewProviderDrawingView.cpp b/src/Mod/TechDraw/Gui/ViewProviderDrawingView.cpp index 0c91dc4b6a..dcaef06f03 100644 --- a/src/Mod/TechDraw/Gui/ViewProviderDrawingView.cpp +++ b/src/Mod/TechDraw/Gui/ViewProviderDrawingView.cpp @@ -29,6 +29,8 @@ #endif #include +#include +#include #include #include #include @@ -40,7 +42,6 @@ #include "MDIViewPage.h" #include "QGIView.h" #include "QGSPage.h" -#include "QGVPage.h" #include "ViewProviderPage.h" using namespace TechDrawGui; @@ -93,11 +94,7 @@ void ViewProviderDrawingView::onChanged(const App::Property *prop) } if (prop == &Visibility) { -// if(Visibility.getValue()) { -// show(); -// } else { -// hide(); -// } + //handled by ViewProviderDocumentObject } else if (prop == &KeepLabel) { QGIView* qgiv = getQView(); if (qgiv) { @@ -152,20 +149,15 @@ void ViewProviderDrawingView::hide() QGIView* ViewProviderDrawingView::getQView() { QGIView *qView = nullptr; - if (m_docReady){ - TechDraw::DrawView* dv = getViewObject(); - if (dv) { - Gui::Document* guiDoc = Gui::Application::Instance->getDocument(getViewObject()->getDocument()); - if (guiDoc) { - Gui::ViewProvider* vp = guiDoc->getViewProvider(getViewObject()->findParentPage()); - ViewProviderPage* dvp = dynamic_cast(vp); - if (dvp) { - if (dvp->getMDIViewPage()) { - if (dvp->getMDIViewPage()->getQGSPage()) { - qView = dynamic_cast(dvp->getMDIViewPage()-> - getQGSPage()->findQViewForDocObj(getViewObject())); - } - } + TechDraw::DrawView* dv = getViewObject(); + if (dv) { + Gui::Document* guiDoc = Gui::Application::Instance->getDocument(getViewObject()->getDocument()); + if (guiDoc != nullptr) { + Gui::ViewProvider* vp = guiDoc->getViewProvider(getViewObject()->findParentPage()); + ViewProviderPage* vpp = dynamic_cast(vp); + if (vpp) { + if (vpp->getQGSPage()) { + qView = dynamic_cast(vpp->getQGSPage()->findQViewForDocObj(getViewObject())); } } } @@ -215,9 +207,9 @@ MDIViewPage* ViewProviderDrawingView::getMDIViewPage() const Gui::Document* guiDoc = Gui::Application::Instance->getDocument(getViewObject()->getDocument()); if (guiDoc) { Gui::ViewProvider* vp = guiDoc->getViewProvider(getViewObject()->findParentPage()); - ViewProviderPage* dvp = dynamic_cast(vp); - if (dvp) { - result = dvp->getMDIViewPage(); + ViewProviderPage* vpp = dynamic_cast(vp); + if (vpp) { + result = vpp->getMDIViewPage(); } } return result; @@ -231,11 +223,13 @@ Gui::MDIView *ViewProviderDrawingView::getMDIView() const void ViewProviderDrawingView::onGuiRepaint(const TechDraw::DrawView* dv) { // Base::Console().Message("VPDV::onGuiRepaint(%s) - this: %x\n", dv->getNameInDocument(), this); + Gui::Document* guiDoc = Gui::Application::Instance->getDocument(getViewObject()->getDocument()); + if (guiDoc == nullptr) { + return; + } + std::vector pages = getViewObject()->findAllParentPages(); if (pages.size() > 1) { - Gui::Document* guiDoc = Gui::Application::Instance->getDocument(getViewObject()->getDocument()); - if (!guiDoc) - return; for (auto& p : pages) { std::vector views = p->Views.getValues(); for (auto& v: views) { @@ -244,13 +238,10 @@ void ViewProviderDrawingView::onGuiRepaint(const TechDraw::DrawView* dv) Gui::ViewProvider* vp = guiDoc->getViewProvider(p); ViewProviderPage* vpPage = dynamic_cast(vp); if (vpPage) { - if (vpPage->getMDIViewPage()) { - if (vpPage->getMDIViewPage()->getQGSPage()) { - QGIView* qView = dynamic_cast(vpPage->getMDIViewPage()-> - getQGSPage()->findQViewForDocObj(v)); - if (qView) { - qView->updateView(true); - } + if (vpPage->getQGSPage()) { + QGIView* qView = dynamic_cast(vpPage->getQGSPage()->findQViewForDocObj(v)); + if (qView != nullptr) { + qView->updateView(true); } } } @@ -265,14 +256,12 @@ void ViewProviderDrawingView::onGuiRepaint(const TechDraw::DrawView* dv) if (qgiv) { qgiv->updateView(true); } else { //we are not part of the Gui page yet. ask page to add us. - //TODO: this bit causes trouble. Should move QGIV creation to attach? - // is MDIVP/QGVP available at attach time? - // wf: mdivp/qgvp is not necessarily directly available at attach time. It should be available - // via the parent DrawPage since the DP is created before any views. -// Base::Console().Message("VPDV::onGuiRepaint - no QGIV for: %s\n",dv->getNameInDocument()); - MDIViewPage* page = getMDIViewPage(); - if (page) { - page->addView(dv); + Gui::ViewProvider* vp = guiDoc->getViewProvider(getViewObject()->findParentPage()); + ViewProviderPage* vpPage = dynamic_cast(vp); + if (vpPage) { + if (vpPage->getQGSPage()) { + vpPage->getQGSPage()->addView(dv); + } } } } diff --git a/src/Mod/TechDraw/Gui/ViewProviderDrawingView.h b/src/Mod/TechDraw/Gui/ViewProviderDrawingView.h index 89089ebefc..0fb90c8499 100644 --- a/src/Mod/TechDraw/Gui/ViewProviderDrawingView.h +++ b/src/Mod/TechDraw/Gui/ViewProviderDrawingView.h @@ -39,6 +39,7 @@ class DrawView; namespace TechDrawGui { class QGIView; class MDIViewPage; +class ViewProviderPage; class TechDrawGuiExport ViewProviderDrawingView : public Gui::ViewProviderDocumentObject { @@ -66,6 +67,7 @@ public: QGIView* getQView(); MDIViewPage* getMDIViewPage() const; Gui::MDIView *getMDIView() const override; + ViewProviderPage* getViewProviderPage() const; /** @name Restoring view provider from document load */ //@{ diff --git a/src/Mod/TechDraw/Gui/ViewProviderPage.cpp b/src/Mod/TechDraw/Gui/ViewProviderPage.cpp index 0f78c88b39..01bebf09cf 100644 --- a/src/Mod/TechDraw/Gui/ViewProviderPage.cpp +++ b/src/Mod/TechDraw/Gui/ViewProviderPage.cpp @@ -85,14 +85,19 @@ ViewProviderPage::ViewProviderPage() sPixmap = "TechDraw_TreePage"; static const char *group = "Grid"; - ADD_PROPERTY_TYPE(ShowFrames ,(true),group,App::Prop_None,"NonGui! Show or hide View frames and Labels on this Page"); + ADD_PROPERTY_TYPE(ShowFrames ,(true),group,App::Prop_None,"Show or hide View frames and Labels on this Page"); ADD_PROPERTY_TYPE(ShowGrid ,(PreferencesGui::showGrid()),group,App::Prop_None,"Show or hide a grid on this Page"); ADD_PROPERTY_TYPE(GridSpacing, (PreferencesGui::gridSpacing()), group, (App::PropertyType)(App::Prop_None), "Grid line spacing in mm"); ShowFrames.setStatus(App::Property::Hidden,true); - Visibility.setStatus(App::Property::Hidden,true); DisplayMode.setStatus(App::Property::Hidden,true); + + m_graphicsScene = new QGSPage(this); + m_graphicsScene->setItemIndexMethod(QGraphicsScene::NoIndex); //this prevents crash when deleting dims. + //scene(view?) indices of dirty regions gets + //out of sync. missing prepareGeometryChange + //somewhere???? QTBUG-18021??? } ViewProviderPage::~ViewProviderPage() @@ -105,14 +110,14 @@ void ViewProviderPage::attach(App::DocumentObject *pcFeat) ViewProviderDocumentObject::attach(pcFeat); auto bnd = boost::bind(&ViewProviderPage::onGuiRepaint, this, bp::_1); - auto feature = getDrawPage(); + TechDraw::DrawPage* feature = dynamic_cast(pcFeat); if (feature) { connectGuiRepaint = feature->signalGuiPaint.connect(bnd); m_pageName = feature->getNameInDocument(); + m_graphicsScene->setObjectName(QString::fromLocal8Bit(m_pageName.c_str())); } else { Base::Console().Log("VPP::attach has no Feature!\n"); } - } void ViewProviderPage::setDisplayMode(const char* ModeName) @@ -128,38 +133,17 @@ std::vector ViewProviderPage::getDisplayModes() const return StrList; } -void ViewProviderPage::show() +void ViewProviderPage::onChanged(const App::Property *prop) { - Visibility.setValue(true); - showMDIViewPage(); -} - -void ViewProviderPage::hide() -{ - Visibility.setValue(false); - removeMDIView(); - ViewProviderDocumentObject::hide(); -} - -void ViewProviderPage::removeMDIView() -{ - if (m_mdiView.isNull()) { - return; + if (prop == &(ShowGrid)) { + setGrid(); + } else if (prop == &(GridSpacing)) { + setGrid(); + } else if (prop == &Visibility) { + //Visibility changes are handled in VPDO::onChanged -> show() or hide() } - //m_mdiView is a QPointer - // https://forum.freecadweb.org/viewtopic.php?f=3&t=22797&p=182614#p182614 - //Gui::getMainWindow()->activatePreviousWindow(); - QList wList= Gui::getMainWindow()->windows(); - if (!wList.contains(m_mdiView)) - return; - - Gui::getMainWindow()->removeWindow(m_mdiView); - Gui::MDIView* aw = Gui::getMainWindow()->activeWindow(); //WF: this bit should be in the remove window logic, not here. - if (!aw) { - return; - } - aw->showMaximized(); + Gui::ViewProviderDocumentObject::onChanged(prop); } void ViewProviderPage::updateData(const App::Property* prop) @@ -178,10 +162,10 @@ void ViewProviderPage::updateData(const App::Property* prop) signalChangeIcon(); //if the template is changed, rebuild the visual } else if (prop == &(page->Template)) { - if (m_mdiView && - !page->isUnsetting()) { - m_mdiView->matchSceneRectToTemplate(); - m_mdiView->updateTemplate(); + if (!page->isUnsetting()) { + //check if a template has been added to scene first? + m_graphicsScene->matchSceneRectToTemplate(); + m_graphicsScene->updateTemplate(); } } else if (prop == &(page->Label)) { if (m_mdiView && @@ -189,8 +173,8 @@ void ViewProviderPage::updateData(const App::Property* prop) m_mdiView->setTabText(page->Label.getValue()); } } else if (prop == &page->Views) { - if (m_mdiView && !page->isUnsetting()) - m_mdiView->fixOrphans(); + if (!page->isUnsetting()) + m_graphicsScene->fixOrphans(); } Gui::ViewProviderDocumentObject::updateData(prop); @@ -254,7 +238,6 @@ void ViewProviderPage::setupContextMenu(QMenu* menu, QObject* receiver, const ch bool ViewProviderPage::setEdit(int ModNum) { if (ModNum == _SHOWDRAWING) { - Visibility.setValue(true); showMDIViewPage(); // show the drawing return false; //finished editing } else if (ModNum == _TOGGLEUPDATE) { @@ -269,45 +252,116 @@ bool ViewProviderPage::setEdit(int ModNum) } } -bool ViewProviderPage::doubleClicked() +void ViewProviderPage::unsetEdit(int ModNum) +{ + Q_UNUSED(ModNum); + return; +} + +bool ViewProviderPage::doubleClicked(void) { show(); - Gui::getMainWindow()->setActiveWindow(m_mdiView); + if (m_mdiView) { + Gui::getMainWindow()->setActiveWindow(m_mdiView); + } return true; } +void ViewProviderPage::show(void) +{ +// Base::Console().Message("VPP::show()\n"); + showMDIViewPage(); + ViewProviderDocumentObject::show(); +} + +void ViewProviderPage::hide(void) +{ +// Base::Console().Message("VPP::hide()\n"); + if (getMDIView()) { + getMDIView()->hide(); //this doesn't remove the mdiViewPage from the mainWindow + removeMDIView(); + } + ViewProviderDocumentObject::hide(); +} + bool ViewProviderPage::showMDIViewPage() { - if (isRestoring() || !Visibility.getValue()) - return true; - if (m_mdiView.isNull()){ - Gui::Document* doc = Gui::Application::Instance->getDocument - (pcObject->getDocument()); - m_mdiView = new MDIViewPage(this, doc, Gui::getMainWindow()); - QString tabTitle = QString::fromUtf8(getDrawPage()->Label.getValue()); - - m_mdiView->setDocumentObject(getDrawPage()->getNameInDocument()); - m_mdiView->setDocumentName(pcObject->getDocument()->getName()); - - m_mdiView->setWindowTitle(tabTitle + QString::fromLatin1("[*]")); - m_mdiView->setWindowIcon(Gui::BitmapFactory().pixmap("TechDraw_TreePage")); - Gui::getMainWindow()->addWindow(m_mdiView); - m_mdiView->viewAll(); - m_mdiView->showMaximized(); - m_mdiView->addChildrenToPage(); - m_mdiView->fixOrphans(true); + createMDIViewPage(); + m_graphicsScene->addChildrenToPage(); + m_graphicsScene->updateTemplate(true); + m_graphicsScene->redrawAllViews(); + m_graphicsScene->fixOrphans(true); } else { - m_mdiView->updateTemplate(true); - m_mdiView->redrawAllViews(); - m_mdiView->fixOrphans(true); + m_graphicsScene->redrawAllViews(); + m_graphicsScene->fixOrphans(true); } + m_graphicsView->centerOnPage(); + + m_mdiView->viewAll(); + m_mdiView->showMaximized(); + setGrid(); return true; } -std::vector ViewProviderPage::claimChildren() const +void ViewProviderPage::createMDIViewPage() +{ +// Base::Console().Message("VPP::createMDIViewPage()\n"); + Gui::Document* doc = Gui::Application::Instance->getDocument + (pcObject->getDocument()); + m_mdiView = new MDIViewPage(this, doc, Gui::getMainWindow()); + if (m_graphicsView == nullptr) { + m_graphicsView = new QGVPage(this, m_graphicsScene, m_mdiView); + std::string objName = m_pageName + "View"; + m_graphicsView->setObjectName(QString::fromLocal8Bit(objName.c_str())); + } + m_mdiView->setScene(m_graphicsScene, m_graphicsView); + m_graphicsScene->setParent(m_graphicsView); //for QObjectParent. required?? + QString tabTitle = QString::fromUtf8(getDrawPage()->Label.getValue()); + + m_mdiView->setDocumentObject(getDrawPage()->getNameInDocument()); + m_mdiView->setDocumentName(pcObject->getDocument()->getName()); + + m_mdiView->setWindowTitle(tabTitle + QString::fromLatin1("[*]")); + m_mdiView->setWindowIcon(Gui::BitmapFactory().pixmap("TechDraw_TreePage")); + Gui::getMainWindow()->addWindow(m_mdiView); + Gui::getMainWindow()->setActiveWindow(m_mdiView); +} + +//NOTE: removing MDIViewPage (parent) destroys QGVPage which will +//delete QGSPage if still parented to QGVPage +void ViewProviderPage::removeMDIView(void) +{ +// Base::Console().Message("VPP::removeMDIViewPage()\n"); + if (!m_mdiView.isNull()) { //m_mdiView is a QPointer + // https://forum.freecadweb.org/viewtopic.php?f=3&t=22797&p=182614#p182614 + //Gui::getMainWindow()->activatePreviousWindow(); + QList wList= Gui::getMainWindow()->windows(); + bool found = wList.contains(m_mdiView); + if (found) { + m_graphicsScene->setParent(nullptr); + Gui::getMainWindow()->removeWindow(m_mdiView); + m_graphicsView = nullptr; //m_graphicsView has been deleted by m_mdiView + Gui::MDIView* aw = Gui::getMainWindow()->activeWindow(); //WF: this bit should be in the remove window logic, not here. + if (aw != nullptr) { + aw->showMaximized(); + } + } + } +} + +MDIViewPage* ViewProviderPage::getMDIViewPage() const +{ + if (m_mdiView.isNull()) { + Base::Console().Log("VPP::getMDIViewPage has no m_mdiView!\n"); + return nullptr; + } + return m_mdiView; +} + +std::vector ViewProviderPage::claimChildren(void) const { std::vector temp; @@ -362,47 +416,19 @@ std::vector ViewProviderPage::claimChildren() const } } -void ViewProviderPage::unsetEdit(int ModNum) -{ - Q_UNUSED(ModNum); - static_cast(showMDIViewPage()); - return; -} - - -MDIViewPage* ViewProviderPage::getMDIViewPage() const -{ - if (m_mdiView.isNull()) { - Base::Console().Log("INFO - ViewProviderPage::getMDIViewPage has no m_mdiView!\n"); - return nullptr; - } - - return m_mdiView; -} - - -void ViewProviderPage::onChanged(const App::Property *prop) -{ - if (prop == &(ShowGrid) || prop == &(GridSpacing)) { - setGrid(); - } - Gui::ViewProviderDocumentObject::onChanged(prop); -} - void ViewProviderPage::startRestoring() { - m_docReady = false; +// Base::Console().Message("VPP::startRestoring()\n"); + //VPDO::startRestoring hides this VPP Gui::ViewProviderDocumentObject::startRestoring(); } +//note this is called when this ViewProvider has been restored, not +//when the whole document has been restored. void ViewProviderPage::finishRestoring() { - m_docReady = true; - //control drawing opening on restore based on Preference - //mantis #2967 ph2 - don't even show blank page - if (getDrawPage()->canUpdate()) { - static_cast(showMDIViewPage()); - } +// Base::Console().Message("VPP::finishRestoring() - canUpdate: %d viz: %d\n", +// getDrawPage()->canUpdate(), Visibility.getValue()); Gui::ViewProviderDocumentObject::finishRestoring(); } @@ -448,16 +474,6 @@ void ViewProviderPage::setTemplateMarkers(bool state) } } -void ViewProviderPage::setGraphicsView(QGVPage* gv) -{ - m_graphicsView = gv; -} - -void ViewProviderPage::setGraphicsScene(QGSPage* gs) -{ - m_graphicsScene = gs; -} - bool ViewProviderPage::canDelete(App::DocumentObject *obj) const { // deletions from a page don't necessarily destroy anything @@ -472,9 +488,9 @@ bool ViewProviderPage::canDelete(App::DocumentObject *obj) const void ViewProviderPage::onGuiRepaint(const TechDraw::DrawPage* dp) { if (dp == getDrawPage()) { - if (!m_mdiView.isNull() && - !getDrawPage()->isUnsetting()) { - m_mdiView->fixOrphans(); + //this signal is for us + if (!getDrawPage()->isUnsetting()) { + m_graphicsScene->fixOrphans(); } } } @@ -483,7 +499,7 @@ TechDraw::DrawPage* ViewProviderPage::getDrawPage() const { //during redo, pcObject can become invalid, but non-zero?? if (!pcObject) { - Base::Console().Message("TROUBLE - VPPage::getDrawPage - no Page Object!\n"); + Base::Console().Log("VPP::getDrawPage - no Page Object!\n"); return nullptr; } return dynamic_cast(pcObject); @@ -491,7 +507,6 @@ TechDraw::DrawPage* ViewProviderPage::getDrawPage() const Gui::MDIView *ViewProviderPage::getMDIView() const { - const_cast(this)->showMDIViewPage(); return m_mdiView.data(); } diff --git a/src/Mod/TechDraw/Gui/ViewProviderPage.h b/src/Mod/TechDraw/Gui/ViewProviderPage.h index 7e36b632a9..d6e7be2c04 100644 --- a/src/Mod/TechDraw/Gui/ViewProviderPage.h +++ b/src/Mod/TechDraw/Gui/ViewProviderPage.h @@ -28,11 +28,11 @@ #include #include +#include #include #include - namespace TechDraw{ class DrawPage; } @@ -82,6 +82,8 @@ public: bool isRestoring() {return !m_docReady;} TechDraw::DrawPage* getDrawPage() const; + + //slots & connections void onGuiRepaint(const TechDraw::DrawPage* dp); typedef boost::signals2::scoped_connection Connection; Connection connectGuiRepaint; @@ -99,13 +101,17 @@ public: void setTemplateMarkers(bool state); QGVPage *getGraphicsView() { return m_graphicsView; } QGSPage* getGraphicsScene() { return m_graphicsScene; } - void setGraphicsView(QGVPage* gv); - void setGraphicsScene(QGSPage* gs); + bool canDelete(App::DocumentObject* obj) const override; + void setGrid(); + QGSPage* getQGSPage(void) {return m_graphicsScene;} + QGVPage* getQGVPage(void) {return m_graphicsView;} + protected: bool setEdit(int ModNum) override; + void createMDIViewPage(); private: QPointer m_mdiView; diff --git a/src/Mod/TechDraw/Gui/ViewProviderRichAnno.cpp b/src/Mod/TechDraw/Gui/ViewProviderRichAnno.cpp index 28d47d695f..19c223ef7d 100644 --- a/src/Mod/TechDraw/Gui/ViewProviderRichAnno.cpp +++ b/src/Mod/TechDraw/Gui/ViewProviderRichAnno.cpp @@ -33,6 +33,8 @@ #include "PreferencesGui.h" #include "QGIView.h" #include "TaskRichAnno.h" +#include "QGSPage.h" +#include "ViewProviderPage.h" #include "ViewProviderRichAnno.h" using namespace TechDrawGui; @@ -104,6 +106,15 @@ void ViewProviderRichAnno::updateData(const App::Property* p) LineColor.setStatus(App::Property::ReadOnly, true); } } + + if (p == &(getViewObject()->AnnoParent)) { +// Base::Console().Message("VPRA::updateData(AnnoParent) - vpp: %X\n", getViewProviderPage()); + if (getViewProviderPage() && + getViewProviderPage()->getGraphicsScene()) { + getViewProviderPage()->getGraphicsScene()->setRichAnnoGroups(); + } + } + ViewProviderDrawingView::updateData(p); } diff --git a/src/Mod/TechDraw/Gui/ViewProviderRichAnno.h b/src/Mod/TechDraw/Gui/ViewProviderRichAnno.h index c8825b2765..daa578cfdd 100644 --- a/src/Mod/TechDraw/Gui/ViewProviderRichAnno.h +++ b/src/Mod/TechDraw/Gui/ViewProviderRichAnno.h @@ -67,7 +67,9 @@ protected: std::string getDefFont(); double getDefFontSize(); double getDefLineWeight(); - void handleChangedPropertyType(Base::XMLReader &reader, const char *TypeName, App::Property * prop) override; + void handleChangedPropertyType(Base::XMLReader &reader, + const char *TypeName, + App::Property * prop) override; private: static App::PropertyIntegerConstraint::Constraints LineStyleRange; diff --git a/src/Mod/TechDraw/Gui/ViewProviderTemplate.cpp b/src/Mod/TechDraw/Gui/ViewProviderTemplate.cpp index 3b489988ab..c1ccf83115 100644 --- a/src/Mod/TechDraw/Gui/ViewProviderTemplate.cpp +++ b/src/Mod/TechDraw/Gui/ViewProviderTemplate.cpp @@ -72,11 +72,11 @@ void ViewProviderTemplate::updateData(const App::Property* prop) if (getTemplate()->isDerivedFrom(TechDraw::DrawSVGTemplate::getClassTypeId())) { auto t = static_cast(getTemplate()); if (prop == &(t->Template)) { - MDIViewPage* mdi = getMDIViewPage(); - if (mdi) { - mdi->attachTemplate(t); - mdi->viewAll(); - mdi->getViewProviderPage()->setGrid(); + auto page = t->getParentPage(); + Gui::ViewProvider* vp = Gui::Application::Instance->getDocument(t->getDocument())->getViewProvider(page); + TechDrawGui::ViewProviderPage* vpp = dynamic_cast(vp); + if (vpp) { + vpp->getGraphicsScene()->attachTemplate(t); } } } @@ -131,9 +131,11 @@ QGITemplate* ViewProviderTemplate::getQTemplate() { TechDraw::DrawTemplate* dt = getTemplate(); if (dt) { - MDIViewPage* mdi = getMDIViewPage(); - if (mdi) { - return mdi->getQGSPage()->getTemplate(); + auto page = dt->getParentPage(); + Gui::ViewProvider* vp = Gui::Application::Instance->getDocument(dt->getDocument())->getViewProvider(page); + TechDrawGui::ViewProviderPage* vpp = dynamic_cast(vp); + if (vpp != nullptr) { + return vpp->getGraphicsScene()->getTemplate(); } } return nullptr;