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 */ 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 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 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 Graphic", CPPUTYPE_SEQINT8 }, 129 { NSPICTPboardType, "image/png", "Portable Network Graphic", 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 149 inline bool isByteSequenceType(const Type& theType) 150 { 151 return (theType == CPPUTYPE_SEQINT8); 152 } 153 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 179 DataProviderBaseImpl::DataProviderBaseImpl(const Any& data) : 180 mData(data), 181 mSystemData(nil) 182 { 183 } 184 185 DataProviderBaseImpl::DataProviderBaseImpl(id data) : 186 mSystemData(data) 187 { 188 [mSystemData retain]; 189 } 190 191 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 214 UniDataProvider::UniDataProvider(const Any& data) : 215 DataProviderBaseImpl(data) 216 { 217 } 218 219 UniDataProvider::UniDataProvider(NSData* data) : 220 DataProviderBaseImpl(data) 221 { 222 } 223 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 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 267 ByteSequenceDataProvider::ByteSequenceDataProvider(const Any& data) : 268 DataProviderBaseImpl(data) 269 { 270 } 271 272 ByteSequenceDataProvider::ByteSequenceDataProvider(NSData* data) : 273 DataProviderBaseImpl(data) 274 { 275 } 276 277 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 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 321 HTMLFormatDataProvider::HTMLFormatDataProvider(const Any& data) : 322 DataProviderBaseImpl(data) 323 { 324 } 325 326 HTMLFormatDataProvider::HTMLFormatDataProvider(NSData* data) : 327 DataProviderBaseImpl(data) 328 { 329 } 330 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 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 387 PNGDataProvider::PNGDataProvider( const Any& data, NSBitmapImageFileType eImageType) : 388 DataProviderBaseImpl(data), 389 meImageType( eImageType ) 390 { 391 } 392 393 PNGDataProvider::PNGDataProvider( NSData* data, NSBitmapImageFileType eImageType) : 394 DataProviderBaseImpl(data), 395 meImageType( eImageType ) 396 { 397 } 398 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 */ 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 450 FileListDataProvider::FileListDataProvider(const Any& data) : 451 DataProviderBaseImpl(data) 452 { 453 } 454 455 FileListDataProvider::FileListDataProvider(NSArray* data) : 456 DataProviderBaseImpl(data) 457 { 458 } 459 460 NSData* FileListDataProvider::getSystemData() 461 { 462 return [NSData data]; 463 } 464 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 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 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 524 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 552 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 580 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 587 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 649 DataProviderPtr_t DataFlavorMapper::getDataProvider( const NSString* /*systemFlavor*/, NSArray* systemData) const 650 { 651 return DataProviderPtr_t(new FileListDataProvider(systemData)); 652 } 653 654 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 692 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 708 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 AOO targets works 737 if( [array count] == 0 || bNeedDummyInternalFlavor) 738 { 739 [array addObject: PBTYPE_DUMMY_INTERNAL]; 740 } 741 742 return [array autorelease]; 743 } 744 745 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 766 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