~oif-team/ubuntu/natty/qt4-x11/xi2.1

« back to all changes in this revision

Viewing changes to doc/src/frameworks-technologies/dnd.qdoc

  • Committer: Bazaar Package Importer
  • Author(s): Alessandro Ghersi
  • Date: 2009-11-02 18:30:08 UTC
  • mfrom: (1.2.2 upstream)
  • mto: (15.2.5 experimental)
  • mto: This revision was merged to the branch mainline in revision 88.
  • Revision ID: james.westby@ubuntu.com-20091102183008-b6a4gcs128mvfb3m
Tags: upstream-4.6.0~beta1
ImportĀ upstreamĀ versionĀ 4.6.0~beta1

Show diffs side-by-side

added added

removed removed

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