Skip to content

Commit

Permalink
+ Start drag and drop of view providers
Browse files Browse the repository at this point in the history
  • Loading branch information
wwmayer committed Mar 11, 2014
1 parent 1818d37 commit 38d55b5
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 45 deletions.
86 changes: 41 additions & 45 deletions src/Gui/Tree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -384,9 +384,10 @@ QMimeData * TreeWidget::mimeData (const QList<QTreeWidgetItem *> items) const
if (parent && parent->type() == TreeWidget::ObjectType) {
// fix issue #0001456
if (!items.contains(parent)) {
App::DocumentObject* par = static_cast<DocumentObjectItem *>(parent)->object()->getObject();
if (!par->getTypeId().isDerivedFrom(App::DocumentObjectGroup::getClassTypeId()))
Gui::ViewProvider* vp = static_cast<DocumentObjectItem *>(parent)->object();
if (!vp->canDragObjects()) {
return 0;
}
}
}
}
Expand Down Expand Up @@ -422,11 +423,12 @@ void TreeWidget::dragMoveEvent(QDragMoveEvent *event)
}
}
else if (targetitem->type() == TreeWidget::ObjectType) {
App::DocumentObject* grp = static_cast<DocumentObjectItem*>(targetitem)->
object()->getObject();
if (!grp->getTypeId().isDerivedFrom(App::DocumentObjectGroup::
getClassTypeId()))
Gui::ViewProviderDocumentObject* vp = static_cast<DocumentObjectItem*>(targetitem)->object();
if (!vp->canDropObjects()) {
event->ignore();
}

App::DocumentObject* grp = vp->getObject();
App::Document* doc = grp->getDocument();
QList<QModelIndex> idxs = selectedIndexes();
for (QList<QModelIndex>::Iterator it = idxs.begin(); it != idxs.end(); ++it) {
Expand All @@ -441,13 +443,24 @@ 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<App::DocumentObjectGroup*>(grp)->isChildOf(
static_cast<App::DocumentObjectGroup*>(obj))) {
event->ignore();
return;
}
}

std::vector<App::DocumentObject*> childs = vp->claimChildren();
if (std::find(childs.begin(), childs.end(), obj) != childs.end()) {
event->ignore();
return;
}
// End
}
}
else {
Expand Down Expand Up @@ -488,41 +501,29 @@ void TreeWidget::dropEvent(QDropEvent *event)

if (targetitem->type() == TreeWidget::ObjectType) {
// add object to group
App::DocumentObject* grp = static_cast<DocumentObjectItem*>(targetitem)
->object()->getObject();
if (!grp->getTypeId().isDerivedFrom(App::DocumentObjectGroup::getClassTypeId()))
return; // no group object
Gui::ViewProviderDocumentObject* vp = static_cast<DocumentObjectItem*>(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<QTreeWidgetItem*>::Iterator it = items.begin(); it != items.end(); ++it) {
Gui::ViewProviderDocumentObject* vpc = static_cast<DocumentObjectItem*>(*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<DocumentObjectItem*>(*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<DocumentObjectItem *>(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();
}
Expand All @@ -532,19 +533,14 @@ void TreeWidget::dropEvent(QDropEvent *event)
Gui::Document* gui = Gui::Application::Instance->getDocument(doc);
gui->openCommand("Move object");
for (QList<QTreeWidgetItem*>::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<DocumentObjectItem*>(*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<DocumentObjectItem*>(*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<DocumentObjectItem *>(parent)->object();
vpp->dragObject(obj);
}
}
gui->commitCommand();
Expand Down
12 changes: 12 additions & 0 deletions src/Gui/ViewProvider.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,18 @@ class GuiExport ViewProvider : public App::PropertyContainer
*/
virtual std::vector<App::DocumentObject*> claimChildren(void) const
{ return std::vector<App::DocumentObject*>(); }
/** 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 */
Expand Down
21 changes: 21 additions & 0 deletions src/Gui/ViewProviderDocumentObjectGroup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,11 +124,32 @@ std::vector<App::DocumentObject*> ViewProviderDocumentObjectGroup::claimChildren
return std::vector<App::DocumentObject*>(static_cast<App::DocumentObjectGroup*>(getObject())->Group.getValues());
}

bool ViewProviderDocumentObjectGroup::canDragObjects() const
{
return true;
}

void ViewProviderDocumentObjectGroup::dragObject(App::DocumentObject* obj)
{
static_cast<App::DocumentObjectGroup*>(getObject())->removeObject(obj);
}

bool ViewProviderDocumentObjectGroup::canDropObjects() const
{
return true;
}

void ViewProviderDocumentObjectGroup::dropObject(App::DocumentObject* obj)
{
static_cast<App::DocumentObjectGroup*>(getObject())->addObject(obj);
}

std::vector<std::string> ViewProviderDocumentObjectGroup::getDisplayModes(void) const
{
// empty
return std::vector<std::string>();
}

bool ViewProviderDocumentObjectGroup::onDelete(const std::vector<std::string> &)
{
Gui::Command::doCommand(Gui::Command::Doc,"App.getDocument(\"%s\").getObject(\"%s\").removeObjectsFromDocument()"
Expand Down
4 changes: 4 additions & 0 deletions src/Gui/ViewProviderDocumentObjectGroup.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ class GuiExport ViewProviderDocumentObjectGroup : public ViewProviderDocumentObj
virtual ~ViewProviderDocumentObjectGroup();

virtual std::vector<App::DocumentObject*> 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*);
Expand Down

0 comments on commit 38d55b5

Please sign in to comment.