Let's say we have the following hierarchy:
+ A
|-- B
|-- D
|-- C
And let's say the user drags C onto B. Is it possible to have both nodes (including children) swapped as the result of that drag and drop operation?
+ A
|-- C
|-- B
|-- D
I've tried multiple approaches: from subclassing the item model (dropMimeData
, insertRows
, etc) to adjusting modes with setDragDropOverwriteMode
and DragDropMode::InternalMove
, to subclassing dropEvent(QDropEvent * e)
and nothing worked so far.
I've encountered the following techincal limitations:
QStandardItemModel::dropMimeData
andQTreeview::dropEvent
won't let you know the source index, they forward mime data, and there's no way to obtain the source's QModelIndex to perform the swapping.The
DragDropMode::InternalMove
andsetDragDropOverwriteMode
approach doesn't work as expected, the source node gets appended to the drop target node somehow, and the source node is removed. If you setDragDropMode::Copy
, the source node is preserved, but the target node isn't overwritten either.
A nudge in the right direction would be appreciated.
I've inspect source code of Qt and it turns out that to fetch source index you should use current selection. So override
QTreeview::dropEvent
and fetch current selection by calling selectedIndexes().Swap is not a problem. You have to just do move twice.
There is spatial method for that: QAbstractItemModel::moveRow (in threes you have only one column so moving row is ok). Here you have a answer with another solutions (for standard item model).
If you have own custom model you have to do it directly on your data and just emit proper signals about moving items.