1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the plugins of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
43 #include "qcocoahelpers.h"
44 #include "qmacclipboard.h"
48 #include "qimagewriter.h"
49 #include "qimagereader.h"
50 #include "qdatastream.h"
52 #include "qdatetime.h"
53 #include "qguiapplication.h"
54 #include "qtextcodec.h"
59 #include <Cocoa/Cocoa.h>
63 extern CGImageRef qt_mac_createCGImageFromQImage(const QImage &img, const QImage **imagePtr = 0); // qpaintengine_mac.cpp
65 typedef QList<QMacPasteboardMime*> MimeList;
66 Q_GLOBAL_STATIC(MimeList, globalMimeList)
67 Q_GLOBAL_STATIC(QStringList, globalDraggedTypesList)
70 \fn void qRegisterDraggedTypes(const QStringList &types)
71 \relates QMacPasteboardMime
73 Registers the given \a types as custom pasteboard types.
75 This function should be called to enable the Drag and Drop events
76 for custom pasteboard types on Cocoa implementations. This is required
77 in addition to a QMacPasteboardMime subclass implementation. By default
78 drag and drop is enabled for all standard pasteboard types.
80 \sa QMacPasteboardMime
82 Q_WIDGETS_EXPORT void qRegisterDraggedTypes(const QStringList &types)
84 (*globalDraggedTypesList()) += types;
87 const QStringList& qEnabledDraggedTypes()
89 return (*globalDraggedTypesList());
93 /*****************************************************************************
95 *****************************************************************************/
96 //#define DEBUG_MIME_MAPS
99 extern QString qt_mac_from_pascal_string(const Str255); //qglobal.cpp
100 extern void qt_mac_from_pascal_string(QString, Str255, TextEncoding encoding=0, int len=-1); //qglobal.cpp
102 ScrapFlavorType qt_mac_mime_type = 'CUTE';
103 CFStringRef qt_mac_mime_typeUTI = CFSTR("com.pasteboard.trolltech.marker");
106 \class QMacPasteboardMime
107 \brief The QMacPasteboardMime class converts between a MIME type and a
108 \l{http://developer.apple.com/macosx/uniformtypeidentifiers.html}{Uniform
109 Type Identifier (UTI)} format.
115 Qt's drag and drop and clipboard facilities use the MIME
116 standard. On X11, this maps trivially to the Xdnd protocol. On
117 Mac, although some applications use MIME to describe clipboard
118 contents, it is more common to use Apple's UTI format.
120 QMacPasteboardMime's role is to bridge the gap between MIME and UTI;
121 By subclasses this class, one can extend Qt's drag and drop
122 and clipboard handling to convert to and from unsupported, or proprietary, UTI formats.
124 A subclass of QMacPasteboardMime will automatically be registered, and active, upon instantiation.
126 Qt has predefined support for the following UTIs:
128 \i public.utf8-plain-text - converts to "text/plain"
129 \i public.utf16-plain-text - converts to "text/plain"
130 \i public.html - converts to "text/html"
131 \i public.url - converts to "text/uri-list"
132 \i public.file-url - converts to "text/uri-list"
133 \i public.tiff - converts to "application/x-qt-image"
134 \i public.vcard - converts to "text/plain"
135 \i com.apple.traditional-mac-plain-text - converts to "text/plain"
136 \i com.apple.pict - converts to "application/x-qt-image"
139 When working with MIME data, Qt will interate through all instances of QMacPasteboardMime to
140 find an instance that can convert to, or from, a specific MIME type. It will do this by calling
141 canConvert() on each instance, starting with (and choosing) the last created instance first.
142 The actual conversions will be done by using convertToMime() and convertFromMime().
144 \note The API uses the term "flavor" in some cases. This is for backwards
145 compatibility reasons, and should now be understood as UTIs.
148 /*! \enum QMacPasteboardMime::QMacPasteboardMimeType
153 Constructs a new conversion object of type \a t, adding it to the
154 globally accessed list of available convertors.
156 QMacPasteboardMime::QMacPasteboardMime(char t) : type(t)
158 globalMimeList()->append(this);
162 Destroys a conversion object, removing it from the global
163 list of available convertors.
165 QMacPasteboardMime::~QMacPasteboardMime()
167 if (!QGuiApplication::closingDown())
168 globalMimeList()->removeAll(this);
171 class QMacPasteboardMimeAny : public QMacPasteboardMime {
175 QMacPasteboardMimeAny() : QMacPasteboardMime(MIME_QT_CONVERTOR|MIME_ALL) {
177 ~QMacPasteboardMimeAny() {
179 QString convertorName();
181 QString flavorFor(const QString &mime);
182 QString mimeFor(QString flav);
183 bool canConvert(const QString &mime, QString flav);
184 QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav);
185 QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav);
188 QString QMacPasteboardMimeAny::convertorName()
190 return QLatin1String("Any-Mime");
193 QString QMacPasteboardMimeAny::flavorFor(const QString &mime)
195 // do not handle the mime type name in the drag pasteboard
196 if (mime == QLatin1String("application/x-qt-mime-type-name"))
198 QString ret = QLatin1String("com.trolltech.anymime.") + mime;
199 return ret.replace(QLatin1Char('/'), QLatin1String("--"));
202 QString QMacPasteboardMimeAny::mimeFor(QString flav)
204 const QString any_prefix = QLatin1String("com.trolltech.anymime.");
205 if (flav.size() > any_prefix.length() && flav.startsWith(any_prefix))
206 return flav.mid(any_prefix.length()).replace(QLatin1String("--"), QLatin1String("/"));
210 bool QMacPasteboardMimeAny::canConvert(const QString &mime, QString flav)
212 return mimeFor(flav) == mime;
215 QVariant QMacPasteboardMimeAny::convertToMime(const QString &mime, QList<QByteArray> data, QString)
217 if (data.count() > 1)
218 qWarning("QMacPasteboardMimeAny: Cannot handle multiple member data");
220 if (mime == QLatin1String("text/plain"))
221 ret = QString::fromUtf8(data.first());
227 QList<QByteArray> QMacPasteboardMimeAny::convertFromMime(const QString &mime, QVariant data, QString)
229 QList<QByteArray> ret;
230 if (mime == QLatin1String("text/plain"))
231 ret.append(data.toString().toUtf8());
233 ret.append(data.toByteArray());
237 class QMacPasteboardMimeTypeName : public QMacPasteboardMime {
241 QMacPasteboardMimeTypeName() : QMacPasteboardMime(MIME_QT_CONVERTOR|MIME_ALL) {
243 ~QMacPasteboardMimeTypeName() {
245 QString convertorName();
247 QString flavorFor(const QString &mime);
248 QString mimeFor(QString flav);
249 bool canConvert(const QString &mime, QString flav);
250 QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav);
251 QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav);
254 QString QMacPasteboardMimeTypeName::convertorName()
256 return QLatin1String("Qt-Mime-Type");
259 QString QMacPasteboardMimeTypeName::flavorFor(const QString &mime)
261 if (mime == QLatin1String("application/x-qt-mime-type-name"))
262 return QLatin1String("com.trolltech.qt.MimeTypeName");
266 QString QMacPasteboardMimeTypeName::mimeFor(QString)
271 bool QMacPasteboardMimeTypeName::canConvert(const QString &, QString)
276 QVariant QMacPasteboardMimeTypeName::convertToMime(const QString &, QList<QByteArray>, QString)
282 QList<QByteArray> QMacPasteboardMimeTypeName::convertFromMime(const QString &, QVariant, QString)
284 QList<QByteArray> ret;
285 ret.append(QString("x-qt-mime-type-name").toUtf8());
289 class QMacPasteboardMimePlainText : public QMacPasteboardMime {
291 QMacPasteboardMimePlainText() : QMacPasteboardMime(MIME_ALL) { }
292 QString convertorName();
294 QString flavorFor(const QString &mime);
295 QString mimeFor(QString flav);
296 bool canConvert(const QString &mime, QString flav);
297 QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav);
298 QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav);
301 QString QMacPasteboardMimePlainText::convertorName()
303 return QLatin1String("PlainText");
306 QString QMacPasteboardMimePlainText::flavorFor(const QString &mime)
308 if (mime == QLatin1String("text/plain"))
309 return QLatin1String("com.apple.traditional-mac-plain-text");
313 QString QMacPasteboardMimePlainText::mimeFor(QString flav)
315 if (flav == QLatin1String("com.apple.traditional-mac-plain-text"))
316 return QLatin1String("text/plain");
320 bool QMacPasteboardMimePlainText::canConvert(const QString &mime, QString flav)
322 return flavorFor(mime) == flav;
325 QVariant QMacPasteboardMimePlainText::convertToMime(const QString &mimetype, QList<QByteArray> data, QString flavor)
327 if (data.count() > 1)
328 qWarning("QMacPasteboardMimePlainText: Cannot handle multiple member data");
329 const QByteArray &firstData = data.first();
331 if (flavor == QCFString(QLatin1String("com.apple.traditional-mac-plain-text"))) {
332 QCFString str(CFStringCreateWithBytes(kCFAllocatorDefault,
333 reinterpret_cast<const UInt8 *>(firstData.constData()),
334 firstData.size(), CFStringGetSystemEncoding(), false));
337 qWarning("QMime::convertToMime: unhandled mimetype: %s", qPrintable(mimetype));
342 QList<QByteArray> QMacPasteboardMimePlainText::convertFromMime(const QString &, QVariant data, QString flavor)
344 QList<QByteArray> ret;
345 QString string = data.toString();
346 if (flavor == QCFString(QLatin1String("com.apple.traditional-mac-plain-text")))
347 ret.append(string.toLatin1());
351 class QMacPasteboardMimeUnicodeText : public QMacPasteboardMime {
353 QMacPasteboardMimeUnicodeText() : QMacPasteboardMime(MIME_ALL) { }
354 QString convertorName();
356 QString flavorFor(const QString &mime);
357 QString mimeFor(QString flav);
358 bool canConvert(const QString &mime, QString flav);
359 QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav);
360 QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav);
363 QString QMacPasteboardMimeUnicodeText::convertorName()
365 return QLatin1String("UnicodeText");
368 QString QMacPasteboardMimeUnicodeText::flavorFor(const QString &mime)
370 if (mime == QLatin1String("text/plain"))
371 return QLatin1String("public.utf16-plain-text");
372 int i = mime.indexOf(QLatin1String("charset="));
374 QString cs(mime.mid(i+8).toLower());
375 i = cs.indexOf(QLatin1Char(';'));
378 if (cs == QLatin1String("system"))
379 return QLatin1String("public.utf8-plain-text");
380 else if (cs == QLatin1String("iso-10646-ucs-2")
381 || cs == QLatin1String("utf16"))
382 return QLatin1String("public.utf16-plain-text");
387 QString QMacPasteboardMimeUnicodeText::mimeFor(QString flav)
389 if (flav == QLatin1String("public.utf16-plain-text") || flav == QLatin1String("public.utf8-plain-text"))
390 return QLatin1String("text/plain");
394 bool QMacPasteboardMimeUnicodeText::canConvert(const QString &mime, QString flav)
396 return flavorFor(mime) == flav;
399 QVariant QMacPasteboardMimeUnicodeText::convertToMime(const QString &mimetype, QList<QByteArray> data, QString flavor)
401 if (data.count() > 1)
402 qWarning("QMacPasteboardMimeUnicodeText: Cannot handle multiple member data");
403 const QByteArray &firstData = data.first();
404 // I can only handle two types (system and unicode) so deal with them that way
406 if (flavor == QLatin1String("public.utf8-plain-text")) {
407 QCFString str(CFStringCreateWithBytes(kCFAllocatorDefault,
408 reinterpret_cast<const UInt8 *>(firstData.constData()),
409 firstData.size(), CFStringGetSystemEncoding(), false));
411 } else if (flavor == QLatin1String("public.utf16-plain-text")) {
412 ret = QString(reinterpret_cast<const QChar *>(firstData.constData()),
413 firstData.size() / sizeof(QChar));
415 qWarning("QMime::convertToMime: unhandled mimetype: %s", qPrintable(mimetype));
420 QList<QByteArray> QMacPasteboardMimeUnicodeText::convertFromMime(const QString &, QVariant data, QString flavor)
422 QList<QByteArray> ret;
423 QString string = data.toString();
424 if (flavor == QLatin1String("public.utf8-plain-text"))
425 ret.append(string.toUtf8());
426 else if (flavor == QLatin1String("public.utf16-plain-text"))
427 ret.append(QByteArray((char*)string.utf16(), string.length()*2));
431 class QMacPasteboardMimeHTMLText : public QMacPasteboardMime {
433 QMacPasteboardMimeHTMLText() : QMacPasteboardMime(MIME_ALL) { }
434 QString convertorName();
436 QString flavorFor(const QString &mime);
437 QString mimeFor(QString flav);
438 bool canConvert(const QString &mime, QString flav);
439 QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav);
440 QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav);
443 QString QMacPasteboardMimeHTMLText::convertorName()
445 return QLatin1String("HTML");
448 QString QMacPasteboardMimeHTMLText::flavorFor(const QString &mime)
450 if (mime == QLatin1String("text/html"))
451 return QLatin1String("public.html");
455 QString QMacPasteboardMimeHTMLText::mimeFor(QString flav)
457 if (flav == QLatin1String("public.html"))
458 return QLatin1String("text/html");
462 bool QMacPasteboardMimeHTMLText::canConvert(const QString &mime, QString flav)
464 return flavorFor(mime) == flav;
467 QVariant QMacPasteboardMimeHTMLText::convertToMime(const QString &mimeType, QList<QByteArray> data, QString flavor)
469 if (!canConvert(mimeType, flavor))
471 if (data.count() > 1)
472 qWarning("QMacPasteboardMimeHTMLText: Cannot handle multiple member data");
476 QList<QByteArray> QMacPasteboardMimeHTMLText::convertFromMime(const QString &mime, QVariant data, QString flavor)
478 QList<QByteArray> ret;
479 if (!canConvert(mime, flavor))
481 ret.append(data.toByteArray());
485 class QMacPasteboardMimeTiff : public QMacPasteboardMime {
487 QMacPasteboardMimeTiff() : QMacPasteboardMime(MIME_ALL) { }
488 QString convertorName();
490 QString flavorFor(const QString &mime);
491 QString mimeFor(QString flav);
492 bool canConvert(const QString &mime, QString flav);
493 QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav);
494 QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav);
497 QString QMacPasteboardMimeTiff::convertorName()
499 return QLatin1String("Tiff");
502 QString QMacPasteboardMimeTiff::flavorFor(const QString &mime)
504 if (mime.startsWith(QLatin1String("application/x-qt-image")))
505 return QLatin1String("public.tiff");
509 QString QMacPasteboardMimeTiff::mimeFor(QString flav)
511 if (flav == QLatin1String("public.tiff"))
512 return QLatin1String("application/x-qt-image");
516 bool QMacPasteboardMimeTiff::canConvert(const QString &mime, QString flav)
518 return flav == QLatin1String("public.tiff") && mime == QLatin1String("application/x-qt-image");
521 QVariant QMacPasteboardMimeTiff::convertToMime(const QString &mime, QList<QByteArray> data, QString flav)
523 if (data.count() > 1)
524 qWarning("QMacPasteboardMimeTiff: Cannot handle multiple member data");
526 if (!canConvert(mime, flav))
528 const QByteArray &a = data.first();
529 QCFType<CGImageRef> image;
530 QCFType<CFDataRef> tiffData = CFDataCreateWithBytesNoCopy(0,
531 reinterpret_cast<const UInt8 *>(a.constData()),
532 a.size(), kCFAllocatorNull);
533 QCFType<CGImageSourceRef> imageSource = CGImageSourceCreateWithData(tiffData, 0);
534 image = CGImageSourceCreateImageAtIndex(imageSource, 0, 0);
536 // ### TODO (msorvig) QPixmap conversion
538 // ret = QVariant(QPixmap::fromMacCGImageRef(image).toImage());
542 QList<QByteArray> QMacPasteboardMimeTiff::convertFromMime(const QString &mime, QVariant variant, QString flav)
544 QList<QByteArray> ret;
545 if (!canConvert(mime, flav))
548 QImage img = qvariant_cast<QImage>(variant);
549 QCFType<CGImageRef> cgimage = qt_mac_image_to_cgimage(img);
551 QCFType<CFMutableDataRef> data = CFDataCreateMutable(0, 0);
552 QCFType<CGImageDestinationRef> imageDestination = CGImageDestinationCreateWithData(data, kUTTypeTIFF, 1, 0);
553 if (imageDestination != 0) {
555 QCFType<CFTypeRef> values[2];
556 QCFType<CFDictionaryRef> options;
557 keys[0] = kCGImagePropertyPixelWidth;
558 keys[1] = kCGImagePropertyPixelHeight;
559 int width = img.width();
560 int height = img.height();
561 values[0] = CFNumberCreate(0, kCFNumberIntType, &width);
562 values[1] = CFNumberCreate(0, kCFNumberIntType, &height);
563 options = CFDictionaryCreate(0, reinterpret_cast<const void **>(keys),
564 reinterpret_cast<const void **>(values), 2,
565 &kCFTypeDictionaryKeyCallBacks,
566 &kCFTypeDictionaryValueCallBacks);
567 CGImageDestinationAddImage(imageDestination, cgimage, options);
568 CGImageDestinationFinalize(imageDestination);
570 QByteArray ar(CFDataGetLength(data), 0);
572 CFRangeMake(0, ar.size()),
573 reinterpret_cast<UInt8 *>(ar.data()));
579 class QMacPasteboardMimeFileUri : public QMacPasteboardMime {
581 QMacPasteboardMimeFileUri() : QMacPasteboardMime(MIME_ALL) { }
582 QString convertorName();
584 QString flavorFor(const QString &mime);
585 QString mimeFor(QString flav);
586 bool canConvert(const QString &mime, QString flav);
587 QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav);
588 QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav);
591 QString QMacPasteboardMimeFileUri::convertorName()
593 return QLatin1String("FileURL");
596 QString QMacPasteboardMimeFileUri::flavorFor(const QString &mime)
598 if (mime == QLatin1String("text/uri-list"))
599 return QCFString(UTTypeCreatePreferredIdentifierForTag(kUTTagClassOSType, CFSTR("furl"), 0));
603 QString QMacPasteboardMimeFileUri::mimeFor(QString flav)
605 if (flav == QCFString(UTTypeCreatePreferredIdentifierForTag(kUTTagClassOSType, CFSTR("furl"), 0)))
606 return QLatin1String("text/uri-list");
610 bool QMacPasteboardMimeFileUri::canConvert(const QString &mime, QString flav)
612 return mime == QLatin1String("text/uri-list")
613 && flav == QCFString(UTTypeCreatePreferredIdentifierForTag(kUTTagClassOSType, CFSTR("furl"), 0));
616 QVariant QMacPasteboardMimeFileUri::convertToMime(const QString &mime, QList<QByteArray> data, QString flav)
618 if (!canConvert(mime, flav))
621 for (int i = 0; i < data.size(); ++i) {
622 QUrl url = QUrl::fromEncoded(data.at(i));
623 if (url.host().toLower() == QLatin1String("localhost"))
624 url.setHost(QString());
625 url.setPath(url.path().normalized(QString::NormalizationForm_C));
628 return QVariant(ret);
631 QList<QByteArray> QMacPasteboardMimeFileUri::convertFromMime(const QString &mime, QVariant data, QString flav)
633 QList<QByteArray> ret;
634 if (!canConvert(mime, flav))
636 QList<QVariant> urls = data.toList();
637 for (int i = 0; i < urls.size(); ++i) {
638 QUrl url = urls.at(i).toUrl();
639 if (url.scheme().isEmpty())
640 url.setScheme(QLatin1String("file"));
641 if (url.scheme().toLower() == QLatin1String("file")) {
642 if (url.host().isEmpty())
643 url.setHost(QLatin1String("localhost"));
644 url.setPath(url.path().normalized(QString::NormalizationForm_D));
646 ret.append(url.toEncoded());
651 class QMacPasteboardMimeUrl : public QMacPasteboardMime {
653 QMacPasteboardMimeUrl() : QMacPasteboardMime(MIME_ALL) { }
654 QString convertorName();
656 QString flavorFor(const QString &mime);
657 QString mimeFor(QString flav);
658 bool canConvert(const QString &mime, QString flav);
659 QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav);
660 QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav);
663 QString QMacPasteboardMimeUrl::convertorName()
665 return QLatin1String("URL");
668 QString QMacPasteboardMimeUrl::flavorFor(const QString &mime)
670 if (mime.startsWith(QLatin1String("text/uri-list")))
671 return QLatin1String("public.url");
675 QString QMacPasteboardMimeUrl::mimeFor(QString flav)
677 if (flav == QLatin1String("public.url"))
678 return QLatin1String("text/uri-list");
682 bool QMacPasteboardMimeUrl::canConvert(const QString &mime, QString flav)
684 return flav == QLatin1String("public.url")
685 && mime == QLatin1String("text/uri-list");
688 QVariant QMacPasteboardMimeUrl::convertToMime(const QString &mime, QList<QByteArray> data, QString flav)
690 if (!canConvert(mime, flav))
694 for (int i=0; i<data.size(); ++i) {
695 QUrl url = QUrl::fromEncoded(data.at(i));
696 if (url.host().toLower() == QLatin1String("localhost"))
697 url.setHost(QString());
698 url.setPath(url.path().normalized(QString::NormalizationForm_C));
701 return QVariant(ret);
704 QList<QByteArray> QMacPasteboardMimeUrl::convertFromMime(const QString &mime, QVariant data, QString flav)
706 QList<QByteArray> ret;
707 if (!canConvert(mime, flav))
710 QList<QVariant> urls = data.toList();
711 for (int i=0; i<urls.size(); ++i) {
712 QUrl url = urls.at(i).toUrl();
713 if (url.scheme().isEmpty())
714 url.setScheme(QLatin1String("file"));
715 if (url.scheme().toLower() == QLatin1String("file")) {
716 if (url.host().isEmpty())
717 url.setHost(QLatin1String("localhost"));
718 url.setPath(url.path().normalized(QString::NormalizationForm_D));
720 ret.append(url.toEncoded());
725 class QMacPasteboardMimeVCard : public QMacPasteboardMime
728 QMacPasteboardMimeVCard() : QMacPasteboardMime(MIME_ALL){ }
729 QString convertorName();
731 QString flavorFor(const QString &mime);
732 QString mimeFor(QString flav);
733 bool canConvert(const QString &mime, QString flav);
734 QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav);
735 QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav);
738 QString QMacPasteboardMimeVCard::convertorName()
740 return QString("VCard");
743 bool QMacPasteboardMimeVCard::canConvert(const QString &mime, QString flav)
745 return mimeFor(flav) == mime;
748 QString QMacPasteboardMimeVCard::flavorFor(const QString &mime)
750 if (mime.startsWith(QLatin1String("text/plain")))
751 return QLatin1String("public.vcard");
755 QString QMacPasteboardMimeVCard::mimeFor(QString flav)
757 if (flav == QLatin1String("public.vcard"))
758 return QLatin1String("text/plain");
762 QVariant QMacPasteboardMimeVCard::convertToMime(const QString &mime, QList<QByteArray> data, QString)
765 if (mime == QLatin1String("text/plain")) {
766 for (int i=0; i<data.size(); ++i)
769 return QVariant(cards);
772 QList<QByteArray> QMacPasteboardMimeVCard::convertFromMime(const QString &mime, QVariant data, QString)
774 QList<QByteArray> ret;
775 if (mime == QLatin1String("text/plain"))
776 ret.append(data.toString().toUtf8());
784 This is an internal function.
786 void QMacPasteboardMime::initializeMimeTypes()
788 if (globalMimeList()->isEmpty()) {
789 //standard types that we wrap
790 new QMacPasteboardMimeTiff;
791 new QMacPasteboardMimeUnicodeText;
792 new QMacPasteboardMimePlainText;
793 new QMacPasteboardMimeHTMLText;
794 new QMacPasteboardMimeFileUri;
795 new QMacPasteboardMimeUrl;
796 new QMacPasteboardMimeTypeName;
797 new QMacPasteboardMimeVCard;
798 //make sure our "non-standard" types are always last! --Sam
799 new QMacPasteboardMimeAny;
806 void QMacPasteboardMime::destroyMimeTypes()
808 MimeList *mimes = globalMimeList();
809 while (!mimes->isEmpty())
810 delete mimes->takeFirst();
814 Returns the most-recently created QMacPasteboardMime of type \a t that can convert
815 between the \a mime and \a flav formats. Returns 0 if no such convertor
819 QMacPasteboardMime::convertor(uchar t, const QString &mime, QString flav)
821 MimeList *mimes = globalMimeList();
822 for (MimeList::const_iterator it = mimes->constBegin(); it != mimes->constEnd(); ++it) {
823 #ifdef DEBUG_MIME_MAPS
824 qDebug("QMacPasteboardMime::convertor: seeing if %s (%d) can convert %s to %d[%c%c%c%c] [%d]",
825 (*it)->convertorName().toLatin1().constData(),
826 (*it)->type & t, mime.toLatin1().constData(),
827 flav, (flav >> 24) & 0xFF, (flav >> 16) & 0xFF, (flav >> 8) & 0xFF, (flav) & 0xFF,
828 (*it)->canConvert(mime,flav));
829 for (int i = 0; i < (*it)->countFlavors(); ++i) {
830 int f = (*it)->flavor(i);
831 qDebug(" %d) %d[%c%c%c%c] [%s]", i, f,
832 (f >> 24) & 0xFF, (f >> 16) & 0xFF, (f >> 8) & 0xFF, (f) & 0xFF,
833 (*it)->convertorName().toLatin1().constData());
836 if (((*it)->type & t) && (*it)->canConvert(mime, flav))
842 Returns a MIME type of type \a t for \a flav, or 0 if none exists.
844 QString QMacPasteboardMime::flavorToMime(uchar t, QString flav)
846 MimeList *mimes = globalMimeList();
847 for (MimeList::const_iterator it = mimes->constBegin(); it != mimes->constEnd(); ++it) {
848 #ifdef DEBUG_MIME_MAPS
849 qDebug("QMacMIme::flavorToMime: attempting %s (%d) for flavor %d[%c%c%c%c] [%s]",
850 (*it)->convertorName().toLatin1().constData(),
851 (*it)->type & t, flav, (flav >> 24) & 0xFF, (flav >> 16) & 0xFF, (flav >> 8) & 0xFF, (flav) & 0xFF,
852 (*it)->mimeFor(flav).toLatin1().constData());
855 if ((*it)->type & t) {
856 QString mimeType = (*it)->mimeFor(flav);
857 if (!mimeType.isNull())
865 Returns a list of all currently defined QMacPasteboardMime objects of type \a t.
867 QList<QMacPasteboardMime*> QMacPasteboardMime::all(uchar t)
870 MimeList *mimes = globalMimeList();
871 for (MimeList::const_iterator it = mimes->constBegin(); it != mimes->constEnd(); ++it) {
880 \fn QString QMacPasteboardMime::convertorName()
882 Returns a name for the convertor.
884 All subclasses must reimplement this pure virtual function.
888 \fn bool QMacPasteboardMime::canConvert(const QString &mime, QString flav)
890 Returns true if the convertor can convert (both ways) between
891 \a mime and \a flav; otherwise returns false.
893 All subclasses must reimplement this pure virtual function.
897 \fn QString QMacPasteboardMime::mimeFor(QString flav)
899 Returns the MIME UTI used for Mac flavor \a flav, or 0 if this
900 convertor does not support \a flav.
902 All subclasses must reimplement this pure virtual function.
906 \fn QString QMacPasteboardMime::flavorFor(const QString &mime)
908 Returns the Mac UTI used for MIME type \a mime, or 0 if this
909 convertor does not support \a mime.
911 All subclasses must reimplement this pure virtual function.
915 \fn QVariant QMacPasteboardMime::convertToMime(const QString &mime, QList<QByteArray> data, QString flav)
917 Returns \a data converted from Mac UTI \a flav to MIME type \a
920 Note that Mac flavors must all be self-terminating. The input \a
921 data may contain trailing data.
923 All subclasses must reimplement this pure virtual function.
927 \fn QList<QByteArray> QMacPasteboardMime::convertFromMime(const QString &mime, QVariant data, QString flav)
929 Returns \a data converted from MIME type \a mime
932 Note that Mac flavors must all be self-terminating. The return
933 value may contain trailing data.
935 All subclasses must reimplement this pure virtual function.