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)
68 static void cleanup_mimes()
70 MimeList *mimes = globalMimeList();
71 while (!mimes->isEmpty())
72 delete mimes->takeFirst();
75 Q_GLOBAL_STATIC(QStringList, globalDraggedTypesList)
78 \fn void qRegisterDraggedTypes(const QStringList &types)
79 \relates QMacPasteboardMime
81 Registers the given \a types as custom pasteboard types.
83 This function should be called to enable the Drag and Drop events
84 for custom pasteboard types on Cocoa implementations. This is required
85 in addition to a QMacPasteboardMime subclass implementation. By default
86 drag and drop is enabled for all standard pasteboard types.
88 \sa QMacPasteboardMime
90 Q_WIDGETS_EXPORT void qRegisterDraggedTypes(const QStringList &types)
92 (*globalDraggedTypesList()) += types;
95 const QStringList& qEnabledDraggedTypes()
97 return (*globalDraggedTypesList());
101 /*****************************************************************************
102 QDnD debug facilities
103 *****************************************************************************/
104 //#define DEBUG_MIME_MAPS
107 extern QString qt_mac_from_pascal_string(const Str255); //qglobal.cpp
108 extern void qt_mac_from_pascal_string(QString, Str255, TextEncoding encoding=0, int len=-1); //qglobal.cpp
110 ScrapFlavorType qt_mac_mime_type = 'CUTE';
111 CFStringRef qt_mac_mime_typeUTI = CFSTR("com.pasteboard.trolltech.marker");
114 \class QMacPasteboardMime
115 \brief The QMacPasteboardMime class converts between a MIME type and a
116 \l{http://developer.apple.com/macosx/uniformtypeidentifiers.html}{Uniform
117 Type Identifier (UTI)} format.
123 Qt's drag and drop and clipboard facilities use the MIME
124 standard. On X11, this maps trivially to the Xdnd protocol. On
125 Mac, although some applications use MIME to describe clipboard
126 contents, it is more common to use Apple's UTI format.
128 QMacPasteboardMime's role is to bridge the gap between MIME and UTI;
129 By subclasses this class, one can extend Qt's drag and drop
130 and clipboard handling to convert to and from unsupported, or proprietary, UTI formats.
132 A subclass of QMacPasteboardMime will automatically be registered, and active, upon instantiation.
134 Qt has predefined support for the following UTIs:
136 \i public.utf8-plain-text - converts to "text/plain"
137 \i public.utf16-plain-text - converts to "text/plain"
138 \i public.html - converts to "text/html"
139 \i public.url - converts to "text/uri-list"
140 \i public.file-url - converts to "text/uri-list"
141 \i public.tiff - converts to "application/x-qt-image"
142 \i public.vcard - converts to "text/plain"
143 \i com.apple.traditional-mac-plain-text - converts to "text/plain"
144 \i com.apple.pict - converts to "application/x-qt-image"
147 When working with MIME data, Qt will interate through all instances of QMacPasteboardMime to
148 find an instance that can convert to, or from, a specific MIME type. It will do this by calling
149 canConvert() on each instance, starting with (and choosing) the last created instance first.
150 The actual conversions will be done by using convertToMime() and convertFromMime().
152 \note The API uses the term "flavor" in some cases. This is for backwards
153 compatibility reasons, and should now be understood as UTIs.
156 /*! \enum QMacPasteboardMime::QMacPasteboardMimeType
161 Constructs a new conversion object of type \a t, adding it to the
162 globally accessed list of available convertors.
164 QMacPasteboardMime::QMacPasteboardMime(char t) : type(t)
166 globalMimeList()->append(this);
170 Destroys a conversion object, removing it from the global
171 list of available convertors.
173 QMacPasteboardMime::~QMacPasteboardMime()
175 if (!QGuiApplication::closingDown())
176 globalMimeList()->removeAll(this);
179 class QMacPasteboardMimeAny : public QMacPasteboardMime {
183 QMacPasteboardMimeAny() : QMacPasteboardMime(MIME_QT_CONVERTOR|MIME_ALL) {
185 ~QMacPasteboardMimeAny() {
187 QString convertorName();
189 QString flavorFor(const QString &mime);
190 QString mimeFor(QString flav);
191 bool canConvert(const QString &mime, QString flav);
192 QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav);
193 QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav);
196 QString QMacPasteboardMimeAny::convertorName()
198 return QLatin1String("Any-Mime");
201 QString QMacPasteboardMimeAny::flavorFor(const QString &mime)
203 // do not handle the mime type name in the drag pasteboard
204 if (mime == QLatin1String("application/x-qt-mime-type-name"))
206 QString ret = QLatin1String("com.trolltech.anymime.") + mime;
207 return ret.replace(QLatin1Char('/'), QLatin1String("--"));
210 QString QMacPasteboardMimeAny::mimeFor(QString flav)
212 const QString any_prefix = QLatin1String("com.trolltech.anymime.");
213 if (flav.size() > any_prefix.length() && flav.startsWith(any_prefix))
214 return flav.mid(any_prefix.length()).replace(QLatin1String("--"), QLatin1String("/"));
218 bool QMacPasteboardMimeAny::canConvert(const QString &mime, QString flav)
220 return mimeFor(flav) == mime;
223 QVariant QMacPasteboardMimeAny::convertToMime(const QString &mime, QList<QByteArray> data, QString)
225 if (data.count() > 1)
226 qWarning("QMacPasteboardMimeAny: Cannot handle multiple member data");
228 if (mime == QLatin1String("text/plain"))
229 ret = QString::fromUtf8(data.first());
235 QList<QByteArray> QMacPasteboardMimeAny::convertFromMime(const QString &mime, QVariant data, QString)
237 QList<QByteArray> ret;
238 if (mime == QLatin1String("text/plain"))
239 ret.append(data.toString().toUtf8());
241 ret.append(data.toByteArray());
245 class QMacPasteboardMimeTypeName : public QMacPasteboardMime {
249 QMacPasteboardMimeTypeName() : QMacPasteboardMime(MIME_QT_CONVERTOR|MIME_ALL) {
251 ~QMacPasteboardMimeTypeName() {
253 QString convertorName();
255 QString flavorFor(const QString &mime);
256 QString mimeFor(QString flav);
257 bool canConvert(const QString &mime, QString flav);
258 QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav);
259 QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav);
262 QString QMacPasteboardMimeTypeName::convertorName()
264 return QLatin1String("Qt-Mime-Type");
267 QString QMacPasteboardMimeTypeName::flavorFor(const QString &mime)
269 if (mime == QLatin1String("application/x-qt-mime-type-name"))
270 return QLatin1String("com.trolltech.qt.MimeTypeName");
274 QString QMacPasteboardMimeTypeName::mimeFor(QString)
279 bool QMacPasteboardMimeTypeName::canConvert(const QString &, QString)
284 QVariant QMacPasteboardMimeTypeName::convertToMime(const QString &, QList<QByteArray>, QString)
290 QList<QByteArray> QMacPasteboardMimeTypeName::convertFromMime(const QString &, QVariant, QString)
292 QList<QByteArray> ret;
293 ret.append(QString("x-qt-mime-type-name").toUtf8());
297 class QMacPasteboardMimePlainText : public QMacPasteboardMime {
299 QMacPasteboardMimePlainText() : QMacPasteboardMime(MIME_ALL) { }
300 QString convertorName();
302 QString flavorFor(const QString &mime);
303 QString mimeFor(QString flav);
304 bool canConvert(const QString &mime, QString flav);
305 QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav);
306 QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav);
309 QString QMacPasteboardMimePlainText::convertorName()
311 return QLatin1String("PlainText");
314 QString QMacPasteboardMimePlainText::flavorFor(const QString &mime)
316 if (mime == QLatin1String("text/plain"))
317 return QLatin1String("com.apple.traditional-mac-plain-text");
321 QString QMacPasteboardMimePlainText::mimeFor(QString flav)
323 if (flav == QLatin1String("com.apple.traditional-mac-plain-text"))
324 return QLatin1String("text/plain");
328 bool QMacPasteboardMimePlainText::canConvert(const QString &mime, QString flav)
330 return flavorFor(mime) == flav;
333 QVariant QMacPasteboardMimePlainText::convertToMime(const QString &mimetype, QList<QByteArray> data, QString flavor)
335 if (data.count() > 1)
336 qWarning("QMacPasteboardMimePlainText: Cannot handle multiple member data");
337 const QByteArray &firstData = data.first();
339 if (flavor == QCFString(QLatin1String("com.apple.traditional-mac-plain-text"))) {
340 QCFString str(CFStringCreateWithBytes(kCFAllocatorDefault,
341 reinterpret_cast<const UInt8 *>(firstData.constData()),
342 firstData.size(), CFStringGetSystemEncoding(), false));
345 qWarning("QMime::convertToMime: unhandled mimetype: %s", qPrintable(mimetype));
350 QList<QByteArray> QMacPasteboardMimePlainText::convertFromMime(const QString &, QVariant data, QString flavor)
352 QList<QByteArray> ret;
353 QString string = data.toString();
354 if (flavor == QCFString(QLatin1String("com.apple.traditional-mac-plain-text")))
355 ret.append(string.toLatin1());
359 class QMacPasteboardMimeUnicodeText : public QMacPasteboardMime {
361 QMacPasteboardMimeUnicodeText() : QMacPasteboardMime(MIME_ALL) { }
362 QString convertorName();
364 QString flavorFor(const QString &mime);
365 QString mimeFor(QString flav);
366 bool canConvert(const QString &mime, QString flav);
367 QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav);
368 QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav);
371 QString QMacPasteboardMimeUnicodeText::convertorName()
373 return QLatin1String("UnicodeText");
376 QString QMacPasteboardMimeUnicodeText::flavorFor(const QString &mime)
378 if (mime == QLatin1String("text/plain"))
379 return QLatin1String("public.utf16-plain-text");
380 int i = mime.indexOf(QLatin1String("charset="));
382 QString cs(mime.mid(i+8).toLower());
383 i = cs.indexOf(QLatin1Char(';'));
386 if (cs == QLatin1String("system"))
387 return QLatin1String("public.utf8-plain-text");
388 else if (cs == QLatin1String("iso-10646-ucs-2")
389 || cs == QLatin1String("utf16"))
390 return QLatin1String("public.utf16-plain-text");
395 QString QMacPasteboardMimeUnicodeText::mimeFor(QString flav)
397 if (flav == QLatin1String("public.utf16-plain-text") || flav == QLatin1String("public.utf8-plain-text"))
398 return QLatin1String("text/plain");
402 bool QMacPasteboardMimeUnicodeText::canConvert(const QString &mime, QString flav)
404 return flavorFor(mime) == flav;
407 QVariant QMacPasteboardMimeUnicodeText::convertToMime(const QString &mimetype, QList<QByteArray> data, QString flavor)
409 if (data.count() > 1)
410 qWarning("QMacPasteboardMimeUnicodeText: Cannot handle multiple member data");
411 const QByteArray &firstData = data.first();
412 // I can only handle two types (system and unicode) so deal with them that way
414 if (flavor == QLatin1String("public.utf8-plain-text")) {
415 QCFString str(CFStringCreateWithBytes(kCFAllocatorDefault,
416 reinterpret_cast<const UInt8 *>(firstData.constData()),
417 firstData.size(), CFStringGetSystemEncoding(), false));
419 } else if (flavor == QLatin1String("public.utf16-plain-text")) {
420 ret = QString(reinterpret_cast<const QChar *>(firstData.constData()),
421 firstData.size() / sizeof(QChar));
423 qWarning("QMime::convertToMime: unhandled mimetype: %s", qPrintable(mimetype));
428 QList<QByteArray> QMacPasteboardMimeUnicodeText::convertFromMime(const QString &, QVariant data, QString flavor)
430 QList<QByteArray> ret;
431 QString string = data.toString();
432 if (flavor == QLatin1String("public.utf8-plain-text"))
433 ret.append(string.toUtf8());
434 else if (flavor == QLatin1String("public.utf16-plain-text"))
435 ret.append(QByteArray((char*)string.utf16(), string.length()*2));
439 class QMacPasteboardMimeHTMLText : public QMacPasteboardMime {
441 QMacPasteboardMimeHTMLText() : QMacPasteboardMime(MIME_ALL) { }
442 QString convertorName();
444 QString flavorFor(const QString &mime);
445 QString mimeFor(QString flav);
446 bool canConvert(const QString &mime, QString flav);
447 QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav);
448 QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav);
451 QString QMacPasteboardMimeHTMLText::convertorName()
453 return QLatin1String("HTML");
456 QString QMacPasteboardMimeHTMLText::flavorFor(const QString &mime)
458 if (mime == QLatin1String("text/html"))
459 return QLatin1String("public.html");
463 QString QMacPasteboardMimeHTMLText::mimeFor(QString flav)
465 if (flav == QLatin1String("public.html"))
466 return QLatin1String("text/html");
470 bool QMacPasteboardMimeHTMLText::canConvert(const QString &mime, QString flav)
472 return flavorFor(mime) == flav;
475 QVariant QMacPasteboardMimeHTMLText::convertToMime(const QString &mimeType, QList<QByteArray> data, QString flavor)
477 if (!canConvert(mimeType, flavor))
479 if (data.count() > 1)
480 qWarning("QMacPasteboardMimeHTMLText: Cannot handle multiple member data");
484 QList<QByteArray> QMacPasteboardMimeHTMLText::convertFromMime(const QString &mime, QVariant data, QString flavor)
486 QList<QByteArray> ret;
487 if (!canConvert(mime, flavor))
489 ret.append(data.toByteArray());
493 class QMacPasteboardMimeTiff : public QMacPasteboardMime {
495 QMacPasteboardMimeTiff() : QMacPasteboardMime(MIME_ALL) { }
496 QString convertorName();
498 QString flavorFor(const QString &mime);
499 QString mimeFor(QString flav);
500 bool canConvert(const QString &mime, QString flav);
501 QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav);
502 QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav);
505 QString QMacPasteboardMimeTiff::convertorName()
507 return QLatin1String("Tiff");
510 QString QMacPasteboardMimeTiff::flavorFor(const QString &mime)
512 if (mime.startsWith(QLatin1String("application/x-qt-image")))
513 return QLatin1String("public.tiff");
517 QString QMacPasteboardMimeTiff::mimeFor(QString flav)
519 if (flav == QLatin1String("public.tiff"))
520 return QLatin1String("application/x-qt-image");
524 bool QMacPasteboardMimeTiff::canConvert(const QString &mime, QString flav)
526 return flav == QLatin1String("public.tiff") && mime == QLatin1String("application/x-qt-image");
529 QVariant QMacPasteboardMimeTiff::convertToMime(const QString &mime, QList<QByteArray> data, QString flav)
531 if (data.count() > 1)
532 qWarning("QMacPasteboardMimeTiff: Cannot handle multiple member data");
534 if (!canConvert(mime, flav))
536 const QByteArray &a = data.first();
537 QCFType<CGImageRef> image;
538 QCFType<CFDataRef> tiffData = CFDataCreateWithBytesNoCopy(0,
539 reinterpret_cast<const UInt8 *>(a.constData()),
540 a.size(), kCFAllocatorNull);
541 QCFType<CGImageSourceRef> imageSource = CGImageSourceCreateWithData(tiffData, 0);
542 image = CGImageSourceCreateImageAtIndex(imageSource, 0, 0);
544 // ### TODO (msorvig) QPixmap conversion
546 // ret = QVariant(QPixmap::fromMacCGImageRef(image).toImage());
550 QList<QByteArray> QMacPasteboardMimeTiff::convertFromMime(const QString &mime, QVariant variant, QString flav)
552 QList<QByteArray> ret;
553 if (!canConvert(mime, flav))
556 QImage img = qvariant_cast<QImage>(variant);
557 QCFType<CGImageRef> cgimage = qt_mac_image_to_cgimage(img);
559 QCFType<CFMutableDataRef> data = CFDataCreateMutable(0, 0);
560 QCFType<CGImageDestinationRef> imageDestination = CGImageDestinationCreateWithData(data, kUTTypeTIFF, 1, 0);
561 if (imageDestination != 0) {
563 QCFType<CFTypeRef> values[2];
564 QCFType<CFDictionaryRef> options;
565 keys[0] = kCGImagePropertyPixelWidth;
566 keys[1] = kCGImagePropertyPixelHeight;
567 int width = img.width();
568 int height = img.height();
569 values[0] = CFNumberCreate(0, kCFNumberIntType, &width);
570 values[1] = CFNumberCreate(0, kCFNumberIntType, &height);
571 options = CFDictionaryCreate(0, reinterpret_cast<const void **>(keys),
572 reinterpret_cast<const void **>(values), 2,
573 &kCFTypeDictionaryKeyCallBacks,
574 &kCFTypeDictionaryValueCallBacks);
575 CGImageDestinationAddImage(imageDestination, cgimage, options);
576 CGImageDestinationFinalize(imageDestination);
578 QByteArray ar(CFDataGetLength(data), 0);
580 CFRangeMake(0, ar.size()),
581 reinterpret_cast<UInt8 *>(ar.data()));
587 class QMacPasteboardMimeFileUri : public QMacPasteboardMime {
589 QMacPasteboardMimeFileUri() : QMacPasteboardMime(MIME_ALL) { }
590 QString convertorName();
592 QString flavorFor(const QString &mime);
593 QString mimeFor(QString flav);
594 bool canConvert(const QString &mime, QString flav);
595 QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav);
596 QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav);
599 QString QMacPasteboardMimeFileUri::convertorName()
601 return QLatin1String("FileURL");
604 QString QMacPasteboardMimeFileUri::flavorFor(const QString &mime)
606 if (mime == QLatin1String("text/uri-list"))
607 return QCFString(UTTypeCreatePreferredIdentifierForTag(kUTTagClassOSType, CFSTR("furl"), 0));
611 QString QMacPasteboardMimeFileUri::mimeFor(QString flav)
613 if (flav == QCFString(UTTypeCreatePreferredIdentifierForTag(kUTTagClassOSType, CFSTR("furl"), 0)))
614 return QLatin1String("text/uri-list");
618 bool QMacPasteboardMimeFileUri::canConvert(const QString &mime, QString flav)
620 return mime == QLatin1String("text/uri-list")
621 && flav == QCFString(UTTypeCreatePreferredIdentifierForTag(kUTTagClassOSType, CFSTR("furl"), 0));
624 QVariant QMacPasteboardMimeFileUri::convertToMime(const QString &mime, QList<QByteArray> data, QString flav)
626 if (!canConvert(mime, flav))
629 for (int i = 0; i < data.size(); ++i) {
630 QUrl url = QUrl::fromEncoded(data.at(i));
631 if (url.host().toLower() == QLatin1String("localhost"))
632 url.setHost(QString());
633 url.setPath(url.path().normalized(QString::NormalizationForm_C));
636 return QVariant(ret);
639 QList<QByteArray> QMacPasteboardMimeFileUri::convertFromMime(const QString &mime, QVariant data, QString flav)
641 QList<QByteArray> ret;
642 if (!canConvert(mime, flav))
644 QList<QVariant> urls = data.toList();
645 for (int i = 0; i < urls.size(); ++i) {
646 QUrl url = urls.at(i).toUrl();
647 if (url.scheme().isEmpty())
648 url.setScheme(QLatin1String("file"));
649 if (url.scheme().toLower() == QLatin1String("file")) {
650 if (url.host().isEmpty())
651 url.setHost(QLatin1String("localhost"));
652 url.setPath(url.path().normalized(QString::NormalizationForm_D));
654 ret.append(url.toEncoded());
659 class QMacPasteboardMimeUrl : public QMacPasteboardMime {
661 QMacPasteboardMimeUrl() : QMacPasteboardMime(MIME_ALL) { }
662 QString convertorName();
664 QString flavorFor(const QString &mime);
665 QString mimeFor(QString flav);
666 bool canConvert(const QString &mime, QString flav);
667 QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav);
668 QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav);
671 QString QMacPasteboardMimeUrl::convertorName()
673 return QLatin1String("URL");
676 QString QMacPasteboardMimeUrl::flavorFor(const QString &mime)
678 if (mime.startsWith(QLatin1String("text/uri-list")))
679 return QLatin1String("public.url");
683 QString QMacPasteboardMimeUrl::mimeFor(QString flav)
685 if (flav == QLatin1String("public.url"))
686 return QLatin1String("text/uri-list");
690 bool QMacPasteboardMimeUrl::canConvert(const QString &mime, QString flav)
692 return flav == QLatin1String("public.url")
693 && mime == QLatin1String("text/uri-list");
696 QVariant QMacPasteboardMimeUrl::convertToMime(const QString &mime, QList<QByteArray> data, QString flav)
698 if (!canConvert(mime, flav))
702 for (int i=0; i<data.size(); ++i) {
703 QUrl url = QUrl::fromEncoded(data.at(i));
704 if (url.host().toLower() == QLatin1String("localhost"))
705 url.setHost(QString());
706 url.setPath(url.path().normalized(QString::NormalizationForm_C));
709 return QVariant(ret);
712 QList<QByteArray> QMacPasteboardMimeUrl::convertFromMime(const QString &mime, QVariant data, QString flav)
714 QList<QByteArray> ret;
715 if (!canConvert(mime, flav))
718 QList<QVariant> urls = data.toList();
719 for (int i=0; i<urls.size(); ++i) {
720 QUrl url = urls.at(i).toUrl();
721 if (url.scheme().isEmpty())
722 url.setScheme(QLatin1String("file"));
723 if (url.scheme().toLower() == QLatin1String("file")) {
724 if (url.host().isEmpty())
725 url.setHost(QLatin1String("localhost"));
726 url.setPath(url.path().normalized(QString::NormalizationForm_D));
728 ret.append(url.toEncoded());
733 class QMacPasteboardMimeVCard : public QMacPasteboardMime
736 QMacPasteboardMimeVCard() : QMacPasteboardMime(MIME_ALL){ }
737 QString convertorName();
739 QString flavorFor(const QString &mime);
740 QString mimeFor(QString flav);
741 bool canConvert(const QString &mime, QString flav);
742 QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav);
743 QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav);
746 QString QMacPasteboardMimeVCard::convertorName()
748 return QString("VCard");
751 bool QMacPasteboardMimeVCard::canConvert(const QString &mime, QString flav)
753 return mimeFor(flav) == mime;
756 QString QMacPasteboardMimeVCard::flavorFor(const QString &mime)
758 if (mime.startsWith(QLatin1String("text/plain")))
759 return QLatin1String("public.vcard");
763 QString QMacPasteboardMimeVCard::mimeFor(QString flav)
765 if (flav == QLatin1String("public.vcard"))
766 return QLatin1String("text/plain");
770 QVariant QMacPasteboardMimeVCard::convertToMime(const QString &mime, QList<QByteArray> data, QString)
773 if (mime == QLatin1String("text/plain")) {
774 for (int i=0; i<data.size(); ++i)
777 return QVariant(cards);
780 QList<QByteArray> QMacPasteboardMimeVCard::convertFromMime(const QString &mime, QVariant data, QString)
782 QList<QByteArray> ret;
783 if (mime == QLatin1String("text/plain"))
784 ret.append(data.toString().toUtf8());
792 This is an internal function.
794 void QMacPasteboardMime::initialize()
796 if (globalMimeList()->isEmpty()) {
797 qAddPostRoutine(cleanup_mimes);
799 //standard types that we wrap
800 new QMacPasteboardMimeTiff;
801 new QMacPasteboardMimeUnicodeText;
802 new QMacPasteboardMimePlainText;
803 new QMacPasteboardMimeHTMLText;
804 new QMacPasteboardMimeFileUri;
805 new QMacPasteboardMimeUrl;
806 new QMacPasteboardMimeTypeName;
807 new QMacPasteboardMimeVCard;
808 //make sure our "non-standard" types are always last! --Sam
809 new QMacPasteboardMimeAny;
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.