diff options
author | Richard Moe Gustavsen <richard.gustavsen@qt.io> | 2017-03-31 11:42:28 +0200 |
---|---|---|
committer | Richard Moe Gustavsen <richard.gustavsen@qt.io> | 2017-04-18 10:18:54 +0000 |
commit | fb8ec15110046366cf926d1a3229d1790eecf230 (patch) | |
tree | ad159f956ff69fc8b0436d206c03198bcc2c45d7 | |
parent | 0a807c2ab69d06195d0ed7a6f1388990d6a784c5 (diff) |
darwin: add tiff support to clipboard for all darwin platforms
This will add copy/paste/dnd support for QPixmap and QImage
to all darwin platforms (and not just macOS, as it is today).
Task-number: QTBUG-57428
Change-Id: Iefc876c0a347077322f195b55c49f2c1c4b4a34b
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
-rw-r--r-- | src/platformsupport/clipboard/clipboard.pro | 1 | ||||
-rw-r--r-- | src/platformsupport/clipboard/qmacmime.mm | 100 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoamimetypes.mm | 92 |
3 files changed, 101 insertions, 92 deletions
diff --git a/src/platformsupport/clipboard/clipboard.pro b/src/platformsupport/clipboard/clipboard.pro index 336d81fe46..70ae7ebace 100644 --- a/src/platformsupport/clipboard/clipboard.pro +++ b/src/platformsupport/clipboard/clipboard.pro @@ -10,6 +10,7 @@ PRECOMPILED_HEADER = ../../corelib/global/qt_pch.h HEADERS += qmacmime_p.h SOURCES += qmacmime.mm +LIBS += -framework ImageIO macos: LIBS_PRIVATE += -framework AppKit load(qt_module) diff --git a/src/platformsupport/clipboard/qmacmime.mm b/src/platformsupport/clipboard/qmacmime.mm index 6a6e033bec..e3f539cfd7 100644 --- a/src/platformsupport/clipboard/qmacmime.mm +++ b/src/platformsupport/clipboard/qmacmime.mm @@ -37,10 +37,15 @@ ** ****************************************************************************/ +#include <ImageIO/ImageIO.h> + #include <QtCore/qsystemdetection.h> +#include <QtGui/qimage.h> #if defined(Q_OS_OSX) #import <AppKit/AppKit.h> +#else +#include <MobileCoreServices/MobileCoreServices.h> #endif #if defined(QT_PLATFORM_UIKIT) @@ -779,6 +784,100 @@ QList<QByteArray> QMacPasteboardMimeVCard::convertFromMime(const QString &mime, return ret; } +extern QImage qt_mac_toQImage(CGImageRef image); +extern CGImageRef qt_mac_toCGImage(const QImage &qImage); + +class QMacPasteboardMimeTiff : public QMacInternalPasteboardMime { +public: + QMacPasteboardMimeTiff() : QMacInternalPasteboardMime(MIME_ALL) { } + QString convertorName(); + + QString flavorFor(const QString &mime); + QString mimeFor(QString flav); + bool canConvert(const QString &mime, QString flav); + QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav); + QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav); +}; + +QString QMacPasteboardMimeTiff::convertorName() +{ + return QLatin1String("Tiff"); +} + +QString QMacPasteboardMimeTiff::flavorFor(const QString &mime) +{ + if (mime.startsWith(QLatin1String("application/x-qt-image"))) + return QLatin1String("public.tiff"); + return QString(); +} + +QString QMacPasteboardMimeTiff::mimeFor(QString flav) +{ + if (flav == QLatin1String("public.tiff")) + return QLatin1String("application/x-qt-image"); + return QString(); +} + +bool QMacPasteboardMimeTiff::canConvert(const QString &mime, QString flav) +{ + return flav == QLatin1String("public.tiff") && mime == QLatin1String("application/x-qt-image"); +} + +QVariant QMacPasteboardMimeTiff::convertToMime(const QString &mime, QList<QByteArray> data, QString flav) +{ + if (data.count() > 1) + qWarning("QMacPasteboardMimeTiff: Cannot handle multiple member data"); + QVariant ret; + if (!canConvert(mime, flav)) + return ret; + const QByteArray &a = data.first(); + QCFType<CGImageRef> image; + QCFType<CFDataRef> tiffData = CFDataCreateWithBytesNoCopy(0, + reinterpret_cast<const UInt8 *>(a.constData()), + a.size(), kCFAllocatorNull); + QCFType<CGImageSourceRef> imageSource = CGImageSourceCreateWithData(tiffData, 0); + image = CGImageSourceCreateImageAtIndex(imageSource, 0, 0); + if (image != 0) + ret = QVariant(qt_mac_toQImage(image)); + return ret; +} + +QList<QByteArray> QMacPasteboardMimeTiff::convertFromMime(const QString &mime, QVariant variant, QString flav) +{ + QList<QByteArray> ret; + if (!canConvert(mime, flav)) + return ret; + + QImage img = qvariant_cast<QImage>(variant); + QCFType<CGImageRef> cgimage = qt_mac_toCGImage(img); + + QCFType<CFMutableDataRef> data = CFDataCreateMutable(0, 0); + QCFType<CGImageDestinationRef> imageDestination = CGImageDestinationCreateWithData(data, kUTTypeTIFF, 1, 0); + if (imageDestination != 0) { + CFTypeRef keys[2]; + QCFType<CFTypeRef> values[2]; + QCFType<CFDictionaryRef> options; + keys[0] = kCGImagePropertyPixelWidth; + keys[1] = kCGImagePropertyPixelHeight; + int width = img.width(); + int height = img.height(); + values[0] = CFNumberCreate(0, kCFNumberIntType, &width); + values[1] = CFNumberCreate(0, kCFNumberIntType, &height); + options = CFDictionaryCreate(0, reinterpret_cast<const void **>(keys), + reinterpret_cast<const void **>(values), 2, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + CGImageDestinationAddImage(imageDestination, cgimage, options); + CGImageDestinationFinalize(imageDestination); + } + QByteArray ar(CFDataGetLength(data), 0); + CFDataGetBytes(data, + CFRangeMake(0, ar.size()), + reinterpret_cast<UInt8 *>(ar.data())); + ret.append(ar); + return ret; +} + /*! \internal @@ -792,6 +891,7 @@ void QMacInternalPasteboardMime::initializeMimeTypes() new QMacPasteboardMimeAny; //standard types that we wrap + new QMacPasteboardMimeTiff; new QMacPasteboardMimePlainTextFallback; new QMacPasteboardMimeUnicodeText; new QMacPasteboardMimeRtfText; diff --git a/src/plugins/platforms/cocoa/qcocoamimetypes.mm b/src/plugins/platforms/cocoa/qcocoamimetypes.mm index 093f86da6e..f7662a92a4 100644 --- a/src/plugins/platforms/cocoa/qcocoamimetypes.mm +++ b/src/plugins/platforms/cocoa/qcocoamimetypes.mm @@ -105,101 +105,9 @@ QList<QByteArray> QMacPasteboardMimeTraditionalMacPlainText::convertFromMime(con return ret; } -class QMacPasteboardMimeTiff : public QMacInternalPasteboardMime { -public: - QMacPasteboardMimeTiff() : QMacInternalPasteboardMime(MIME_ALL) { } - QString convertorName(); - - QString flavorFor(const QString &mime); - QString mimeFor(QString flav); - bool canConvert(const QString &mime, QString flav); - QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav); - QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav); -}; - -QString QMacPasteboardMimeTiff::convertorName() -{ - return QLatin1String("Tiff"); -} - -QString QMacPasteboardMimeTiff::flavorFor(const QString &mime) -{ - if (mime.startsWith(QLatin1String("application/x-qt-image"))) - return QLatin1String("public.tiff"); - return QString(); -} - -QString QMacPasteboardMimeTiff::mimeFor(QString flav) -{ - if (flav == QLatin1String("public.tiff")) - return QLatin1String("application/x-qt-image"); - return QString(); -} - -bool QMacPasteboardMimeTiff::canConvert(const QString &mime, QString flav) -{ - return flav == QLatin1String("public.tiff") && mime == QLatin1String("application/x-qt-image"); -} - -QVariant QMacPasteboardMimeTiff::convertToMime(const QString &mime, QList<QByteArray> data, QString flav) -{ - if (data.count() > 1) - qWarning("QMacPasteboardMimeTiff: Cannot handle multiple member data"); - QVariant ret; - if (!canConvert(mime, flav)) - return ret; - const QByteArray &a = data.first(); - QCFType<CGImageRef> image; - QCFType<CFDataRef> tiffData = CFDataCreateWithBytesNoCopy(0, - reinterpret_cast<const UInt8 *>(a.constData()), - a.size(), kCFAllocatorNull); - QCFType<CGImageSourceRef> imageSource = CGImageSourceCreateWithData(tiffData, 0); - image = CGImageSourceCreateImageAtIndex(imageSource, 0, 0); - if (image != 0) - ret = QVariant(qt_mac_toQImage(image)); - return ret; -} - -QList<QByteArray> QMacPasteboardMimeTiff::convertFromMime(const QString &mime, QVariant variant, QString flav) -{ - QList<QByteArray> ret; - if (!canConvert(mime, flav)) - return ret; - - QImage img = qvariant_cast<QImage>(variant); - QCFType<CGImageRef> cgimage = qt_mac_toCGImage(img); - - QCFType<CFMutableDataRef> data = CFDataCreateMutable(0, 0); - QCFType<CGImageDestinationRef> imageDestination = CGImageDestinationCreateWithData(data, kUTTypeTIFF, 1, 0); - if (imageDestination != 0) { - CFTypeRef keys[2]; - QCFType<CFTypeRef> values[2]; - QCFType<CFDictionaryRef> options; - keys[0] = kCGImagePropertyPixelWidth; - keys[1] = kCGImagePropertyPixelHeight; - int width = img.width(); - int height = img.height(); - values[0] = CFNumberCreate(0, kCFNumberIntType, &width); - values[1] = CFNumberCreate(0, kCFNumberIntType, &height); - options = CFDictionaryCreate(0, reinterpret_cast<const void **>(keys), - reinterpret_cast<const void **>(values), 2, - &kCFTypeDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks); - CGImageDestinationAddImage(imageDestination, cgimage, options); - CGImageDestinationFinalize(imageDestination); - } - QByteArray ar(CFDataGetLength(data), 0); - CFDataGetBytes(data, - CFRangeMake(0, ar.size()), - reinterpret_cast<UInt8 *>(ar.data())); - ret.append(ar); - return ret; -} - void QCocoaMimeTypes::initializeMimeTypes() { new QMacPasteboardMimeTraditionalMacPlainText; - new QMacPasteboardMimeTiff; } QT_END_NAMESPACE |