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