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 "private/qguiapplication_p.h"
|
||||
#include "qpa/qplatformintegration.h"
|
||||
#include "qpa/qplatformdrag.h"
|
||||
#include <qpixmap.h>
|
||||
#include <qpoint.h>
|
||||
#include "qdnd_p.h"
|
||||
@ -223,6 +225,8 @@ QObject *QDrag::target() const
|
||||
loop. Other events are still delivered to the application while
|
||||
the operation is performed. On Windows, the Qt event loop is
|
||||
blocked during the operation.
|
||||
|
||||
\sa cancel()
|
||||
*/
|
||||
|
||||
Qt::DropAction QDrag::exec(Qt::DropActions supportedActions)
|
||||
@ -377,6 +381,21 @@ Qt::DropAction QDrag::defaultAction() const
|
||||
Q_D(const QDrag);
|
||||
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)
|
||||
|
||||
|
@ -77,6 +77,8 @@ public:
|
||||
Qt::DropActions supportedActions() const;
|
||||
Qt::DropAction defaultAction() const;
|
||||
|
||||
static void cancel();
|
||||
|
||||
Q_SIGNALS:
|
||||
void actionChanged(Qt::DropAction action);
|
||||
void targetChanged(QObject *newTarget);
|
||||
|
@ -154,6 +154,20 @@ Qt::DropAction QPlatformDrag::defaultAction(Qt::DropActions possibleActions,
|
||||
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.
|
||||
*/
|
||||
|
@ -92,6 +92,7 @@ public:
|
||||
virtual QMimeData *platformDropData() = 0;
|
||||
|
||||
virtual Qt::DropAction drag(QDrag *m_drag) = 0;
|
||||
virtual void cancelDrag();
|
||||
void updateAction(Qt::DropAction action);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void QBasicDrag::cancelDrag()
|
||||
{
|
||||
if (m_eventLoop) {
|
||||
cancel();
|
||||
m_eventLoop->quit();
|
||||
}
|
||||
}
|
||||
|
||||
void QBasicDrag::restoreCursor()
|
||||
{
|
||||
if (m_restoreCursor) {
|
||||
|
@ -66,6 +66,7 @@ public:
|
||||
virtual ~QBasicDrag();
|
||||
|
||||
virtual Qt::DropAction drag(QDrag *drag) Q_DECL_OVERRIDE;
|
||||
void cancelDrag() 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;
|
||||
do {
|
||||
if (fEscapePressed) {
|
||||
if (fEscapePressed || QWindowsDrag::isCanceled()) {
|
||||
hr = ResultFromScode(DRAGDROP_S_CANCEL);
|
||||
break;
|
||||
}
|
||||
@ -677,6 +677,8 @@ QWindowsOleDropTarget::Drop(LPDATAOBJECT pDataObj, DWORD grfKeyState,
|
||||
\ingroup qt-lighthouse-win
|
||||
*/
|
||||
|
||||
bool QWindowsDrag::m_canceled = false;
|
||||
|
||||
QWindowsDrag::QWindowsDrag() :
|
||||
m_dropDataObject(0), m_cachedDropTargetHelper(0)
|
||||
{
|
||||
@ -806,6 +808,7 @@ Qt::DropAction QWindowsDrag::drag(QDrag *drag)
|
||||
Qt::DropAction dragResult = Qt::IgnoreAction;
|
||||
|
||||
DWORD resultEffect;
|
||||
QWindowsDrag::m_canceled = false;
|
||||
QWindowsOleDropSource *windowDropSource = new QWindowsOleDropSource(this);
|
||||
windowDropSource->createCursors();
|
||||
QWindowsOleDataObject *dropDataObject = new QWindowsOleDataObject(dropData);
|
||||
|
@ -87,6 +87,8 @@ public:
|
||||
Qt::DropAction drag(QDrag *drag) Q_DECL_OVERRIDE;
|
||||
|
||||
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; }
|
||||
void setDropDataObject(IDataObject *dataObject) { m_dropDataObject = dataObject; }
|
||||
@ -98,6 +100,8 @@ public:
|
||||
QPixmap defaultCursor(Qt::DropAction action) const;
|
||||
|
||||
private:
|
||||
static bool m_canceled;
|
||||
|
||||
QWindowsDropMimeData m_dropData;
|
||||
IDataObject *m_dropDataObject;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user