source: trunk/src/gui/kernel/qclipboard_pm.cpp@ 473

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

general: Made it build using GCC4 and fixed a couple warnings.

  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Date Revision Author Id
File size: 15.1 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** Copyright (C) 2009 netlabs.org. OS/2 parts.
7**
8** This file is part of the QtGui module of the Qt Toolkit.
9**
10** $QT_BEGIN_LICENSE:LGPL$
11** Commercial Usage
12** Licensees holding valid Qt Commercial licenses may use this file in
13** accordance with the Qt Commercial License Agreement provided with the
14** Software or, alternatively, in accordance with the terms contained in
15** a written agreement between you and Nokia.
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, Nokia gives you certain
26** additional rights. These rights are described in the Nokia Qt LGPL
27** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
28** 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** If you are unsure which license is appropriate for your use, please
39** contact the sales department at [email protected].
40** $QT_END_LICENSE$
41**
42****************************************************************************/
43
44#include "qclipboard.h"
45
46#ifndef QT_NO_CLIPBOARD
47
48#include "qapplication.h"
49#include "qapplication_p.h"
50#include "qeventloop.h"
51#include "qwidget.h"
52#include "qevent.h"
53#include "qmime.h"
54#include "qdnd_p.h"
55#include "qclipboard_p.h"
56
57#include "qt_os2.h"
58#include "private/qpmobjectwindow_pm_p.h"
59
60//#define QCLIPBOARD_DEBUG
61
62#ifdef QCLIPBOARD_DEBUG
63# include "qdebug.h"
64# define DEBUG(a) qDebug a
65#else
66# define DEBUG(a) do {} while(0)
67#endif
68
69QT_BEGIN_NAMESPACE
70
71extern bool qt_sendSpontaneousEvent(QObject*, QEvent*); // qapplication.cpp
72
73////////////////////////////////////////////////////////////////////////////////
74
75class QClipboardWatcher : public QInternalMimeData
76{
77public:
78 QClipboardWatcher() {}
79
80 bool hasFormat_sys(const QString &mimetype) const;
81 QStringList formats_sys() const;
82 QVariant retrieveData_sys(const QString &mimetype, QVariant::Type preferredType) const;
83
84private:
85
86 bool peekData(bool leaveOpen = false) const;
87
88 mutable QList<ULONG> formats;
89 mutable QList<QPMMime::Match> matches;
90};
91
92bool QClipboardWatcher::peekData(bool leaveOpen) const
93{
94 if (!WinOpenClipbrd(NULLHANDLE)) {
95#ifndef QT_NO_DEBUG
96 qWarning("QClipboardWatcher::peekData: WinOpenClipbrd "
97 "failed with 0x%lX", WinGetLastError(NULLHANDLE));
98#endif
99 return false;
100 }
101
102 QList<ULONG> newFormats;
103 ULONG cf = 0;
104 while ((cf = WinEnumClipbrdFmts(NULLHANDLE, cf)))
105 newFormats << cf;
106
107 if (!leaveOpen)
108 WinCloseClipbrd(NULLHANDLE);
109
110 // optimization: we don't want to call the potentially expensive
111 // allConvertersFromFormats() unlesss we really got a different set
112 if (newFormats == formats)
113 return true;
114
115 formats = newFormats;
116 matches = QPMMime::allConvertersFromFormats(formats);
117
118#ifdef QCLIPBOARD_DEBUG
119 foreach(ULONG cf, formats)
120 DEBUG(("QClipboardWatcher::peekData: have format 0x%lX (%ls)",
121 cf, QPMMime::formatName(cf).utf16()));
122 foreach(QPMMime::Match match, matches)
123 DEBUG(("QClipboardWatcher::peekData: converter %p mime \"%ls\" "
124 "format 0x%lX priority %d", match.converter, match.mime.utf16(),
125 match.format, match.priority));
126#endif
127
128 return true;
129}
130
131bool QClipboardWatcher::hasFormat_sys(const QString &mime) const
132{
133 if (!peekData())
134 return false;
135
136 foreach (QPMMime::Match match, matches)
137 if (match.mime == mime)
138 return true;
139
140 return false;
141}
142
143QStringList QClipboardWatcher::formats_sys() const
144{
145 QStringList fmts;
146
147 if (!peekData())
148 return fmts;
149
150 foreach (QPMMime::Match match, matches)
151 fmts << match.mime;
152
153 return fmts;
154}
155
156QVariant QClipboardWatcher::retrieveData_sys(const QString &mime,
157 QVariant::Type type) const
158{
159 QVariant result;
160
161 if (!peekData(true /*leaveOpen*/))
162 return result;
163
164 foreach (QPMMime::Match match, matches) {
165 if (match.mime == mime) {
166 ULONG flags;
167 if (WinQueryClipbrdFmtInfo(NULLHANDLE, match.format, &flags)) {
168 ULONG data = WinQueryClipbrdData(NULLHANDLE, match.format);
169 result = match.converter->convertFromFormat(match.format, flags,
170 data, match.mime, type);
171 }
172 break;
173 }
174 }
175
176 WinCloseClipbrd(NULLHANDLE);
177
178 return result;
179}
180
181////////////////////////////////////////////////////////////////////////////////
182
183class QClipboardData : public QPMObjectWindow
184{
185public:
186 QClipboardData();
187 ~QClipboardData();
188
189 void setSource(QMimeData *s);
190
191 void setAsClipboardViewer();
192 bool ownsClipboard() const;
193 void putAllMimeToClipboard(bool isDelayed);
194 void flushClipboard();
195
196 const QMimeData *mimeData() const;
197
198 static QClipboardData *instance()
199 {
200 if (instancePtr == 0) {
201 instancePtr = new QClipboardData;
202 }
203 Q_ASSERT(instancePtr);
204 return instancePtr;
205 }
206
207 static void deleteInstance()
208 {
209 delete instancePtr;
210 instancePtr = 0;
211 }
212
213private:
214 bool setClipboard(QPMMime *converter, ULONG format, bool isDelayed);
215
216 MRESULT message(ULONG msg, MPARAM mp1, MPARAM mp2);
217
218 QMimeData *src;
219 QList<QPMMime::Match> matches;
220 HWND prevClipboardViewer;
221
222 QClipboardWatcher watcher;
223
224 bool ignore_WM_DESTROYCLIPBOARD;
225
226 static QClipboardData *instancePtr;
227};
228
229// static
230QClipboardData *QClipboardData::instancePtr = 0;
231
232QClipboardData::QClipboardData()
233 : src(0), prevClipboardViewer(NULLHANDLE)
234 , ignore_WM_DESTROYCLIPBOARD(false)
235{
236}
237
238QClipboardData::~QClipboardData()
239{
240 setSource(0);
241
242 // make sure we are not the clipboard viewer any more
243 if (hwnd() == WinQueryClipbrdViewer(NULLHANDLE))
244 WinSetClipbrdViewer(NULLHANDLE, prevClipboardViewer);
245}
246
247void QClipboardData::setSource(QMimeData *s)
248{
249 if (s == src)
250 return;
251 delete src;
252 src = s;
253
254 // build the list of all mime <-> cf matches
255 matches.clear();
256 if (src)
257 matches = QPMMime::allConvertersFromMimeData(src);
258
259#ifdef QCLIPBOARD_DEBUG
260 if (src) {
261 DEBUG(() << "QClipboardData::setSource: mimes" << src->formats());
262 foreach(QPMMime::Match match, matches)
263 DEBUG(("QClipboardData::setSource: match: converter %p format 0x%lX "
264 "(%ls) priority %d", match.converter, match.format,
265 QPMMime::formatName(match.format).utf16(), match.priority));
266 }
267#endif
268}
269
270void QClipboardData::setAsClipboardViewer()
271{
272 DEBUG(("QClipboardData::setAsClipboardViewer"));
273
274 HWND clipboardViewer = WinQueryClipbrdViewer(NULLHANDLE);
275 if (hwnd() != clipboardViewer) {
276 prevClipboardViewer = clipboardViewer;
277 BOOL ok = WinSetClipbrdViewer(NULLHANDLE, hwnd());
278 Q_UNUSED(ok);
279#ifndef QT_NO_DEBUG
280 if (!ok)
281 qWarning("QClipboardData::setAsClipboardViewer: WinSetClipbrdViewer "
282 " failed with 0x%lX", WinGetLastError(NULLHANDLE));
283#endif
284 }
285}
286
287bool QClipboardData::ownsClipboard() const
288{
289 return src && hwnd() == WinQueryClipbrdOwner(NULLHANDLE);
290}
291
292bool QClipboardData::setClipboard(QPMMime *converter, ULONG format,
293 bool isDelayed)
294{
295 Q_ASSERT(src);
296 if (!src)
297 return false;
298
299 bool ok, ok2;
300 ULONG flags = 0, data = 0;
301
302 if (isDelayed) {
303 // setup delayed rendering of clipboard data
304 ok = converter->convertFromMimeData(src, format, flags, 0);
305 if (ok) {
306 WinSetClipbrdOwner(NULLHANDLE, hwnd());
307 ok2 = WinSetClipbrdData(NULLHANDLE, 0, format, flags);
308 }
309 } else {
310 // render now
311 ok = converter->convertFromMimeData(src, format, flags, &data);
312 if (ok)
313 ok2 = WinSetClipbrdData(NULLHANDLE, data, format, flags);
314 }
315 DEBUG(("QClipboardData::setClipboard: convert to format 0x%lX (%ls) "
316 "flags 0x%lX data 0x%lX delayed %d ok %d", format,
317 QPMMime::formatName(format).utf16(), flags, data, isDelayed, ok));
318#ifndef QT_NO_DEBUG
319 if (!ok2) {
320 qWarning("QClipboardData::setClipboard: WinSetClipbrdData "
321 "failed with 0x%lX", WinGetLastError(NULLHANDLE));
322 }