source: trunk/src/gui/kernel/qdnd_win.cpp@ 441

Last change on this file since 441 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 30.0 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the QtGui module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qapplication.h"
43
44#include "qapplication_p.h"
45#include "qevent.h"
46#include "qpainter.h"
47#include "qwidget.h"
48#include "qbuffer.h"
49#include "qdatastream.h"
50#include "qcursor.h"
51#include "qt_windows.h"
52#include <shlobj.h>
53#ifndef QT_NO_ACCESSIBILITY
54#include "qaccessible.h"
55#endif
56#include "qdnd_p.h"
57#include "qdebug.h"
58
59#if defined(Q_OS_WINCE)
60#include "qguifunctions_wince.h"
61#endif
62
63// support for xbuttons
64#ifndef MK_XBUTTON1
65#define MK_XBUTTON1 0x0020
66#define MK_XBUTTON2 0x0040
67#endif
68
69QT_BEGIN_NAMESPACE
70
71#if !(defined(QT_NO_DRAGANDDROP) && defined(QT_NO_CLIPBOARD))
72
73//---------------------------------------------------------------------
74// QOleDataObject Constructor
75//---------------------------------------------------------------------
76
77QOleDataObject::QOleDataObject(QMimeData *mimeData)
78{
79 m_refs = 1;
80 data = mimeData;
81 CF_PERFORMEDDROPEFFECT = RegisterClipboardFormat(CFSTR_PERFORMEDDROPEFFECT);
82 performedEffect = DROPEFFECT_NONE;
83}
84
85QOleDataObject::~QOleDataObject()
86{
87}
88
89void QOleDataObject::releaseQt()
90{
91 data = 0;
92}
93
94const QMimeData *QOleDataObject::mimeData() const
95{
96 return data;
97}
98
99DWORD QOleDataObject::reportedPerformedEffect() const
100{
101 return performedEffect;
102}
103
104//---------------------------------------------------------------------
105// IUnknown Methods
106//---------------------------------------------------------------------
107
108STDMETHODIMP
109QOleDataObject::QueryInterface(REFIID iid, void FAR* FAR* ppv)
110{
111 if (iid == IID_IUnknown || iid == IID_IDataObject) {
112 *ppv = this;
113 AddRef();
114 return NOERROR;
115 }
116 *ppv = NULL;
117 return ResultFromScode(E_NOINTERFACE);
118}
119
120STDMETHODIMP_(ULONG)
121QOleDataObject::AddRef(void)
122{
123 return ++m_refs;
124}
125
126STDMETHODIMP_(ULONG)
127QOleDataObject::Release(void)
128{
129 if (--m_refs == 0) {
130 releaseQt();
131 delete this;
132 return 0;
133 }
134 return m_refs;
135}
136
137//---------------------------------------------------------------------
138// IDataObject Methods
139//
140// The following methods are NOT supported for data transfer using the
141// clipboard or drag-drop:
142//
143// IDataObject::SetData -- return E_NOTIMPL
144// IDataObject::DAdvise -- return OLE_E_ADVISENOTSUPPORTED
145// ::DUnadvise
146// ::EnumDAdvise
147// IDataObject::GetCanonicalFormatEtc -- return E_NOTIMPL
148// (NOTE: must set pformatetcOut->ptd = NULL)
149//---------------------------------------------------------------------
150
151STDMETHODIMP
152QOleDataObject::GetData(LPFORMATETC pformatetc, LPSTGMEDIUM pmedium)
153{
154#ifdef QDND_DEBUG
155 qDebug("QOleDataObject::GetData(LPFORMATETC pformatetc, LPSTGMEDIUM pmedium)");
156#ifndef Q_OS_WINCE
157 char buf[256] = {0};
158 GetClipboardFormatNameA(pformatetc->cfFormat, buf, 255);
159 qDebug("CF = %d : %s", pformatetc->cfFormat, buf);
160#endif
161#endif
162
163 if (!data)
164 return ResultFromScode(DATA_E_FORMATETC);
165
166 QWindowsMime *converter = QWindowsMime::converterFromMime(*pformatetc, data);
167
168 if (converter && converter->convertFromMime(*pformatetc, data, pmedium))
169 return ResultFromScode(S_OK);
170 else
171 return ResultFromScode(DATA_E_FORMATETC);
172}
173
174STDMETHODIMP
175QOleDataObject::GetDataHere(LPFORMATETC, LPSTGMEDIUM)
176{
177 return ResultFromScode(DATA_E_FORMATETC);
178}
179
180STDMETHODIMP
181QOleDataObject::QueryGetData(LPFORMATETC pformatetc)
182{
183#ifdef QDND_DEBUG
184 qDebug("QOleDataObject::QueryGetData(LPFORMATETC pformatetc)");
185#endif
186
187 if (!data)
188 return ResultFromScode(DATA_E_FORMATETC);
189
190 if (QWindowsMime::converterFromMime(*pformatetc, data))
191 return ResultFromScode(S_OK);
192 return ResultFromScode(S_FALSE);
193}
194
195STDMETHODIMP
196QOleDataObject::GetCanonicalFormatEtc(LPFORMATETC, LPFORMATETC pformatetcOut)
197{
198 pformatetcOut->ptd = NULL;
199 return ResultFromScode(E_NOTIMPL);
200}
201
202STDMETHODIMP
203QOleDataObject::SetData(LPFORMATETC pFormatetc, STGMEDIUM *pMedium, BOOL fRelease)
204{
205 if (pFormatetc->cfFormat == CF_PERFORMEDDROPEFFECT && pMedium->tymed == TYMED_HGLOBAL) {
206 DWORD * val = (DWORD*)GlobalLock(pMedium->hGlobal);
207 performedEffect = *val;
208 GlobalUnlock(pMedium->hGlobal);
209 if (fRelease)
210 ReleaseStgMedium(pMedium);
211 return ResultFromScode(S_OK);
212 }
213 return ResultFromScode(E_NOTIMPL);
214}
215
216
217STDMETHODIMP
218QOleDataObject::EnumFormatEtc(DWORD dwDirection, LPENUMFORMATETC FAR* ppenumFormatEtc)
219{
220#ifdef QDND_DEBUG
221 qDebug("QOleDataObject::EnumFormatEtc(DWORD dwDirection, LPENUMFORMATETC FAR* ppenumFormatEtc)");
222#endif
223
224 if (!data)
225 return ResultFromScode(DATA_E_FORMATETC);
226
227 SCODE sc = S_OK;
228
229 QVector<FORMATETC> fmtetcs;
230 if (dwDirection == DATADIR_GET) {
231 fmtetcs = QWindowsMime::allFormatsForMime(data);
232 } else {
233 FORMATETC formatetc;
234 formatetc.cfFormat = CF_PERFORMEDDROPEFFECT;
235 formatetc.dwAspect = DVASPECT_CONTENT;
236 formatetc.lindex = -1;
237 formatetc.ptd = NULL;
238 formatetc.tymed = TYMED_HGLOBAL;
239 fmtetcs.append(formatetc);
240 }
241
242 QOleEnumFmtEtc *enumFmtEtc = new QOleEnumFmtEtc(fmtetcs);
243 *ppenumFormatEtc = enumFmtEtc;
244 if (enumFmtEtc->isNull()) {
245 delete enumFmtEtc;
246 *ppenumFormatEtc = NULL;
247 sc = E_OUTOFMEMORY;
248 }
249
250 return ResultFromScode(sc);
251}
252
253STDMETHODIMP
254QOleDataObject::DAdvise(FORMATETC FAR*, DWORD,
255 LPADVISESINK, DWORD FAR*)
256{
257 return ResultFromScode(OLE_E_ADVISENOTSUPPORTED);
258}
259
260
261STDMETHODIMP
262QOleDataObject::DUnadvise(DWORD)
263{
264 return ResultFromScode(OLE_E_ADVISENOTSUPPORTED);
265}
266
267STDMETHODIMP
268QOleDataObject::EnumDAdvise(LPENUMSTATDATA FAR*)
269{
270 return ResultFromScode(OLE_E_ADVISENOTSUPPORTED);
271}
272
273#endif // QT_NO_DRAGANDDROP && QT_NO_CLIPBOARD
274
275#ifndef QT_NO_DRAGANDDROP
276
277//#define QDND_DEBUG
278
279#ifdef QDND_DEBUG
280extern QString dragActionsToString(Qt::DropActions actions);
281#endif
282
283Qt::DropActions translateToQDragDropActions(DWORD pdwEffects)
284{
285 Qt::DropActions actions = Qt::IgnoreAction;
286 if (pdwEffects & DROPEFFECT_LINK)
287 actions |= Qt::LinkAction;
288 if (pdwEffects & DROPEFFECT_COPY)
289 actions |= Qt::CopyAction;
290 if (pdwEffects & DROPEFFECT_MOVE)
291 actions |= Qt::MoveAction;
292 return actions;
293}
294
295Qt::DropAction translateToQDragDropAction(DWORD pdwEffect)
296{
297 if (pdwEffect & DROPEFFECT_LINK)
298 return Qt::LinkAction;
299 if (pdwEffect & DROPEFFECT_COPY)
300 return Qt::CopyAction;
301 if (pdwEffect & DROPEFFECT_MOVE)
302 return Qt::MoveAction;
303 return Qt::IgnoreAction;
304}
305
306DWORD translateToWinDragEffects(Qt::DropActions action)
307{
308 DWORD effect = DROPEFFECT_NONE;
309 if (action & Qt::LinkAction)
310 effect |= DROPEFFECT_LINK;
311 if (action & Qt::CopyAction)
312 effect |= DROPEFFECT_COPY;
313 if (action & Qt::MoveAction)
314 effect |= DROPEFFECT_MOVE;
315 return effect;
316}
317
318Qt::KeyboardModifiers toQtKeyboardModifiers(DWORD keyState)
319{
320 Qt::KeyboardModifiers modifiers = Qt::NoModifier;
321