If children can have children can have children ..., then you'll need to design a pair of recursive methods to 1) create the tree inside the mime data object from the source item and 2) restore the tree from the mime data after the drop.
For the first, you basically start at the source item and write its information to the stream, then recurse for each child, appending the child's information and then recursing into its children and appending their information, and so on until you reach bottom. You then recurse back up one level and handle the next child at that level until finally you have recursed back to the source item again. Your then have a mime data object that contains the tree and all of its sub-trees, rooted at the source item. For the recursive function, at a minimum you will need to pass in a pointer to the current tree item (source or child) as well as the data stream reference so you can append to it.
// This recursive method is called from the method that creates the mime data at the beginning of the drag. It is called with the
// source TreeItem and the writable QDataStream as arguments
{
// write info for current item to data stream
// ...
// Now do the same for each child of the current item. If no children, then the recursion stops going deeper here
for each childItem in pItem->children()
buildTree( childItem, ds );
// done at this level. Return and go up a level
}
// This recursive method is called from the method that creates the mime data at the beginning of the drag. It is called with the
// source TreeItem and the writable QDataStream as arguments
void buildTree( TreeItem * pItem, QDataStream & ds )
{
// write info for current item to data stream
// ...
// Now do the same for each child of the current item. If no children, then the recursion stops going deeper here
for each childItem in pItem->children()
buildTree( childItem, ds );
// done at this level. Return and go up a level
}
To copy to clipboard, switch view to plain text mode
To restore, you do the same thing - from the data stream, restore the source item, then recurse to restore the first child's tree, and so forth until you have rebuilt the copy of the tree from the data stream. Once again, your recursive function will have to pass the data stream reference and probably the current parent item for the children you are reading in.
// This method is initially called from the dropMimeData method after the data stream is opened.
// When the recursion finally returns to the dropMimeData method, the TreeItem pointer that is returned
// will contain the complete tree that was encoded in the mime data. It can then be inserted into
// the proper place in the tree where it was dropped.
{
TreeItem * thisItem = new TreeItem;
// restore thisItem's info from the stream, including the count of its children
// ...
// then for each child, restore its sub-tree
for ( auto nChild = 0; nChild < childCount; ++nChild )
{
TreeItem * pChild = restoreTree( ds );
if ( pChild != nullptr )
thisItem->appendChild( pChild );
}
return thisItem;
}
// This method is initially called from the dropMimeData method after the data stream is opened.
// When the recursion finally returns to the dropMimeData method, the TreeItem pointer that is returned
// will contain the complete tree that was encoded in the mime data. It can then be inserted into
// the proper place in the tree where it was dropped.
TreeItem * restoreTree( QDataStream & ds )
{
TreeItem * thisItem = new TreeItem;
// restore thisItem's info from the stream, including the count of its children
// ...
// then for each child, restore its sub-tree
for ( auto nChild = 0; nChild < childCount; ++nChild )
{
TreeItem * pChild = restoreTree( ds );
if ( pChild != nullptr )
thisItem->appendChild( pChild );
}
return thisItem;
}
To copy to clipboard, switch view to plain text mode
You will probably have to add some bookkeeping information to the data stream when you create it so you can rebuild the tree structure. For example, for each tree item, you might write out the count of its children so you know if you have to recurse or not. You might also want to assign an ID to each node of the tree and write that out along with the ID of that node's parent, if any. That way you have a sanity check you can use to determine if you are rebuilding the tree correctly.
Google "depth first tree traversal", "depth first search", or "depth first recursion" if you want to learn more.
Bookmarks