+ support of drag'n'drop for custom view provider

This commit is contained in:
wmayer 2015-11-03 16:21:51 +01:00
parent 06d3926603
commit 919d47015a
4 changed files with 315 additions and 0 deletions

View File

@ -304,6 +304,23 @@ RuntimeError::RuntimeError(const RuntimeError &inst)
// ---------------------------------------------------------
NotImplementedError::NotImplementedError(const char * sMessage)
: Exception(sMessage)
{
}
NotImplementedError::NotImplementedError(const std::string& sMessage)
: Exception(sMessage)
{
}
NotImplementedError::NotImplementedError(const NotImplementedError &inst)
: Exception(inst)
{
}
// ---------------------------------------------------------
DivisionByZeroError::DivisionByZeroError(const char * sMessage)
: Exception(sMessage)
{

View File

@ -270,6 +270,22 @@ public:
virtual ~RuntimeError() throw() {}
};
/**
* The NotImplementedError can be used to indicate that an invoked function is not implemented.
* @author Werner Mayer
*/
class BaseExport NotImplementedError : public Exception
{
public:
/// Construction
NotImplementedError(const char * sMessage);
NotImplementedError(const std::string& sMessage);
/// Construction
NotImplementedError(const NotImplementedError &inst);
/// Destruction
virtual ~NotImplementedError() throw() {}
};
/**
* The DivisionByZeroError can be used to indicate a division by zero.
* @author Werner Mayer

View File

@ -803,6 +803,198 @@ std::string ViewProviderPythonFeatureImp::setDisplayMode(const char* ModeName)
return ModeName;
}
ViewProviderPythonFeatureImp::ValueT
ViewProviderPythonFeatureImp::canDragObjects() const
{
// Run the onChanged method of the proxy object.
Base::PyGILStateLocker lock;
try {
App::Property* proxy = object->getPropertyByName("Proxy");
if (proxy && proxy->getTypeId() == App::PropertyPythonObject::getClassTypeId()) {
Py::Object vp = static_cast<App::PropertyPythonObject*>(proxy)->getValue();
if (vp.hasAttr(std::string("canDragObjects"))) {
Py::Callable method(vp.getAttr(std::string("canDragObjects")));
Py::Tuple args;
Py::Boolean ok(method.apply(args));
return static_cast<bool>(ok) ? Accepted : Rejected;
}
else {
return NotImplemented;
}
}
}
catch (Py::Exception&) {
Base::PyException e; // extract the Python error text
e.ReportException();
}
return Rejected;
}
ViewProviderPythonFeatureImp::ValueT
ViewProviderPythonFeatureImp::canDragObject(App::DocumentObject* obj) const
{
// Run the onChanged method of the proxy object.
Base::PyGILStateLocker lock;
try {
App::Property* proxy = object->getPropertyByName("Proxy");
if (proxy && proxy->getTypeId() == App::PropertyPythonObject::getClassTypeId()) {
Py::Object vp = static_cast<App::PropertyPythonObject*>(proxy)->getValue();
if (vp.hasAttr(std::string("canDragObject"))) {
Py::Callable method(vp.getAttr(std::string("canDragObject")));
Py::Tuple args(1);
args.setItem(0, Py::Object(obj->getPyObject(), true));
Py::Boolean ok(method.apply(args));
return static_cast<bool>(ok) ? Accepted : Rejected;
}
else {
return NotImplemented;
}
}
}
catch (Py::Exception&) {
Base::PyException e; // extract the Python error text
e.ReportException();
}
return Rejected;
}
ViewProviderPythonFeatureImp::ValueT
ViewProviderPythonFeatureImp::dragObject(App::DocumentObject* obj)
{
// Run the onChanged method of the proxy object.
Base::PyGILStateLocker lock;
try {
App::Property* proxy = object->getPropertyByName("Proxy");
if (proxy && proxy->getTypeId() == App::PropertyPythonObject::getClassTypeId()) {
Py::Object vp = static_cast<App::PropertyPythonObject*>(proxy)->getValue();
if (vp.hasAttr(std::string("dragObject"))) {
if (vp.hasAttr("__object__")) {
Py::Callable method(vp.getAttr(std::string("dragObject")));
Py::Tuple args(1);
args.setItem(0, Py::Object(obj->getPyObject(), true));
method.apply(args);
return Accepted;
}
else {
Py::Callable method(vp.getAttr(std::string("dragObject")));
Py::Tuple args(2);
args.setItem(0, Py::Object(object->getPyObject(), true));
args.setItem(1, Py::Object(obj->getPyObject(), true));
method.apply(args);
return Accepted;
}
}
else {
return NotImplemented;
}
}
}
catch (Py::Exception&) {
Base::PyException e; // extract the Python error text
e.ReportException();
}
return Rejected;
}
ViewProviderPythonFeatureImp::ValueT
ViewProviderPythonFeatureImp::canDropObjects() const
{
// Run the onChanged method of the proxy object.
Base::PyGILStateLocker lock;
try {
App::Property* proxy = object->getPropertyByName("Proxy");
if (proxy && proxy->getTypeId() == App::PropertyPythonObject::getClassTypeId()) {
Py::Object vp = static_cast<App::PropertyPythonObject*>(proxy)->getValue();
if (vp.hasAttr(std::string("canDropObjects"))) {
Py::Callable method(vp.getAttr(std::string("canDropObjects")));
Py::Tuple args;
Py::Boolean ok(method.apply(args));
return static_cast<bool>(ok) ? Accepted : Rejected;
}
else {
return NotImplemented;
}
}
}
catch (Py::Exception&) {
Base::PyException e; // extract the Python error text
e.ReportException();
}
return Rejected;
}
ViewProviderPythonFeatureImp::ValueT
ViewProviderPythonFeatureImp::canDropObject(App::DocumentObject* obj) const
{
// Run the onChanged method of the proxy object.
Base::PyGILStateLocker lock;
try {
App::Property* proxy = object->getPropertyByName("Proxy");
if (proxy && proxy->getTypeId() == App::PropertyPythonObject::getClassTypeId()) {
Py::Object vp = static_cast<App::PropertyPythonObject*>(proxy)->getValue();
if (vp.hasAttr(std::string("canDropObject"))) {
Py::Callable method(vp.getAttr(std::string("canDropObject")));
Py::Tuple args(1);
args.setItem(0, Py::Object(obj->getPyObject(), true));
Py::Boolean ok(method.apply(args));
return static_cast<bool>(ok) ? Accepted : Rejected;
}
else {
return NotImplemented;
}
}
}
catch (Py::Exception&) {
Base::PyException e; // extract the Python error text
e.ReportException();
}
return Rejected;
}
ViewProviderPythonFeatureImp::ValueT
ViewProviderPythonFeatureImp::dropObject(App::DocumentObject* obj)
{
// Run the onChanged method of the proxy object.
Base::PyGILStateLocker lock;
try {
App::Property* proxy = object->getPropertyByName("Proxy");
if (proxy && proxy->getTypeId() == App::PropertyPythonObject::getClassTypeId()) {
Py::Object vp = static_cast<App::PropertyPythonObject*>(proxy)->getValue();
if (vp.hasAttr(std::string("dropObject"))) {
if (vp.hasAttr("__object__")) {
Py::Callable method(vp.getAttr(std::string("dropObject")));
Py::Tuple args(1);
args.setItem(0, Py::Object(obj->getPyObject(), true));
method.apply(args);
return Accepted;
}
else {
Py::Callable method(vp.getAttr(std::string("dropObject")));
Py::Tuple args(2);
args.setItem(0, Py::Object(object->getPyObject(), true));
args.setItem(1, Py::Object(obj->getPyObject(), true));
method.apply(args);
return Accepted;
}
}
else {
return NotImplemented;
}
}
}
catch (Py::Exception&) {
Base::PyException e; // extract the Python error text
e.ReportException();
}
return Rejected;
}
// ---------------------------------------------------------
namespace Gui {

View File

@ -38,6 +38,12 @@ namespace Gui {
class GuiExport ViewProviderPythonFeatureImp
{
public:
enum ValueT {
NotImplemented = 0, // not handled
Accepted = 1, // handled and accepted
Rejected = 2 // handled and rejected
};
/// constructor.
ViewProviderPythonFeatureImp(ViewProviderDocumentObject*);
/// destructor.
@ -75,6 +81,22 @@ public:
std::string setDisplayMode(const char* ModeName);
//@}
/** @name Drag and drop */
//@{
/// Returns true if the view provider generally supports dragging objects
ValueT canDragObjects() const;
/// Check whether the object can be removed from the view provider by drag and drop
ValueT canDragObject(App::DocumentObject*) const;
/// Starts to drag the object
ValueT dragObject(App::DocumentObject*);
/// Returns true if the view provider generally accepts dropping of objects
ValueT canDropObjects() const;
/// Check whether the object can be dropped to the view provider by drag and drop
ValueT canDropObject(App::DocumentObject*) const;
/// If the dropped object type is accepted the object will be added as child
ValueT dropObject(App::DocumentObject*);
//@}
private:
ViewProviderDocumentObject* object;
};
@ -174,6 +196,74 @@ public:
}
//@}
/** @name Drag and drop */
//@{
/// Returns true if the view provider generally supports dragging objects
virtual bool canDragObjects() const {
switch (imp->canDragObjects()) {
case ViewProviderPythonFeatureImp::Accepted:
return true;
case ViewProviderPythonFeatureImp::Rejected:
return false;
default:
return ViewProviderT::canDragObjects();
}
}
/// Check whether the object can be removed from the view provider by drag and drop
virtual bool canDragObject(App::DocumentObject* obj) const {
switch (imp->canDragObject(obj)) {
case ViewProviderPythonFeatureImp::Accepted:
return true;
case ViewProviderPythonFeatureImp::Rejected:
return false;
default:
return ViewProviderT::canDragObject(obj);
}
}
/// Starts to drag the object
virtual void dragObject(App::DocumentObject* obj) {
switch (imp->dragObject(obj)) {
case ViewProviderPythonFeatureImp::Accepted:
case ViewProviderPythonFeatureImp::Rejected:
return;
default:
return ViewProviderT::dragObject(obj);
}
}
/// Returns true if the view provider generally accepts dropping of objects
virtual bool canDropObjects() const {
switch (imp->canDropObjects()) {
case ViewProviderPythonFeatureImp::Accepted:
return true;
case ViewProviderPythonFeatureImp::Rejected:
return false;
default:
return ViewProviderT::canDropObjects();
}
}
/// Check whether the object can be dropped to the view provider by drag and drop
virtual bool canDropObject(App::DocumentObject* obj) const {
switch (imp->canDropObject(obj)) {
case ViewProviderPythonFeatureImp::Accepted:
return true;
case ViewProviderPythonFeatureImp::Rejected:
return false;
default:
return ViewProviderT::canDropObject(obj);
}
}
/// If the dropped object type is accepted the object will be added as child
virtual void dropObject(App::DocumentObject* obj) {
switch (imp->dropObject(obj)) {
case ViewProviderPythonFeatureImp::Accepted:
case ViewProviderPythonFeatureImp::Rejected:
return;
default:
return ViewProviderT::dropObject(obj);
}
}
//@}
/** @name Display methods */
//@{
/// get the default display mode