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

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

gui/kernel: mime: Added support for the "text/html" clipboard format used by Mozilla.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Revision Author Id
File size: 24.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 "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 (custom
103 formats registered in the system atom table by name are given in double
104 quotes):
105
106 \table
107 \header \o PM Format \o Equivalent MIME type
108 \row \o \c CF_TEXT \o \c text/plain (system codepage,
109 zero-terminated string)
110 \row \o \c "text/unicode" \o \c text/plain (16-bit Unicode,
111 zero-terminated string, Mozilla-compatible)
112 \row \o \c "text/html" \o \c text/html (16-bit Unicode,
113 zero-terminated string, Mozilla-compatible)
114 \row \o \c CF_BITMAP \o \c{image/xyz}, where \c xyz is
115 a \l{QImageWriter::supportedImageFormats()}{Qt image format}
116 \row \o \c "x-mime:<mime>" \o data in the format corresponding to the given
117 MIME type \c <mime>
118 \endtable
119
120 Note that all "x-mime:<mime>" formats use the CFI_POINTER storage type. That
121 is, the clipboard contains a pointer to the memory block containing the MIME
122 data in the corresponding format. The first 4 bytes of this memory block
123 always contain the length of the subsequent MIME data array, in bytes.
124
125 An example use of this class by the user application would be to map the
126 PM Metafile clipboard format (\c CF_METAFILE) to and from the MIME type
127 \c{image/x-metafile}. This conversion might simply be adding or removing a
128 header, or even just passing on the data. See \l{Drag and Drop} for more
129 information on choosing and definition MIME types.
130*/
131
132/*!
133Constructs a new conversion object, adding it to the globally accessed
134list of available converters.
135*/
136QPMMime::QPMMime()
137{
138 theMimeList()->addMime(this);
139}
140
141/*!
142Destroys a conversion object, removing it from the global
143list of available converters.
144*/
145QPMMime::~QPMMime()
146{
147 theMimeList()->removeMime(this);
148}
149
150/*!
151 Registers the MIME type \a mime, and returns an ID number
152 identifying the format on OS/2. Intended to be used by QPMMime
153 implementations for registering custom clipboard formats they use.
154*/
155// static
156ULONG QPMMime::registerMimeType(const QString &mime)
157{
158 ULONG cf = WinAddAtom(WinQuerySystemAtomTable(), mime.toLocal8Bit());
159 if (!cf) {
160#ifndef QT_NO_DEBUG
161 qWarning("QPMMime: WinAddAtom failed with %lX",
162 WinGetLastError(NULLHANDLE));
163#endif
164 return 0;
165 }
166
167 return cf;
168}
169
170/*!
171 Allocates a block of shared memory of the given size and returns the address
172 of this block. This memory block may be then filled with data and returned
173 by convertFromMimeData() as the value of the CFI_POINTER type.
174*/
175// static
176ULONG QPMMime::allocateMemory(size_t size)
177{
178 if (size == 0)
179 return 0;
180
181 ULONG data = 0;
182
183 // allocate giveable memory for the array
184 APIRET arc = DosAllocSharedMem((PVOID *)&data, NULL, size,
185 PAG_WRITE | PAG_COMMIT | OBJ_GIVEABLE);
186 if (arc != NO_ERROR) {
187#ifndef QT_NO_DEBUG
188 qWarning("QPMMime::allocateMemory: DosAllocSharedMem failed with %lu", arc);
189#endif
190 return 0;
191 }
192
193 return data;
194}
195
196/*!
197 Frees memory allocated by allocateMemory(). Normally, not used because the
198 CFI_POINTER memory blocks are owned by the system after
199 convertFromMimeData() returns.
200*/
201// static
202void QPMMime::freeMemory(ULONG addr)
203{
204 DosFreeMem((PVOID)addr);
205}
206
207/*!
208 \fn QList<MimeCFPair> QPMMime::formatsForMimeData(const QMimeData *mimeData) const
209
210 Returns a list of ULONG values representing the different OS/2 PM
211 clipboard formats that can be provided for the \a mimeData, in order of
212 precedence (the most suitable format goes first), or an empty list if
213 neither of the mime types provided by \a mimeData is supported by this
214 converter. Note that each item in the returned list is actually a pair
215 consisting of the mime type name and the corresponding format identifier.
216
217 All subclasses must reimplement this pure virtual function.
218*/
219
220/*!
221 \fn bool QPMMime::convertFromMimeData(const QMimeData *mimeData, ULONG format,
222 ULONG &flags, ULONG *data) const
223
224 Converts the \a mimeData to the specified \a format.
225
226 If \a data is not NULL, a handle to the converted data should be then placed
227 in a variable pointed to by \a data and with the necessary flags describing
228 the handle returned in the \a flags variable.
229
230 The following flags describing the data storage type are recognized:
231
232 \table
233 \row \o \c CFI_POINTER \o \a data is a pointer to a block of memory
234 allocated with QPMMime::allocateMemory()
235 \row \o \c CFI_HANDLE \o \a data is a handle to the appropriate
236 PM resource
237 \endtable
238
239 If \a data is NULL then a delayed conversion is requested by the caller.
240 The implementation should return the appropriate flags in the \a flags
241 variable and may perform the real data conversion later when this method is
242 called again with \a data being non-NULL.
243
244 Return true if the conversion was successful.
245
246 All subclasses must reimplement this pure virtual function.
247*/
248
249/*!
250 \fn QList<MimeCFPair> QPMMime::mimesForFormats(const QList<ULONG> &formats) const
251
252 Returns a list of mime types that will be created form the specified \a list
253 of \a formats, in order of precedence (the most suitable mime type comes
254 first), or an empty list if neither of the \a formats is supported by this
255 converter. Note that each item in the returned list is actually a pair
256 consisting of the mime type name and the corresponding format identifier.
257
258 All subclasses must reimplement this pure virtual function.
259*/
260
261/*!
262 \fn QVariant QPMMime::convertFromFormat(ULONG format, ULONG flags, ULONG data,
263 const QString &mimeType,
264 QVariant::Type preferredType) const
265
266 Returns a QVariant containing the converted from the \a data in the
267 specified \a format with the given \a flags to the requested \a mimeType. If
268 possible the QVariant should be of the \a preferredType to avoid needless
269 conversions.
270
271 All subclasses must reimplement this pure virtual function.
272*/
273
274// static
275QList<QPMMime::Match> QPMMime::allConvertersFromFormats(const QList<ULONG> &formats)
276{
277 QList<Match> matches;
278
279 QList<QPMMime*> mimes = theMimeList()->mimes();
280 foreach(QPMMime *mime, mimes) {
281 QList<MimeCFPair> fmts = mime->mimesForFormats(formats);
282 int priority = 0;
283 foreach (MimeCFPair fmt, fmts) {
284 ++priority;
285 QList<Match>::iterator it = matches.begin();
286 for (; it != matches.end(); ++it) {
287 Match &match = *it;
288 if (match.mime == fmt.mime) {
289 // replace if priority is higher, ignore otherwise
290 if (priority < match.priority) {
291 match.converter = mime;
292 match.format = fmt.format;
293 match.priority = priority;
294 }
295 break;
296 }
297 }
298 if (it == matches.end()) {
299 matches += Match(mime, fmt.mime, fmt.format, priority);
300 }
301 }
302 }
303
304 return matches;
305}
306
307// static
308QList<QPMMime::Match> QPMMime::allConvertersFromMimeData(const QMimeData *mimeData)
309{
310 QList<Match> matches;
311
312 QList<QPMMime*> mimes = theMimeList()->mimes();
313 foreach(QPMMime *mime, mimes) {
314 QList<MimeCFPair> fmts = mime->formatsForMimeData(mimeData);
315 int priority = 0;
316 foreach (MimeCFPair fmt, fmts) {
317 ++priority;
318 QList<Match>::iterator it = matches.begin();
319 for (; it != matches.end(); ++it) {
320 Match &match = *it;
321 if (mime == mimes.last()) { // QPMMimeAnyMime?
322 if (match.mime == fmt.mime){
323 // we assume that specialized converters (that come
324 // first) provide a more precise conversion than
325 // QPMMimeAnyMime and don't let it get into the list in
326 // order to avoid unnecessary duplicate representations
327 break;
328 }
329 }
330 if (match.format == fmt.format) {
331 // replace if priority is higher, ignore otherwise
332 if (priority < match.priority) {
333 match.converter = mime;
334 match.mime = fmt.mime;
335 match.priority = priority;
336 }
337 break;
338 }
339 }
340 if (it == matches.end()) {
341 matches += Match(mime, fmt.mime, fmt.format, priority);
342 }
343 }
344 }
345
346 return matches;
347}
348
349QString QPMMime::formatName(ULONG format)
350{
351 QString name;
352 HATOMTBL tbl = WinQuerySystemAtomTable();
353 if (tbl != NULLHANDLE) {
354 ULONG len = WinQueryAtomLength(tbl, format);
355 QByteArray atom(len, '\0');
356 WinQueryAtomName(tbl, format, atom.data(), atom.size() + 1);
357 name = QString::fromLocal8Bit(atom);
358 }
359 return name;
360}
361
362////////////////////////////////////////////////////////////////////////////////
363
364class QPMMimeText : public QPMMime
365{
366public:
367 QPMMimeText();
368
369 // for converting from Qt
370 QList<MimeCFPair> formatsForMimeData(const QMimeData *mimeData) const;
371 bool convertFromMimeData(const QMimeData *mimeData, ULONG format,
372 ULONG &flags, ULONG *data) const;
373
374 // for converting to Qt
375 QList<MimeCFPair> mimesForFormats(const QList<ULONG> &formats) const;
376 QVariant convertFromFormat(ULONG format, ULONG flags, ULONG data,
377 const QString &mimeType,
378 QVariant::Type preferredType) const;
379
380 const ULONG CF_TextUnicode;
381 const ULONG CF_TextHtml;
382};
383
384QPMMimeText::QPMMimeText()
385 // "text/unicode" is what Mozilla uses to for unicode
386 : CF_TextUnicode (registerMimeType(QLatin1String("text/unicode")))
387 // "text/html" is what Mozilla uses to for HTML
388 , CF_TextHtml (registerMimeType(QLatin1String("text/html")))
389{
390}
391
392QList<QPMMime::MimeCFPair> QPMMimeText::formatsForMimeData(const QMimeData *mimeData) const
393{
394 QList<MimeCFPair> fmts;
395 // prefer HTML as it's reacher
396 if (mimeData->hasHtml())
397 fmts << MimeCFPair(QLatin1String("text/html"), CF_TextHtml);
398 // prefer unicode over local8Bit
399 if (mimeData->hasText())
400 fmts << MimeCFPair(QLatin1String("text/plain"), CF_TextUnicode)
401 << MimeCFPair(QLatin1String("text/plain"), CF_TEXT);
402 return fmts;
403}
404
405// text/plain is defined as using CRLF, but so many programs don't,
406// and programmers just look for '\n' in strings.
407// OS/2 really needs CRLF, so we ensure it here.
408bool QPMMimeText::convertFromMimeData(const QMimeData *mimeData, ULONG format,
409 ULONG &flags, ULONG *data) const
410{
411 if (!mimeData->hasText())
412 return false;
413
414 flags = CFI_POINTER;
415
416 if (data == NULL)
417 return true; // delayed rendering, nothing to do
418
419 QByteArray r;
420
421 if (format == CF_TEXT) {
422 QByteArray str = mimeData->text().toLocal8Bit();
423 // Anticipate required space for CRLFs at 1/40
424 int maxsize = str.size()+str.size()/40+1;
425 r.fill('\0', maxsize);
426 char *o = r.data();
427 const char *d = str.data();
428 const int s = str.size();
429 bool cr = false;
430 int j = 0;
431 for (int i = 0; i < s; i++) {
432 char c = d[i];
433 if (c == '\r')
434 cr = true;
435 else {
436 if (c == '\n') {
437 if (!cr)
438 o[j++] = '\r';
439 }
440 cr = false;
441 }
442 o[j++] = c;
443 if (j+1 >= maxsize) {
444 maxsize += maxsize/4;
445 r.resize(maxsize);
446 o = r.data();
447 }
448 }
449 if (j < r.size())
450 o[j] = '\0';
451 } else if (format == CF_TextUnicode || CF_TextHtml) {
452 QString str = mimeData->text();
453 const QChar *u = str.unicode();
454 QString res;
455 const int s = str.length();
456 int maxsize = s + s/40 + 3;
457 res.resize(maxsize);
458 int ri = 0;
459 bool cr = false;
460 for (int i = 0; i < s; ++i) {
461 if (*u == QLatin1Char('\r'))
462 cr = true;
463 else {
464 if (*u == QLatin1Char('\n') && !cr)
465 res[ri++] = QLatin1Char('\r');
466 cr = false;
467 }
468 res[ri++] = *u;
469 if (ri+3 >= maxsize) {
470 maxsize += maxsize/4;
471 res.resize(maxsize);
472 }
473 ++u;
474 }
475 res.truncate(ri);
476 const int byteLength = res.length()*2;
477 r.fill('\0', byteLength + 2);
478 memcpy(r.data(), res.unicode(), byteLength);
479 r[byteLength] = 0;
480 r[byteLength+1] = 0;
481 } else{
482 return false;
483 }
484
485 *data = QPMMime::allocateMemory(r.size());
486 if (!*data)
487 return false;
488
489 memcpy((void *)*data, r.data(), r.size());
490 return true;
491}
492
493QList<QPMMime::MimeCFPair> QPMMimeText::mimesForFormats(const QList<ULONG> &formats) const
494{
495 QList<MimeCFPair> mimes;
496 // prefer HTML as it's reacher
497 if (formats.contains(CF_TextHtml))
498 mimes << MimeCFPair(QLatin1String("text/html"), CF_TextHtml);
499 // prefer unicode over local8Bit
500 if (formats.contains(CF_TextUnicode))
501 mimes << MimeCFPair(QLatin1String("text/plain"), CF_TextUnicode);
502 if (formats.contains(CF_TEXT))
503 mimes << MimeCFPair(QLatin1String("text/plain"), CF_TEXT);
504 return mimes;
505}
506
507QVariant QPMMimeText::convertFromFormat(ULONG format, ULONG flags, ULONG data,
508 const QString &mimeType,
509 QVariant::Type preferredType) const
510{
511 QVariant ret;
512
513 if (!mimeType.startsWith("text/plain") &&
514 !mimeType.startsWith("text/html"))
515 return ret;
516 if (!(flags & CFI_POINTER) || !data)
517 return ret;
518
519 QString str;
520
521 if (format == CF_TEXT) {
522 const char *d = (const char *)data;
523 QByteArray r("");
524 if (*d) {
525 const int s = qstrlen(d);
526 r.fill('\0', s);
527 char *o = r.data();
528 int j = 0;
529 for (int i = 0; i < s; i++) {
530 char c = d[i];
531 if (c != '\r')
532 o[j++] = c;
533 }
534 }
535 str = QString::fromLocal8Bit(r);
536 } else if (format == CF_TextUnicode || CF_TextHtml) {
537 str = QString::fromUtf16((const unsigned short *)data);
538 str.replace(QLatin1String("\r\n"), QLatin1String("\n"));
539 }
540
541 if (preferredType == QVariant::String)
542 ret = str;
543 else
544 ret = str.toUtf8();
545
546 return ret;
547}
548
549////////////////////////////////////////////////////////////////////////////////
550
551class QPMMimeAnyMime : public QPMMime
552{
553public:
554 QPMMimeAnyMime();
555
556 // for converting from Qt
557 QList<MimeCFPair> formatsForMimeData(const QMimeData *mimeData) const;
558 bool convertFromMimeData(const QMimeData *mimeData, ULONG format,
559 ULONG &flags, ULONG *data) const;
560
561 // for converting to Qt
562 QList<MimeCFPair> mimesForFormats(const QList<ULONG> &formats) const;
563 QVariant convertFromFormat(ULONG format, ULONG flags, ULONG data,
564 const QString &mimeType,
565 QVariant::Type preferredType) const;
566
567private:
568 ULONG registerMimeType(const QString &mime) const;
569 QString registerFormat(ULONG format) const;
570
571 mutable QMap<QString, ULONG> cfMap;
572 mutable QMap<ULONG, QString> mimeMap;
573
574 static QStringList ianaTypes;
575 static QString mimePrefix;
576 static QString customPrefix;
577};
578
579// static
580QStringList QPMMimeAnyMime::ianaTypes;
581QString QPMMimeAnyMime::mimePrefix;
582QString QPMMimeAnyMime::customPrefix;
583
584QPMMimeAnyMime::QPMMimeAnyMime()
585{
586 //MIME Media-Types
587 if (!ianaTypes.size()) {
588 ianaTypes.append(QLatin1String("application/"));
589 ianaTypes.append(QLatin1String("audio/"));
590 ianaTypes.append(QLatin1String("example/"));
591 ianaTypes.append(QLatin1String("image/"));
592 ianaTypes.append(QLatin1String("message/"));
593 ianaTypes.append(QLatin1String("model/"));
594 ianaTypes.append(QLatin1String("multipart/"));
595 ianaTypes.append(QLatin1String("text/"));
596 ianaTypes.append(QLatin1String("video/"));
597
598 mimePrefix = QLatin1String("x-mime:");
599 customPrefix = QLatin1String("application/x-qt-pm-mime;value=\"");
600 }
601}
602
603QList<QPMMime::MimeCFPair> QPMMimeAnyMime::formatsForMimeData(const QMimeData *mimeData) const
604{
605 QList<MimeCFPair> fmts;
606
607 QStringList mimes = QInternalMimeData::formatsHelper(mimeData);
608 foreach (QString mime, mimes) {
609 ULONG cf = cfMap.value(mime);
610 if (!cf)
611 cf = registerMimeType(mime);
612 if (cf)
613 fmts << MimeCFPair(mime, cf);
614 }
615
616 return fmts;
617}
618
619bool QPMMimeAnyMime::convertFromMimeData(const QMimeData *mimeData, ULONG format,
620 ULONG &flags, ULONG *data) const
621{
622 QString mime = mimeMap.value(format);
623 if (mime.isNull())
624 return false;
625
626 flags = CFI_POINTER;
627
628 if (data == NULL)
629 return true; // delayed rendering, nothing to do
630
631 QByteArray r = QInternalMimeData::renderDataHelper(mime, mimeData);
632 if (r.isNull())
633 return false;
634
635 *data = QPMMime::allocateMemory(r.size() + sizeof(ULONG));
636 if (!*data)
637 return false;
638
639 *((ULONG *)(*data)) = r.size();
640 memcpy((void *)(*data + sizeof(ULONG)), r.data(), r.size());
641 return true;
642}
643
644QList<QPMMime::MimeCFPair> QPMMimeAnyMime::mimesForFormats(const QList<ULONG> &formats) const
645{
646 QList<MimeCFPair> mimes;
647
648 foreach (ULONG format, formats) {
649 QString mime = mimeMap.value(format);
650 if (mime.isEmpty())
651 mime = registerFormat(format);
652 if (!mime.isEmpty())
653 mimes << MimeCFPair(mime, format);
654 }
655
656 return mimes;
657}
658
659QVariant QPMMimeAnyMime::convertFromFormat(ULONG format, ULONG flags, ULONG data,
660 const QString &mimeType,
661 QVariant::Type preferredType) const
662{
663 Q_UNUSED(preferredType);
664
665 QVariant ret;
666
667 if (cfMap.value(mimeType) != format)
668 return ret;
669
670 if (!(flags & CFI_POINTER) || !data)
671 return ret;
672
673 // get the real block size (always rounded to the page boundary (4K))
674 ULONG sz = ~0, fl = 0, arc;
675 arc = DosQueryMem((PVOID)data, &sz, &fl);
676 if (arc != NO_ERROR) {
677#ifndef QT_NO_DEBUG
678 qWarning("QPMMimeText::convertFromFormat: DosQueryMem failed with %lu", arc);
679#endif
680 return ret;
681 }
682 ULONG size = *((ULONG *)data);
683 if (!size || size + sizeof(ULONG) > sz)
684 return ret;
685
686 // it should be enough to return the data and let QMimeData do the rest.
687 ret = QByteArray((const char *)(data + sizeof(ULONG)), size);
688 return ret;
689}
690
691ULONG QPMMimeAnyMime::registerMimeType(const QString &mime) const
692{
693 if (mime.isEmpty())
694 return 0;
695
696 QString mimeToReg = mime;
697
698 bool ianaType = false;
699 foreach(QString prefix, ianaTypes) {
700 if (mime.startsWith(prefix)) {
701 ianaType = true;
702 break;
703 }
704 }
705 if (!ianaType) {
706 // prepend the non-standard type with the prefix that makes it comply
707 // with the standard
708 mimeToReg = customPrefix + mime + QChar('\"');
709 }
710
711 mimeToReg = mimePrefix + mimeToReg;
712 ULONG cf = QPMMime::registerMimeType(mimeToReg);
713 if (cf) {
714 cfMap[mime] = cf;
715 mimeMap[cf] = mime;
716 }
717 return cf;
718}
719
720QString QPMMimeAnyMime::registerFormat(ULONG format) const
721{
722 QString mime;
723
724 if (!format)
725 return mime;
726
727 QString atomStr = formatName(format);
728 if (atomStr.startsWith(mimePrefix)) {
729 // the format represents the mime type we can recognize
730 mime = atomStr.mid(mimePrefix.size());
731 if (!mime.isEmpty()) {
732 cfMap[mime] = format;
733 mimeMap[format] = mime;
734 }
735 }
736 return mime;
737}
738
739////////////////////////////////////////////////////////////////////////////////
740
741QPMMimeList::QPMMimeList()
742 : initialized(false)
743{
744}
745
746QPMMimeList::~QPMMimeList()
747{
748 while (list.size())
749 delete list.first();
750}
751
752
753void QPMMimeList::init()
754{
755 if (!initialized) {
756 initialized = true;
757 new QPMMimeAnyMime; // must be the first (used as a fallback)
758 new QPMMimeText;
759 }
760}
761
762void QPMMimeList::addMime(QPMMime *mime)
763{
764 init();
765 list.prepend(mime);
766}
767
768void QPMMimeList::removeMime(QPMMime *mime)
769{
770 init();
771 list.removeAll(mime);
772}
773
774QList<QPMMime*> QPMMimeList::mimes()
775{
776 init();
777 return list;
778}
779
780QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.