qsimpledrag.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/gui/kernel/qsimpledrag.cpp
Source codeSwitch to Preprocessed file
LineSourceCount
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 QtGui module of the Qt Toolkit.-
7**-
8** $QT_BEGIN_LICENSE:LGPL21$-
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 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 or version 3 as published by the Free-
20** Software Foundation and appearing in the file LICENSE.LGPLv21 and-
21** LICENSE.LGPLv3 included in the packaging of this file. Please review the-
22** following information to ensure the GNU Lesser General Public License-
23** requirements will be met: https://www.gnu.org/licenses/lgpl.html and-
24** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.-
25**-
26** As a special exception, The Qt Company gives you certain additional-
27** rights. These rights are described in The Qt Company LGPL Exception-
28** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.-
29**-
30** $QT_END_LICENSE$-
31**-
32****************************************************************************/-
33-
34#include "qsimpledrag_p.h"-
35-
36#include "qbitmap.h"-
37#include "qdrag.h"-
38#include "qpixmap.h"-
39#include "qevent.h"-
40#include "qfile.h"-
41#include "qtextcodec.h"-
42#include "qguiapplication.h"-
43#include "qpoint.h"-
44#include "qbuffer.h"-
45#include "qimage.h"-
46#include "qregexp.h"-
47#include "qdir.h"-
48#include "qimagereader.h"-
49#include "qimagewriter.h"-
50-
51#include <QtCore/QEventLoop>-
52#include <QtCore/QDebug>-
53-
54#include <private/qguiapplication_p.h>-
55#include <private/qdnd_p.h>-
56-
57#include <private/qshapedpixmapdndwindow_p.h>-
58#include <private/qhighdpiscaling_p.h>-
59-
60QT_BEGIN_NAMESPACE-
61-
62#ifndef QT_NO_DRAGANDDROP-
63-
64static QWindow* topLevelAt(const QPoint &pos)-
65{-
66 QWindowList list = QGuiApplication::topLevelWindows();-
67 for (int i = list.count()-1; i >= 0; --i) {
i >= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
68 QWindow *w = list.at(i);-
69 if (w->isVisible() && w->geometry().contains(pos) && !qobject_cast<QShapedPixmapWindow*>(w))
w->isVisible()Description
TRUEnever evaluated
FALSEnever evaluated
w->geometry().contains(pos)Description
TRUEnever evaluated
FALSEnever evaluated
!qobject_cast<...mapWindow*>(w)Description
TRUEnever evaluated
FALSEnever evaluated
0
70 return w;
never executed: return w;
0
71 }
never executed: end of block
0
72 return 0;
never executed: return 0;
0
73}-
74-
75/*!-
76 \class QBasicDrag-
77 \brief QBasicDrag is a base class for implementing platform drag and drop.-
78 \since 5.0-
79 \internal-
80 \ingroup qpa-
81-
82 QBasicDrag implements QPlatformDrag::drag() by running a local event loop in which-
83 it tracks mouse movements and moves the drag icon (QShapedPixmapWindow) accordingly.-
84 It provides new virtuals allowing for querying whether the receiving window-
85 (within the Qt application or outside) accepts the drag and sets the state accordingly.-
86*/-
87-
88QBasicDrag::QBasicDrag() :-
89 m_restoreCursor(false), m_eventLoop(0),-
90 m_executed_drop_action(Qt::IgnoreAction), m_can_drop(false),-
91 m_drag(0), m_drag_icon_window(0), m_useCompositing(true),-
92 m_screen(Q_NULLPTR)-
93{-
94}
never executed: end of block
0
95-
96QBasicDrag::~QBasicDrag()-
97{-
98 delete m_drag_icon_window;-
99}
never executed: end of block
0
100-
101void QBasicDrag::enableEventFilter()-
102{-
103 qApp->installEventFilter(this);-
104}
never executed: end of block
0
105-
106void QBasicDrag::disableEventFilter()-
107{-
108 qApp->removeEventFilter(this);-
109}
never executed: end of block
0
110-
111-
112static inline QPoint getNativeMousePos(QEvent *e, QObject *o)-
113{-
114 return QHighDpi::toNativePixels(static_cast<QMouseEvent *>(e)->globalPos(), qobject_cast<QWindow*>(o));
never executed: return QHighDpi::toNativePixels(static_cast<QMouseEvent *>(e)->globalPos(), qobject_cast<QWindow*>(o));
0
115}-
116-
117bool QBasicDrag::eventFilter(QObject *o, QEvent *e)-
118{-
119 Q_UNUSED(o);-
120-
121 if (!m_drag) {
!m_dragDescription
TRUEnever evaluated
FALSEnever evaluated
0
122 if (e->type() == QEvent::KeyRelease && static_cast<QKeyEvent*>(e)->key() == Qt::Key_Escape) {
e->type() == Q...nt::KeyReleaseDescription
TRUEnever evaluated
FALSEnever evaluated
static_cast<QK...Qt::Key_EscapeDescription
TRUEnever evaluated
FALSEnever evaluated
0
123 disableEventFilter();-
124 exitDndEventLoop();-
125 return true; // block the key release
never executed: return true;
0
126 }-
127 return false;
never executed: return false;
0
128 }-
129-
130 switch (e->type()) {-
131 case QEvent::ShortcutOverride:
never executed: case QEvent::ShortcutOverride:
0
132 // prevent accelerators from firing while dragging-
133 e->accept();-
134 return true;
never executed: return true;
0
135-
136 case QEvent::KeyPress:
never executed: case QEvent::KeyPress:
0
137 case QEvent::KeyRelease:
never executed: case QEvent::KeyRelease:
0
138 {-
139 QKeyEvent *ke = static_cast<QKeyEvent *>(e);-
140 if (ke->key() == Qt::Key_Escape && e->type() == QEvent::KeyPress) {
ke->key() == Qt::Key_EscapeDescription
TRUEnever evaluated
FALSEnever evaluated
e->type() == QEvent::KeyPressDescription
TRUEnever evaluated
FALSEnever evaluated
0
141 cancel();-
142 disableEventFilter();-
143 exitDndEventLoop();-
144-
145 }
never executed: end of block
0
146 return true; // Eat all key events
never executed: return true;
0
147 }-
148-
149 case QEvent::MouseMove:
never executed: case QEvent::MouseMove:
0
150 {-
151 QPoint nativePosition = getNativeMousePos(e, o);-
152 move(nativePosition);-
153 return true; // Eat all mouse move events
never executed: return true;
0
154 }-
155 case QEvent::MouseButtonRelease:
never executed: case QEvent::MouseButtonRelease:
0
156 disableEventFilter();-
157 if (canDrop()) {
canDrop()Description
TRUEnever evaluated
FALSEnever evaluated
0
158 QPoint nativePosition = getNativeMousePos(e, o);-
159 drop(nativePosition);-
160 } else {
never executed: end of block
0
161 cancel();-
162 }
never executed: end of block
0
163 exitDndEventLoop();-
164 QCoreApplication::postEvent(o, new QMouseEvent(*static_cast<QMouseEvent *>(e)));-
165 return true; // defer mouse release events until drag event loop has returned
never executed: return true;
0
166 case QEvent::MouseButtonDblClick:
never executed: case QEvent::MouseButtonDblClick:
0
167 case QEvent::Wheel:
never executed: case QEvent::Wheel:
0
168 return true;
never executed: return true;
0
169 default:
never executed: default:
0
170 break;
never executed: break;
0
171 }-
172 return false;
never executed: return false;
0
173}-
174-
175Qt::DropAction QBasicDrag::drag(QDrag *o)-
176{-
177 m_drag = o;-
178 m_executed_drop_action = Qt::IgnoreAction;-
179 m_can_drop = false;-
180 m_restoreCursor = true;-
181#ifndef QT_NO_CURSOR-
182 qApp->setOverrideCursor(Qt::DragCopyCursor);-
183 updateCursor(m_executed_drop_action);-
184#endif-
185 startDrag();-
186 m_eventLoop = new QEventLoop;-
187 m_eventLoop->exec();-
188 delete m_eventLoop;-
189 m_eventLoop = 0;-
190 m_drag = 0;-
191 endDrag();-
192 return m_executed_drop_action;
never executed: return m_executed_drop_action;
0
193}-
194-
195void QBasicDrag::restoreCursor()-
196{-
197 if (m_restoreCursor) {
m_restoreCursorDescription
TRUEnever evaluated
FALSEnever evaluated
0
198#ifndef QT_NO_CURSOR-
199 QGuiApplication::restoreOverrideCursor();-
200#endif-
201 m_restoreCursor = false;-
202 }
never executed: end of block
0
203}
never executed: end of block
0
204-
205void QBasicDrag::startDrag()-
206{-
207 QPoint pos;-
208#ifndef QT_NO_CURSOR-
209 pos = QCursor::pos();-
210 if (pos.x() == int(qInf())) {
pos.x() == int(qInf())Description
TRUEnever evaluated
FALSEnever evaluated
0
211 // ### fixme: no mouse pos registered. Get pos from touch...-
212 pos = QPoint();-
213 }
never executed: end of block
0
214#endif-
215 recreateShapedPixmapWindow(m_screen, pos);-
216 enableEventFilter();-
217}
never executed: end of block
0
218-
219void QBasicDrag::endDrag()-
220{-
221}-
222-
223void QBasicDrag::recreateShapedPixmapWindow(QScreen *screen, const QPoint &pos)-
224{-
225 delete m_drag_icon_window;-
226 // ### TODO Check if its really necessary to have m_drag_icon_window-
227 // when QDrag is used without a pixmap - QDrag::setPixmap()-
228 m_drag_icon_window = new QShapedPixmapWindow(screen);-
229-
230 m_drag_icon_window->setUseCompositing(m_useCompositing);-
231 m_drag_icon_window->setPixmap(m_drag->pixmap());-
232 m_drag_icon_window->setHotspot(m_drag->hotSpot());-
233 m_drag_icon_window->updateGeometry(pos);-
234 m_drag_icon_window->setVisible(true);-
235}
never executed: end of block
0
236-
237void QBasicDrag::cancel()-
238{-
239 disableEventFilter();-
240 restoreCursor();-
241 m_drag_icon_window->setVisible(false);-
242}
never executed: end of block
0
243-
244/*!-
245 Move the drag label to \a globalPos, which is-
246 interpreted in device independent coordinates. Typically called from reimplementations of move().-
247 */-
248-
249void QBasicDrag::moveShapedPixmapWindow(const QPoint &globalPos)-
250{-
251 if (m_drag)
m_dragDescription
TRUEnever evaluated
FALSEnever evaluated
0
252 m_drag_icon_window->updateGeometry(globalPos);
never executed: m_drag_icon_window->updateGeometry(globalPos);
0
253}
never executed: end of block
0
254-
255void QBasicDrag::drop(const QPoint &)-
256{-
257 disableEventFilter();-
258 restoreCursor();-
259 m_drag_icon_window->setVisible(false);-
260}
never executed: end of block
0
261-
262void QBasicDrag::exitDndEventLoop()-
263{-
264 if (m_eventLoop && m_eventLoop->isRunning())
m_eventLoopDescription
TRUEnever evaluated
FALSEnever evaluated
m_eventLoop->isRunning()Description
TRUEnever evaluated
FALSEnever evaluated
0
265 m_eventLoop->exit();
never executed: m_eventLoop->exit();
0
266}
never executed: end of block
0
267-
268void QBasicDrag::updateCursor(Qt::DropAction action)-
269{-
270#ifndef QT_NO_CURSOR-
271 Qt::CursorShape cursorShape = Qt::ForbiddenCursor;-
272 if (canDrop()) {
canDrop()Description
TRUEnever evaluated
FALSEnever evaluated
0
273 switch (action) {-
274 case Qt::CopyAction:
never executed: case Qt::CopyAction:
0
275 cursorShape = Qt::DragCopyCursor;-
276 break;
never executed: break;
0
277 case Qt::LinkAction:
never executed: case Qt::LinkAction:
0
278 cursorShape = Qt::DragLinkCursor;-
279 break;
never executed: break;
0
280 default:
never executed: default:
0
281 cursorShape = Qt::DragMoveCursor;-
282 break;
never executed: break;
0
283 }-
284 }-
285-
286 QCursor *cursor = QGuiApplication::overrideCursor();-
287 QPixmap pixmap = m_drag->dragCursor(action);-
288 if (!cursor) {
!cursorDescription
TRUEnever evaluated
FALSEnever evaluated
0
289 QGuiApplication::changeOverrideCursor((pixmap.isNull()) ? QCursor(cursorShape) : QCursor(pixmap));-
290 } else {
never executed: end of block
0
291 if (!pixmap.isNull()) {
!pixmap.isNull()Description
TRUEnever evaluated
FALSEnever evaluated
0
292 if ((cursor->pixmap().cacheKey() != pixmap.cacheKey())) {
(cursor->pixma...ap.cacheKey())Description
TRUEnever evaluated
FALSEnever evaluated
0
293 QGuiApplication::changeOverrideCursor(QCursor(pixmap));-
294 }
never executed: end of block
0
295 } else {
never executed: end of block
0
296 if (cursorShape != cursor->shape()) {
cursorShape != cursor->shape()Description
TRUEnever evaluated
FALSEnever evaluated
0
297 QGuiApplication::changeOverrideCursor(QCursor(cursorShape));-
298 }
never executed: end of block
0
299 }
never executed: end of block
0
300 }-
301#endif-
302 updateAction(action);-
303}
never executed: end of block
0
304-
305/*!-
306 \class QSimpleDrag-
307 \brief QSimpleDrag implements QBasicDrag for Drag and Drop operations within the Qt Application itself.-
308 \since 5.0-
309 \internal-
310 \ingroup qpa-
311-
312 The class checks whether the receiving window is a window of the Qt application-
313 and sets the state accordingly. It does not take windows of other applications-
314 into account.-
315*/-
316-
317QSimpleDrag::QSimpleDrag() : m_current_window(0)-
318{-
319}
never executed: end of block
0
320-
321QMimeData *QSimpleDrag::platformDropData()-
322{-
323 if (drag())
drag()Description
TRUEnever evaluated
FALSEnever evaluated
0
324 return drag()->mimeData();
never executed: return drag()->mimeData();
0
325 return 0;
never executed: return 0;
0
326}-
327-
328void QSimpleDrag::startDrag()-
329{-
330 QBasicDrag::startDrag();-
331 m_current_window = topLevelAt(QCursor::pos());-
332 if (m_current_window) {
m_current_windowDescription
TRUEnever evaluated
FALSEnever evaluated
0
333 QPlatformDragQtResponse response = QWindowSystemInterface::handleDrag(m_current_window, drag()->mimeData(), QCursor::pos(), drag()->supportedActions());-
334 setCanDrop(response.isAccepted());-
335 updateCursor(response.acceptedAction());-
336 } else {
never executed: end of block
0
337 setCanDrop(false);-
338 updateCursor(Qt::IgnoreAction);-
339 }
never executed: end of block
0
340 setExecutedDropAction(Qt::IgnoreAction);-
341}
never executed: end of block
0
342-
343void QSimpleDrag::cancel()-
344{-
345 QBasicDrag::cancel();-
346 if (drag() && m_current_window) {
drag()Description
TRUEnever evaluated
FALSEnever evaluated
m_current_windowDescription
TRUEnever evaluated
FALSEnever evaluated
0
347 QWindowSystemInterface::handleDrag(m_current_window, 0, QPoint(), Qt::IgnoreAction);-
348 m_current_window = 0;-
349 }
never executed: end of block
0
350}
never executed: end of block
0
351-
352void QSimpleDrag::move(const QPoint &globalPos)-
353{-
354 //### not high-DPI aware-
355 moveShapedPixmapWindow(globalPos);-
356 QWindow *window = topLevelAt(globalPos);-
357 if (!window)
!windowDescription
TRUEnever evaluated
FALSEnever evaluated
0
358 return;
never executed: return;
0
359-
360 const QPoint pos = globalPos - window->geometry().topLeft();-
361 const QPlatformDragQtResponse qt_response =-
362 QWindowSystemInterface::handleDrag(window, drag()->mimeData(), pos, drag()->supportedActions());-
363-
364 updateCursor(qt_response.acceptedAction());-
365 setCanDrop(qt_response.isAccepted());-
366}
never executed: end of block
0
367-
368void QSimpleDrag::drop(const QPoint &globalPos)-
369{-
370 //### not high-DPI aware-
371-
372 QBasicDrag::drop(globalPos);-
373 QWindow *window = topLevelAt(globalPos);-
374 if (!window)
!windowDescription
TRUEnever evaluated
FALSEnever evaluated
0
375 return;
never executed: return;
0
376-
377 const QPoint pos = globalPos - window->geometry().topLeft();-
378 const QPlatformDropQtResponse response =-
379 QWindowSystemInterface::handleDrop(window, drag()->mimeData(),pos, drag()->supportedActions());-
380 if (response.isAccepted()) {
response.isAccepted()Description
TRUEnever evaluated
FALSEnever evaluated
0
381 setExecutedDropAction(response.acceptedAction());-
382 } else {
never executed: end of block
0
383 setExecutedDropAction(Qt::IgnoreAction);-
384 }
never executed: end of block
0
385}-
386-
387#endif // QT_NO_DRAGANDDROP-
388-
389QT_END_NAMESPACE-
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial 4.3.0-BETA-master-30-08-2018-4cb69e9