1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the documentation of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:FDL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Free Documentation License Usage
18** Alternatively, this file may be used under the terms of the GNU Free
19** Documentation License version 1.3 as published by the Free Software
20** Foundation and appearing in the file included in the packaging of
21** this file. Please review the following information to ensure
22** the GNU Free Documentation License version 1.3 requirements
23** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
24** $QT_END_LICENSE$
25**
26****************************************************************************/
27
28/*!
29    \page dnd.html
30    \title Drag and Drop
31    \brief An overview of the drag and drop system provided by Qt.
32
33    \ingroup qt-gui-concepts
34
35    Drag and drop provides a simple visual mechanism which users can use
36    to transfer information between and within applications. Drag
37    and drop is similar in function to the clipboard's cut and paste
38    mechanism.
39
40    \tableofcontents
41
42    This document describes the basic drag and drop mechanism and
43    outlines the approach used to enable it in custom controls. Drag
44    and drop operations are also supported by many of Qt's controls,
45    such as the item views and graphics view framework, as well as
46    editing controls for Qt Widgets and Qt Quick. More information
47    about item views and graphics view is available in
48    \l{Using drag and drop with item views} and \l{Graphics View
49    Framework}.
50
51    \section1 Drag and Drop Classes
52
53    These classes deal with drag and drop and the necessary mime type
54    encoding and decoding.
55
56    \annotatedlist draganddrop
57
58    \section1 Configuration
59
60    The QStyleHints object provides some properties that are related
61    to drag and drop operations:
62
63    \list
64    \li \l{QStyleHints::startDragTime()} describes the amount of time in
65       milliseconds that the user must hold down a mouse button over an
66       object before a drag will begin.
67    \li \l{QStyleHints::startDragDistance()} indicates how far the user has to
68       move the mouse while holding down a mouse button before the movement
69       will be interpreted as dragging.
70    \li \l{QStyleHints::startDragVelocity()} indicates how fast (in pixels/second)
71       the user has to move the mouse to start a drag. A value of \c 0 means
72       that there is no such limit.
73    \endlist
74
75    These quantities provide sensible default values that are compliant with
76    the underlying windowing system for you to use if you
77    provide drag and drop support in your controls.
78
79    \section1 Drag and Drop in Qt Quick
80
81    The rest of the document focuses mainly on how to implement drag and drop
82    in C++. For using drag and drop inside a Qt Quick scene, please read the
83    documentation for the Qt Quick \l{Drag}, \l{DragEvent}, and \l{DropArea} items,
84    as well as the \l {Qt Quick Examples - Drag and Drop}{Qt Quick Drag and Drop} examples.
85
86    \section1 Dragging
87
88    To start a drag, create a QDrag object, and call its
89    exec() function. In most applications, it is a good idea to begin a drag
90    and drop operation only after a mouse button has been pressed and the
91    cursor has been moved a certain distance. However, the simplest way to
92    enable dragging from a widget is to reimplement the widget's
93    \l{QWidget::mousePressEvent()}{mousePressEvent()} and start a drag
94    and drop operation:
95
96    \snippet dragging/mainwindow.cpp 0
97    \dots 8
98    \snippet dragging/mainwindow.cpp 2
99
100    Although the user may take some time to complete the dragging operation,
101    as far as the application is concerned the exec() function is a blocking
102    function that returns with \l{Qt::DropActions}{one of several values}.
103    These indicate how the operation ended, and are described in more detail
104    below.
105
106    Note that the exec() function does not block the main event loop.
107
108    For widgets that need to distinguish between mouse clicks and drags, it
109    is useful to reimplement the widget's
110    \l{QWidget::mousePressEvent()}{mousePressEvent()} function to record to
111    start position of the drag:
112
113    \snippet draganddrop/dragwidget.cpp 6
114
115    Later, in \l{QWidget::mouseMoveEvent()}{mouseMoveEvent()}, we can determine
116    whether a drag should begin, and construct a drag object to handle the
117    operation:
118
119    \snippet draganddrop/dragwidget.cpp 7
120    \dots
121    \snippet draganddrop/dragwidget.cpp 8
122
123    This particular approach uses the \l QPoint::manhattanLength() function
124    to get a rough estimate of the distance between where the mouse click
125    occurred and the current cursor position. This function trades accuracy
126    for speed, and is usually suitable for this purpose.
127
128    \section1 Dropping
129
130    To be able to receive media dropped on a widget, call
131    \l{QWidget::setAcceptDrops()}{setAcceptDrops(true)} for the widget,
132    and reimplement the \l{QWidget::dragEnterEvent()}{dragEnterEvent()} and
133    \l{QWidget::dropEvent()}{dropEvent()} event handler functions.
134
135    For example, the following code enables drop events in the constructor of
136    a QWidget subclass, making it possible to usefully implement drop event
137    handlers:
138
139    \snippet dropevents/window.cpp 0
140    \dots
141    \snippet dropevents/window.cpp 1
142    \snippet dropevents/window.cpp 2
143
144    The dragEnterEvent() function is typically used to inform Qt about the
145    types of data that the widget accepts.
146    You must reimplement this function if you want to receive either
147    QDragMoveEvent or QDropEvent in your reimplementations of
148    \l{QWidget::dragMoveEvent()}{dragMoveEvent()} and
149    \l{QWidget::dropEvent()}{dropEvent()}.
150
151    The following code shows how \l{QWidget::dragEnterEvent()}{dragEnterEvent()}
152    can be reimplemented to
153    tell the drag and drop system that we can only handle plain text:
154
155    \snippet dropevents/window.cpp 3
156
157    The \l{QWidget::dropEvent()}{dropEvent()} is used to unpack dropped data
158    and handle it in way that is suitable for your application.
159
160    In the following code, the text supplied in the event is passed to a
161    QTextBrowser and a QComboBox is filled with the list of MIME types that
162    are used to describe the data:
163
164    \snippet dropevents/window.cpp 4
165
166    In this case, we accept the proposed action without checking what it is.
167    In a real world application, it may be necessary to return from the
168    \l{QWidget::dropEvent()}{dropEvent()} function without accepting the
169    proposed action or handling
170    the data if the action is not relevant. For example, we may choose to
171    ignore Qt::LinkAction actions if we do not support
172    links to external sources in our application.
173
174    \section2 Overriding Proposed Actions
175
176    We may also ignore the proposed action, and perform some other action on
177    the data. To do this, we would call the event object's
178    \l{QDropEvent::setDropAction()}{setDropAction()} with the preferred
179    action from Qt::DropAction before calling \l{QEvent::}{accept()}.
180    This ensures that the replacement drop action is used instead of the
181    proposed action.
182
183    For more sophisticated applications, reimplementing
184    \l{QWidget::dragMoveEvent()}{dragMoveEvent()} and
185    \l{QWidget::dragLeaveEvent()}{dragLeaveEvent()} will let you make
186    certain parts of your widgets sensitive to drop events, and give you more
187    control over drag and drop in your application.
188
189    \section2 Subclassing Complex Widgets
190
191    Certain standard Qt widgets provide their own support for drag and drop.
192    When subclassing these widgets, it may be necessary to reimplement
193    \l{QWidget::dragMoveEvent()}{dragMoveEvent()} in addition to
194    \l{QWidget::dragEnterEvent()}{dragEnterEvent()} and
195    \l{QWidget::dropEvent()}{dropEvent()} to prevent the base class from
196    providing default drag and drop handling, and to handle any special
197    cases you are interested in.
198
199    \section1 Drag and Drop Actions
200
201    In the simplest case, the target of a drag and drop action receives a
202    copy of the data being dragged, and the source decides whether to
203    delete the original. This is described by the \c CopyAction action.
204    The target may also choose to handle other actions, specifically the
205    \c MoveAction and \c LinkAction actions. If the source calls
206    QDrag::exec(), and it returns \c MoveAction, the source is responsible
207    for deleting any original data if it chooses to do so. The QMimeData
208    and QDrag objects created by the source widget \e{should not be deleted}
209    - they will be destroyed by Qt. The target is responsible for taking
210    ownership of the data sent in the drag and drop operation; this is
211    usually done by keeping references to the data.
212
213    If the target understands the \c LinkAction action, it should
214    store its own reference to the original information; the source
215    does not need to perform any further processing on the data. The
216    most common use of drag and drop actions is when performing a
217    Move within the same widget; see the section on \l{Drop Actions}
218    for more information about this feature.
219
220    The other major use of drag actions is when using a reference type
221    such as text/uri-list, where the dragged data are actually references
222    to files or objects.
223
224    \section1 Adding New Drag and Drop Types
225
226    Drag and drop is not limited to text and images. Any type of information
227    can be transferred in a drag and drop operation. To drag information
228    between applications, the applications must be able to indicate to each
229    other which data formats they can accept and which they can produce.
230    This is achieved using
231    \l{http://www.rfc-editor.org/rfc/rfc1341.txt}{MIME types}. The QDrag
232    object constructed by the source contains a list of MIME types that it
233    uses to represent the data (ordered from most appropriate to least
234    appropriate), and the drop target uses one of these to access the data.
235    For common data types, the convenience functions handle the MIME types
236    used transparently but, for custom data types, it is necessary to
237    state them explicitly.
238
239    To implement drag and drop actions for a type of information that is
240    not covered by the QDrag convenience functions, the first and most
241    important step is to look for existing formats that are appropriate:
242    The Internet Assigned Numbers Authority (\l{http://www.iana.org}{IANA})
243    provides a
244    \l{http://www.iana.org/assignments/media-types/}{hierarchical
245    list of MIME media types} at the Information Sciences Institute
246    (\l{http://www.isi.edu}{ISI}).
247    Using standard MIME types maximizes the interoperability of
248    your application with other software now and in the future.
249
250    To support an additional media type, simply set the data in the QMimeData
251    object with the \l{QMimeData::setData()}{setData()} function, supplying
252    the full MIME type and a QByteArray containing the data in the appropriate
253    format. The following code takes a pixmap from a label and stores it
254    as a Portable Network Graphics (PNG) file in a QMimeData object:
255
256    \snippet separations/finalwidget.cpp 0
257
258    Of course, for this case we could have simply used
259    \l{QMimeData::setImageData()}{setImageData()} instead to supply image data
260    in a variety of formats:
261
262    \snippet separations/finalwidget.cpp 1
263
264    The QByteArray approach is still useful in this case because it provides
265    greater control over the amount of data stored in the QMimeData object.
266
267    Note that custom datatypes used in item views must be declared as
268    \l{QMetaObject}{meta objects} and that stream operators for them
269    must be implemented.
270
271    \section1 Drop Actions
272
273    In the clipboard model, the user can \e cut or \e copy the source
274    information, then later paste it. Similarly in the drag and drop
275    model, the user can drag a \e copy of the information or they can drag
276    the information itself to a new place (\e moving it). The
277    drag and drop model has an additional complication for the programmer:
278    The program doesn't know whether the user wants to cut or copy the
279    information until the operation is complete. This often makes no
280    difference when dragging information between applications, but within
281    an application it is important to check which drop action was used.
282
283    We can reimplement the mouseMoveEvent() for a widget, and start a drag
284    and drop operation with a combination of possible drop actions. For
285    example, we may want to ensure that dragging always moves objects in
286    the widget:
287
288    \snippet draganddrop/dragwidget.cpp 7
289    \dots
290    \snippet draganddrop/dragwidget.cpp 8
291
292    The action returned by the exec() function may default to a
293    \c CopyAction if the information is dropped into another application
294    but, if it is dropped in another widget in the same application, we
295    may obtain a different drop action.
296
297    The proposed drop actions can be filtered in a widget's dragMoveEvent()
298    function. However, it is possible to accept all proposed actions in
299    the dragEnterEvent() and let the user decide which they want to accept
300    later:
301
302    \snippet draganddrop/dragwidget.cpp 0
303
304    When a drop occurs in the widget, the dropEvent() handler function is
305    called, and we can deal with each possible action in turn. First, we
306    deal with drag and drop operations within the same widget:
307
308    \snippet draganddrop/dragwidget.cpp 1
309
310    In this case, we refuse to deal with move operations. Each type of drop
311    action that we accept is checked and dealt with accordingly:
312
313    \snippet draganddrop/dragwidget.cpp 2
314    \snippet draganddrop/dragwidget.cpp 3
315    \snippet draganddrop/dragwidget.cpp 4
316    \dots
317    \snippet draganddrop/dragwidget.cpp 5
318
319    Note that we checked for individual drop actions in the above code.
320    As mentioned above in the section on
321    \l{#Overriding Proposed Actions}{Overriding Proposed Actions}, it is
322    sometimes necessary to override the proposed drop action and choose a
323    different one from the selection of possible drop actions.
324    To do this, you need to check for the presence of each action in the value
325    supplied by the event's \l{QDropEvent::}{possibleActions()}, set the drop
326    action with \l{QDropEvent::}{setDropAction()}, and call
327    \l{QEvent::}{accept()}.
328
329    \section1 Drop Rectangles
330
331    The widget's dragMoveEvent() can be used to restrict drops to certain parts
332    of the widget by only accepting the proposed drop actions when the cursor
333    is within those areas. For example, the following code accepts any proposed
334    drop actions when the cursor is over a child widget (\c dropFrame):
335
336    \snippet droprectangle/window.cpp 0
337
338    The dragMoveEvent() can also be used if you need to give visual
339    feedback during a drag and drop operation, to scroll the window, or
340    whatever is appropriate.
341
342    \section1 The Clipboard
343
344    Applications can also communicate with each other by putting data on
345    the clipboard. To access this, you need to obtain a QClipboard object
346    from the QApplication object.
347
348    The QMimeData class is used to represent data that is transferred to and
349    from the clipboard. To put data on the clipboard, you can use the
350    setText(), setImage(), and setPixmap() convenience functions for common
351    data types. These functions are similar to those found in the QMimeData
352    class, except that they also take an additional argument that controls
353    where the data is stored: If \l{QClipboard::Mode}{Clipboard} is
354    specified, the data is placed on the clipboard; if
355    \l{QClipboard::Mode}{Selection} is specified, the data is placed in the
356    mouse selection (on X11 only). By default, data is put on the clipboard.
357
358    For example, we can copy the contents of a QLineEdit to the clipboard
359    with the following code:
360
361    \snippet ../widgets/widgets/charactermap/mainwindow.cpp 11
362
363    Data with different MIME types can also be put on the clipboard.
364    Construct a QMimeData object and set data with setData() function in
365    the way described in the previous section; this object can then be
366    put on the clipboard with the
367    \l{QClipboard::setMimeData()}{setMimeData()} function.
368
369    The QClipboard class can notify the application about changes to the
370    data it contains via its \l{QClipboard::dataChanged()}{dataChanged()}
371    signal. For example, we can monitor the clipboard by connecting this
372    signal to a slot in a widget:
373
374    \snippet clipboard/clipwindow.cpp 0
375
376    The slot connected to this signal can read the data on the clipboard
377    using one of the MIME types that can be used to represent it:
378
379    \snippet clipboard/clipwindow.cpp 1
380    \dots
381    \snippet clipboard/clipwindow.cpp 2
382
383    The \l{QClipboard::selectionChanged()}{selectionChanged()} signal can
384    be used on X11 to monitor the mouse selection.
385
386    \section1 Examples
387
388    \list
389    \li \l{draganddrop/draggableicons}{Draggable Icons}
390    \li \l{draganddrop/draggabletext}{Draggable Text}
391    \li \l{draganddrop/dropsite}{Drop Site}
392    \li \l{draganddrop/fridgemagnets}{Fridge Magnets}
393    \li \l{draganddrop/puzzle}{Drag and Drop Puzzle}
394    \endlist
395
396    \section1 Interoperating with Other Applications
397
398    On X11, the public \l{http://www.newplanetsoftware.com/xdnd/}{XDND
399    protocol} is used, while on Windows Qt uses the OLE standard, and
400    Qt for \macos uses the Cocoa Drag Manager. On X11, XDND uses MIME,
401    so no translation is necessary. The Qt API is the same regardless of
402    the platform. On Windows, MIME-aware applications can communicate by
403    using clipboard format names that are MIME types. Already some
404    Windows applications use MIME naming conventions for their
405    clipboard formats.
406
407    Custom classes for translating proprietary clipboard formats can be
408    registered by reimplementing QWinMime on Windows or
409    QMacPasteboardMime on \macos.
410
411*/
412