diff options
Diffstat (limited to 'src/gui/kernel/qdnd_win.cpp')
-rw-r--r-- | src/gui/kernel/qdnd_win.cpp | 1027 |
1 files changed, 0 insertions, 1027 deletions
diff --git a/src/gui/kernel/qdnd_win.cpp b/src/gui/kernel/qdnd_win.cpp deleted file mode 100644 index 073937fc45..0000000000 --- a/src/gui/kernel/qdnd_win.cpp +++ /dev/null @@ -1,1027 +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 "qapplication.h" - -#include "qapplication_p.h" -#include "qevent.h" -#include "qpainter.h" -#include "qwidget.h" -#include "qbuffer.h" -#include "qdatastream.h" -#include "qcursor.h" -#include "qt_windows.h" -#include <shlobj.h> -#ifndef QT_NO_ACCESSIBILITY -#include "qaccessible.h" -#endif -#include "qdnd_p.h" -#include "qdebug.h" - -#if defined(Q_OS_WINCE) -#include "qguifunctions_wince.h" -#endif - -// support for xbuttons -#ifndef MK_XBUTTON1 -#define MK_XBUTTON1 0x0020 -#define MK_XBUTTON2 0x0040 -#endif - -QT_BEGIN_NAMESPACE - -#if !(defined(QT_NO_DRAGANDDROP) && defined(QT_NO_CLIPBOARD)) - -//--------------------------------------------------------------------- -// QOleDataObject Constructor -//--------------------------------------------------------------------- - -QOleDataObject::QOleDataObject(QMimeData *mimeData) -{ - m_refs = 1; - data = mimeData; - CF_PERFORMEDDROPEFFECT = RegisterClipboardFormat(CFSTR_PERFORMEDDROPEFFECT); - performedEffect = DROPEFFECT_NONE; -} - -QOleDataObject::~QOleDataObject() -{ -} - -void QOleDataObject::releaseQt() -{ - data = 0; -} - -const QMimeData *QOleDataObject::mimeData() const -{ - return data; -} - -DWORD QOleDataObject::reportedPerformedEffect() const -{ - return performedEffect; -} - -//--------------------------------------------------------------------- -// IUnknown Methods -//--------------------------------------------------------------------- - -STDMETHODIMP -QOleDataObject::QueryInterface(REFIID iid, void FAR* FAR* ppv) -{ - if (iid == IID_IUnknown || iid == IID_IDataObject) { - *ppv = this; - AddRef(); - return NOERROR; - } - *ppv = NULL; - return ResultFromScode(E_NOINTERFACE); -} - -STDMETHODIMP_(ULONG) -QOleDataObject::AddRef(void) -{ - return ++m_refs; -} - -STDMETHODIMP_(ULONG) -QOleDataObject::Release(void) -{ - if (--m_refs == 0) { - releaseQt(); - delete this; - return 0; - } - return m_refs; -} - -//--------------------------------------------------------------------- -// IDataObject Methods -// -// The following methods are NOT supported for data transfer using the -// clipboard or drag-drop: -// -// IDataObject::SetData -- return E_NOTIMPL -// IDataObject::DAdvise -- return OLE_E_ADVISENOTSUPPORTED -// ::DUnadvise -// ::EnumDAdvise -// IDataObject::GetCanonicalFormatEtc -- return E_NOTIMPL -// (NOTE: must set pformatetcOut->ptd = NULL) -//--------------------------------------------------------------------- - -STDMETHODIMP -QOleDataObject::GetData(LPFORMATETC pformatetc, LPSTGMEDIUM pmedium) -{ -#ifdef QDND_DEBUG - qDebug("QOleDataObject::GetData(LPFORMATETC pformatetc, LPSTGMEDIUM pmedium)"); -#ifndef Q_OS_WINCE - wchar_t buf[256] = {0}; - GetClipboardFormatName(pformatetc->cfFormat, buf, 255); - qDebug("CF = %d : %s", pformatetc->cfFormat, QString::fromWCharArray(buf)); -#endif -#endif - - if (!data) - return ResultFromScode(DATA_E_FORMATETC); - - QWindowsMime *converter = QWindowsMime::converterFromMime(*pformatetc, data); - - if (converter && converter->convertFromMime(*pformatetc, data, pmedium)) - return ResultFromScode(S_OK); - else - return ResultFromScode(DATA_E_FORMATETC); -} - -STDMETHODIMP -QOleDataObject::GetDataHere(LPFORMATETC, LPSTGMEDIUM) -{ - return ResultFromScode(DATA_E_FORMATETC); -} - -STDMETHODIMP -QOleDataObject::QueryGetData(LPFORMATETC pformatetc) -{ -#ifdef QDND_DEBUG - qDebug("QOleDataObject::QueryGetData(LPFORMATETC pformatetc)"); -#endif - - if (!data) - return ResultFromScode(DATA_E_FORMATETC); - - if (QWindowsMime::converterFromMime(*pformatetc, data)) - return ResultFromScode(S_OK); - return ResultFromScode(S_FALSE); -} - -STDMETHODIMP -QOleDataObject::GetCanonicalFormatEtc(LPFORMATETC, LPFORMATETC pformatetcOut) -{ - pformatetcOut->ptd = NULL; - return ResultFromScode(E_NOTIMPL); -} - -STDMETHODIMP -QOleDataObject::SetData(LPFORMATETC pFormatetc, STGMEDIUM *pMedium, BOOL fRelease) -{ - if (pFormatetc->cfFormat == CF_PERFORMEDDROPEFFECT && pMedium->tymed == TYMED_HGLOBAL) { - DWORD * val = (DWORD*)GlobalLock(pMedium->hGlobal); - performedEffect = *val; - GlobalUnlock(pMedium->hGlobal); - if (fRelease) - ReleaseStgMedium(pMedium); - return ResultFromScode(S_OK); - } - return ResultFromScode(E_NOTIMPL); -} - - -STDMETHODIMP -QOleDataObject::EnumFormatEtc(DWORD dwDirection, LPENUMFORMATETC FAR* ppenumFormatEtc) -{ -#ifdef QDND_DEBUG - qDebug("QOleDataObject::EnumFormatEtc(DWORD dwDirection, LPENUMFORMATETC FAR* ppenumFormatEtc)"); -#endif - - if (!data) - return ResultFromScode(DATA_E_FORMATETC); - - SCODE sc = S_OK; - - QVector<FORMATETC> fmtetcs; - if (dwDirection == DATADIR_GET) { - fmtetcs = QWindowsMime::allFormatsForMime(data); - } else { - FORMATETC formatetc; - formatetc.cfFormat = CF_PERFORMEDDROPEFFECT; - formatetc.dwAspect = DVASPECT_CONTENT; - formatetc.lindex = -1; - formatetc.ptd = NULL; - formatetc.tymed = TYMED_HGLOBAL; - fmtetcs.append(formatetc); - } - - QOleEnumFmtEtc *enumFmtEtc = new QOleEnumFmtEtc(fmtetcs); - *ppenumFormatEtc = enumFmtEtc; - if (enumFmtEtc->isNull()) { - delete enumFmtEtc; - *ppenumFormatEtc = NULL; - sc = E_OUTOFMEMORY; - } - - return ResultFromScode(sc); -} - -STDMETHODIMP -QOleDataObject::DAdvise(FORMATETC FAR*, DWORD, - LPADVISESINK, DWORD FAR*) -{ - return ResultFromScode(OLE_E_ADVISENOTSUPPORTED); -} - - -STDMETHODIMP -QOleDataObject::DUnadvise(DWORD) -{ - return ResultFromScode(OLE_E_ADVISENOTSUPPORTED); -} - -STDMETHODIMP -QOleDataObject::EnumDAdvise(LPENUMSTATDATA FAR*) -{ - return ResultFromScode(OLE_E_ADVISENOTSUPPORTED); -} - -#endif // QT_NO_DRAGANDDROP && QT_NO_CLIPBOARD - -#ifndef QT_NO_DRAGANDDROP - -//#define QDND_DEBUG - -#ifdef QDND_DEBUG -extern QString dragActionsToString(Qt::DropActions actions); -#endif - -Qt::DropActions translateToQDragDropActions(DWORD pdwEffects) -{ - Qt::DropActions actions = Qt::IgnoreAction; - if (pdwEffects & DROPEFFECT_LINK) - actions |= Qt::LinkAction; - if (pdwEffects & DROPEFFECT_COPY) - actions |= Qt::CopyAction; - if (pdwEffects & DROPEFFECT_MOVE) - actions |= Qt::MoveAction; - return actions; -} - -Qt::DropAction translateToQDragDropAction(DWORD pdwEffect) -{ - if (pdwEffect & DROPEFFECT_LINK) - return Qt::LinkAction; - if (pdwEffect & DROPEFFECT_COPY) - return Qt::CopyAction; - if (pdwEffect & DROPEFFECT_MOVE) - return Qt::MoveAction; - return Qt::IgnoreAction; -} - -DWORD translateToWinDragEffects(Qt::DropActions action) -{ - DWORD effect = DROPEFFECT_NONE; - if (action & Qt::LinkAction) - effect |= DROPEFFECT_LINK; - if (action & Qt::CopyAction) - effect |= DROPEFFECT_COPY; - if (action & Qt::MoveAction) - effect |= DROPEFFECT_MOVE; - return effect; -} - -Qt::KeyboardModifiers toQtKeyboardModifiers(DWORD keyState) -{ - Qt::KeyboardModifiers modifiers = Qt::NoModifier; - - if (keyState & MK_SHIFT) - modifiers |= Qt::ShiftModifier; - if (keyState & MK_CONTROL) - modifiers |= Qt::ControlModifier; - if (keyState & MK_ALT) - modifiers |= Qt::AltModifier; - - return modifiers; -} - -Qt::MouseButtons toQtMouseButtons(DWORD keyState) -{ - Qt::MouseButtons buttons = Qt::NoButton; - - if (keyState & MK_LBUTTON) - buttons |= Qt::LeftButton; - if (keyState & MK_RBUTTON) - buttons |= Qt::RightButton; - if (keyState & MK_MBUTTON) - buttons |= Qt::MidButton; - - return buttons; -} - -class QOleDropSource : public IDropSource -{ -public: - QOleDropSource(); - virtual ~QOleDropSource(); - - void createCursors(); - - // IUnknown methods - STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObj); - STDMETHOD_(ULONG,AddRef)(void); - STDMETHOD_(ULONG,Release)(void); - - // IDropSource methods - STDMETHOD(QueryContinueDrag)(BOOL fEscapePressed, DWORD grfKeyState); - STDMETHOD(GiveFeedback)(DWORD dwEffect); - -private: - Qt::MouseButtons currentButtons; - Qt::DropAction currentAction; - QMap <Qt::DropAction, QCursor> cursors; - - ULONG m_refs; -}; - - -QOleDropSource::QOleDropSource() -{ - currentButtons = Qt::NoButton; - m_refs = 1; - currentAction = Qt::IgnoreAction; -} - -QOleDropSource::~QOleDropSource() -{ -} - -void QOleDropSource::createCursors() -{ - QDragManager *manager = QDragManager::self(); - if (manager && manager->object - && (!manager->object->pixmap().isNull() - || manager->hasCustomDragCursors())) { - QPixmap pm = manager->object->pixmap(); - QList<Qt::DropAction> actions; - actions << Qt::MoveAction << Qt::CopyAction << Qt::LinkAction; - if (!manager->object->pixmap().isNull()) - actions << Qt::IgnoreAction; - QPoint hotSpot = manager->object->hotSpot(); - for (int cnum = 0; cnum < actions.size(); ++cnum) { - QPixmap cpm = manager->dragCursor(actions.at(cnum)); - int w = cpm.width(); - int h = cpm.height(); - - if (!pm.isNull()) { - int x1 = qMin(-hotSpot.x(), 0); - int x2 = qMax(pm.width() - hotSpot.x(), cpm.width()); - int y1 = qMin(-hotSpot.y(), 0); - int y2 = qMax(pm.height() - hotSpot.y(), cpm.height()); - - w = x2 - x1 + 1; - h = y2 - y1 + 1; - } - - QRect srcRect = pm.rect(); - QPoint pmDest = QPoint(qMax(0, -hotSpot.x()), qMax(0, -hotSpot.y())); - QPoint newHotSpot = hotSpot; - -#if defined(Q_OS_WINCE) - // Limited cursor size - int reqw = GetSystemMetrics(SM_CXCURSOR); - int reqh = GetSystemMetrics(SM_CYCURSOR); - - QPoint hotspotInPM = newHotSpot - pmDest; - if (reqw < w) { - // Not wide enough - move objectpm right - qreal r = qreal(newHotSpot.x()) / w; - newHotSpot = QPoint(int(r * reqw), newHotSpot.y()); - if (newHotSpot.x() + cpm.width() > reqw) - newHotSpot.setX(reqw - cpm.width()); - - srcRect = QRect(QPoint(hotspotInPM.x() - newHotSpot.x(), srcRect.top()), QSize(reqw, srcRect.height())); - } - if (reqh < h) { - qreal r = qreal(newHotSpot.y()) / h; - newHotSpot = QPoint(newHotSpot.x(), int(r * reqh)); - if (newHotSpot.y() + cpm.height() > reqh) - newHotSpot.setY(reqh - cpm.height()); - - srcRect = QRect(QPoint(srcRect.left(), hotspotInPM.y() - newHotSpot.y()), QSize(srcRect.width(), reqh)); - } - // Always use system cursor size - w = reqw; - h = reqh; -#endif - - QPixmap newCursor(w, h); - if (!pm.isNull()) { - newCursor.fill(QColor(0, 0, 0, 0)); - QPainter p(&newCursor); - p.drawPixmap(pmDest, pm, srcRect); - p.drawPixmap(qMax(0,newHotSpot.x()),qMax(0,newHotSpot.y()),cpm); - } else { - newCursor = cpm; - } - -#ifndef QT_NO_CURSOR - cursors[actions.at(cnum)] = QCursor(newCursor, pm.isNull() ? 0 : qMax(0,newHotSpot.x()), - pm.isNull() ? 0 : qMax(0,newHotSpot.y())); -#endif - } - } -} - - - -//--------------------------------------------------------------------- -// IUnknown Methods -//--------------------------------------------------------------------- - - -STDMETHODIMP -QOleDropSource::QueryInterface(REFIID iid, void FAR* FAR* ppv) -{ - if(iid == IID_IUnknown || iid == IID_IDropSource) - { - *ppv = this; - ++m_refs; - return NOERROR; - } - *ppv = NULL; - return ResultFromScode(E_NOINTERFACE); -} - - -STDMETHODIMP_(ULONG) -QOleDropSource::AddRef(void) -{ - return ++m_refs; -} - - -STDMETHODIMP_(ULONG) -QOleDropSource::Release(void) -{ - if(--m_refs == 0) - { - delete this; - return 0; - } - return m_refs; -} - -static inline Qt::MouseButtons keystate_to_mousebutton(DWORD grfKeyState) -{ - Qt::MouseButtons result; - if (grfKeyState & MK_LBUTTON) - result |= Qt::LeftButton; - if (grfKeyState & MK_MBUTTON) - result |= Qt::MidButton; - if (grfKeyState & MK_RBUTTON) - result |= Qt::RightButton; - if (grfKeyState & MK_XBUTTON1) - result |= Qt::XButton1; - if (grfKeyState & MK_XBUTTON2) - result |= Qt::XButton2; - return result; -} - -//--------------------------------------------------------------------- -// IDropSource Methods -//--------------------------------------------------------------------- -QT_ENSURE_STACK_ALIGNED_FOR_SSE STDMETHODIMP -QOleDropSource::QueryContinueDrag(BOOL fEscapePressed, DWORD grfKeyState) -{ -#ifdef QDND_DEBUG - qDebug("QOleDropSource::QueryContinueDrag(fEscapePressed %d, grfKeyState %d)", fEscapePressed, grfKeyState); -#endif - - if (fEscapePressed) { - return ResultFromScode(DRAGDROP_S_CANCEL); - } else if ((GetAsyncKeyState(VK_LBUTTON) == 0) - && (GetAsyncKeyState(VK_MBUTTON) == 0) - && (GetAsyncKeyState(VK_RBUTTON) == 0)) { - // grfKeyState is broken on CE & some Windows XP versions, - // therefore we need to check the state manually - return ResultFromScode(DRAGDROP_S_DROP); - } else { -#if !defined(Q_OS_WINCE) - if (currentButtons == Qt::NoButton) { - currentButtons = keystate_to_mousebutton(grfKeyState); - } else { - Qt::MouseButtons buttons = keystate_to_mousebutton(grfKeyState); - if (!(currentButtons & buttons)) - return ResultFromScode(DRAGDROP_S_DROP); - } -#endif - QApplication::processEvents(); - return NOERROR; - } -} - -QT_ENSURE_STACK_ALIGNED_FOR_SSE STDMETHODIMP -QOleDropSource::GiveFeedback(DWORD dwEffect) -{ - Qt::DropAction action = translateToQDragDropAction(dwEffect); - -#ifdef QDND_DEBUG - qDebug("QOleDropSource::GiveFeedback(DWORD dwEffect)"); - qDebug("dwEffect = %s", dragActionsToString(action).toLatin1().data()); -#endif - - if (currentAction != action) { - currentAction = action; - QDragManager::self()->emitActionChanged(currentAction); - } - - if (cursors.contains(currentAction)) { -#ifndef QT_NO_CURSOR - SetCursor(cursors[currentAction].handle()); -#endif - return ResultFromScode(S_OK); - } - - return ResultFromScode(DRAGDROP_S_USEDEFAULTCURSORS); -} - -//--------------------------------------------------------------------- -// QOleDropTarget -//--------------------------------------------------------------------- - -QOleDropTarget::QOleDropTarget(QWidget* w) -: widget(w) -{ - m_refs = 1; -} - -void QOleDropTarget::releaseQt() -{ - widget = 0; -} - -//--------------------------------------------------------------------- -// IUnknown Methods -//--------------------------------------------------------------------- - - -STDMETHODIMP -QOleDropTarget::QueryInterface(REFIID iid, void FAR* FAR* ppv) -{ - if(iid == IID_IUnknown || iid == IID_IDropTarget) - { - *ppv = this; - AddRef(); - return NOERROR; - } - *ppv = NULL; - return ResultFromScode(E_NOINTERFACE); -} - - -STDMETHODIMP_(ULONG) -QOleDropTarget::AddRef(void) -{ - return ++m_refs; -} - - -STDMETHODIMP_(ULONG) -QOleDropTarget::Release(void) -{ - if(--m_refs == 0) - { - delete this; - return 0; - } - return m_refs; -} - -//--------------------------------------------------------------------- -// IDropTarget Methods -//--------------------------------------------------------------------- - -QT_ENSURE_STACK_ALIGNED_FOR_SSE STDMETHODIMP -QOleDropTarget::DragEnter(LPDATAOBJECT pDataObj, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect) -{ -#ifdef QDND_DEBUG - qDebug("QOleDropTarget::DragEnter(LPDATAOBJECT pDataObj, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect)"); -#endif - - if (!QApplicationPrivate::tryModalHelper(widget)) { - *pdwEffect = DROPEFFECT_NONE; - return NOERROR; - } - - QDragManager *manager = QDragManager::self(); - manager->dropData->currentDataObject = pDataObj; - manager->dropData->currentDataObject->AddRef(); - sendDragEnterEvent(widget, grfKeyState, pt, pdwEffect); - *pdwEffect = chosenEffect; - - return NOERROR; -} - -void QOleDropTarget::sendDragEnterEvent(QWidget *dragEnterWidget, DWORD grfKeyState, - POINTL pt, LPDWORD pdwEffect) -{ - Q_ASSERT(dragEnterWidget); - lastPoint = dragEnterWidget->mapFromGlobal(QPoint(pt.x,pt.y)); - lastKeyState = grfKeyState; - - chosenEffect = DROPEFFECT_NONE; - currentWidget = dragEnterWidget; - - QDragManager *manager = QDragManager::self(); - QMimeData * md = manager->source() ? manager->dragPrivate()->data : manager->dropData; - QDragEnterEvent enterEvent(lastPoint, translateToQDragDropActions(*pdwEffect), md, - toQtMouseButtons(grfKeyState), toQtKeyboardModifiers(grfKeyState)); - QApplication::sendEvent(dragEnterWidget, &enterEvent); - answerRect = enterEvent.answerRect(); - - if (enterEvent.isAccepted()) { - chosenEffect = translateToWinDragEffects(enterEvent.dropAction()); - } - - // Documentation states that a drag move event is sendt immidiatly after - // a drag enter event. This will honor widgets overriding dragMoveEvent only: - if (enterEvent.isAccepted()) { - QDragMoveEvent moveEvent(lastPoint, translateToQDragDropActions(*pdwEffect), md, - toQtMouseButtons(grfKeyState), toQtKeyboardModifiers(grfKeyState)); - answerRect = enterEvent.answerRect(); - moveEvent.setDropAction(enterEvent.dropAction()); - moveEvent.accept(); // accept by default, since enter event was accepted. - - QApplication::sendEvent(dragEnterWidget, &moveEvent); - if (moveEvent.isAccepted()) { - answerRect = moveEvent.answerRect(); - chosenEffect = translateToWinDragEffects(moveEvent.dropAction()); - } else { - chosenEffect = DROPEFFECT_NONE; - } - } - -} - -QT_ENSURE_STACK_ALIGNED_FOR_SSE STDMETHODIMP -QOleDropTarget::DragOver(DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect) -{ -#ifdef QDND_DEBUG - qDebug("QOleDropTarget::DragOver(grfKeyState %d, pt (%d,%d), pdwEffect %d)", grfKeyState, pt.x, pt.y, pdwEffect); -#endif - - QWidget *dragOverWidget = widget->childAt(widget->mapFromGlobal(QPoint(pt.x, pt.y))); - if (!dragOverWidget) - dragOverWidget = widget; - - - if (!QApplicationPrivate::tryModalHelper(dragOverWidget) - || !dragOverWidget->testAttribute(Qt::WA_DropSiteRegistered)) { - *pdwEffect = DROPEFFECT_NONE; - return NOERROR; - } - - QPoint tmpPoint = dragOverWidget->mapFromGlobal(QPoint(pt.x, pt.y)); - // see if we should compress this event - if ((tmpPoint == lastPoint || answerRect.contains(tmpPoint)) && lastKeyState == grfKeyState) { - *pdwEffect = chosenEffect; - return NOERROR; - } - - if (!dragOverWidget->internalWinId() && dragOverWidget != currentWidget) { - QPointer<QWidget> dragOverWidgetGuard(dragOverWidget); - // Send drag leave event to the previous drag widget. - QDragLeaveEvent dragLeave; - if (currentWidget) - QApplication::sendEvent(currentWidget, &dragLeave); - if (!dragOverWidgetGuard) { - dragOverWidget = widget->childAt(widget->mapFromGlobal(QPoint(pt.x, pt.y))); - if (!dragOverWidget) - dragOverWidget = widget; - } - // Send drag enter event to the current drag widget. - sendDragEnterEvent(dragOverWidget, grfKeyState, pt, pdwEffect); - } - - QDragManager *manager = QDragManager::self(); - QMimeData *md = manager->source() ? manager->dragPrivate()->data : manager->dropData; - - QDragMoveEvent oldEvent(lastPoint, translateToQDragDropActions(*pdwEffect), md, - toQtMouseButtons(lastKeyState), toQtKeyboardModifiers(lastKeyState)); - - - lastPoint = tmpPoint; - lastKeyState = grfKeyState; - - QDragMoveEvent e(lastPoint, translateToQDragDropActions(*pdwEffect), md, - toQtMouseButtons(grfKeyState), toQtKeyboardModifiers(grfKeyState)); - if (chosenEffect != DROPEFFECT_NONE) { - if (oldEvent.dropAction() == e.dropAction() && - oldEvent.keyboardModifiers() == e.keyboardModifiers()) - e.setDropAction(translateToQDragDropAction(chosenEffect)); - e.accept(); - } - QApplication::sendEvent(dragOverWidget, &e); - - answerRect = e.answerRect(); - if (e.isAccepted()) - chosenEffect = translateToWinDragEffects(e.dropAction()); - else - chosenEffect = DROPEFFECT_NONE; - *pdwEffect = chosenEffect; - - return NOERROR; -} - -QT_ENSURE_STACK_ALIGNED_FOR_SSE STDMETHODIMP -QOleDropTarget::DragLeave() -{ -#ifdef QDND_DEBUG - qDebug("QOleDropTarget::DragLeave()"); -#endif - - if (!QApplicationPrivate::tryModalHelper(widget)) { - return NOERROR; - } - - currentWidget = 0; - QDragLeaveEvent e; - QApplication::sendEvent(widget, &e); - - QDragManager *manager = QDragManager::self(); - - if (manager->dropData->currentDataObject) { // Sanity - manager->dropData->currentDataObject->Release(); - manager->dropData->currentDataObject = 0; - } - - return NOERROR; -} - -#define KEY_STATE_BUTTON_MASK (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON) - -QT_ENSURE_STACK_ALIGNED_FOR_SSE STDMETHODIMP -QOleDropTarget::Drop(LPDATAOBJECT /*pDataObj*/, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect) -{ -#ifdef QDND_DEBUG - qDebug("QOleDropTarget::Drop(LPDATAOBJECT /*pDataObj*/, grfKeyState %d, POINTL pt, LPDWORD pdwEffect)", grfKeyState); -#endif - - QWidget *dropWidget = widget->childAt(widget->mapFromGlobal(QPoint(pt.x, pt.y))); - if (!dropWidget) - dropWidget = widget; - - if (!QApplicationPrivate::tryModalHelper(dropWidget) - || !dropWidget->testAttribute(Qt::WA_DropSiteRegistered)) { - *pdwEffect = DROPEFFECT_NONE; - return NOERROR; - } - - lastPoint = dropWidget->mapFromGlobal(QPoint(pt.x,pt.y)); - // grfKeyState does not all ways contain button state in the drop so if - // it doesn't then use the last known button state; - if ((grfKeyState & KEY_STATE_BUTTON_MASK) == 0) - grfKeyState |= lastKeyState & KEY_STATE_BUTTON_MASK; - lastKeyState = grfKeyState; - - QDragManager *manager = QDragManager::self(); - QMimeData *md = manager->source() ? manager->dragPrivate()->data : manager->dropData; - QDropEvent e(lastPoint, translateToQDragDropActions(*pdwEffect), md, - toQtMouseButtons(grfKeyState), toQtKeyboardModifiers(grfKeyState)); - if (chosenEffect != DROPEFFECT_NONE) { - e.setDropAction(translateToQDragDropAction(chosenEffect)); - } - QApplication::sendEvent(dropWidget, &e); - - if (chosenEffect != DROPEFFECT_NONE) { - e.accept(); - } - - - if (e.isAccepted()) { - if (e.dropAction() == Qt::MoveAction || e.dropAction() == Qt::TargetMoveAction) { - if (e.dropAction() == Qt::MoveAction) - chosenEffect = DROPEFFECT_MOVE; - else - chosenEffect = DROPEFFECT_COPY; - HGLOBAL hData = GlobalAlloc(0, sizeof(DWORD)); - if (hData) { - DWORD *moveEffect = (DWORD *)GlobalLock(hData);; - *moveEffect = DROPEFFECT_MOVE; - GlobalUnlock(hData); - STGMEDIUM medium; - memset(&medium, 0, sizeof(STGMEDIUM)); - medium.tymed = TYMED_HGLOBAL; - medium.hGlobal = hData; - FORMATETC format; - format.cfFormat = RegisterClipboardFormat(CFSTR_PERFORMEDDROPEFFECT); - format.tymed = TYMED_HGLOBAL; - format.ptd = 0; - format.dwAspect = 1; - format.lindex = -1; - manager->dropData->currentDataObject->SetData(&format, &medium, true); - } - } else { - chosenEffect = translateToWinDragEffects(e.dropAction()); - } - } else { - chosenEffect = DROPEFFECT_NONE; - } - *pdwEffect = chosenEffect; - - - if (manager->dropData->currentDataObject) { - manager->dropData->currentDataObject->Release(); - manager->dropData->currentDataObject = 0; - } - - return NOERROR; - - // We won't get any mouserelease-event, so manually adjust qApp state: -///### test this QApplication::winMouseButtonUp(); -} - -//--------------------------------------------------------------------- -// QDropData -//--------------------------------------------------------------------- - -bool QDropData::hasFormat_sys(const QString &mimeType) const -{ - if (!currentDataObject) // Sanity - return false; - - return QWindowsMime::converterToMime(mimeType, currentDataObject) != 0; -} - -QStringList QDropData::formats_sys() const -{ - QStringList fmts; - if (!currentDataObject) // Sanity - return fmts; - - fmts = QWindowsMime::allMimesForFormats(currentDataObject); - - return fmts; -} - -QVariant QDropData::retrieveData_sys(const QString &mimeType, QVariant::Type type) const -{ - QVariant result; - - if (!currentDataObject) // Sanity - return result; - - QWindowsMime *converter = QWindowsMime::converterToMime(mimeType, currentDataObject); - - if (converter) - result = converter->convertToMime(mimeType, currentDataObject, type); - - return result; -} - -Qt::DropAction QDragManager::drag(QDrag *o) - -{ -#ifdef QDND_DEBUG - qDebug("QDragManager::drag(QDrag *drag)"); -#endif - - if (object == o || !o || !o->d_func()->source) - return Qt::IgnoreAction; - - if (object) { - cancel(); - qApp->removeEventFilter(this); - beingCancelled = false; - } - - object = o; - -#ifdef QDND_DEBUG - qDebug("actions = %s", dragActionsToString(dragPrivate()->possible_actions).toLatin1().data()); -#endif - - dragPrivate()->target = 0; - -#ifndef QT_NO_ACCESSIBILITY - QAccessible::updateAccessibility(this, 0, QAccessible::DragDropStart); -#endif - - DWORD resultEffect; - QOleDropSource *src = new QOleDropSource(); - src->createCursors(); - QOleDataObject *obj = new QOleDataObject(o->mimeData()); - DWORD allowedEffects = translateToWinDragEffects(dragPrivate()->possible_actions); - -#if !defined(Q_OS_WINCE) || defined(GWES_ICONCURS) - HRESULT r = DoDragDrop(obj, src, allowedEffects, &resultEffect); -#else - HRESULT r = DRAGDROP_S_CANCEL; - resultEffect = DROPEFFECT_MOVE; -#endif - - Qt::DropAction ret = Qt::IgnoreAction; - if (r == DRAGDROP_S_DROP) { - if (obj->reportedPerformedEffect() == DROPEFFECT_MOVE && resultEffect != DROPEFFECT_MOVE) { - ret = Qt::TargetMoveAction; - resultEffect = DROPEFFECT_MOVE; - } else { - ret = translateToQDragDropAction(resultEffect); - } - // Force it to be a copy if an unsupported operation occurred. - // This indicates a bug in the drop target. - if (resultEffect != DROPEFFECT_NONE && !(resultEffect & allowedEffects)) - ret = Qt::CopyAction; - } else { - dragPrivate()->target = 0; - } - - // clean up - obj->releaseQt(); - obj->Release(); // Will delete obj if refcount becomes 0 - src->Release(); // Will delete src if refcount becomes 0 - object = 0; - o->setMimeData(0); - o->deleteLater(); - -#ifndef QT_NO_ACCESSIBILITY - QAccessible::updateAccessibility(this, 0, QAccessible::DragDropEnd); -#endif - - return ret; -} - -void QDragManager::cancel(bool /* deleteSource */) -{ - if (object) { - beingCancelled = true; - object = 0; - } - -#ifndef QT_NO_CURSOR - // insert cancel code here ######## todo - - if (restoreCursor) { - QApplication::restoreOverrideCursor(); - restoreCursor = false; - } -#endif -#ifndef QT_NO_ACCESSIBILITY - QAccessible::updateAccessibility(this, 0, QAccessible::DragDropEnd); -#endif -} - -void QDragManager::updatePixmap() -{ - // not used in windows implementation -} - -bool QDragManager::eventFilter(QObject *, QEvent *) -{ - // not used in windows implementation - return false; -} - -void QDragManager::timerEvent(QTimerEvent*) -{ - // not used in windows implementation -} - -void QDragManager::move(const QPoint &) -{ - // not used in windows implementation -} - -void QDragManager::drop() -{ - // not used in windows implementation -} - -QT_END_NAMESPACE - -#endif // QT_NO_DRAGANDDROP |