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