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(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 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 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 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(NSString* systemDataFlavor) const 525 { 526 DataFlavor oOOFlavor; 527 528 for (size_t i = 0; i < SIZE_FLAVOR_MAP; i++) 529 { 530 if ([systemDataFlavor caseInsensitiveCompare: 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 NSString* DataFlavorMapper::openOfficeToSystemFlavor(const DataFlavor& oOOFlavor, bool& rbInternal) const 553 { 554 NSString* sysFlavor = NULL; 555 rbInternal = false; 556 557 for( size_t i = 0; i < SIZE_FLAVOR_MAP; ++i ) 558 { 559 if (oOOFlavor.MimeType.compareToAscii(flavorMap[i].OOoFlavor, strlen(flavorMap[i].OOoFlavor)) == 0) 560 { 561 sysFlavor = flavorMap[i].SystemFlavor; 562 } 563 } 564 565 if(!sysFlavor) 566 { 567 rbInternal = true; 568 OfficeOnlyTypes::const_iterator it = maOfficeOnlyTypes.find( oOOFlavor.MimeType ); 569 570 if( it == maOfficeOnlyTypes.end() ) 571 sysFlavor = maOfficeOnlyTypes[ oOOFlavor.MimeType ] = OUStringToNSString( oOOFlavor.MimeType ); 572 else 573 sysFlavor = it->second; 574 } 575 576 return sysFlavor; 577 } 578 579 NSString* DataFlavorMapper::openOfficeImageToSystemFlavor(NSPasteboard* pPasteboard) const 580 { 581 NSArray *supportedTypes = [NSArray arrayWithObjects: NSTIFFPboardType, NSPICTPboardType, nil]; 582 NSString *sysFlavor = [pPasteboard availableTypeFromArray:supportedTypes]; 583 return sysFlavor; 584 } 585 586 DataProviderPtr_t DataFlavorMapper::getDataProvider(NSString* systemFlavor, Reference<XTransferable> rTransferable) const 587 { 588 DataProviderPtr_t dp; 589 590 try 591 { 592 DataFlavor oOOFlavor = systemToOpenOfficeFlavor(systemFlavor); 593 594 Any data = rTransferable->getTransferData(oOOFlavor); 595 596 if (isByteSequenceType(data.getValueType())) 597 { 598 /* 599 the HTMLFormatDataProvider prepends segment information to HTML 600 this is useful for exchange with MS Word (which brings this stuff from Windows) 601 but annoying for other applications. Since this extension is not a standard datatype 602 on the Mac, let us not provide but provide normal HTML 603 604 if ([systemFlavor caseInsensitiveCompare: NSHTMLPboardType] == NSOrderedSame) 605 { 606 dp = DataProviderPtr_t(new HTMLFormatDataProvider(data)); 607 } 608 else 609 */ 610 if ([systemFlavor caseInsensitiveCompare: NSPICTPboardType] == NSOrderedSame) 611 { 612 dp = DataProviderPtr_t( new PNGDataProvider( data, PICTImageFileType)); 613 } 614 else if ([systemFlavor caseInsensitiveCompare: NSTIFFPboardType] == NSOrderedSame) 615 { 616 dp = DataProviderPtr_t( new PNGDataProvider( data, NSTIFFFileType)); 617 } 618 else if ([systemFlavor caseInsensitiveCompare: NSFilenamesPboardType] == NSOrderedSame) 619 { 620 dp = DataProviderPtr_t(new FileListDataProvider(data)); 621 } 622 else 623 { 624 dp = DataProviderPtr_t(new ByteSequenceDataProvider(data)); 625 } 626 } 627 else // Must be OUString type 628 { 629 BOOST_ASSERT(isOUStringType(data.getValueType())); 630 dp = DataProviderPtr_t(new UniDataProvider(data)); 631 } 632 } 633 catch(UnsupportedFlavorException&) 634 { 635 // Somebody violates the contract of the clipboard 636 // interface @see XTransferable 637 } 638 639 return dp; 640 } 641 642 DataProviderPtr_t DataFlavorMapper::getDataProvider(const NSString* /*systemFlavor*/, NSArray* systemData) const 643 { 644 return DataProviderPtr_t(new FileListDataProvider(systemData)); 645 } 646 647 DataProviderPtr_t DataFlavorMapper::getDataProvider(const NSString* systemFlavor, NSData* systemData) const 648 { 649 DataProviderPtr_t dp; 650 651 if ([systemFlavor caseInsensitiveCompare: NSStringPboardType] == NSOrderedSame) 652 { 653 dp = DataProviderPtr_t(new UniDataProvider(systemData)); 654 } 655 else if ([systemFlavor caseInsensitiveCompare: NSHTMLPboardType] == NSOrderedSame) 656 { 657 dp = DataProviderPtr_t(new HTMLFormatDataProvider(systemData)); 658 } 659 else if ([systemFlavor caseInsensitiveCompare: NSPICTPboardType] == NSOrderedSame) 660 { 661 dp = DataProviderPtr_t( new PNGDataProvider(systemData, PICTImageFileType)); 662 } 663 else if ([systemFlavor caseInsensitiveCompare: NSTIFFPboardType] == NSOrderedSame) 664 { 665 dp = DataProviderPtr_t( new PNGDataProvider(systemData, NSTIFFFileType)); 666 } 667 else if ([systemFlavor caseInsensitiveCompare: NSFilenamesPboardType] == NSOrderedSame) 668 { 669 //dp = DataProviderPtr_t(new FileListDataProvider(systemData)); 670 } 671 else 672 { 673 dp = DataProviderPtr_t(new ByteSequenceDataProvider(systemData)); 674 } 675 676 return dp; 677 } 678 679 bool DataFlavorMapper::isValidMimeContentType(const rtl::OUString& contentType) const 680 { 681 bool result = true; 682 683 try 684 { 685 Reference<XMimeContentType> xCntType(mrXMimeCntFactory->createMimeContentType(contentType)); 686 } 687 catch( IllegalArgumentException& ) 688 { 689 result = false; 690 } 691 692 return result; 693 } 694 695 NSArray* DataFlavorMapper::flavorSequenceToTypesArray(const com::sun::star::uno::Sequence<com::sun::star::datatransfer::DataFlavor>& flavors) const 696 { 697 sal_uInt32 nFlavors = flavors.getLength(); 698 NSMutableArray* array = [[NSMutableArray alloc] initWithCapacity: 1]; 699 700 bool bNeedDummyInternalFlavor(false); 701 702 for (sal_uInt32 i = 0; i < nFlavors; i++) 703 { 704 if( flavors[i].MimeType.compareToAscii( "image/bmp", 9 ) == 0 ) 705 { 706 [array addObject: NSTIFFPboardType]; 707 [array addObject: NSPICTPboardType]; 708 } 709 else 710 { 711 NSString* str = openOfficeToSystemFlavor(flavors[i], bNeedDummyInternalFlavor); 712 713 if (str != NULL) 714 { 715 [str retain]; 716 [array addObject: str]; 717 } 718 } 719 } 720 721 // #i89462# #i90747# 722 // in case no system flavor was found to report 723 // report at least one so D&D between OOo targets works 724 if( [array count] == 0 || bNeedDummyInternalFlavor) 725 { 726 [array addObject: PBTYPE_DUMMY_INTERNAL]; 727 } 728 729 return [array autorelease]; 730 } 731 732 com::sun::star::uno::Sequence<com::sun::star::datatransfer::DataFlavor> DataFlavorMapper::typesArrayToFlavorSequence(NSArray* types) const 733 { 734 int nFormats = [types count]; 735 Sequence<DataFlavor> flavors; 736 737 for (int i = 0; i < nFormats; i++) 738 { 739 NSString* sysFormat = [types objectAtIndex: i]; 740 DataFlavor oOOFlavor = systemToOpenOfficeFlavor(sysFormat); 741 742 if (isValidFlavor(oOOFlavor)) 743 { 744 flavors.realloc(flavors.getLength() + 1); 745 flavors[flavors.getLength() - 1] = oOOFlavor; 746 } 747 } 748 749 return flavors; 750 } 751 752 753 NSArray* DataFlavorMapper::getAllSupportedPboardTypes() const 754 { 755 NSMutableArray* array = [[NSMutableArray alloc] initWithCapacity: SIZE_FLAVOR_MAP]; 756 757 for (sal_uInt32 i = 0; i < SIZE_FLAVOR_MAP; i++) 758 { 759 [array addObject: flavorMap[i].SystemFlavor]; 760 } 761 762 return [array autorelease]; 763 } 764