diff --git a/src/Gui/Application.cpp b/src/Gui/Application.cpp index 049cfcb396..d197384a86 100644 --- a/src/Gui/Application.cpp +++ b/src/Gui/Application.cpp @@ -85,6 +85,7 @@ #include "SoFCDB.h" #include "PythonConsolePy.h" #include "PythonDebugger.h" +#include "MDIViewPy.h" #include "View3DPy.h" #include "DlgOnlineHelpImp.h" #include "SpaceballEvent.h" @@ -93,6 +94,7 @@ #include "TransactionObject.h" #include "FileDialog.h" +#include "TextDocumentEditorView.h" #include "SplitView3DInventor.h" #include "View3DInventor.h" #include "ViewProvider.h" @@ -430,6 +432,7 @@ Application::Application(bool GUIenabled) OutputStdout ::init_type(); OutputStderr ::init_type(); PythonStdin ::init_type(); + MDIViewPy ::init_type(); View3DInventorPy ::init_type(); View3DInventorViewerPy ::init_type(); AbstractSplitViewPy ::init_type(); @@ -1654,6 +1657,7 @@ void Application::initTypes(void) Gui::View3DInventor ::init(); Gui::AbstractSplitView ::init(); Gui::SplitView3DInventor ::init(); + Gui::TextDocumentEditorView ::init(); // View Provider Gui::ViewProvider ::init(); Gui::ViewProviderExtension ::init(); diff --git a/src/Gui/CMakeLists.txt b/src/Gui/CMakeLists.txt index b709ecbccf..329db88658 100644 --- a/src/Gui/CMakeLists.txt +++ b/src/Gui/CMakeLists.txt @@ -1133,11 +1133,13 @@ SOURCE_GROUP("Widget" FILES ${Widget_SRCS}) # The view sources SET(View_CPP_SRCS MDIView.cpp + MDIViewPy.cpp GraphvizView.cpp ActiveObjectList.cpp ) SET(View_HPP_SRCS MDIView.h + MDIViewPy.h GraphvizView.h ActiveObjectList.h ) diff --git a/src/Gui/MDIView.cpp b/src/Gui/MDIView.cpp index b6e1486365..a010b95da7 100644 --- a/src/Gui/MDIView.cpp +++ b/src/Gui/MDIView.cpp @@ -36,6 +36,7 @@ #include "MDIView.h" +#include "MDIViewPy.h" #include "Command.h" #include "Document.h" #include "Application.h" @@ -44,11 +45,15 @@ using namespace Gui; -TYPESYSTEM_SOURCE_ABSTRACT(Gui::MDIView,Gui::BaseView); +TYPESYSTEM_SOURCE_ABSTRACT(Gui::MDIView,Gui::BaseView) MDIView::MDIView(Gui::Document* pcDocument,QWidget* parent, Qt::WindowFlags wflags) - : QMainWindow(parent, wflags), BaseView(pcDocument),currentMode(Child), wstate(Qt::WindowNoState) + : QMainWindow(parent, wflags) + , BaseView(pcDocument) + , pythonObject(nullptr) + , currentMode(Child) + , wstate(Qt::WindowNoState) , ActiveObjects(pcDocument) { setAttribute(Qt::WA_DeleteOnClose); @@ -83,6 +88,12 @@ MDIView::~MDIView() } if (connectDelObject.connected()) connectDelObject.disconnect(); + + if (pythonObject) { + Base::PyGILStateLocker lock; + Py_DECREF(pythonObject); + pythonObject = nullptr; + } } void MDIView::deleteSelf() @@ -111,6 +122,15 @@ void MDIView::deleteSelf() _pcDocument = 0; } +PyObject* MDIView::getPyObject() +{ + if (!pythonObject) + pythonObject = new MDIViewPy(this); + + Py_INCREF(pythonObject); + return pythonObject; +} + void MDIView::setOverrideCursor(const QCursor& c) { Q_UNUSED(c); diff --git a/src/Gui/MDIView.h b/src/Gui/MDIView.h index 064a68e346..063c210353 100644 --- a/src/Gui/MDIView.h +++ b/src/Gui/MDIView.h @@ -55,7 +55,6 @@ class GuiExport MDIView : public QMainWindow, public BaseView TYPESYSTEM_HEADER(); - public: /** View constructor * Attach the view to the given document. If the document is zero @@ -80,10 +79,12 @@ public: virtual bool canClose(void); /// delete itself virtual void deleteSelf(); + virtual PyObject *getPyObject(); /** @name Printing */ //@{ public Q_SLOTS: virtual void print(QPrinter* printer); + public: /** Print content of view */ virtual void print(); @@ -149,6 +150,9 @@ protected: /** \internal */ void changeEvent(QEvent *e); +protected: + PyObject* pythonObject; + private: ViewMode currentMode; Qt::WindowStates wstate; diff --git a/src/Gui/MDIViewPy.cpp b/src/Gui/MDIViewPy.cpp new file mode 100644 index 0000000000..31a399cebd --- /dev/null +++ b/src/Gui/MDIViewPy.cpp @@ -0,0 +1,172 @@ +/*************************************************************************** + * Copyright (c) 2019 Werner Mayer * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library 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 this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#include "PreCompiled.h" + +#include "MDIViewPy.h" +#include "Application.h" +#include "Document.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +using namespace Gui; + + +void MDIViewPy::init_type() +{ + behaviors().name("MDIViewPy"); + behaviors().doc("Python binding class for the MDI view class"); + // you must have overwritten the virtual functions + behaviors().supportRepr(); + behaviors().supportGetattr(); + behaviors().supportSetattr(); + + add_varargs_method("message",&MDIViewPy::message,"message()"); + add_varargs_method("fitAll",&MDIViewPy::fitAll,"fitAll()"); + add_varargs_method("setActiveObject", &MDIViewPy::setActiveObject, "setActiveObject(name,object,subname=None)\nadd or set a new active object"); + add_varargs_method("getActiveObject", &MDIViewPy::getActiveObject, "getActiveObject(name,resolve=True)\nreturns the active object for the given type"); +} + +MDIViewPy::MDIViewPy(MDIView *mdi) + : _view(mdi) +{ +} + +MDIViewPy::~MDIViewPy() +{ +} + +Py::Object MDIViewPy::repr() +{ + std::string s; + std::ostringstream s_out; + if (!_view) + throw Py::RuntimeError("Cannot print representation of deleted object"); + s_out << "MDIView"; + return Py::String(s_out.str()); +} + +Py::Object MDIViewPy::message(const Py::Tuple& args) +{ + const char **ppReturn = 0; + char *psMsgStr; + if (!PyArg_ParseTuple(args.ptr(), "s;Message string needed (string)",&psMsgStr)) // convert args: Python->C + throw Py::Exception(); + + try { + if (_view) + _view->onMsg(psMsgStr,ppReturn); + } + catch (const Base::Exception& e) { + throw Py::RuntimeError(e.what()); + } + catch (const std::exception& e) { + throw Py::RuntimeError(e.what()); + } + catch (...) { + throw Py::RuntimeError("Unknown C++ exception"); + } + return Py::None(); +} + +Py::Object MDIViewPy::fitAll(const Py::Tuple& args) +{ + if (!PyArg_ParseTuple(args.ptr(), "")) + throw Py::Exception(); + + try { + if (_view) + _view->viewAll(); + } + catch (const Base::Exception& e) { + throw Py::RuntimeError(e.what()); + } + catch (const std::exception& e) { + throw Py::RuntimeError(e.what()); + } + catch (...) { + throw Py::RuntimeError("Unknown C++ exception"); + } + return Py::None(); +} + +Py::Object MDIViewPy::setActiveObject(const Py::Tuple& args) +{ + PyObject* docObject = Py_None; + char* name; + char *subname = 0; + if (!PyArg_ParseTuple(args.ptr(), "s|Os", &name, &docObject, &subname)) + throw Py::Exception(); + + if (_view) { + if (docObject == Py_None) { + _view->setActiveObject(0, name); + } + else { + if (!PyObject_TypeCheck(docObject, &App::DocumentObjectPy::Type)) + throw Py::TypeError("Expect the second argument to be a document object or None"); + + App::DocumentObject* obj = static_cast(docObject)->getDocumentObjectPtr(); + _view->setActiveObject(obj, name, subname); + } + } + + return Py::None(); +} + +Py::Object MDIViewPy::getActiveObject(const Py::Tuple& args) +{ + const char* name; + PyObject *resolve = Py_True; + if (!PyArg_ParseTuple(args.ptr(), "s|O", &name,&resolve)) + throw Py::Exception(); + + App::DocumentObject *parent = nullptr; + std::string subname; + App::DocumentObject* obj = nullptr; + if (_view) + obj = _view->getActiveObject(name,&parent,&subname); + if (!obj) + return Py::None(); + + if (PyObject_IsTrue(resolve)) + return Py::asObject(obj->getPyObject()); + + return Py::TupleN( + Py::asObject(obj->getPyObject()), + Py::asObject(parent->getPyObject()), + Py::String(subname.c_str())); +} diff --git a/src/Gui/MDIViewPy.h b/src/Gui/MDIViewPy.h new file mode 100644 index 0000000000..46a0665bf3 --- /dev/null +++ b/src/Gui/MDIViewPy.h @@ -0,0 +1,57 @@ +/*************************************************************************** + * Copyright (c) 2019 Werner Mayer * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library 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 this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#ifndef GUI_MDIVIEWPY_H +#define GUI_MDIVIEWPY_H + +#include +#include +#include + +namespace Gui { +class MDIView; + +class MDIViewPy : public Py::PythonExtension +{ +public: + static void init_type(void); // announce properties and methods + + MDIViewPy(MDIView *mdi); + ~MDIViewPy(); + + Py::Object repr(); + + Py::Object message(const Py::Tuple&); + Py::Object fitAll(const Py::Tuple&); + Py::Object setActiveObject(const Py::Tuple&); + Py::Object getActiveObject(const Py::Tuple&); + + MDIView* getMDIViewPtr() {return _view.data();} + +private: + QPointer _view; +}; + +} // namespace Gui + +#endif //GUI_MDIVIEWPY_H diff --git a/src/Gui/TextDocumentEditorView.cpp b/src/Gui/TextDocumentEditorView.cpp index 771114e624..4b48efee85 100644 --- a/src/Gui/TextDocumentEditorView.cpp +++ b/src/Gui/TextDocumentEditorView.cpp @@ -40,6 +40,8 @@ using namespace Gui; +TYPESYSTEM_SOURCE_ABSTRACT(Gui::TextDocumentEditorView, Gui::MDIView) + TextDocumentEditorView::TextDocumentEditorView( App::TextDocument* txtDoc, QPlainTextEdit* e, QWidget* parent) diff --git a/src/Gui/TextDocumentEditorView.h b/src/Gui/TextDocumentEditorView.h index c1d2db217b..528d52d7c4 100644 --- a/src/Gui/TextDocumentEditorView.h +++ b/src/Gui/TextDocumentEditorView.h @@ -39,6 +39,8 @@ namespace Gui { class GuiExport TextDocumentEditorView : public MDIView { Q_OBJECT + TYPESYSTEM_HEADER(); + public: TextDocumentEditorView( App::TextDocument* textDocument, diff --git a/src/Gui/View3DInventor.cpp b/src/Gui/View3DInventor.cpp index d927b6c784..bee3e54115 100644 --- a/src/Gui/View3DInventor.cpp +++ b/src/Gui/View3DInventor.cpp @@ -105,7 +105,7 @@ void GLOverlayWidget::paintEvent(QPaintEvent*) /* TRANSLATOR Gui::View3DInventor */ -TYPESYSTEM_SOURCE_ABSTRACT(Gui::View3DInventor,Gui::MDIView); +TYPESYSTEM_SOURCE_ABSTRACT(Gui::View3DInventor,Gui::MDIView) View3DInventor::View3DInventor(Gui::Document* pcDocument, QWidget* parent, const QtGLWidget* sharewidget, Qt::WindowFlags wflags) diff --git a/src/Mod/Spreadsheet/Gui/AppSpreadsheetGui.cpp b/src/Mod/Spreadsheet/Gui/AppSpreadsheetGui.cpp index 1cd55423b7..35c750d5dc 100644 --- a/src/Mod/Spreadsheet/Gui/AppSpreadsheetGui.cpp +++ b/src/Mod/Spreadsheet/Gui/AppSpreadsheetGui.cpp @@ -117,7 +117,7 @@ PyMOD_INIT_FUNC(SpreadsheetGui) SpreadsheetGui::ViewProviderSheet::init(); SpreadsheetGui::Workbench::init(); -// SpreadsheetGui::SheetView::init(); + SpreadsheetGui::SheetView::init(); // add resources and reloads the translators loadSpreadsheetResource(); diff --git a/src/Mod/Spreadsheet/Gui/SpreadsheetView.cpp b/src/Mod/Spreadsheet/Gui/SpreadsheetView.cpp index d0c4b57dc9..8d47c91883 100644 --- a/src/Mod/Spreadsheet/Gui/SpreadsheetView.cpp +++ b/src/Mod/Spreadsheet/Gui/SpreadsheetView.cpp @@ -60,7 +60,7 @@ using namespace App; /* TRANSLATOR SpreadsheetGui::SheetView */ -TYPESYSTEM_SOURCE_ABSTRACT(SpreadsheetGui::SheetView, Gui::MDIView); +TYPESYSTEM_SOURCE_ABSTRACT(SpreadsheetGui::SheetView, Gui::MDIView) SheetView::SheetView(Gui::Document *pcDocument, App::DocumentObject *docObj, QWidget *parent) : MDIView(pcDocument, parent) @@ -364,7 +364,7 @@ QModelIndex SheetView::currentIndex() const PyObject *SheetView::getPyObject() { - Py_Return; + return Gui::MDIView::getPyObject(); } void SheetView::deleteSelf() diff --git a/src/Mod/TechDraw/Gui/AppTechDrawGui.cpp b/src/Mod/TechDraw/Gui/AppTechDrawGui.cpp index d5511b046e..087d8eaf74 100644 --- a/src/Mod/TechDraw/Gui/AppTechDrawGui.cpp +++ b/src/Mod/TechDraw/Gui/AppTechDrawGui.cpp @@ -37,6 +37,7 @@ #include #include "Workbench.h" +#include "MDIViewPage.h" #include "DlgPrefsTechDrawImp.h" #include "DlgPrefsTechDraw2Imp.h" @@ -114,6 +115,7 @@ PyMOD_INIT_FUNC(TechDrawGui) CreateTechDrawCommandsAnnotate(); TechDrawGui::Workbench::init(); + TechDrawGui::MDIViewPage::init(); TechDrawGui::ViewProviderPage::init(); TechDrawGui::ViewProviderDrawingView::init(); diff --git a/src/Mod/TechDraw/Gui/MDIViewPage.cpp b/src/Mod/TechDraw/Gui/MDIViewPage.cpp index 28d76da7f6..a1f56e3316 100644 --- a/src/Mod/TechDraw/Gui/MDIViewPage.cpp +++ b/src/Mod/TechDraw/Gui/MDIViewPage.cpp @@ -111,6 +111,8 @@ using namespace TechDrawGui; /* TRANSLATOR TechDrawGui::MDIViewPage */ +TYPESYSTEM_SOURCE_ABSTRACT(TechDrawGui::MDIViewPage, Gui::MDIView) + MDIViewPage::MDIViewPage(ViewProviderPage *pageVp, Gui::Document* doc, QWidget* parent) : Gui::MDIView(doc, parent), m_orientation(QPrinter::Landscape), @@ -847,7 +849,7 @@ QPrinter::PaperSize MDIViewPage::getPaperSize(int w, int h) const PyObject* MDIViewPage::getPyObject() { - Py_Return; + return Gui::MDIView::getPyObject(); } void MDIViewPage::contextMenuEvent(QContextMenuEvent *event) diff --git a/src/Mod/TechDraw/Gui/MDIViewPage.h b/src/Mod/TechDraw/Gui/MDIViewPage.h index b19293e1de..33005e946f 100644 --- a/src/Mod/TechDraw/Gui/MDIViewPage.h +++ b/src/Mod/TechDraw/Gui/MDIViewPage.h @@ -51,6 +51,7 @@ class QGIView; class TechDrawGuiExport MDIViewPage : public Gui::MDIView, public Gui::SelectionObserver { Q_OBJECT + TYPESYSTEM_HEADER(); public: MDIViewPage(ViewProviderPage *page, Gui::Document* doc, QWidget* parent = 0);