summaryrefslogtreecommitdiff
path: root/vcl/ios/DataFlavorMapping.cxx
diff options
context:
space:
mode:
authorTor Lillqvist <tml@collabora.com>2019-05-24 01:51:00 +0300
committerTor Lillqvist <tml@collabora.com>2019-05-28 12:39:09 +0300
commitb8c1f54d67c5ae90a868f9b33747c43b97c23351 (patch)
tree37ea8331c239d83d7c919a36a5262e6634ee7dbf /vcl/ios/DataFlavorMapping.cxx
parent1c7a2eff17f09feaa2709eaab60855f8e1aa7469 (diff)
tdf#124752: Add system clipboard interface for iOS
Based on the corresponding macOS code. Work in progress. The image support ifdeffed out still (because it uses some macOS specific APIs for which I couldn't right away find the equivalent iOS ones). I made it much simpler than the macOS code. I dropped the keeping of a local in-process clipboard completely. Firstly, as far as I see, the iOS clipboard API (UIPasteboard etc) does not even offer the possibility to separately offer some formats and actually provide the data on request. Secondly, we must be prepared anyway that the system can kill an iOS app at any stage while the user is using some other app, so we need to make sure everything that is copied goes onto the system clipboard right away anyway. I had to disable the copying of HTML to the clipboard as that lead to a mysterious assertion failure. See comment in DataFlavorMapper::openOfficeToSystemFlavor(). But RTF seems to work well, too. I assume RTF is what gets used for cross-application copy/paste (and cross-device, even, through Apple's Universal Clipboard thing, where you can copy/paste between your Macs and iOS devices on the same network). I am not sure how relevant the various application/x-openoffice-foo formats are. Change-Id: I174495e33d86fc3990996c229243c05d6cbfcda7
Diffstat (limited to 'vcl/ios/DataFlavorMapping.cxx')
-rw-r--r--vcl/ios/DataFlavorMapping.cxx703
1 files changed, 703 insertions, 0 deletions
diff --git a/vcl/ios/DataFlavorMapping.cxx b/vcl/ios/DataFlavorMapping.cxx
new file mode 100644
index 000000000000..b57209fd2621
--- /dev/null
+++ b/vcl/ios/DataFlavorMapping.cxx
@@ -0,0 +1,703 @@
+/* -*- Mode: ObjC; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include "DataFlavorMapping.hxx"
+#include "HtmlFmtFlt.hxx"
+#include <com/sun/star/datatransfer/UnsupportedFlavorException.hpp>
+#include <com/sun/star/datatransfer/XMimeContentType.hpp>
+#include <com/sun/star/datatransfer/MimeContentTypeFactory.hpp>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <comphelper/processfactory.hxx>
+
+#include <rtl/ustring.hxx>
+#include <sal/log.hxx>
+#include <osl/endian.h>
+
+#include <cassert>
+#include <cstring>
+
+#include <premac.h>
+#include <UIKit/UIKit.h>
+#include <MobileCoreServices/MobileCoreServices.h>
+#include <postmac.h>
+
+using namespace css::datatransfer;
+using namespace css::uno;
+using namespace css::lang;
+using namespace cppu;
+
+namespace
+{
+bool ImageToPNG(css::uno::Sequence<sal_Int8> const& rImgData,
+ css::uno::Sequence<sal_Int8>& rPngData)
+{
+#if 1
+ // Skip this complexity for now. Work in progress.
+ (void)rImgData;
+ (void)rPngData;
+ return false;
+#else
+ NSData* pData = [NSData dataWithBytesNoCopy:const_cast<sal_Int8*>(rImgData.getConstArray())
+ length:rImgData.getLength()
+ freeWhenDone:0];
+ if (!pData)
+ return false;
+
+ NSBitmapImageRep* pRep = [NSBitmapImageRep imageRepWithData:pData];
+ if (!pRep)
+ return false;
+
+ NSData* pOut = [pRep representationUsingType:NSPNGFileType properties:@{}];
+ if (!pOut)
+ return false;
+
+ const size_t nPngSize = [pOut length];
+ rPngData.realloc(nPngSize);
+ [pOut getBytes:rPngData.getArray() length:nPngSize];
+ return (nPngSize > 0);
+#endif
+}
+
+bool PNGToImage(css::uno::Sequence<sal_Int8> const& rPngData,
+ css::uno::Sequence<sal_Int8>& rImgData)
+{
+#if 1
+ (void)rPngData;
+ (void)rImgData;
+ return false;
+#else
+ NSData* pData = [NSData dataWithBytesNoCopy:const_cast<sal_Int8*>(rPngData.getConstArray())
+ length:rPngData.getLength()
+ freeWhenDone:0];
+ if (!pData)
+ return false;
+
+ NSBitmapImageRep* pRep = [NSBitmapImageRep imageRepWithData:pData];
+ if (!pRep)
+ return false;
+
+ NSData* pOut = [pRep representationUsingType:eOutFormat properties:@{}];
+ if (!pOut)
+ return false;
+
+ const size_t nImgSize = [pOut length];
+ rImgData.realloc(nImgSize);
+ [pOut getBytes:rImgData.getArray() length:nImgSize];
+ return (nImgSize > 0);
+#endif
+}
+
+/* Determine whether or not a DataFlavor is valid.
+ */
+bool isValidFlavor(const DataFlavor& aFlavor)
+{
+ size_t len = aFlavor.MimeType.getLength();
+ Type dtype = aFlavor.DataType;
+ return ((len > 0)
+ && ((dtype == cppu::UnoType<Sequence<sal_Int8>>::get())
+ || (dtype == cppu::UnoType<OUString>::get())));
+}
+
+OUString NSStringToOUString(const NSString* cfString)
+{
+ assert(cfString && "Invalid parameter");
+
+ const char* utf8Str = [cfString UTF8String];
+ unsigned int len = rtl_str_getLength(utf8Str);
+
+ return OUString(utf8Str, len, RTL_TEXTENCODING_UTF8);
+}
+
+NSString* OUStringToNSString(const OUString& ustring)
+{
+ OString utf8Str = OUStringToOString(ustring, RTL_TEXTENCODING_UTF8);
+ return [NSString stringWithCString:utf8Str.getStr() encoding:NSUTF8StringEncoding];
+}
+
+NSString* PBTYPE_PLAINTEXT = (__bridge NSString*)kUTTypePlainText;
+NSString* PBTYPE_RTF = (__bridge NSString*)kUTTypeRTF;
+NSString* PBTYPE_PNG = (__bridge NSString*)kUTTypePNG;
+NSString* PBTYPE_JPEG = (__bridge NSString*)kUTTypeJPEG;
+NSString* PBTYPE_HTML = (__bridge NSString*)kUTTypeHTML;
+NSString* PBTYPE_PDF = (__bridge NSString*)kUTTypePDF;
+NSString* PBTYPE_SESX
+ = @"application/x-openoffice-embed-source-xml;windows_formatname=\"Star Embed Source (XML)\"";
+NSString* PBTYPE_SLSDX = @"application/"
+ @"x-openoffice-linksrcdescriptor-xml;windows_formatname=\"Star Link "
+ @"Source Descriptor (XML)\"";
+NSString* PBTYPE_LSX
+ = @"application/x-openoffice-link-source-xml;windows_formatname=\"Star Link Source (XML)\"";
+NSString* PBTYPE_EOX = @"application/x-openoffice-embedded-obj-xml;windows_formatname=\"Star "
+ @"Embedded Object (XML)\"";
+NSString* PBTYPE_SVXB
+ = @"application/x-openoffice-svbx;windows_formatname=\"SVXB (StarView Bitmap/Animation)\"";
+NSString* PBTYPE_GDIMF = @"application/x-openoffice-gdimetafile;windows_formatname=\"GDIMetaFile\"";
+NSString* PBTYPE_SODX = @"application/x-openoffice-objectdescriptor-xml;windows_formatname=\"Star "
+ @"Object Descriptor (XML)\"";
+NSString* PBTYPE_DUMMY_INTERNAL = @"application/x-openoffice-internal";
+
+const char* FLAVOR_SESX
+ = "application/x-openoffice-embed-source-xml;windows_formatname=\"Star Embed Source (XML)\"";
+const char* FLAVOR_SLSDX = "application/"
+ "x-openoffice-linksrcdescriptor-xml;windows_formatname=\"Star Link "
+ "Source Descriptor (XML)\"";
+const char* FLAVOR_LSX
+ = "application/x-openoffice-link-source-xml;windows_formatname=\"Star Link Source (XML)\"";
+const char* FLAVOR_EOX
+ = "application/x-openoffice-embedded-obj-xml;windows_formatname=\"Star Embedded Object (XML)\"";
+const char* FLAVOR_SVXB
+ = "application/x-openoffice-svbx;windows_formatname=\"SVXB (StarView Bitmap/Animation)\"";
+const char* FLAVOR_GDIMF
+ = "application/x-openoffice-gdimetafile;windows_formatname=\"GDIMetaFile\"";
+const char* FLAVOR_SODX = "application/x-openoffice-objectdescriptor-xml;windows_formatname=\"Star "
+ "Object Descriptor (XML)\"";
+const char* FLAVOR_DUMMY_INTERNAL = "application/x-openoffice-internal";
+
+struct FlavorMap
+{
+ NSString* SystemFlavor;
+ const char* OOoFlavor;
+ const char* HumanPresentableName;
+ bool DataTypeOUString; // sequence<byte> otherwise
+};
+
+static const FlavorMap flavorMap[]
+ = { { PBTYPE_PLAINTEXT, "text/plain;charset=utf-16", "Unicode Text (UTF-16)", true },
+ { PBTYPE_RTF, "text/rtf", "Rich Text Format", false },
+ { PBTYPE_PNG, "image/png", "Portable Network Graphics", false },
+ { PBTYPE_JPEG, "image/jpeg", "Portable Network Graphics", false },
+ // Nope, sorry. See comment in openOfficeToSystemFlavor() below.
+ // { PBTYPE_HTML, "text/html", "Plain HTML", false },
+ { PBTYPE_PDF, "application/pdf", "PDF File", false },
+ { PBTYPE_SESX, FLAVOR_SESX, "Star Embed Source (XML)", false },
+ { PBTYPE_SLSDX, FLAVOR_SLSDX, "Star Link Source Descriptor (XML)", false },
+ { PBTYPE_LSX, FLAVOR_LSX, "Star Link Source (XML)", false },
+ { PBTYPE_EOX, FLAVOR_EOX, "Star Embedded Object (XML)", false },
+ { PBTYPE_SVXB, FLAVOR_SVXB, "SVXB (StarView Bitmap/Animation", false },
+ { PBTYPE_GDIMF, FLAVOR_GDIMF, "GDIMetaFile", false },
+ { PBTYPE_SODX, FLAVOR_SODX, "Star Object Descriptor (XML)", false },
+ { PBTYPE_DUMMY_INTERNAL, FLAVOR_DUMMY_INTERNAL, "internal data", false } };
+
+#define SIZE_FLAVOR_MAP (sizeof(flavorMap) / sizeof(FlavorMap))
+
+inline bool isByteSequenceType(const Type& theType)
+{
+ return (theType == cppu::UnoType<Sequence<sal_Int8>>::get());
+}
+
+inline bool isOUStringType(const Type& theType)
+{
+ return (theType == cppu::UnoType<OUString>::get());
+}
+
+} // unnamed namespace
+
+/* A base class for other data provider.
+ */
+class DataProviderBaseImpl : public DataProvider
+{
+public:
+ DataProviderBaseImpl(const Any& data);
+ DataProviderBaseImpl(id data);
+ virtual ~DataProviderBaseImpl() override;
+
+protected:
+ Any mData;
+ //NSData* mSystemData;
+ id mSystemData;
+};
+
+DataProviderBaseImpl::DataProviderBaseImpl(const Any& data)
+ : mData(data)
+ , mSystemData(nil)
+{
+}
+
+DataProviderBaseImpl::DataProviderBaseImpl(id data)
+ : mSystemData(data)
+{
+ [mSystemData retain];
+}
+
+DataProviderBaseImpl::~DataProviderBaseImpl()
+{
+ if (mSystemData)
+ {
+ [mSystemData release];
+ }
+}
+
+class UniDataProvider : public DataProviderBaseImpl
+{
+public:
+ UniDataProvider(const Any& data);
+ UniDataProvider(NSData* data);
+
+ NSData* getSystemData() override;
+ Any getOOoData() override;
+};
+
+UniDataProvider::UniDataProvider(const Any& data)
+ : DataProviderBaseImpl(data)
+{
+}
+
+UniDataProvider::UniDataProvider(NSData* data)
+ : DataProviderBaseImpl(data)
+{
+}
+
+NSData* UniDataProvider::getSystemData()
+{
+ OUString ustr;
+ mData >>= ustr;
+
+ OString strUtf8;
+ ustr.convertToString(&strUtf8, RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS);
+
+ return [NSData dataWithBytes:strUtf8.getStr() length:strUtf8.getLength()];
+}
+
+Any UniDataProvider::getOOoData()
+{
+ Any oOOData;
+
+ if (mSystemData)
+ {
+ oOOData <<= OUString(static_cast<const sal_Char*>([mSystemData bytes]),
+ [mSystemData length], RTL_TEXTENCODING_UTF8);
+ }
+ else
+ {
+ oOOData = mData;
+ }
+
+ return oOOData;
+}
+
+class ByteSequenceDataProvider : public DataProviderBaseImpl
+{
+public:
+ ByteSequenceDataProvider(const Any& data);
+ ByteSequenceDataProvider(NSData* data);
+
+ NSData* getSystemData() override;
+ Any getOOoData() override;
+};
+
+ByteSequenceDataProvider::ByteSequenceDataProvider(const Any& data)
+ : DataProviderBaseImpl(data)
+{
+}
+
+ByteSequenceDataProvider::ByteSequenceDataProvider(NSData* data)
+ : DataProviderBaseImpl(data)
+{
+}
+
+NSData* ByteSequenceDataProvider::getSystemData()
+{
+ Sequence<sal_Int8> rawData;
+ mData >>= rawData;
+
+ return [NSData dataWithBytes:rawData.getArray() length:rawData.getLength()];
+}
+
+Any ByteSequenceDataProvider::getOOoData()
+{
+ Any oOOData;
+
+ if (mSystemData)
+ {
+ unsigned int flavorDataLength = [mSystemData length];
+ Sequence<sal_Int8> byteSequence;
+ byteSequence.realloc(flavorDataLength);
+ memcpy(byteSequence.getArray(), [mSystemData bytes], flavorDataLength);
+ oOOData <<= byteSequence;
+ }
+ else
+ {
+ oOOData = mData;
+ }
+
+ return oOOData;
+}
+
+class HTMLFormatDataProvider : public DataProviderBaseImpl
+{
+public:
+ HTMLFormatDataProvider(NSData* data);
+
+ NSData* getSystemData() override;
+ Any getOOoData() override;
+};
+
+HTMLFormatDataProvider::HTMLFormatDataProvider(NSData* data)
+ : DataProviderBaseImpl(data)
+{
+}
+
+NSData* HTMLFormatDataProvider::getSystemData()
+{
+ Sequence<sal_Int8> textHtmlData;
+ mData >>= textHtmlData;
+
+ Sequence<sal_Int8> htmlFormatData = TextHtmlToHTMLFormat(textHtmlData);
+
+ return [NSData dataWithBytes:htmlFormatData.getArray() length:htmlFormatData.getLength()];
+}
+
+Any HTMLFormatDataProvider::getOOoData()
+{
+ Any oOOData;
+
+ if (mSystemData)
+ {
+ unsigned int flavorDataLength = [mSystemData length];
+ Sequence<sal_Int8> unkHtmlData;
+
+ unkHtmlData.realloc(flavorDataLength);
+ memcpy(unkHtmlData.getArray(), [mSystemData bytes], flavorDataLength);
+
+ Sequence<sal_Int8>* pPlainHtml = &unkHtmlData;
+ Sequence<sal_Int8> plainHtml;
+
+ if (isHTMLFormat(unkHtmlData))
+ {
+ plainHtml = HTMLFormatToTextHtml(unkHtmlData);
+ pPlainHtml = &plainHtml;
+ }
+
+ oOOData <<= *pPlainHtml;
+ }
+ else
+ {
+ oOOData = mData;
+ }
+
+ return oOOData;
+}
+
+class PNGDataProvider : public DataProviderBaseImpl
+{
+public:
+ PNGDataProvider(const Any&);
+ PNGDataProvider(NSData*);
+
+ NSData* getSystemData() override;
+ Any getOOoData() override;
+};
+
+PNGDataProvider::PNGDataProvider(const Any& data)
+ : DataProviderBaseImpl(data)
+{
+}
+
+PNGDataProvider::PNGDataProvider(NSData* data)
+ : DataProviderBaseImpl(data)
+{
+}
+
+NSData* PNGDataProvider::getSystemData()
+{
+ Sequence<sal_Int8> pngData;
+ mData >>= pngData;
+
+ Sequence<sal_Int8> imgData;
+ NSData* sysData = nullptr;
+ if (PNGToImage(pngData, imgData))
+ sysData = [NSData dataWithBytes:imgData.getArray() length:imgData.getLength()];
+
+ return sysData;
+}
+
+Any PNGDataProvider::getOOoData()
+{
+ Any oOOData;
+
+ if (mSystemData)
+ {
+ const unsigned int flavorDataLength = [mSystemData length];
+ Sequence<sal_Int8> imgData(flavorDataLength);
+ memcpy(imgData.getArray(), [mSystemData bytes], flavorDataLength);
+
+ Sequence<sal_Int8> pngData;
+ if (ImageToPNG(imgData, pngData))
+ oOOData <<= pngData;
+ }
+ else
+ {
+ oOOData = mData;
+ }
+
+ return oOOData;
+}
+
+DataFlavorMapper::DataFlavorMapper()
+{
+ Reference<XComponentContext> xContext = comphelper::getProcessComponentContext();
+ mrXMimeCntFactory = MimeContentTypeFactory::create(xContext);
+}
+
+DataFlavorMapper::~DataFlavorMapper()
+{
+ // release potential NSStrings
+ for (OfficeOnlyTypes::iterator it = maOfficeOnlyTypes.begin(); it != maOfficeOnlyTypes.end();
+ ++it)
+ {
+ [it->second release];
+ it->second = nil;
+ }
+}
+
+DataFlavor DataFlavorMapper::systemToOpenOfficeFlavor(const NSString* systemDataFlavor) const
+{
+ DataFlavor oOOFlavor;
+
+ for (size_t i = 0; i < SIZE_FLAVOR_MAP; i++)
+ {
+ if ([systemDataFlavor
+ caseInsensitiveCompare:const_cast<NSString*>(flavorMap[i].SystemFlavor)]
+ == NSOrderedSame)
+ {
+ oOOFlavor.MimeType = OUString::createFromAscii(flavorMap[i].OOoFlavor);
+ oOOFlavor.HumanPresentableName
+ = OUString::createFromAscii(flavorMap[i].HumanPresentableName);
+ oOOFlavor.DataType = flavorMap[i].DataTypeOUString
+ ? cppu::UnoType<OUString>::get()
+ : cppu::UnoType<Sequence<sal_Int8>>::get();
+ return oOOFlavor;
+ }
+ } // for
+
+ // look if this might be an internal type; if it comes in here it must have
+ // been through openOfficeToSystemFlavor before, so it should then be in the map
+ OUString aTryFlavor(NSStringToOUString(systemDataFlavor));
+ if (maOfficeOnlyTypes.find(aTryFlavor) != maOfficeOnlyTypes.end())
+ {
+ oOOFlavor.MimeType = aTryFlavor;
+ oOOFlavor.HumanPresentableName.clear();
+ oOOFlavor.DataType = cppu::UnoType<Sequence<sal_Int8>>::get();
+ }
+
+ return oOOFlavor;
+}
+
+NSString* DataFlavorMapper::openOfficeToSystemFlavor(const DataFlavor& oOOFlavor,
+ bool& rbInternal) const
+{
+ NSString* sysFlavor = nullptr;
+ rbInternal = false;
+
+ for (size_t i = 0; i < SIZE_FLAVOR_MAP; ++i)
+ {
+ if (oOOFlavor.MimeType.startsWith(OUString::createFromAscii(flavorMap[i].OOoFlavor)))
+ {
+ sysFlavor = flavorMap[i].SystemFlavor;
+ }
+ }
+
+ if (!sysFlavor)
+ {
+ // For some reason, if we allow text/html, we get an OSL_ENSURE failure in xmloff that
+ // apparently is a symptom of something being seriously wrong:
+ // xmloff/source/transform/OOo2Oasis.cxx:1925: duplicate doc handler
+ // Because is then followed a bit later by an assertion failure:
+ // Assertion failed: (!m_pFirst && !m_pLast && "There are still indices registered"), function ~SwIndexReg, file [...]/sw/source/core/bastyp/index.cxx, line 226
+
+ if (oOOFlavor.MimeType == "text/html")
+ return nil;
+
+ rbInternal = true;
+ OfficeOnlyTypes::const_iterator it = maOfficeOnlyTypes.find(oOOFlavor.MimeType);
+
+ if (it == maOfficeOnlyTypes.end())
+ sysFlavor = maOfficeOnlyTypes[oOOFlavor.MimeType]
+ = OUStringToNSString(oOOFlavor.MimeType);
+ else
+ sysFlavor = it->second;
+ }
+
+ return sysFlavor;
+}
+
+NSString* DataFlavorMapper::openOfficeImageToSystemFlavor(UIPasteboard* pPasteboard)
+{
+ if ([pPasteboard containsPasteboardTypes:@[ PBTYPE_PNG ]])
+ return PBTYPE_PNG;
+ else if ([pPasteboard containsPasteboardTypes:@[ PBTYPE_JPEG ]])
+ return PBTYPE_JPEG;
+ else if ([pPasteboard containsPasteboardTypes:@[ PBTYPE_PDF ]])
+ return PBTYPE_PDF;
+ return @"";
+}
+
+DataProviderPtr_t
+DataFlavorMapper::getDataProvider(const NSString* systemFlavor,
+ Reference<XTransferable> const& rTransferable) const
+{
+ DataProviderPtr_t dp;
+
+ try
+ {
+ DataFlavor oOOFlavor = systemToOpenOfficeFlavor(systemFlavor);
+
+ Any data = rTransferable->getTransferData(oOOFlavor);
+
+ if (isByteSequenceType(data.getValueType()))
+ {
+ if ([systemFlavor caseInsensitiveCompare:PBTYPE_PNG] == NSOrderedSame)
+ {
+ dp = DataProviderPtr_t(new PNGDataProvider(data));
+ }
+ else
+ {
+ dp = DataProviderPtr_t(new ByteSequenceDataProvider(data));
+ }
+ }
+ else // Must be OUString type
+ {
+ SAL_WARN_IF(!isOUStringType(data.getValueType()), "vcl", "must be OUString type");
+ dp = DataProviderPtr_t(new UniDataProvider(data));
+ }
+ }
+ catch (UnsupportedFlavorException&)
+ {
+ // Somebody violates the contract of the clipboard
+ // interface @see XTransferable
+ }
+
+ return dp;
+}
+
+DataProviderPtr_t DataFlavorMapper::getDataProvider(const NSString* systemFlavor,
+ NSData* systemData)
+{
+ DataProviderPtr_t dp;
+
+ if ([systemFlavor caseInsensitiveCompare:PBTYPE_PLAINTEXT] == NSOrderedSame)
+ {
+ dp = DataProviderPtr_t(new UniDataProvider(systemData));
+ }
+ else if ([systemFlavor caseInsensitiveCompare:PBTYPE_HTML] == NSOrderedSame)
+ {
+ dp = DataProviderPtr_t(new HTMLFormatDataProvider(systemData));
+ }
+ else if ([systemFlavor caseInsensitiveCompare:PBTYPE_PNG] == NSOrderedSame)
+ {
+ dp = DataProviderPtr_t(new PNGDataProvider(systemData));
+ }
+ else
+ {
+ dp = DataProviderPtr_t(new ByteSequenceDataProvider(systemData));
+ }
+
+ return dp;
+}
+
+bool DataFlavorMapper::isValidMimeContentType(const OUString& contentType) const
+{
+ bool result = true;
+
+ try
+ {
+ Reference<XMimeContentType> xCntType(mrXMimeCntFactory->createMimeContentType(contentType));
+ }
+ catch (IllegalArgumentException&)
+ {
+ result = false;
+ }
+
+ return result;
+}
+
+NSArray* DataFlavorMapper::flavorSequenceToTypesArray(
+ const css::uno::Sequence<css::datatransfer::DataFlavor>& flavors) const
+{
+ const sal_uInt32 nFlavors = flavors.getLength();
+ NSMutableArray* array = [[NSMutableArray alloc] initWithCapacity:1];
+
+ bool bNeedDummyInternalFlavor(false);
+
+ for (sal_uInt32 i = 0; i < nFlavors; i++)
+ {
+ if (flavors[i].MimeType.startsWith("image/bmp"))
+ {
+ [array addObject:PBTYPE_PNG];
+ }
+ else
+ {
+ const NSString* str = openOfficeToSystemFlavor(flavors[i], bNeedDummyInternalFlavor);
+
+ if (str != nil)
+ {
+ [str retain];
+ [array addObject:str];
+ }
+ }
+ }
+
+ // #i89462# #i90747#
+ // in case no system flavor was found to report
+ // report at least one so D&D between OOo targets works
+ if ([array count] == 0 || bNeedDummyInternalFlavor)
+ {
+ [array addObject:PBTYPE_DUMMY_INTERNAL];
+ }
+
+ return [array autorelease];
+}
+
+css::uno::Sequence<css::datatransfer::DataFlavor>
+DataFlavorMapper::typesArrayToFlavorSequence(NSArray* types) const
+{
+ int nFormats = [types count];
+ Sequence<DataFlavor> flavors;
+
+ for (int i = 0; i < nFormats; i++)
+ {
+ NSString* sysFormat = [types objectAtIndex:i];
+ DataFlavor oOOFlavor = systemToOpenOfficeFlavor(sysFormat);
+
+ if (isValidFlavor(oOOFlavor))
+ {
+ flavors.realloc(flavors.getLength() + 1);
+ flavors[flavors.getLength() - 1] = oOOFlavor;
+ }
+ }
+
+ return flavors;
+}
+
+NSArray* DataFlavorMapper::getAllSupportedPboardTypes()
+{
+ NSMutableArray* array = [[NSMutableArray alloc] initWithCapacity:SIZE_FLAVOR_MAP];
+
+ for (sal_uInt32 i = 0; i < SIZE_FLAVOR_MAP; i++)
+ {
+ [array addObject:flavorMap[i].SystemFlavor];
+ }
+
+ return [array autorelease];
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */