diff --git a/Modules/QtWidgets/src/QmitkDataStorageTreeModel.cpp b/Modules/QtWidgets/src/QmitkDataStorageTreeModel.cpp index a429b81..460e2a8 100644 --- a/Modules/QtWidgets/src/QmitkDataStorageTreeModel.cpp +++ b/Modules/QtWidgets/src/QmitkDataStorageTreeModel.cpp @@ -143,7 +143,7 @@ Qt::DropActions QmitkDataStorageTreeModel::supportedDragActions() const } bool QmitkDataStorageTreeModel::dropMimeData(const QMimeData *data, - Qt::DropAction action, int /*row*/, int /*column*/, const QModelIndex &parent) + Qt::DropAction action, int row, int /*column*/, const QModelIndex &parent) { // Early exit, returning true, but not actually doing anything (ignoring data). if (action == Qt::IgnoreAction) @@ -161,25 +161,39 @@ bool QmitkDataStorageTreeModel::dropMimeData(const QMimeData *data, // First we extract a Qlist of TreeItem* pointers. QList listOfItemsToDrop = ToTreeItemPtrList(data); - // Retrieve the TreeItem* where we are dropping stuff, and its parent. + // Retrieve the TreeItem* where we are dropping stuff TreeItem* dropItem = this->TreeItemFromIndex(parent); - TreeItem* parentItem = dropItem->GetParent(); - // If item was dropped onto empty space, we select the root node - if(dropItem == m_Root) + TreeItem* parentOfDraggedItems = listOfItemsToDrop[0]->GetParent(); + bool draggedNodesAreSiblings = true; + QList::iterator diIter; + for (diIter = listOfItemsToDrop.begin() + 1; + diIter != listOfItemsToDrop.end(); + diIter++) { - parentItem = m_Root; + if (parentOfDraggedItems != (*diIter)->GetParent()) + { + draggedNodesAreSiblings = false; + break; + } } - // Dragging and Dropping is only allowed within the same parent, so use the first item in list to validate. - // (otherwise, you could have a derived image such as a segmentation, and assign it to another image). - // NOTE: We are assuming the input list is valid... i.e. when it was dragged, all the items had the same parent. + // Dragging and Dropping is only allowed within the same parent, i.e. the dragged nodes must have + // the same parent that must be the same as where we drop the items. + // (Otherwise, you could have a derived image such as a segmentation, and assign it to another image.) - if(listOfItemsToDrop[0] != dropItem && listOfItemsToDrop[0]->GetParent() == parentItem) + if (draggedNodesAreSiblings && dropItem == parentOfDraggedItems) { // Retrieve the index of where we are dropping stuff. - QModelIndex dropItemModelIndex = this->IndexFromTreeItem(dropItem); - QModelIndex parentModelIndex = this->IndexFromTreeItem(parentItem); + QModelIndex parentModelIndex = this->IndexFromTreeItem(parentOfDraggedItems); + + // Select the target index position, or put it at the end of the list. + if (row == -1) + { + row = dropItem->GetChildCount(); + } + + int dropIndex = row; // Iterate through the list of TreeItem (which may be at non-consecutive indexes). QList::iterator diIter; @@ -187,26 +201,27 @@ bool QmitkDataStorageTreeModel::dropMimeData(const QMimeData *data, diIter != listOfItemsToDrop.end(); diIter++) { + TreeItem* itemToDrop = *diIter; + if (itemToDrop->GetIndex() < row) + { + --dropIndex; + } // Here we assume that as you remove items, one at a time, that GetIndex() will be valid. - this->beginRemoveRows(parentModelIndex, (*diIter)->GetIndex(), (*diIter)->GetIndex()); - parentItem->RemoveChild(*diIter); + int itemToDropIndex = itemToDrop->GetIndex(); + this->beginRemoveRows(parentModelIndex, itemToDropIndex, itemToDropIndex); + parentOfDraggedItems->RemoveChild(itemToDrop); this->endRemoveRows(); } - // Select the target index position, or put it at the end of the list. - int dropIndex = dropItemModelIndex.row(); - - if (dropIndex == -1 || dropIndex > parentItem->GetChildCount()) - dropIndex = parentItem->GetChildCount(); - // Now insert items again at the drop item position - this->beginInsertRows(parentModelIndex, dropIndex, dropIndex + listOfItemsToDrop.size() - 1); + QModelIndex dropItemIndex = this->IndexFromTreeItem(dropItem); + this->beginInsertRows(dropItemIndex, dropIndex, dropIndex + listOfItemsToDrop.size() - 1); for (diIter = listOfItemsToDrop.begin(); diIter != listOfItemsToDrop.end(); diIter++) { - parentItem->InsertChild( (*diIter), dropIndex ); + dropItem->InsertChild((*diIter), dropIndex); dropIndex++; } this->endInsertRows(); @@ -529,7 +544,8 @@ void QmitkDataStorageTreeModel::RemoveNodeInternal( const mitk::DataNode* node ) QModelIndex parentIndex = this->IndexFromTreeItem(parentTreeItem); // emit beginRemoveRows event (QModelIndex is empty because we dont have a tree model) - this->beginRemoveRows(parentIndex, treeItem->GetIndex(), treeItem->GetIndex()); + int treeItemIndex = treeItem->GetIndex(); + this->beginRemoveRows(parentIndex, treeItemIndex, treeItemIndex); // remove node std::vector children = treeItem->GetChildren();