doc/src/frameworks-technologies/dnd.qdoc
changeset 0 1918ee327afb
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     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 */