diff --git a/src/Gui/MDIViewPy.cpp b/src/Gui/MDIViewPy.cpp index 31a399cebd..33ec535da1 100644 --- a/src/Gui/MDIViewPy.cpp +++ b/src/Gui/MDIViewPy.cpp @@ -54,7 +54,9 @@ void MDIViewPy::init_type() behaviors().supportGetattr(); behaviors().supportSetattr(); - add_varargs_method("message",&MDIViewPy::message,"message()"); + add_varargs_method("message",&MDIViewPy::sendMessage,"deprecated: use sendMessage"); + add_varargs_method("sendMessage",&MDIViewPy::sendMessage,"sendMessage(str)"); + add_varargs_method("supportMessage",&MDIViewPy::supportMessage,"supportMessage(str)"); 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"); @@ -67,6 +69,8 @@ MDIViewPy::MDIViewPy(MDIView *mdi) MDIViewPy::~MDIViewPy() { + // in case the class is instantiated on the stack + ob_refcnt = 0; } Py::Object MDIViewPy::repr() @@ -79,16 +83,41 @@ Py::Object MDIViewPy::repr() return Py::String(s_out.str()); } -Py::Object MDIViewPy::message(const Py::Tuple& args) +Py::Object MDIViewPy::sendMessage(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 + if (!PyArg_ParseTuple(args.ptr(), "s;Message string needed (string)",&psMsgStr)) throw Py::Exception(); try { + bool ok = false; if (_view) - _view->onMsg(psMsgStr,ppReturn); + ok = _view->onMsg(psMsgStr,ppReturn); + return Py::Boolean(ok); + } + 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"); + } +} + +Py::Object MDIViewPy::supportMessage(const Py::Tuple& args) +{ + char *psMsgStr; + if (!PyArg_ParseTuple(args.ptr(), "s;Message string needed (string)",&psMsgStr)) + throw Py::Exception(); + + try { + bool ok = false; + if (_view) + _view->onHasMsg(psMsgStr); + return Py::Boolean(ok); } catch (const Base::Exception& e) { throw Py::RuntimeError(e.what()); @@ -99,7 +128,6 @@ Py::Object MDIViewPy::message(const Py::Tuple& args) catch (...) { throw Py::RuntimeError("Unknown C++ exception"); } - return Py::None(); } Py::Object MDIViewPy::fitAll(const Py::Tuple& args) diff --git a/src/Gui/MDIViewPy.h b/src/Gui/MDIViewPy.h index 46a0665bf3..469bdca6f3 100644 --- a/src/Gui/MDIViewPy.h +++ b/src/Gui/MDIViewPy.h @@ -27,11 +27,12 @@ #include #include #include +#include namespace Gui { class MDIView; -class MDIViewPy : public Py::PythonExtension +class GuiExport MDIViewPy : public Py::PythonExtension { public: static void init_type(void); // announce properties and methods @@ -41,7 +42,8 @@ public: Py::Object repr(); - Py::Object message(const Py::Tuple&); + Py::Object sendMessage(const Py::Tuple&); + Py::Object supportMessage(const Py::Tuple&); Py::Object fitAll(const Py::Tuple&); Py::Object setActiveObject(const Py::Tuple&); Py::Object getActiveObject(const Py::Tuple&); diff --git a/src/Mod/Spreadsheet/Gui/AppSpreadsheetGui.cpp b/src/Mod/Spreadsheet/Gui/AppSpreadsheetGui.cpp index a0fc4b5b39..fd0e01d708 100644 --- a/src/Mod/Spreadsheet/Gui/AppSpreadsheetGui.cpp +++ b/src/Mod/Spreadsheet/Gui/AppSpreadsheetGui.cpp @@ -121,6 +121,7 @@ PyMOD_INIT_FUNC(SpreadsheetGui) SpreadsheetGui::ViewProviderSheetPython::init(); SpreadsheetGui::Workbench::init(); SpreadsheetGui::SheetView::init(); + SpreadsheetGui::SheetViewPy::init_type(); // register preference page new Gui::PrefPageProducer ("Spreadsheet"); diff --git a/src/Mod/Spreadsheet/Gui/SpreadsheetView.cpp b/src/Mod/Spreadsheet/Gui/SpreadsheetView.cpp index 1eca8136bf..3895df45ca 100644 --- a/src/Mod/Spreadsheet/Gui/SpreadsheetView.cpp +++ b/src/Mod/Spreadsheet/Gui/SpreadsheetView.cpp @@ -48,6 +48,7 @@ #include #include #include +#include #include #include "qtcolorpicker.h" @@ -447,7 +448,7 @@ void SpreadsheetGui::SheetView::setCurrentIndex(App::CellAddress cell) const PyObject *SheetView::getPyObject() { if (!pythonObject) - pythonObject = new SpreadsheetViewPy(this); + pythonObject = new SheetViewPy(this); Py_INCREF(pythonObject); return pythonObject; @@ -458,4 +459,76 @@ void SheetView::deleteSelf() Gui::MDIView::deleteSelf(); } +// ---------------------------------------------------------- + +void SheetViewPy::init_type() +{ + behaviors().name("SheetViewPy"); + behaviors().doc("Python binding class for the Sheet view class"); + // you must have overwritten the virtual functions + behaviors().supportRepr(); + behaviors().supportGetattr(); + behaviors().supportSetattr(); + + add_varargs_method("getSheet", &SheetViewPy::getSheet, "getSheet()"); + behaviors().readyType(); +} + +SheetViewPy::SheetViewPy(SheetView *mdi) + : base(mdi) +{ +} + +SheetViewPy::~SheetViewPy() +{ +} + +Py::Object SheetViewPy::repr() +{ + std::ostringstream s_out; + if (!getSheetViewPtr()) + throw Py::RuntimeError("Cannot print representation of deleted object"); + s_out << "SheetView"; + return Py::String(s_out.str()); +} + +// Since with PyCXX it's not possible to make a sub-class of MDIViewPy +// a trick is to use MDIViewPy as class member and override getattr() to +// join the attributes of both classes. This way all methods of MDIViewPy +// appear for SheetViewPy, too. +Py::Object SheetViewPy::getattr(const char * attr) +{ + if (!getSheetViewPtr()) + throw Py::RuntimeError("Cannot print representation of deleted object"); + std::string name( attr ); + if (name == "__dict__" || name == "__class__") { + Py::Dict dict_self(BaseType::getattr("__dict__")); + Py::Dict dict_base(base.getattr("__dict__")); + for (auto it : dict_base) { + dict_self.setItem(it.first, it.second); + } + return dict_self; + } + + try { + return BaseType::getattr(attr); + } + catch (Py::AttributeError& e) { + e.clear(); + return base.getattr(attr); + } +} + +SheetView* SheetViewPy::getSheetViewPtr() +{ + return qobject_cast(base.getMDIViewPtr()); +} + +Py::Object SheetViewPy::getSheet(const Py::Tuple& args) +{ + if (!PyArg_ParseTuple(args.ptr(), "")) + throw Py::Exception(); + return Py::asObject(new Spreadsheet::SheetPy(getSheetViewPtr()->getSheet())); +} + #include "moc_SpreadsheetView.cpp" diff --git a/src/Mod/Spreadsheet/Gui/SpreadsheetView.h b/src/Mod/Spreadsheet/Gui/SpreadsheetView.h index 60b5fc98da..03691eace0 100644 --- a/src/Mod/Spreadsheet/Gui/SpreadsheetView.h +++ b/src/Mod/Spreadsheet/Gui/SpreadsheetView.h @@ -24,6 +24,7 @@ #define SpreadsheetView_H #include +#include #include #include "SheetModel.h" #include @@ -117,6 +118,25 @@ protected: std::map newRowSizes; }; +class SheetViewPy : public Py::PythonExtension +{ +public: + using BaseType = Py::PythonExtension; + static void init_type(); + + SheetViewPy(SheetView *mdi); + ~SheetViewPy(); + + Py::Object repr(); + Py::Object getattr(const char *); + Py::Object getSheet(const Py::Tuple&); + + SheetView* getSheetViewPtr(); + +protected: + Gui::MDIViewPy base; +}; + } // namespace SpreadsheetModGui #endif // SpreadsheetView_H