Results 1 to 15 of 15

Thread: Drag-n-Drop with cut and not copy

  1. #1
    Join Date
    Jan 2006
    Location
    Scandinavia
    Posts
    62
    Thanks
    5
    Thanked 2 Times in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Drag-n-Drop with cut and not copy

    Hi,

    I would like to use QTextEdit with drag-n-drop but with CUT-n-PASTE and not the default COPY-n-PASTE.

    To do this I I subclassed QTextEdit and and re-implemented
    Qt Code:
    1. dragEnterEvent
    To copy to clipboard, switch view to plain text mode 
    and
    Qt Code:
    1. dropEvent(QDropEvent *event)
    To copy to clipboard, switch view to plain text mode 
    . However,. even though it now works with cut-n-paste the cursor is all screwed up.

    I.e. the cursor position is where I SELECTED the text and not where I dropped the text. IF I change that (setPosition, setTextCursor etc) I still end up with the problem that if I click somewhere on the document the 'ACTUAL' cursor moves to where I click BUT it is invisible, the cursor symbol is where the cursor was BEFORE I clicked on the document....

    I COULD probably fix it by re-implementing more mouse events (mousePress, etc) but I think it should be possible to solve much easier.

    So my questions are
    1) Best way of getting cut-n-paste instead of copy-n-paste for drag-n-drop of text in a QTextEdit?

    2) If it IS by subclassing dragEnterEvent and dropEvent then how can I fix the cursor problem?


    See my code below for how it is implemented now
    Qt Code:
    1. void TextEdit::dragEnterEvent(QDragEnterEvent *e)
    2. {
    3. e->acceptProposedAction();
    4. }
    5.  
    6.  
    7. void TextEdit::dropEvent(QDropEvent *event)
    8. {
    9. event->acceptProposedAction();
    10.  
    11. if ( event->dropAction() == Qt::CopyAction)
    12. {
    13.  
    14.  
    15. QTextCursor cursor = textCursor(); // copy of cursor
    16.  
    17. // Drop position cursor
    18. QTextCursor insertionCursor = cursorForPosition( event->pos() );
    19.  
    20. insertionCursor.beginEditBlock(); /* Start atomic operation (undo/redo) */
    21.  
    22. QTextDocumentFragment text = cursor.selection(); /* Extract text before removing selected area */
    23.  
    24. cursor.removeSelectedText(); /* Remove from original position */
    25. insertionCursor.insertFragment( text ); /* Insert dragged text/image/link */
    26.  
    27. // Tried with set setTextCursor here but that only moved the visible cursor
    28. // initially. Clicking on the document still gives an active invisible cursor
    29. // AND a non-active visible cursor symbol
    30.  
    31. insertionCursor.endEditBlock(); /* End atomic operation (undo/redo) */
    32. }
    33. }
    To copy to clipboard, switch view to plain text mode 

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,364
    Thanks
    3
    Thanked 5,012 Times in 4,791 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Drag-n-Drop with cut and not copy

    Try adding the following line at the end of your drop event:
    Qt Code:
    1. setTextCursor(insertionCursor);
    To copy to clipboard, switch view to plain text mode 

  3. #3
    Join Date
    Jan 2006
    Location
    Scandinavia
    Posts
    62
    Thanks
    5
    Thanked 2 Times in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Drag-n-Drop with cut and not copy

    Quote Originally Posted by wysota View Post
    Try adding the following line at the end of your drop event:
    Qt Code:
    1. setTextCursor(insertionCursor);
    To copy to clipboard, switch view to plain text mode 
    What happens then is that the active cursor gets to where the dropped text went (which is what I want), BUT if I click with the mouse on the text document the cursor symbol stays where it was while the invisible cursor (the active one) moves to where the mouse click went.
    - is this fuzzy or am I explaining it OK?

    What I want is of course them to be one and the same - but preferably w/out having to re-implement ALL mouseEvents

  4. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,364
    Thanks
    3
    Thanked 5,012 Times in 4,791 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Drag-n-Drop with cut and not copy

    Quote Originally Posted by KjellKod View Post
    - is this fuzzy or am I explaining it OK?
    I think J-P already stated in some other thread that he didn't understand it and I have to agree with him - I don't understand either...

    Which cursor does QTextEdit::textCursor() return?

  5. #5
    Join Date
    Jan 2006
    Location
    Scandinavia
    Posts
    62
    Thanks
    5
    Thanked 2 Times in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Drag-n-Drop with cut and not copy

    Quote Originally Posted by wysota View Post
    I think J-P already stated in some other thread that he didn't understand it and I have to agree with him - I don't understand either...

    Which cursor does QTextEdit::textCursor() return?
    Yeah. I know it's a little confusing - I think I read that thread too - as far as I could see other people had the same problem but I didn't find a solution for it.

    QTextEdit::textCursor() returns a copy of the actual cursor. So any changes to that cursor will NOT affect the 'active' cursor.

    I've attached a main.cpp file and my TextEdit I don't know if you have time to check it but if so the following steps would explain the problem
    1) write some text - whatever to play with
    2) select part of the text with the mouse - and do a drag-n-drop of that text to another section of the document
    3) You will see that (correctly) the cursor moved to the place where the text was dropped.
    4) Click on another location on the document - you will see that the curser symbol didn't move to the place where you clicked.
    5) Try pressing some keys on the keyboard - the letters will appear where you latest clicked with the mouse and NOT where the visible cursor symbol is.
    Attached Files Attached Files

  6. #6
    Join Date
    Jan 2006
    Location
    Scandinavia
    Posts
    62
    Thanks
    5
    Thanked 2 Times in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Drag-n-Drop with cut and not copy

    I noticed that I had made some minor changes to TextEdit in the zip file - compared to example above - it was for testing and doesn't affect the behaviour
    Last edited by KjellKod; 18th February 2007 at 08:44.

  7. #7
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,518 Times in 1,388 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: Drag-n-Drop with cut and not copy

    Ok, the example speaks for itself. Here's a workaround:
    Qt Code:
    1. void TextEdit::dropEvent(QDropEvent *event)
    2. {
    3. QDropEvent drop(event->pos(), Qt::MoveAction, event->mimeData(),
    4. event->mouseButtons(), Qt::ShiftModifier, event->type()); // <-- Qt::ShiftModifier is important
    5. QTextEdit::dropEvent(&drop);
    6. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by jacek; 18th February 2007 at 12:04. Reason: wrapped too long line
    J-P Nurmi

  8. The following user says thank you to jpn for this useful post:

    KjellKod (18th February 2007)

  9. #8
    Join Date
    Jan 2006
    Location
    Scandinavia
    Posts
    62
    Thanks
    5
    Thanked 2 Times in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Drag-n-Drop with cut and not copy

    That was a great workaround J-P ...
    Simply by making a new dropEvent and calling the parent. I WILL use that one!
    (Now why didn't I think of that )

    But I am still confused how the QTextCursor got all messed up - do you know?

  10. #9
    Join Date
    Jan 2006
    Location
    Scandinavia
    Posts
    62
    Thanks
    5
    Thanked 2 Times in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Drag-n-Drop with cut and not copy

    Quote Originally Posted by jpn View Post
    Qt Code:
    1. QDropEvent drop(event->pos(), Qt::MoveAction, event->mimeData(),
    2. event->mouseButtons(), Qt::ShiftModifier, event->type()); // <-- Qt::ShiftModifier is important
    3. }
    To copy to clipboard, switch view to plain text mode 
    Why is Qt::ShiftModifier important? Wouldn't it be better to use the actual modifiers for the event? I.e.
    Qt Code:
    1. event->keyboardModifiers()
    2. // instead of
    3. Qt::ShiftModifier
    To copy to clipboard, switch view to plain text mode 
    Last edited by jacek; 18th February 2007 at 12:04. Reason: wrapped too long line

  11. #10
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,518 Times in 1,388 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: Drag-n-Drop with cut and not copy

    Quote Originally Posted by KjellKod View Post
    But I am still confused how the QTextCursor got all messed up - do you know?
    If you have enough interest, you can further investigate the issue by comparing the original code of yours and QTextControlPrivate::dropEvent() in src/gui/text/qtextcontrol.cpp..
    J-P Nurmi

  12. #11
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,364
    Thanks
    3
    Thanked 5,012 Times in 4,791 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Drag-n-Drop with cut and not copy

    Quote Originally Posted by KjellKod View Post
    Wouldn't it be better to use the actual modifiers for the event? I.e.
    Qt Code:
    1. event->keyboardModifiers()
    2. // instead of
    3. Qt::ShiftModifier
    To copy to clipboard, switch view to plain text mode 
    The whole point of the "hack" is to make Shift the modifier. This will change the event to move instead of copy. If you use keyboardModifiers(), you might "inherit" some other modifier which would make it a link instead of move.

  13. #12
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,518 Times in 1,388 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: Drag-n-Drop with cut and not copy

    Quote Originally Posted by KjellKod View Post
    Why is Qt::ShiftModifier important? Wouldn't it be better to use the actual modifiers for the event? I.e.
    Qt Code:
    1. event->keyboardModifiers()
    2. // instead of
    3. Qt::ShiftModifier
    To copy to clipboard, switch view to plain text mode 
    It's important because the inner QTextControl ends up using QDropEvent::proposedAction(). The proposed action is determined by a private Qt class called QDragManager according to the modifiers (QDragManager::defaultAction() in src/gui/kernel/qdnd.cpp). I found all this out by simply debugging through the dropEvent() code.
    J-P Nurmi

  14. The following user says thank you to jpn for this useful post:

    KjellKod (18th February 2007)

  15. #13
    Join Date
    Jan 2006
    Location
    Scandinavia
    Posts
    62
    Thanks
    5
    Thanked 2 Times in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Drag-n-Drop with cut and not copy

    I see what you mean - the shift modifier makes it into cut-n-paste rather than copy-n-paste

    I've been a bit hesitant to look at Qt's code but I see now that when encountering problems like this that's definitely worthwhile

    Thanks again J-P.

  16. #14
    Join Date
    Jan 2006
    Location
    Scandinavia
    Posts
    62
    Thanks
    5
    Thanked 2 Times in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Drag-n-Drop with cut and not copy

    Quote Originally Posted by jpn View Post
    If you have enough interest, you can further investigate the issue by comparing the original code of yours and QTextControlPrivate::dropEvent() in src/gui/text/qtextcontrol.cpp..
    Now when I see the Trolls code I realize that I've tried to do exactly what they're doing. I belive that it is a bug in the Qt code since setting the cursor with
    Qt Code:
    1. setTextCursor
    To copy to clipboard, switch view to plain text mode 
    doesn't work.

  17. #15
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,518 Times in 1,388 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: Drag-n-Drop with cut and not copy

    Quote Originally Posted by KjellKod View Post
    I see what you mean - the shift modifier makes it into cut-n-paste rather than copy-n-paste
    Yep, exactly.

    I've been a bit hesitant to look at Qt's code but I see now that when encountering problems like this that's definitely worthwhile
    Please don't hesitate to do so, it's definitely the most powerful way to find out why something works like it does.

    The sources throughout Qt are pretty clean and understandable. However, one confusing thing when looking into the sources of Qt for the first time might be the usage of Pimpl. Whether it's a new concept or not, one gets quickly used to the way it's used in Qt.

    Thanks again J-P.
    No problem at all, happy hacking with Qt!
    J-P Nurmi

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.