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