diff --git a/src/Gui/Application.cpp b/src/Gui/Application.cpp index bdadb7ad2e..cd46f0b4a2 100644 --- a/src/Gui/Application.cpp +++ b/src/Gui/Application.cpp @@ -81,6 +81,7 @@ #include "PythonDebugger.h" #include "MainWindowPy.h" #include "MDIViewPy.h" +#include "Placement.h" #include "SoFCDB.h" #include "Selection.h" #include "SelectionFilterPy.h" @@ -359,6 +360,7 @@ struct PyMethodDef FreeCADGui_methods[] = { } // namespace Gui +// clang-format off Application::Application(bool GUIenabled) { // App::GetApplication().Attach(this); @@ -452,6 +454,10 @@ Application::Application(bool GUIenabled) Base::Interpreter().addType(UiLoaderPy::type_object(), module, "UiLoader"); PyResource::init_type(); + Gui::Dialog::TaskPlacementPy::init_type(); + Base::Interpreter().addType(Gui::Dialog::TaskPlacementPy::type_object(), + module, "TaskPlacement"); + // PySide additions PyModule_AddObject(module, "PySideUic", Base::Interpreter().addModule(new PySideUicModule)); @@ -555,6 +561,7 @@ Application::Application(bool GUIenabled) MacroCommand::load(); } } +// clang-format on Application::~Application() { diff --git a/src/Gui/Placement.cpp b/src/Gui/Placement.cpp index c34be6dd37..72f1b1064e 100644 --- a/src/Gui/Placement.cpp +++ b/src/Gui/Placement.cpp @@ -32,13 +32,16 @@ #include #include +#include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -1152,4 +1155,227 @@ void TaskPlacement::clicked(int id) } } +// ---------------------------------------------- + +void TaskPlacementPy::init_type() +{ + behaviors().name("TaskPlacement"); + behaviors().doc("TaskPlacement"); + behaviors().set_tp_new(PyMake); + // you must have overwritten the virtual functions + behaviors().supportRepr(); + behaviors().supportGetattr(); + behaviors().supportSetattr(); + // clang-format off + add_varargs_method("setPropertyName",&TaskPlacementPy::setPropertyName,"setPropertyName(string)"); + add_varargs_method("setPlacement",&TaskPlacementPy::setPlacement,"setPlacement(Placement)"); + add_varargs_method("setSelection",&TaskPlacementPy::setSelection,"setSelection(list)"); + add_varargs_method("bindObject",&TaskPlacementPy::bindObject,"bindObject()"); + + add_varargs_method("showDefaultButtons",&TaskPlacementPy::showDefaultButtons, "showDefaultButtons(bool)"); + add_varargs_method("accept",&TaskPlacementPy::accept,"accept()"); + add_varargs_method("reject",&TaskPlacementPy::reject,"reject()"); + add_varargs_method("clicked",&TaskPlacementPy::clicked,"clicked()"); + add_varargs_method("open",&TaskPlacementPy::open,"open()"); + add_varargs_method("isAllowedAlterDocument",&TaskPlacementPy::isAllowedAlterDocument,"isAllowedAlterDocument()"); + add_varargs_method("isAllowedAlterView",&TaskPlacementPy::isAllowedAlterView,"isAllowedAlterView()"); + add_varargs_method("isAllowedAlterSelection",&TaskPlacementPy::isAllowedAlterSelection,"isAllowedAlterSelection()"); + add_varargs_method("getStandardButtons",&TaskPlacementPy::getStandardButtons,"getStandardButtons()"); + // clang-format on +} + +PyObject* TaskPlacementPy::PyMake(struct _typeobject * type, PyObject * args, PyObject * kwds) +{ + Q_UNUSED(type) + Q_UNUSED(kwds) + if (!PyArg_ParseTuple(args, "")) { + return nullptr; + } + return new TaskPlacementPy(); +} + +TaskPlacementPy::TaskPlacementPy() + : widget{new Placement} +{ +} + +TaskPlacementPy::~TaskPlacementPy() = default; + +Py::Object TaskPlacementPy::repr() +{ + return Py::String("TaskPlacement"); +} + +Py::Object TaskPlacementPy::getattr(const char * name) +{ + if (strcmp(name, "form") == 0) { + Gui::PythonWrapper wrap; + wrap.loadWidgetsModule(); + return wrap.fromQWidget(widget, "QDialog"); + } + return BaseType::getattr(name); +} + +int TaskPlacementPy::setattr(const char* name, const Py::Object& attr) +{ + if (strcmp(name, "form") == 0 && attr.isNone()) { + delete widget; + widget = nullptr; + return {}; + } + return BaseType::setattr(name, attr); +} + +Py::Object TaskPlacementPy::setPropertyName(const Py::Tuple& args) +{ + const char* propname {}; + if (!PyArg_ParseTuple(args.ptr(), "s", &propname)) { + throw Py::Exception(); + } + + if (widget) { + widget->setPropertyName(propname); + } + return Py::None(); +} + +Py::Object TaskPlacementPy::setPlacement(const Py::Tuple& args) +{ + PyObject* plm {}; + if (!PyArg_ParseTuple(args.ptr(), "O!", &Base::PlacementPy::Type, &plm)) { + throw Py::Exception(); + } + + if (widget) { + widget->setPlacement(*static_cast(plm)->getPlacementPtr()); + } + return Py::None(); +} + +Py::Object TaskPlacementPy::setSelection(const Py::Tuple& args) +{ + std::vector sel; + Py::Sequence list(args[0]); + + for (const auto& obj : list) { + if (PyObject_TypeCheck(obj.ptr(), &App::DocumentObjectPy::Type)) { + auto doc = static_cast(obj.ptr()); + sel.emplace_back(doc->getDocumentObjectPtr()); + } + } + + if (widget) { + widget->setSelection(sel); + } + return Py::None(); +} + +Py::Object TaskPlacementPy::bindObject(const Py::Tuple& args) +{ + if (!PyArg_ParseTuple(args.ptr(), "")) { + throw Py::Exception(); + } + + if (widget) { + widget->bindObject(); + } + return Py::None(); +} + +Py::Object TaskPlacementPy::showDefaultButtons(const Py::Tuple& args) +{ + if (widget) { + widget->showDefaultButtons(Py::Boolean(args[0])); + } + return Py::None(); +} + +Py::Object TaskPlacementPy::accept(const Py::Tuple& args) +{ + if (!PyArg_ParseTuple(args.ptr(), "")) { + throw Py::Exception(); + } + + bool res = true; + if (widget) { + widget->accept(); + res = widget->result() == QDialog::Accepted; + } + return Py::Boolean(res); +} + +Py::Object TaskPlacementPy::reject(const Py::Tuple& args) +{ + if (!PyArg_ParseTuple(args.ptr(), "")) { + throw Py::Exception(); + } + + bool res = true; + if (widget) { + widget->reject(); + res = widget->result() == QDialog::Rejected; + } + return Py::Boolean(res); +} + +Py::Object TaskPlacementPy::clicked(const Py::Tuple& args) +{ + int index {}; + if (!PyArg_ParseTuple(args.ptr(), "i", &index)) { + throw Py::Exception(); + } + + if (widget && index == QDialogButtonBox::Apply) { + widget->onApplyButtonClicked(); + } + return Py::None(); +} + +Py::Object TaskPlacementPy::open(const Py::Tuple& args) +{ + if (!PyArg_ParseTuple(args.ptr(), "")) { + throw Py::Exception(); + } + + if (widget) { + widget->open(); + } + return Py::None(); +} + +Py::Object TaskPlacementPy::isAllowedAlterDocument(const Py::Tuple& args) +{ + if (!PyArg_ParseTuple(args.ptr(), "")) { + throw Py::Exception(); + } + return Py::Boolean(true); +} + +Py::Object TaskPlacementPy::isAllowedAlterView(const Py::Tuple& args) +{ + if (!PyArg_ParseTuple(args.ptr(), "")) { + throw Py::Exception(); + } + return Py::Boolean(true); +} + +Py::Object TaskPlacementPy::isAllowedAlterSelection(const Py::Tuple& args) +{ + if (!PyArg_ParseTuple(args.ptr(), "")) { + throw Py::Exception(); + } + return Py::Boolean(true); +} + +Py::Object TaskPlacementPy::getStandardButtons(const Py::Tuple& args) +{ + if (!PyArg_ParseTuple(args.ptr(), "")) { + throw Py::Exception(); + } + auto buttons = QDialogButtonBox::Ok| + QDialogButtonBox::Cancel| + QDialogButtonBox::Apply; + return Py::Long(static_cast(buttons)); +} + #include "moc_Placement.cpp" diff --git a/src/Gui/Placement.h b/src/Gui/Placement.h index c59bd869e1..66fcf7ac3b 100644 --- a/src/Gui/Placement.h +++ b/src/Gui/Placement.h @@ -212,6 +212,41 @@ private: Placement* widget; }; +class TaskPlacementPy: public Py::PythonExtension +{ +public: + using BaseType = Py::PythonExtension; + static void init_type(); + + TaskPlacementPy(); + ~TaskPlacementPy() override; + + Py::Object repr() override; + Py::Object getattr(const char* name) override; + int setattr(const char* name, const Py::Object&) override; + + Py::Object setPropertyName(const Py::Tuple&); + Py::Object setPlacement(const Py::Tuple&); + Py::Object setSelection(const Py::Tuple&); + Py::Object bindObject(const Py::Tuple&); + + Py::Object showDefaultButtons(const Py::Tuple&); + Py::Object accept(const Py::Tuple&); + Py::Object reject(const Py::Tuple&); + Py::Object clicked(const Py::Tuple&); + Py::Object open(const Py::Tuple&); + Py::Object isAllowedAlterDocument(const Py::Tuple&); + Py::Object isAllowedAlterView(const Py::Tuple&); + Py::Object isAllowedAlterSelection(const Py::Tuple&); + Py::Object getStandardButtons(const Py::Tuple&); + +private: + static PyObject* PyMake(struct _typeobject*, PyObject*, PyObject*); + +private: + QPointer widget; +}; + } // namespace Dialog } // namespace Gui