diff --git a/src/Gui/Document.cpp b/src/Gui/Document.cpp index d9e9ef5a9a..3e95f5586b 100644 --- a/src/Gui/Document.cpp +++ b/src/Gui/Document.cpp @@ -1956,44 +1956,56 @@ MDIView* Document::getActiveView(void) const return 0; } -MDIView *Document::setActiveView(ViewProviderDocumentObject *vp, Base::Type typeId) { - MDIView *view = 0; - if(!vp) +MDIView *Document::setActiveView(ViewProviderDocumentObject *vp, Base::Type typeId) +{ + MDIView *view = nullptr; + if (!vp) { view = getActiveView(); - else{ + } + else { view = vp->getMDIView(); - if(!view) { + if (!view) { auto obj = vp->getObject(); - if(!obj) + if (!obj) { view = getActiveView(); + } else { auto linked = obj->getLinkedObject(true); - if(linked!=obj) { + if (linked!=obj) { auto vpLinked = dynamic_cast( Application::Instance->getViewProvider(linked)); - if(vpLinked) + if (vpLinked) view = vpLinked->getMDIView(); } - if(!view && typeId.isBad()) - typeId = View3DInventor::getClassTypeId(); + + if (!view && typeId.isBad()) { + MDIView* active = getActiveView(); + if (active && active->containsViewProvider(vp)) + view = active; + else + typeId = View3DInventor::getClassTypeId(); + } } } } - if(!view || (!typeId.isBad() && !view->isDerivedFrom(typeId))) { - view = 0; + + if (!view || (!typeId.isBad() && !view->isDerivedFrom(typeId))) { + view = nullptr; for (auto *v : d->baseViews) { - if(v->isDerivedFrom(MDIView::getClassTypeId()) && - (typeId.isBad() || v->isDerivedFrom(typeId))) - { + if (v->isDerivedFrom(MDIView::getClassTypeId()) && + (typeId.isBad() || v->isDerivedFrom(typeId))) { view = static_cast(v); break; } } } - if(!view && !typeId.isBad()) + + if (!view && !typeId.isBad()) view = createView(typeId); - if(view) + + if (view) getMainWindow()->setActiveWindow(view); + return view; } diff --git a/src/Gui/MDIView.h b/src/Gui/MDIView.h index 063c210353..87c6e835d7 100644 --- a/src/Gui/MDIView.h +++ b/src/Gui/MDIView.h @@ -35,6 +35,7 @@ QT_END_NAMESPACE namespace Gui { class Document; +class ViewProvider; class ViewProviderDocumentObject; /** Base class of all windows belonging to a document. @@ -131,6 +132,16 @@ public: return ActiveObjects.hasObject(o,n,subname); } + /*! + * \brief containsViewProvider + * Checks if the given view provider is part of this view. The default implementation + * returns false. + * \return bool + */ + virtual bool containsViewProvider(const ViewProvider*) const { + return false; + } + public Q_SLOTS: virtual void setOverrideCursor(const QCursor&); virtual void restoreOverrideCursor(); diff --git a/src/Gui/SplitView3DInventor.cpp b/src/Gui/SplitView3DInventor.cpp index c1dc0d8ac6..41633ff0b4 100644 --- a/src/Gui/SplitView3DInventor.cpp +++ b/src/Gui/SplitView3DInventor.cpp @@ -72,6 +72,16 @@ void AbstractSplitView::deleteSelf() MDIView::deleteSelf(); } +bool AbstractSplitView::containsViewProvider(const ViewProvider* vp) const +{ + for (auto it = _viewer.begin(); it != _viewer.end(); ++it) { + if ((*it)->containsViewProvider(vp)) + return true; + } + + return false; +} + void AbstractSplitView::setupSettings() { // attach Parameter Observer diff --git a/src/Gui/SplitView3DInventor.h b/src/Gui/SplitView3DInventor.h index 1605eb559c..2b28a6e035 100644 --- a/src/Gui/SplitView3DInventor.h +++ b/src/Gui/SplitView3DInventor.h @@ -56,6 +56,7 @@ public: View3DInventorViewer *getViewer(unsigned int) const; void setOverrideCursor(const QCursor&); + virtual bool containsViewProvider(const ViewProvider*) const; PyObject *getPyObject(void); void setPyObject(PyObject *); diff --git a/src/Gui/View3DInventor.cpp b/src/Gui/View3DInventor.cpp index bee3e54115..fc6bc76288 100644 --- a/src/Gui/View3DInventor.cpp +++ b/src/Gui/View3DInventor.cpp @@ -84,6 +84,7 @@ #include #include "View3DInventorExamples.h" +#include "ViewProviderDocumentObject.h" #include "SoFCSelectionAction.h" #include "View3DPy.h" #include "SoFCDB.h" @@ -516,6 +517,11 @@ void View3DInventor::print(QPrinter* printer) p.end(); } +bool View3DInventor::containsViewProvider(const ViewProvider* vp) const +{ + return _viewer->containsViewProvider(vp); +} + // ********************************************************************************** bool View3DInventor::onMsg(const char* pMsg, const char** ppReturn) diff --git a/src/Gui/View3DInventor.h b/src/Gui/View3DInventor.h index 24a7d6aa0d..5e22c96192 100644 --- a/src/Gui/View3DInventor.h +++ b/src/Gui/View3DInventor.h @@ -106,7 +106,8 @@ public: void removeOverlayWidget(); View3DInventorViewer *getViewer(void) const {return _viewer;} - + virtual bool containsViewProvider(const ViewProvider*) const; + public Q_SLOTS: /// override the cursor in this view void setOverrideCursor(const QCursor&); diff --git a/src/Gui/View3DInventorViewer.cpp b/src/Gui/View3DInventorViewer.cpp index 37f5998cb5..9e5e745a40 100644 --- a/src/Gui/View3DInventorViewer.cpp +++ b/src/Gui/View3DInventorViewer.cpp @@ -968,6 +968,15 @@ SbBool View3DInventorViewer::hasViewProvider(ViewProvider* pcProvider) const return _ViewProviderSet.find(pcProvider) != _ViewProviderSet.end(); } +SbBool View3DInventorViewer::containsViewProvider(const ViewProvider* vp) const +{ + SoSearchAction sa; + sa.setNode(const_cast(vp)->getRoot()); + sa.setSearchingAll(true); + sa.apply(getSoRenderManager()->getSceneGraph()); + return sa.getPath() != nullptr; +} + /// adds an ViewProvider to the view, e.g. from a feature void View3DInventorViewer::addViewProvider(ViewProvider* pcProvider) { diff --git a/src/Gui/View3DInventorViewer.h b/src/Gui/View3DInventorViewer.h index cd174f6b54..db713a4d72 100644 --- a/src/Gui/View3DInventorViewer.h +++ b/src/Gui/View3DInventorViewer.h @@ -181,7 +181,12 @@ public: /** @name Handling of view providers */ //@{ + /// Checks if the view provider is a top-level object of the scene SbBool hasViewProvider(ViewProvider*) const; + /// Checks if the view provider is part of the scene. + /// In contrast to hasViewProvider() this method also checks if the view + /// provider is a child of another view provider + SbBool containsViewProvider(const ViewProvider*) const; /// adds an ViewProvider to the view, e.g. from a feature void addViewProvider(ViewProvider*); /// remove a ViewProvider