Skip to content

Commit

Permalink
App: extend Document::findObject to allow to search by label
Browse files Browse the repository at this point in the history
  • Loading branch information
wwmayer committed Jun 27, 2020
1 parent 1f741aa commit 79e11ce
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 27 deletions.
24 changes: 20 additions & 4 deletions src/App/Document.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4546,15 +4546,31 @@ std::vector< DocumentObject* > Document::getObjectsWithExtension(const Base::Typ
}


std::vector<DocumentObject*> Document::findObjects(const Base::Type& typeId, const char* objname) const
std::vector<DocumentObject*> 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<DocumentObject*> Objects;
DocumentObject* found = nullptr;
for (std::vector<DocumentObject*>::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;
Expand Down
2 changes: 1 addition & 1 deletion src/App/Document.h
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ class AppExport Document : public App::PropertyContainer
std::vector<DocumentObject*> 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<DocumentObject*> getObjectsWithExtension(const Base::Type& typeId, bool derived = true) const;
std::vector<DocumentObject*> findObjects(const Base::Type& typeId, const char* objname) const;
std::vector<DocumentObject*> findObjects(const Base::Type& typeId, const char* objname, const char* label) const;
/// Returns an array with the correct types already.
template<typename T> inline std::vector<T*> getObjectsOfType() const;
int countObjectsOfType(const Base::Type& typeId) const;
Expand Down
8 changes: 4 additions & 4 deletions src/App/DocumentPy.xml
Original file line number Diff line number Diff line change
Expand Up @@ -158,11 +158,11 @@ object of this document.
NOTE: It's possible that several objects have the same label name.</UserDocu>
</Documentation>
</Methode>
<Methode Name="findObjects">
<Methode Name="findObjects" Keyword="true">
<Documentation>
<UserDocu>findObjects([string (type)], [string (name)]) -&gt; list
Return a list of objects that match the specified type and name.
Both parameters are optional.</UserDocu>
<UserDocu>findObjects([string (type)], [string (name)], [string (label)]) -&gt; list
Return a list of objects that match the specified type, name or label.
All parameters are optional.</UserDocu>
</Documentation>
</Methode>
<Methode Name="getLinksTo">
Expand Down
33 changes: 15 additions & 18 deletions src/App/DocumentPyImp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<DocumentObject*> 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;
Expand Down

0 comments on commit 79e11ce

Please sign in to comment.