From d21cd009b1bd3daf90faefd1e55646c96a70bea9 Mon Sep 17 00:00:00 2001 From: wmayer Date: Sat, 27 Jun 2020 15:58:23 +0200 Subject: [PATCH] App: extend Document::findObject to allow to search by label --- src/App/Document.cpp | 24 ++++++++++++++++++++---- src/App/Document.h | 2 +- src/App/DocumentPy.xml | 8 ++++---- src/App/DocumentPyImp.cpp | 33 +++++++++++++++------------------ 4 files changed, 40 insertions(+), 27 deletions(-) diff --git a/src/App/Document.cpp b/src/App/Document.cpp index b1ab47a3ad..e05d83802d 100644 --- a/src/App/Document.cpp +++ b/src/App/Document.cpp @@ -4546,15 +4546,31 @@ std::vector< DocumentObject* > Document::getObjectsWithExtension(const Base::Typ } -std::vector Document::findObjects(const Base::Type& typeId, const char* objname) const +std::vector Document::findObjects(const Base::Type& typeId, const char* objname, const char* label) const { - boost::regex rx(objname); boost::cmatch what; + boost::regex rx_name, rx_label; + + if (objname) + rx_name.set_expression(objname); + + if (label) + rx_label.set_expression(label); + std::vector Objects; + DocumentObject* found = nullptr; for (std::vector::const_iterator it = d->objectArray.begin(); it != d->objectArray.end(); ++it) { if ((*it)->getTypeId().isDerivedFrom(typeId)) { - if (boost::regex_match((*it)->getNameInDocument(), what, rx)) - Objects.push_back(*it); + found = *it; + + if (!rx_name.empty() && !boost::regex_search((*it)->getNameInDocument(), what, rx_name)) + found = nullptr; + + if (!rx_label.empty() && !boost::regex_search((*it)->Label.getValue(), what, rx_label)) + found = nullptr; + + if (found) + Objects.push_back(found); } } return Objects; diff --git a/src/App/Document.h b/src/App/Document.h index 7b316ad1c6..5c38c1e56e 100644 --- a/src/App/Document.h +++ b/src/App/Document.h @@ -301,7 +301,7 @@ public: std::vector getObjectsOfType(const Base::Type& typeId) const; /// Returns all object with given extensions. If derived=true also all objects with extensions derived from the given one std::vector getObjectsWithExtension(const Base::Type& typeId, bool derived = true) const; - std::vector findObjects(const Base::Type& typeId, const char* objname) const; + std::vector findObjects(const Base::Type& typeId, const char* objname, const char* label) const; /// Returns an array with the correct types already. template inline std::vector getObjectsOfType() const; int countObjectsOfType(const Base::Type& typeId) const; diff --git a/src/App/DocumentPy.xml b/src/App/DocumentPy.xml index d49cbdf345..bc78129c91 100644 --- a/src/App/DocumentPy.xml +++ b/src/App/DocumentPy.xml @@ -158,11 +158,11 @@ object of this document. NOTE: It's possible that several objects have the same label name. - + - findObjects([string (type)], [string (name)]) -> list -Return a list of objects that match the specified type and name. -Both parameters are optional. + findObjects([string (type)], [string (name)], [string (label)]) -> list +Return a list of objects that match the specified type, name or label. +All parameters are optional. diff --git a/src/App/DocumentPyImp.cpp b/src/App/DocumentPyImp.cpp index 7f6762bb74..1835af5757 100644 --- a/src/App/DocumentPyImp.cpp +++ b/src/App/DocumentPyImp.cpp @@ -535,36 +535,33 @@ PyObject* DocumentPy::getObjectsByLabel(PyObject *args) return Py::new_reference_to(list); } -PyObject* DocumentPy::findObjects(PyObject *args) +PyObject* DocumentPy::findObjects(PyObject *args, PyObject *kwds) { - char *sType="App::DocumentObject", *sName=0; - if (!PyArg_ParseTuple(args, "|ss",&sType, &sName)) // convert args: Python->C - return NULL; // NULL triggers exception + const char *sType = "App::DocumentObject", *sName = nullptr, *sLabel = nullptr; + static char *kwlist[] = {"Type", "Name", "Label", nullptr}; + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|sss", + kwlist, &sType, &sName, &sLabel)) + return nullptr; Base::Type type = Base::Type::fromName(sType); if (type == Base::Type::badType()) { - PyErr_Format(Base::BaseExceptionFreeCADError, "'%s' is not a valid type", sType); - return NULL; + PyErr_Format(PyExc_TypeError, "'%s' is not a valid type", sType); + return nullptr; } if (!type.isDerivedFrom(App::DocumentObject::getClassTypeId())) { - PyErr_Format(Base::BaseExceptionFreeCADError, "Type '%s' does not inherit from 'App::DocumentObject'", sType); - return NULL; + PyErr_Format(PyExc_TypeError, "Type '%s' does not inherit from 'App::DocumentObject'", sType); + return nullptr; } std::vector res; - if (sName) { - try { - res = getDocumentPtr()->findObjects(type, sName); - } - catch (const boost::regex_error& e) { - PyErr_SetString(PyExc_RuntimeError, e.what()); - return 0; - } + try { + res = getDocumentPtr()->findObjects(type, sName, sLabel); } - else { - res = getDocumentPtr()->getObjectsOfType(type); + catch (const boost::regex_error& e) { + PyErr_SetString(PyExc_RuntimeError, e.what()); + return 0; } Py_ssize_t index=0;