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_embeddedobj.hxx"
26 #include <com/sun/star/embed/XEmbedObjectCreator.hpp>
27 #include <com/sun/star/embed/XEmbeddedObject.hpp>
28 #include <com/sun/star/embed/EntryInitModes.hpp>
29 #include <com/sun/star/beans/PropertyValue.hpp>
30 #include <com/sun/star/datatransfer/DataFlavor.hpp>
31 #include <com/sun/star/ucb/CommandAbortedException.hpp>
32 
33 
34 #include <osl/thread.h>
35 #include <osl/file.hxx>
36 #include <vos/module.hxx>
37 #include <comphelper/classids.hxx>
38 
39 #include "platform.h"
40 #include <comphelper/mimeconfighelper.hxx>
41 
42 #include "xdialogcreator.hxx"
43 #include "oleembobj.hxx"
44 // LLA: tip from FS
45 // #include <confighelper.hxx>
46 #include <xdialogcreator.hxx>
47 #include <oleembobj.hxx>
48 
49 
50 #ifdef WNT
51 
52 #include <oledlg.h>
53 
54 class InitializedOleGuard
55 {
56 public:
InitializedOleGuard()57 	InitializedOleGuard()
58 	{
59 		if ( !SUCCEEDED( OleInitialize( NULL ) ) )
60 			throw ::com::sun::star::uno::RuntimeException();
61 	}
62 
~InitializedOleGuard()63 	~InitializedOleGuard()
64 	{
65 		OleUninitialize();
66 	}
67 };
68 
69 extern "C" {
70 typedef UINT STDAPICALLTYPE OleUIInsertObjectA_Type(LPOLEUIINSERTOBJECTA);
71 }
72 
73 #endif
74 
75 
76 using namespace ::com::sun::star;
77 using namespace ::comphelper;
78 //-------------------------------------------------------------------------
GetRelatedInternalID_Impl(const uno::Sequence<sal_Int8> & aClassID)79 uno::Sequence< sal_Int8 > GetRelatedInternalID_Impl( const uno::Sequence< sal_Int8 >& aClassID )
80 {
81 	// Writer
82 	if ( MimeConfigurationHelper::ClassIDsEqual( aClassID, MimeConfigurationHelper::GetSequenceClassID( SO3_SW_OLE_EMBED_CLASSID_60 ) )
83 	  || MimeConfigurationHelper::ClassIDsEqual( aClassID, MimeConfigurationHelper::GetSequenceClassID( SO3_SW_OLE_EMBED_CLASSID_8 ) ) )
84 		return MimeConfigurationHelper::GetSequenceClassID( SO3_SW_CLASSID_60 );
85 
86 	// Calc
87 	if ( MimeConfigurationHelper::ClassIDsEqual( aClassID, MimeConfigurationHelper::GetSequenceClassID( SO3_SC_OLE_EMBED_CLASSID_60 ) )
88 	  || MimeConfigurationHelper::ClassIDsEqual( aClassID, MimeConfigurationHelper::GetSequenceClassID( SO3_SC_OLE_EMBED_CLASSID_8 ) ) )
89 		return MimeConfigurationHelper::GetSequenceClassID( SO3_SC_CLASSID_60 );
90 
91 	// Impress
92 	if ( MimeConfigurationHelper::ClassIDsEqual( aClassID, MimeConfigurationHelper::GetSequenceClassID( SO3_SIMPRESS_OLE_EMBED_CLASSID_60 ) )
93 	  || MimeConfigurationHelper::ClassIDsEqual( aClassID, MimeConfigurationHelper::GetSequenceClassID( SO3_SIMPRESS_OLE_EMBED_CLASSID_8 ) ) )
94 		return MimeConfigurationHelper::GetSequenceClassID( SO3_SIMPRESS_CLASSID_60 );
95 
96 	// Draw
97 	if ( MimeConfigurationHelper::ClassIDsEqual( aClassID, MimeConfigurationHelper::GetSequenceClassID( SO3_SDRAW_OLE_EMBED_CLASSID_60 ) )
98 	  || MimeConfigurationHelper::ClassIDsEqual( aClassID, MimeConfigurationHelper::GetSequenceClassID( SO3_SDRAW_OLE_EMBED_CLASSID_8 ) ) )
99 		return MimeConfigurationHelper::GetSequenceClassID( SO3_SDRAW_CLASSID_60 );
100 
101 	// Chart
102 	if ( MimeConfigurationHelper::ClassIDsEqual( aClassID, MimeConfigurationHelper::GetSequenceClassID( SO3_SCH_OLE_EMBED_CLASSID_60 ) )
103 	  || MimeConfigurationHelper::ClassIDsEqual( aClassID, MimeConfigurationHelper::GetSequenceClassID( SO3_SCH_OLE_EMBED_CLASSID_8 ) ) )
104 		return MimeConfigurationHelper::GetSequenceClassID( SO3_SCH_CLASSID_60 );
105 
106 	// Math
107 	if ( MimeConfigurationHelper::ClassIDsEqual( aClassID, MimeConfigurationHelper::GetSequenceClassID( SO3_SM_OLE_EMBED_CLASSID_60 ) )
108 	  || MimeConfigurationHelper::ClassIDsEqual( aClassID, MimeConfigurationHelper::GetSequenceClassID( SO3_SM_OLE_EMBED_CLASSID_8 ) ) )
109 		return MimeConfigurationHelper::GetSequenceClassID( SO3_SM_CLASSID_60 );
110 
111 	return aClassID;
112 }
113 
114 //-------------------------------------------------------------------------
impl_staticGetSupportedServiceNames()115 uno::Sequence< ::rtl::OUString > SAL_CALL MSOLEDialogObjectCreator::impl_staticGetSupportedServiceNames()
116 {
117     uno::Sequence< ::rtl::OUString > aRet(2);
118     aRet[0] = ::rtl::OUString::createFromAscii("com.sun.star.embed.MSOLEObjectSystemCreator");
119     aRet[1] = ::rtl::OUString::createFromAscii("com.sun.star.comp.embed.MSOLEObjectSystemCreator");
120     return aRet;
121 }
122 
123 //-------------------------------------------------------------------------
impl_staticGetImplementationName()124 ::rtl::OUString SAL_CALL MSOLEDialogObjectCreator::impl_staticGetImplementationName()
125 {
126     return ::rtl::OUString::createFromAscii("com.sun.star.comp.embed.MSOLEObjectSystemCreator");
127 }
128 
129 //-------------------------------------------------------------------------
impl_staticCreateSelfInstance(const uno::Reference<lang::XMultiServiceFactory> & xServiceManager)130 uno::Reference< uno::XInterface > SAL_CALL MSOLEDialogObjectCreator::impl_staticCreateSelfInstance(
131 			const uno::Reference< lang::XMultiServiceFactory >& xServiceManager )
132 {
133 	return uno::Reference< uno::XInterface >( *new MSOLEDialogObjectCreator( xServiceManager ) );
134 }
135 
136 //-------------------------------------------------------------------------
createInstanceByDialog(const uno::Reference<embed::XStorage> & xStorage,const::rtl::OUString & sEntName,const uno::Sequence<beans::PropertyValue> & aInObjArgs)137 embed::InsertedObjectInfo SAL_CALL MSOLEDialogObjectCreator::createInstanceByDialog(
138 			const uno::Reference< embed::XStorage >& xStorage,
139 			const ::rtl::OUString& sEntName,
140 			const uno::Sequence< beans::PropertyValue >& aInObjArgs )
141 	throw ( lang::IllegalArgumentException,
142 			io::IOException,
143 			uno::Exception,
144 			uno::RuntimeException )
145 {
146 	embed::InsertedObjectInfo aObjectInfo;
147 	uno::Sequence< beans::PropertyValue > aObjArgs( aInObjArgs );
148 
149 #ifdef WNT
150 
151 	if ( !xStorage.is() )
152 		throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "No parent storage is provided!\n" ),
153 											uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
154 											1 );
155 
156 	if ( !sEntName.getLength() )
157 		throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "Empty element name is provided!\n" ),
158 											uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
159 											2 );
160 
161 	InitializedOleGuard aGuard;
162 
163 	OLEUIINSERTOBJECT io;
164 	char szFile[MAX_PATH];
165 	UINT uTemp;
166 
167 	memset(&io, 0, sizeof(io));
168 
169 	io.cbStruct = sizeof(io);
170 	io.hWndOwner = GetActiveWindow();
171 
172 	szFile[0] = 0;
173 	io.lpszFile = szFile;
174 	io.cchFile = MAX_PATH;
175 
176 	io.dwFlags = IOF_SELECTCREATENEW | IOF_DISABLELINK;
177 
178 
179 	::vos::OModule aOleDlgLib;
180 	if( !aOleDlgLib.load( ::rtl::OUString::createFromAscii( "oledlg" ) ) )
181 		throw uno::RuntimeException();
182 
183 	OleUIInsertObjectA_Type * pInsertFct = (OleUIInsertObjectA_Type *)
184 								aOleDlgLib.getSymbol( ::rtl::OUString::createFromAscii( "OleUIInsertObjectA" ) );
185 	if( !pInsertFct )
186 		throw uno::RuntimeException();
187 
188 	uTemp=pInsertFct(&io);
189 
190 	if ( OLEUI_OK == uTemp )
191 	{
192 		if (io.dwFlags & IOF_SELECTCREATENEW)
193 		{
194 			uno::Reference< embed::XEmbedObjectCreator > xEmbCreator(
195 						m_xFactory->createInstance(
196 								::rtl::OUString::createFromAscii( "com.sun.star.embed.EmbeddedObjectCreator" ) ),
197 						uno::UNO_QUERY );
198 			if ( !xEmbCreator.is() )
199 				throw uno::RuntimeException();
200 
201 			uno::Sequence< sal_Int8 > aClassID = MimeConfigurationHelper::GetSequenceClassID( io.clsid.Data1,
202 																	 io.clsid.Data2,
203 																	 io.clsid.Data3,
204 																	 io.clsid.Data4[0],
205 																	 io.clsid.Data4[1],
206 																	 io.clsid.Data4[2],
207 																	 io.clsid.Data4[3],
208 																	 io.clsid.Data4[4],
209 																	 io.clsid.Data4[5],
210 																	 io.clsid.Data4[6],
211 																	 io.clsid.Data4[7] );
212 
213 			aClassID = GetRelatedInternalID_Impl( aClassID );
214 
215 			//TODO: retrieve ClassName
216 			::rtl::OUString aClassName;
217 			aObjectInfo.Object = uno::Reference< embed::XEmbeddedObject >(
218 							xEmbCreator->createInstanceInitNew( aClassID, aClassName, xStorage, sEntName, aObjArgs ),
219 							uno::UNO_QUERY );
220 		}
221 		else
222 		{
223 			::rtl::OUString aFileName = ::rtl::OStringToOUString( ::rtl::OString( szFile ), osl_getThreadTextEncoding() );
224     		rtl::OUString aFileURL;
225         	if ( osl::FileBase::getFileURLFromSystemPath( aFileName, aFileURL ) != osl::FileBase::E_None )
226 				throw uno::RuntimeException();
227 
228 			uno::Sequence< beans::PropertyValue > aMediaDescr( 1 );
229 			aMediaDescr[0].Name = ::rtl::OUString::createFromAscii( "URL" );
230 			aMediaDescr[0].Value <<= aFileURL;
231 
232 			// TODO: use config helper for type detection
233 			uno::Reference< embed::XEmbedObjectCreator > xEmbCreator;
234 			::comphelper::MimeConfigurationHelper aHelper( m_xFactory );
235 
236 			if ( aHelper.AddFilterNameCheckOwnFile( aMediaDescr ) )
237 				xEmbCreator = uno::Reference< embed::XEmbedObjectCreator >(
238 						m_xFactory->createInstance(
239 								::rtl::OUString::createFromAscii( "com.sun.star.embed.EmbeddedObjectCreator" ) ),
240 						uno::UNO_QUERY );
241 			else
242 				xEmbCreator = uno::Reference< embed::XEmbedObjectCreator >(
243 						m_xFactory->createInstance(
244 								::rtl::OUString::createFromAscii( "com.sun.star.embed.OLEEmbeddedObjectFactory" ) ),
245 						uno::UNO_QUERY );
246 
247 			if ( !xEmbCreator.is() )
248 				throw uno::RuntimeException();
249 
250 			aObjectInfo.Object = uno::Reference< embed::XEmbeddedObject >(
251 							xEmbCreator->createInstanceInitFromMediaDescriptor( xStorage, sEntName, aMediaDescr, aObjArgs ),
252 							uno::UNO_QUERY );
253 		}
254 
255 		if ( ( io.dwFlags & IOF_CHECKDISPLAYASICON) && io.hMetaPict != NULL )
256 		{
257 			METAFILEPICT* pMF = ( METAFILEPICT* )GlobalLock( io.hMetaPict );
258 			if ( pMF )
259 			{
260 				sal_uInt32 nBufSize = GetMetaFileBitsEx( pMF->hMF, 0, NULL );
261 				uno::Sequence< sal_Int8 > aMetafile( nBufSize + 22 );
262 				sal_uInt8* pBuf = (sal_uInt8*)( aMetafile.getArray() );
263 				*( (long* )pBuf ) = 0x9ac6cdd7L;
264 				*( (short* )( pBuf+6 )) = ( SHORT ) 0;
265 				*( (short* )( pBuf+8 )) = ( SHORT ) 0;
266 				*( (short* )( pBuf+10 )) = ( SHORT ) pMF->xExt;
267 				*( (short* )( pBuf+12 )) = ( SHORT ) pMF->yExt;
268 				*( (short* )( pBuf+14 )) = ( USHORT ) 2540;
269 
270 				if ( nBufSize && nBufSize == GetMetaFileBitsEx( pMF->hMF, nBufSize, pBuf+22 ) )
271 				{
272 					datatransfer::DataFlavor aFlavor(
273                         ::rtl::OUString::createFromAscii( "application/x-openoffice-wmf;windows_formatname=\"Image WMF\"" ),
274 						::rtl::OUString::createFromAscii( "Image WMF" ),
275 						getCppuType( ( const uno::Sequence< sal_Int8 >* ) 0 ) );
276 
277 					aObjectInfo.Options.realloc( 2 );
278 					aObjectInfo.Options[0].Name = ::rtl::OUString::createFromAscii( "Icon" );
279 					aObjectInfo.Options[0].Value <<= aMetafile;
280 					aObjectInfo.Options[1].Name = ::rtl::OUString::createFromAscii( "IconFormat" );
281 					aObjectInfo.Options[1].Value <<= aFlavor;
282 				}
283 
284 				GlobalUnlock( io.hMetaPict );
285 			}
286 		}
287 	}
288 	else
289 		throw ucb::CommandAbortedException();
290 
291 #else
292 	throw lang::NoSupportException(); // TODO:
293 #endif
294 
295 	OSL_ENSURE( aObjectInfo.Object.is(), "No object was created!\n" );
296 	if ( !aObjectInfo.Object.is() )
297 		throw uno::RuntimeException();
298 
299 	return aObjectInfo;
300 }
301 
302 //-------------------------------------------------------------------------
createInstanceInitFromClipboard(const uno::Reference<embed::XStorage> & xStorage,const::rtl::OUString & sEntryName,const uno::Sequence<beans::PropertyValue> & aObjectArgs)303 embed::InsertedObjectInfo SAL_CALL MSOLEDialogObjectCreator::createInstanceInitFromClipboard(
304 				const uno::Reference< embed::XStorage >& xStorage,
305 				const ::rtl::OUString& sEntryName,
306 				const uno::Sequence< beans::PropertyValue >& aObjectArgs )
307 		throw ( lang::IllegalArgumentException,
308 				io::IOException,
309 				uno::Exception,
310 				uno::RuntimeException )
311 {
312 	embed::InsertedObjectInfo aObjectInfo;
313 
314 #ifdef WNT
315 
316 	if ( !xStorage.is() )
317 		throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "No parent storage is provided!\n" ),
318 											uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
319 											1 );
320 
321 	if ( !sEntryName.getLength() )
322 		throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "Empty element name is provided!\n" ),
323 											uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
324 											2 );
325 
326 	uno::Reference< embed::XEmbeddedObject > xResult(
327 					static_cast< ::cppu::OWeakObject* > ( new OleEmbeddedObject( m_xFactory ) ),
328 					uno::UNO_QUERY );
329 
330 	uno::Reference< embed::XEmbedPersist > xPersist( xResult, uno::UNO_QUERY );
331 
332 	if ( !xPersist.is() )
333 		throw uno::RuntimeException(); // TODO: the interface must be supported by own document objects
334 
335 	xPersist->setPersistentEntry( xStorage,
336 									sEntryName,
337 									embed::EntryInitModes::DEFAULT_INIT,
338 									uno::Sequence< beans::PropertyValue >(),
339 									aObjectArgs );
340 
341 	aObjectInfo.Object = xResult;
342 
343 	// TODO/LATER: in case of iconifie object the icon should be stored in aObjectInfo
344 #else
345 	throw lang::NoSupportException(); // TODO:
346 #endif
347 
348 	OSL_ENSURE( aObjectInfo.Object.is(), "No object was created!\n" );
349 	if ( !aObjectInfo.Object.is() )
350 		throw uno::RuntimeException();
351 
352 	return aObjectInfo;
353 }
354 
355 //-------------------------------------------------------------------------
getImplementationName()356 ::rtl::OUString SAL_CALL MSOLEDialogObjectCreator::getImplementationName()
357 	throw ( uno::RuntimeException )
358 {
359 	return impl_staticGetImplementationName();
360 }
361 
362 //-------------------------------------------------------------------------
supportsService(const::rtl::OUString & ServiceName)363 sal_Bool SAL_CALL MSOLEDialogObjectCreator::supportsService( const ::rtl::OUString& ServiceName )
364 	throw ( uno::RuntimeException )
365 {
366 	uno::Sequence< ::rtl::OUString > aSeq = impl_staticGetSupportedServiceNames();
367 
368 	for ( sal_Int32 nInd = 0; nInd < aSeq.getLength(); nInd++ )
369     	if ( ServiceName.compareTo( aSeq[nInd] ) == 0 )
370         	return sal_True;
371 
372 	return sal_False;
373 }
374 
375 //-------------------------------------------------------------------------
getSupportedServiceNames()376 uno::Sequence< ::rtl::OUString > SAL_CALL MSOLEDialogObjectCreator::getSupportedServiceNames()
377 	throw ( uno::RuntimeException )
378 {
379 	return impl_staticGetSupportedServiceNames();
380 }
381 
382