From 38d55b540e72c0fe5c6fcf1458c6ad5167fe01c7 Mon Sep 17 00:00:00 2001 From: wmayer Date: Tue, 11 Mar 2014 17:36:17 +0100 Subject: [PATCH] + Start drag and drop of view providers --- src/Gui/Tree.cpp | 86 ++++++++++----------- src/Gui/ViewProvider.h | 12 +++ src/Gui/ViewProviderDocumentObjectGroup.cpp | 21 +++++ src/Gui/ViewProviderDocumentObjectGroup.h | 4 + 4 files changed, 78 insertions(+), 45 deletions(-) diff --git a/src/Gui/Tree.cpp b/src/Gui/Tree.cpp index 567e18b9de..db89432cfd 100644 --- a/src/Gui/Tree.cpp +++ b/src/Gui/Tree.cpp @@ -384,9 +384,10 @@ QMimeData * TreeWidget::mimeData (const QList items) const if (parent && parent->type() == TreeWidget::ObjectType) { // fix issue #0001456 if (!items.contains(parent)) { - App::DocumentObject* par = static_cast(parent)->object()->getObject(); - if (!par->getTypeId().isDerivedFrom(App::DocumentObjectGroup::getClassTypeId())) + Gui::ViewProvider* vp = static_cast(parent)->object(); + if (!vp->canDragObjects()) { return 0; + } } } } @@ -422,11 +423,12 @@ void TreeWidget::dragMoveEvent(QDragMoveEvent *event) } } else if (targetitem->type() == TreeWidget::ObjectType) { - App::DocumentObject* grp = static_cast(targetitem)-> - object()->getObject(); - if (!grp->getTypeId().isDerivedFrom(App::DocumentObjectGroup:: - getClassTypeId())) + Gui::ViewProviderDocumentObject* vp = static_cast(targetitem)->object(); + if (!vp->canDropObjects()) { event->ignore(); + } + + App::DocumentObject* grp = vp->getObject(); App::Document* doc = grp->getDocument(); QList idxs = selectedIndexes(); for (QList::Iterator it = idxs.begin(); it != idxs.end(); ++it) { @@ -441,6 +443,10 @@ void TreeWidget::dragMoveEvent(QDragMoveEvent *event) event->ignore(); return; } + + // Begin + // TODO: Implement a general way to check whether the target object is already a child of the dragged object. + // This is important to avoid a cyclic dependency!!! if (obj->getTypeId().isDerivedFrom(App::DocumentObjectGroup::getClassTypeId())) { if (static_cast(grp)->isChildOf( static_cast(obj))) { @@ -448,6 +454,13 @@ void TreeWidget::dragMoveEvent(QDragMoveEvent *event) return; } } + + std::vector childs = vp->claimChildren(); + if (std::find(childs.begin(), childs.end(), obj) != childs.end()) { + event->ignore(); + return; + } + // End } } else { @@ -488,41 +501,29 @@ void TreeWidget::dropEvent(QDropEvent *event) if (targetitem->type() == TreeWidget::ObjectType) { // add object to group - App::DocumentObject* grp = static_cast(targetitem) - ->object()->getObject(); - if (!grp->getTypeId().isDerivedFrom(App::DocumentObjectGroup::getClassTypeId())) - return; // no group object + Gui::ViewProviderDocumentObject* vp = static_cast(targetitem)->object(); + App::DocumentObject* grp = vp->getObject(); + if (!vp->canDropObjects()) { + return; // no group like object + } // Open command App::Document* doc = grp->getDocument(); Gui::Document* gui = Gui::Application::Instance->getDocument(doc); gui->openCommand("Move object"); for (QList::Iterator it = items.begin(); it != items.end(); ++it) { + Gui::ViewProviderDocumentObject* vpc = static_cast(*it)->object(); + App::DocumentObject* obj = vpc->getObject(); + + // does this have a parent object QTreeWidgetItem* parent = (*it)->parent(); - // get document object - App::DocumentObject* obj = static_cast(*it) - ->object()->getObject(); - App::DocumentObjectGroup* par = App::DocumentObjectGroup - ::getGroupOfObject(obj); - if (par) { - // allow an object to be in one group only - QString cmd; - cmd = QString::fromAscii("App.getDocument(\"%1\").getObject(\"%2\").removeObject(" - "App.getDocument(\"%1\").getObject(\"%3\"))") - .arg(QString::fromAscii(doc->getName())) - .arg(QString::fromAscii(par->getNameInDocument())) - .arg(QString::fromAscii(obj->getNameInDocument())); - Gui::Application::Instance->runPythonCode(cmd.toUtf8()); + if (parent && parent->type() == TreeWidget::ObjectType) { + Gui::ViewProvider* vpp = static_cast(parent)->object(); + vpp->dragObject(obj); } - // build Python command for execution - QString cmd; - cmd = QString::fromAscii("App.getDocument(\"%1\").getObject(\"%2\").addObject(" - "App.getDocument(\"%1\").getObject(\"%3\"))") - .arg(QString::fromAscii(doc->getName())) - .arg(QString::fromAscii(grp->getNameInDocument())) - .arg(QString::fromAscii(obj->getNameInDocument())); - Gui::Application::Instance->runPythonCode(cmd.toUtf8()); + // now add the object to the target object + vp->dropObject(obj); } gui->commitCommand(); } @@ -532,19 +533,14 @@ void TreeWidget::dropEvent(QDropEvent *event) Gui::Document* gui = Gui::Application::Instance->getDocument(doc); gui->openCommand("Move object"); for (QList::Iterator it = items.begin(); it != items.end(); ++it) { - // get document object - // there must be a group that references this object - App::DocumentObject* obj = static_cast(*it) - ->object()->getObject(); - App::DocumentObjectGroup* grp = App::DocumentObjectGroup - ::getGroupOfObject(obj); - if (grp) { - QString cmd = QString::fromAscii("App.getDocument(\"%1\").getObject(\"%2\").removeObject(" - "App.getDocument(\"%1\").getObject(\"%3\"))") - .arg(QString::fromAscii(doc->getName())) - .arg(QString::fromAscii(grp->getNameInDocument())) - .arg(QString::fromAscii(obj->getNameInDocument())); - Gui::Application::Instance->runPythonCode(cmd.toUtf8()); + Gui::ViewProviderDocumentObject* vpc = static_cast(*it)->object(); + App::DocumentObject* obj = vpc->getObject(); + + // does this have a parent object + QTreeWidgetItem* parent = (*it)->parent(); + if (parent && parent->type() == TreeWidget::ObjectType) { + Gui::ViewProvider* vpp = static_cast(parent)->object(); + vpp->dragObject(obj); } } gui->commitCommand(); diff --git a/src/Gui/ViewProvider.h b/src/Gui/ViewProvider.h index a1f3e5e1a7..75fa8dafda 100644 --- a/src/Gui/ViewProvider.h +++ b/src/Gui/ViewProvider.h @@ -148,6 +148,18 @@ public: */ virtual std::vector claimChildren(void) const { return std::vector(); } + /** Check whether children can be removed from the view provider by drag and drop */ + virtual bool canDragObjects() const + { return false; } + /** Remove a child from the view provider by drag and drop */ + virtual void dragObject(App::DocumentObject*) + { } + /** Check whether objects can be added to the view provider by drag and drop */ + virtual bool canDropObjects() const + { return false; } + /** Add an object to the view provider by drag and drop */ + virtual void dropObject(App::DocumentObject*) + { } //@} /** @name Signals of the view provider */ diff --git a/src/Gui/ViewProviderDocumentObjectGroup.cpp b/src/Gui/ViewProviderDocumentObjectGroup.cpp index 13b2be0f03..b9055a1121 100644 --- a/src/Gui/ViewProviderDocumentObjectGroup.cpp +++ b/src/Gui/ViewProviderDocumentObjectGroup.cpp @@ -124,11 +124,32 @@ std::vector ViewProviderDocumentObjectGroup::claimChildren return std::vector(static_cast(getObject())->Group.getValues()); } +bool ViewProviderDocumentObjectGroup::canDragObjects() const +{ + return true; +} + +void ViewProviderDocumentObjectGroup::dragObject(App::DocumentObject* obj) +{ + static_cast(getObject())->removeObject(obj); +} + +bool ViewProviderDocumentObjectGroup::canDropObjects() const +{ + return true; +} + +void ViewProviderDocumentObjectGroup::dropObject(App::DocumentObject* obj) +{ + static_cast(getObject())->addObject(obj); +} + std::vector ViewProviderDocumentObjectGroup::getDisplayModes(void) const { // empty return std::vector(); } + bool ViewProviderDocumentObjectGroup::onDelete(const std::vector &) { Gui::Command::doCommand(Gui::Command::Doc,"App.getDocument(\"%s\").getObject(\"%s\").removeObjectsFromDocument()" diff --git a/src/Gui/ViewProviderDocumentObjectGroup.h b/src/Gui/ViewProviderDocumentObjectGroup.h index aab9757509..5ba06eae98 100644 --- a/src/Gui/ViewProviderDocumentObjectGroup.h +++ b/src/Gui/ViewProviderDocumentObjectGroup.h @@ -41,6 +41,10 @@ public: virtual ~ViewProviderDocumentObjectGroup(); virtual std::vector claimChildren(void)const; + virtual bool canDragObjects() const; + virtual void dragObject(App::DocumentObject*); + virtual bool canDropObjects() const; + virtual void dropObject(App::DocumentObject*); void attach(App::DocumentObject *pcObject); void updateData(const App::Property*);