PDA

View Full Version : Drag and Drop for tree model



frank100
1st December 2010, 15:43
Hi!

I have a custom tree view with drag/drop support.

Every node in the tree can have different types and descendants, hence some drops might be rejected.

The whole thing is already working because I reject invalid descendants within the setData() function of the model. However I would like to provide immediate visual feedback to the user changing the cursor drop icon.

The first solution I thought was implementing a custom dragMoveEvent() within the view which could retrieve constantly the cursor position and issue an Qt::IgnoreAction or Qt::CopyAction depending on the validity of the insertion. I do not like this because I would have to implement some model logic within the viewer. Since I have many node types I do not wish to define a new mimetype for everyone.

I am convinced there must be a more elegant solution based on MVC. Any ideas?

wysota
1st December 2010, 16:08
I didn't quite get that part about multiple mime types. Could you explain? dragMoveEvent() is in general the proper way to go but I'm afraid you misinterpreted something about how it should work.

frank100
6th December 2010, 11:25
I would like to come up with a design where the model decides which objects can be dropped.

I know that the dragMoveEvent() solution will work, but this way I will have to code into the View the logic for valid/invalid node combinations. I believe it would be "more MVC" if such logic could be coded into the Model

wysota
6th December 2010, 14:34
The view can ask the model for a list of mime-types or whatever else data you wish to decide upon that can be dropped on a particular model index through a custom role.

frank100
8th December 2010, 14:50
thanks! However my tree has something like 400 node types. In every other case having just one mimetype is OK. I thought it would be too much work definining one mimetype for every case.

Furthermore, as far as I know the view asks such list of mime-types only once, when drag mode is entered. The dragMoveEvent() can acept/deny drops depending on the node the cursor is floating.

Could I replicate the same functionality from the model in a more MVC way? I want the model to acept/reject a node drop (before drop happens) depending on the item the cursor is covering. With dragMoveEvent() the view takes that decision. Even if the mimeTypes() of my model supports 400 types, these should be different depending on where within the view the cursor is floating.

So far I have implemented a static member dropCompatible() in my model which I call from the dragMoveEvent(). In that case the model can decide if the dragged node can be droped into the selected one. But in such case my view can only support my model :-(

thanks for all!

wysota
8th December 2010, 19:21
thanks! However my tree has something like 400 node types. In every other case having just one mimetype is OK. I thought it would be too much work definining one mimetype for every case.
You don't have to use mime-types. And actually you probably shouldn't. A trivial solution to the problem is introduction of TypeRole and AcceptedTypeRole roles. FIrst would say "my type is T" and the second would say "I accept drags of type X, Y and Z". Then it's just a matter of checking whether T in {X, Y, Z} and accepting or rejecting the drop.