xref: /AOO41X/main/vcl/aqua/source/dtrans/DataFlavorMapping.cxx (revision 76e2130f8cccf265357978b6c54141771a45656b)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #include "vcl/unohelp.hxx"
25 #include <DataFlavorMapping.hxx>
26 #include "HtmlFmtFlt.hxx"
27 #include "PictToBmpFlt.hxx"
28 #include "com/sun/star/datatransfer/UnsupportedFlavorException.hpp"
29 #include "com/sun/star/datatransfer/XMimeContentType.hpp"
30 #include "com/sun/star/lang/XMultiServiceFactory.hpp"
31 #include "com/sun/star/uno/Sequence.hxx"
32 
33 #include <rtl/ustring.hxx>
34 #include <rtl/memory.h>
35 #include <osl/endian.h>
36 
37 #include <vector>
38 #include <stdio.h>
39 
40 #include <premac.h>
41 #include <Cocoa/Cocoa.h>
42 #include <postmac.h>
43 
44 using namespace ::com::sun::star::datatransfer;
45 using namespace rtl;
46 using namespace ::com::sun::star::uno;
47 using namespace com::sun::star::lang;
48 using namespace cppu;
49 using namespace std;
50 
51 namespace // private
52 {
53   const Type CPPUTYPE_SEQINT8  = getCppuType((Sequence<sal_Int8>*)0);
54   const Type CPPUTYPE_OUSTRING = getCppuType( (OUString*)0 );
55 
56   /* Determine whether or not a DataFlavor is valid.
57    */
isValidFlavor(const DataFlavor & aFlavor)58   bool isValidFlavor(const DataFlavor& aFlavor)
59   {
60     size_t len = aFlavor.MimeType.getLength();
61     Type dtype = aFlavor.DataType;
62     return ((len > 0) && ((dtype == CPPUTYPE_SEQINT8) || (dtype == CPPUTYPE_OUSTRING)));
63   }
64 
65   typedef vector<sal_Unicode> UnicodeBuffer;
66 
NSStringToOUString(const NSString * cfString)67   OUString NSStringToOUString( const NSString* cfString)
68   {
69     BOOST_ASSERT(cfString && "Invalid parameter");
70 
71     const char* utf8Str = [cfString UTF8String];
72     unsigned int len = rtl_str_getLength(utf8Str);
73 
74     return OUString(utf8Str, len, RTL_TEXTENCODING_UTF8);
75   }
76 
OUStringToNSString(const OUString & ustring)77   NSString* OUStringToNSString(const OUString& ustring)
78   {
79     OString utf8Str = OUStringToOString(ustring, RTL_TEXTENCODING_UTF8);
80     return [NSString stringWithCString: utf8Str.getStr() encoding: NSUTF8StringEncoding];
81   }
82 
83 
84   const NSString* PBTYPE_UT16 = @"CorePasteboardFlavorType 0x75743136";
85   const NSString* PBTYPE_PICT = @"CorePasteboardFlavorType 0x50494354";
86   const NSString* PBTYPE_HTML = @"CorePasteboardFlavorType 0x48544D4C";
87   const NSString* PBTYPE_SODX = @"application/x-openoffice-objectdescriptor-xml;windows_formatname=\"Star Object Descriptor (XML)\"";
88   const NSString* PBTYPE_SESX = @"application/x-openoffice-embed-source-xml;windows_formatname=\"Star Embed Source (XML)\"";
89   const NSString* PBTYPE_SLSDX = @"application/x-openoffice-linksrcdescriptor-xml;windows_formatname=\"Star Link Source Descriptor (XML)\"";
90   const NSString* PBTYPE_ESX = @"application/x-openoffice-embed-source-xml;windows_formatname=\"Star Embed Source (XML)\"";
91   const NSString* PBTYPE_LSX = @"application/x-openoffice-link-source-xml;windows_formatname=\"Star Link Source (XML)\"";
92   const NSString* PBTYPE_EOX = @"application/x-openoffice-embedded-obj-xml;windows_formatname=\"Star Embedded Object (XML)\"";
93   const NSString* PBTYPE_SVXB = @"application/x-openoffice-svbx;windows_formatname=\"SVXB (StarView Bitmap/Animation)\"";
94   const NSString* PBTYPE_GDIMF = @"application/x-openoffice-gdimetafile;windows_formatname=\"GDIMetaFile\"";
95   const NSString* PBTYPE_WMF = @"application/x-openoffice-wmf;windows_formatname=\"Image WMF\"";
96   const NSString* PBTYPE_EMF = @"application/x-openoffice-emf;windows_formatname=\"Image EMF\"";
97 
98   const NSString* PBTYPE_DUMMY_INTERNAL = @"application/x-openoffice-internal";
99 
100   const char* FLAVOR_SODX = "application/x-openoffice-objectdescriptor-xml;windows_formatname=\"Star Object Descriptor (XML)\"";
101   const char* FLAVOR_SESX = "application/x-openoffice-embed-source-xml;windows_formatname=\"Star Embed Source (XML)\"";
102   const char* FLAVOR_SLSDX = "application/x-openoffice-linksrcdescriptor-xml;windows_formatname=\"Star Link Source Descriptor (XML)\"";
103   const char* FLAVOR_ESX = "application/x-openoffice-embed-source-xml;windows_formatname=\"Star Embed Source (XML)\"";
104   const char* FLAVOR_LSX = "application/x-openoffice-link-source-xml;windows_formatname=\"Star Link Source (XML)\"";
105   const char* FLAVOR_EOX = "application/x-openoffice-embedded-obj-xml;windows_formatname=\"Star Embedded Object (XML)\"";
106   const char* FLAVOR_SVXB = "application/x-openoffice-svbx;windows_formatname=\"SVXB (StarView Bitmap/Animation)\"";
107   const char* FLAVOR_GDIMF = "application/x-openoffice-gdimetafile;windows_formatname=\"GDIMetaFile\"";
108   const char* FLAVOR_WMF = "application/x-openoffice-wmf;windows_formatname=\"Image WMF\"";
109   const char* FLAVOR_EMF = "application/x-openoffice-emf;windows_formatname=\"Image EMF\"";
110 
111   const char* FLAVOR_DUMMY_INTERNAL = "application/x-openoffice-internal";
112 
113 
114   struct FlavorMap
115   {
116     const NSString* SystemFlavor;
117     const char* OOoFlavor;
118     const char* HumanPresentableName;
119     Type DataType;
120   };
121 
122   /* At the moment it appears as if only MS Office pastes "public.html" to the clipboard.
123    */
124   static const FlavorMap flavorMap[] =
125     {
126       { NSStringPboardType, "text/plain;charset=utf-16", "Unicode Text (UTF-16)", CPPUTYPE_OUSTRING },
127       { NSRTFPboardType, "text/richtext", "Rich Text Format", CPPUTYPE_SEQINT8 },
128       { NSTIFFPboardType, "image/png", "Portable Network Graphics", CPPUTYPE_SEQINT8 },
129       { NSPICTPboardType, "image/png", "Portable Network Graphics", CPPUTYPE_SEQINT8 },
130       { NSHTMLPboardType, "text/html", "Plain Html", CPPUTYPE_SEQINT8 },
131       { NSFilenamesPboardType, "application/x-openoffice-filelist;windows_formatname=\"FileList\"", "FileList", CPPUTYPE_SEQINT8 },
132       { PBTYPE_SESX, FLAVOR_SESX, "Star Embed Source (XML)", CPPUTYPE_SEQINT8 },
133       { PBTYPE_SLSDX, FLAVOR_SLSDX, "Star Link Source Descriptor (XML)", CPPUTYPE_SEQINT8 },
134       { PBTYPE_ESX, FLAVOR_ESX, "Star Embed Source (XML)", CPPUTYPE_SEQINT8 },
135       { PBTYPE_LSX, FLAVOR_LSX, "Star Link Source (XML)", CPPUTYPE_SEQINT8 },
136       { PBTYPE_EOX, FLAVOR_EOX, "Star Embedded Object (XML)", CPPUTYPE_SEQINT8 },
137       { PBTYPE_SVXB, FLAVOR_SVXB, "SVXB (StarView Bitmap/Animation", CPPUTYPE_SEQINT8 },
138       { PBTYPE_GDIMF, FLAVOR_GDIMF, "GDIMetaFile", CPPUTYPE_SEQINT8 },
139       { PBTYPE_WMF, FLAVOR_WMF, "Windows MetaFile", CPPUTYPE_SEQINT8 },
140       { PBTYPE_EMF, FLAVOR_EMF, "Windows Enhanced MetaFile", CPPUTYPE_SEQINT8 },
141       { PBTYPE_SODX, FLAVOR_SODX, "Star Object Descriptor (XML)", CPPUTYPE_SEQINT8 },
142       { PBTYPE_DUMMY_INTERNAL, FLAVOR_DUMMY_INTERNAL, "internal data",CPPUTYPE_SEQINT8 }
143     };
144 
145 
146   #define SIZE_FLAVOR_MAP (sizeof(flavorMap)/sizeof(FlavorMap))
147 
148 
isByteSequenceType(const Type & theType)149   inline bool isByteSequenceType(const Type& theType)
150   {
151     return (theType == CPPUTYPE_SEQINT8);
152   }
153 
isOUStringType(const Type & theType)154   inline bool isOUStringType(const Type& theType)
155   {
156     return (theType == CPPUTYPE_OUSTRING);
157   }
158 
159 } // namespace private
160 
161 
162 //###########################
163 
164 /* A base class for other data provider.
165  */
166 class DataProviderBaseImpl : public DataProvider
167 {
168 public:
169   DataProviderBaseImpl(const Any& data);
170   DataProviderBaseImpl(id data);
171   virtual ~DataProviderBaseImpl();
172 
173 protected:
174   Any mData;
175   //NSData* mSystemData;
176   id mSystemData;
177 };
178 
DataProviderBaseImpl(const Any & data)179 DataProviderBaseImpl::DataProviderBaseImpl(const Any& data) :
180   mData(data),
181   mSystemData(nil)
182 {
183 }
184 
DataProviderBaseImpl(id data)185 DataProviderBaseImpl::DataProviderBaseImpl(id data) :
186   mSystemData(data)
187 {
188   [mSystemData retain];
189 }
190 
191 
~DataProviderBaseImpl()192 DataProviderBaseImpl::~DataProviderBaseImpl()
193 {
194   if (mSystemData)
195     {
196       [mSystemData release];
197     }
198 }
199 
200 //#################################
201 
202 class UniDataProvider : public DataProviderBaseImpl
203 {
204 public:
205   UniDataProvider(const Any& data);
206 
207   UniDataProvider(NSData* data);
208 
209   virtual NSData* getSystemData();
210 
211   virtual Any getOOoData();
212 };
213 
UniDataProvider(const Any & data)214 UniDataProvider::UniDataProvider(const Any& data) :
215   DataProviderBaseImpl(data)
216 {
217 }
218 
UniDataProvider(NSData * data)219 UniDataProvider::UniDataProvider(NSData* data) :
220   DataProviderBaseImpl(data)
221 {
222 }
223 
getSystemData()224 NSData* UniDataProvider::getSystemData()
225 {
226   OUString ustr;
227   mData >>= ustr;
228 
229   OString strUtf8;
230   ustr.convertToString(&strUtf8, RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS);
231 
232   return [NSData dataWithBytes: strUtf8.getStr() length: strUtf8.getLength()];
233 }
234 
getOOoData()235 Any UniDataProvider::getOOoData()
236 {
237   Any oOOData;
238 
239   if (mSystemData)
240     {
241       oOOData = makeAny(OUString(reinterpret_cast<const sal_Char*>([mSystemData bytes]),
242                                  [mSystemData length],
243                                  RTL_TEXTENCODING_UTF8));
244     }
245   else
246     {
247       oOOData = mData;
248     }
249 
250   return oOOData;
251 }
252 
253 //###########################
254 
255 class ByteSequenceDataProvider : public DataProviderBaseImpl
256 {
257 public:
258   ByteSequenceDataProvider(const Any& data);
259 
260   ByteSequenceDataProvider(NSData* data);
261 
262   virtual NSData* getSystemData();
263 
264   virtual Any getOOoData();
265 };
266 
ByteSequenceDataProvider(const Any & data)267 ByteSequenceDataProvider::ByteSequenceDataProvider(const Any& data) :
268   DataProviderBaseImpl(data)
269 {
270 }
271 
ByteSequenceDataProvider(NSData * data)272 ByteSequenceDataProvider::ByteSequenceDataProvider(NSData* data) :
273   DataProviderBaseImpl(data)
274 {
275 }
276 
277 
getSystemData()278 NSData* ByteSequenceDataProvider::getSystemData()
279 {
280    Sequence<sal_Int8> rawData;
281    mData >>= rawData;
282 
283    return [NSData dataWithBytes: rawData.getArray() length: rawData.getLength()];
284 }
285 
getOOoData()286 Any ByteSequenceDataProvider::getOOoData()
287 {
288   Any oOOData;
289 
290   if (mSystemData)
291     {
292       unsigned int flavorDataLength = [mSystemData length];
293       Sequence<sal_Int8> byteSequence;
294       byteSequence.realloc(flavorDataLength);
295       memcpy(byteSequence.getArray(), [mSystemData bytes], flavorDataLength);
296       oOOData = makeAny(byteSequence);
297     }
298   else
299     {
300       oOOData =  mData;
301     }
302 
303   return oOOData;
304 }
305 
306 
307 //###########################
308 
309 class HTMLFormatDataProvider : public DataProviderBaseImpl
310 {
311 public:
312   HTMLFormatDataProvider(const Any& data);
313 
314   HTMLFormatDataProvider(NSData* data);
315 
316   virtual NSData* getSystemData();
317 
318   virtual Any getOOoData();
319 };
320 
HTMLFormatDataProvider(const Any & data)321 HTMLFormatDataProvider::HTMLFormatDataProvider(const Any& data) :
322   DataProviderBaseImpl(data)
323 {
324 }
325 
HTMLFormatDataProvider(NSData * data)326 HTMLFormatDataProvider::HTMLFormatDataProvider(NSData* data) :
327   DataProviderBaseImpl(data)
328 {
329 }
330 
getSystemData()331 NSData* HTMLFormatDataProvider::getSystemData()
332 {
333   Sequence<sal_Int8> textHtmlData;
334   mData >>= textHtmlData;
335 
336   Sequence<sal_Int8> htmlFormatData = TextHtmlToHTMLFormat(textHtmlData);
337 
338   return [NSData dataWithBytes: htmlFormatData.getArray() length: htmlFormatData.getLength()];
339 }
340 
getOOoData()341 Any HTMLFormatDataProvider::getOOoData()
342 {
343   Any oOOData;
344 
345   if (mSystemData)
346     {
347       unsigned int flavorDataLength = [mSystemData length];
348       Sequence<sal_Int8> unkHtmlData;
349 
350       unkHtmlData.realloc(flavorDataLength);
351       memcpy(unkHtmlData.getArray(), [mSystemData bytes], flavorDataLength);
352 
353       Sequence<sal_Int8>* pPlainHtml = &unkHtmlData;
354       Sequence<sal_Int8> plainHtml;
355 
356       if (isHTMLFormat(unkHtmlData))
357         {
358           plainHtml = HTMLFormatToTextHtml(unkHtmlData);
359           pPlainHtml = &plainHtml;
360         }
361 
362       oOOData = makeAny(*pPlainHtml);
363     }
364   else
365     {
366       oOOData = mData;
367     }
368 
369   return oOOData;
370 }
371 
372 //###########################
373 
374 class PNGDataProvider : public DataProviderBaseImpl
375 {
376     NSBitmapImageFileType meImageType;
377 public:
378     PNGDataProvider( const Any&, NSBitmapImageFileType);
379 
380     PNGDataProvider( NSData*, NSBitmapImageFileType);
381 
382     virtual NSData* getSystemData();
383 
384     virtual Any getOOoData();
385 };
386 
PNGDataProvider(const Any & data,NSBitmapImageFileType eImageType)387 PNGDataProvider::PNGDataProvider( const Any& data, NSBitmapImageFileType eImageType) :
388   DataProviderBaseImpl(data),
389   meImageType( eImageType )
390 {
391 }
392 
PNGDataProvider(NSData * data,NSBitmapImageFileType eImageType)393 PNGDataProvider::PNGDataProvider( NSData* data, NSBitmapImageFileType eImageType) :
394   DataProviderBaseImpl(data),
395   meImageType( eImageType )
396 {
397 }
398 
getSystemData()399 NSData* PNGDataProvider::getSystemData()
400 {
401     Sequence<sal_Int8> pngData;
402     mData >>= pngData;
403 
404     Sequence<sal_Int8> imgData;
405     NSData* sysData = NULL;
406     if( PNGToImage( pngData, imgData, meImageType))
407         sysData = [NSData dataWithBytes: imgData.getArray() length: imgData.getLength()];
408 
409     return sysData;
410 }
411 
412 /* The AOO 'PCT' filter is not yet good enough to be used
413    and there is no flavor defined for exchanging 'PCT' with AOO
414    so we convert 'PCT' to a PNG and provide this to AOO
415 */
getOOoData()416 Any PNGDataProvider::getOOoData()
417 {
418     Any oOOData;
419 
420     if( mSystemData)
421     {
422         const unsigned int flavorDataLength = [mSystemData length];
423         Sequence<sal_Int8> imgData( flavorDataLength);
424         memcpy( imgData.getArray(), [mSystemData bytes], flavorDataLength);
425 
426         Sequence<sal_Int8> pngData;
427         if( ImageToPNG( imgData, pngData, meImageType))
428             oOOData = makeAny( pngData);
429     }
430     else
431     {
432         oOOData = mData;
433     }
434 
435   return oOOData;
436 }
437 
438 //######################
439 
440 class FileListDataProvider : public DataProviderBaseImpl
441 {
442 public:
443   FileListDataProvider(const Any& data);
444   FileListDataProvider(NSArray* data);
445 
446   virtual NSData* getSystemData();
447   virtual Any getOOoData();
448 };
449 
FileListDataProvider(const Any & data)450 FileListDataProvider::FileListDataProvider(const Any& data) :
451   DataProviderBaseImpl(data)
452 {
453 }
454 
FileListDataProvider(NSArray * data)455 FileListDataProvider::FileListDataProvider(NSArray* data) :
456   DataProviderBaseImpl(data)
457 {
458 }
459 
getSystemData()460 NSData* FileListDataProvider::getSystemData()
461 {
462   return [NSData data];
463 }
464 
getOOoData()465 Any FileListDataProvider::getOOoData()
466 {
467   Any oOOData;
468 
469   if (mSystemData)
470     {
471       size_t length = [mSystemData count];
472       size_t lenSeqRequired = 0;
473 
474       for (size_t i = 0; i < length; i++)
475         {
476           NSString* fname = [mSystemData objectAtIndex: i];
477           lenSeqRequired += [fname maximumLengthOfBytesUsingEncoding: NSUnicodeStringEncoding] + sizeof(unichar);
478         }
479 
480       Sequence<sal_Int8> oOOFileList(lenSeqRequired);
481       unichar* pBuffer = reinterpret_cast<unichar*>(oOOFileList.getArray());
482       rtl_zeroMemory(pBuffer, lenSeqRequired);
483 
484       for (size_t i = 0; i < length; i++)
485         {
486           NSString* fname = [mSystemData objectAtIndex: i];
487           [fname getCharacters: pBuffer];
488           size_t l = [fname length];
489           pBuffer += l + 1;
490         }
491 
492       oOOData = makeAny(oOOFileList);
493     }
494   else
495     {
496       oOOData = mData;
497     }
498 
499   return oOOData;
500 }
501 
502 //###########################
503 
DataFlavorMapper()504 DataFlavorMapper::DataFlavorMapper()
505 {
506     Reference<XMultiServiceFactory> mrServiceManager = vcl::unohelper::GetMultiServiceFactory();
507     mrXMimeCntFactory = Reference<XMimeContentTypeFactory>(mrServiceManager->createInstance(
508        OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.datatransfer.MimeContentTypeFactory"))), UNO_QUERY);
509 
510   if (!mrXMimeCntFactory.is())
511     throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM("AquaClipboard: Cannot create com.sun.star.datatransfer.MimeContentTypeFactory")), NULL);
512 }
513 
~DataFlavorMapper()514 DataFlavorMapper::~DataFlavorMapper()
515 {
516     // release potential NSStrings
517     for( OfficeOnlyTypes::iterator it = maOfficeOnlyTypes.begin(); it != maOfficeOnlyTypes.end(); ++it )
518     {
519         [it->second release];
520         it->second = nil;
521     }
522 }
523 
systemToOpenOfficeFlavor(const NSString * systemDataFlavor) const524 DataFlavor DataFlavorMapper::systemToOpenOfficeFlavor( const NSString* systemDataFlavor) const
525 {
526   DataFlavor oOOFlavor;
527 
528   for (size_t i = 0; i < SIZE_FLAVOR_MAP; i++)
529     {
530       if ([systemDataFlavor caseInsensitiveCompare:const_cast<NSString*>(flavorMap[i].SystemFlavor)] == NSOrderedSame)
531         {
532           oOOFlavor.MimeType = OUString::createFromAscii( flavorMap[i].OOoFlavor);
533           oOOFlavor.HumanPresentableName = OUString::createFromAscii( flavorMap[i].HumanPresentableName);
534           oOOFlavor.DataType = flavorMap[i].DataType;
535           return oOOFlavor;
536         }
537     } // for
538 
539     // look if this might be an internal type; if it comes in here it must have
540     // been through openOfficeToSystemFlavor before, so it should then be in the map
541     rtl::OUString aTryFlavor( NSStringToOUString( systemDataFlavor ) );
542     if( maOfficeOnlyTypes.find( aTryFlavor ) != maOfficeOnlyTypes.end() )
543     {
544         oOOFlavor.MimeType = aTryFlavor;
545         oOOFlavor.HumanPresentableName = rtl::OUString();
546         oOOFlavor.DataType = CPPUTYPE_SEQINT8;
547     }
548 
549     return oOOFlavor;
550 }
551 
openOfficeToSystemFlavor(const DataFlavor & oOOFlavor,bool & rbInternal) const552 const NSString* DataFlavorMapper::openOfficeToSystemFlavor( const DataFlavor& oOOFlavor, bool& rbInternal) const
553 {
554     const NSString* sysFlavor = NULL;
555     rbInternal = false;
556     rbInternal = false;
557 
558     for( size_t i = 0; i < SIZE_FLAVOR_MAP; ++i )
559     {
560         if (oOOFlavor.MimeType.compareToAscii(flavorMap[i].OOoFlavor, strlen(flavorMap[i].OOoFlavor)) == 0)
561         {
562             sysFlavor = flavorMap[i].SystemFlavor;
563         }
564     }
565 
566     if(!sysFlavor)
567     {
568         rbInternal = true;
569         OfficeOnlyTypes::const_iterator it = maOfficeOnlyTypes.find( oOOFlavor.MimeType );
570 
571         if( it == maOfficeOnlyTypes.end() )
572             sysFlavor = maOfficeOnlyTypes[ oOOFlavor.MimeType ] = OUStringToNSString( oOOFlavor.MimeType );
573         else
574             sysFlavor = it->second;
575     }
576 
577     return sysFlavor;
578 }
579 
openOfficeImageToSystemFlavor(NSPasteboard * pPasteboard) const580 NSString* DataFlavorMapper::openOfficeImageToSystemFlavor(NSPasteboard* pPasteboard) const
581 {
582     NSArray *supportedTypes = [NSArray arrayWithObjects: NSTIFFPboardType, NSPICTPboardType, nil];
583     NSString *sysFlavor = [pPasteboard availableTypeFromArray:supportedTypes];
584     return sysFlavor;
585 }
586 
getDataProvider(const NSString * systemFlavor,Reference<XTransferable> rTransferable) const587 DataProviderPtr_t DataFlavorMapper::getDataProvider( const NSString* systemFlavor, Reference<XTransferable> rTransferable) const
588 {
589   DataProviderPtr_t dp;
590 
591   try
592     {
593       DataFlavor oOOFlavor = systemToOpenOfficeFlavor(systemFlavor);
594 
595       Any data = rTransferable->getTransferData(oOOFlavor);
596 
597       if (isByteSequenceType(data.getValueType()))
598         {
599           /*
600              the HTMLFormatDataProvider prepends segment information to HTML
601              this is useful for exchange with MS Word (which brings this stuff from Windows)
602              but annoying for other applications. Since this extension is not a standard datatype
603              on the Mac, let us not provide but provide normal HTML
604 
605           if ([systemFlavor caseInsensitiveCompare: NSHTMLPboardType] == NSOrderedSame)
606             {
607               dp = DataProviderPtr_t(new HTMLFormatDataProvider(data));
608             }
609           else
610           */
611 #ifdef MAC_OS_X_VERSION_10_6
612           if ([systemFlavor caseInsensitiveCompare: NSPasteboardTypePNG] == NSOrderedSame)
613             {
614               dp = DataProviderPtr_t( new PNGDataProvider( data, NSPNGFileType));
615             } else
616 #endif // MAC_OS_X_VERSION_10_5
617          if ([systemFlavor caseInsensitiveCompare: NSPICTPboardType] == NSOrderedSame)
618             {
619               dp = DataProviderPtr_t( new PNGDataProvider( data, PICTImageFileType));
620             }
621           else if ([systemFlavor caseInsensitiveCompare: NSTIFFPboardType] == NSOrderedSame)
622             {
623               dp = DataProviderPtr_t( new PNGDataProvider( data, NSTIFFFileType));
624             }
625           else if ([systemFlavor caseInsensitiveCompare: NSFilenamesPboardType] == NSOrderedSame)
626             {
627               dp = DataProviderPtr_t(new FileListDataProvider(data));
628             }
629           else
630             {
631               dp = DataProviderPtr_t(new ByteSequenceDataProvider(data));
632             }
633         }
634       else // Must be OUString type
635         {
636           BOOST_ASSERT(isOUStringType(data.getValueType()));
637           dp = DataProviderPtr_t(new UniDataProvider(data));
638         }
639     }
640   catch(UnsupportedFlavorException&)
641     {
642       // Somebody violates the contract of the clipboard
643       // interface @see XTransferable
644     }
645 
646   return dp;
647 }
648 
getDataProvider(const NSString *,NSArray * systemData) const649 DataProviderPtr_t DataFlavorMapper::getDataProvider( const NSString* /*systemFlavor*/, NSArray* systemData) const
650 {
651   return DataProviderPtr_t(new FileListDataProvider(systemData));
652 }
653 
getDataProvider(const NSString * systemFlavor,NSData * systemData) const654 DataProviderPtr_t DataFlavorMapper::getDataProvider( const NSString* systemFlavor, NSData* systemData) const
655 {
656   DataProviderPtr_t dp;
657 
658   if ([systemFlavor caseInsensitiveCompare: NSStringPboardType] == NSOrderedSame)
659     {
660       dp = DataProviderPtr_t(new UniDataProvider(systemData));
661     }
662   else if ([systemFlavor caseInsensitiveCompare: NSHTMLPboardType] == NSOrderedSame)
663     {
664       dp = DataProviderPtr_t(new HTMLFormatDataProvider(systemData));
665     }
666 #ifdef MAC_OS_X_VERSION_10_6
667   else if ([systemFlavor caseInsensitiveCompare: NSPasteboardTypePNG] == NSOrderedSame)
668     {
669       dp = DataProviderPtr_t( new PNGDataProvider(systemData, NSPNGFileType));
670     }
671 #endif // MAC_OS_X_VERSION_10_6
672   else if ([systemFlavor caseInsensitiveCompare: NSPICTPboardType] == NSOrderedSame)
673     {
674       dp = DataProviderPtr_t( new PNGDataProvider(systemData, PICTImageFileType));
675     }
676   else if ([systemFlavor caseInsensitiveCompare: NSTIFFPboardType] == NSOrderedSame)
677     {
678       dp = DataProviderPtr_t( new PNGDataProvider(systemData, NSTIFFFileType));
679     }
680   else if ([systemFlavor caseInsensitiveCompare: NSFilenamesPboardType] == NSOrderedSame)
681     {
682       //dp = DataProviderPtr_t(new FileListDataProvider(systemData));
683     }
684   else
685     {
686       dp = DataProviderPtr_t(new ByteSequenceDataProvider(systemData));
687     }
688 
689   return dp;
690 }
691 
isValidMimeContentType(const rtl::OUString & contentType) const692 bool DataFlavorMapper::isValidMimeContentType(const rtl::OUString& contentType) const
693 {
694   bool result = true;
695 
696   try
697     {
698       Reference<XMimeContentType> xCntType(mrXMimeCntFactory->createMimeContentType(contentType));
699     }
700   catch( IllegalArgumentException& )
701     {
702       result = false;
703     }
704 
705   return result;
706 }
707 
flavorSequenceToTypesArray(const com::sun::star::uno::Sequence<com::sun::star::datatransfer::DataFlavor> & flavors) const708 NSArray* DataFlavorMapper::flavorSequenceToTypesArray(const com::sun::star::uno::Sequence<com::sun::star::datatransfer::DataFlavor>& flavors) const
709 {
710   sal_uInt32 nFlavors = flavors.getLength();
711   NSMutableArray* array = [[NSMutableArray alloc] initWithCapacity: 1];
712 
713   bool bNeedDummyInternalFlavor(false);
714 
715   for (sal_uInt32 i = 0; i < nFlavors; i++)
716   {
717       if( flavors[i].MimeType.compareToAscii( "image/bmp", 9 ) == 0 )
718       {
719           [array addObject: NSTIFFPboardType];
720           [array addObject: NSPICTPboardType];
721       }
722       else
723       {
724           const NSString* str = openOfficeToSystemFlavor(flavors[i], bNeedDummyInternalFlavor);
725 
726           if (str != NULL)
727           {
728               [str retain];
729               [array addObject: str];
730           }
731       }
732   }
733 
734    // #i89462# #i90747#
735    // in case no system flavor was found to report
736    // report at least one so D&D between OOo targets works
737   if( [array count] == 0 || bNeedDummyInternalFlavor)
738   {
739       [array addObject: PBTYPE_DUMMY_INTERNAL];
740   }
741 
742   return [array autorelease];
743 }
744 
typesArrayToFlavorSequence(NSArray * types) const745 com::sun::star::uno::Sequence<com::sun::star::datatransfer::DataFlavor> DataFlavorMapper::typesArrayToFlavorSequence(NSArray* types) const
746 {
747   int nFormats = [types count];
748   Sequence<DataFlavor> flavors;
749 
750   for (int i = 0; i < nFormats; i++)
751     {
752       NSString* sysFormat = [types objectAtIndex: i];
753       DataFlavor oOOFlavor = systemToOpenOfficeFlavor(sysFormat);
754 
755       if (isValidFlavor(oOOFlavor))
756         {
757           flavors.realloc(flavors.getLength() + 1);
758           flavors[flavors.getLength() - 1] = oOOFlavor;
759         }
760     }
761 
762   return flavors;
763 }
764 
765 
getAllSupportedPboardTypes() const766 NSArray* DataFlavorMapper::getAllSupportedPboardTypes() const
767 {
768   NSMutableArray* array = [[NSMutableArray alloc] initWithCapacity: SIZE_FLAVOR_MAP];
769 
770   for (sal_uInt32 i = 0; i < SIZE_FLAVOR_MAP; i++)
771     {
772       [array addObject: flavorMap[i].SystemFlavor];
773     }
774 
775   return [array autorelease];
776 }
777