1 /****************************************************************************
3 ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
6 ** This file is part of the QtGui module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
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 Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
40 ****************************************************************************/
43 #include "private/qguiapplication_p.h"
48 #ifndef QT_NO_DRAGANDDROP
56 \brief The QDrag class provides support for MIME-based drag and drop data
59 Drag and drop is an intuitive way for users to copy or move data around in an
60 application, and is used in many desktop environments as a mechanism for copying
61 data between applications. Drag and drop support in Qt is centered around the
62 QDrag class that handles most of the details of a drag and drop operation.
64 The data to be transferred by the drag and drop operation is contained in a
65 QMimeData object. This is specified with the setMimeData() function in the
68 \snippet dragging/mainwindow.cpp 1
70 Note that setMimeData() assigns ownership of the QMimeData object to the
71 QDrag object. The QDrag must be constructed on the heap with a parent QObject
72 to ensure that Qt can clean up after the drag and drop operation has been
75 A pixmap can be used to represent the data while the drag is in
76 progress, and will move with the cursor to the drop target. This
77 pixmap typically shows an icon that represents the MIME type of
78 the data being transferred, but any pixmap can be set with
79 setPixmap(). The cursor's hot spot can be given a position
80 relative to the top-left corner of the pixmap with the
81 setHotSpot() function. The following code positions the pixmap so
82 that the cursor's hot spot points to the center of its bottom
85 \snippet separations/finalwidget.cpp 2
87 \note On X11, the pixmap may not be able to keep up with the mouse
88 movements if the hot spot causes the pixmap to be displayed
89 directly under the cursor.
91 The source and target widgets can be found with source() and target().
92 These functions are often used to determine whether drag and drop operations
93 started and finished at the same widget, so that special behavior can be
96 QDrag only deals with the drag and drop operation itself. It is up to the
97 developer to decide when a drag operation begins, and how a QDrag object should
98 be constructed and used. For a given widget, it is often necessary to
99 reimplement \l{QWidget::mousePressEvent()}{mousePressEvent()} to determine
100 whether the user has pressed a mouse button, and reimplement
101 \l{QWidget::mouseMoveEvent()}{mouseMoveEvent()} to check whether a QDrag is
104 \sa {Drag and Drop}, QClipboard, QMimeData, QWindowsMime, QMacPasteboardMime,
105 {Draggable Icons Example}, {Draggable Text Example}, {Drop Site Example},
106 {Fridge Magnets Example}
110 Constructs a new drag object for the widget specified by \a dragSource.
112 QDrag::QDrag(QObject *dragSource)
113 : QObject(*new QDragPrivate, dragSource)
116 d->source = dragSource;
119 d->hotspot = QPoint(-10, -10);
120 d->executed_action = Qt::IgnoreAction;
121 d->supported_actions = Qt::IgnoreAction;
122 d->default_action = Qt::IgnoreAction;
126 Destroys the drag object.
135 Sets the data to be sent to the given MIME \a data. Ownership of the data is
136 transferred to the QDrag object.
138 void QDrag::setMimeData(QMimeData *data)
149 Returns the MIME data that is encapsulated by the drag object.
151 QMimeData *QDrag::mimeData() const
158 Sets \a pixmap as the pixmap used to represent the data in a drag
159 and drop operation. You can only set a pixmap before the drag is
162 void QDrag::setPixmap(const QPixmap &pixmap)
169 Returns the pixmap used to represent the data in a drag and drop operation.
171 QPixmap QDrag::pixmap() const
178 Sets the position of the hot spot relative to the top-left corner of the
179 pixmap used to the point specified by \a hotspot.
181 \b{Note:} on X11, the pixmap may not be able to keep up with the mouse
182 movements if the hot spot causes the pixmap to be displayed
183 directly under the cursor.
185 void QDrag::setHotSpot(const QPoint& hotspot)
188 d->hotspot = hotspot;
192 Returns the position of the hot spot relative to the top-left corner of the
195 QPoint QDrag::hotSpot() const
202 Returns the source of the drag object. This is the widget where the drag
203 and drop operation originated.
205 QObject *QDrag::source() const
212 Returns the target of the drag and drop operation. This is the widget where
213 the drag object was dropped.
215 QObject *QDrag::target() const
224 Starts the drag and drop operation and returns a value indicating the requested
225 drop action when it is completed. The drop actions that the user can choose
226 from are specified in \a supportedActions. The default proposed action will be selected
227 among the allowed actions in the following order: Move, Copy and Link.
229 \b{Note:} On Linux and Mac OS X, the drag and drop operation
230 can take some time, but this function does not block the event
231 loop. Other events are still delivered to the application while
232 the operation is performed. On Windows, the Qt event loop is
233 blocked during the operation.
236 Qt::DropAction QDrag::exec(Qt::DropActions supportedActions)
238 return exec(supportedActions, Qt::IgnoreAction);
244 Starts the drag and drop operation and returns a value indicating the requested
245 drop action when it is completed. The drop actions that the user can choose
246 from are specified in \a supportedActions.
248 The \a defaultDropAction determines which action will be proposed when the user performs a
249 drag without using modifier keys.
251 \b{Note:} On Linux and Mac OS X, the drag and drop operation
252 can take some time, but this function does not block the event
253 loop. Other events are still delivered to the application while
254 the operation is performed. On Windows, the Qt event loop is
255 blocked during the operation. However, QDrag::exec() on
256 Windows causes processEvents() to be called frequently to keep the GUI responsive.
257 If any loops or operations are called while a drag operation is active, it will block the drag operation.
260 Qt::DropAction QDrag::exec(Qt::DropActions supportedActions, Qt::DropAction defaultDropAction)
264 qWarning("QDrag: No mimedata set before starting the drag");
265 return d->executed_action;
267 Qt::DropAction transformedDefaultDropAction = Qt::IgnoreAction;
269 if (defaultDropAction == Qt::IgnoreAction) {
270 if (supportedActions & Qt::MoveAction) {
271 transformedDefaultDropAction = Qt::MoveAction;
272 } else if (supportedActions & Qt::CopyAction) {
273 transformedDefaultDropAction = Qt::CopyAction;
274 } else if (supportedActions & Qt::LinkAction) {
275 transformedDefaultDropAction = Qt::LinkAction;
278 transformedDefaultDropAction = defaultDropAction;
280 d->supported_actions = supportedActions;
281 d->default_action = transformedDefaultDropAction;
282 d->executed_action = QDragManager::self()->drag(this);
284 return d->executed_action;
290 \b{Note:} It is recommended to use exec() instead of this function.
292 Starts the drag and drop operation and returns a value indicating the requested
293 drop action when it is completed. The drop actions that the user can choose
294 from are specified in \a request. Qt::CopyAction is always allowed.
296 \b{Note:} Although the drag and drop operation can take some time, this function
297 does not block the event loop. Other events are still delivered to the application
298 while the operation is performed.
302 Qt::DropAction QDrag::start(Qt::DropActions request)
306 qWarning("QDrag: No mimedata set before starting the drag");
307 return d->executed_action;
309 d->supported_actions = request | Qt::CopyAction;
310 d->default_action = Qt::IgnoreAction;
311 d->executed_action = QDragManager::self()->drag(this);
312 return d->executed_action;
316 Sets the drag \a cursor for the \a action. This allows you
317 to override the default native cursors. To revert to using the
318 native cursor for \a action pass in a null QPixmap as \a cursor.
320 The \a action can only be CopyAction, MoveAction or LinkAction.
321 All other values of DropAction are ignored.
323 void QDrag::setDragCursor(const QPixmap &cursor, Qt::DropAction action)
326 if (action != Qt::CopyAction && action != Qt::MoveAction && action != Qt::LinkAction)
329 d->customCursors.remove(action);
331 d->customCursors[action] = cursor;
335 Returns the drag cursor for the \a action.
340 QPixmap QDrag::dragCursor(Qt::DropAction action) const
342 typedef QMap<Qt::DropAction, QPixmap>::const_iterator Iterator;
345 const Iterator it = d->customCursors.constFind(action);
346 if (it != d->customCursors.constEnd())
349 Qt::CursorShape shape = Qt::ForbiddenCursor;
352 shape = Qt::DragMoveCursor;
355 shape = Qt::DragCopyCursor;
358 shape = Qt::DragLinkCursor;
361 shape = Qt::ForbiddenCursor;
363 return QGuiApplicationPrivate::instance()->getPixmapCursor(shape);
367 Returns the set of possible drop actions for this drag operation.
369 \sa exec(), defaultAction()
371 Qt::DropActions QDrag::supportedActions() const
374 return d->supported_actions;
379 Returns the default proposed drop action for this drag operation.
381 \sa exec(), supportedActions()
383 Qt::DropAction QDrag::defaultAction() const
386 return d->default_action;
389 \fn void QDrag::actionChanged(Qt::DropAction action)
391 This signal is emitted when the \a action associated with the
398 \fn void QDrag::targetChanged(QObject *newTarget)
400 This signal is emitted when the target of the drag and drop
401 operation changes, with \a newTarget the new target.
403 \sa target(), actionChanged()
408 #endif // QT_NO_DRAGANDDROP