From 53844f7fe8f485a06962df5b8385a9c1f5e448dd Mon Sep 17 00:00:00 2001 From: marioalexis Date: Tue, 15 Aug 2023 09:39:22 -0300 Subject: [PATCH] Gui: Change SelectionFilterPy to new PyCXX extension type --- src/Gui/Application.cpp | 1 + src/Gui/CMakeLists.txt | 2 + src/Gui/Selection.cpp | 1 + src/Gui/SelectionFilter.cpp | 109 +------------------------- src/Gui/SelectionFilter.h | 32 +------- src/Gui/SelectionFilterPy.cpp | 143 ++++++++++++++++++++++++++++++++++ src/Gui/SelectionFilterPy.h | 63 +++++++++++++++ 7 files changed, 212 insertions(+), 139 deletions(-) create mode 100644 src/Gui/SelectionFilterPy.cpp create mode 100644 src/Gui/SelectionFilterPy.h diff --git a/src/Gui/Application.cpp b/src/Gui/Application.cpp index e511f3d35e..55832f4997 100644 --- a/src/Gui/Application.cpp +++ b/src/Gui/Application.cpp @@ -83,6 +83,7 @@ #include "MDIViewPy.h" #include "SoFCDB.h" #include "Selection.h" +#include "SelectionFilterPy.h" #include "SoFCOffscreenRenderer.h" #include "SplitView3DInventor.h" #include "TaskView/TaskView.h" diff --git a/src/Gui/CMakeLists.txt b/src/Gui/CMakeLists.txt index b41d0e7824..0b62b44fdc 100644 --- a/src/Gui/CMakeLists.txt +++ b/src/Gui/CMakeLists.txt @@ -1128,6 +1128,8 @@ SET(Selection_SRCS Selection.cpp SelectionFilter.h SelectionFilter.cpp + SelectionFilterPy.h + SelectionFilterPy.cpp SelectionFilter.y SelectionFilter.l SelectionObserverPython.cpp diff --git a/src/Gui/Selection.cpp b/src/Gui/Selection.cpp index 88444ab2dc..c8df935cd8 100644 --- a/src/Gui/Selection.cpp +++ b/src/Gui/Selection.cpp @@ -47,6 +47,7 @@ #include "MainWindow.h" #include "MDIView.h" #include "SelectionFilter.h" +#include "SelectionFilterPy.h" #include "SelectionObserverPython.h" #include "Tree.h" #include "ViewProviderDocumentObject.h" diff --git a/src/Gui/SelectionFilter.cpp b/src/Gui/SelectionFilter.cpp index 13f293bc3d..aa5ef36ea6 100644 --- a/src/Gui/SelectionFilter.cpp +++ b/src/Gui/SelectionFilter.cpp @@ -34,6 +34,7 @@ #include "Selection.h" #include "SelectionFilter.h" +#include "SelectionFilterPy.h" #include "SelectionObject.h" @@ -231,114 +232,6 @@ void SelectionFilter::addError(const char* e) Errors += '\n'; } -// ---------------------------------------------------------------------------- - -void SelectionFilterPy::init_type() -{ - behaviors().name("SelectionFilter"); - behaviors().doc("Filter for certain selection\n" - "Example strings are:\n" - "\"SELECT Part::Feature SUBELEMENT Edge\",\n" - "\"SELECT Part::Feature\", \n" - "\"SELECT Part::Feature COUNT 1..5\"\n"); - // you must have overwritten the virtual functions - behaviors().supportRepr(); - behaviors().supportGetattr(); - behaviors().supportSetattr(); - behaviors().set_tp_new(PyMake); - add_varargs_method("match",&SelectionFilterPy::match, - "Check if the current selection matches the filter"); - add_varargs_method("result",&SelectionFilterPy::result, - "If match() returns True then with result() you get a list of the matching objects"); - add_varargs_method("test",&SelectionFilterPy::test, - "test(Feature, SubName='')\n" - "Test if a given object is described in the filter.\n" - "If SubName is not empty the sub-element gets also tested."); - add_varargs_method("setFilter",&SelectionFilterPy::setFilter, - "Set a new selection filter"); -} - -PyObject *SelectionFilterPy::PyMake(struct _typeobject *, PyObject *args, PyObject *) -{ - char* str; - if (!PyArg_ParseTuple(args, "s",&str)) - return nullptr; - try { - SelectionFilter filter(str); - return new SelectionFilterPy(filter.getFilter()); - } - catch (const Base::Exception& e) { - PyErr_SetString(PyExc_SyntaxError, e.what()); - return nullptr; - } -} - -SelectionFilterPy::SelectionFilterPy(const std::string& s) - : filter(s) -{ -} - -SelectionFilterPy::~SelectionFilterPy() -{ -} - -Py::Object SelectionFilterPy::repr() -{ - std::string s; - std::ostringstream s_out; - s_out << "SelectionFilter"; - return Py::String(s_out.str()); -} - -Py::Object SelectionFilterPy::match(const Py::Tuple& args) -{ - if (!PyArg_ParseTuple(args.ptr(), "")) - throw Py::Exception(); - return Py::Boolean(filter.match()); -} - -Py::Object SelectionFilterPy::test(const Py::Tuple& args) -{ - PyObject * pcObj; - char* text=nullptr; - if (!PyArg_ParseTuple(args.ptr(), "O!|s",&(App::DocumentObjectPy::Type),&pcObj,&text)) - throw Py::Exception(); - - auto docObj = static_cast(pcObj); - - return Py::Boolean(filter.test(docObj->getDocumentObjectPtr(),text)); -} - -Py::Object SelectionFilterPy::result(const Py::Tuple&) -{ - Py::List list; - std::vector >::iterator it; - for (it = filter.Result.begin(); it != filter.Result.end(); ++it) { - std::vector::iterator jt; - Py::Tuple tuple(it->size()); - int index=0; - for (jt = it->begin(); jt != it->end(); ++jt) { - tuple[index++] = Py::asObject(jt->getPyObject()); - } - list.append(tuple); - } - return list; -} - -Py::Object SelectionFilterPy::setFilter(const Py::Tuple& args) -{ - char* text=nullptr; - if (!PyArg_ParseTuple(args.ptr(), "s",&text)) - throw Py::Exception(); - try { - filter.setFilter(text); - return Py::None(); - } - catch (const Base::Exception& e) { - throw Py::Exception(PyExc_SyntaxError, e.what()); - } -} - // === Parser & Scanner stuff =============================================== // include the Scanner and the Parser for the filter language diff --git a/src/Gui/SelectionFilter.h b/src/Gui/SelectionFilter.h index 7299c63d57..90d3430bb7 100644 --- a/src/Gui/SelectionFilter.h +++ b/src/Gui/SelectionFilter.h @@ -35,7 +35,7 @@ namespace App { namespace Gui { struct Node_Block; - + class SelectionFilterPy; /** Selection filter definition * This class builds up a type/count tree out of a string @@ -139,36 +139,6 @@ private: Py::Object gate; }; -/** - * Python binding for SelectionFilter class. - * \code - * filter=Gui.Selection.Filter("SELECT Part::Feature SUBELEMENT Edge") - * Gui.Selection.addSelectionGate(filter) - * \endcode - * @see SelectionFilter - * @author Werner Mayer - */ -class SelectionFilterPy : public Py::PythonExtension -{ -public: - SelectionFilter filter; - -public: - static void init_type(); // announce properties and methods - - explicit SelectionFilterPy(const std::string&); - ~SelectionFilterPy() override; - - Py::Object repr() override; - Py::Object match(const Py::Tuple&); - Py::Object result(const Py::Tuple&); - Py::Object test(const Py::Tuple&); - Py::Object setFilter(const Py::Tuple&); - -private: - static PyObject *PyMake(struct _typeobject *, PyObject *, PyObject *); -}; - /** * A Python wrapper around SelectionFilterPy to implement the SelectionGate interface * \code diff --git a/src/Gui/SelectionFilterPy.cpp b/src/Gui/SelectionFilterPy.cpp new file mode 100644 index 0000000000..230cc606a0 --- /dev/null +++ b/src/Gui/SelectionFilterPy.cpp @@ -0,0 +1,143 @@ +/*************************************************************************** + * Copyright (c) 2009 Jürgen Riegel * + * * + * 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 + +#include "SelectionFilterPy.h" + + +using namespace Gui; + +SelectionFilterPy::SelectionFilterPy(Py::PythonClassInstance* self, Py::Tuple& args, Py::Dict& kwds) + : Py::PythonClass::PythonClass(self, args, kwds), filter("") +{ + const char* str; + if (!PyArg_ParseTuple(args.ptr(), "s", &str)) { + throw Py::Exception(); + } + try { + filter = SelectionFilter(str); + } + catch (const Base::Exception& e) { + throw Py::Exception(PyExc_SyntaxError, e.what()); + } +} + +SelectionFilterPy::~SelectionFilterPy() +{ +} + +Py::Object SelectionFilterPy::repr() +{ + std::string s; + std::ostringstream s_out; + s_out << "SelectionFilter"; + return Py::String(s_out.str()); +} + +Py::Object SelectionFilterPy::match() +{ + return Py::Boolean(filter.match()); +} +PYCXX_NOARGS_METHOD_DECL(SelectionFilterPy, match) + +Py::Object SelectionFilterPy::test(const Py::Tuple& args) +{ + PyObject * pcObj; + char* text=nullptr; + if (!PyArg_ParseTuple(args.ptr(), "O!|s", + &(App::DocumentObjectPy::Type), &pcObj, &text)) { + throw Py::Exception(); + } + + auto docObj = static_cast(pcObj); + + return Py::Boolean(filter.test(docObj->getDocumentObjectPtr(),text)); +} +PYCXX_VARARGS_METHOD_DECL(SelectionFilterPy, test) + +Py::Object SelectionFilterPy::result() +{ + Py::List list; + for (const auto& vec : filter.Result) { + Py::Tuple tuple(vec.size()); + int index=0; + for (auto sel : vec) { + tuple[index++] = Py::asObject(sel.getPyObject()); + } + list.append(tuple); + } + + return list; +} +PYCXX_NOARGS_METHOD_DECL(SelectionFilterPy, result) + +Py::Object SelectionFilterPy::setFilter(const Py::Tuple& args) +{ + char* text=nullptr; + if (!PyArg_ParseTuple(args.ptr(), "s", &text)) { + throw Py::Exception(); + } + + try { + filter.setFilter(text); + return Py::None(); + } + catch (const Base::Exception& e) { + throw Py::Exception(PyExc_SyntaxError, e.what()); + } +} +PYCXX_VARARGS_METHOD_DECL(SelectionFilterPy, setFilter) + +Py::Object SelectionFilterPy::getFilter() +{ + return Py::String(filter.getFilter()); +} +PYCXX_NOARGS_METHOD_DECL(SelectionFilterPy, getFilter) + +void SelectionFilterPy::init_type() +{ + behaviors().name("Gui.SelectionFilter"); + behaviors().doc("Filter for certain selection\n" + "Example strings are:\n" + "\"SELECT Part::Feature SUBELEMENT Edge\",\n" + "\"SELECT Part::Feature\", \n" + "\"SELECT Part::Feature COUNT 1..5\"\n"); + // you must have overwritten the virtual functions + behaviors().supportRepr(); + behaviors().supportGetattro(); + behaviors().supportSetattro(); + PYCXX_ADD_NOARGS_METHOD(match, match, + "Check if the current selection matches the filter"); + PYCXX_ADD_NOARGS_METHOD(result, result, + "If match() returns True then with result() you get a list of the matching objects"); + PYCXX_ADD_VARARGS_METHOD(test, test, + "test(Feature, SubName='')\n" + "Test if a given object is described in the filter.\n" + "If SubName is not empty the sub-element gets also tested."); + PYCXX_ADD_VARARGS_METHOD(setFilter, setFilter, + "Set a new selection filter from a string"); + PYCXX_ADD_NOARGS_METHOD(getFilter, getFilter, + "Get the selection filter string"); + + behaviors().readyType(); +} diff --git a/src/Gui/SelectionFilterPy.h b/src/Gui/SelectionFilterPy.h new file mode 100644 index 0000000000..d5edbc02e7 --- /dev/null +++ b/src/Gui/SelectionFilterPy.h @@ -0,0 +1,63 @@ +/*************************************************************************** + * Copyright (c) 2009 Jürgen Riegel * + * * + * 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_SELECTIONFILTERPY_H +#define GUI_SELECTIONFILTERPY_H + +#include + +#include "SelectionFilter.h" + + +namespace Gui { +/** + * Python binding for SelectionFilter class. + * \code + * filter=Gui.Selection.Filter("SELECT Part::Feature SUBELEMENT Edge") + * Gui.Selection.addSelectionGate(filter) + * \endcode + * @see SelectionFilter + * @author Werner Mayer + */ +class SelectionFilterPy : public Py::PythonClass +{ +public: + SelectionFilter filter; + +public: + static void init_type(); // announce properties and methods + + SelectionFilterPy(Py::PythonClassInstance* self, Py::Tuple& args, Py::Dict& kdws); + + ~SelectionFilterPy() override; + + Py::Object repr() override; + Py::Object match(); + Py::Object result(); + Py::Object test(const Py::Tuple&); + Py::Object setFilter(const Py::Tuple&); + Py::Object getFilter(); +}; + +} // namespace Gui + +#endif // GUI_SELECTIONFILTERPY_H