Clean up DnD code

Some cleanups of the DnD code to prepare for
creating a platform API.
This commit is contained in:
Lars Knoll 2011-05-30 22:20:15 +02:00
parent bf8dfc394a
commit 07f8aecb52
4 changed files with 405 additions and 482 deletions

View File

@ -26,7 +26,6 @@ SOURCES += \
kernel/qcursor.cpp \
kernel/qdrag.cpp \
kernel/qdnd.cpp \
kernel/qdnd_qpa.cpp \
kernel/qevent.cpp \
kernel/qkeysequence.cpp \
kernel/qkeymapper.cpp \

View File

@ -65,8 +65,6 @@
QT_BEGIN_NAMESPACE
#ifndef QT_NO_DRAGANDDROP
//#define QDND_DEBUG
#ifdef QDND_DEBUG
@ -123,6 +121,18 @@ QString KeyboardModifiersToString(Qt::KeyboardModifiers moderfies)
}
#endif
class QDropData : public QInternalMimeData
{
public:
QDropData();
~QDropData();
protected:
bool hasFormat_sys(const QString &mimeType) const;
QStringList formats_sys() const;
QVariant retrieveData_sys(const QString &mimeType, QVariant::Type type) const;
};
// the universe's only drag manager
QDragManager *QDragManager::instance = 0;
@ -141,13 +151,15 @@ QDragManager::QDragManager()
restoreCursor = false;
willDrop = false;
eventLoop = 0;
dropData = new QDropData();
platformDropData = new QDropData();
currentDropTarget = 0;
#ifdef Q_WS_X11
xdndMimeTransferedPixmapIndex = 0;
#endif
currentWindow = 0;
possible_actions = Qt::IgnoreAction;
}
@ -158,7 +170,7 @@ QDragManager::~QDragManager()
QGuiApplication::restoreOverrideCursor();
#endif
instance = 0;
delete dropData;
delete platformDropData;
}
QDragManager *QDragManager::self()
@ -173,23 +185,23 @@ QPixmap QDragManager::dragCursor(Qt::DropAction action) const
QDragPrivate * d = dragPrivate();
if (d && d->customCursors.contains(action))
return d->customCursors[action];
else if (action == Qt::MoveAction)
return QGuiApplicationPrivate::instance()->getPixmapCursor(Qt::DragMoveCursor);
else if (action == Qt::CopyAction)
return QGuiApplicationPrivate::instance()->getPixmapCursor(Qt::DragCopyCursor);
else if (action == Qt::LinkAction)
return QGuiApplicationPrivate::instance()->getPixmapCursor(Qt::DragLinkCursor);
#ifdef Q_WS_WIN
else if (action == Qt::IgnoreAction)
return QGuiApplicationPrivate::instance()->getPixmapCursor(Qt::ForbiddenCursor);
#endif
return QPixmap();
}
bool QDragManager::hasCustomDragCursors() const
{
QDragPrivate * d = dragPrivate();
return d && !d->customCursors.isEmpty();
Qt::CursorShape shape = Qt::ForbiddenCursor;
switch (action) {
case Qt::MoveAction:
shape = Qt::DragMoveCursor;
break;
case Qt::CopyAction:
shape = Qt::DragCopyCursor;
break;
case Qt::LinkAction:
shape = Qt::DragLinkCursor;
break;
default:
shape = Qt::ForbiddenCursor;
}
return QGuiApplicationPrivate::instance()->getPixmapCursor(Qt::DragMoveCursor);
}
Qt::DropAction QDragManager::defaultAction(Qt::DropActions possibleActions,
@ -231,10 +243,6 @@ Qt::DropAction QDragManager::defaultAction(Qt::DropActions possibleActions,
defaultAction = Qt::LinkAction;
#endif
// if the object is set take the list of possibles from it
if (object)
possibleActions = object->d_func()->possible_actions;
#ifdef QDND_DEBUG
qDebug("possible actions : %s", dragActionsToString(possibleActions).latin1());
#endif
@ -276,7 +284,331 @@ QObject *QDragManager::currentTarget()
return currentDropTarget;
}
static QPixmap *defaultPm = 0;
static const int default_pm_hotx = -2;
static const int default_pm_hoty = -16;
static const char *const default_pm[] = {
"13 9 3 1",
". c None",
" c #000000",
"X c #FFFFFF",
"X X X X X X X",
" X X X X X X ",
"X ......... X",
" X.........X ",
"X ......... X",
" X.........X ",
"X ......... X",
" X X X X X X ",
"X X X X X X X",
};
// Shift/Ctrl handling, and final drop status
static Qt::DropAction global_accepted_action = Qt::CopyAction;
static Qt::KeyboardModifiers oldstate;
class QShapedPixmapWindow : public QWindow {
QPixmap pixmap;
public:
QShapedPixmapWindow() :
QWindow(0)
{
setWindowFlags(Qt::Tool | Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint);
// ### Should we set the surface type to raster?
// ### FIXME
// setAttribute(Qt::WA_TransparentForMouseEvents);
}
void move(const QPoint &p) {
QRect g = geometry();
g.setTopLeft(p);
setGeometry(g);
}
void setPixmap(QPixmap pm)
{
pixmap = pm;
// ###
// if (!pixmap.mask().isNull()) {
// setMask(pixmap.mask());
// } else {
// clearMask();
// }
setGeometry(QRect(geometry().topLeft(), pm.size()));
}
// ### Get it painted again!
// void paintEvent(QPaintEvent*)
// {
// QPainter p(this);
// p.drawPixmap(0,0,pixmap);
// }
};
static QShapedPixmapWindow *qt_qws_dnd_deco = 0;
void QDragManager::updatePixmap()
{
if (qt_qws_dnd_deco) {
QPixmap pm;
QPoint pm_hot(default_pm_hotx,default_pm_hoty);
if (object) {
pm = object->pixmap();
if (!pm.isNull())
pm_hot = object->hotSpot();
}
if (pm.isNull()) {
if (!defaultPm)
defaultPm = new QPixmap(default_pm);
pm = *defaultPm;
}
qt_qws_dnd_deco->setPixmap(pm);
qt_qws_dnd_deco->move(QCursor::pos()-pm_hot);
if (willDrop) {
qt_qws_dnd_deco->show();
} else {
qt_qws_dnd_deco->hide();
}
}
}
void QDragManager::move(const QMouseEvent *me)
{
QWindow *window = QGuiApplication::topLevelAt(me->globalPos());
QPoint pos;
if (window)
pos = me->globalPos() - window->geometry().topLeft();
if (me->buttons()) {
Qt::DropAction prevAction = global_accepted_action;
if (currentWindow != window) {
if (currentWindow) {
QDragLeaveEvent dle;
QCoreApplication::sendEvent(currentWindow, &dle);
willDrop = false;
global_accepted_action = Qt::IgnoreAction;
}
currentWindow = window;
if (currentWindow) {
QDragEnterEvent dee(pos, possible_actions, dropData(), me->buttons(), me->modifiers());
QCoreApplication::sendEvent(currentWindow, &dee);
willDrop = dee.isAccepted() && dee.dropAction() != Qt::IgnoreAction;
global_accepted_action = willDrop ? dee.dropAction() : Qt::IgnoreAction;
}
updateCursor();
restoreCursor = true;
} else if (window) {
Q_ASSERT(currentWindow);
QDragMoveEvent dme(pos, possible_actions, dropData(), me->buttons(), me->modifiers());
if (global_accepted_action != Qt::IgnoreAction) {
dme.setDropAction(global_accepted_action);
dme.accept();
}
QCoreApplication::sendEvent(currentWindow, &dme);
willDrop = dme.isAccepted();
global_accepted_action = willDrop ? dme.dropAction() : Qt::IgnoreAction;
updatePixmap();
updateCursor();
}
if (global_accepted_action != prevAction)
emitActionChanged(global_accepted_action);
}
}
void QDragManager::updateCursor()
{
#ifndef QT_NO_CURSOR
if (willDrop) {
if (qt_qws_dnd_deco)
qt_qws_dnd_deco->show();
if (currentActionForOverrideCursor != global_accepted_action) {
QGuiApplication::changeOverrideCursor(QCursor(dragCursor(global_accepted_action), 0, 0));
currentActionForOverrideCursor = global_accepted_action;
}
} else {
QCursor *overrideCursor = QGuiApplication::overrideCursor();
if (!overrideCursor || overrideCursor->shape() != Qt::ForbiddenCursor) {
QGuiApplication::changeOverrideCursor(QCursor(Qt::ForbiddenCursor));
currentActionForOverrideCursor = Qt::IgnoreAction;
}
if (qt_qws_dnd_deco)
qt_qws_dnd_deco->hide();
}
#endif
}
bool QDragManager::eventFilter(QObject *o, QEvent *e)
{
if (beingCancelled) {
if (e->type() == QEvent::KeyRelease && static_cast<QKeyEvent*>(e)->key() == Qt::Key_Escape) {
qApp->removeEventFilter(this);
Q_ASSERT(object == 0);
beingCancelled = false;
eventLoop->exit();
return true; // block the key release
}
return false;
}
Q_ASSERT(object != 0);
if (!qobject_cast<QWindow *>(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<QKeyEvent *>(e);
if (ke->key() == Qt::Key_Escape && e->type() == QEvent::KeyPress) {
cancel();
qApp->removeEventFilter(this);
beingCancelled = false;
eventLoop->exit();
} else {
// ### x11 forces move!
updateCursor();
}
return true; // Eat all key events
}
case QEvent::MouseMove:
move(static_cast<QMouseEvent *>(e));
return true; // Eat all mouse events
case QEvent::MouseButtonRelease:
qApp->removeEventFilter(this);
if (willDrop)
drop(static_cast<QMouseEvent *>(e));
else
cancel();
beingCancelled = false;
eventLoop->exit();
return true; // Eat all mouse events
case QEvent::MouseButtonPress:
case QEvent::MouseButtonDblClick:
case QEvent::Wheel:
return true;
default:
break;
}
return false;
}
Qt::DropAction QDragManager::drag(QDrag *o)
{
if (object == o || !o || !o->source())
return Qt::IgnoreAction;
if (object) {
cancel();
qApp->removeEventFilter(this);
beingCancelled = false;
}
object = o;
if (!qt_qws_dnd_deco)
qt_qws_dnd_deco = new QShapedPixmapWindow();
oldstate = Qt::NoModifier; // #### Should use state that caused the drag
// drag_mode = mode;
possible_actions = dragPrivate()->possible_actions;
willDrop = false;
updatePixmap();
updateCursor();
restoreCursor = true;
object->d_func()->target = 0;
qApp->installEventFilter(this);
global_accepted_action = Qt::CopyAction;
#ifndef QT_NO_CURSOR
qApp->setOverrideCursor(Qt::ArrowCursor);
restoreCursor = true;
updateCursor();
#endif
eventLoop = new QEventLoop;
(void) eventLoop->exec();
delete eventLoop;
eventLoop = 0;
delete qt_qws_dnd_deco;
qt_qws_dnd_deco = 0;
return global_accepted_action;
}
void QDragManager::cancel(bool deleteSource)
{
// qDebug("QDragManager::cancel");
beingCancelled = true;
if (object->target()) {
QDragLeaveEvent dle;
QCoreApplication::sendEvent(object->target(), &dle);
}
#ifndef QT_NO_CURSOR
if (restoreCursor) {
QGuiApplication::restoreOverrideCursor();
restoreCursor = false;
}
#endif
if (object) {
if (deleteSource)
object->deleteLater();
object = 0;
}
delete qt_qws_dnd_deco;
qt_qws_dnd_deco = 0;
global_accepted_action = Qt::IgnoreAction;
}
void QDragManager::drop(const QMouseEvent *me)
{
#ifndef QT_NO_CURSOR
if (restoreCursor) {
QGuiApplication::restoreOverrideCursor();
restoreCursor = false;
}
#endif
willDrop = false;
QWindow *window = QGuiApplication::topLevelAt(me->globalPos());
if (window) {
QPoint pos = me->globalPos() - window->geometry().topLeft();
QDropEvent de(pos, possible_actions, dropData(), me->buttons(), me->modifiers());
QCoreApplication::sendEvent(window, &de);
if (de.isAccepted())
global_accepted_action = de.dropAction();
else
global_accepted_action = Qt::IgnoreAction;
if (object)
object->deleteLater();
object = 0;
}
currentWindow = 0;
}
QDropData::QDropData()
: QInternalMimeData()
@ -286,6 +618,31 @@ QDropData::QDropData()
QDropData::~QDropData()
{
}
QVariant QDropData::retrieveData_sys(const QString &mimetype, QVariant::Type type) const
{
QDrag *object = QDragManager::self()->object;
if (!object)
return QVariant();
QByteArray data = object->mimeData()->data(mimetype);
if (type == QVariant::String)
return QString::fromUtf8(data);
return data;
}
bool QDropData::hasFormat_sys(const QString &format) const
{
return formats().contains(format);
}
QStringList QDropData::formats_sys() const
{
QDrag *object = QDragManager::self()->object;
if (object)
return object->mimeData()->formats();
return QStringList();
}
#endif // QT_NO_DRAGANDDROP
#if !(defined(QT_NO_DRAGANDDROP) && defined(QT_NO_CLIPBOARD))

View File

@ -65,6 +65,7 @@
QT_BEGIN_NAMESPACE
class QEventLoop;
class QMouseEvent;
#ifndef QT_NO_DRAGANDDROP
@ -106,24 +107,9 @@ public:
Qt::DropAction defaultDropAction;
};
class QDropData : public QInternalMimeData
{
Q_OBJECT
public:
QDropData();
~QDropData();
protected:
bool hasFormat_sys(const QString &mimeType) const;
QStringList formats_sys() const;
QVariant retrieveData_sys(const QString &mimeType, QVariant::Type type) const;
};
class Q_GUI_EXPORT QDragManager: public QObject {
class Q_GUI_EXPORT QDragManager : public QObject {
Q_OBJECT
QDragManager();
~QDragManager();
// only friend classes can use QDragManager.
friend class QDrag;
friend class QDragMoveEvent;
@ -131,44 +117,47 @@ class Q_GUI_EXPORT QDragManager: public QObject {
friend class QApplication;
bool eventFilter(QObject *, QEvent *);
void timerEvent(QTimerEvent*);
public:
Qt::DropAction drag(QDrag *);
void cancel(bool deleteSource = true);
void move(const QPoint &);
void drop();
void updatePixmap();
QObject *source() const { return object ? object->d_func()->source : 0; }
QDragPrivate *dragPrivate() const { return object ? object->d_func() : 0; }
static QDragPrivate *dragPrivate(QDrag *drag) { return drag ? drag->d_func() : 0; }
QDragManager();
~QDragManager();
static QDragManager *self();
virtual Qt::DropAction drag(QDrag *);
virtual void cancel(bool deleteSource = true);
virtual void move(const QMouseEvent *me);
virtual void drop(const QMouseEvent *me);
void updatePixmap();
void updateCursor();
Qt::DropAction defaultAction(Qt::DropActions possibleActions,
Qt::KeyboardModifiers modifiers) const;
QDrag *object;
QPixmap dragCursor(Qt::DropAction action) const;
void updateCursor();
QDragPrivate *dragPrivate() const { return object ? object->d_func() : 0; }
inline QMimeData *dropData()
{ return object ? dragPrivate()->data : platformDropData; }
QDrag *object;
QMimeData *platformDropData;
bool beingCancelled;
bool restoreCursor;
bool willDrop;
QEventLoop *eventLoop;
QPixmap dragCursor(Qt::DropAction action) const;
bool hasCustomDragCursors() const;
QDropData *dropData;
void emitActionChanged(Qt::DropAction newAction) { if (object) emit object->actionChanged(newAction); }
void setCurrentTarget(QObject *target, bool dropped = false);
QObject *currentTarget();
QWindow *currentWindow;
Qt::DropActions possible_actions;
private:
Qt::DropAction currentActionForOverrideCursor;
QObject *currentDropTarget;

View File

@ -1,422 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** 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, Nokia gives you certain additional
** rights. These rights are described in the Nokia 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.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qguiapplication.h"
#ifndef QT_NO_DRAGANDDROP
#include "qdatetime.h"
#include "qbitmap.h"
#include "qcursor.h"
#include "qevent.h"
#include "qpainter.h"
#include "qdnd_p.h"
#include "qwindow.h"
#include <qdebug.h>
QT_BEGIN_NAMESPACE
QT_USE_NAMESPACE
static QPixmap *defaultPm = 0;
static const int default_pm_hotx = -2;
static const int default_pm_hoty = -16;
static const char *const default_pm[] = {
"13 9 3 1",
". c None",
" c #000000",
"X c #FFFFFF",
"X X X X X X X",
" X X X X X X ",
"X ......... X",
" X.........X ",
"X ......... X",
" X.........X ",
"X ......... X",
" X X X X X X ",
"X X X X X X X",
};
// Shift/Ctrl handling, and final drop status
static Qt::DropAction global_accepted_action = Qt::CopyAction;
static Qt::DropActions possible_actions = Qt::IgnoreAction;
// static variables in place of a proper cross-process solution
static QDrag *drag_object;
static bool qt_qws_dnd_dragging = false;
static Qt::KeyboardModifiers oldstate;
class QShapedPixmapWindow : public QWindow {
QPixmap pixmap;
public:
QShapedPixmapWindow() :
QWindow(0)
{
setWindowFlags(Qt::Tool | Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint);
// ### Should we set the surface type to raster?
// ### FIXME
// setAttribute(Qt::WA_TransparentForMouseEvents);
}
void move(const QPoint &p) {
QRect g = geometry();
g.setTopLeft(p);
setGeometry(g);
}
void setPixmap(QPixmap pm)
{
pixmap = pm;
// ###
// if (!pixmap.mask().isNull()) {
// setMask(pixmap.mask());
// } else {
// clearMask();
// }
setGeometry(QRect(geometry().topLeft(), pm.size()));
}
// ### Get it painted again!
// void paintEvent(QPaintEvent*)
// {
// QPainter p(this);
// p.drawPixmap(0,0,pixmap);
// }
};
static QShapedPixmapWindow *qt_qws_dnd_deco = 0;
void QDragManager::updatePixmap()
{
if (qt_qws_dnd_deco) {
QPixmap pm;
QPoint pm_hot(default_pm_hotx,default_pm_hoty);
if (drag_object) {
pm = drag_object->pixmap();
if (!pm.isNull())
pm_hot = drag_object->hotSpot();
}
if (pm.isNull()) {
if (!defaultPm)
defaultPm = new QPixmap(default_pm);
pm = *defaultPm;
}
qt_qws_dnd_deco->setPixmap(pm);
qt_qws_dnd_deco->move(QCursor::pos()-pm_hot);
if (willDrop) {
qt_qws_dnd_deco->show();
} else {
qt_qws_dnd_deco->hide();
}
}
}
void QDragManager::timerEvent(QTimerEvent *) { }
void QDragManager::move(const QPoint &) { }
void QDragManager::updateCursor()
{
#ifndef QT_NO_CURSOR
if (willDrop) {
if (qt_qws_dnd_deco)
qt_qws_dnd_deco->show();
if (currentActionForOverrideCursor != global_accepted_action) {
QGuiApplication::changeOverrideCursor(QCursor(dragCursor(global_accepted_action), 0, 0));
currentActionForOverrideCursor = global_accepted_action;
}
} else {
QCursor *overrideCursor = QGuiApplication::overrideCursor();
if (!overrideCursor || overrideCursor->shape() != Qt::ForbiddenCursor) {
QGuiApplication::changeOverrideCursor(QCursor(Qt::ForbiddenCursor));
currentActionForOverrideCursor = Qt::IgnoreAction;
}
if (qt_qws_dnd_deco)
qt_qws_dnd_deco->hide();
}
#endif
}
bool QDragManager::eventFilter(QObject *o, QEvent *e)
{
if (beingCancelled) {
if (e->type() == QEvent::KeyRelease && static_cast<QKeyEvent*>(e)->key() == Qt::Key_Escape) {
qApp->removeEventFilter(this);
Q_ASSERT(object == 0);
beingCancelled = false;
eventLoop->exit();
return true; // block the key release
}
return false;
}
if (!qobject_cast<QWindow *>(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 = ((QKeyEvent*)e);
if (ke->key() == Qt::Key_Escape && e->type() == QEvent::KeyPress) {
cancel();
qApp->removeEventFilter(this);
beingCancelled = false;
eventLoop->exit();
} else {
updateCursor();
}
return true; // Eat all key events
}
case QEvent::MouseButtonPress:
case QEvent::MouseMove:
{
QMouseEvent *me = (QMouseEvent *)e;
QWindow *window = QGuiApplication::topLevelAt(me->globalPos());
QPoint pos;
if (window)
pos = me->globalPos() - window->geometry().topLeft();
qDebug() << window << o;
QMimeData *dropData = object ? dragPrivate()->data : this->dropData;
if (object)
possible_actions = dragPrivate()->possible_actions;
else
possible_actions = Qt::IgnoreAction;
if (me->buttons()) {
Qt::DropAction prevAction = global_accepted_action;
if (currentWindow != window) {
if (currentWindow) {
QDragLeaveEvent dle;
QCoreApplication::sendEvent(currentWindow, &dle);
willDrop = false;
global_accepted_action = Qt::IgnoreAction;
}
currentWindow = window;
if (currentWindow) {
QDragEnterEvent dee(pos, possible_actions, dropData, me->buttons(), me->modifiers());
QCoreApplication::sendEvent(currentWindow, &dee);
willDrop = dee.isAccepted() && dee.dropAction() != Qt::IgnoreAction;
global_accepted_action = willDrop ? dee.dropAction() : Qt::IgnoreAction;
}
updateCursor();
restoreCursor = true;
} else if (window) {
Q_ASSERT(currentWindow);
QDragMoveEvent dme(pos, possible_actions, dropData, me->buttons(), me->modifiers());
if (global_accepted_action != Qt::IgnoreAction) {
dme.setDropAction(global_accepted_action);
dme.accept();
}
QCoreApplication::sendEvent(currentWindow, &dme);
willDrop = dme.isAccepted();
global_accepted_action = willDrop ? dme.dropAction() : Qt::IgnoreAction;
updatePixmap();
updateCursor();
}
if (global_accepted_action != prevAction)
emitActionChanged(global_accepted_action);
}
return true; // Eat all mouse events
}
case QEvent::MouseButtonRelease:
{
qApp->removeEventFilter(this);
if (restoreCursor) {
willDrop = false;
#ifndef QT_NO_CURSOR
QGuiApplication::restoreOverrideCursor();
#endif
restoreCursor = false;
}
QMouseEvent *me = (QMouseEvent *)e;
QWindow *window = QGuiApplication::topLevelAt(me->globalPos());
if (window) {
QPoint pos = me->globalPos() - window->geometry().topLeft();
QMimeData *dropData = object ? dragPrivate()->data : this->dropData;
QDropEvent de(pos, possible_actions, dropData, me->buttons(), me->modifiers());
QCoreApplication::sendEvent(window, &de);
if (de.isAccepted())
global_accepted_action = de.dropAction();
else
global_accepted_action = Qt::IgnoreAction;
if (object)
object->deleteLater();
drag_object = object = 0;
}
currentWindow = 0;
eventLoop->exit();
return true; // Eat all mouse events
}
default:
break;
}
return false;
}
Qt::DropAction QDragManager::drag(QDrag *o)
{
if (object == o || !o || !o->source())
return Qt::IgnoreAction;
if (object) {
cancel();
qApp->removeEventFilter(this);
beingCancelled = false;
}
object = drag_object = o;
if (!qt_qws_dnd_deco)
qt_qws_dnd_deco = new QShapedPixmapWindow();
oldstate = Qt::NoModifier; // #### Should use state that caused the drag
// drag_mode = mode;
willDrop = false;
updatePixmap();
updateCursor();
restoreCursor = true;
object->d_func()->target = 0;
qApp->installEventFilter(this);
global_accepted_action = Qt::CopyAction;
#ifndef QT_NO_CURSOR
qApp->setOverrideCursor(Qt::ArrowCursor);
restoreCursor = true;
updateCursor();
#endif
qt_qws_dnd_dragging = true;
eventLoop = new QEventLoop;
(void) eventLoop->exec();
delete eventLoop;
eventLoop = 0;
delete qt_qws_dnd_deco;
qt_qws_dnd_deco = 0;
qt_qws_dnd_dragging = false;
return global_accepted_action;
}
void QDragManager::cancel(bool deleteSource)
{
// qDebug("QDragManager::cancel");
beingCancelled = true;
if (object->target()) {
QDragLeaveEvent dle;
QCoreApplication::sendEvent(object->target(), &dle);
}
#ifndef QT_NO_CURSOR
if (restoreCursor) {
QGuiApplication::restoreOverrideCursor();
restoreCursor = false;
}
#endif
if (drag_object) {
if (deleteSource)
object->deleteLater();
drag_object = object = 0;
}
delete qt_qws_dnd_deco;
qt_qws_dnd_deco = 0;
global_accepted_action = Qt::IgnoreAction;
}
void QDragManager::drop()
{
}
QVariant QDropData::retrieveData_sys(const QString &mimetype, QVariant::Type type) const
{
if (!drag_object)
return QVariant();
QByteArray data = drag_object->mimeData()->data(mimetype);
if (type == QVariant::String)
return QString::fromUtf8(data);
return data;
}
bool QDropData::hasFormat_sys(const QString &format) const
{
return formats().contains(format);
}
QStringList QDropData::formats_sys() const
{
if (drag_object)
return drag_object->mimeData()->formats();
return QStringList();
}
#endif // QT_NO_DRAGANDDROP
QT_END_NAMESPACE