From 16ab7f710b8b308805ff9fbbef72c4060ea21d7a Mon Sep 17 00:00:00 2001 From: jriegel Date: Wed, 31 Dec 2014 15:55:17 +0100 Subject: [PATCH] Active object manager for the Viewer --- src/Gui/ActiveObjectList.cpp | 46 ++++++++++++++ src/Gui/ActiveObjectList.h | 72 ++++++++++++++++++++++ src/Gui/Application.h | 1 + src/Gui/ApplicationPy.cpp | 44 +++++++++---- src/Gui/CMakeLists.txt | 2 + src/Gui/MDIView.h | 3 + src/Gui/View3DPy.cpp | 116 ++++++++++++++++++++--------------- src/Gui/View3DPy.h | 3 +- 8 files changed, 225 insertions(+), 62 deletions(-) create mode 100644 src/Gui/ActiveObjectList.cpp create mode 100644 src/Gui/ActiveObjectList.h diff --git a/src/Gui/ActiveObjectList.cpp b/src/Gui/ActiveObjectList.cpp new file mode 100644 index 000000000..c0c22c455 --- /dev/null +++ b/src/Gui/ActiveObjectList.cpp @@ -0,0 +1,46 @@ +/*************************************************************************** +* (c) Jürgen Riegel (juergen.riegel@web.de) 2014 * +* * +* This file is part of the FreeCAD CAx development system. * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU Library General Public License (LGPL) * +* as published by the Free Software Foundation; either version 2 of * +* the License, or (at your option) any later version. * +* for detail see the LICENCE text file. * +* * +* FreeCAD is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +* GNU Library General Public License for more details. * +* * +* You should have received a copy of the GNU Library General Public * +* License along with FreeCAD; if not, write to the Free Software * +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +* USA * +* * +* Juergen Riegel 2014 * +***************************************************************************/ + +#include "PreCompiled.h" + +#ifndef _PreComp_ + +#endif + +#include "ActiveObjectList.h" + + + +using namespace Gui; + + +void Gui::ActiveObjectList::setObject(App::DocumentObject* obj, const char* name) +{ + _ObjectMap[name] = obj; +} + +bool Gui::ActiveObjectList::hasObject(const char*name) +{ + return _ObjectMap.find(name) != _ObjectMap.end(); +} diff --git a/src/Gui/ActiveObjectList.h b/src/Gui/ActiveObjectList.h new file mode 100644 index 000000000..c2b40ead4 --- /dev/null +++ b/src/Gui/ActiveObjectList.h @@ -0,0 +1,72 @@ +/*************************************************************************** +* (c) Jürgen Riegel (juergen.riegel@web.de) 2014 * +* * +* This file is part of the FreeCAD CAx development system. * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU Library General Public License (LGPL) * +* as published by the Free Software Foundation; either version 2 of * +* the License, or (at your option) any later version. * +* for detail see the LICENCE text file. * +* * +* FreeCAD is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +* GNU Library General Public License for more details. * +* * +* You should have received a copy of the GNU Library General Public * +* License along with FreeCAD; if not, write to the Free Software * +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +* USA * +* * +* Juergen Riegel 2014 * +***************************************************************************/ + + +#ifndef GUI_ActiveObjectList_H +#define GUI_ActiveObjectList_H + +#include +namespace App { + class DocumentObject; +} + +namespace Gui +{ + + class Document; + + /** List of active or special objects + * This class holds a list of objects with a special name. + * Its mainly used to points to something like the active Body or Part in a edit session. + * The class is used the viewer (editor) of a document. + * @see Gui::MDIViewer + * @author Jürgen Riegel + */ + class GuiExport ActiveObjectList + { + + public: + template T* getObject(const char*); + void setObject(App::DocumentObject*, const char*); + bool hasObject(const char*); + protected: + std::map _ObjectMap; + + + }; + + 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 + +#endif \ No newline at end of file diff --git a/src/Gui/Application.h b/src/Gui/Application.h index 96baeb1dc..ea9ed2f19 100644 --- a/src/Gui/Application.h +++ b/src/Gui/Application.h @@ -232,6 +232,7 @@ public: PYFUNCDEF_S(sActiveDocument); PYFUNCDEF_S(sSetActiveDocument); + PYFUNCDEF_S(sActiveView); PYFUNCDEF_S(sGetDocument); PYFUNCDEF_S(sDoCommand); diff --git a/src/Gui/ApplicationPy.cpp b/src/Gui/ApplicationPy.cpp index 7a6992d2e..1e3833fd5 100644 --- a/src/Gui/ApplicationPy.cpp +++ b/src/Gui/ApplicationPy.cpp @@ -139,13 +139,16 @@ PyMethodDef Application::Methods[] = { "Open a macro, Inventor or VRML file"}, {"export", (PyCFunction) Application::sExport, 1, "save scene to Inventor or VRML file"}, - {"activeDocument", (PyCFunction) Application::sActiveDocument, 1, + { "activeDocument", (PyCFunction)Application::sActiveDocument, 1, "activeDocument() -> object or None\n\n" - "Return the active document or None if no one exists"}, + "Return the active document or None if no one exists" }, {"setActiveDocument", (PyCFunction) Application::sSetActiveDocument,1, "setActiveDocument(string or App.Document) -> None\n\n" "Activate the specified document"}, - {"getDocument", (PyCFunction) Application::sGetDocument, 1, + { "activeView", (PyCFunction)Application::sActiveView, 1, + "activeView() -> object or None\n\n" + "Return the active view of the active document or None if no one exists" }, + { "getDocument", (PyCFunction)Application::sGetDocument, 1, "getDocument(string) -> object\n\n" "Get a document by its name"}, {"doCommand", (PyCFunction) Application::sDoCommand, 1, @@ -167,17 +170,34 @@ PyMethodDef Application::Methods[] = { {NULL, NULL} /* Sentinel */ }; -PyObject* Gui::Application::sActiveDocument(PyObject * /*self*/, PyObject *args,PyObject * /*kwd*/) +PyObject* Gui::Application::sActiveDocument(PyObject * /*self*/, PyObject *args, PyObject * /*kwd*/) { - if (!PyArg_ParseTuple(args, "")) // convert args: Python->C - return NULL; // NULL triggers exception + if (!PyArg_ParseTuple(args, "")) // convert args: Python->C + return NULL; // NULL triggers exception - Document *pcDoc = Instance->activeDocument(); - if (pcDoc) { - return pcDoc->getPyObject(); - } else { - Py_Return; - } + Document *pcDoc = Instance->activeDocument(); + if (pcDoc) { + return pcDoc->getPyObject(); + } + else { + Py_Return; + } +} + +PyObject* Gui::Application::sActiveView(PyObject * /*self*/, PyObject *args, PyObject * /*kwd*/) +{ + if (!PyArg_ParseTuple(args, "")) // convert args: Python->C + return NULL; // NULL triggers exception + + Document *pcDoc = Instance->activeDocument(); + if (pcDoc) { + Gui::MDIView *pcView = pcDoc->getActiveView(); + if (pcView) + // already incremented in getPyObject(). + return pcView->getPyObject(); + } + + Py_Return; } PyObject* Gui::Application::sSetActiveDocument(PyObject * /*self*/, PyObject *args,PyObject * /*kwd*/) diff --git a/src/Gui/CMakeLists.txt b/src/Gui/CMakeLists.txt index 7f08a36ff..9af98125d 100644 --- a/src/Gui/CMakeLists.txt +++ b/src/Gui/CMakeLists.txt @@ -933,10 +933,12 @@ SOURCE_GROUP("Widget" FILES ${Widget_SRCS}) SET(View_CPP_SRCS MDIView.cpp GraphvizView.cpp + ActiveObjectList.cpp ) SET(View_HPP_SRCS MDIView.h GraphvizView.h + ActiveObjectList.h ) SET(View_SRCS ${View_CPP_SRCS} diff --git a/src/Gui/MDIView.h b/src/Gui/MDIView.h index 5892169c1..e02818129 100644 --- a/src/Gui/MDIView.h +++ b/src/Gui/MDIView.h @@ -26,6 +26,7 @@ #include "View.h" #include +#include "ActiveObjectList.h" QT_BEGIN_NAMESPACE class QPrinter; @@ -108,6 +109,8 @@ public: virtual void setCurrentViewMode(ViewMode mode); ViewMode currentViewMode() const { return currentMode; } + ActiveObjectList ActiveObjects; + public Q_SLOTS: virtual void setOverrideCursor(const QCursor&); virtual void restoreOverrideCursor(); diff --git a/src/Gui/View3DPy.cpp b/src/Gui/View3DPy.cpp index eee00ecd6..6d4a91821 100644 --- a/src/Gui/View3DPy.cpp +++ b/src/Gui/View3DPy.cpp @@ -64,6 +64,7 @@ #include #include +#include #include using namespace Gui; @@ -223,15 +224,20 @@ Py::Object View3DInventorPy::getattr(const char * attr) s_out << "Cannot access attribute '" << attr << "' of deleted object"; throw Py::RuntimeError(s_out.str()); } - else { - Py::Object obj = Py::PythonExtension::getattr(attr); - if (PyCFunction_Check(obj.ptr())) { - PyCFunctionObject* op = reinterpret_cast(obj.ptr()); - if (!pycxx_handler) - pycxx_handler = op->m_ml->ml_meth; - op->m_ml->ml_meth = method_varargs_ext_handler; - } - return obj; + else { + App::DocumentObject *docObj = _view->ActiveObjects.getObject(attr); + if (docObj){ + return Py::Object(docObj->getPyObject()); + }else{ + Py::Object obj = Py::PythonExtension::getattr(attr); + if (PyCFunction_Check(obj.ptr())) { + PyCFunctionObject* op = reinterpret_cast(obj.ptr()); + if (!pycxx_handler) + pycxx_handler = op->m_ml->ml_meth; + op->m_ml->ml_meth = method_varargs_ext_handler; + } + return obj; + } } } @@ -2116,47 +2122,59 @@ Py::Object View3DInventorPy::addDraggerCallback(const Py::Tuple& args) Py::Object View3DInventorPy::removeDraggerCallback(const Py::Tuple& args) { - PyObject* dragger; - char* type; - PyObject* method; - if (!PyArg_ParseTuple(args.ptr(), "OsO", &dragger,&type, &method)) - throw Py::Exception(); + PyObject* dragger; + char* type; + PyObject* method; + if (!PyArg_ParseTuple(args.ptr(), "OsO", &dragger, &type, &method)) + throw Py::Exception(); - //Check if dragger is a SoDragger object and cast - void* ptr = 0; - try { - Base::Interpreter().convertSWIGPointerObj("pivy.coin", "SoDragger *", dragger, &ptr, 0); - } - catch (const Base::Exception&) { - throw Py::Exception("The first argument must be of type SoDragger"); - } + //Check if dragger is a SoDragger object and cast + void* ptr = 0; + try { + Base::Interpreter().convertSWIGPointerObj("pivy.coin", "SoDragger *", dragger, &ptr, 0); + } + catch (const Base::Exception&) { + throw Py::Exception("The first argument must be of type SoDragger"); + } - SoDragger* drag = reinterpret_cast(ptr); - try { - if (strcmp(type,"addFinishCallback")==0) { - drag->removeFinishCallback(draggerCallback,method); - } - else if (strcmp(type,"addStartCallback")==0) { - drag->removeStartCallback(draggerCallback,method); - } - else if (strcmp(type,"addMotionCallback")==0) { - drag->removeMotionCallback(draggerCallback,method); - } - else if (strcmp(type,"addValueChangedCallback")==0) { - drag->removeValueChangedCallback(draggerCallback,method); - } - else { - std::string s; - std::ostringstream s_out; - s_out << type << " is not a valid dragger callback type"; - throw Py::Exception(s_out.str()); - } + SoDragger* drag = reinterpret_cast(ptr); + try { + if (strcmp(type, "addFinishCallback") == 0) { + drag->removeFinishCallback(draggerCallback, method); + } + else if (strcmp(type, "addStartCallback") == 0) { + drag->removeStartCallback(draggerCallback, method); + } + else if (strcmp(type, "addMotionCallback") == 0) { + drag->removeMotionCallback(draggerCallback, method); + } + else if (strcmp(type, "addValueChangedCallback") == 0) { + drag->removeValueChangedCallback(draggerCallback, method); + } + else { + std::string s; + std::ostringstream s_out; + s_out << type << " is not a valid dragger callback type"; + throw Py::Exception(s_out.str()); + } - callbacks.remove(method); - Py_DECREF(method); - return Py::Callable(method, false); - } - catch (const Py::Exception&) { - throw; - } + callbacks.remove(method); + Py_DECREF(method); + return Py::Callable(method, false); + } + catch (const Py::Exception&) { + throw; + } +} + +Py::Object View3DInventorPy::setActiveObject(const Py::Tuple& args) +{ + App::DocumentObjectPy* 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); + } } diff --git a/src/Gui/View3DPy.h b/src/Gui/View3DPy.h index b87f8fdf3..604048ade 100644 --- a/src/Gui/View3DPy.h +++ b/src/Gui/View3DPy.h @@ -101,7 +101,8 @@ public: Py::Object setAxisCross(const Py::Tuple&); Py::Object hasAxisCross(const Py::Tuple&); Py::Object addDraggerCallback(const Py::Tuple&); - Py::Object removeDraggerCallback(const Py::Tuple&); + Py::Object removeDraggerCallback(const Py::Tuple&); + Py::Object setActiveObject(const Py::Tuple&); private: static void eventCallback(void * ud, SoEventCallback * n);