+ support of Python feature classes without an execute() method
+ if execute() method of Python feature is missing or if it returns false call the execute() method of the C++ feature + fix SketchObjectPython
This commit is contained in:
parent
169b2e356e
commit
e7a3dc48e8
|
@ -44,7 +44,11 @@ FeaturePythonImp::~FeaturePythonImp()
|
|||
{
|
||||
}
|
||||
|
||||
DocumentObjectExecReturn *FeaturePythonImp::execute()
|
||||
/*!
|
||||
Calls the execute() method of the Python feature class. If the Python feature class doesn't have an execute()
|
||||
method or if it returns False this method also return false and true otherwise.
|
||||
*/
|
||||
bool FeaturePythonImp::execute()
|
||||
{
|
||||
// Run the execute method of the proxy object.
|
||||
Base::PyGILStateLocker lock;
|
||||
|
@ -52,16 +56,24 @@ DocumentObjectExecReturn *FeaturePythonImp::execute()
|
|||
Property* proxy = object->getPropertyByName("Proxy");
|
||||
if (proxy && proxy->getTypeId() == PropertyPythonObject::getClassTypeId()) {
|
||||
Py::Object feature = static_cast<PropertyPythonObject*>(proxy)->getValue();
|
||||
if (feature.hasAttr("__object__")) {
|
||||
Py::Callable method(feature.getAttr(std::string("execute")));
|
||||
Py::Tuple args;
|
||||
method.apply(args);
|
||||
}
|
||||
else {
|
||||
Py::Callable method(feature.getAttr(std::string("execute")));
|
||||
Py::Tuple args(1);
|
||||
args.setItem(0, Py::Object(object->getPyObject(), true));
|
||||
method.apply(args);
|
||||
if (feature.hasAttr(std::string("execute"))) {
|
||||
if (feature.hasAttr("__object__")) {
|
||||
Py::Callable method(feature.getAttr(std::string("execute")));
|
||||
Py::Tuple args;
|
||||
Py::Object res = method.apply(args);
|
||||
if (res.isBoolean() && !res.isTrue())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
Py::Callable method(feature.getAttr(std::string("execute")));
|
||||
Py::Tuple args(1);
|
||||
args.setItem(0, Py::Object(object->getPyObject(), true));
|
||||
Py::Object res = method.apply(args);
|
||||
if (res.isBoolean() && !res.isTrue())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -70,10 +82,10 @@ DocumentObjectExecReturn *FeaturePythonImp::execute()
|
|||
e.ReportException();
|
||||
std::stringstream str;
|
||||
str << object->Label.getValue() << ": " << e.what();
|
||||
return new App::DocumentObjectExecReturn(str.str());
|
||||
throw Base::RuntimeError(str.str());
|
||||
}
|
||||
|
||||
return DocumentObject::StdReturn;
|
||||
return false;
|
||||
}
|
||||
|
||||
void FeaturePythonImp::onBeforeChange(const Property* prop)
|
||||
|
@ -175,5 +187,3 @@ template<> const char* App::GeometryPython::getViewProviderName(void) const {
|
|||
}
|
||||
// explicit template instantiation
|
||||
template class AppExport FeaturePythonT<GeoFeature>;
}
|
||||
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ public:
|
|||
FeaturePythonImp(App::DocumentObject*);
|
||||
~FeaturePythonImp();
|
||||
|
||||
DocumentObjectExecReturn *execute();
|
||||
bool execute();
|
||||
void onBeforeChange(const Property* prop);
|
||||
void onChanged(const Property* prop);
|
||||
PyObject *getPyObject(void);
|
||||
|
@ -84,7 +84,15 @@ public:
|
|||
}
|
||||
/// recalculate the Feature
|
||||
virtual DocumentObjectExecReturn *execute(void) {
|
||||
return imp->execute();
|
||||
try {
|
||||
bool handled = imp->execute();
|
||||
if (!handled)
|
||||
return FeatureT::execute();
|
||||
}
|
||||
catch (const Base::Exception& e) {
|
||||
return new App::DocumentObjectExecReturn(e.what());
|
||||
}
|
||||
return DocumentObject::StdReturn;
|
||||
}
|
||||
/// returns the type name of the ViewProvider
|
||||
virtual const char* getViewProviderName(void) const {
|
||||
|
|
|
@ -85,12 +85,12 @@ PyMethodDef FeaturePythonPyT<FeaturePyT>::Methods[] = {
|
|||
{"addProperty",
|
||||
(PyCFunction) staticCallback_addProperty,
|
||||
METH_VARARGS,
|
||||
"addProperty(string, string) -- Add a generic property.\nThe first argument specifies the type, the second the\nname of the property.\n "
|
||||
"addProperty(string, string) -- Add a generic property.\nThe first argument specifies the type, the second the\nname of the property.\n"
|
||||
},
|
||||
{"removeProperty",
|
||||
(PyCFunction) staticCallback_removeProperty,
|
||||
METH_VARARGS,
|
||||
"removeProperty(string) -- Remove a generic property.\nNote, you can only remove user-defined properties but not built-in ones.\n "
|
||||
"removeProperty(string) -- Remove a generic property.\nNote, you can only remove user-defined properties but not built-in ones.\n"
|
||||
},
|
||||
{"supportedProperties",
|
||||
(PyCFunction) staticCallback_supportedProperties,
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#include <boost/bind.hpp>
|
||||
|
||||
#include <App/Document.h>
|
||||
#include <App/FeaturePythonPyImp.h>
|
||||
#include <Base/Writer.h>
|
||||
#include <Base/Reader.h>
|
||||
#include <Base/Tools.h>
|
||||
|
@ -4016,6 +4017,13 @@ PROPERTY_SOURCE_TEMPLATE(Sketcher::SketchObjectPython, Sketcher::SketchObject)
|
|||
template<> const char* Sketcher::SketchObjectPython::getViewProviderName(void) const {
|
||||
return "SketcherGui::ViewProviderPython";
|
||||
}
|
||||
template<> PyObject* Sketcher::SketchObjectPython::getPyObject(void) {
|
||||
if (PythonObject.is(Py::_None())) {
|
||||
// ref counter is set to 1
|
||||
PythonObject = Py::Object(new FeaturePythonPyT<SketchObjectPy>(this),true);
|
||||
}
|
||||
return Py::new_reference_to(PythonObject);
|
||||
}
|
||||
/// @endcond
|
||||
|
||||
// explicit template instantiation
|
||||
|
|
Loading…
Reference in New Issue
Block a user