update dev300-m57
[ooovba.git] / dtrans / source / aqua / DataFlavorMapping.cxx
blobb33d497bb6764dcf913c59c17f62567214161a26
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: DataFlavorMapping.cxx,v $
10 * $Revision: 1.6 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #include <DataFlavorMapping.hxx>
32 #include "HtmlFmtFlt.hxx"
33 #include "PictToBmpFlt.hxx"
34 #include <com/sun/star/datatransfer/UnsupportedFlavorException.hpp>
35 #include <com/sun/star/datatransfer/XMimeContentType.hpp>
36 #include "com/sun/star/uno/Sequence.hxx"
38 #include <rtl/ustring.hxx>
39 #include <rtl/memory.h>
40 #include <osl/endian.h>
42 #include <vector>
43 #include <stdio.h>
45 #include <premac.h>
46 #include <QuickTime/QuickTime.h>
47 #include <postmac.h>
49 using namespace ::com::sun::star::datatransfer;
50 using namespace rtl;
51 using namespace ::com::sun::star::uno;
52 using namespace com::sun::star::lang;
53 using namespace cppu;
54 using namespace std;
56 namespace // private
58 const Type CPPUTYPE_SEQINT8 = getCppuType((Sequence<sal_Int8>*)0);
59 const Type CPPUTYPE_OUSTRING = getCppuType( (OUString*)0 );
61 /* Determine whether or not a DataFlavor is valid.
63 bool isValidFlavor(const DataFlavor& aFlavor)
65 size_t len = aFlavor.MimeType.getLength();
66 Type dtype = aFlavor.DataType;
67 return ((len > 0) && ((dtype == CPPUTYPE_SEQINT8) || (dtype == CPPUTYPE_OUSTRING)));
70 typedef vector<sal_Unicode> UnicodeBuffer;
72 OUString NSStringToOUString(NSString* cfString)
74 BOOST_ASSERT(cfString && "Invalid parameter");
76 const char* utf8Str = [cfString UTF8String];
77 unsigned int len = rtl_str_getLength(utf8Str);
79 return OUString(utf8Str, len, RTL_TEXTENCODING_UTF8);
82 NSString* OUStringToNSString(const OUString& ustring)
84 OString utf8Str = OUStringToOString(ustring, RTL_TEXTENCODING_UTF8);
85 return [NSString stringWithCString: utf8Str.getStr() encoding: NSUTF8StringEncoding];
89 const NSString* PBTYPE_UT16 = @"CorePasteboardFlavorType 0x75743136";
90 const NSString* PBTYPE_PICT = @"CorePasteboardFlavorType 0x50494354";
91 const NSString* PBTYPE_HTML = @"CorePasteboardFlavorType 0x48544D4C";
92 const NSString* PBTYPE_SODX = @"application/x-openoffice-objectdescriptor-xml;windows_formatname=\"Star Object Descriptor (XML)\"";
93 const NSString* PBTYPE_SESX = @"application/x-openoffice-embed-source-xml;windows_formatname=\"Star Embed Source (XML)\"";
94 const NSString* PBTYPE_SLSDX = @"application/x-openoffice-linksrcdescriptor-xml;windows_formatname=\"Star Link Source Descriptor (XML)\"";
95 const NSString* PBTYPE_ESX = @"application/x-openoffice-embed-source-xml;windows_formatname=\"Star Embed Source (XML)\"";
96 const NSString* PBTYPE_LSX = @"application/x-openoffice-link-source-xml;windows_formatname=\"Star Link Source (XML)\"";
97 const NSString* PBTYPE_EOX = @"application/x-openoffice-embedded-obj-xml;windows_formatname=\"Star Embedded Object (XML)\"";
98 const NSString* PBTYPE_SVXB = @"application/x-openoffice-svbx;windows_formatname=\"SVXB (StarView Bitmap/Animation)\"";
99 const NSString* PBTYPE_GDIMF = @"application/x-openoffice-gdimetafile;windows_formatname=\"GDIMetaFile\"";
100 const NSString* PBTYPE_WMF = @"application/x-openoffice-wmf;windows_formatname=\"Image WMF\"";
101 const NSString* PBTYPE_EMF = @"application/x-openoffice-emf;windows_formatname=\"Image EMF\"";
103 const NSString* PBTYPE_DUMMY_INTERNAL = @"application/x-openoffice-internal";
105 const char* FLAVOR_SODX = "application/x-openoffice-objectdescriptor-xml;windows_formatname=\"Star Object Descriptor (XML)\"";
106 const char* FLAVOR_SESX = "application/x-openoffice-embed-source-xml;windows_formatname=\"Star Embed Source (XML)\"";
107 const char* FLAVOR_SLSDX = "application/x-openoffice-linksrcdescriptor-xml;windows_formatname=\"Star Link Source Descriptor (XML)\"";
108 const char* FLAVOR_ESX = "application/x-openoffice-embed-source-xml;windows_formatname=\"Star Embed Source (XML)\"";
109 const char* FLAVOR_LSX = "application/x-openoffice-link-source-xml;windows_formatname=\"Star Link Source (XML)\"";
110 const char* FLAVOR_EOX = "application/x-openoffice-embedded-obj-xml;windows_formatname=\"Star Embedded Object (XML)\"";
111 const char* FLAVOR_SVXB = "application/x-openoffice-svbx;windows_formatname=\"SVXB (StarView Bitmap/Animation)\"";
112 const char* FLAVOR_GDIMF = "application/x-openoffice-gdimetafile;windows_formatname=\"GDIMetaFile\"";
113 const char* FLAVOR_WMF = "application/x-openoffice-wmf;windows_formatname=\"Image WMF\"";
114 const char* FLAVOR_EMF = "application/x-openoffice-emf;windows_formatname=\"Image EMF\"";
116 const char* FLAVOR_DUMMY_INTERNAL = "application/x-openoffice-internal";
119 struct FlavorMap
121 NSString* SystemFlavor;
122 const char* OOoFlavor;
123 const char* HumanPresentableName;
124 Type DataType;
127 /* At the moment it appears as if only MS Office pastes "public.html" to the clipboard.
129 FlavorMap flavorMap[] =
131 { NSStringPboardType, "text/plain;charset=utf-16", "Unicode Text (UTF-16)", CPPUTYPE_OUSTRING },
132 { NSRTFPboardType, "text/richtext", "Rich Text Format", CPPUTYPE_SEQINT8 },
133 { NSPICTPboardType, "image/bmp", "Windows Bitmap", CPPUTYPE_SEQINT8 },
134 { NSHTMLPboardType, "text/html", "Plain Html", CPPUTYPE_SEQINT8 },
135 { NSFilenamesPboardType, "application/x-openoffice-filelist;windows_formatname=\"FileList\"", "FileList", CPPUTYPE_SEQINT8 },
136 { PBTYPE_SESX, FLAVOR_SESX, "Star Embed Source (XML)", CPPUTYPE_SEQINT8 },
137 { PBTYPE_SLSDX, FLAVOR_SLSDX, "Star Link Source Descriptor (XML)", CPPUTYPE_SEQINT8 },
138 { PBTYPE_ESX, FLAVOR_ESX, "Star Embed Source (XML)", CPPUTYPE_SEQINT8 },
139 { PBTYPE_LSX, FLAVOR_LSX, "Star Link Source (XML)", CPPUTYPE_SEQINT8 },
140 { PBTYPE_EOX, FLAVOR_EOX, "Star Embedded Object (XML)", CPPUTYPE_SEQINT8 },
141 { PBTYPE_SVXB, FLAVOR_SVXB, "SVXB (StarView Bitmap/Animation", CPPUTYPE_SEQINT8 },
142 { PBTYPE_GDIMF, FLAVOR_GDIMF, "GDIMetaFile", CPPUTYPE_SEQINT8 },
143 { PBTYPE_WMF, FLAVOR_WMF, "Windows MetaFile", CPPUTYPE_SEQINT8 },
144 { PBTYPE_EMF, FLAVOR_EMF, "Windows Enhanced MetaFile", CPPUTYPE_SEQINT8 },
145 { PBTYPE_SODX, FLAVOR_SODX, "Star Object Descriptor (XML)", CPPUTYPE_SEQINT8 },
146 { PBTYPE_DUMMY_INTERNAL, FLAVOR_DUMMY_INTERNAL, "internal data",CPPUTYPE_SEQINT8 }
147 // { PBTYPE_UT16, "text/plain;charset=utf-16", "Unicode Text (UTF-16)", CPPUTYPE_OUSTRING }
148 // { kUTTypePICT, @"PICT", "image/x-macpict;windows_formatname=\"Mac Pict\"", "Mac Pict", CPPUTYPE_SEQINT8 }
149 // { kUTTypeHTML, @"HTML", "text/html", "Plain Html", CPPUTYPE_SEQINT8 }
153 #define SIZE_FLAVOR_MAP (sizeof(flavorMap)/sizeof(FlavorMap))
156 inline bool isByteSequenceType(const Type& theType)
158 return (theType == CPPUTYPE_SEQINT8);
161 inline bool isOUStringType(const Type& theType)
163 return (theType == CPPUTYPE_OUSTRING);
166 } // namespace private
169 //###########################
171 /* A base class for other data provider.
173 class DataProviderBaseImpl : public DataProvider
175 public:
176 DataProviderBaseImpl(const Any& data);
177 DataProviderBaseImpl(id data);
178 virtual ~DataProviderBaseImpl();
180 protected:
181 Any mData;
182 //NSData* mSystemData;
183 id mSystemData;
186 DataProviderBaseImpl::DataProviderBaseImpl(const Any& data) :
187 mData(data),
188 mSystemData(nil)
192 DataProviderBaseImpl::DataProviderBaseImpl(id data) :
193 mSystemData(data)
195 [mSystemData retain];
199 DataProviderBaseImpl::~DataProviderBaseImpl()
201 if (mSystemData)
203 [mSystemData release];
207 //#################################
209 class UniDataProvider : public DataProviderBaseImpl
211 public:
212 UniDataProvider(const Any& data);
214 UniDataProvider(NSData* data);
216 virtual NSData* getSystemData();
218 virtual Any getOOoData();
221 UniDataProvider::UniDataProvider(const Any& data) :
222 DataProviderBaseImpl(data)
226 UniDataProvider::UniDataProvider(NSData* data) :
227 DataProviderBaseImpl(data)
231 NSData* UniDataProvider::getSystemData()
233 OUString ustr;
234 mData >>= ustr;
236 OString strUtf8;
237 ustr.convertToString(&strUtf8, RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS);
239 return [NSData dataWithBytes: strUtf8.getStr() length: strUtf8.getLength()];
242 Any UniDataProvider::getOOoData()
244 Any oOOData;
246 if (mSystemData)
248 oOOData = makeAny(OUString(reinterpret_cast<const sal_Char*>([mSystemData bytes]),
249 [mSystemData length],
250 RTL_TEXTENCODING_UTF8));
252 else
254 oOOData = mData;
257 return oOOData;
260 //###########################
262 class ByteSequenceDataProvider : public DataProviderBaseImpl
264 public:
265 ByteSequenceDataProvider(const Any& data);
267 ByteSequenceDataProvider(NSData* data);
269 virtual NSData* getSystemData();
271 virtual Any getOOoData();
274 ByteSequenceDataProvider::ByteSequenceDataProvider(const Any& data) :
275 DataProviderBaseImpl(data)
279 ByteSequenceDataProvider::ByteSequenceDataProvider(NSData* data) :
280 DataProviderBaseImpl(data)
285 NSData* ByteSequenceDataProvider::getSystemData()
287 Sequence<sal_Int8> rawData;
288 mData >>= rawData;
290 return [NSData dataWithBytes: rawData.getArray() length: rawData.getLength()];
293 Any ByteSequenceDataProvider::getOOoData()
295 Any oOOData;
297 if (mSystemData)
299 unsigned int flavorDataLength = [mSystemData length];
300 Sequence<sal_Int8> byteSequence;
301 byteSequence.realloc(flavorDataLength);
302 memcpy(byteSequence.getArray(), [mSystemData bytes], flavorDataLength);
303 oOOData = makeAny(byteSequence);
305 else
307 oOOData = mData;
310 return oOOData;
314 //###########################
316 class HTMLFormatDataProvider : public DataProviderBaseImpl
318 public:
319 HTMLFormatDataProvider(const Any& data);
321 HTMLFormatDataProvider(NSData* data);
323 virtual NSData* getSystemData();
325 virtual Any getOOoData();
328 HTMLFormatDataProvider::HTMLFormatDataProvider(const Any& data) :
329 DataProviderBaseImpl(data)
333 HTMLFormatDataProvider::HTMLFormatDataProvider(NSData* data) :
334 DataProviderBaseImpl(data)
338 NSData* HTMLFormatDataProvider::getSystemData()
340 Sequence<sal_Int8> textHtmlData;
341 mData >>= textHtmlData;
343 Sequence<sal_Int8> htmlFormatData = TextHtmlToHTMLFormat(textHtmlData);
345 return [NSData dataWithBytes: htmlFormatData.getArray() length: htmlFormatData.getLength()];
348 Any HTMLFormatDataProvider::getOOoData()
350 Any oOOData;
352 if (mSystemData)
354 unsigned int flavorDataLength = [mSystemData length];
355 Sequence<sal_Int8> unkHtmlData;
357 unkHtmlData.realloc(flavorDataLength);
358 memcpy(unkHtmlData.getArray(), [mSystemData bytes], flavorDataLength);
360 Sequence<sal_Int8>* pPlainHtml = &unkHtmlData;
361 Sequence<sal_Int8> plainHtml;
363 if (isHTMLFormat(unkHtmlData))
365 plainHtml = HTMLFormatToTextHtml(unkHtmlData);
366 pPlainHtml = &plainHtml;
369 oOOData = makeAny(*pPlainHtml);
371 else
373 oOOData = mData;
376 return oOOData;
379 //###########################
381 class BMPDataProvider : public DataProviderBaseImpl
383 public:
384 BMPDataProvider(const Any& data);
386 BMPDataProvider(NSData* data);
388 virtual NSData* getSystemData();
390 virtual Any getOOoData();
393 BMPDataProvider::BMPDataProvider(const Any& data) :
394 DataProviderBaseImpl(data)
398 BMPDataProvider::BMPDataProvider(NSData* data) :
399 DataProviderBaseImpl(data)
403 NSData* BMPDataProvider::getSystemData()
405 Sequence<sal_Int8> bmpData;
406 mData >>= bmpData;
408 Sequence<sal_Int8> pictData;
409 NSData* sysData = NULL;
411 if (BMPtoPICT(bmpData, pictData))
413 sysData = [NSData dataWithBytes: pictData.getArray() length: pictData.getLength()];
416 return sysData;
419 /* At the moment the OOo 'PCT' filter is not good enough to be used
420 and there is no flavor defined for exchanging 'PCT' with OOo so
421 we will at the moment convert 'PCT' to a Windows BMP and provide
422 this to OOo
424 Any BMPDataProvider::getOOoData()
426 Any oOOData;
428 if (mSystemData)
430 unsigned int flavorDataLength = [mSystemData length];
431 Sequence<sal_Int8> pictData(flavorDataLength);
433 memcpy(pictData.getArray(), [mSystemData bytes], flavorDataLength);
435 Sequence<sal_Int8> bmpData;
437 if (PICTtoBMP(pictData, bmpData))
439 oOOData = makeAny(bmpData);
442 else
444 oOOData = mData;
447 return oOOData;
450 //######################
452 class FileListDataProvider : public DataProviderBaseImpl
454 public:
455 FileListDataProvider(const Any& data);
456 FileListDataProvider(NSArray* data);
458 virtual NSData* getSystemData();
459 virtual Any getOOoData();
462 FileListDataProvider::FileListDataProvider(const Any& data) :
463 DataProviderBaseImpl(data)
467 FileListDataProvider::FileListDataProvider(NSArray* data) :
468 DataProviderBaseImpl(data)
472 NSData* FileListDataProvider::getSystemData()
474 return [NSData data];
477 Any FileListDataProvider::getOOoData()
479 Any oOOData;
481 if (mSystemData)
483 size_t length = [mSystemData count];
484 size_t lenSeqRequired = 0;
486 for (size_t i = 0; i < length; i++)
488 NSString* fname = [mSystemData objectAtIndex: i];
489 lenSeqRequired += [fname maximumLengthOfBytesUsingEncoding: NSUnicodeStringEncoding] + sizeof(unichar);
492 Sequence<sal_Int8> oOOFileList(lenSeqRequired);
493 unichar* pBuffer = reinterpret_cast<unichar*>(oOOFileList.getArray());
494 rtl_zeroMemory(pBuffer, lenSeqRequired);
496 for (size_t i = 0; i < length; i++)
498 NSString* fname = [mSystemData objectAtIndex: i];
499 [fname getCharacters: pBuffer];
500 size_t l = [fname length];
501 pBuffer += l + 1;
504 oOOData = makeAny(oOOFileList);
506 else
508 oOOData = mData;
511 return oOOData;
514 //###########################
516 DataFlavorMapper::DataFlavorMapper(const Reference<XComponentContext>& context) :
517 mXComponentContext(context)
519 Reference<XMultiComponentFactory> mrServiceManager = mXComponentContext->getServiceManager();
520 mrXMimeCntFactory = Reference<XMimeContentTypeFactory>(mrServiceManager->createInstanceWithContext(
521 OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.datatransfer.MimeContentTypeFactory")), mXComponentContext), UNO_QUERY);
523 if (!mrXMimeCntFactory.is())
524 throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM("AquaClipboard: Cannot create com.sun.star.datatransfer.MimeContentTypeFactory")), NULL);
527 DataFlavor DataFlavorMapper::systemToOpenOfficeFlavor(NSString* systemDataFlavor) const
529 DataFlavor oOOFlavor;
531 for (size_t i = 0; i < SIZE_FLAVOR_MAP; i++)
533 if ([systemDataFlavor caseInsensitiveCompare: flavorMap[i].SystemFlavor] == NSOrderedSame)
535 oOOFlavor.MimeType = OUString::createFromAscii(flavorMap[i].OOoFlavor);
536 oOOFlavor.HumanPresentableName = OUString(RTL_CONSTASCII_USTRINGPARAM(flavorMap[i].HumanPresentableName));
537 oOOFlavor.DataType = flavorMap[i].DataType;
538 return oOOFlavor;
540 } // for
542 return oOOFlavor;
545 NSString* DataFlavorMapper::openOfficeToSystemFlavor(const DataFlavor& oOOFlavor) const
547 NSString* sysFlavor = NULL;
549 for (size_t i = 0; i < SIZE_FLAVOR_MAP; i++)
551 if (oOOFlavor.MimeType.compareToAscii(flavorMap[i].OOoFlavor, strlen(flavorMap[i].OOoFlavor)) == 0)
553 sysFlavor = flavorMap[i].SystemFlavor;
557 return sysFlavor;
560 DataProviderPtr_t DataFlavorMapper::getDataProvider(NSString* systemFlavor, Reference<XTransferable> rTransferable) const
562 DataProviderPtr_t dp;
566 DataFlavor oOOFlavor = systemToOpenOfficeFlavor(systemFlavor);
568 Any data = rTransferable->getTransferData(oOOFlavor);
570 if (isByteSequenceType(data.getValueType()))
572 if ([systemFlavor caseInsensitiveCompare: NSHTMLPboardType] == NSOrderedSame)
574 dp = DataProviderPtr_t(new HTMLFormatDataProvider(data));
576 else if ([systemFlavor caseInsensitiveCompare: NSPICTPboardType] == NSOrderedSame)
578 dp = DataProviderPtr_t(new BMPDataProvider(data));
580 else if ([systemFlavor caseInsensitiveCompare: NSFilenamesPboardType] == NSOrderedSame)
582 dp = DataProviderPtr_t(new FileListDataProvider(data));
584 else
586 dp = DataProviderPtr_t(new ByteSequenceDataProvider(data));
589 else // Must be OUString type
591 BOOST_ASSERT(isOUStringType(data.getValueType()));
592 dp = DataProviderPtr_t(new UniDataProvider(data));
595 catch(UnsupportedFlavorException&)
597 // Somebody violates the contract of the clipboard
598 // interface @see XTransferable
601 return dp;
604 DataProviderPtr_t DataFlavorMapper::getDataProvider(const NSString* systemFlavor, NSArray* systemData) const
606 return DataProviderPtr_t(new FileListDataProvider(systemData));
609 DataProviderPtr_t DataFlavorMapper::getDataProvider(const NSString* systemFlavor, NSData* systemData) const
611 DataProviderPtr_t dp;
613 if ([systemFlavor caseInsensitiveCompare: NSStringPboardType] == NSOrderedSame)
615 dp = DataProviderPtr_t(new UniDataProvider(systemData));
617 else if ([systemFlavor caseInsensitiveCompare: NSHTMLPboardType] == NSOrderedSame)
619 dp = DataProviderPtr_t(new HTMLFormatDataProvider(systemData));
621 else if ([systemFlavor caseInsensitiveCompare: NSPICTPboardType] == NSOrderedSame)
623 dp = DataProviderPtr_t(new BMPDataProvider(systemData));
625 else if ([systemFlavor caseInsensitiveCompare: NSFilenamesPboardType] == NSOrderedSame)
627 //dp = DataProviderPtr_t(new FileListDataProvider(systemData));
629 else
631 dp = DataProviderPtr_t(new ByteSequenceDataProvider(systemData));
634 return dp;
637 bool DataFlavorMapper::isValidMimeContentType(const rtl::OUString& contentType) const
639 bool result = true;
643 Reference<XMimeContentType> xCntType(mrXMimeCntFactory->createMimeContentType(contentType));
645 catch( IllegalArgumentException& )
647 result = false;
650 return result;
653 NSArray* DataFlavorMapper::flavorSequenceToTypesArray(const com::sun::star::uno::Sequence<com::sun::star::datatransfer::DataFlavor>& flavors) const
655 sal_uInt32 nFlavors = flavors.getLength();
656 NSMutableArray* array = [[NSMutableArray alloc] initWithCapacity: 1];
658 for (sal_uInt32 i = 0; i < nFlavors; i++)
660 NSString* str = openOfficeToSystemFlavor(flavors[i]);
662 if (str != NULL)
664 [array addObject: str];
668 // #i89462# #i90747#
669 // in case no system flavor was found to report
670 // report at least one so D&D between OOo targets works
671 if( [array count] == 0 )
673 [array addObject: PBTYPE_DUMMY_INTERNAL];
676 return [array autorelease];
679 com::sun::star::uno::Sequence<com::sun::star::datatransfer::DataFlavor> DataFlavorMapper::typesArrayToFlavorSequence(NSArray* types) const
681 int nFormats = [types count];
682 Sequence<DataFlavor> flavors;
684 for (int i = 0; i < nFormats; i++)
686 NSString* sysFormat = [types objectAtIndex: i];
687 DataFlavor oOOFlavor = systemToOpenOfficeFlavor(sysFormat);
689 if (isValidFlavor(oOOFlavor))
691 flavors.realloc(flavors.getLength() + 1);
692 flavors[flavors.getLength() - 1] = oOOFlavor;
696 return flavors;
700 NSArray* DataFlavorMapper::getAllSupportedPboardTypes() const
702 NSMutableArray* array = [[NSMutableArray alloc] initWithCapacity: SIZE_FLAVOR_MAP];
704 for (sal_uInt32 i = 0; i < SIZE_FLAVOR_MAP; i++)
706 [array addObject: flavorMap[i].SystemFlavor];
709 return [array autorelease];