source: trunk/src/gui/kernel/qmime_pm.cpp@ 324

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

gui/kernel: Improved mime <-> PM clipboard format conversion interfaces.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Revision Author Id
File size: 10.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** 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 "qmime.h"
45
46#include "qimagereader.h"
47#include "qimagewriter.h"
48#include "qdatastream.h"
49#include "qbuffer.h"
50#include "qt_os2.h"
51#include "qapplication_p.h"
52#include "qtextcodec.h"
53#include "qregexp.h"
54#include "qalgorithms.h"
55#include "qmap.h"
56#include "qdnd_p.h"
57#include "qurl.h"
58#include "qvariant.h"
59#include "qtextdocument.h"
60#include "qdir.h"
61
62#define QMIME_DEBUG
63
64QT_BEGIN_NAMESPACE
65
66class QPMMimeList
67{
68public:
69 QPMMimeList();
70 ~QPMMimeList();
71 void addMime(QPMMime *mime);
72 void removeMime(QPMMime *mime);
73 QList<QPMMime*> mimes();
74
75private:
76 void init();
77 bool initialized;
78 QList<QPMMime*> list;
79};
80
81Q_GLOBAL_STATIC(QPMMimeList, theMimeList);
82
83
84/*!
85 \class QPMMime
86 \brief The QMPMime class maps open-standard MIME to OS/2 PM Clipboard
87 formats.
88 \ingroup io
89 \ingroup draganddrop
90 \ingroup misc
91
92 Qt's drag-and-drop and clipboard facilities use the MIME standard.
93 On X11, this maps trivially to the Xdnd protocol, but on OS/2
94 although some applications use MIME types to describe clipboard
95 formats, others use arbitrary non-standardized naming conventions,
96 or unnamed built-in formats of the Presentation Manager.
97
98 By instantiating subclasses of QPMMime that provide conversions between OS/2
99 PM Clipboard and MIME formats, you can convert proprietary clipboard formats
100 to MIME formats.
101
102 Qt has predefined support for the following PM Clipboard formats:
103
104 \table
105 \header \o PM Format \o Equivalent MIME type
106 \row \o \c CF_TEXT \o \c text/plain
107 \row \o \c CF_BITMAP \o \c{image/xyz}, where \c xyz is
108 a \l{QImageWriter::supportedImageFormats()}{Qt image format}
109 \endtable
110
111 An example use of this class would be to map the PM Metafile
112 clipboard format (\c CF_METAFILE) to and from the MIME type
113 \c{image/x-metafile}. This conversion might simply be adding or removing a
114 header, or even just passing on the data. See \l{Drag and Drop} for more
115 information on choosing and definition MIME types.
116*/
117
118/*!
119Constructs a new conversion object, adding it to the globally accessed
120list of available converters.
121*/
122QPMMime::QPMMime()
123{
124 theMimeList()->addMime(this);
125}
126
127/*!
128Destroys a conversion object, removing it from the global
129list of available converters.
130*/
131QPMMime::~QPMMime()
132{
133 theMimeList()->removeMime(this);
134}
135
136/*!
137 Registers the MIME type \a mime, and returns an ID number
138 identifying the format on OS/2.
139*/
140ULONG QPMMime::registerMimeType(const QString &mime)
141{
142 QString atom = QLatin1String("mime:") + mime;
143
144 ULONG cf = WinAddAtom(WinQuerySystemAtomTable(), atom.toLocal8Bit());
145 if (!cf) {
146#ifndef QT_NO_DEBUG
147 qWarning("QPMMime: WinAddAtom failed with %lX",
148 WinGetLastError(NULLHANDLE));
149#endif
150 return 0;
151 }
152
153 return cf;
154}
155
156/*!
157 \fn QList<ULONG> QPMMime::formatsForMimeData(const QMimeData *mimeData) const
158
159 Returns a list of ULONG values representing the different OS/2 PM
160 clipboard formats that can be provided for the \a mimeData, in order of
161 precedence (the most suitable format goes first), or an empty list if
162 neither of the mime types provided by \a mimeData is supported by this
163 converter.
164
165 All subclasses must reimplement this pure virtual function.
166*/
167
168/*!
169 \fn bool QPMMime::convertFromMimeData(const QMimeData *mimeData, ULONG format,
170 ULONG &flags, ULONG *data) const
171
172 Converts the \a mimeData to the specified \a format.
173
174 If \a data is not NULL, a handle to the converted data should then be placed
175 in a variable pointed to by \a data and with the necessary flags describing
176 the handle returned in the \a flags variable.
177
178 The following flags describing the data type are recognized:
179
180 \table
181 \row \o \c CFI_POINTER \o \a data is a pointer to a block of memory
182 allocated with QPMMime::allocMem()
183 \row \o \c CFI_HANDLE \o \a data is a handle to the appropriate
184 PM resource
185 \endtable
186
187 If \a data is NULL then a delayed conversion is requested by the caller.
188 The implementation should return the appropriate flags in the \a flags
189 variable and may perform the real data conversion later when this method is
190 called again with \a data being non-NULL.
191
192 Return true if the conversion was successful.
193
194 All subclasses must reimplement this pure virtual function.
195*/
196
197/*!
198 \fn QStringList QPMMime::mimesForFormats(const QList<ULONG> &formats) const
199
200 Returns a list of mime types that will be created form the specified \a list
201 of \a formats, in order of precedence (the most suitable mime type comes
202 first), or an empty list if neither of the \a formats is supported by this
203 converter.
204
205 All subclasses must reimplement this pure virtual function.
206*/
207
208/*!
209 \fn QVariant QPMMime::convertFromFormat(ULONG format, ULONG flags, ULONG data,
210 const QString &mimeType,
211 QVariant::Type preferredType) const
212
213 Returns a QVariant containing the converted from the \a data in the
214 specified \a format with the given \a flags to the requested \a mimeType. If
215 possible the QVariant should be of the \a preferredType to avoid needless
216 conversions.
217
218 All subclasses must reimplement this pure virtual function.
219*/
220
221// static
222QList<QPMMime::Match> QPMMime::allConvertersFromFormats(const QList<ULONG> &formats)
223{
224 QList<Match> matches;
225
226 QList<QPMMime*> mimes = theMimeList()->mimes();
227 for (int i = mimes.size()-1; i >= 0; --i) {
228 QStringList fmts = mimes[i]->mimesForFormats(formats);
229 int priority = 0;
230 foreach (QString fmt, fmts) {
231 ++priority;
232 QList<Match>::iterator it = matches.begin();
233 for (; it != matches.end(); ++it) {
234 Match &match = *it;
235 if (match.mime == fmt) {
236 // replace if priority is higher, ignore otherwise
237 if (priority < match.priority) {
238 match.converter = mimes[i];
239 match.priority = priority;
240 }
241 break;
242 }
243 }
244 if (it == matches.end()) {
245 matches += Match(mimes[i], fmt, priority);
246 }
247 }
248 }
249
250 return matches;
251}
252
253// static
254QList<QPMMime::Match> QPMMime::allConvertersFromMimeData(const QMimeData *mimeData)
255{
256 QList<Match> matches;
257
258 QList<QPMMime*> mimes = theMimeList()->mimes();
259 for (int i = mimes.size()-1; i >= 0; --i) {
260 QList<ULONG> cfs = mimes[i]->formatsForMimeData(mimeData);
261 int priority = 0;
262 foreach (ULONG cf, cfs) {
263 ++priority;
264 QList<Match>::iterator it = matches.begin();
265 for (; it != matches.end(); ++it) {
266 Match &match = *it;
267 if (match.format == cf) {
268 // replace if priority is higher, ignore otherwise
269 if (priority < match.priority) {
270 match.converter = mimes[i];
271 match.priority = priority;
272 }
273 break;
274 }
275 }
276 if (it == matches.end()) {
277 matches += Match(mimes[i], cf, priority);
278 }
279 }
280 }
281
282 return matches;
283}
284
285////////////////////////////////////////////////////////////////////////////////
286
287////////////////////////////////////////////////////////////////////////////////
288
289QPMMimeList::QPMMimeList()
290 : initialized(false)
291{
292}
293
294QPMMimeList::~QPMMimeList()
295{
296 while (list.size())
297 delete list.first();
298}
299
300
301void QPMMimeList::init()
302{
303 if (!initialized) {
304 initialized = true;
305 // @todo new QPMMimeXXX;
306 }
307}
308
309void QPMMimeList::addMime(QPMMime *mime)
310{
311 init();
312 list.append(mime);
313}
314
315void QPMMimeList::removeMime(QPMMime *mime)
316{
317 init();
318 list.removeAll(mime);
319}
320
321QList<QPMMime*> QPMMimeList::mimes()
322{
323 init();
324 return list;
325}
326
327QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.