From 775744c1accf230a72b5b6651bec500ef7662c68 Mon Sep 17 00:00:00 2001 From: jriegel Date: Mon, 5 Jan 2015 15:00:10 +0100 Subject: [PATCH] some fixes in Active object handling on Viewer --- src/Gui/ActiveObjectList.h | 16 ++-- src/Gui/MDIView.cpp | 4 + src/Gui/MDIView.h | 4 +- src/Gui/View3DPy.cpp | 15 ++- src/Mod/PartDesign/Gui/Workbench.cpp | 132 +++++++++++++++++---------- 5 files changed, 106 insertions(+), 65 deletions(-) diff --git a/src/Gui/ActiveObjectList.h b/src/Gui/ActiveObjectList.h index c2b40ead4..3174ff147 100644 --- a/src/Gui/ActiveObjectList.h +++ b/src/Gui/ActiveObjectList.h @@ -47,7 +47,12 @@ namespace Gui { public: - template T* getObject(const char*); + template + inline _T getObject(const char* name) + { + std::map::const_iterator pos = _ObjectMap.find(name); + return pos == _ObjectMap.end() ? 0 : dynamic_cast<_T>(pos->second); + } void setObject(App::DocumentObject*, const char*); bool hasObject(const char*); protected: @@ -56,15 +61,6 @@ namespace Gui }; - template - T* Gui::ActiveObjectList::getObject(const char* name) - { - auto pos = _ObjectMap.find(name); - if (pos == _ObjectMap.end()) - return 0; - else - return dynamic_cast(pos->second); - } } //namespace Gui diff --git a/src/Gui/MDIView.cpp b/src/Gui/MDIView.cpp index 56c5dae1f..e29bd3e4a 100644 --- a/src/Gui/MDIView.cpp +++ b/src/Gui/MDIView.cpp @@ -38,6 +38,7 @@ #include "Document.h" #include "Application.h" #include "MainWindow.h" +#include "ActiveObjectList.h" using namespace Gui; @@ -48,6 +49,7 @@ MDIView::MDIView(Gui::Document* pcDocument,QWidget* parent, Qt::WindowFlags wfla : QMainWindow(parent, wflags), BaseView(pcDocument),currentMode(Child), wstate(Qt::WindowNoState) { setAttribute(Qt::WA_DeleteOnClose); + pcActiveObjects = new ActiveObjectList(); } MDIView::~MDIView() @@ -70,6 +72,8 @@ MDIView::~MDIView() } } } + + delete pcActiveObjects; } void MDIView::deleteSelf() diff --git a/src/Gui/MDIView.h b/src/Gui/MDIView.h index e02818129..5fd6abcf2 100644 --- a/src/Gui/MDIView.h +++ b/src/Gui/MDIView.h @@ -26,7 +26,6 @@ #include "View.h" #include -#include "ActiveObjectList.h" QT_BEGIN_NAMESPACE class QPrinter; @@ -35,6 +34,7 @@ QT_END_NAMESPACE namespace Gui { class Document; +class ActiveObjectList; /** Base class of all windows belonging to a document. * There are two ways of belonging to a document: @@ -109,7 +109,7 @@ public: virtual void setCurrentViewMode(ViewMode mode); ViewMode currentViewMode() const { return currentMode; } - ActiveObjectList ActiveObjects; + ActiveObjectList *pcActiveObjects; public Q_SLOTS: virtual void setOverrideCursor(const QCursor&); diff --git a/src/Gui/View3DPy.cpp b/src/Gui/View3DPy.cpp index 6d4a91821..e9fffda82 100644 --- a/src/Gui/View3DPy.cpp +++ b/src/Gui/View3DPy.cpp @@ -52,6 +52,8 @@ #include "View3DInventor.h" #include "View3DInventorViewer.h" #include "View3DViewerPy.h" +#include "ActiveObjectList.h" + #include #include @@ -174,6 +176,7 @@ void View3DInventorPy::init_type() "Remove the DraggerCalback function from the coin node\n" "Possibles types :\n" "'addFinishCallback','addStartCallback','addMotionCallback','addValueChangedCallback'\n"); + add_varargs_method("setActiveObject", &View3DInventorPy::setActiveObject, "setActiveObject(name,object)\nadd or set a new active object"); } View3DInventorPy::View3DInventorPy(View3DInventor *vi) @@ -225,10 +228,12 @@ Py::Object View3DInventorPy::getattr(const char * attr) throw Py::RuntimeError(s_out.str()); } else { - App::DocumentObject *docObj = _view->ActiveObjects.getObject(attr); + // see if a active object has the same name + App::DocumentObject *docObj = _view->pcActiveObjects->getObject(attr); if (docObj){ - return Py::Object(docObj->getPyObject()); + return Py::Object(docObj->getPyObject(),true); }else{ + // else looking for a methode with the name and call it Py::Object obj = Py::PythonExtension::getattr(attr); if (PyCFunction_Check(obj.ptr())) { PyCFunctionObject* op = reinterpret_cast(obj.ptr()); @@ -2169,12 +2174,14 @@ Py::Object View3DInventorPy::removeDraggerCallback(const Py::Tuple& args) Py::Object View3DInventorPy::setActiveObject(const Py::Tuple& args) { - App::DocumentObjectPy* docObject = 0; + PyObject* docObject = 0; char* name; if (!PyArg_ParseTuple(args.ptr(), "sO!", &name, &App::DocumentObjectPy::Type, &docObject)) throw Py::Exception(); if (docObject){ - _view->ActiveObjects.setObject(docObject->getDocumentObjectPtr(), name); + App::DocumentObject* obj = static_cast(docObject)->getDocumentObjectPtr(); + _view->pcActiveObjects->setObject(obj, name); } + return Py::None(); } diff --git a/src/Mod/PartDesign/Gui/Workbench.cpp b/src/Mod/PartDesign/Gui/Workbench.cpp index 73cb88f1e..f5efc1233 100644 --- a/src/Mod/PartDesign/Gui/Workbench.cpp +++ b/src/Mod/PartDesign/Gui/Workbench.cpp @@ -47,6 +47,8 @@ #include #include #include +#include + #include #include @@ -101,7 +103,21 @@ Workbench::~Workbench() PartDesign::Body *Workbench::setUpPart(const App::Part *part) { + // first do the general Part setup Gui::ViewProviderPart::setUpPart(part); + + // check for Bodies + std::vector bodies = part->getObjectsOfType(PartDesign::Body::getClassTypeId()); + assert(bodies.size() == 0); + + std::string PartName = part->getNameInDocument(); + std::string BodyName = part->getDocument()->getUniqueObjectName("MainBody"); + + Gui::Command::addModule(Gui::Command::Doc, "PartDesign"); + Gui::Command::doCommand(Gui::Command::Doc, "App.activeDocument().addObject('PartDesign::Body','%s')", BodyName.c_str()); + Gui::Command::doCommand(Gui::Command::Doc, "App.activeDocument().%s.addObject(App.activeDocument().ActiveObject)", part->getNameInDocument()); + Gui::Command::doCommand(Gui::Command::Gui, "Gui.activeView().setActiveObject('Body',App.activeDocument().%s)", BodyName.c_str()); + return NULL; } @@ -322,72 +338,90 @@ void Workbench::_switchToDocument(const App::Document* doc) if (doc == NULL) return; PartDesign::Body* activeBody = NULL; + App::Part* activePart = NULL; std::vector bodies = doc->getObjectsOfType(PartDesign::Body::getClassTypeId()); - // Is there a body feature in this document? - if (bodies.empty()) + // No tip, so build up structure or migrate + if (!doc->Tip.getValue()) { - _doMigration(doc); + if (doc->countObjects() == 0){ + std::string PartName = doc->getUniqueObjectName("Part"); + //// create a PartDesign Part for now, can be later any kind of Part or an empty one + Gui::Command::addModule(Gui::Command::Doc, "PartDesignGui"); + Gui::Command::doCommand(Gui::Command::Doc, "App.activeDocument().Tip = App.activeDocument().addObject('App::Part','%s')", PartName.c_str()); + Gui::Command::doCommand(Gui::Command::Doc, "PartDesignGui.setUpPart(App.activeDocument().%s)", PartName.c_str()); + Gui::Command::doCommand(Gui::Command::Gui, "Gui.activeView().setActiveObject('Part',App.activeDocument().%s)", PartName.c_str()); + + activeBody = Gui::Application::Instance->activeDocument()->getActiveView()->pcActiveObjects->getObject("Body"); + + // body have to be created + assert(activeBody); + + } else + // empty document with no tip, so do migration + _doMigration(doc); } else { - // Find active body - for (std::vector::const_iterator b = bodies.begin(); b != bodies.end(); b++) { - PartDesign::Body* body = static_cast(*b); - if (body->IsActive.getValue()) { - activeBody = body; - break; - } - } + activeBody = Gui::Application::Instance->activeDocument()->getActiveView()->pcActiveObjects->getObject("Body"); + activePart = Gui::Application::Instance->activeDocument()->getActiveView()->pcActiveObjects->getObject("Part"); - // Do the base planes exist in this document? - bool found = false; - std::vector planes = doc->getObjectsOfType(App::Plane::getClassTypeId()); - for (std::vector::const_iterator p = planes.begin(); p != planes.end(); p++) { - for (unsigned i = 0; i < 3; i++) { - if (strcmp(PartDesignGui::BaseplaneNames[i], (*p)->getNameInDocument()) == 0) { - found = true; - break; - } - } - if (found) break; - } + //// Find active body + //for (std::vector::const_iterator b = bodies.begin(); b != bodies.end(); b++) { + // PartDesign::Body* body = static_cast(*b); + // if (body->IsActive.getValue()) { + // activeBody = body; + // break; + // } + //} - if (!found) { - // Add the planes ... - Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().addObject('App::Plane','%s')", PartDesignGui::BaseplaneNames[0]); - Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().ActiveObject.Label = '%s'", QObject::tr("XY-Plane").toStdString().c_str()); - Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().addObject('App::Plane','%s')", PartDesignGui::BaseplaneNames[1]); - Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().ActiveObject.Placement = App.Placement(App.Vector(),App.Rotation(App.Vector(1,0,0),90))"); - Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().ActiveObject.Label = '%s'", QObject::tr("XZ-Plane").toStdString().c_str()); - Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().addObject('App::Plane','%s')", PartDesignGui::BaseplaneNames[2]); - Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().ActiveObject.Placement = App.Placement(App.Vector(),App.Rotation(App.Vector(0,1,0),90))"); - Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().ActiveObject.Label = '%s'", QObject::tr("YZ-Plane").toStdString().c_str()); - // ... and put them in the 'Origin' group - Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().addObject('App::DocumentObjectGroup','%s')", QObject::tr("Origin").toStdString().c_str()); - for (unsigned i = 0; i < 3; i++) - Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().Origin.addObject(App.activeDocument().getObject('%s'))", PartDesignGui::BaseplaneNames[i]); - // TODO: Fold the group (is that possible through the Python interface?) - } + //// Do the base planes exist in this document? + //bool found = false; + //std::vector planes = doc->getObjectsOfType(App::Plane::getClassTypeId()); + //for (std::vector::const_iterator p = planes.begin(); p != planes.end(); p++) { + // for (unsigned i = 0; i < 3; i++) { + // if (strcmp(PartDesignGui::BaseplaneNames[i], (*p)->getNameInDocument()) == 0) { + // found = true; + // break; + // } + // } + // if (found) break; + //} + + //if (!found) { + // // Add the planes ... + // Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().addObject('App::Plane','%s')", PartDesignGui::BaseplaneNames[0]); + // Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().ActiveObject.Label = '%s'", QObject::tr("XY-Plane").toStdString().c_str()); + // Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().addObject('App::Plane','%s')", PartDesignGui::BaseplaneNames[1]); + // Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().ActiveObject.Placement = App.Placement(App.Vector(),App.Rotation(App.Vector(1,0,0),90))"); + // Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().ActiveObject.Label = '%s'", QObject::tr("XZ-Plane").toStdString().c_str()); + // Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().addObject('App::Plane','%s')", PartDesignGui::BaseplaneNames[2]); + // Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().ActiveObject.Placement = App.Placement(App.Vector(),App.Rotation(App.Vector(0,1,0),90))"); + // Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().ActiveObject.Label = '%s'", QObject::tr("YZ-Plane").toStdString().c_str()); + // // ... and put them in the 'Origin' group + // Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().addObject('App::DocumentObjectGroup','%s')", QObject::tr("Origin").toStdString().c_str()); + // for (unsigned i = 0; i < 3; i++) + // Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().Origin.addObject(App.activeDocument().getObject('%s'))", PartDesignGui::BaseplaneNames[i]); + // // TODO: Fold the group (is that possible through the Python interface?) + //} } - // If there is only one body, make it active - if ((activeBody == NULL) && (bodies.size() == 1)) - activeBody = static_cast(bodies.front()); + //// If there is only one body, make it active + //if ((activeBody == NULL) && (bodies.size() == 1)) + // activeBody = static_cast(bodies.front()); - // add the non PartDesign feature group to the Part - if( groupCreated && doc->Tip.getValue() != NULL) - Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().Tip.addObject(App.activeDocument().NonBodyFeatures)"); + //// add the non PartDesign feature group to the Part + //if( groupCreated && doc->Tip.getValue() != NULL) + // Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().Tip.addObject(App.activeDocument().NonBodyFeatures)"); - if (activeBody != NULL) { - Gui::Command::doCommand(Gui::Command::Doc,"import PartDesignGui"); - Gui::Command::doCommand(Gui::Command::Gui,"PartDesignGui.setActiveBody(App.activeDocument().%s)", activeBody->getNameInDocument()); - } else { + if (activeBody == NULL) { QMessageBox::critical(Gui::getMainWindow(), QObject::tr("Could not create body"), QObject::tr("No body was found in this document, and none could be created. Please report this bug." "We recommend you do not use this document with the PartDesign workbench until the bug has been fixed." )); } + + std::string bodyName = activeBody->getNameInDocument(); } void Workbench::slotActiveDocument(const Gui::Document& Doc)