Implement canceling of Qt-initiated drags.
- Add new virtual QPlatformDrag::cancelDrag() [avoiding a conflict with existing QBasicDrag::cancel()] - Implement on Windows by returning DRAGDROP_S_CANCEL from IOleDropSource::QueryContinueDrag() as suggested on report. - Implement in QBasicDrag by calling QBasicDrag::cancel() and quitting the event loop. - Add new API static void QDrag::cancel() for it. Task-number: QTBUG-47004 Change-Id: I4b4bb52e5fc226c8e04688ac1b0f9550daaf918e Reviewed-by: Jørgen Lind <jorgen.lind@theqtcompany.com> Reviewed-by: David Faure <david.faure@kdab.com>
This commit is contained in:
parent
746fbbe039
commit
6f65ddbc21
@ -33,6 +33,8 @@
|
|||||||
|
|
||||||
#include <qdrag.h>
|
#include <qdrag.h>
|
||||||
#include "private/qguiapplication_p.h"
|
#include "private/qguiapplication_p.h"
|
||||||
|
#include "qpa/qplatformintegration.h"
|
||||||
|
#include "qpa/qplatformdrag.h"
|
||||||
#include <qpixmap.h>
|
#include <qpixmap.h>
|
||||||
#include <qpoint.h>
|
#include <qpoint.h>
|
||||||
#include "qdnd_p.h"
|
#include "qdnd_p.h"
|
||||||
@ -223,6 +225,8 @@ QObject *QDrag::target() const
|
|||||||
loop. Other events are still delivered to the application while
|
loop. Other events are still delivered to the application while
|
||||||
the operation is performed. On Windows, the Qt event loop is
|
the operation is performed. On Windows, the Qt event loop is
|
||||||
blocked during the operation.
|
blocked during the operation.
|
||||||
|
|
||||||
|
\sa cancel()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Qt::DropAction QDrag::exec(Qt::DropActions supportedActions)
|
Qt::DropAction QDrag::exec(Qt::DropActions supportedActions)
|
||||||
@ -377,6 +381,21 @@ Qt::DropAction QDrag::defaultAction() const
|
|||||||
Q_D(const QDrag);
|
Q_D(const QDrag);
|
||||||
return d->default_action;
|
return d->default_action;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Cancels a drag operation initiated by Qt.
|
||||||
|
|
||||||
|
\note This is currently implemented on Windows and X11.
|
||||||
|
|
||||||
|
\since 5.6
|
||||||
|
\sa exec()
|
||||||
|
*/
|
||||||
|
void QDrag::cancel()
|
||||||
|
{
|
||||||
|
if (QPlatformDrag *platformDrag = QGuiApplicationPrivate::platformIntegration()->drag())
|
||||||
|
platformDrag->cancelDrag();
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\fn void QDrag::actionChanged(Qt::DropAction action)
|
\fn void QDrag::actionChanged(Qt::DropAction action)
|
||||||
|
|
||||||
|
@ -77,6 +77,8 @@ public:
|
|||||||
Qt::DropActions supportedActions() const;
|
Qt::DropActions supportedActions() const;
|
||||||
Qt::DropAction defaultAction() const;
|
Qt::DropAction defaultAction() const;
|
||||||
|
|
||||||
|
static void cancel();
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void actionChanged(Qt::DropAction action);
|
void actionChanged(Qt::DropAction action);
|
||||||
void targetChanged(QObject *newTarget);
|
void targetChanged(QObject *newTarget);
|
||||||
|
@ -154,6 +154,20 @@ Qt::DropAction QPlatformDrag::defaultAction(Qt::DropActions possibleActions,
|
|||||||
return default_action;
|
return default_action;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Cancels the currently active drag (only for drags of
|
||||||
|
the current application initiated by QPlatformDrag::drag()).
|
||||||
|
|
||||||
|
The default implementation does nothing.
|
||||||
|
|
||||||
|
\since 5.6
|
||||||
|
*/
|
||||||
|
|
||||||
|
void QPlatformDrag::cancelDrag()
|
||||||
|
{
|
||||||
|
Q_UNIMPLEMENTED();
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Called to notify QDrag about changes of the current action.
|
\brief Called to notify QDrag about changes of the current action.
|
||||||
*/
|
*/
|
||||||
|
@ -92,6 +92,7 @@ public:
|
|||||||
virtual QMimeData *platformDropData() = 0;
|
virtual QMimeData *platformDropData() = 0;
|
||||||
|
|
||||||
virtual Qt::DropAction drag(QDrag *m_drag) = 0;
|
virtual Qt::DropAction drag(QDrag *m_drag) = 0;
|
||||||
|
virtual void cancelDrag();
|
||||||
void updateAction(Qt::DropAction action);
|
void updateAction(Qt::DropAction action);
|
||||||
|
|
||||||
virtual Qt::DropAction defaultAction(Qt::DropActions possibleActions, Qt::KeyboardModifiers modifiers) const;
|
virtual Qt::DropAction defaultAction(Qt::DropActions possibleActions, Qt::KeyboardModifiers modifiers) const;
|
||||||
|
@ -191,6 +191,14 @@ Qt::DropAction QBasicDrag::drag(QDrag *o)
|
|||||||
return m_executed_drop_action;
|
return m_executed_drop_action;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QBasicDrag::cancelDrag()
|
||||||
|
{
|
||||||
|
if (m_eventLoop) {
|
||||||
|
cancel();
|
||||||
|
m_eventLoop->quit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void QBasicDrag::restoreCursor()
|
void QBasicDrag::restoreCursor()
|
||||||
{
|
{
|
||||||
if (m_restoreCursor) {
|
if (m_restoreCursor) {
|
||||||
|
@ -66,6 +66,7 @@ public:
|
|||||||
virtual ~QBasicDrag();
|
virtual ~QBasicDrag();
|
||||||
|
|
||||||
virtual Qt::DropAction drag(QDrag *drag) Q_DECL_OVERRIDE;
|
virtual Qt::DropAction drag(QDrag *drag) Q_DECL_OVERRIDE;
|
||||||
|
void cancelDrag() Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
virtual bool eventFilter(QObject *o, QEvent *e) Q_DECL_OVERRIDE;
|
virtual bool eventFilter(QObject *o, QEvent *e) Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
|
@ -397,7 +397,7 @@ QWindowsOleDropSource::QueryContinueDrag(BOOL fEscapePressed, DWORD grfKeyState)
|
|||||||
{
|
{
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
do {
|
do {
|
||||||
if (fEscapePressed) {
|
if (fEscapePressed || QWindowsDrag::isCanceled()) {
|
||||||
hr = ResultFromScode(DRAGDROP_S_CANCEL);
|
hr = ResultFromScode(DRAGDROP_S_CANCEL);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -677,6 +677,8 @@ QWindowsOleDropTarget::Drop(LPDATAOBJECT pDataObj, DWORD grfKeyState,
|
|||||||
\ingroup qt-lighthouse-win
|
\ingroup qt-lighthouse-win
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
bool QWindowsDrag::m_canceled = false;
|
||||||
|
|
||||||
QWindowsDrag::QWindowsDrag() :
|
QWindowsDrag::QWindowsDrag() :
|
||||||
m_dropDataObject(0), m_cachedDropTargetHelper(0)
|
m_dropDataObject(0), m_cachedDropTargetHelper(0)
|
||||||
{
|
{
|
||||||
@ -806,6 +808,7 @@ Qt::DropAction QWindowsDrag::drag(QDrag *drag)
|
|||||||
Qt::DropAction dragResult = Qt::IgnoreAction;
|
Qt::DropAction dragResult = Qt::IgnoreAction;
|
||||||
|
|
||||||
DWORD resultEffect;
|
DWORD resultEffect;
|
||||||
|
QWindowsDrag::m_canceled = false;
|
||||||
QWindowsOleDropSource *windowDropSource = new QWindowsOleDropSource(this);
|
QWindowsOleDropSource *windowDropSource = new QWindowsOleDropSource(this);
|
||||||
windowDropSource->createCursors();
|
windowDropSource->createCursors();
|
||||||
QWindowsOleDataObject *dropDataObject = new QWindowsOleDataObject(dropData);
|
QWindowsOleDataObject *dropDataObject = new QWindowsOleDataObject(dropData);
|
||||||
|
@ -87,6 +87,8 @@ public:
|
|||||||
Qt::DropAction drag(QDrag *drag) Q_DECL_OVERRIDE;
|
Qt::DropAction drag(QDrag *drag) Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
static QWindowsDrag *instance();
|
static QWindowsDrag *instance();
|
||||||
|
void cancelDrag() Q_DECL_OVERRIDE { QWindowsDrag::m_canceled = true; }
|
||||||
|
static bool isCanceled() { return QWindowsDrag::m_canceled; }
|
||||||
|
|
||||||
IDataObject *dropDataObject() const { return m_dropDataObject; }
|
IDataObject *dropDataObject() const { return m_dropDataObject; }
|
||||||
void setDropDataObject(IDataObject *dataObject) { m_dropDataObject = dataObject; }
|
void setDropDataObject(IDataObject *dataObject) { m_dropDataObject = dataObject; }
|
||||||
@ -98,6 +100,8 @@ public:
|
|||||||
QPixmap defaultCursor(Qt::DropAction action) const;
|
QPixmap defaultCursor(Qt::DropAction action) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
static bool m_canceled;
|
||||||
|
|
||||||
QWindowsDropMimeData m_dropData;
|
QWindowsDropMimeData m_dropData;
|
||||||
IDataObject *m_dropDataObject;
|
IDataObject *m_dropDataObject;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user