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 QtGui module of the Qt Toolkit.
7**
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 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 Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include "qplatformdrag.h"
41
42#include <QtGui/private/qdnd_p.h>
43#include <QtGui/QKeyEvent>
44#include <QtGui/QGuiApplication>
45#include <QtCore/QEventLoop>
46
47QT_BEGIN_NAMESPACE
48
49#ifdef QDND_DEBUG
50# include <QtCore/QDebug>
51#endif
52
53QPlatformDropQtResponse::QPlatformDropQtResponse(bool accepted, Qt::DropAction acceptedAction)
54 : m_accepted(accepted)
55 , m_accepted_action(acceptedAction)
56{
57}
58
59bool QPlatformDropQtResponse::isAccepted() const
60{
61 return m_accepted;
62}
63
64Qt::DropAction QPlatformDropQtResponse::acceptedAction() const
65{
66 return m_accepted_action;
67}
68
69QPlatformDragQtResponse::QPlatformDragQtResponse(bool accepted, Qt::DropAction acceptedAction, QRect answerRect)
70 : QPlatformDropQtResponse(accepted,acceptedAction)
71 , m_answer_rect(answerRect)
72{
73}
74
75QRect QPlatformDragQtResponse::answerRect() const
76{
77 return m_answer_rect;
78}
79
80class QPlatformDragPrivate {
81public:
82 QPlatformDragPrivate() : cursor_drop_action(Qt::IgnoreAction) {}
83
84 Qt::DropAction cursor_drop_action;
85};
86
87/*!
88 \class QPlatformDrag
89 \since 5.0
90 \internal
91 \preliminary
92 \ingroup qpa
93
94 \brief The QPlatformDrag class provides an abstraction for drag.
95 */
96QPlatformDrag::QPlatformDrag() : d_ptr(new QPlatformDragPrivate)
97{
98}
99
100QPlatformDrag::~QPlatformDrag()
101{
102 delete d_ptr;
103}
104
105QDrag *QPlatformDrag::currentDrag() const
106{
107 return QDragManager::self()->object();
108}
109
110Qt::DropAction QPlatformDrag::defaultAction(Qt::DropActions possibleActions,
111 Qt::KeyboardModifiers modifiers) const
112{
113#ifdef QDND_DEBUG
114 qDebug() << "QDragManager::defaultAction(Qt::DropActions possibleActions)\nkeyboard modifiers : " << modifiers;
115#endif
116
117 Qt::DropAction default_action = Qt::IgnoreAction;
118
119 if (currentDrag()) {
120 default_action = currentDrag()->defaultAction();
121 }
122
123
124 if (default_action == Qt::IgnoreAction) {
125 //This means that the drag was initiated by QDrag::start and we need to
126 //preserve the old behavior
127 default_action = Qt::CopyAction;
128 }
129
130 if (modifiers & Qt::ControlModifier && modifiers & Qt::ShiftModifier)
131 default_action = Qt::LinkAction;
132 else if (modifiers & Qt::ControlModifier)
133 default_action = Qt::CopyAction;
134 else if (modifiers & Qt::ShiftModifier)
135 default_action = Qt::MoveAction;
136 else if (modifiers & Qt::AltModifier)
137 default_action = Qt::LinkAction;
138
139#ifdef QDND_DEBUG
140 qDebug() << "possible actions : " << possibleActions;
141#endif
142
143 // Check if the action determined is allowed
144 if (!(possibleActions & default_action)) {
145 if (possibleActions & Qt::CopyAction)
146 default_action = Qt::CopyAction;
147 else if (possibleActions & Qt::MoveAction)
148 default_action = Qt::MoveAction;
149 else if (possibleActions & Qt::LinkAction)
150 default_action = Qt::LinkAction;
151 else
152 default_action = Qt::IgnoreAction;
153 }
154
155#ifdef QDND_DEBUG
156 qDebug() << "default action : " << default_action;
157#endif
158
159 return default_action;
160}
161
162/*!
163 \brief Cancels the currently active drag (only for drags of
164 the current application initiated by QPlatformDrag::drag()).
165
166 The default implementation does nothing.
167
168 \since 5.7
169 */
170
171void QPlatformDrag::cancelDrag()
172{
173 Q_UNIMPLEMENTED();
174}
175
176/*!
177 \brief Called to notify QDrag about changes of the current action.
178 */
179
180void QPlatformDrag::updateAction(Qt::DropAction action)
181{
182 Q_D(QPlatformDrag);
183 if (d->cursor_drop_action != action) {
184 d->cursor_drop_action = action;
185 emit currentDrag()->actionChanged(action);
186 }
187}
188
189static const char *const default_pm[] = {
190"13 9 3 1",
191". c None",
192" c #000000",
193"X c #FFFFFF",
194"X X X X X X X",
195" X X X X X X ",
196"X ......... X",
197" X.........X ",
198"X ......... X",
199" X.........X ",
200"X ......... X",
201" X X X X X X ",
202"X X X X X X X",
203};
204
205Q_GLOBAL_STATIC_WITH_ARGS(QPixmap,qt_drag_default_pixmap,(default_pm))
206
207QPixmap QPlatformDrag::defaultPixmap()
208{
209 return *qt_drag_default_pixmap();
210}
211
212/*!
213 \since 5.4
214 \brief Returns bool indicating whether QPlatformDrag takes ownership
215 and therefore responsibility of deleting the QDrag object passed in
216 from QPlatformDrag::drag. This can be useful on platforms where QDrag
217 object has to be kept around.
218 */
219bool QPlatformDrag::ownsDragObject() const
220{
221 return false;
222}
223
224QT_END_NAMESPACE
225