Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Qt drag/drop: cannot move when copy is enabled (Ubuntu Gnome)

I'm implementing a view and a model where I want to support both moving items internally (by dragging), and copying items (by pressing Ctrl while dragging). I've done everything I need to do according to the instructions. I've set up the mime functions, I've implemented removeRows(), and flags(). The problem is when I drag, it defaults to a copy operation (I get the arrow cursor with a plus sign, and it indeed copies the item by creating a new one in the model).

The only difference I can see is this: If I return only Qt::MoveAction in supportedDropActions(), it only moves. If I return (Qt::CopyAction | Qt::MoveAction), it only copies.

Any ideas? I want it to work like files in Nautilus (Gnome) or Windows file Explorer: drag moves icons around, ctrl+drag copies them.

like image 899
Scott Avatar asked Nov 14 '22 02:11

Scott


1 Answers

I'm sorry I didn't follow up by answering this question when I found what I was doing wrong. The code that messed me up was in QAbstractItemView::startDrag():

if (d->defaultDropAction != Qt::IgnoreAction && (supportedActions & d->defaultDropAction))
        defaultDropAction = d->defaultDropAction;
    else if (supportedActions & Qt::CopyAction && dragDropMode() != QAbstractItemView::InternalMove)
        defaultDropAction = Qt::CopyAction;

The problem is I wasn't setting the defaultDropAction property on the widget as in setDefaultDropAction( Qt::MoveAction ); Therefore startDrag() was defaulting to CopyAction. If the defaultDropAction is Qt::MoveAction, then you can use the keyboard Ctrl to switch a drag in progress to a copy action, which is my desired behavior.

I love Qt, but there sure are a lot of confusing and somewhat intertwined properties related to drag/drop. It's easy to to not get the right combination of properties.

Bottom line: make sure to set the defaultDropAction to Qt::MoveAction.

like image 132
Scott Avatar answered Nov 15 '22 16:11

Scott