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/bmp", "Windows Bitmap", CPPUTYPE_SEQINT8 }, 129 { NSPICTPboardType, "image/bmp", "Windows Bitmap", 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 BMPDataProvider : public DataProviderBaseImpl 375 { 376 NSBitmapImageFileType meImageType; 377 public: 378 BMPDataProvider(const Any& data, NSBitmapImageFileType eImageType ); 379 380 BMPDataProvider(NSData* data, NSBitmapImageFileType eImageType); 381 382 virtual NSData* getSystemData(); 383 384 virtual Any getOOoData(); 385 }; 386 387 BMPDataProvider::BMPDataProvider(const Any& data, NSBitmapImageFileType eImageType) : 388 DataProviderBaseImpl(data), 389 meImageType( eImageType ) 390 { 391 } 392 393 BMPDataProvider::BMPDataProvider(NSData* data, NSBitmapImageFileType eImageType) : 394 DataProviderBaseImpl(data), 395 meImageType( eImageType ) 396 { 397 } 398 399 NSData* BMPDataProvider::getSystemData() 400 { 401 Sequence<sal_Int8> bmpData; 402 mData >>= bmpData; 403 404 Sequence<sal_Int8> pictData; 405 NSData* sysData = NULL; 406 407 if (BMPToImage(bmpData, pictData, meImageType)) 408 { 409 sysData = [NSData dataWithBytes: pictData.getArray() length: pictData.getLength()]; 410 } 411 412 return sysData; 413 } 414 415 /* At the moment the OOo 'PCT' filter is not good enough to be used 416 and there is no flavor defined for exchanging 'PCT' with OOo so 417 we will at the moment convert 'PCT' to a Windows BMP and provide 418 this to OOo 419 */ 420 Any BMPDataProvider::getOOoData() 421 { 422 Any oOOData; 423 424 if (mSystemData) 425 { 426 unsigned int flavorDataLength = [mSystemData length]; 427 Sequence<sal_Int8> pictData(flavorDataLength); 428 429 memcpy(pictData.getArray(), [mSystemData bytes], flavorDataLength); 430 431 Sequence<sal_Int8> bmpData; 432 433 if (ImageToBMP(pictData, bmpData, meImageType)) 434 { 435 oOOData = makeAny(bmpData); 436 } 437 } 438 else 439 { 440 oOOData = mData; 441 } 442 443 return oOOData; 444 } 445 446 //###################### 447 448 class FileListDataProvider : public DataProviderBaseImpl 449 { 450 public: 451 FileListDataProvider(const Any& data); 452 FileListDataProvider(NSArray* data); 453 454 virtual NSData* getSystemData(); 455 virtual Any getOOoData(); 456 }; 457 458 FileListDataProvider::FileListDataProvider(const Any& data) : 459 DataProviderBaseImpl(data) 460 { 461 } 462 463 FileListDataProvider::FileListDataProvider(NSArray* data) : 464 DataProviderBaseImpl(data) 465 { 466 } 467 468 NSData* FileListDataProvider::getSystemData() 469 { 470 return [NSData data]; 471 } 472 473 Any FileListDataProvider::getOOoData() 474 { 475 Any oOOData; 476 477 if (mSystemData) 478 { 479 size_t length = [mSystemData count]; 480 size_t lenSeqRequired = 0; 481 482 for (size_t i = 0; i < length; i++) 483 { 484 NSString* fname = [mSystemData objectAtIndex: i]; 485 lenSeqRequired += [fname maximumLengthOfBytesUsingEncoding: NSUnicodeStringEncoding] + sizeof(unichar); 486 } 487 488 Sequence<sal_Int8> oOOFileList(lenSeqRequired); 489 unichar* pBuffer = reinterpret_cast<unichar*>(oOOFileList.getArray()); 490 rtl_zeroMemory(pBuffer, lenSeqRequired); 491 492 for (size_t i = 0; i < length; i++) 493 { 494 NSString* fname = [mSystemData objectAtIndex: i]; 495 [fname getCharacters: pBuffer]; 496 size_t l = [fname length]; 497 pBuffer += l + 1; 498 } 499 500 oOOData = makeAny(oOOFileList); 501 } 502 else 503 { 504 oOOData = mData; 505 } 506 507 return oOOData; 508 } 509 510 //########################### 511 512 DataFlavorMapper::DataFlavorMapper() 513 { 514 Reference<XMultiServiceFactory> mrServiceManager = vcl::unohelper::GetMultiServiceFactory(); 515 mrXMimeCntFactory = Reference<XMimeContentTypeFactory>(mrServiceManager->createInstance( 516 OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.datatransfer.MimeContentTypeFactory"))), UNO_QUERY); 517 518 if (!mrXMimeCntFactory.is()) 519 throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM("AquaClipboard: Cannot create com.sun.star.datatransfer.MimeContentTypeFactory")), NULL); 520 } 521 522 DataFlavorMapper::~DataFlavorMapper() 523 { 524 // release potential NSStrings 525 for( OfficeOnlyTypes::iterator it = maOfficeOnlyTypes.begin(); it != maOfficeOnlyTypes.end(); ++it ) 526 { 527 [it->second release]; 528 it->second = nil; 529 } 530 } 531 532 DataFlavor DataFlavorMapper::systemToOpenOfficeFlavor(NSString* systemDataFlavor) const 533 { 534 DataFlavor oOOFlavor; 535 536 for (size_t i = 0; i < SIZE_FLAVOR_MAP; i++) 537 { 538 if ([systemDataFlavor caseInsensitiveCompare: flavorMap[i].SystemFlavor] == NSOrderedSame) 539 { 540 oOOFlavor.MimeType = OUString::createFromAscii(flavorMap[i].OOoFlavor); 541 oOOFlavor.HumanPresentableName = OUString(RTL_CONSTASCII_USTRINGPARAM(flavorMap[i].HumanPresentableName)); 542 oOOFlavor.DataType = flavorMap[i].DataType; 543 return oOOFlavor; 544 } 545 } // for 546 547 // look if this might be an internal type; if it comes in here it must have 548 // been through openOfficeToSystemFlavor before, so it should then be in the map 549 rtl::OUString aTryFlavor( NSStringToOUString( systemDataFlavor ) ); 550 if( maOfficeOnlyTypes.find( aTryFlavor ) != maOfficeOnlyTypes.end() ) 551 { 552 oOOFlavor.MimeType = aTryFlavor; 553 oOOFlavor.HumanPresentableName = rtl::OUString(); 554 oOOFlavor.DataType = CPPUTYPE_SEQINT8; 555 } 556 557 return oOOFlavor; 558 } 559 560 NSString* DataFlavorMapper::openOfficeToSystemFlavor(const DataFlavor& oOOFlavor) const 561 { 562 NSString* sysFlavor = NULL; 563 564 for( size_t i = 0; i < SIZE_FLAVOR_MAP; ++i ) 565 { 566 if (oOOFlavor.MimeType.compareToAscii(flavorMap[i].OOoFlavor, strlen(flavorMap[i].OOoFlavor)) == 0) 567 { 568 sysFlavor = flavorMap[i].SystemFlavor; 569 } 570 } 571 572 if( ! sysFlavor ) 573 { 574 OfficeOnlyTypes::const_iterator it = maOfficeOnlyTypes.find( oOOFlavor.MimeType ); 575 if( it == maOfficeOnlyTypes.end() ) 576 sysFlavor = maOfficeOnlyTypes[ oOOFlavor.MimeType ] = OUStringToNSString( oOOFlavor.MimeType ); 577 else 578 sysFlavor = it->second; 579 } 580 581 return sysFlavor; 582 } 583 584 NSString* DataFlavorMapper::openOfficeImageToSystemFlavor(NSPasteboard* pPasteboard) const 585 { 586 NSArray *supportedTypes = [NSArray arrayWithObjects: NSTIFFPboardType, NSPICTPboardType, nil]; 587 NSString *sysFlavor = [pPasteboard availableTypeFromArray:supportedTypes]; 588 return sysFlavor; 589 } 590 591 DataProviderPtr_t DataFlavorMapper::getDataProvider(NSString* systemFlavor, Reference<XTransferable> rTransferable) const 592 { 593 DataProviderPtr_t dp; 594 595 try 596 { 597 DataFlavor oOOFlavor = systemToOpenOfficeFlavor(systemFlavor); 598 599 Any data = rTransferable->getTransferData(oOOFlavor); 600 601 if (isByteSequenceType(data.getValueType())) 602 { 603 /* 604 the HTMLFormatDataProvider prepends segment information to HTML 605 this is useful for exchange with MS Word (which brings this stuff from Windows) 606 but annoying for other applications. Since this extension is not a standard datatype 607 on the Mac, let us not provide but provide normal HTML 608 609 if ([systemFlavor caseInsensitiveCompare: NSHTMLPboardType] == NSOrderedSame) 610 { 611 dp = DataProviderPtr_t(new HTMLFormatDataProvider(data)); 612 } 613 else 614 */ 615 if ([systemFlavor caseInsensitiveCompare: NSPICTPboardType] == NSOrderedSame) 616 { 617 dp = DataProviderPtr_t(new BMPDataProvider(data, PICTImageFileType)); 618 } 619 else if ([systemFlavor caseInsensitiveCompare: NSTIFFPboardType] == NSOrderedSame) 620 { 621 dp = DataProviderPtr_t(new BMPDataProvider(data, NSTIFFFileType)); 622 } 623 else if ([systemFlavor caseInsensitiveCompare: NSFilenamesPboardType] == NSOrderedSame) 624 { 625 dp = DataProviderPtr_t(new FileListDataProvider(data)); 626 } 627 else 628 { 629 dp = DataProviderPtr_t(new ByteSequenceDataProvider(data)); 630 } 631 } 632 else // Must be OUString type 633 { 634 BOOST_ASSERT(isOUStringType(data.getValueType())); 635 dp = DataProviderPtr_t(new UniDataProvider(data)); 636 } 637 } 638 catch(UnsupportedFlavorException&) 639 { 640 // Somebody violates the contract of the clipboard 641 // interface @see XTransferable 642 } 643 644 return dp; 645 } 646 647 DataProviderPtr_t DataFlavorMapper::getDataProvider(const NSString* /*systemFlavor*/, NSArray* systemData) const 648 { 649 return DataProviderPtr_t(new FileListDataProvider(systemData)); 650 } 651 652 DataProviderPtr_t DataFlavorMapper::getDataProvider(const NSString* systemFlavor, NSData* systemData) const 653 { 654 DataProviderPtr_t dp; 655 656 if ([systemFlavor caseInsensitiveCompare: NSStringPboardType] == NSOrderedSame) 657 { 658 dp = DataProviderPtr_t(new UniDataProvider(systemData)); 659 } 660 else if ([systemFlavor caseInsensitiveCompare: NSHTMLPboardType] == NSOrderedSame) 661 { 662 dp = DataProviderPtr_t(new HTMLFormatDataProvider(systemData)); 663 } 664 else if ([systemFlavor caseInsensitiveCompare: NSPICTPboardType] == NSOrderedSame) 665 { 666 dp = DataProviderPtr_t(new BMPDataProvider(systemData, PICTImageFileType)); 667 } 668 else if ([systemFlavor caseInsensitiveCompare: NSTIFFPboardType] == NSOrderedSame) 669 { 670 dp = DataProviderPtr_t(new BMPDataProvider(systemData, NSTIFFFileType)); 671 } 672 else if ([systemFlavor caseInsensitiveCompare: NSFilenamesPboardType] == NSOrderedSame) 673 { 674 //dp = DataProviderPtr_t(new FileListDataProvider(systemData)); 675 } 676 else 677 { 678 dp = DataProviderPtr_t(new ByteSequenceDataProvider(systemData)); 679 } 680 681 return dp; 682 } 683 684 bool DataFlavorMapper::isValidMimeContentType(const rtl::OUString& contentType) const 685 { 686 bool result = true; 687 688 try 689 { 690 Reference<XMimeContentType> xCntType(mrXMimeCntFactory->createMimeContentType(contentType)); 691 } 692 catch( IllegalArgumentException& ) 693 { 694 result = false; 695 } 696 697 return result; 698 } 699 700 NSArray* DataFlavorMapper::flavorSequenceToTypesArray(const com::sun::star::uno::Sequence<com::sun::star::datatransfer::DataFlavor>& flavors) const 701 { 702 sal_uInt32 nFlavors = flavors.getLength(); 703 NSMutableArray* array = [[NSMutableArray alloc] initWithCapacity: 1]; 704 705 for (sal_uInt32 i = 0; i < nFlavors; i++) 706 { 707 if( flavors[i].MimeType.compareToAscii( "image/bmp", 9 ) == 0 ) 708 { 709 [array addObject: NSTIFFPboardType]; 710 [array addObject: NSPICTPboardType]; 711 } 712 else 713 { 714 NSString* str = openOfficeToSystemFlavor(flavors[i]); 715 716 if (str != NULL) 717 { 718 [str retain]; 719 [array addObject: str]; 720 } 721 } 722 } 723 724 // #i89462# #i90747# 725 // in case no system flavor was found to report 726 // report at least one so D&D between OOo targets works 727 if( [array count] == 0 ) 728 { 729 [array addObject: PBTYPE_DUMMY_INTERNAL]; 730 } 731 732 return [array autorelease]; 733 } 734 735 com::sun::star::uno::Sequence<com::sun::star::datatransfer::DataFlavor> DataFlavorMapper::typesArrayToFlavorSequence(NSArray* types) const 736 { 737 int nFormats = [types count]; 738 Sequence<DataFlavor> flavors; 739 740 for (int i = 0; i < nFormats; i++) 741 { 742 NSString* sysFormat = [types objectAtIndex: i]; 743 DataFlavor oOOFlavor = systemToOpenOfficeFlavor(sysFormat); 744 745 if (isValidFlavor(oOOFlavor)) 746 { 747 flavors.realloc(flavors.getLength() + 1); 748 flavors[flavors.getLength() - 1] = oOOFlavor; 749 } 750 } 751 752 return flavors; 753 } 754 755 756 NSArray* DataFlavorMapper::getAllSupportedPboardTypes() const 757 { 758 NSMutableArray* array = [[NSMutableArray alloc] initWithCapacity: SIZE_FLAVOR_MAP]; 759 760 for (sal_uInt32 i = 0; i < SIZE_FLAVOR_MAP; i++) 761 { 762 [array addObject: flavorMap[i].SystemFlavor]; 763 } 764 765 return [array autorelease]; 766 } 767