From 700c9a8a38b6f9febb2a0d8c7d71d4d292f15d3c Mon Sep 17 00:00:00 2001 From: Florian Foinant-Willig Date: Sun, 13 Apr 2025 14:20:43 +0200 Subject: [PATCH] Add `locked` keyword to ViewProvider::addProperty --- src/Gui/ViewProvider.pyi | 14 ++++--- src/Gui/ViewProviderPyImp.cpp | 69 +++++++++++++++++++++++------------ 2 files changed, 55 insertions(+), 28 deletions(-) diff --git a/src/Gui/ViewProvider.pyi b/src/Gui/ViewProvider.pyi index 46d8ec4e9e..939f463223 100644 --- a/src/Gui/ViewProvider.pyi +++ b/src/Gui/ViewProvider.pyi @@ -20,16 +20,18 @@ class ViewProvider(ExtensionContainer): def addProperty( self, + *, type: str, name: str, group: str, doc: str, attr: int = 0, - ro: bool = False, - hd: bool = False, + read_only: bool = False, + hidden: bool = False, + locked: bool = False, ) -> "ViewProvider": """ - addProperty(type, name, group, doc, attr=0, ro=False, hd=False) -> ViewProvider + addProperty(type, name, group, doc, attr=0, read_only=False, hidden=False, locked=False) -> ViewProvider Add a generic property. @@ -41,10 +43,12 @@ class ViewProvider(ExtensionContainer): Property group. Optional. attr : int Property attributes. - ro : bool + read_only : bool Read only property. - hd : bool + hidden : bool Hidden property. + locked : bool + Locked property. """ ... diff --git a/src/Gui/ViewProviderPyImp.cpp b/src/Gui/ViewProviderPyImp.cpp index 60200ebd79..340824e476 100644 --- a/src/Gui/ViewProviderPyImp.cpp +++ b/src/Gui/ViewProviderPyImp.cpp @@ -60,33 +60,56 @@ std::string ViewProviderPy::representation() const return ""; } -PyObject* ViewProviderPy::addProperty(PyObject *args) +PyObject* ViewProviderPy::addProperty(PyObject* args, PyObject* kwd) { - char *sType,*sName=nullptr,*sGroup=nullptr,*sDoc=nullptr; - short attr=0; - std::string sDocStr; - PyObject *ro = Py_False, *hd = Py_False; - if (!PyArg_ParseTuple(args, "s|ssethO!O!", &sType,&sName,&sGroup,"utf-8",&sDoc,&attr, - &PyBool_Type, &ro, &PyBool_Type, &hd)) + char *sType, *sName = nullptr, *sGroup = nullptr, *sDoc = nullptr; + short attr = 0; + PyObject *ro = Py_False, *hd = Py_False, *lk = Py_False; + PyObject* enumVals = nullptr; + const std::array kwlist {"type", + "name", + "group", + "doc", + "attr", + "read_only", + "hidden", + "locked", + "enum_vals", + nullptr}; + if (!Base::Wrapped_ParseTupleAndKeywords(args, + kwd, + "ss|sethO!O!O!O", + kwlist, + &sType, + &sName, + &sGroup, + "utf-8", + &sDoc, + &attr, + &PyBool_Type, + &ro, + &PyBool_Type, + &hd, + &PyBool_Type, + &lk, + &enumVals)) { return nullptr; - - if (sDoc) { - sDocStr = sDoc; - PyMem_Free(sDoc); } - App::Property* prop=nullptr; - try { - prop = getViewProviderPtr()->addDynamicProperty(sType,sName,sGroup,sDocStr.c_str(),attr, - Base::asBoolean(ro), Base::asBoolean(hd)); - } - catch (const Base::Exception& e) { - throw Py::RuntimeError(e.what()); - } - if (!prop) { - std::stringstream str; - str << "No property found of type '" << sType << "'" << std::ends; - throw Py::TypeError(str.str()); + App::Property* prop = getViewProviderPtr()->addDynamicProperty(sType, + sName, + sGroup, + sDoc, + attr, + Base::asBoolean(ro), + Base::asBoolean(hd)); + + prop->setStatus(App::Property::LockDynamic, Base::asBoolean(lk)); + + // enum support + auto* propEnum = freecad_cast(prop); + if (propEnum && enumVals) { + propEnum->setPyObject(enumVals); } return Py::new_reference_to(this);