From 1df7a6a50a794721edb1bc63d268378f4f0ed7c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Thu, 23 May 2013 12:44:20 +0200 Subject: Move QBasicDrag and QSimpleDrag to QtGui. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These are useful as default implementations of QPlatformIntegration::drag(), instead of having it return 0 which will lead to crashes in Qt Quick 2 and widgets applications that use drag and drop. Task-number: QTBUG-31288 Change-Id: I70efa139306ced5d879def0f74e3a72d3bcd64f7 Reviewed-by: Jørgen Lind --- src/gui/kernel/kernel.pri | 4 + src/gui/kernel/qplatformintegration.cpp | 7 +- src/gui/kernel/qshapedpixmapdndwindow.cpp | 106 ++++++ src/gui/kernel/qshapedpixmapdndwindow_p.h | 75 +++++ src/gui/kernel/qsimpledrag.cpp | 366 +++++++++++++++++++++ src/gui/kernel/qsimpledrag_p.h | 122 +++++++ src/platformsupport/dnd/dnd.pri | 6 - src/platformsupport/dnd/qshapedpixmapdndwindow.cpp | 106 ------ src/platformsupport/dnd/qshapedpixmapdndwindow_p.h | 75 ----- src/platformsupport/dnd/qsimpledrag.cpp | 366 --------------------- src/platformsupport/dnd/qsimpledrag_p.h | 122 ------- src/platformsupport/platformsupport.pro | 1 - src/plugins/platforms/cocoa/qcocoadrag.h | 2 +- src/plugins/platforms/qnx/qqnxintegration.cpp | 2 +- src/plugins/platforms/xcb/qxcbdrag.cpp | 4 +- src/plugins/platforms/xcb/qxcbdrag.h | 2 +- 16 files changed, 684 insertions(+), 682 deletions(-) create mode 100644 src/gui/kernel/qshapedpixmapdndwindow.cpp create mode 100644 src/gui/kernel/qshapedpixmapdndwindow_p.h create mode 100644 src/gui/kernel/qsimpledrag.cpp create mode 100644 src/gui/kernel/qsimpledrag_p.h delete mode 100644 src/platformsupport/dnd/dnd.pri delete mode 100644 src/platformsupport/dnd/qshapedpixmapdndwindow.cpp delete mode 100644 src/platformsupport/dnd/qshapedpixmapdndwindow_p.h delete mode 100644 src/platformsupport/dnd/qsimpledrag.cpp delete mode 100644 src/platformsupport/dnd/qsimpledrag_p.h (limited to 'src') diff --git a/src/gui/kernel/kernel.pri b/src/gui/kernel/kernel.pri index 91374fe2dd..3c019fc5b5 100644 --- a/src/gui/kernel/kernel.pri +++ b/src/gui/kernel/kernel.pri @@ -31,6 +31,8 @@ HEADERS += \ kernel/qplatformclipboard.h \ kernel/qplatformnativeinterface.h \ kernel/qplatformmenu.h \ + kernel/qshapedpixmapdndwindow_p.h \ + kernel/qsimpledrag_p.h \ kernel/qsurfaceformat.h \ kernel/qguiapplication.h \ kernel/qguiapplication_p.h \ @@ -89,6 +91,8 @@ SOURCES += \ kernel/qplatformclipboard.cpp \ kernel/qplatformnativeinterface.cpp \ kernel/qsessionmanager.cpp \ + kernel/qshapedpixmapdndwindow.cpp \ + kernel/qsimpledrag.cpp \ kernel/qsurfaceformat.cpp \ kernel/qguiapplication.cpp \ kernel/qwindow.cpp \ diff --git a/src/gui/kernel/qplatformintegration.cpp b/src/gui/kernel/qplatformintegration.cpp index e82e30df80..e4f45ebb6e 100644 --- a/src/gui/kernel/qplatformintegration.cpp +++ b/src/gui/kernel/qplatformintegration.cpp @@ -49,6 +49,7 @@ #include #include #include +#include QT_BEGIN_NAMESPACE @@ -99,7 +100,11 @@ QPlatformClipboard *QPlatformIntegration::clipboard() const */ QPlatformDrag *QPlatformIntegration::drag() const { - return 0; + static QSimpleDrag *drag = 0; + if (!drag) { + drag = new QSimpleDrag; + } + return drag; } #endif diff --git a/src/gui/kernel/qshapedpixmapdndwindow.cpp b/src/gui/kernel/qshapedpixmapdndwindow.cpp new file mode 100644 index 0000000000..b3e64b01d0 --- /dev/null +++ b/src/gui/kernel/qshapedpixmapdndwindow.cpp @@ -0,0 +1,106 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qshapedpixmapdndwindow_p.h" + +#include +#include + +QT_BEGIN_NAMESPACE + +QShapedPixmapWindow::QShapedPixmapWindow() + : QWindow(), + m_backingStore(0) +{ + QSurfaceFormat format; + format.setAlphaBufferSize(8); + setFormat(format); + setSurfaceType(RasterSurface); + setFlags(Qt::ToolTip | Qt::FramelessWindowHint | + Qt::X11BypassWindowManagerHint | Qt::WindowTransparentForInput); + create(); + m_backingStore = new QBackingStore(this); +} + +void QShapedPixmapWindow::render() +{ + QRect rect(QPoint(), geometry().size()); + + m_backingStore->beginPaint(rect); + + QPaintDevice *device = m_backingStore->paintDevice(); + + { + QPainter p(device); + p.setCompositionMode(QPainter::CompositionMode_Source); + p.drawPixmap(0, 0, m_pixmap); + } + + m_backingStore->endPaint(); + m_backingStore->flush(rect); +} + +void QShapedPixmapWindow::setPixmap(const QPixmap &pixmap) +{ + m_pixmap = pixmap; +} + +void QShapedPixmapWindow::setHotspot(const QPoint &hotspot) +{ + m_hotSpot = hotspot; +} + +void QShapedPixmapWindow::updateGeometry() +{ + QRect rect(QCursor::pos() - m_hotSpot, m_pixmap.size()); + if (m_pixmap.isNull()) + m_backingStore->resize(QSize(1,1)); + else if (m_backingStore->size() != m_pixmap.size()) + m_backingStore->resize(m_pixmap.size()); + setGeometry(rect); +} + +void QShapedPixmapWindow::exposeEvent(QExposeEvent *) +{ + render(); +} + +QT_END_NAMESPACE diff --git a/src/gui/kernel/qshapedpixmapdndwindow_p.h b/src/gui/kernel/qshapedpixmapdndwindow_p.h new file mode 100644 index 0000000000..20674b6b19 --- /dev/null +++ b/src/gui/kernel/qshapedpixmapdndwindow_p.h @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSHAPEDPIXMAPDNDWINDOW_H +#define QSHAPEDPIXMAPDNDWINDOW_H + +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class QShapedPixmapWindow : public QWindow +{ + Q_OBJECT +public: + QShapedPixmapWindow(); + + void render(); + + void setPixmap(const QPixmap &pixmap); + void setHotspot(const QPoint &hotspot); + + void updateGeometry(); + +protected: + void exposeEvent(QExposeEvent *); + +private: + QBackingStore *m_backingStore; + QPixmap m_pixmap; + QPoint m_hotSpot; +}; + +QT_END_NAMESPACE + +#endif // QSHAPEDPIXMAPDNDWINDOW_H diff --git a/src/gui/kernel/qsimpledrag.cpp b/src/gui/kernel/qsimpledrag.cpp new file mode 100644 index 0000000000..f6912a2d57 --- /dev/null +++ b/src/gui/kernel/qsimpledrag.cpp @@ -0,0 +1,366 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsimpledrag_p.h" + +#include "qbitmap.h" +#include "qdrag.h" +#include "qpixmap.h" +#include "qevent.h" +#include "qfile.h" +#include "qtextcodec.h" +#include "qguiapplication.h" +#include "qpoint.h" +#include "qbuffer.h" +#include "qimage.h" +#include "qregexp.h" +#include "qdir.h" +#include "qimagereader.h" +#include "qimagewriter.h" + +#include +#include + +#include +#include + +#include + +QT_BEGIN_NAMESPACE + +#ifndef QT_NO_DRAGANDDROP + +static QWindow* topLevelAt(const QPoint &pos) +{ + QWindowList list = QGuiApplication::topLevelWindows(); + for (int i = list.count()-1; i >= 0; --i) { + QWindow *w = list.at(i); + if (w->isVisible() && w->geometry().contains(pos) && !qobject_cast(w)) + return w; + } + return 0; +} + +/*! + \class QBasicDrag + \brief QBasicDrag is a base class for implementing platform drag and drop. + \since 5.0 + \internal + \ingroup qpa + + QBasicDrag implements QPlatformDrag::drag() by running a local event loop in which + it tracks mouse movements and moves the drag icon (QShapedPixmapWindow) accordingly. + It provides new virtuals allowing for querying whether the receiving window + (within the Qt application or outside) accepts the drag and sets the state accordingly. +*/ + +QBasicDrag::QBasicDrag() : + m_restoreCursor(false), m_eventLoop(0), + m_executed_drop_action(Qt::IgnoreAction), m_can_drop(false), + m_drag(0), m_drag_icon_window(0) +{ +} + +QBasicDrag::~QBasicDrag() +{ + delete m_drag_icon_window; +} + +void QBasicDrag::enableEventFilter() +{ + qApp->installEventFilter(this); +} + +void QBasicDrag::disableEventFilter() +{ + qApp->removeEventFilter(this); +} + +bool QBasicDrag::eventFilter(QObject *o, QEvent *e) +{ + if (!m_drag) { + if (e->type() == QEvent::KeyRelease && static_cast(e)->key() == Qt::Key_Escape) { + disableEventFilter(); + exitDndEventLoop(); + return true; // block the key release + } + return false; + } + + if (!qobject_cast(o)) + return false; + + switch (e->type()) { + case QEvent::ShortcutOverride: + // prevent accelerators from firing while dragging + e->accept(); + return true; + + case QEvent::KeyPress: + case QEvent::KeyRelease: + { + QKeyEvent *ke = static_cast(e); + if (ke->key() == Qt::Key_Escape && e->type() == QEvent::KeyPress) { + cancel(); + disableEventFilter(); + exitDndEventLoop(); + + } + return true; // Eat all key events + } + + case QEvent::MouseMove: + move(static_cast(e)); + return true; // Eat all mouse events + + case QEvent::MouseButtonRelease: + disableEventFilter(); + if (canDrop()) { + drop(static_cast(e)); + } else { + cancel(); + } + exitDndEventLoop(); + return true; // Eat all mouse events + + case QEvent::MouseButtonPress: + case QEvent::MouseButtonDblClick: + case QEvent::Wheel: + return true; + default: + break; + } + return false; +} + +Qt::DropAction QBasicDrag::drag(QDrag *o) +{ + m_drag = o; + m_executed_drop_action = Qt::IgnoreAction; + m_can_drop = false; + m_restoreCursor = true; +#ifndef QT_NO_CURSOR + qApp->setOverrideCursor(Qt::DragCopyCursor); + updateCursor(m_executed_drop_action); +#endif + startDrag(); + m_eventLoop = new QEventLoop; + m_eventLoop->exec(); + delete m_eventLoop; + m_eventLoop = 0; + m_drag = 0; + endDrag(); + return m_executed_drop_action; +} + +void QBasicDrag::restoreCursor() +{ + if (m_restoreCursor) { +#ifndef QT_NO_CURSOR + QGuiApplication::restoreOverrideCursor(); +#endif + m_restoreCursor = false; + } +} + +void QBasicDrag::startDrag() +{ + // ### TODO Check if its really necessary to have m_drag_icon_window + // when QDrag is used without a pixmap - QDrag::setPixmap() + if (!m_drag_icon_window) + m_drag_icon_window = new QShapedPixmapWindow(); + + m_drag_icon_window->setPixmap(m_drag->pixmap()); + m_drag_icon_window->setHotspot(m_drag->hotSpot()); + m_drag_icon_window->updateGeometry(); + m_drag_icon_window->setVisible(true); + + enableEventFilter(); +} + +void QBasicDrag::endDrag() +{ +} + +void QBasicDrag::cancel() +{ + disableEventFilter(); + restoreCursor(); + m_drag_icon_window->setVisible(false); +} + +void QBasicDrag::move(const QMouseEvent *) +{ + if (m_drag) + m_drag_icon_window->updateGeometry(); +} + +void QBasicDrag::drop(const QMouseEvent *) +{ + disableEventFilter(); + restoreCursor(); + m_drag_icon_window->setVisible(false); +} + +void QBasicDrag::exitDndEventLoop() +{ + if (m_eventLoop && m_eventLoop->isRunning()) + m_eventLoop->exit(); +} + +void QBasicDrag::updateCursor(Qt::DropAction action) +{ +#ifndef QT_NO_CURSOR + Qt::CursorShape cursorShape = Qt::ForbiddenCursor; + if (canDrop()) { + switch (action) { + case Qt::CopyAction: + cursorShape = Qt::DragCopyCursor; + break; + case Qt::LinkAction: + cursorShape = Qt::DragLinkCursor; + break; + default: + cursorShape = Qt::DragMoveCursor; + break; + } + } + + QCursor *cursor = qApp->overrideCursor(); + QPixmap pixmap = m_drag->dragCursor(action); + if (!cursor) { + qApp->changeOverrideCursor((pixmap.isNull()) ? QCursor(cursorShape) : QCursor(pixmap)); + } else { + if (!pixmap.isNull()) { + if ((cursor->pixmap().cacheKey() != pixmap.cacheKey())) { + qApp->changeOverrideCursor(QCursor(pixmap)); + } + } else { + if (cursorShape != cursor->shape()) { + qApp->changeOverrideCursor(QCursor(cursorShape)); + } + } + } +#endif + updateAction(action); +} + +/*! + \class QSimpleDrag + \brief QSimpleDrag implements QBasicDrag for Drag and Drop operations within the Qt Application itself. + \since 5.0 + \internal + \ingroup qpa + + The class checks whether the receiving window is a window of the Qt application + and sets the state accordingly. It does not take windows of other applications + into account. +*/ + +QSimpleDrag::QSimpleDrag() : m_current_window(0) +{ +} + +QMimeData *QSimpleDrag::platformDropData() +{ + if (drag()) + return drag()->mimeData(); + return 0; +} + +void QSimpleDrag::startDrag() +{ + QBasicDrag::startDrag(); + m_current_window = topLevelAt(QCursor::pos()); + if (m_current_window) { + QPlatformDragQtResponse response = QWindowSystemInterface::handleDrag(m_current_window, drag()->mimeData(), QCursor::pos(), drag()->supportedActions()); + setCanDrop(response.isAccepted()); + updateCursor(response.acceptedAction()); + } else { + setCanDrop(false); + updateCursor(Qt::IgnoreAction); + } + setExecutedDropAction(Qt::IgnoreAction); +} + +void QSimpleDrag::cancel() +{ + QBasicDrag::cancel(); + if (drag()) + QWindowSystemInterface::handleDrag(m_current_window, 0, QPoint(), Qt::IgnoreAction); + m_current_window = 0; +} + +void QSimpleDrag::move(const QMouseEvent *me) +{ + QBasicDrag::move(me); + QWindow *window = topLevelAt(me->globalPos()); + if (!window) + return; + + const QPoint pos = me->globalPos() - window->geometry().topLeft(); + const QPlatformDragQtResponse qt_response = + QWindowSystemInterface::handleDrag(window, drag()->mimeData(), pos, drag()->supportedActions()); + + updateCursor(qt_response.acceptedAction()); + setCanDrop(qt_response.isAccepted()); +} + +void QSimpleDrag::drop(const QMouseEvent *me) +{ + QBasicDrag::drop(me); + QWindow *window = topLevelAt(me->globalPos()); + if (!window) + return; + + const QPoint pos = me->globalPos() - window->geometry().topLeft(); + const QPlatformDropQtResponse response = + QWindowSystemInterface::handleDrop(window, drag()->mimeData(),pos, drag()->supportedActions()); + if (response.isAccepted()) { + setExecutedDropAction(response.acceptedAction()); + } else { + setExecutedDropAction(Qt::IgnoreAction); + } +} + +#endif // QT_NO_DRAGANDDROP + +QT_END_NAMESPACE diff --git a/src/gui/kernel/qsimpledrag_p.h b/src/gui/kernel/qsimpledrag_p.h new file mode 100644 index 0000000000..36ea4c1ec5 --- /dev/null +++ b/src/gui/kernel/qsimpledrag_p.h @@ -0,0 +1,122 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSIMPLEDRAG_H +#define QSIMPLEDRAG_H + +#include + +#include + +QT_BEGIN_NAMESPACE + +#ifndef QT_NO_DRAGANDDROP + +class QMouseEvent; +class QWindow; +class QEventLoop; +class QDropData; +class QShapedPixmapWindow; + +class Q_GUI_EXPORT QBasicDrag : public QPlatformDrag, public QObject +{ +public: + virtual ~QBasicDrag(); + + virtual Qt::DropAction drag(QDrag *drag); + + virtual bool eventFilter(QObject *o, QEvent *e); + +protected: + QBasicDrag(); + + virtual void startDrag(); + virtual void cancel(); + virtual void move(const QMouseEvent *me); + virtual void drop(const QMouseEvent *me); + virtual void endDrag(); + + QShapedPixmapWindow *shapedPixmapWindow() const { return m_drag_icon_window; } + void updateCursor(Qt::DropAction action); + + bool canDrop() const { return m_can_drop; } + void setCanDrop(bool c) { m_can_drop = c; } + + Qt::DropAction executedDropAction() const { return m_executed_drop_action; } + void setExecutedDropAction(Qt::DropAction da) { m_executed_drop_action = da; } + + QDrag *drag() const { return m_drag; } + +private: + void enableEventFilter(); + void disableEventFilter(); + void restoreCursor(); + void exitDndEventLoop(); + + bool m_restoreCursor; + QEventLoop *m_eventLoop; + Qt::DropAction m_executed_drop_action; + bool m_can_drop; + QDrag *m_drag; + QShapedPixmapWindow *m_drag_icon_window; +}; + +class Q_GUI_EXPORT QSimpleDrag : public QBasicDrag +{ +public: + QSimpleDrag(); + virtual QMimeData *platformDropData(); + +protected: + virtual void startDrag(); + virtual void cancel(); + virtual void move(const QMouseEvent *me); + virtual void drop(const QMouseEvent *me); + +private: + QWindow *m_current_window; +}; + +#endif // QT_NO_DRAGANDDROP + +QT_END_NAMESPACE + +#endif diff --git a/src/platformsupport/dnd/dnd.pri b/src/platformsupport/dnd/dnd.pri deleted file mode 100644 index 47feb81ef2..0000000000 --- a/src/platformsupport/dnd/dnd.pri +++ /dev/null @@ -1,6 +0,0 @@ -HEADERS += \ - $$PWD/qsimpledrag_p.h \ - $$PWD/qshapedpixmapdndwindow_p.h -SOURCES += \ - $$PWD/qsimpledrag.cpp \ - $$PWD/qshapedpixmapdndwindow.cpp diff --git a/src/platformsupport/dnd/qshapedpixmapdndwindow.cpp b/src/platformsupport/dnd/qshapedpixmapdndwindow.cpp deleted file mode 100644 index b3e64b01d0..0000000000 --- a/src/platformsupport/dnd/qshapedpixmapdndwindow.cpp +++ /dev/null @@ -1,106 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qshapedpixmapdndwindow_p.h" - -#include -#include - -QT_BEGIN_NAMESPACE - -QShapedPixmapWindow::QShapedPixmapWindow() - : QWindow(), - m_backingStore(0) -{ - QSurfaceFormat format; - format.setAlphaBufferSize(8); - setFormat(format); - setSurfaceType(RasterSurface); - setFlags(Qt::ToolTip | Qt::FramelessWindowHint | - Qt::X11BypassWindowManagerHint | Qt::WindowTransparentForInput); - create(); - m_backingStore = new QBackingStore(this); -} - -void QShapedPixmapWindow::render() -{ - QRect rect(QPoint(), geometry().size()); - - m_backingStore->beginPaint(rect); - - QPaintDevice *device = m_backingStore->paintDevice(); - - { - QPainter p(device); - p.setCompositionMode(QPainter::CompositionMode_Source); - p.drawPixmap(0, 0, m_pixmap); - } - - m_backingStore->endPaint(); - m_backingStore->flush(rect); -} - -void QShapedPixmapWindow::setPixmap(const QPixmap &pixmap) -{ - m_pixmap = pixmap; -} - -void QShapedPixmapWindow::setHotspot(const QPoint &hotspot) -{ - m_hotSpot = hotspot; -} - -void QShapedPixmapWindow::updateGeometry() -{ - QRect rect(QCursor::pos() - m_hotSpot, m_pixmap.size()); - if (m_pixmap.isNull()) - m_backingStore->resize(QSize(1,1)); - else if (m_backingStore->size() != m_pixmap.size()) - m_backingStore->resize(m_pixmap.size()); - setGeometry(rect); -} - -void QShapedPixmapWindow::exposeEvent(QExposeEvent *) -{ - render(); -} - -QT_END_NAMESPACE diff --git a/src/platformsupport/dnd/qshapedpixmapdndwindow_p.h b/src/platformsupport/dnd/qshapedpixmapdndwindow_p.h deleted file mode 100644 index 20674b6b19..0000000000 --- a/src/platformsupport/dnd/qshapedpixmapdndwindow_p.h +++ /dev/null @@ -1,75 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSHAPEDPIXMAPDNDWINDOW_H -#define QSHAPEDPIXMAPDNDWINDOW_H - -#include -#include -#include - -QT_BEGIN_NAMESPACE - -class QShapedPixmapWindow : public QWindow -{ - Q_OBJECT -public: - QShapedPixmapWindow(); - - void render(); - - void setPixmap(const QPixmap &pixmap); - void setHotspot(const QPoint &hotspot); - - void updateGeometry(); - -protected: - void exposeEvent(QExposeEvent *); - -private: - QBackingStore *m_backingStore; - QPixmap m_pixmap; - QPoint m_hotSpot; -}; - -QT_END_NAMESPACE - -#endif // QSHAPEDPIXMAPDNDWINDOW_H diff --git a/src/platformsupport/dnd/qsimpledrag.cpp b/src/platformsupport/dnd/qsimpledrag.cpp deleted file mode 100644 index f2ff177055..0000000000 --- a/src/platformsupport/dnd/qsimpledrag.cpp +++ /dev/null @@ -1,366 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qsimpledrag_p.h" - -#include "qbitmap.h" -#include "qdrag.h" -#include "qpixmap.h" -#include "qevent.h" -#include "qfile.h" -#include "qtextcodec.h" -#include "qguiapplication.h" -#include "qpoint.h" -#include "qbuffer.h" -#include "qimage.h" -#include "qregexp.h" -#include "qdir.h" -#include "qimagereader.h" -#include "qimagewriter.h" - -#include -#include - -#include -#include - -#include - -QT_BEGIN_NAMESPACE - -#ifndef QT_NO_DRAGANDDROP - -static QWindow* topLevelAt(const QPoint &pos) -{ - QWindowList list = QGuiApplication::topLevelWindows(); - for (int i = list.count()-1; i >= 0; --i) { - QWindow *w = list.at(i); - if (w->isVisible() && w->geometry().contains(pos) && !qobject_cast(w)) - return w; - } - return 0; -} - -/*! - \class QBasicDrag - \brief QBasicDrag is a base class for implementing platform drag and drop. - \since 5.0 - \internal - \ingroup qpa - - QBasicDrag implements QPlatformDrag::drag() by running a local event loop in which - it tracks mouse movements and moves the drag icon (QShapedPixmapWindow) accordingly. - It provides new virtuals allowing for querying whether the receiving window - (within the Qt application or outside) accepts the drag and sets the state accordingly. -*/ - -QBasicDrag::QBasicDrag() : - m_restoreCursor(false), m_eventLoop(0), - m_executed_drop_action(Qt::IgnoreAction), m_can_drop(false), - m_drag(0), m_drag_icon_window(0) -{ -} - -QBasicDrag::~QBasicDrag() -{ - delete m_drag_icon_window; -} - -void QBasicDrag::enableEventFilter() -{ - qApp->installEventFilter(this); -} - -void QBasicDrag::disableEventFilter() -{ - qApp->removeEventFilter(this); -} - -bool QBasicDrag::eventFilter(QObject *o, QEvent *e) -{ - if (!m_drag) { - if (e->type() == QEvent::KeyRelease && static_cast(e)->key() == Qt::Key_Escape) { - disableEventFilter(); - exitDndEventLoop(); - return true; // block the key release - } - return false; - } - - if (!qobject_cast(o)) - return false; - - switch (e->type()) { - case QEvent::ShortcutOverride: - // prevent accelerators from firing while dragging - e->accept(); - return true; - - case QEvent::KeyPress: - case QEvent::KeyRelease: - { - QKeyEvent *ke = static_cast(e); - if (ke->key() == Qt::Key_Escape && e->type() == QEvent::KeyPress) { - cancel(); - disableEventFilter(); - exitDndEventLoop(); - - } - return true; // Eat all key events - } - - case QEvent::MouseMove: - move(static_cast(e)); - return true; // Eat all mouse events - - case QEvent::MouseButtonRelease: - disableEventFilter(); - if (canDrop()) { - drop(static_cast(e)); - } else { - cancel(); - } - exitDndEventLoop(); - return true; // Eat all mouse events - - case QEvent::MouseButtonPress: - case QEvent::MouseButtonDblClick: - case QEvent::Wheel: - return true; - default: - break; - } - return false; -} - -Qt::DropAction QBasicDrag::drag(QDrag *o) -{ - m_drag = o; - m_executed_drop_action = Qt::IgnoreAction; - m_can_drop = false; - m_restoreCursor = true; -#ifndef QT_NO_CURSOR - qApp->setOverrideCursor(Qt::DragCopyCursor); - updateCursor(m_executed_drop_action); -#endif - startDrag(); - m_eventLoop = new QEventLoop; - m_eventLoop->exec(); - delete m_eventLoop; - m_eventLoop = 0; - m_drag = 0; - endDrag(); - return m_executed_drop_action; -} - -void QBasicDrag::restoreCursor() -{ - if (m_restoreCursor) { -#ifndef QT_NO_CURSOR - QGuiApplication::restoreOverrideCursor(); -#endif - m_restoreCursor = false; - } -} - -void QBasicDrag::startDrag() -{ - // ### TODO Check if its really necessary to have m_drag_icon_window - // when QDrag is used without a pixmap - QDrag::setPixmap() - if (!m_drag_icon_window) - m_drag_icon_window = new QShapedPixmapWindow(); - - m_drag_icon_window->setPixmap(m_drag->pixmap()); - m_drag_icon_window->setHotspot(m_drag->hotSpot()); - m_drag_icon_window->updateGeometry(); - m_drag_icon_window->setVisible(true); - - enableEventFilter(); -} - -void QBasicDrag::endDrag() -{ -} - -void QBasicDrag::cancel() -{ - disableEventFilter(); - restoreCursor(); - m_drag_icon_window->setVisible(false); -} - -void QBasicDrag::move(const QMouseEvent *) -{ - if (m_drag) - m_drag_icon_window->updateGeometry(); -} - -void QBasicDrag::drop(const QMouseEvent *) -{ - disableEventFilter(); - restoreCursor(); - m_drag_icon_window->setVisible(false); -} - -void QBasicDrag::exitDndEventLoop() -{ - if (m_eventLoop && m_eventLoop->isRunning()) - m_eventLoop->exit(); -} - -void QBasicDrag::updateCursor(Qt::DropAction action) -{ -#ifndef QT_NO_CURSOR - Qt::CursorShape cursorShape = Qt::ForbiddenCursor; - if (canDrop()) { - switch (action) { - case Qt::CopyAction: - cursorShape = Qt::DragCopyCursor; - break; - case Qt::LinkAction: - cursorShape = Qt::DragLinkCursor; - break; - default: - cursorShape = Qt::DragMoveCursor; - break; - } - } - - QCursor *cursor = qApp->overrideCursor(); - QPixmap pixmap = m_drag->dragCursor(action); - if (!cursor) { - qApp->changeOverrideCursor((pixmap.isNull()) ? QCursor(cursorShape) : QCursor(pixmap)); - } else { - if (!pixmap.isNull()) { - if ((cursor->pixmap().cacheKey() != pixmap.cacheKey())) { - qApp->changeOverrideCursor(QCursor(pixmap)); - } - } else { - if (cursorShape != cursor->shape()) { - qApp->changeOverrideCursor(QCursor(cursorShape)); - } - } - } -#endif - updateAction(action); -} - -/*! - \class QSimpleDrag - \brief QSimpleDrag implements QBasicDrag for Drag and Drop operations within the Qt Application itself. - \since 5.0 - \internal - \ingroup qpa - - The class checks whether the receiving window is a window of the Qt application - and sets the state accordingly. It does not take windows of other applications - into account. -*/ - -QSimpleDrag::QSimpleDrag() : m_current_window(0) -{ -} - -QMimeData *QSimpleDrag::platformDropData() -{ - if (drag()) - return drag()->mimeData(); - return 0; -} - -void QSimpleDrag::startDrag() -{ - QBasicDrag::startDrag(); - m_current_window = topLevelAt(QCursor::pos()); - if (m_current_window) { - QPlatformDragQtResponse response = QWindowSystemInterface::handleDrag(m_current_window, drag()->mimeData(), QCursor::pos(), drag()->supportedActions()); - setCanDrop(response.isAccepted()); - updateCursor(response.acceptedAction()); - } else { - setCanDrop(false); - updateCursor(Qt::IgnoreAction); - } - setExecutedDropAction(Qt::IgnoreAction); -} - -void QSimpleDrag::cancel() -{ - QBasicDrag::cancel(); - if (drag()) - QWindowSystemInterface::handleDrag(m_current_window, 0, QPoint(), Qt::IgnoreAction); - m_current_window = 0; -} - -void QSimpleDrag::move(const QMouseEvent *me) -{ - QBasicDrag::move(me); - QWindow *window = topLevelAt(me->globalPos()); - if (!window) - return; - - const QPoint pos = me->globalPos() - window->geometry().topLeft(); - const QPlatformDragQtResponse qt_response = - QWindowSystemInterface::handleDrag(window, drag()->mimeData(), pos, drag()->supportedActions()); - - updateCursor(qt_response.acceptedAction()); - setCanDrop(qt_response.isAccepted()); -} - -void QSimpleDrag::drop(const QMouseEvent *me) -{ - QBasicDrag::drop(me); - QWindow *window = topLevelAt(me->globalPos()); - if (!window) - return; - - const QPoint pos = me->globalPos() - window->geometry().topLeft(); - const QPlatformDropQtResponse response = - QWindowSystemInterface::handleDrop(window, drag()->mimeData(),pos, drag()->supportedActions()); - if (response.isAccepted()) { - setExecutedDropAction(response.acceptedAction()); - } else { - setExecutedDropAction(Qt::IgnoreAction); - } -} - -#endif // QT_NO_DRAGANDDROP - -QT_END_NAMESPACE diff --git a/src/platformsupport/dnd/qsimpledrag_p.h b/src/platformsupport/dnd/qsimpledrag_p.h deleted file mode 100644 index 10237b36d7..0000000000 --- a/src/platformsupport/dnd/qsimpledrag_p.h +++ /dev/null @@ -1,122 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSIMPLEDRAG_H -#define QSIMPLEDRAG_H - -#include - -#include - -QT_BEGIN_NAMESPACE - -#ifndef QT_NO_DRAGANDDROP - -class QMouseEvent; -class QWindow; -class QEventLoop; -class QDropData; -class QShapedPixmapWindow; - -class QBasicDrag : public QPlatformDrag, public QObject -{ -public: - virtual ~QBasicDrag(); - - virtual Qt::DropAction drag(QDrag *drag); - - virtual bool eventFilter(QObject *o, QEvent *e); - -protected: - QBasicDrag(); - - virtual void startDrag(); - virtual void cancel(); - virtual void move(const QMouseEvent *me); - virtual void drop(const QMouseEvent *me); - virtual void endDrag(); - - QShapedPixmapWindow *shapedPixmapWindow() const { return m_drag_icon_window; } - void updateCursor(Qt::DropAction action); - - bool canDrop() const { return m_can_drop; } - void setCanDrop(bool c) { m_can_drop = c; } - - Qt::DropAction executedDropAction() const { return m_executed_drop_action; } - void setExecutedDropAction(Qt::DropAction da) { m_executed_drop_action = da; } - - QDrag *drag() const { return m_drag; } - -private: - void enableEventFilter(); - void disableEventFilter(); - void restoreCursor(); - void exitDndEventLoop(); - - bool m_restoreCursor; - QEventLoop *m_eventLoop; - Qt::DropAction m_executed_drop_action; - bool m_can_drop; - QDrag *m_drag; - QShapedPixmapWindow *m_drag_icon_window; -}; - -class QSimpleDrag : public QBasicDrag -{ -public: - QSimpleDrag(); - virtual QMimeData *platformDropData(); - -protected: - virtual void startDrag(); - virtual void cancel(); - virtual void move(const QMouseEvent *me); - virtual void drop(const QMouseEvent *me); - -private: - QWindow *m_current_window; -}; - -#endif // QT_NO_DRAGANDDROP - -QT_END_NAMESPACE - -#endif diff --git a/src/platformsupport/platformsupport.pro b/src/platformsupport/platformsupport.pro index 4cb1f2c1bf..da87f395fd 100644 --- a/src/platformsupport/platformsupport.pro +++ b/src/platformsupport/platformsupport.pro @@ -9,7 +9,6 @@ PRECOMPILED_HEADER = ../corelib/global/qt_pch.h include(cfsocketnotifier/cfsocketnotifier.pri) include(cglconvenience/cglconvenience.pri) -include(dnd/dnd.pri) include(eglconvenience/eglconvenience.pri) include(eventdispatchers/eventdispatchers.pri) include(fbconvenience/fbconvenience.pri) diff --git a/src/plugins/platforms/cocoa/qcocoadrag.h b/src/plugins/platforms/cocoa/qcocoadrag.h index 6e29fd1a78..80259df600 100644 --- a/src/plugins/platforms/cocoa/qcocoadrag.h +++ b/src/plugins/platforms/cocoa/qcocoadrag.h @@ -45,7 +45,7 @@ #include #include #include -#include +#include #include diff --git a/src/plugins/platforms/qnx/qqnxintegration.cpp b/src/plugins/platforms/qnx/qqnxintegration.cpp index 072f60dff8..feb05e3093 100644 --- a/src/plugins/platforms/qnx/qqnxintegration.cpp +++ b/src/plugins/platforms/qnx/qqnxintegration.cpp @@ -89,7 +89,7 @@ #include #endif -#include +#include #include #include diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp index db736cef4e..4961e0377c 100644 --- a/src/plugins/platforms/xcb/qxcbdrag.cpp +++ b/src/plugins/platforms/xcb/qxcbdrag.cpp @@ -57,8 +57,8 @@ #include -#include -#include +#include +#include QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/xcb/qxcbdrag.h b/src/plugins/platforms/xcb/qxcbdrag.h index 5678c2d303..5648f70d9e 100644 --- a/src/plugins/platforms/xcb/qxcbdrag.h +++ b/src/plugins/platforms/xcb/qxcbdrag.h @@ -43,7 +43,7 @@ #define QXCBDRAG_H #include -#include +#include #include #include #include -- cgit v1.2.3