+ 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:
wmayer 2015-10-21 00:22:40 +02:00
parent 169b2e356e
commit e7a3dc48e8
4 changed files with 45 additions and 19 deletions

View File

@ -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>; }

View File

@ -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 {

View File

@ -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,

View File

@ -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