bump product version to 7.2.5.1
[LibreOffice.git] / vcl / osx / DataFlavorMapping.cxx
blob82065b2c88becf3335065ae05f2148e23a827be5
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
21 #include <sal/log.hxx>
23 #include "DataFlavorMapping.hxx"
24 #include "HtmlFmtFlt.hxx"
25 #include "PictToBmpFlt.hxx"
26 #include <com/sun/star/datatransfer/UnsupportedFlavorException.hpp>
27 #include <com/sun/star/datatransfer/XMimeContentType.hpp>
28 #include <com/sun/star/datatransfer/MimeContentTypeFactory.hpp>
29 #include <com/sun/star/lang/IllegalArgumentException.hpp>
30 #include <com/sun/star/uno/Sequence.hxx>
31 #include <comphelper/processfactory.hxx>
33 #include <rtl/ustring.hxx>
34 #include <osl/endian.h>
36 #include <cassert>
37 #include <string.h>
38 #include <string_view>
40 #include <premac.h>
41 #include <Cocoa/Cocoa.h>
42 #include <postmac.h>
44 using namespace ::com::sun::star::datatransfer;
45 using namespace ::com::sun::star::uno;
46 using namespace com::sun::star::lang;
47 using namespace cppu;
48 using namespace std;
50 namespace
52 /* Determine whether or not a DataFlavor is valid.
54 bool isValidFlavor(const DataFlavor& aFlavor)
56 size_t len = aFlavor.MimeType.getLength();
57 Type dtype = aFlavor.DataType;
58 return ((len > 0) && ((dtype == cppu::UnoType<Sequence<sal_Int8>>::get()) || (dtype == cppu::UnoType<OUString>::get())));
61 OUString NSStringToOUString( const NSString* cfString)
63 assert(cfString && "Invalid parameter");
65 const char* utf8Str = [cfString UTF8String];
66 unsigned int len = rtl_str_getLength(utf8Str);
68 return OUString(utf8Str, len, RTL_TEXTENCODING_UTF8);
71 NSString* OUStringToNSString(std::u16string_view ustring)
73 OString utf8Str = OUStringToOString(ustring, RTL_TEXTENCODING_UTF8);
74 return [NSString stringWithCString: utf8Str.getStr() encoding: NSUTF8StringEncoding];
77 const char* FLAVOR_SESX = "application/x-openoffice-embed-source-xml;windows_formatname=\"Star Embed Source (XML)\"";
78 const char* FLAVOR_SLSDX = "application/x-openoffice-linksrcdescriptor-xml;windows_formatname=\"Star Link Source Descriptor (XML)\"";
79 const char* FLAVOR_ESX = "application/x-openoffice-embed-source-xml;windows_formatname=\"Star Embed Source (XML)\"";
80 const char* FLAVOR_LSX = "application/x-openoffice-link-source-xml;windows_formatname=\"Star Link Source (XML)\"";
81 const char* FLAVOR_EOX = "application/x-openoffice-embedded-obj-xml;windows_formatname=\"Star Embedded Object (XML)\"";
82 const char* FLAVOR_SVXB = "application/x-openoffice-svbx;windows_formatname=\"SVXB (StarView Bitmap/Animation)\"";
83 const char* FLAVOR_GDIMF = "application/x-openoffice-gdimetafile;windows_formatname=\"GDIMetaFile\"";
84 const char* FLAVOR_WMF = "application/x-openoffice-wmf;windows_formatname=\"Image WMF\"";
85 const char* FLAVOR_EMF = "application/x-openoffice-emf;windows_formatname=\"Image EMF\"";
86 const char* FLAVOR_SODX = "application/x-openoffice-objectdescriptor-xml;windows_formatname=\"Star Object Descriptor (XML)\"";
87 const char* FLAVOR_LINK = "application/x-openoffice-link;windows_formatname=\"Link\"";
88 const char* FLAVOR_DUMMY_INTERNAL = "application/x-openoffice-internal";
90 struct FlavorMap
92 const NSString* SystemFlavor;
93 const char* OOoFlavor;
94 const char* HumanPresentableName;
95 bool DataTypeOUString; // sequence<byte> otherwise
98 // This is a list of the bidirectional mapping between (internal) MIME types and (system)
99 // pasteboard types.
101 // Only pasteboard types mentioned here will be recognized, mapped, and available for pasting in a
102 // fresh LibreOffice process. When copy-pasting in-process, the situation is different.
104 // Also MIME types not mentioned here will be stored on the pasteboard (using the same type name),
105 // though. But that is IMHO a bit pointless as they in general won't then be pasteable anyway in a
106 // new LibreOffice process. See the use of the maOfficeOnlyTypes array.
108 // The SystemFlavor member is nil for the cases where there is no predefined pasteboard type UTI
109 // and we use the internal MIME type (media type) also on the pasteboard. That is OK in macOS,
110 // there is no requirement that the types are well-formed UTIs. It is different on iOS, I think,
111 // though. For an introduction to UTIs, see for instance
112 // https://alastairs-place.net/blog/2012/06/06/utis-are-better-than-you-think-and-heres-why/
114 // In those cases the MIME type might actually have parameters appended, separated by semicolons.
115 // At least the FLAVOR_SODX one must have at least a typename="%PRODUCTNAME %PRODUCTVERSION
116 // Spreadsheet" parameter (with macros expanded and translated) for LO to recognise it. See
117 // lcl_TestFormat() in sc/source/ui/view/cellsh.cxx.
119 const FlavorMap flavorMap[] =
121 { NSPasteboardTypeString, "text/plain;charset=utf-16", "Unicode Text (UTF-16)", true },
122 { NSPasteboardTypeRTF, "text/rtf", "Rich Text Format", false },
123 { NSPasteboardTypePDF, "application/pdf", "PDF File", false },
124 { NSPasteboardTypeTIFF, "image/png", "Portable Network Graphics", false },
125 { NSPasteboardTypeHTML, "text/html", "Plain Html", false },
126 SAL_WNODEPRECATED_DECLARATIONS_PUSH
127 // "'NSFilenamesPboardType' is deprecated: first deprecated in macOS 10.14 - Create
128 // multiple pasteboard items with NSPasteboardTypeFileURL or kUTTypeFileURL instead"
129 { NSFilenamesPboardType, "application/x-openoffice-filelist;windows_formatname=\"FileList\"", "FileList", false },
130 SAL_WNODEPRECATED_DECLARATIONS_POP
131 { nil, FLAVOR_SESX, "Star Embed Source (XML)", false },
132 { nil, FLAVOR_SLSDX, "Star Link Source Descriptor (XML)", false },
133 { nil, FLAVOR_ESX, "Star Embed Source (XML)", false },
134 { nil, FLAVOR_LSX, "Star Link Source (XML)", false },
135 { nil, FLAVOR_EOX, "Star Embedded Object (XML)", false },
136 { nil, FLAVOR_SVXB, "SVXB (StarView Bitmap/Animation", false },
137 { nil, FLAVOR_GDIMF, "GDIMetaFile", false },
138 { nil, FLAVOR_WMF, "Windows MetaFile", false },
139 { nil, FLAVOR_EMF, "Windows Enhanced MetaFile", false },
140 { nil, FLAVOR_SODX, "Star Object Descriptor (XML)", false },
141 { nil, FLAVOR_LINK, "Dynamic Data Exchange (DDE link)", false },
142 { nil, FLAVOR_DUMMY_INTERNAL, "internal data",false }
145 #define SIZE_FLAVOR_MAP (sizeof(flavorMap)/sizeof(FlavorMap))
147 bool isByteSequenceType(const Type& theType)
149 return (theType == cppu::UnoType<Sequence<sal_Int8>>::get());
152 bool isOUStringType(const Type& theType)
154 return (theType == cppu::UnoType<OUString>::get() );
157 /* A base class for other data provider.
159 class DataProviderBaseImpl : public DataProvider
161 public:
162 DataProviderBaseImpl(const Any& data);
163 DataProviderBaseImpl(id data);
164 virtual ~DataProviderBaseImpl() override;
166 protected:
167 Any mData;
168 //NSData* mSystemData;
169 id mSystemData;
172 } // unnamed namespace
174 DataProviderBaseImpl::DataProviderBaseImpl(const Any& data) :
175 mData(data),
176 mSystemData(nil)
180 DataProviderBaseImpl::DataProviderBaseImpl(id data) :
181 mSystemData(data)
183 [mSystemData retain];
186 DataProviderBaseImpl::~DataProviderBaseImpl()
188 if (mSystemData)
190 [mSystemData release];
194 namespace {
196 class UniDataProvider : public DataProviderBaseImpl
198 public:
199 UniDataProvider(const Any& data);
201 UniDataProvider(NSData* data);
203 virtual NSData* getSystemData() override;
205 virtual Any getOOoData() override;
210 UniDataProvider::UniDataProvider(const Any& data) :
211 DataProviderBaseImpl(data)
215 UniDataProvider::UniDataProvider(NSData* data) :
216 DataProviderBaseImpl(data)
220 NSData* UniDataProvider::getSystemData()
222 OUString ustr;
223 mData >>= ustr;
225 OString strUtf8;
226 ustr.convertToString(&strUtf8, RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS);
228 return [NSData dataWithBytes: strUtf8.getStr() length: strUtf8.getLength()];
231 Any UniDataProvider::getOOoData()
233 Any oOOData;
235 if (mSystemData)
237 oOOData <<= OUString(static_cast<const char*>([mSystemData bytes]),
238 [mSystemData length],
239 RTL_TEXTENCODING_UTF8);
241 else
243 oOOData = mData;
246 return oOOData;
249 namespace {
251 class ByteSequenceDataProvider : public DataProviderBaseImpl
253 public:
254 ByteSequenceDataProvider(const Any& data);
256 ByteSequenceDataProvider(NSData* data);
258 virtual NSData* getSystemData() override;
260 virtual Any getOOoData() override;
265 ByteSequenceDataProvider::ByteSequenceDataProvider(const Any& data) :
266 DataProviderBaseImpl(data)
270 ByteSequenceDataProvider::ByteSequenceDataProvider(NSData* data) :
271 DataProviderBaseImpl(data)
275 NSData* ByteSequenceDataProvider::getSystemData()
277 Sequence<sal_Int8> rawData;
278 mData >>= rawData;
280 return [NSData dataWithBytes: rawData.getArray() length: rawData.getLength()];
283 Any ByteSequenceDataProvider::getOOoData()
285 Any oOOData;
287 if (mSystemData)
289 unsigned int flavorDataLength = [mSystemData length];
290 Sequence<sal_Int8> byteSequence;
291 byteSequence.realloc(flavorDataLength);
292 memcpy(byteSequence.getArray(), [mSystemData bytes], flavorDataLength);
293 oOOData <<= byteSequence;
295 else
297 oOOData = mData;
300 return oOOData;
303 namespace {
305 class HTMLFormatDataProvider : public DataProviderBaseImpl
307 public:
308 HTMLFormatDataProvider(NSData* data);
310 virtual NSData* getSystemData() override;
312 virtual Any getOOoData() override;
317 HTMLFormatDataProvider::HTMLFormatDataProvider(NSData* data) :
318 DataProviderBaseImpl(data)
322 NSData* HTMLFormatDataProvider::getSystemData()
324 Sequence<sal_Int8> textHtmlData;
325 mData >>= textHtmlData;
327 Sequence<sal_Int8> htmlFormatData = TextHtmlToHTMLFormat(textHtmlData);
329 return [NSData dataWithBytes: htmlFormatData.getArray() length: htmlFormatData.getLength()];
332 Any HTMLFormatDataProvider::getOOoData()
334 Any oOOData;
336 if (mSystemData)
338 unsigned int flavorDataLength = [mSystemData length];
339 Sequence<sal_Int8> unkHtmlData;
341 unkHtmlData.realloc(flavorDataLength);
342 memcpy(unkHtmlData.getArray(), [mSystemData bytes], flavorDataLength);
344 Sequence<sal_Int8>* pPlainHtml = &unkHtmlData;
345 Sequence<sal_Int8> plainHtml;
347 if (isHTMLFormat(unkHtmlData))
349 plainHtml = HTMLFormatToTextHtml(unkHtmlData);
350 pPlainHtml = &plainHtml;
353 oOOData <<= *pPlainHtml;
355 else
357 oOOData = mData;
360 return oOOData;
363 namespace {
366 class PNGDataProvider : public DataProviderBaseImpl
368 NSBitmapImageFileType meImageType;
369 public:
370 PNGDataProvider( const Any&, NSBitmapImageFileType);
372 PNGDataProvider( NSData*, NSBitmapImageFileType);
374 virtual NSData* getSystemData() override;
376 virtual Any getOOoData() override;
381 PNGDataProvider::PNGDataProvider( const Any& data, NSBitmapImageFileType eImageType) :
382 DataProviderBaseImpl(data),
383 meImageType( eImageType )
387 PNGDataProvider::PNGDataProvider( NSData* data, NSBitmapImageFileType eImageType) :
388 DataProviderBaseImpl(data),
389 meImageType( eImageType )
393 NSData* PNGDataProvider::getSystemData()
395 Sequence<sal_Int8> pngData;
396 mData >>= pngData;
398 Sequence<sal_Int8> imgData;
399 NSData* sysData = nullptr;
400 if( PNGToImage( pngData, imgData, meImageType))
401 sysData = [NSData dataWithBytes: imgData.getArray() length: imgData.getLength()];
403 return sysData;
406 /* The AOO 'PCT' filter is not yet good enough to be used
407 and there is no flavor defined for exchanging 'PCT' with AOO
408 so we convert 'PCT' to a PNG and provide this to AOO
410 Any PNGDataProvider::getOOoData()
412 Any oOOData;
414 if( mSystemData)
416 const unsigned int flavorDataLength = [mSystemData length];
417 Sequence<sal_Int8> imgData( flavorDataLength);
418 memcpy( imgData.getArray(), [mSystemData bytes], flavorDataLength);
420 Sequence<sal_Int8> pngData;
421 if( ImageToPNG( imgData, pngData))
422 oOOData <<= pngData;
424 else
426 oOOData = mData;
429 return oOOData;
432 namespace {
434 class FileListDataProvider : public DataProviderBaseImpl
436 public:
437 FileListDataProvider(const Any& data);
438 FileListDataProvider(NSArray* data);
440 virtual NSData* getSystemData() override;
441 virtual Any getOOoData() override;
446 FileListDataProvider::FileListDataProvider(const Any& data) :
447 DataProviderBaseImpl(data)
451 FileListDataProvider::FileListDataProvider(NSArray* data) :
452 DataProviderBaseImpl(data)
456 NSData* FileListDataProvider::getSystemData()
458 return [NSData data];
461 Any FileListDataProvider::getOOoData()
463 Any oOOData;
465 if (mSystemData)
467 size_t length = [mSystemData count];
468 size_t lenSeqRequired = 0;
470 for (size_t i = 0; i < length; i++)
472 NSString* fname = [mSystemData objectAtIndex: i];
473 lenSeqRequired += [fname maximumLengthOfBytesUsingEncoding: NSUnicodeStringEncoding] + sizeof(unichar);
476 Sequence<sal_Int8> oOOFileList(lenSeqRequired);
477 unichar* pBuffer = reinterpret_cast<unichar*>(oOOFileList.getArray());
478 memset(pBuffer, 0, lenSeqRequired);
480 for (size_t i = 0; i < length; i++)
482 NSString* fname = [mSystemData objectAtIndex: i];
483 [fname getCharacters: pBuffer];
484 size_t l = [fname length];
485 pBuffer += l + 1;
488 oOOData <<= oOOFileList;
490 else
492 oOOData = mData;
495 return oOOData;
498 DataFlavorMapper::DataFlavorMapper()
500 Reference<XComponentContext> xContext = comphelper::getProcessComponentContext();
501 mrXMimeCntFactory = MimeContentTypeFactory::create( xContext );
504 DataFlavorMapper::~DataFlavorMapper()
506 // release potential NSStrings
507 for( OfficeOnlyTypes::iterator it = maOfficeOnlyTypes.begin(); it != maOfficeOnlyTypes.end(); ++it )
509 [it->second release];
510 it->second = nil;
514 DataFlavor DataFlavorMapper::systemToOpenOfficeFlavor( const NSString* systemDataFlavor) const
516 DataFlavor oOOFlavor;
518 for (size_t i = 0; i < SIZE_FLAVOR_MAP; i++)
520 if ((flavorMap[i].SystemFlavor == nil && ([systemDataFlavor isEqualToString:[NSString stringWithUTF8String:flavorMap[i].OOoFlavor]]
522 [systemDataFlavor hasPrefix:[[NSString stringWithUTF8String:flavorMap[i].OOoFlavor] stringByAppendingString:@";"]]))
524 (flavorMap[i].SystemFlavor != nil && [systemDataFlavor isEqualToString:const_cast<NSString*>(flavorMap[i].SystemFlavor)]))
526 if (flavorMap[i].SystemFlavor == nil)
527 oOOFlavor.MimeType = NSStringToOUString(systemDataFlavor);
528 else
529 oOOFlavor.MimeType = OUString::createFromAscii(flavorMap[i].OOoFlavor);
530 oOOFlavor.HumanPresentableName = OUString::createFromAscii(flavorMap[i].HumanPresentableName);
531 oOOFlavor.DataType = flavorMap[i].DataTypeOUString ? cppu::UnoType<OUString>::get() : cppu::UnoType<Sequence<sal_Int8>>::get();
532 return oOOFlavor;
534 } // for
536 // look if this might be an internal type; if it comes in here it must have
537 // been through openOfficeToSystemFlavor before, so it should then be in the map
538 OUString aTryFlavor( NSStringToOUString( systemDataFlavor ) );
539 if( maOfficeOnlyTypes.find( aTryFlavor ) != maOfficeOnlyTypes.end() )
541 oOOFlavor.MimeType = aTryFlavor;
542 oOOFlavor.HumanPresentableName.clear();
543 oOOFlavor.DataType = cppu::UnoType<Sequence<sal_Int8>>::get();
546 return oOOFlavor;
549 const NSString* DataFlavorMapper::openOfficeToSystemFlavor( const DataFlavor& oOOFlavor, bool& rbInternal) const
551 const NSString* sysFlavor = nullptr;
552 rbInternal = false;
554 for( size_t i = 0; i < SIZE_FLAVOR_MAP; ++i )
556 if (oOOFlavor.MimeType.startsWith(OUString::createFromAscii(flavorMap[i].OOoFlavor)))
558 if (flavorMap[i].SystemFlavor != nil)
559 sysFlavor = flavorMap[i].SystemFlavor;
560 else
561 sysFlavor = OUStringToNSString(oOOFlavor.MimeType);
565 if(!sysFlavor)
567 rbInternal = true;
568 OfficeOnlyTypes::const_iterator it = maOfficeOnlyTypes.find( oOOFlavor.MimeType );
570 if( it == maOfficeOnlyTypes.end() )
571 sysFlavor = maOfficeOnlyTypes[ oOOFlavor.MimeType ] = OUStringToNSString( oOOFlavor.MimeType );
572 else
573 sysFlavor = it->second;
576 return sysFlavor;
579 NSString* DataFlavorMapper::openOfficeImageToSystemFlavor(NSPasteboard* pPasteboard)
581 NSArray *supportedTypes = [NSArray arrayWithObjects: NSPasteboardTypeTIFF, nil];
582 NSString *sysFlavor = [pPasteboard availableTypeFromArray:supportedTypes];
583 return sysFlavor;
586 DataProviderPtr_t DataFlavorMapper::getDataProvider( const NSString* systemFlavor, Reference<XTransferable> const & rTransferable) const
588 DataProviderPtr_t dp;
592 DataFlavor oOOFlavor = systemToOpenOfficeFlavor(systemFlavor);
594 Any data = rTransferable->getTransferData(oOOFlavor);
596 if (isByteSequenceType(data.getValueType()))
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
604 if ([systemFlavor caseInsensitiveCompare: NSHTMLPboardType] == NSOrderedSame)
606 dp = DataProviderPtr_t(new HTMLFormatDataProvider(data));
608 else
610 if ([systemFlavor caseInsensitiveCompare: NSPasteboardTypeTIFF] == NSOrderedSame)
612 dp = DataProviderPtr_t( new PNGDataProvider( data, NSBitmapImageFileTypeTIFF));
614 SAL_WNODEPRECATED_DECLARATIONS_PUSH
615 // "'NSFilenamesPboardType' is deprecated: first deprecated in macOS 10.14 - Create
616 // multiple pasteboard items with NSPasteboardTypeFileURL or kUTTypeFileURL instead"
617 else if ([systemFlavor caseInsensitiveCompare: NSFilenamesPboardType] == NSOrderedSame)
618 SAL_WNODEPRECATED_DECLARATIONS_POP
620 dp = DataProviderPtr_t(new FileListDataProvider(data));
622 else
624 dp = DataProviderPtr_t(new ByteSequenceDataProvider(data));
627 else // Must be OUString type
629 SAL_WARN_IF(
630 !isOUStringType(data.getValueType()), "vcl",
631 "must be OUString type");
632 dp = DataProviderPtr_t(new UniDataProvider(data));
635 catch( const UnsupportedFlavorException& e )
637 SAL_WARN( "vcl.osx.clipboard", "DataFlavorMapper::getDataProvider(): Exception: " << e.Message );
638 // Somebody violates the contract of the clipboard
639 // interface @see XTransferable
642 return dp;
645 DataProviderPtr_t DataFlavorMapper::getDataProvider( const NSString* /*systemFlavor*/, NSArray* systemData)
647 return DataProviderPtr_t(new FileListDataProvider(systemData));
650 DataProviderPtr_t DataFlavorMapper::getDataProvider( const NSString* systemFlavor, NSData* systemData)
652 DataProviderPtr_t dp;
654 if ([systemFlavor caseInsensitiveCompare: NSPasteboardTypeString] == NSOrderedSame)
656 dp = DataProviderPtr_t(new UniDataProvider(systemData));
658 else if ([systemFlavor caseInsensitiveCompare: NSPasteboardTypeHTML] == NSOrderedSame)
660 dp = DataProviderPtr_t(new HTMLFormatDataProvider(systemData));
662 else if ([systemFlavor caseInsensitiveCompare: NSPasteboardTypeTIFF] == NSOrderedSame)
664 dp = DataProviderPtr_t( new PNGDataProvider(systemData, NSBitmapImageFileTypeTIFF));
666 SAL_WNODEPRECATED_DECLARATIONS_PUSH
667 // "'NSFilenamesPboardType' is deprecated: first deprecated in macOS 10.14 - Create multiple
668 // pasteboard items with NSPasteboardTypeFileURL or kUTTypeFileURL instead"
669 else if ([systemFlavor caseInsensitiveCompare: NSFilenamesPboardType] == NSOrderedSame)
670 SAL_WNODEPRECATED_DECLARATIONS_POP
672 //dp = DataProviderPtr_t(new FileListDataProvider(systemData));
674 else
676 dp = DataProviderPtr_t(new ByteSequenceDataProvider(systemData));
679 return dp;
682 bool DataFlavorMapper::isValidMimeContentType(const OUString& contentType) const
684 bool result = true;
688 Reference<XMimeContentType> xCntType(mrXMimeCntFactory->createMimeContentType(contentType));
690 catch( const IllegalArgumentException& e )
692 SAL_WARN("vcl.osx.clipboard", "DataFlavorMapper::isValidMimeContentType(): Exception: " << e.Message);
693 result = false;
696 return result;
699 NSArray* DataFlavorMapper::flavorSequenceToTypesArray(const css::uno::Sequence<css::datatransfer::DataFlavor>& flavors) const
701 sal_uInt32 nFlavors = flavors.getLength();
702 NSMutableArray* array = [[NSMutableArray alloc] initWithCapacity: 1];
704 bool bNeedDummyInternalFlavor(false);
706 for (sal_uInt32 i = 0; i < nFlavors; i++)
708 if( flavors[i].MimeType.startsWith("image/bmp") )
710 [array addObject: NSPasteboardTypeTIFF];
712 else
714 const NSString* str = openOfficeToSystemFlavor(flavors[i], bNeedDummyInternalFlavor);
716 if (str != nullptr)
718 [str retain];
719 [array addObject: str];
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 || bNeedDummyInternalFlavor)
729 [array addObject: [NSString stringWithUTF8String: FLAVOR_DUMMY_INTERNAL]];
732 return [array autorelease];
735 css::uno::Sequence<css::datatransfer::DataFlavor> DataFlavorMapper::typesArrayToFlavorSequence(NSArray* types) const
737 int nFormats = [types count];
738 Sequence<DataFlavor> flavors;
740 for (int i = 0; i < nFormats; i++)
742 NSString* sysFormat = [types objectAtIndex: i];
743 DataFlavor oOOFlavor = systemToOpenOfficeFlavor(sysFormat);
745 if (isValidFlavor(oOOFlavor))
747 flavors.realloc(flavors.getLength() + 1);
748 flavors[flavors.getLength() - 1] = oOOFlavor;
752 return flavors;
755 NSArray* DataFlavorMapper::getAllSupportedPboardTypes()
757 NSMutableArray* array = [[NSMutableArray alloc] initWithCapacity: SIZE_FLAVOR_MAP];
759 for (sal_uInt32 i = 0; i < SIZE_FLAVOR_MAP; i++)
761 if (flavorMap[i].SystemFlavor != nil)
762 [array addObject: flavorMap[i].SystemFlavor];
763 else
764 [array addObject: [NSString stringWithUTF8String: flavorMap[i].OOoFlavor]];
767 return [array autorelease];
770 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */