1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). |
4 | ** Contact: http://www.qt-project.org/legal |
5 | ** |
6 | ** This file is part of the QtGui module of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:LGPL$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and Digia. For licensing terms and |
14 | ** conditions see http://qt.digia.com/licensing. For further information |
15 | ** use the contact form at http://qt.digia.com/contact-us. |
16 | ** |
17 | ** GNU Lesser General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU Lesser |
19 | ** General Public License version 2.1 as published by the Free Software |
20 | ** Foundation and appearing in the file LICENSE.LGPL included in the |
21 | ** packaging of this file. Please review the following information to |
22 | ** ensure the GNU Lesser General Public License version 2.1 requirements |
23 | ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
24 | ** |
25 | ** In addition, as a special exception, Digia gives you certain additional |
26 | ** rights. These rights are described in the Digia Qt LGPL Exception |
27 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
28 | ** |
29 | ** GNU General Public License Usage |
30 | ** Alternatively, this file may be used under the terms of the GNU |
31 | ** General Public License version 3.0 as published by the Free Software |
32 | ** Foundation and appearing in the file LICENSE.GPL included in the |
33 | ** packaging of this file. Please review the following information to |
34 | ** ensure the GNU General Public License version 3.0 requirements will be |
35 | ** met: http://www.gnu.org/copyleft/gpl.html. |
36 | ** |
37 | ** |
38 | ** $QT_END_LICENSE$ |
39 | ** |
40 | ****************************************************************************/ |
41 | |
42 | #ifndef QDND_P_H |
43 | #define QDND_P_H |
44 | |
45 | // |
46 | // W A R N I N G |
47 | // ------------- |
48 | // |
49 | // This file is not part of the Qt API. It exists for the convenience |
50 | // of other Qt classes. This header file may change from version to |
51 | // version without notice, or even be removed. |
52 | // |
53 | // We mean it. |
54 | // |
55 | |
56 | #include "QtCore/qobject.h" |
57 | #include "QtCore/qmap.h" |
58 | #include "QtGui/qmime.h" |
59 | #include "QtGui/qdrag.h" |
60 | #include "QtGui/qpixmap.h" |
61 | #include "QtGui/qcursor.h" |
62 | #include "QtCore/qpoint.h" |
63 | #include "private/qobject_p.h" |
64 | #ifdef Q_WS_MAC |
65 | # include "private/qt_mac_p.h" |
66 | #endif |
67 | |
68 | #if defined(Q_WS_WIN) |
69 | # include <qt_windows.h> |
70 | # include <objidl.h> |
71 | #endif |
72 | |
73 | QT_BEGIN_NAMESPACE |
74 | |
75 | class QEventLoop; |
76 | |
77 | #if !(defined(QT_NO_DRAGANDDROP) && defined(QT_NO_CLIPBOARD)) |
78 | |
79 | class Q_GUI_EXPORT QInternalMimeData : public QMimeData |
80 | { |
81 | Q_OBJECT |
82 | public: |
83 | QInternalMimeData(); |
84 | ~QInternalMimeData(); |
85 | |
86 | bool hasFormat(const QString &mimeType) const; |
87 | QStringList formats() const; |
88 | static bool canReadData(const QString &mimeType); |
89 | |
90 | |
91 | static QStringList formatsHelper(const QMimeData *data); |
92 | static bool hasFormatHelper(const QString &mimeType, const QMimeData *data); |
93 | static QByteArray renderDataHelper(const QString &mimeType, const QMimeData *data); |
94 | |
95 | protected: |
96 | QVariant retrieveData(const QString &mimeType, QVariant::Type type) const; |
97 | |
98 | virtual bool hasFormat_sys(const QString &mimeType) const = 0; |
99 | virtual QStringList formats_sys() const = 0; |
100 | virtual QVariant retrieveData_sys(const QString &mimeType, QVariant::Type type) const = 0; |
101 | }; |
102 | |
103 | #ifdef Q_WS_WIN |
104 | class QOleDataObject : public IDataObject |
105 | { |
106 | public: |
107 | explicit QOleDataObject(QMimeData *mimeData); |
108 | virtual ~QOleDataObject(); |
109 | |
110 | void releaseQt(); |
111 | const QMimeData *mimeData() const; |
112 | DWORD reportedPerformedEffect() const; |
113 | |
114 | // IUnknown methods |
115 | STDMETHOD(QueryInterface)(REFIID riid, void FAR* FAR* ppvObj); |
116 | STDMETHOD_(ULONG,AddRef)(void); |
117 | STDMETHOD_(ULONG,Release)(void); |
118 | |
119 | // IDataObject methods |
120 | STDMETHOD(GetData)(LPFORMATETC pformatetcIn, LPSTGMEDIUM pmedium); |
121 | STDMETHOD(GetDataHere)(LPFORMATETC pformatetc, LPSTGMEDIUM pmedium); |
122 | STDMETHOD(QueryGetData)(LPFORMATETC pformatetc); |
123 | STDMETHOD(GetCanonicalFormatEtc)(LPFORMATETC pformatetc, LPFORMATETC pformatetcOut); |
124 | STDMETHOD(SetData)(LPFORMATETC pformatetc, STGMEDIUM FAR * pmedium, |
125 | BOOL fRelease); |
126 | STDMETHOD(EnumFormatEtc)(DWORD dwDirection, LPENUMFORMATETC FAR* ppenumFormatEtc); |
127 | STDMETHOD(DAdvise)(FORMATETC FAR* pFormatetc, DWORD advf, |
128 | LPADVISESINK pAdvSink, DWORD FAR* pdwConnection); |
129 | STDMETHOD(DUnadvise)(DWORD dwConnection); |
130 | STDMETHOD(EnumDAdvise)(LPENUMSTATDATA FAR* ppenumAdvise); |
131 | |
132 | private: |
133 | ULONG m_refs; |
134 | QPointer<QMimeData> data; |
135 | int CF_PERFORMEDDROPEFFECT; |
136 | DWORD performedEffect; |
137 | }; |
138 | |
139 | class QOleEnumFmtEtc : public IEnumFORMATETC |
140 | { |
141 | public: |
142 | explicit QOleEnumFmtEtc(const QVector<FORMATETC> &fmtetcs); |
143 | explicit QOleEnumFmtEtc(const QVector<LPFORMATETC> &lpfmtetcs); |
144 | virtual ~QOleEnumFmtEtc(); |
145 | |
146 | bool isNull() const; |
147 | |
148 | // IUnknown methods |
149 | STDMETHOD(QueryInterface)(REFIID riid, void FAR* FAR* ppvObj); |
150 | STDMETHOD_(ULONG,AddRef)(void); |
151 | STDMETHOD_(ULONG,Release)(void); |
152 | |
153 | // IEnumFORMATETC methods |
154 | STDMETHOD(Next)(ULONG celt, LPFORMATETC rgelt, ULONG FAR* pceltFetched); |
155 | STDMETHOD(Skip)(ULONG celt); |
156 | STDMETHOD(Reset)(void); |
157 | STDMETHOD(Clone)(LPENUMFORMATETC FAR* newEnum); |
158 | |
159 | private: |
160 | bool copyFormatEtc(LPFORMATETC dest, LPFORMATETC src) const; |
161 | |
162 | ULONG m_dwRefs; |
163 | ULONG m_nIndex; |
164 | QVector<LPFORMATETC> m_lpfmtetcs; |
165 | bool m_isNull; |
166 | }; |
167 | |
168 | #endif |
169 | |
170 | #endif //QT_NO_DRAGANDDROP && QT_NO_CLIPBOARD |
171 | |
172 | #ifndef QT_NO_DRAGANDDROP |
173 | |
174 | class QDragPrivate : public QObjectPrivate |
175 | { |
176 | public: |
177 | QWidget *source; |
178 | QWidget *target; |
179 | QMimeData *data; |
180 | QPixmap pixmap; |
181 | QPoint hotspot; |
182 | Qt::DropActions possible_actions; |
183 | Qt::DropAction executed_action; |
184 | QMap<Qt::DropAction, QPixmap> customCursors; |
185 | Qt::DropAction defaultDropAction; |
186 | }; |
187 | |
188 | class QDropData : public QInternalMimeData |
189 | { |
190 | Q_OBJECT |
191 | public: |
192 | QDropData(); |
193 | ~QDropData(); |
194 | |
195 | protected: |
196 | bool hasFormat_sys(const QString &mimeType) const; |
197 | QStringList formats_sys() const; |
198 | QVariant retrieveData_sys(const QString &mimeType, QVariant::Type type) const; |
199 | |
200 | #if defined(Q_WS_WIN) |
201 | public: |
202 | LPDATAOBJECT currentDataObject; |
203 | #endif |
204 | }; |
205 | |
206 | class QDragManager: public QObject { |
207 | Q_OBJECT |
208 | |
209 | QDragManager(); |
210 | ~QDragManager(); |
211 | // only friend classes can use QDragManager. |
212 | friend class QDrag; |
213 | friend class QDragMoveEvent; |
214 | friend class QDropEvent; |
215 | friend class QApplication; |
216 | #ifdef Q_WS_MAC |
217 | friend class QWidgetPrivate; //dnd is implemented here |
218 | #endif |
219 | |
220 | bool eventFilter(QObject *, QEvent *); |
221 | void timerEvent(QTimerEvent*); |
222 | |
223 | public: |
224 | Qt::DropAction drag(QDrag *); |
225 | |
226 | void cancel(bool deleteSource = true); |
227 | void move(const QPoint &); |
228 | void drop(); |
229 | void updatePixmap(); |
230 | QWidget *source() const { return object ? object->d_func()->source : 0; } |
231 | QDragPrivate *dragPrivate() const { return object ? object->d_func() : 0; } |
232 | static QDragPrivate *dragPrivate(QDrag *drag) { return drag ? drag->d_func() : 0; } |
233 | |
234 | static QDragManager *self(); |
235 | Qt::DropAction defaultAction(Qt::DropActions possibleActions, |
236 | Qt::KeyboardModifiers modifiers) const; |
237 | |
238 | QDrag *object; |
239 | |
240 | void updateCursor(); |
241 | |
242 | bool beingCancelled; |
243 | bool restoreCursor; |
244 | bool willDrop; |
245 | QEventLoop *eventLoop; |
246 | |
247 | QPixmap dragCursor(Qt::DropAction action) const; |
248 | |
249 | bool hasCustomDragCursors() const; |
250 | |
251 | QDropData *dropData; |
252 | |
253 | void emitActionChanged(Qt::DropAction newAction) { if (object) emit object->actionChanged(newAction); } |
254 | |
255 | void setCurrentTarget(QWidget *target, bool dropped = false); |
256 | QWidget *currentTarget(); |
257 | |
258 | #ifdef Q_WS_X11 |
259 | QPixmap xdndMimeTransferedPixmap[2]; |
260 | int xdndMimeTransferedPixmapIndex; |
261 | #endif |
262 | |
263 | private: |
264 | #if defined(Q_WS_QWS) || defined(Q_WS_QPA) |
265 | Qt::DropAction currentActionForOverrideCursor; |
266 | #endif |
267 | #ifdef Q_OS_SYMBIAN |
268 | #ifndef QT_NO_CURSOR |
269 | QCursor overrideCursor; |
270 | #endif |
271 | #endif |
272 | QWidget *currentDropTarget; |
273 | |
274 | static QDragManager *instance; |
275 | Q_DISABLE_COPY(QDragManager) |
276 | }; |
277 | |
278 | |
279 | #if defined(Q_WS_WIN) |
280 | |
281 | class QOleDropTarget : public IDropTarget |
282 | { |
283 | public: |
284 | QOleDropTarget(QWidget* w); |
285 | virtual ~QOleDropTarget() {} |
286 | |
287 | void releaseQt(); |
288 | |
289 | // IUnknown methods |
290 | STDMETHOD(QueryInterface)(REFIID riid, void FAR* FAR* ppvObj); |
291 | STDMETHOD_(ULONG, AddRef)(void); |
292 | STDMETHOD_(ULONG, Release)(void); |
293 | |
294 | // IDropTarget methods |
295 | STDMETHOD(DragEnter)(LPDATAOBJECT pDataObj, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect); |
296 | STDMETHOD(DragOver)(DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect); |
297 | STDMETHOD(DragLeave)(); |
298 | STDMETHOD(Drop)(LPDATAOBJECT pDataObj, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect); |
299 | |
300 | private: |
301 | ULONG m_refs; |
302 | QWidget* widget; |
303 | QPointer<QWidget> currentWidget; |
304 | QRect answerRect; |
305 | QPoint lastPoint; |
306 | DWORD chosenEffect; |
307 | DWORD lastKeyState; |
308 | |
309 | void sendDragEnterEvent(QWidget *to, DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect); |
310 | }; |
311 | |
312 | #endif |
313 | |
314 | #if defined (Q_WS_MAC) |
315 | class QCocoaDropData : public QInternalMimeData |
316 | { |
317 | Q_OBJECT |
318 | public: |
319 | QCocoaDropData(CFStringRef pasteboard); |
320 | ~QCocoaDropData(); |
321 | |
322 | protected: |
323 | bool hasFormat_sys(const QString &mimeType) const; |
324 | QStringList formats_sys() const; |
325 | QVariant retrieveData_sys(const QString &mimeType, QVariant::Type type) const; |
326 | public: |
327 | CFStringRef dropPasteboard; |
328 | }; |
329 | #endif |
330 | |
331 | #endif // !QT_NO_DRAGANDDROP |
332 | |
333 | |
334 | QT_END_NAMESPACE |
335 | |
336 | #endif // QDND_P_H |
337 | |