Update ooo320-m1
[ooovba.git] / vcl / aqua / source / dtrans / DataFlavorMapping.cxx
blobf617e30eb54a7e46de876d222fa768075ddc9de2
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 "vcl/unohelp.hxx"
32 #include <DataFlavorMapping.hxx>
33 #include "HtmlFmtFlt.hxx"
34 #include "PictToBmpFlt.hxx"
35 #include "com/sun/star/datatransfer/UnsupportedFlavorException.hpp"
36 #include "com/sun/star/datatransfer/XMimeContentType.hpp"
37 #include "com/sun/star/lang/XMultiServiceFactory.hpp"
38 #include "com/sun/star/uno/Sequence.hxx"
40 #include <rtl/ustring.hxx>
41 #include <rtl/memory.h>
42 #include <osl/endian.h>
44 #include <vector>
45 #include <stdio.h>
47 #include <premac.h>
48 #include <QuickTime/QuickTime.h>
49 #include <postmac.h>
51 using namespace ::com::sun::star::datatransfer;
52 using namespace rtl;
53 using namespace ::com::sun::star::uno;
54 using namespace com::sun::star::lang;
55 using namespace cppu;
56 using namespace std;
58 namespace // private
60 const Type CPPUTYPE_SEQINT8 = getCppuType((Sequence<sal_Int8>*)0);
61 const Type CPPUTYPE_OUSTRING = getCppuType( (OUString*)0 );
63 /* Determine whether or not a DataFlavor is valid.
65 bool isValidFlavor(const DataFlavor& aFlavor)
67 size_t len = aFlavor.MimeType.getLength();
68 Type dtype = aFlavor.DataType;
69 return ((len > 0) && ((dtype == CPPUTYPE_SEQINT8) || (dtype == CPPUTYPE_OUSTRING)));
72 typedef vector<sal_Unicode> UnicodeBuffer;
74 OUString NSStringToOUString(NSString* cfString)
76 BOOST_ASSERT(cfString && "Invalid parameter");
78 const char* utf8Str = [cfString UTF8String];
79 unsigned int len = rtl_str_getLength(utf8Str);
81 return OUString(utf8Str, len, RTL_TEXTENCODING_UTF8);
84 NSString* OUStringToNSString(const OUString& ustring)
86 OString utf8Str = OUStringToOString(ustring, RTL_TEXTENCODING_UTF8);
87 return [NSString stringWithCString: utf8Str.getStr() encoding: NSUTF8StringEncoding];
91 const NSString* PBTYPE_UT16 = @"CorePasteboardFlavorType 0x75743136";
92 const NSString* PBTYPE_PICT = @"CorePasteboardFlavorType 0x50494354";
93 const NSString* PBTYPE_HTML = @"CorePasteboardFlavorType 0x48544D4C";
94 const NSString* PBTYPE_SODX = @"application/x-openoffice-objectdescriptor-xml;windows_formatname=\"Star Object Descriptor (XML)\"";
95 const NSString* PBTYPE_SESX = @"application/x-openoffice-embed-source-xml;windows_formatname=\"Star Embed Source (XML)\"";
96 const NSString* PBTYPE_SLSDX = @"application/x-openoffice-linksrcdescriptor-xml;windows_formatname=\"Star Link Source Descriptor (XML)\"";
97 const NSString* PBTYPE_ESX = @"application/x-openoffice-embed-source-xml;windows_formatname=\"Star Embed Source (XML)\"";
98 const NSString* PBTYPE_LSX = @"application/x-openoffice-link-source-xml;windows_formatname=\"Star Link Source (XML)\"";
99 const NSString* PBTYPE_EOX = @"application/x-openoffice-embedded-obj-xml;windows_formatname=\"Star Embedded Object (XML)\"";
100 const NSString* PBTYPE_SVXB = @"application/x-openoffice-svbx;windows_formatname=\"SVXB (StarView Bitmap/Animation)\"";
101 const NSString* PBTYPE_GDIMF = @"application/x-openoffice-gdimetafile;windows_formatname=\"GDIMetaFile\"";
102 const NSString* PBTYPE_WMF = @"application/x-openoffice-wmf;windows_formatname=\"Image WMF\"";
103 const NSString* PBTYPE_EMF = @"application/x-openoffice-emf;windows_formatname=\"Image EMF\"";
105 const NSString* PBTYPE_DUMMY_INTERNAL = @"application/x-openoffice-internal";
107 const char* FLAVOR_SODX = "application/x-openoffice-objectdescriptor-xml;windows_formatname=\"Star Object Descriptor (XML)\"";
108 const char* FLAVOR_SESX = "application/x-openoffice-embed-source-xml;windows_formatname=\"Star Embed Source (XML)\"";
109 const char* FLAVOR_SLSDX = "application/x-openoffice-linksrcdescriptor-xml;windows_formatname=\"Star Link Source Descriptor (XML)\"";
110 const char* FLAVOR_ESX = "application/x-openoffice-embed-source-xml;windows_formatname=\"Star Embed Source (XML)\"";
111 const char* FLAVOR_LSX = "application/x-openoffice-link-source-xml;windows_formatname=\"Star Link Source (XML)\"";
112 const char* FLAVOR_EOX = "application/x-openoffice-embedded-obj-xml;windows_formatname=\"Star Embedded Object (XML)\"";
113 const char* FLAVOR_SVXB = "application/x-openoffice-svbx;windows_formatname=\"SVXB (StarView Bitmap/Animation)\"";
114 const char* FLAVOR_GDIMF = "application/x-openoffice-gdimetafile;windows_formatname=\"GDIMetaFile\"";
115 const char* FLAVOR_WMF = "application/x-openoffice-wmf;windows_formatname=\"Image WMF\"";
116 const char* FLAVOR_EMF = "application/x-openoffice-emf;windows_formatname=\"Image EMF\"";
118 const char* FLAVOR_DUMMY_INTERNAL = "application/x-openoffice-internal";
121 struct FlavorMap
123 NSString* SystemFlavor;
124 const char* OOoFlavor;
125 const char* HumanPresentableName;
126 Type DataType;
129 /* At the moment it appears as if only MS Office pastes "public.html" to the clipboard.
131 FlavorMap flavorMap[] =
133 { NSStringPboardType, "text/plain;charset=utf-16", "Unicode Text (UTF-16)", CPPUTYPE_OUSTRING },
134 { NSRTFPboardType, "text/richtext", "Rich Text Format", CPPUTYPE_SEQINT8 },
135 { NSPICTPboardType, "image/bmp", "Windows Bitmap", CPPUTYPE_SEQINT8 },
136 { NSHTMLPboardType, "text/html", "Plain Html", CPPUTYPE_SEQINT8 },
137 { NSFilenamesPboardType, "application/x-openoffice-filelist;windows_formatname=\"FileList\"", "FileList", CPPUTYPE_SEQINT8 },
138 { PBTYPE_SESX, FLAVOR_SESX, "Star Embed Source (XML)", CPPUTYPE_SEQINT8 },
139 { PBTYPE_SLSDX, FLAVOR_SLSDX, "Star Link Source Descriptor (XML)", CPPUTYPE_SEQINT8 },
140 { PBTYPE_ESX, FLAVOR_ESX, "Star Embed Source (XML)", CPPUTYPE_SEQINT8 },
141 { PBTYPE_LSX, FLAVOR_LSX, "Star Link Source (XML)", CPPUTYPE_SEQINT8 },
142 { PBTYPE_EOX, FLAVOR_EOX, "Star Embedded Object (XML)", CPPUTYPE_SEQINT8 },
143 { PBTYPE_SVXB, FLAVOR_SVXB, "SVXB (StarView Bitmap/Animation", CPPUTYPE_SEQINT8 },
144 { PBTYPE_GDIMF, FLAVOR_GDIMF, "GDIMetaFile", CPPUTYPE_SEQINT8 },
145 { PBTYPE_WMF, FLAVOR_WMF, "Windows MetaFile", CPPUTYPE_SEQINT8 },
146 { PBTYPE_EMF, FLAVOR_EMF, "Windows Enhanced MetaFile", CPPUTYPE_SEQINT8 },
147 { PBTYPE_SODX, FLAVOR_SODX, "Star Object Descriptor (XML)", CPPUTYPE_SEQINT8 },
148 { PBTYPE_DUMMY_INTERNAL, FLAVOR_DUMMY_INTERNAL, "internal data",CPPUTYPE_SEQINT8 }
149 // { PBTYPE_UT16, "text/plain;charset=utf-16", "Unicode Text (UTF-16)", CPPUTYPE_OUSTRING }
150 // { kUTTypePICT, @"PICT", "image/x-macpict;windows_formatname=\"Mac Pict\"", "Mac Pict", CPPUTYPE_SEQINT8 }
151 // { kUTTypeHTML, @"HTML", "text/html", "Plain Html", CPPUTYPE_SEQINT8 }
155 #define SIZE_FLAVOR_MAP (sizeof(flavorMap)/sizeof(FlavorMap))
158 inline bool isByteSequenceType(const Type& theType)
160 return (theType == CPPUTYPE_SEQINT8);
163 inline bool isOUStringType(const Type& theType)
165 return (theType == CPPUTYPE_OUSTRING);
168 } // namespace private
171 //###########################
173 /* A base class for other data provider.
175 class DataProviderBaseImpl : public DataProvider
177 public:
178 DataProviderBaseImpl(const Any& data);
179 DataProviderBaseImpl(id data);
180 virtual ~DataProviderBaseImpl();
182 protected:
183 Any mData;
184 //NSData* mSystemData;
185 id mSystemData;
188 DataProviderBaseImpl::DataProviderBaseImpl(const Any& data) :
189 mData(data),
190 mSystemData(nil)
194 DataProviderBaseImpl::DataProviderBaseImpl(id data) :
195 mSystemData(data)
197 [mSystemData retain];
201 DataProviderBaseImpl::~DataProviderBaseImpl()
203 if (mSystemData)
205 [mSystemData release];
209 //#################################
211 class UniDataProvider : public DataProviderBaseImpl
213 public:
214 UniDataProvider(const Any& data);
216 UniDataProvider(NSData* data);
218 virtual NSData* getSystemData();
220 virtual Any getOOoData();
223 UniDataProvider::UniDataProvider(const Any& data) :
224 DataProviderBaseImpl(data)
228 UniDataProvider::UniDataProvider(NSData* data) :
229 DataProviderBaseImpl(data)
233 NSData* UniDataProvider::getSystemData()
235 OUString ustr;
236 mData >>= ustr;
238 OString strUtf8;
239 ustr.convertToString(&strUtf8, RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS);
241 return [NSData dataWithBytes: strUtf8.getStr() length: strUtf8.getLength()];
244 Any UniDataProvider::getOOoData()
246 Any oOOData;
248 if (mSystemData)
250 oOOData = makeAny(OUString(reinterpret_cast<const sal_Char*>([mSystemData bytes]),
251 [mSystemData length],
252 RTL_TEXTENCODING_UTF8));
254 else
256 oOOData = mData;
259 return oOOData;
262 //###########################
264 class ByteSequenceDataProvider : public DataProviderBaseImpl
266 public:
267 ByteSequenceDataProvider(const Any& data);
269 ByteSequenceDataProvider(NSData* data);
271 virtual NSData* getSystemData();
273 virtual Any getOOoData();
276 ByteSequenceDataProvider::ByteSequenceDataProvider(const Any& data) :
277 DataProviderBaseImpl(data)
281 ByteSequenceDataProvider::ByteSequenceDataProvider(NSData* data) :
282 DataProviderBaseImpl(data)
287 NSData* ByteSequenceDataProvider::getSystemData()
289 Sequence<sal_Int8> rawData;
290 mData >>= rawData;
292 return [NSData dataWithBytes: rawData.getArray() length: rawData.getLength()];
295 Any ByteSequenceDataProvider::getOOoData()
297 Any oOOData;
299 if (mSystemData)
301 unsigned int flavorDataLength = [mSystemData length];
302 Sequence<sal_Int8> byteSequence;
303 byteSequence.realloc(flavorDataLength);
304 memcpy(byteSequence.getArray(), [mSystemData bytes], flavorDataLength);
305 oOOData = makeAny(byteSequence);
307 else
309 oOOData = mData;
312 return oOOData;
316 //###########################
318 class HTMLFormatDataProvider : public DataProviderBaseImpl
320 public:
321 HTMLFormatDataProvider(const Any& data);
323 HTMLFormatDataProvider(NSData* data);
325 virtual NSData* getSystemData();
327 virtual Any getOOoData();
330 HTMLFormatDataProvider::HTMLFormatDataProvider(const Any& data) :
331 DataProviderBaseImpl(data)
335 HTMLFormatDataProvider::HTMLFormatDataProvider(NSData* data) :
336 DataProviderBaseImpl(data)
340 NSData* HTMLFormatDataProvider::getSystemData()
342 Sequence<sal_Int8> textHtmlData;
343 mData >>= textHtmlData;
345 Sequence<sal_Int8> htmlFormatData = TextHtmlToHTMLFormat(textHtmlData);
347 return [NSData dataWithBytes: htmlFormatData.getArray() length: htmlFormatData.getLength()];
350 Any HTMLFormatDataProvider::getOOoData()
352 Any oOOData;
354 if (mSystemData)
356 unsigned int flavorDataLength = [mSystemData length];
357 Sequence<sal_Int8> unkHtmlData;
359 unkHtmlData.realloc(flavorDataLength);
360 memcpy(unkHtmlData.getArray(), [mSystemData bytes], flavorDataLength);
362 Sequence<sal_Int8>* pPlainHtml = &unkHtmlData;
363 Sequence<sal_Int8> plainHtml;
365 if (isHTMLFormat(unkHtmlData))
367 plainHtml = HTMLFormatToTextHtml(unkHtmlData);
368 pPlainHtml = &plainHtml;
371 oOOData = makeAny(*pPlainHtml);
373 else
375 oOOData = mData;
378 return oOOData;
381 //###########################
383 class BMPDataProvider : public DataProviderBaseImpl
385 public:
386 BMPDataProvider(const Any& data);
388 BMPDataProvider(NSData* data);
390 virtual NSData* getSystemData();
392 virtual Any getOOoData();
395 BMPDataProvider::BMPDataProvider(const Any& data) :
396 DataProviderBaseImpl(data)
400 BMPDataProvider::BMPDataProvider(NSData* data) :
401 DataProviderBaseImpl(data)
405 NSData* BMPDataProvider::getSystemData()
407 Sequence<sal_Int8> bmpData;
408 mData >>= bmpData;
410 Sequence<sal_Int8> pictData;
411 NSData* sysData = NULL;
413 if (BMPtoPICT(bmpData, pictData))
415 sysData = [NSData dataWithBytes: pictData.getArray() length: pictData.getLength()];
418 return sysData;
421 /* At the moment the OOo 'PCT' filter is not good enough to be used
422 and there is no flavor defined for exchanging 'PCT' with OOo so
423 we will at the moment convert 'PCT' to a Windows BMP and provide
424 this to OOo
426 Any BMPDataProvider::getOOoData()
428 Any oOOData;
430 if (mSystemData)
432 unsigned int flavorDataLength = [mSystemData length];
433 Sequence<sal_Int8> pictData(flavorDataLength);
435 memcpy(pictData.getArray(), [mSystemData bytes], flavorDataLength);
437 Sequence<sal_Int8> bmpData;
439 if (PICTtoBMP(pictData, bmpData))
441 oOOData = makeAny(bmpData);
444 else
446 oOOData = mData;
449 return oOOData;
452 //######################
454 class FileListDataProvider : public DataProviderBaseImpl
456 public:
457 FileListDataProvider(const Any& data);
458 FileListDataProvider(NSArray* data);
460 virtual NSData* getSystemData();
461 virtual Any getOOoData();
464 FileListDataProvider::FileListDataProvider(const Any& data) :
465 DataProviderBaseImpl(data)
469 FileListDataProvider::FileListDataProvider(NSArray* data) :
470 DataProviderBaseImpl(data)
474 NSData* FileListDataProvider::getSystemData()
476 return [NSData data];
479 Any FileListDataProvider::getOOoData()
481 Any oOOData;
483 if (mSystemData)
485 size_t length = [mSystemData count];
486 size_t lenSeqRequired = 0;
488 for (size_t i = 0; i < length; i++)
490 NSString* fname = [mSystemData objectAtIndex: i];
491 lenSeqRequired += [fname maximumLengthOfBytesUsingEncoding: NSUnicodeStringEncoding] + sizeof(unichar);
494 Sequence<sal_Int8> oOOFileList(lenSeqRequired);
495 unichar* pBuffer = reinterpret_cast<unichar*>(oOOFileList.getArray());
496 rtl_zeroMemory(pBuffer, lenSeqRequired);
498 for (size_t i = 0; i < length; i++)
500 NSString* fname = [mSystemData objectAtIndex: i];
501 [fname getCharacters: pBuffer];
502 size_t l = [fname length];
503 pBuffer += l + 1;
506 oOOData = makeAny(oOOFileList);
508 else
510 oOOData = mData;
513 return oOOData;
516 //###########################
518 DataFlavorMapper::DataFlavorMapper()
520 Reference<XMultiServiceFactory> mrServiceManager = vcl::unohelper::GetMultiServiceFactory();
521 mrXMimeCntFactory = Reference<XMimeContentTypeFactory>(mrServiceManager->createInstance(
522 OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.datatransfer.MimeContentTypeFactory"))), UNO_QUERY);
524 if (!mrXMimeCntFactory.is())
525 throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM("AquaClipboard: Cannot create com.sun.star.datatransfer.MimeContentTypeFactory")), NULL);
528 DataFlavor DataFlavorMapper::systemToOpenOfficeFlavor(NSString* systemDataFlavor) const
530 DataFlavor oOOFlavor;
532 for (size_t i = 0; i < SIZE_FLAVOR_MAP; i++)
534 if ([systemDataFlavor caseInsensitiveCompare: flavorMap[i].SystemFlavor] == NSOrderedSame)
536 oOOFlavor.MimeType = OUString::createFromAscii(flavorMap[i].OOoFlavor);
537 oOOFlavor.HumanPresentableName = OUString(RTL_CONSTASCII_USTRINGPARAM(flavorMap[i].HumanPresentableName));
538 oOOFlavor.DataType = flavorMap[i].DataType;
539 return oOOFlavor;
541 } // for
543 return oOOFlavor;
546 NSString* DataFlavorMapper::openOfficeToSystemFlavor(const DataFlavor& oOOFlavor) const
548 NSString* sysFlavor = NULL;
550 for (size_t i = 0; i < SIZE_FLAVOR_MAP; i++)
552 if (oOOFlavor.MimeType.compareToAscii(flavorMap[i].OOoFlavor, strlen(flavorMap[i].OOoFlavor)) == 0)
554 sysFlavor = flavorMap[i].SystemFlavor;
558 return sysFlavor;
561 DataProviderPtr_t DataFlavorMapper::getDataProvider(NSString* systemFlavor, Reference<XTransferable> rTransferable) const
563 DataProviderPtr_t dp;
567 DataFlavor oOOFlavor = systemToOpenOfficeFlavor(systemFlavor);
569 Any data = rTransferable->getTransferData(oOOFlavor);
571 if (isByteSequenceType(data.getValueType()))
573 if ([systemFlavor caseInsensitiveCompare: NSHTMLPboardType] == NSOrderedSame)
575 dp = DataProviderPtr_t(new HTMLFormatDataProvider(data));
577 else if ([systemFlavor caseInsensitiveCompare: NSPICTPboardType] == NSOrderedSame)
579 dp = DataProviderPtr_t(new BMPDataProvider(data));
581 else if ([systemFlavor caseInsensitiveCompare: NSFilenamesPboardType] == NSOrderedSame)
583 dp = DataProviderPtr_t(new FileListDataProvider(data));
585 else
587 dp = DataProviderPtr_t(new ByteSequenceDataProvider(data));
590 else // Must be OUString type
592 BOOST_ASSERT(isOUStringType(data.getValueType()));
593 dp = DataProviderPtr_t(new UniDataProvider(data));
596 catch(UnsupportedFlavorException&)
598 // Somebody violates the contract of the clipboard
599 // interface @see XTransferable
602 return dp;
605 DataProviderPtr_t DataFlavorMapper::getDataProvider(const NSString* systemFlavor, NSArray* systemData) const
607 return DataProviderPtr_t(new FileListDataProvider(systemData));
610 DataProviderPtr_t DataFlavorMapper::getDataProvider(const NSString* systemFlavor, NSData* systemData) const
612 DataProviderPtr_t dp;
614 if ([systemFlavor caseInsensitiveCompare: NSStringPboardType] == NSOrderedSame)
616 dp = DataProviderPtr_t(new UniDataProvider(systemData));
618 else if ([systemFlavor caseInsensitiveCompare: NSHTMLPboardType] == NSOrderedSame)
620 dp = DataProviderPtr_t(new HTMLFormatDataProvider(systemData));
622 else if ([systemFlavor caseInsensitiveCompare: NSPICTPboardType] == NSOrderedSame)
624 dp = DataProviderPtr_t(new BMPDataProvider(systemData));
626 else if ([systemFlavor caseInsensitiveCompare: NSFilenamesPboardType] == NSOrderedSame)
628 //dp = DataProviderPtr_t(new FileListDataProvider(systemData));
630 else
632 dp = DataProviderPtr_t(new ByteSequenceDataProvider(systemData));
635 return dp;
638 bool DataFlavorMapper::isValidMimeContentType(const rtl::OUString& contentType) const
640 bool result = true;
644 Reference<XMimeContentType> xCntType(mrXMimeCntFactory->createMimeContentType(contentType));
646 catch( IllegalArgumentException& )
648 result = false;
651 return result;
654 NSArray* DataFlavorMapper::flavorSequenceToTypesArray(const com::sun::star::uno::Sequence<com::sun::star::datatransfer::DataFlavor>& flavors) const
656 sal_uInt32 nFlavors = flavors.getLength();
657 NSMutableArray* array = [[NSMutableArray alloc] initWithCapacity: 1];
659 for (sal_uInt32 i = 0; i < nFlavors; i++)
661 NSString* str = openOfficeToSystemFlavor(flavors[i]);
663 if (str != NULL)
665 [array addObject: str];
669 // #i89462# #i90747#
670 // in case no system flavor was found to report
671 // report at least one so D&D between OOo targets works
672 if( [array count] == 0 )
674 [array addObject: PBTYPE_DUMMY_INTERNAL];
677 return [array autorelease];
680 com::sun::star::uno::Sequence<com::sun::star::datatransfer::DataFlavor> DataFlavorMapper::typesArrayToFlavorSequence(NSArray* types) const
682 int nFormats = [types count];
683 Sequence<DataFlavor> flavors;
685 for (int i = 0; i < nFormats; i++)
687 NSString* sysFormat = [types objectAtIndex: i];
688 DataFlavor oOOFlavor = systemToOpenOfficeFlavor(sysFormat);
690 if (isValidFlavor(oOOFlavor))
692 flavors.realloc(flavors.getLength() + 1);
693 flavors[flavors.getLength() - 1] = oOOFlavor;
697 return flavors;
701 NSArray* DataFlavorMapper::getAllSupportedPboardTypes() const
703 NSMutableArray* array = [[NSMutableArray alloc] initWithCapacity: SIZE_FLAVOR_MAP];
705 for (sal_uInt32 i = 0; i < SIZE_FLAVOR_MAP; i++)
707 [array addObject: flavorMap[i].SystemFlavor];
710 return [array autorelease];