+ 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:
@@ -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.
|
// Run the execute method of the proxy object.
|
||||||
Base::PyGILStateLocker lock;
|
Base::PyGILStateLocker lock;
|
||||||
@@ -52,16 +56,24 @@ DocumentObjectExecReturn *FeaturePythonImp::execute()
|
|||||||
Property* proxy = object->getPropertyByName("Proxy");
|
Property* proxy = object->getPropertyByName("Proxy");
|
||||||
if (proxy && proxy->getTypeId() == PropertyPythonObject::getClassTypeId()) {
|
if (proxy && proxy->getTypeId() == PropertyPythonObject::getClassTypeId()) {
|
||||||
Py::Object feature = static_cast<PropertyPythonObject*>(proxy)->getValue();
|
Py::Object feature = static_cast<PropertyPythonObject*>(proxy)->getValue();
|
||||||
if (feature.hasAttr("__object__")) {
|
if (feature.hasAttr(std::string("execute"))) {
|
||||||
Py::Callable method(feature.getAttr(std::string("execute")));
|
if (feature.hasAttr("__object__")) {
|
||||||
Py::Tuple args;
|
Py::Callable method(feature.getAttr(std::string("execute")));
|
||||||
method.apply(args);
|
Py::Tuple args;
|
||||||
}
|
Py::Object res = method.apply(args);
|
||||||
else {
|
if (res.isBoolean() && !res.isTrue())
|
||||||
Py::Callable method(feature.getAttr(std::string("execute")));
|
return false;
|
||||||
Py::Tuple args(1);
|
return true;
|
||||||
args.setItem(0, Py::Object(object->getPyObject(), true));
|
}
|
||||||
method.apply(args);
|
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();
|
e.ReportException();
|
||||||
std::stringstream str;
|
std::stringstream str;
|
||||||
str << object->Label.getValue() << ": " << e.what();
|
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)
|
void FeaturePythonImp::onBeforeChange(const Property* prop)
|
||||||
@@ -175,5 +187,3 @@ template<> const char* App::GeometryPython::getViewProviderName(void) const {
|
|||||||
}
|
}
|
||||||
// explicit template instantiation
|
// explicit template instantiation
|
||||||
template class AppExport FeaturePythonT<GeoFeature>;
|
template class AppExport FeaturePythonT<GeoFeature>;
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ public:
|
|||||||
FeaturePythonImp(App::DocumentObject*);
|
FeaturePythonImp(App::DocumentObject*);
|
||||||
~FeaturePythonImp();
|
~FeaturePythonImp();
|
||||||
|
|
||||||
DocumentObjectExecReturn *execute();
|
bool execute();
|
||||||
void onBeforeChange(const Property* prop);
|
void onBeforeChange(const Property* prop);
|
||||||
void onChanged(const Property* prop);
|
void onChanged(const Property* prop);
|
||||||
PyObject *getPyObject(void);
|
PyObject *getPyObject(void);
|
||||||
@@ -84,7 +84,15 @@ public:
|
|||||||
}
|
}
|
||||||
/// recalculate the Feature
|
/// recalculate the Feature
|
||||||
virtual DocumentObjectExecReturn *execute(void) {
|
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
|
/// returns the type name of the ViewProvider
|
||||||
virtual const char* getViewProviderName(void) const {
|
virtual const char* getViewProviderName(void) const {
|
||||||
|
|||||||
@@ -85,12 +85,12 @@ PyMethodDef FeaturePythonPyT<FeaturePyT>::Methods[] = {
|
|||||||
{"addProperty",
|
{"addProperty",
|
||||||
(PyCFunction) staticCallback_addProperty,
|
(PyCFunction) staticCallback_addProperty,
|
||||||
METH_VARARGS,
|
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",
|
{"removeProperty",
|
||||||
(PyCFunction) staticCallback_removeProperty,
|
(PyCFunction) staticCallback_removeProperty,
|
||||||
METH_VARARGS,
|
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",
|
{"supportedProperties",
|
||||||
(PyCFunction) staticCallback_supportedProperties,
|
(PyCFunction) staticCallback_supportedProperties,
|
||||||
|
|||||||
@@ -49,6 +49,7 @@
|
|||||||
#include <boost/bind.hpp>
|
#include <boost/bind.hpp>
|
||||||
|
|
||||||
#include <App/Document.h>
|
#include <App/Document.h>
|
||||||
|
#include <App/FeaturePythonPyImp.h>
|
||||||
#include <Base/Writer.h>
|
#include <Base/Writer.h>
|
||||||
#include <Base/Reader.h>
|
#include <Base/Reader.h>
|
||||||
#include <Base/Tools.h>
|
#include <Base/Tools.h>
|
||||||
@@ -4016,6 +4017,13 @@ PROPERTY_SOURCE_TEMPLATE(Sketcher::SketchObjectPython, Sketcher::SketchObject)
|
|||||||
template<> const char* Sketcher::SketchObjectPython::getViewProviderName(void) const {
|
template<> const char* Sketcher::SketchObjectPython::getViewProviderName(void) const {
|
||||||
return "SketcherGui::ViewProviderPython";
|
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
|
/// @endcond
|
||||||
|
|
||||||
// explicit template instantiation
|
// explicit template instantiation
|
||||||
|
|||||||
Reference in New Issue
Block a user