diff --git a/src/Gui/Tree.cpp b/src/Gui/Tree.cpp index db89432cf..5fd80e626 100644 --- a/src/Gui/Tree.cpp +++ b/src/Gui/Tree.cpp @@ -428,6 +428,10 @@ void TreeWidget::dragMoveEvent(QDragMoveEvent *event) event->ignore(); } + QList children; + for (int i=0; ichildCount(); i++) + children << targetitem->child(i); + App::DocumentObject* grp = vp->getObject(); App::Document* doc = grp->getDocument(); QList idxs = selectedIndexes(); @@ -444,23 +448,19 @@ void TreeWidget::dragMoveEvent(QDragMoveEvent *event) 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))) { - event->ignore(); - return; - } - } - - std::vector childs = vp->claimChildren(); - if (std::find(childs.begin(), childs.end(), obj) != childs.end()) { + // To avoid a cylic dependency it must be made sure to not allow to + // drag'n'drop a tree item onto a child or grandchild item of it. + if (static_cast(targetitem)->isChildOfItem( + static_cast(item))) { + event->ignore(); + return; + } + + // if the item is already a child of the target item there is nothing to do + if (children.contains(item)) { event->ignore(); return; } - // End } } else { @@ -1314,6 +1314,23 @@ void DocumentObjectItem::setData (int column, int role, const QVariant & value) } } +bool DocumentObjectItem::isChildOfItem(DocumentObjectItem* item) +{ + int numChild = item->childCount(); + for (int i=0; ichild(i); + if (child == this) + return true; + if (child->type() == TreeWidget::ObjectType) { + DocumentObjectItem* obj = static_cast(child); + if (this->isChildOfItem(obj)) + return true; + } + } + + return false; +} + void DocumentObjectItem::slotChangeIcon() { previousStatus = -1; diff --git a/src/Gui/Tree.h b/src/Gui/Tree.h index f6ce2da66..3aea80ca8 100644 --- a/src/Gui/Tree.h +++ b/src/Gui/Tree.h @@ -182,6 +182,7 @@ public: void displayStatusInfo(); void setExpandedStatus(bool); void setData(int column, int role, const QVariant & value); + bool isChildOfItem(DocumentObjectItem*); protected: void slotChangeIcon();