19f62ea84SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
39f62ea84SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
49f62ea84SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
59f62ea84SAndrew Rist  * distributed with this work for additional information
69f62ea84SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
79f62ea84SAndrew Rist  * to you under the Apache License, Version 2.0 (the
89f62ea84SAndrew Rist  * "License"); you may not use this file except in compliance
99f62ea84SAndrew Rist  * with the License.  You may obtain a copy of the License at
109f62ea84SAndrew Rist  *
119f62ea84SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
129f62ea84SAndrew Rist  *
139f62ea84SAndrew Rist  * Unless required by applicable law or agreed to in writing,
149f62ea84SAndrew Rist  * software distributed under the License is distributed on an
159f62ea84SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
169f62ea84SAndrew Rist  * KIND, either express or implied.  See the License for the
179f62ea84SAndrew Rist  * specific language governing permissions and limitations
189f62ea84SAndrew Rist  * under the License.
199f62ea84SAndrew Rist  *
209f62ea84SAndrew Rist  *************************************************************/
219f62ea84SAndrew Rist 
229f62ea84SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_vcl.hxx"
26cdf0e10cSrcweir #include <sal/types.h>
27cdf0e10cSrcweir 
28cdf0e10cSrcweir #ifndef _TRANSFERABLE_HXX_
29cdf0e10cSrcweir #include "OSXTransferable.hxx"
30cdf0e10cSrcweir #endif
31cdf0e10cSrcweir 
32cdf0e10cSrcweir #include "DataFlavorMapping.hxx"
33cdf0e10cSrcweir 
34cdf0e10cSrcweir using namespace rtl;
35cdf0e10cSrcweir using namespace std;
36cdf0e10cSrcweir using namespace osl;
37cdf0e10cSrcweir using namespace cppu;
38cdf0e10cSrcweir using namespace com::sun::star::uno;
39cdf0e10cSrcweir using namespace com::sun::star::datatransfer;
40cdf0e10cSrcweir using namespace com::sun::star::io;
41cdf0e10cSrcweir using namespace com::sun::star::lang;
42cdf0e10cSrcweir using namespace com::sun::star::container;
43cdf0e10cSrcweir 
44cdf0e10cSrcweir const Type CPPUTYPE_SEQINT8  = getCppuType((Sequence<sal_Int8>*)0);
45cdf0e10cSrcweir const Type CPPUTYPE_OUSTRING = getCppuType((OUString*)0);
46cdf0e10cSrcweir 
47cdf0e10cSrcweir namespace // private
48cdf0e10cSrcweir {
49cdf0e10cSrcweir 	bool isValidFlavor( const DataFlavor& aFlavor )
50cdf0e10cSrcweir 	{
51cdf0e10cSrcweir 	  size_t len = aFlavor.MimeType.getLength();
52cdf0e10cSrcweir 	  Type dtype = aFlavor.DataType;
53cdf0e10cSrcweir 	  return ((len > 0) && ((dtype == CPPUTYPE_SEQINT8) || (dtype == CPPUTYPE_OUSTRING)));
54cdf0e10cSrcweir 	}
55cdf0e10cSrcweir 
56cdf0e10cSrcweir } // namespace private
57cdf0e10cSrcweir 
58cdf0e10cSrcweir 
59cdf0e10cSrcweir OSXTransferable::OSXTransferable(const Reference<XMimeContentTypeFactory> rXMimeCntFactory,
60cdf0e10cSrcweir 								 DataFlavorMapperPtr_t pDataFlavorMapper,
61cdf0e10cSrcweir 								 NSPasteboard* pasteboard) :
62cdf0e10cSrcweir   mrXMimeCntFactory(rXMimeCntFactory),
63cdf0e10cSrcweir   mDataFlavorMapper(pDataFlavorMapper),
64cdf0e10cSrcweir   mPasteboard(pasteboard)
65cdf0e10cSrcweir {
66cdf0e10cSrcweir   [mPasteboard retain];
67cdf0e10cSrcweir 
68cdf0e10cSrcweir   initClipboardItemList();
69cdf0e10cSrcweir }
70cdf0e10cSrcweir 
71cdf0e10cSrcweir 
72cdf0e10cSrcweir OSXTransferable::~OSXTransferable()
73cdf0e10cSrcweir {
74cdf0e10cSrcweir   [mPasteboard release];
75cdf0e10cSrcweir }
76cdf0e10cSrcweir 
77cdf0e10cSrcweir 
78cdf0e10cSrcweir Any SAL_CALL OSXTransferable::getTransferData( const DataFlavor& aFlavor )
79cdf0e10cSrcweir   throw( UnsupportedFlavorException, IOException, RuntimeException )
80cdf0e10cSrcweir {
81cdf0e10cSrcweir   if (!isValidFlavor(aFlavor) || !isDataFlavorSupported(aFlavor))
82cdf0e10cSrcweir 	{
83cdf0e10cSrcweir 	  throw UnsupportedFlavorException(OUString(RTL_CONSTASCII_USTRINGPARAM("AquaClipboard: Unsupported data flavor")),
84cdf0e10cSrcweir 									   static_cast<XTransferable*>(this));
85cdf0e10cSrcweir 	}
86cdf0e10cSrcweir 
87cdf0e10cSrcweir   NSString* sysFormat =
88*45fd3b9aSArmin Le Grand       (aFlavor.MimeType.compareToAscii( "image/png", 9 ) == 0)
89cdf0e10cSrcweir       ? mDataFlavorMapper->openOfficeImageToSystemFlavor( mPasteboard )
90cdf0e10cSrcweir       : mDataFlavorMapper->openOfficeToSystemFlavor(aFlavor);
91cdf0e10cSrcweir   DataProviderPtr_t dp;
92cdf0e10cSrcweir 
93cdf0e10cSrcweir   if ([sysFormat caseInsensitiveCompare: NSFilenamesPboardType] == NSOrderedSame)
94cdf0e10cSrcweir 	{
95cdf0e10cSrcweir 	  NSArray* sysData = [mPasteboard propertyListForType: sysFormat];
96cdf0e10cSrcweir 	  dp = mDataFlavorMapper->getDataProvider(sysFormat, sysData);
97cdf0e10cSrcweir 	}
98cdf0e10cSrcweir   else
99cdf0e10cSrcweir 	{
100cdf0e10cSrcweir 	  NSData* sysData = [mPasteboard dataForType: sysFormat];
101cdf0e10cSrcweir 	  dp = mDataFlavorMapper->getDataProvider(sysFormat, sysData);
102cdf0e10cSrcweir 	}
103cdf0e10cSrcweir 
104cdf0e10cSrcweir   if (dp.get() == NULL)
105cdf0e10cSrcweir 	{
106cdf0e10cSrcweir 	  throw UnsupportedFlavorException(OUString(RTL_CONSTASCII_USTRINGPARAM("AquaClipboard: Unsupported data flavor")),
107cdf0e10cSrcweir 									   static_cast<XTransferable*>(this));
108cdf0e10cSrcweir 	}
109cdf0e10cSrcweir 
110cdf0e10cSrcweir   return dp->getOOoData();
111cdf0e10cSrcweir }
112cdf0e10cSrcweir 
113cdf0e10cSrcweir 
114cdf0e10cSrcweir bool OSXTransferable::isUnicodeText(const DataFlavor& flavor)
115cdf0e10cSrcweir {
116cdf0e10cSrcweir   return (flavor.DataType == CPPUTYPE_OUSTRING);
117cdf0e10cSrcweir }
118cdf0e10cSrcweir 
119cdf0e10cSrcweir 
120cdf0e10cSrcweir Sequence< DataFlavor > SAL_CALL OSXTransferable::getTransferDataFlavors(  )
121cdf0e10cSrcweir 	throw( RuntimeException )
122cdf0e10cSrcweir {
123cdf0e10cSrcweir   return mFlavorList;
124cdf0e10cSrcweir }
125cdf0e10cSrcweir 
126cdf0e10cSrcweir 
127cdf0e10cSrcweir sal_Bool SAL_CALL OSXTransferable::isDataFlavorSupported(const DataFlavor& aFlavor)
128cdf0e10cSrcweir 	throw( RuntimeException )
129cdf0e10cSrcweir {
130cdf0e10cSrcweir 	for (sal_Int32 i = 0; i < mFlavorList.getLength(); i++)
131cdf0e10cSrcweir 	  if (compareDataFlavors(aFlavor, mFlavorList[i]))
132cdf0e10cSrcweir 		return sal_True;
133cdf0e10cSrcweir 
134cdf0e10cSrcweir 	return sal_False;
135cdf0e10cSrcweir }
136cdf0e10cSrcweir 
137cdf0e10cSrcweir 
138cdf0e10cSrcweir void OSXTransferable::initClipboardItemList()
139cdf0e10cSrcweir {
140cdf0e10cSrcweir   NSArray* pboardFormats = [mPasteboard types];
141cdf0e10cSrcweir 
142cdf0e10cSrcweir   if (pboardFormats == NULL)
143cdf0e10cSrcweir 	{
144cdf0e10cSrcweir 	  throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM("AquaClipboard: Cannot get clipboard data")),
145cdf0e10cSrcweir 							 static_cast<XTransferable*>(this));
146cdf0e10cSrcweir 	}
147cdf0e10cSrcweir 
148cdf0e10cSrcweir   mFlavorList = mDataFlavorMapper->typesArrayToFlavorSequence(pboardFormats);
149cdf0e10cSrcweir }
150cdf0e10cSrcweir 
151cdf0e10cSrcweir 
152cdf0e10cSrcweir /* Compares two DataFlavors. Returns true if both DataFlavor have the same media type
153cdf0e10cSrcweir    and the number of parameter and all parameter values do match otherwise false
154cdf0e10cSrcweir    is returned.
155cdf0e10cSrcweir  */
156cdf0e10cSrcweir bool OSXTransferable::compareDataFlavors(const DataFlavor& lhs, const DataFlavor& rhs )
157cdf0e10cSrcweir {
158cdf0e10cSrcweir 	try
159cdf0e10cSrcweir 	{
160cdf0e10cSrcweir 		Reference<XMimeContentType> xLhs(mrXMimeCntFactory->createMimeContentType(lhs.MimeType));
161cdf0e10cSrcweir 		Reference<XMimeContentType> xRhs(mrXMimeCntFactory->createMimeContentType(rhs.MimeType));
162cdf0e10cSrcweir 
163cdf0e10cSrcweir 		if (!xLhs->getFullMediaType().equalsIgnoreAsciiCase(xRhs->getFullMediaType()) ||
164cdf0e10cSrcweir 			!cmpAllContentTypeParameter(xLhs, xRhs))
165cdf0e10cSrcweir 		  {
166cdf0e10cSrcweir 			return false;
167cdf0e10cSrcweir 		  }
168cdf0e10cSrcweir 	}
169cdf0e10cSrcweir 	catch( IllegalArgumentException& )
170cdf0e10cSrcweir 	{
171cdf0e10cSrcweir 		OSL_ENSURE( sal_False, "Invalid content type detected" );
172cdf0e10cSrcweir 		return false;
173cdf0e10cSrcweir 	}
174cdf0e10cSrcweir 
175cdf0e10cSrcweir 	return true;
176cdf0e10cSrcweir }
177cdf0e10cSrcweir 
178cdf0e10cSrcweir 
179cdf0e10cSrcweir bool OSXTransferable::cmpAllContentTypeParameter(const Reference<XMimeContentType> xLhs,
180cdf0e10cSrcweir 											   const Reference<XMimeContentType> xRhs) const
181cdf0e10cSrcweir {
182cdf0e10cSrcweir   Sequence<OUString> xLhsFlavors = xLhs->getParameters();
183cdf0e10cSrcweir   Sequence<OUString> xRhsFlavors = xRhs->getParameters();
184cdf0e10cSrcweir 
185cdf0e10cSrcweir   // Stop here if the number of parameters is different already
186cdf0e10cSrcweir   if (xLhsFlavors.getLength() != xRhsFlavors.getLength())
187cdf0e10cSrcweir 	return false;
188cdf0e10cSrcweir 
189cdf0e10cSrcweir   try
190cdf0e10cSrcweir 	{
191cdf0e10cSrcweir 	  OUString pLhs;
192cdf0e10cSrcweir 	  OUString pRhs;
193cdf0e10cSrcweir 
194cdf0e10cSrcweir 	  for (sal_Int32 i = 0; i < xLhsFlavors.getLength(); i++)
195cdf0e10cSrcweir 		{
196cdf0e10cSrcweir 		  pLhs = xLhs->getParameterValue(xLhsFlavors[i]);
197cdf0e10cSrcweir 		  pRhs = xRhs->getParameterValue(xLhsFlavors[i]);
198cdf0e10cSrcweir 
199cdf0e10cSrcweir 		  if (!pLhs.equalsIgnoreAsciiCase(pRhs))
200cdf0e10cSrcweir 			{
201cdf0e10cSrcweir 			  return false;
202cdf0e10cSrcweir 			}
203cdf0e10cSrcweir 		}
204cdf0e10cSrcweir 	}
205cdf0e10cSrcweir   catch(IllegalArgumentException&)
206cdf0e10cSrcweir 	{
207cdf0e10cSrcweir 	  return false;
208cdf0e10cSrcweir 	}
209cdf0e10cSrcweir 
210cdf0e10cSrcweir   return true;
211cdf0e10cSrcweir }
212