1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 #include <com/sun/star/embed/XEmbedObjectCreator.hpp>
30 #include <com/sun/star/embed/XEmbeddedObject.hpp>
31 #include <com/sun/star/embed/EntryInitModes.hpp>
32 #include <com/sun/star/beans/PropertyValue.hpp>
33 #include <com/sun/star/datatransfer/DataFlavor.hpp>
34 #include <com/sun/star/ucb/CommandAbortedException.hpp>
36 #include <osl/thread.h>
37 #include <osl/file.hxx>
38 #include <osl/module.hxx>
39 #include <comphelper/classids.hxx>
42 #include <comphelper/mimeconfighelper.hxx>
44 #include "xdialogcreator.hxx"
45 #include "oleembobj.hxx"
46 #include <xdialogcreator.hxx>
47 #include <oleembobj.hxx>
54 class InitializedOleGuard
59 if ( !SUCCEEDED( OleInitialize( NULL
) ) )
60 throw ::com::sun::star::uno::RuntimeException();
63 ~InitializedOleGuard()
70 typedef UINT STDAPICALLTYPE
OleUIInsertObjectA_Type(LPOLEUIINSERTOBJECTA
);
76 using namespace ::com::sun::star
;
77 using namespace ::comphelper
;
78 //-------------------------------------------------------------------------
79 uno::Sequence
< sal_Int8
> GetRelatedInternalID_Impl( const uno::Sequence
< sal_Int8
>& aClassID
)
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
);
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
);
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
);
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
);
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
);
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
);
114 //-------------------------------------------------------------------------
115 uno::Sequence
< ::rtl::OUString
> SAL_CALL
MSOLEDialogObjectCreator::impl_staticGetSupportedServiceNames()
117 uno::Sequence
< ::rtl::OUString
> aRet(2);
118 aRet
[0] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.embed.MSOLEObjectSystemCreator"));
119 aRet
[1] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.embed.MSOLEObjectSystemCreator"));
123 //-------------------------------------------------------------------------
124 ::rtl::OUString SAL_CALL
MSOLEDialogObjectCreator::impl_staticGetImplementationName()
126 return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.embed.MSOLEObjectSystemCreator"));
129 //-------------------------------------------------------------------------
130 uno::Reference
< uno::XInterface
> SAL_CALL
MSOLEDialogObjectCreator::impl_staticCreateSelfInstance(
131 const uno::Reference
< lang::XMultiServiceFactory
>& xServiceManager
)
133 return uno::Reference
< uno::XInterface
>( *new MSOLEDialogObjectCreator( xServiceManager
) );
136 //-------------------------------------------------------------------------
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
,
144 uno::RuntimeException
)
146 embed::InsertedObjectInfo aObjectInfo
;
147 uno::Sequence
< beans::PropertyValue
> aObjArgs( aInObjArgs
);
151 if ( !xStorage
.is() )
152 throw lang::IllegalArgumentException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "No parent storage is provided!\n" )),
153 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >(this) ),
156 if ( !sEntName
.getLength() )
157 throw lang::IllegalArgumentException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Empty element name is provided!\n" )),
158 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >(this) ),
161 InitializedOleGuard aGuard
;
163 OLEUIINSERTOBJECT io
;
164 char szFile
[MAX_PATH
];
167 memset(&io
, 0, sizeof(io
));
169 io
.cbStruct
= sizeof(io
);
170 io
.hWndOwner
= GetActiveWindow();
173 io
.lpszFile
= szFile
;
174 io
.cchFile
= MAX_PATH
;
176 io
.dwFlags
= IOF_SELECTCREATENEW
| IOF_DISABLELINK
;
179 ::osl::Module aOleDlgLib
;
180 if( !aOleDlgLib
.load( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "oledlg" ) ) ))
181 throw uno::RuntimeException();
183 OleUIInsertObjectA_Type
* pInsertFct
= (OleUIInsertObjectA_Type
*)
184 aOleDlgLib
.getSymbol( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "OleUIInsertObjectA" ) ));
186 throw uno::RuntimeException();
188 uTemp
=pInsertFct(&io
);
190 if ( OLEUI_OK
== uTemp
)
192 if (io
.dwFlags
& IOF_SELECTCREATENEW
)
194 uno::Reference
< embed::XEmbedObjectCreator
> xEmbCreator(
195 m_xFactory
->createInstance(
196 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.embed.EmbeddedObjectCreator" ) )),
198 if ( !xEmbCreator
.is() )
199 throw uno::RuntimeException();
201 uno::Sequence
< sal_Int8
> aClassID
= MimeConfigurationHelper::GetSequenceClassID( io
.clsid
.Data1
,
213 aClassID
= GetRelatedInternalID_Impl( aClassID
);
215 //TODO: retrieve ClassName
216 ::rtl::OUString aClassName
;
217 aObjectInfo
.Object
= uno::Reference
< embed::XEmbeddedObject
>(
218 xEmbCreator
->createInstanceInitNew( aClassID
, aClassName
, xStorage
, sEntName
, aObjArgs
),
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();
228 uno::Sequence
< beans::PropertyValue
> aMediaDescr( 1 );
229 aMediaDescr
[0].Name
= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "URL" ));
230 aMediaDescr
[0].Value
<<= aFileURL
;
232 // TODO: use config helper for type detection
233 uno::Reference
< embed::XEmbedObjectCreator
> xEmbCreator
;
234 ::comphelper::MimeConfigurationHelper
aHelper( m_xFactory
);
236 if ( aHelper
.AddFilterNameCheckOwnFile( aMediaDescr
) )
237 xEmbCreator
= uno::Reference
< embed::XEmbedObjectCreator
>(
238 m_xFactory
->createInstance(
239 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.embed.EmbeddedObjectCreator" ) )),
242 xEmbCreator
= uno::Reference
< embed::XEmbedObjectCreator
>(
243 m_xFactory
->createInstance(
244 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.embed.OLEEmbeddedObjectFactory" ) )),
247 if ( !xEmbCreator
.is() )
248 throw uno::RuntimeException();
250 aObjectInfo
.Object
= uno::Reference
< embed::XEmbeddedObject
>(
251 xEmbCreator
->createInstanceInitFromMediaDescriptor( xStorage
, sEntName
, aMediaDescr
, aObjArgs
),
255 if ( ( io
.dwFlags
& IOF_CHECKDISPLAYASICON
) && io
.hMetaPict
!= NULL
)
257 METAFILEPICT
* pMF
= ( METAFILEPICT
* )GlobalLock( io
.hMetaPict
);
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;
270 if ( nBufSize
&& nBufSize
== GetMetaFileBitsEx( pMF
->hMF
, nBufSize
, pBuf
+22 ) )
272 datatransfer::DataFlavor
aFlavor(
273 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "application/x-openoffice-wmf;windows_formatname=\"Image WMF\"" )),
274 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Image WMF" )),
275 getCppuType( ( const uno::Sequence
< sal_Int8
>* ) 0 ) );
277 aObjectInfo
.Options
.realloc( 2 );
278 aObjectInfo
.Options
[0].Name
= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Icon" ));
279 aObjectInfo
.Options
[0].Value
<<= aMetafile
;
280 aObjectInfo
.Options
[1].Name
= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "IconFormat" ));
281 aObjectInfo
.Options
[1].Value
<<= aFlavor
;
284 GlobalUnlock( io
.hMetaPict
);
289 throw ucb::CommandAbortedException();
292 throw lang::NoSupportException(); // TODO:
295 OSL_ENSURE( aObjectInfo
.Object
.is(), "No object was created!\n" );
296 if ( !aObjectInfo
.Object
.is() )
297 throw uno::RuntimeException();
302 //-------------------------------------------------------------------------
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
,
310 uno::RuntimeException
)
312 embed::InsertedObjectInfo aObjectInfo
;
316 if ( !xStorage
.is() )
317 throw lang::IllegalArgumentException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "No parent storage is provided!\n" )),
318 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >(this) ),
321 if ( !sEntryName
.getLength() )
322 throw lang::IllegalArgumentException( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Empty element name is provided!\n" )),
323 uno::Reference
< uno::XInterface
>( static_cast< ::cppu::OWeakObject
* >(this) ),
326 uno::Reference
< embed::XEmbeddedObject
> xResult(
327 static_cast< ::cppu::OWeakObject
* > ( new OleEmbeddedObject( m_xFactory
) ),
330 uno::Reference
< embed::XEmbedPersist
> xPersist( xResult
, uno::UNO_QUERY
);
332 if ( !xPersist
.is() )
333 throw uno::RuntimeException(); // TODO: the interface must be supported by own document objects
335 xPersist
->setPersistentEntry( xStorage
,
337 embed::EntryInitModes::DEFAULT_INIT
,
338 uno::Sequence
< beans::PropertyValue
>(),
341 aObjectInfo
.Object
= xResult
;
343 // TODO/LATER: in case of iconifie object the icon should be stored in aObjectInfo
345 throw lang::NoSupportException(); // TODO:
348 OSL_ENSURE( aObjectInfo
.Object
.is(), "No object was created!\n" );
349 if ( !aObjectInfo
.Object
.is() )
350 throw uno::RuntimeException();
355 //-------------------------------------------------------------------------
356 ::rtl::OUString SAL_CALL
MSOLEDialogObjectCreator::getImplementationName()
357 throw ( uno::RuntimeException
)
359 return impl_staticGetImplementationName();
362 //-------------------------------------------------------------------------
363 sal_Bool SAL_CALL
MSOLEDialogObjectCreator::supportsService( const ::rtl::OUString
& ServiceName
)
364 throw ( uno::RuntimeException
)
366 uno::Sequence
< ::rtl::OUString
> aSeq
= impl_staticGetSupportedServiceNames();
368 for ( sal_Int32 nInd
= 0; nInd
< aSeq
.getLength(); nInd
++ )
369 if ( ServiceName
.compareTo( aSeq
[nInd
] ) == 0 )
375 //-------------------------------------------------------------------------
376 uno::Sequence
< ::rtl::OUString
> SAL_CALL
MSOLEDialogObjectCreator::getSupportedServiceNames()
377 throw ( uno::RuntimeException
)
379 return impl_staticGetSupportedServiceNames();
382 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */