From 38e02188ee132fd8c483fcb9773979875677c070 Mon Sep 17 00:00:00 2001 From: Cyril Oblikov Date: Thu, 27 Sep 2012 17:55:16 +0300 Subject: [PATCH] Possibility to change custom Drag&Drop cursors while dragging something. Implementation for Windows and X11. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Additional checks to figure out if new Drag&Drop cursors where set. This means it is possible now to keep QDrag object in your program and call setDragCursor() method every time we need to change cursor depending on context. Change-Id: I4be69e44b2863371a7ffbb29efc17c18210d6cde Reviewed-by: Friedemann Kleint Reviewed-by: Gatis Paeglis Reviewed-by: Samuel Rødal --- src/platformsupport/dnd/qsimpledrag.cpp | 15 ++++++- .../platforms/windows/qwindowsdrag.cpp | 40 +++++++++++-------- 2 files changed, 36 insertions(+), 19 deletions(-) diff --git a/src/platformsupport/dnd/qsimpledrag.cpp b/src/platformsupport/dnd/qsimpledrag.cpp index d8ef17ede3..18e6b97e3c 100644 --- a/src/platformsupport/dnd/qsimpledrag.cpp +++ b/src/platformsupport/dnd/qsimpledrag.cpp @@ -253,8 +253,19 @@ void QBasicDrag::updateCursor(Qt::DropAction action) } QCursor *cursor = qApp->overrideCursor(); - if (cursor && cursorShape != cursor->shape()) { - qApp->changeOverrideCursor(QCursor(cursorShape)); + 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)); + } + } } updateAction(action); } diff --git a/src/plugins/platforms/windows/qwindowsdrag.cpp b/src/plugins/platforms/windows/qwindowsdrag.cpp index ad2ff22f1d..a0434fb6f3 100644 --- a/src/plugins/platforms/windows/qwindowsdrag.cpp +++ b/src/plugins/platforms/windows/qwindowsdrag.cpp @@ -301,9 +301,15 @@ public: STDMETHOD(GiveFeedback)(DWORD dwEffect); private: - typedef QMap ActionCursorMap; - - inline void clearCursors(); + class DragCursorHandle { + Q_DISABLE_COPY(DragCursorHandle) + public: + DragCursorHandle(HCURSOR c, quint64 k) : cursor(c), cacheKey(k) {} + ~DragCursorHandle() { DestroyCursor(cursor); } + HCURSOR cursor; + quint64 cacheKey; + }; + typedef QMap > ActionCursorMap; QWindowsDrag *m_drag; Qt::MouseButtons m_currentButtons; @@ -322,7 +328,7 @@ QWindowsOleDropSource::QWindowsOleDropSource(QWindowsDrag *drag) : QWindowsOleDropSource::~QWindowsOleDropSource() { - clearCursors(); + m_cursors.clear(); if (QWindowsContext::verboseOLE) qDebug("%s", __FUNCTION__); } @@ -347,10 +353,14 @@ void QWindowsOleDropSource::createCursors() QPixmap cpm = drag->dragCursor(action); if (cpm.isNull()) cpm = m_drag->defaultCursor(action); + QSharedPointer cursorHandler = m_cursors.value(action); + if (!cursorHandler.isNull() && cpm.cacheKey() == cursorHandler->cacheKey) + continue; if (cpm.isNull()) { qWarning("%s: Unable to obtain drag cursor for %d.", __FUNCTION__, action); continue; } + int w = cpm.width(); int h = cpm.height(); @@ -380,23 +390,14 @@ void QWindowsOleDropSource::createCursors() const int hotX = hasPixmap ? qMax(0,newHotSpot.x()) : 0; const int hotY = hasPixmap ? qMax(0,newHotSpot.y()) : 0; - if (const HCURSOR sysCursor = QWindowsCursor::createPixmapCursor(newCursor, hotX, hotY)) - m_cursors.insert(actions.at(cnum), sysCursor); + if (const HCURSOR sysCursor = QWindowsCursor::createPixmapCursor(newCursor, hotX, hotY)) { + m_cursors.insert(action, QSharedPointer(new DragCursorHandle(sysCursor, cpm.cacheKey()))); + } } if (QWindowsContext::verboseOLE) qDebug("%s %d cursors", __FUNCTION__, m_cursors.size()); } -void QWindowsOleDropSource::clearCursors() -{ - if (!m_cursors.isEmpty()) { - const ActionCursorMap::const_iterator cend = m_cursors.constEnd(); - for (ActionCursorMap::const_iterator it = m_cursors.constBegin(); it != cend; ++it) - DestroyCursor(it.value()); - m_cursors.clear(); - } -} - //--------------------------------------------------------------------- // IUnknown Methods //--------------------------------------------------------------------- @@ -488,9 +489,14 @@ QWindowsOleDropSource::GiveFeedback(DWORD dwEffect) if (QWindowsContext::verboseOLE > 2) qDebug("%s dwEffect=%lu, action=%d", __FUNCTION__, dwEffect, action); + QSharedPointer cursorHandler = m_cursors.value(action); + quint64 currentCacheKey = m_drag->currentDrag()->dragCursor(action).cacheKey(); + if (cursorHandler.isNull() || currentCacheKey != cursorHandler->cacheKey) + createCursors(); + const ActionCursorMap::const_iterator it = m_cursors.constFind(action); if (it != m_cursors.constEnd()) { - SetCursor(it.value()); + SetCursor(it.value()->cursor); return ResultFromScode(S_OK); }