+ Avoid cyclic dependency of tree items

This commit is contained in:
wmayer 2014-03-11 19:27:46 +01:00
parent fb8b88773a
commit f80419ad3f
2 changed files with 32 additions and 14 deletions

View File

@ -428,6 +428,10 @@ void TreeWidget::dragMoveEvent(QDragMoveEvent *event)
event->ignore(); event->ignore();
} }
QList<QTreeWidgetItem *> children;
for (int i=0; i<targetitem->childCount(); i++)
children << targetitem->child(i);
App::DocumentObject* grp = vp->getObject(); App::DocumentObject* grp = vp->getObject();
App::Document* doc = grp->getDocument(); App::Document* doc = grp->getDocument();
QList<QModelIndex> idxs = selectedIndexes(); QList<QModelIndex> idxs = selectedIndexes();
@ -444,23 +448,19 @@ void TreeWidget::dragMoveEvent(QDragMoveEvent *event)
return; return;
} }
// Begin // To avoid a cylic dependency it must be made sure to not allow to
// TODO: Implement a general way to check whether the target object is already a child of the dragged object. // drag'n'drop a tree item onto a child or grandchild item of it.
// This is important to avoid a cyclic dependency!!! if (static_cast<DocumentObjectItem*>(targetitem)->isChildOfItem(
if (obj->getTypeId().isDerivedFrom(App::DocumentObjectGroup::getClassTypeId())) { static_cast<DocumentObjectItem*>(item))) {
if (static_cast<App::DocumentObjectGroup*>(grp)->isChildOf(
static_cast<App::DocumentObjectGroup*>(obj))) {
event->ignore(); event->ignore();
return; return;
} }
}
std::vector<App::DocumentObject*> childs = vp->claimChildren(); // if the item is already a child of the target item there is nothing to do
if (std::find(childs.begin(), childs.end(), obj) != childs.end()) { if (children.contains(item)) {
event->ignore(); event->ignore();
return; return;
} }
// End
} }
} }
else { 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; i<numChild; i++) {
QTreeWidgetItem* child = item->child(i);
if (child == this)
return true;
if (child->type() == TreeWidget::ObjectType) {
DocumentObjectItem* obj = static_cast<DocumentObjectItem*>(child);
if (this->isChildOfItem(obj))
return true;
}
}
return false;
}
void DocumentObjectItem::slotChangeIcon() void DocumentObjectItem::slotChangeIcon()
{ {
previousStatus = -1; previousStatus = -1;

View File

@ -182,6 +182,7 @@ public:
void displayStatusInfo(); void displayStatusInfo();
void setExpandedStatus(bool); void setExpandedStatus(bool);
void setData(int column, int role, const QVariant & value); void setData(int column, int role, const QVariant & value);
bool isChildOfItem(DocumentObjectItem*);
protected: protected:
void slotChangeIcon(); void slotChangeIcon();