xref: /AOO41X/main/vcl/aqua/source/dtrans/OSXTransferable.cxx (revision 300bfcc48c1aee2e5a1e1c3fd1072c366bf43f0f)
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 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_vcl.hxx"
26 #include <sal/types.h>
27 
28 #ifndef _TRANSFERABLE_HXX_
29 #include "OSXTransferable.hxx"
30 #endif
31 
32 #include "DataFlavorMapping.hxx"
33 
34 using namespace rtl;
35 using namespace std;
36 using namespace osl;
37 using namespace cppu;
38 using namespace com::sun::star::uno;
39 using namespace com::sun::star::datatransfer;
40 using namespace com::sun::star::io;
41 using namespace com::sun::star::lang;
42 using namespace com::sun::star::container;
43 
44 const Type CPPUTYPE_SEQINT8  = getCppuType((Sequence<sal_Int8>*)0);
45 const Type CPPUTYPE_OUSTRING = getCppuType((OUString*)0);
46 
47 namespace // private
48 {
isValidFlavor(const DataFlavor & aFlavor)49     bool isValidFlavor( const DataFlavor& aFlavor )
50     {
51       size_t len = aFlavor.MimeType.getLength();
52       Type dtype = aFlavor.DataType;
53       return ((len > 0) && ((dtype == CPPUTYPE_SEQINT8) || (dtype == CPPUTYPE_OUSTRING)));
54     }
55 
56 } // namespace private
57 
58 
OSXTransferable(const Reference<XMimeContentTypeFactory> rXMimeCntFactory,DataFlavorMapperPtr_t pDataFlavorMapper,NSPasteboard * pasteboard)59 OSXTransferable::OSXTransferable(const Reference<XMimeContentTypeFactory> rXMimeCntFactory,
60                                  DataFlavorMapperPtr_t pDataFlavorMapper,
61                                  NSPasteboard* pasteboard) :
62   mrXMimeCntFactory(rXMimeCntFactory),
63   mDataFlavorMapper(pDataFlavorMapper),
64   mPasteboard(pasteboard)
65 {
66   [mPasteboard retain];
67 
68   initClipboardItemList();
69 }
70 
71 
~OSXTransferable()72 OSXTransferable::~OSXTransferable()
73 {
74   [mPasteboard release];
75 }
76 
77 
getTransferData(const DataFlavor & aFlavor)78 Any SAL_CALL OSXTransferable::getTransferData( const DataFlavor& aFlavor )
79   throw( UnsupportedFlavorException, IOException, RuntimeException )
80 {
81   if (!isValidFlavor(aFlavor) || !isDataFlavorSupported(aFlavor))
82     {
83       throw UnsupportedFlavorException(OUString(RTL_CONSTASCII_USTRINGPARAM("AquaClipboard: Unsupported data flavor")),
84                                        static_cast<XTransferable*>(this));
85     }
86 
87   bool bInternal(false);
88   const NSString* sysFormat =
89       (aFlavor.MimeType.compareToAscii( "image/png", 9 ) == 0)
90       ? mDataFlavorMapper->openOfficeImageToSystemFlavor( mPasteboard )
91       : mDataFlavorMapper->openOfficeToSystemFlavor(aFlavor, bInternal);
92   DataProviderPtr_t dp;
93 
94   if ([sysFormat caseInsensitiveCompare: NSFilenamesPboardType] == NSOrderedSame)
95     {
96       NSArray* sysData = [mPasteboard propertyListForType: (NSString*)sysFormat];
97       dp = mDataFlavorMapper->getDataProvider(sysFormat, sysData);
98     }
99   else
100     {
101       NSData* sysData = [mPasteboard dataForType: (NSString*)sysFormat];
102       dp = mDataFlavorMapper->getDataProvider(sysFormat, sysData);
103     }
104 
105   if (dp.get() == NULL)
106     {
107       throw UnsupportedFlavorException(OUString(RTL_CONSTASCII_USTRINGPARAM("AquaClipboard: Unsupported data flavor")),
108                                        static_cast<XTransferable*>(this));
109     }
110 
111   return dp->getOOoData();
112 }
113 
114 
isUnicodeText(const DataFlavor & flavor)115 bool OSXTransferable::isUnicodeText(const DataFlavor& flavor)
116 {
117   return (flavor.DataType == CPPUTYPE_OUSTRING);
118 }
119 
120 
getTransferDataFlavors()121 Sequence< DataFlavor > SAL_CALL OSXTransferable::getTransferDataFlavors(  )
122     throw( RuntimeException )
123 {
124   return mFlavorList;
125 }
126 
127 
isDataFlavorSupported(const DataFlavor & aFlavor)128 sal_Bool SAL_CALL OSXTransferable::isDataFlavorSupported(const DataFlavor& aFlavor)
129     throw( RuntimeException )
130 {
131     for (sal_Int32 i = 0; i < mFlavorList.getLength(); i++)
132       if (compareDataFlavors(aFlavor, mFlavorList[i]))
133         return sal_True;
134 
135     return sal_False;
136 }
137 
138 
initClipboardItemList()139 void OSXTransferable::initClipboardItemList()
140 {
141   NSArray* pboardFormats = [mPasteboard types];
142 
143   if (pboardFormats == NULL)
144     {
145       throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM("AquaClipboard: Cannot get clipboard data")),
146                              static_cast<XTransferable*>(this));
147     }
148 
149   mFlavorList = mDataFlavorMapper->typesArrayToFlavorSequence(pboardFormats);
150 }
151 
152 
153 /* Compares two DataFlavors. Returns true if both DataFlavor have the same media type
154    and the number of parameter and all parameter values do match otherwise false
155    is returned.
156  */
compareDataFlavors(const DataFlavor & lhs,const DataFlavor & rhs)157 bool OSXTransferable::compareDataFlavors(const DataFlavor& lhs, const DataFlavor& rhs )
158 {
159     try
160     {
161         Reference<XMimeContentType> xLhs(mrXMimeCntFactory->createMimeContentType(lhs.MimeType));
162         Reference<XMimeContentType> xRhs(mrXMimeCntFactory->createMimeContentType(rhs.MimeType));
163 
164         if (!xLhs->getFullMediaType().equalsIgnoreAsciiCase(xRhs->getFullMediaType()) ||
165             !cmpAllContentTypeParameter(xLhs, xRhs))
166           {
167             return false;
168           }
169     }
170     catch( IllegalArgumentException& )
171     {
172         OSL_ENSURE( sal_False, "Invalid content type detected" );
173         return false;
174     }
175 
176     return true;
177 }
178 
179 
cmpAllContentTypeParameter(const Reference<XMimeContentType> xLhs,const Reference<XMimeContentType> xRhs) const180 bool OSXTransferable::cmpAllContentTypeParameter(const Reference<XMimeContentType> xLhs,
181                                                const Reference<XMimeContentType> xRhs) const
182 {
183   Sequence<OUString> xLhsFlavors = xLhs->getParameters();
184   Sequence<OUString> xRhsFlavors = xRhs->getParameters();
185 
186   // Stop here if the number of parameters is different already
187   if (xLhsFlavors.getLength() != xRhsFlavors.getLength())
188     return false;
189 
190   try
191     {
192       OUString pLhs;
193       OUString pRhs;
194 
195       for (sal_Int32 i = 0; i < xLhsFlavors.getLength(); i++)
196         {
197           pLhs = xLhs->getParameterValue(xLhsFlavors[i]);
198           pRhs = xRhs->getParameterValue(xLhsFlavors[i]);
199 
200           if (!pLhs.equalsIgnoreAsciiCase(pRhs))
201             {
202               return false;
203             }
204         }
205     }
206   catch(IllegalArgumentException&)
207     {
208       return false;
209     }
210 
211   return true;
212 }
213