diff --git a/CMakeLists.txt b/CMakeLists.txt index 17cda74bc..3bc629c75 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -360,6 +360,17 @@ MARK_AS_ADVANCED(FORCE FREECAD_LIBPACK_CHECKFILE6X FREECAD_LIBPACK_CHECKFILE7X) find_package(Spnav) endif(WIN32) +# -------------------------------- Shiboken/PySide ------------------------ + + find_package(Shiboken) + IF(SHIBOKEN_INCLUDE_DIR) + message("-- Shiboken has been found.") + ENDIF(SHIBOKEN_INCLUDE_DIR) + find_package(PySide) + IF(PYSIDE_INCLUDE_DIR) + message("-- PySide has been found.") + ENDIF(PYSIDE_INCLUDE_DIR) + # ------------------------------ Matplotlib ------------------------------ find_package(Matplotlib) diff --git a/src/Gui/CMakeLists.txt b/src/Gui/CMakeLists.txt index 104e4486b..79137b392 100644 --- a/src/Gui/CMakeLists.txt +++ b/src/Gui/CMakeLists.txt @@ -3,6 +3,7 @@ if(WIN32) add_definitions(-DFCGui -DQIIS_MAKEDLL) endif(WIN32) + if (FREECAD_USE_3DCONNEXION) add_definitions(-D_USE_3DCONNEXION_SDK) endif(FREECAD_USE_3DCONNEXION) @@ -59,6 +60,28 @@ IF(SPNAV_FOUND) ) ENDIF(SPNAV_FOUND) +if(SHIBOKEN_INCLUDE_DIR) + add_definitions(-DHAVE_SHIBOKEN) + include_directories( + ${SHIBOKEN_INCLUDE_DIR} + ) + set(FreeCADGui_LIBS + ${FreeCADGui_LIBS} + ${SHIBOKEN_LIBRARY} + ) +endif(SHIBOKEN_INCLUDE_DIR) + +if(PYSIDE_INCLUDE_DIR) + add_definitions(-DHAVE_PYSIDE) + include_directories( + ${PYSIDE_INCLUDE_DIR} + ) + set(FreeCADGui_LIBS + ${FreeCADGui_LIBS} + ${PYSIDE_LIBRARY} + ) +endif(PYSIDE_INCLUDE_DIR) + generate_from_xml(DocumentPy) generate_from_xml(PythonWorkbenchPy) generate_from_xml(ViewProviderPy) diff --git a/src/Gui/TaskView/TaskDialogPython.cpp b/src/Gui/TaskView/TaskDialogPython.cpp index c921eb110..e8da8ca38 100644 --- a/src/Gui/TaskView/TaskDialogPython.cpp +++ b/src/Gui/TaskView/TaskDialogPython.cpp @@ -186,24 +186,22 @@ TaskWatcherPython::TaskWatcherPython(const Py::Object& o) if (!tb && !title.isEmpty()) tb = new Gui::TaskView::TaskBox(icon, title, true, 0); Py::List list(watcher.getAttr(std::string("widgets"))); - Py::Module mainmod(PyImport_AddModule((char*)"sip")); - Py::Callable func = mainmod.getDict().getItem("unwrapinstance"); - for (Py::List::iterator it = list.begin(); it != list.end(); ++it) { - Py::Tuple arguments(1); - arguments[0] = *it; //PyQt pointer - Py::Object result = func.apply(arguments); - void* ptr = PyLong_AsVoidPtr(result.ptr()); - QObject* object = reinterpret_cast(ptr); - if (object) { - QWidget* w = qobject_cast(object); - if (w) { - if (tb) - tb->groupLayout()->addWidget(w); - else - Content.push_back(w); + + Gui::PythonWrapper wrap; + if (wrap.loadModule()) { + for (Py::List::iterator it = list.begin(); it != list.end(); ++it) { + QObject* object = wrap.toQObject(*it); + if (object) { + QWidget* w = qobject_cast(object); + if (w) { + if (tb) + tb->groupLayout()->addWidget(w); + else + Content.push_back(w); + } } } - } + } } if (tb) Content.push_back(tb); @@ -278,30 +276,28 @@ TaskDialogPython::TaskDialogPython(const Py::Object& o) : dlg(o) } } else if (dlg.hasAttr(std::string("form"))) { - Py::Object f(dlg.getAttr(std::string("form"))); - Py::List widgets; - if (f.isList()) { - widgets = f; - } - else { - widgets.append(f); - } - for (Py::List::iterator it = widgets.begin(); it != widgets.end(); ++it) { - Py::Module mainmod(PyImport_AddModule((char*)"sip")); - Py::Callable func = mainmod.getDict().getItem("unwrapinstance"); - Py::Tuple arguments(1); - arguments[0] = *it; //PyQt pointer - Py::Object result = func.apply(arguments); - void* ptr = PyLong_AsVoidPtr(result.ptr()); - QObject* object = reinterpret_cast(ptr); - if (object) { - QWidget* form = qobject_cast(object); - if (form) { - Gui::TaskView::TaskBox* taskbox = new Gui::TaskView::TaskBox( - form->windowIcon().pixmap(32), form->windowTitle(), true, 0); - taskbox->groupLayout()->addWidget(form); - Content.push_back(taskbox); - } + Py::Object f(dlg.getAttr(std::string("form"))); + Py::List widgets; + if (f.isList()) { + widgets = f; + } + else { + widgets.append(f); + } + + Gui::PythonWrapper wrap; + if (wrap.loadModule()) { + for (Py::List::iterator it = widgets.begin(); it != widgets.end(); ++it) { + QObject* object = wrap.toQObject(*it); + if (object) { + QWidget* form = qobject_cast(object); + if (form) { + Gui::TaskView::TaskBox* taskbox = new Gui::TaskView::TaskBox( + form->windowIcon().pixmap(32), form->windowTitle(), true, 0); + taskbox->groupLayout()->addWidget(form); + Content.push_back(taskbox); + } + } } } } diff --git a/src/Gui/WidgetFactory.cpp b/src/Gui/WidgetFactory.cpp index fd734154f..2996f2592 100644 --- a/src/Gui/WidgetFactory.cpp +++ b/src/Gui/WidgetFactory.cpp @@ -23,6 +23,20 @@ #include "PreCompiled.h" +#if 0 // disable for now +#ifdef HAVE_SHIBOKEN +# undef _POSIX_C_SOURCE +# undef _XOPEN_SOURCE +# include +# include +# include +# ifdef HAVE_PYSIDE +# include +PyTypeObject** SbkPySide_QtCoreTypes=NULL; +# endif +#endif +#endif + #include #include #include @@ -37,6 +51,64 @@ using namespace Gui; +PythonWrapper::PythonWrapper() +{ +} + +QObject* PythonWrapper::toQObject(const Py::Object& pyobject) +{ +#if 0 + // http://pastebin.com/JByDAF5Z +//#if defined (HAVE_SHIBOKEN) && defined(HAVE_PYSIDE) + PyTypeObject * type = Shiboken::SbkType(); + if (type) { + if (Shiboken::Object::checkType(pyobject.ptr())) { + SbkObject* sbkobject = reinterpret_cast(pyobject.ptr()); + void* cppobject = Shiboken::Object::cppPointer(sbkobject, type); + return reinterpret_cast(cppobject); + } + } +#else + Py::Module mainmod(PyImport_AddModule((char*)"sip")); + Py::Callable func = mainmod.getDict().getItem("unwrapinstance"); + Py::Tuple arguments(1); + arguments[0] = pyobject; //PyQt pointer + Py::Object result = func.apply(arguments); + void* ptr = PyLong_AsVoidPtr(result.ptr()); + return reinterpret_cast(ptr); +#endif + + return 0; +} + +Py::Object PythonWrapper::toPython(QWidget* widget) +{ + // todo: Port to PySide + Py::Module sipmod(PyImport_AddModule((char*)"sip")); + Py::Callable func = sipmod.getDict().getItem("wrapinstance"); + Py::Tuple arguments(2); + arguments[0] = Py::asObject(PyLong_FromVoidPtr(widget)); + Py::Module qtmod(PyImport_ImportModule((char*)"PyQt4.Qt")); + arguments[1] = qtmod.getDict().getItem("QWidget"); + return func.apply(arguments); +} + +bool PythonWrapper::loadModule() +{ +#if 0 +//#if defined (HAVE_SHIBOKEN) && defined(HAVE_PYSIDE) + if (SbkPySide_QtCoreTypes) + return true; // already loaded + Shiboken::AutoDecRef requiredModule(Shiboken::Module::import("PySide.QtCore")); + if (requiredModule.isNull()) + return false; + SbkPySide_QtCoreTypes = Shiboken::Module::getTypes(requiredModule); +#endif + return true; +} + +// ---------------------------------------------------- + Gui::WidgetFactoryInst* Gui::WidgetFactoryInst::_pcSingleton = NULL; WidgetFactoryInst& WidgetFactoryInst::instance() @@ -232,23 +304,17 @@ Py::Object UiLoaderPy::repr() Py::Object UiLoaderPy::createWidget(const Py::Tuple& args) { - Py::Module sipmod(PyImport_AddModule((char*)"sip")); - Py::Module qtmod(PyImport_ImportModule((char*)"PyQt4.Qt")); + Gui::PythonWrapper wrap; // 1st argument std::string className = (std::string)Py::String(args[0]); // 2nd argument QWidget* parent = 0; - if (args.size() > 1) { - Py::Callable func = sipmod.getDict().getItem("unwrapinstance"); - Py::Tuple arguments(1); - arguments[0] = args[1]; //PyQt pointer - Py::Object result = func.apply(arguments); - void* ptr = PyLong_AsVoidPtr(result.ptr()); - QObject* object = reinterpret_cast(ptr); - if (object) - parent = qobject_cast(object); + if (wrap.loadModule() && args.size() > 1) { + QObject* object = wrap.toQObject(args[1]); + if (object) + parent = qobject_cast(object); } // 3rd argument @@ -259,11 +325,7 @@ Py::Object UiLoaderPy::createWidget(const Py::Tuple& args) QWidget* widget = loader.createWidget(QString::fromAscii(className.c_str()), parent, QString::fromAscii(objectName.c_str())); - Py::Callable func = sipmod.getDict().getItem("wrapinstance"); - Py::Tuple arguments(2); - arguments[0] = Py::asObject(PyLong_FromVoidPtr(widget)); - arguments[1] = qtmod.getDict().getItem("QWidget"); - return func.apply(arguments); + return wrap.toPython(widget); } // ---------------------------------------------------- diff --git a/src/Gui/WidgetFactory.h b/src/Gui/WidgetFactory.h index 705e4c36b..5442c7efc 100644 --- a/src/Gui/WidgetFactory.h +++ b/src/Gui/WidgetFactory.h @@ -38,6 +38,17 @@ namespace Gui { namespace Dialog{ class PreferencePage; } + +class GuiExport PythonWrapper +{ +public: + PythonWrapper(); + bool loadModule(); + + QObject* toQObject(const Py::Object&); + Py::Object toPython(QWidget*); +}; + /** * The widget factory provides methods for the dynamic creation of widgets. * To create these widgets once they must be registered to the factory.