1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
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 The Qt Company. For licensing terms
14 ** and conditions see http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free
20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22 ** following information to ensure the GNU Lesser General Public License
23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 **
26 ** As a special exception, The Qt Company gives you certain additional
27 ** rights. These rights are described in The Qt Company LGPL Exception
28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 **
30 ** GNU General Public License Usage
31 ** Alternatively, this file may be used under the terms of the GNU
32 ** General Public License version 3.0 as published by the Free Software
33 ** Foundation and appearing in the file LICENSE.GPL included in the
34 ** packaging of this file.  Please review the following information to
35 ** ensure the GNU General Public License version 3.0 requirements will be
36 ** met: http://www.gnu.org/copyleft/gpl.html.
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();
source()230     QWidget *source() const { return object ? object->d_func()->source : 0; }
dragPrivate()231     QDragPrivate *dragPrivate() const { return object ? object->d_func() : 0; }
dragPrivate(QDrag * drag)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 
emitActionChanged(Qt::DropAction newAction)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);
~QOleDropTarget()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