1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <com/sun/star/embed/EmbeddedObjectCreator.hpp>
21 #include <com/sun/star/embed/XEmbeddedObject.hpp>
22 #include <com/sun/star/embed/EntryInitModes.hpp>
23 #include <com/sun/star/embed/OLEEmbeddedObjectFactory.hpp>
24 #include <com/sun/star/beans/PropertyValue.hpp>
25 #include <com/sun/star/datatransfer/DataFlavor.hpp>
26 #include <com/sun/star/ucb/CommandAbortedException.hpp>
28 #include <osl/thread.h>
29 #include <osl/file.hxx>
30 #include <osl/module.hxx>
31 #include <comphelper/classids.hxx>
34 #include <comphelper/mimeconfighelper.hxx>
35 #include <comphelper/processfactory.hxx>
36 #include <cppuhelper/supportsservice.hxx>
38 #include <xdialogcreator.hxx>
39 #include <oleembobj.hxx>
46 class InitializedOleGuard
51 if ( !SUCCEEDED( OleInitialize( nullptr ) ) )
52 throw css::uno::RuntimeException();
55 ~InitializedOleGuard()
62 typedef UINT STDAPICALLTYPE
OleUIInsertObjectA_Type(LPOLEUIINSERTOBJECTA
);
68 using namespace ::com::sun::star
;
69 using namespace ::comphelper
;
71 uno::Sequence
< sal_Int8
> GetRelatedInternalID_Impl( const uno::Sequence
< sal_Int8
>& aClassID
)
74 if ( MimeConfigurationHelper::ClassIDsEqual( aClassID
, MimeConfigurationHelper::GetSequenceClassID( SO3_SW_OLE_EMBED_CLASSID_60
) )
75 || MimeConfigurationHelper::ClassIDsEqual( aClassID
, MimeConfigurationHelper::GetSequenceClassID( SO3_SW_OLE_EMBED_CLASSID_8
) ) )
76 return MimeConfigurationHelper::GetSequenceClassID( SO3_SW_CLASSID_60
);
79 if ( MimeConfigurationHelper::ClassIDsEqual( aClassID
, MimeConfigurationHelper::GetSequenceClassID( SO3_SC_OLE_EMBED_CLASSID_60
) )
80 || MimeConfigurationHelper::ClassIDsEqual( aClassID
, MimeConfigurationHelper::GetSequenceClassID( SO3_SC_OLE_EMBED_CLASSID_8
) ) )
81 return MimeConfigurationHelper::GetSequenceClassID( SO3_SC_CLASSID_60
);
84 if ( MimeConfigurationHelper::ClassIDsEqual( aClassID
, MimeConfigurationHelper::GetSequenceClassID( SO3_SIMPRESS_OLE_EMBED_CLASSID_60
) )
85 || MimeConfigurationHelper::ClassIDsEqual( aClassID
, MimeConfigurationHelper::GetSequenceClassID( SO3_SIMPRESS_OLE_EMBED_CLASSID_8
) ) )
86 return MimeConfigurationHelper::GetSequenceClassID( SO3_SIMPRESS_CLASSID_60
);
89 if ( MimeConfigurationHelper::ClassIDsEqual( aClassID
, MimeConfigurationHelper::GetSequenceClassID( SO3_SDRAW_OLE_EMBED_CLASSID_60
) )
90 || MimeConfigurationHelper::ClassIDsEqual( aClassID
, MimeConfigurationHelper::GetSequenceClassID( SO3_SDRAW_OLE_EMBED_CLASSID_8
) ) )
91 return MimeConfigurationHelper::GetSequenceClassID( SO3_SDRAW_CLASSID_60
);
94 if ( MimeConfigurationHelper::ClassIDsEqual( aClassID
, MimeConfigurationHelper::GetSequenceClassID( SO3_SCH_OLE_EMBED_CLASSID_60
) )
95 || MimeConfigurationHelper::ClassIDsEqual( aClassID
, MimeConfigurationHelper::GetSequenceClassID( SO3_SCH_OLE_EMBED_CLASSID_8
) ) )
96 return MimeConfigurationHelper::GetSequenceClassID( SO3_SCH_CLASSID_60
);
99 if ( MimeConfigurationHelper::ClassIDsEqual( aClassID
, MimeConfigurationHelper::GetSequenceClassID( SO3_SM_OLE_EMBED_CLASSID_60
) )
100 || MimeConfigurationHelper::ClassIDsEqual( aClassID
, MimeConfigurationHelper::GetSequenceClassID( SO3_SM_OLE_EMBED_CLASSID_8
) ) )
101 return MimeConfigurationHelper::GetSequenceClassID( SO3_SM_CLASSID_60
);
107 uno::Sequence
< OUString
> SAL_CALL
MSOLEDialogObjectCreator::impl_staticGetSupportedServiceNames()
109 uno::Sequence
< OUString
> aRet(2);
110 aRet
[0] = "com.sun.star.embed.MSOLEObjectSystemCreator";
111 aRet
[1] = "com.sun.star.comp.embed.MSOLEObjectSystemCreator";
116 OUString SAL_CALL
MSOLEDialogObjectCreator::impl_staticGetImplementationName()
118 return OUString("com.sun.star.comp.embed.MSOLEObjectSystemCreator");
122 uno::Reference
< uno::XInterface
> SAL_CALL
MSOLEDialogObjectCreator::impl_staticCreateSelfInstance(
123 const uno::Reference
< lang::XMultiServiceFactory
>& xServiceManager
)
125 return uno::Reference
< uno::XInterface
>( *new MSOLEDialogObjectCreator( xServiceManager
) );
129 embed::InsertedObjectInfo SAL_CALL
MSOLEDialogObjectCreator::createInstanceByDialog(
130 const uno::Reference
< embed::XStorage
>& xStorage
,
131 const OUString
& sEntName
,
132 const uno::Sequence
< beans::PropertyValue
>& aInObjArgs
)
133 throw ( lang::IllegalArgumentException
,
136 uno::RuntimeException
)
138 embed::InsertedObjectInfo aObjectInfo
;
139 uno::Sequence
< beans::PropertyValue
> aObjArgs( aInObjArgs
);
143 if ( !xStorage
.is() )
144 throw lang::IllegalArgumentException( "No parent storage is provided!",
145 static_cast< ::cppu::OWeakObject
* >(this),
148 if ( !sEntName
.getLength() )
149 throw lang::IllegalArgumentException( "Empty element name is provided!",
150 static_cast< ::cppu::OWeakObject
* >(this),
153 InitializedOleGuard aGuard
;
155 OLEUIINSERTOBJECT io
;
156 char szFile
[MAX_PATH
];
159 memset(&io
, 0, sizeof(io
));
161 io
.cbStruct
= sizeof(io
);
162 io
.hWndOwner
= GetActiveWindow();
165 io
.lpszFile
= szFile
;
166 io
.cchFile
= MAX_PATH
;
168 io
.dwFlags
= IOF_SELECTCREATENEW
| IOF_DISABLELINK
;
171 ::osl::Module aOleDlgLib
;
172 if( !aOleDlgLib
.load( "oledlg" ))
173 throw uno::RuntimeException();
175 OleUIInsertObjectA_Type
* pInsertFct
= reinterpret_cast<OleUIInsertObjectA_Type
*>(
176 aOleDlgLib
.getSymbol( "OleUIInsertObjectA" ));
178 throw uno::RuntimeException();
180 uTemp
=pInsertFct(&io
);
182 if ( OLEUI_OK
== uTemp
)
184 if (io
.dwFlags
& IOF_SELECTCREATENEW
)
186 uno::Reference
< embed::XEmbeddedObjectCreator
> xEmbCreator
= embed::EmbeddedObjectCreator::create( comphelper::getComponentContext(m_xFactory
) );
188 uno::Sequence
< sal_Int8
> aClassID
= MimeConfigurationHelper::GetSequenceClassID( io
.clsid
.Data1
,
200 aClassID
= GetRelatedInternalID_Impl( aClassID
);
202 //TODO: retrieve ClassName
204 aObjectInfo
.Object
.set( xEmbCreator
->createInstanceInitNew( aClassID
, aClassName
, xStorage
, sEntName
, aObjArgs
),
209 OUString aFileName
= OStringToOUString( OString( szFile
), osl_getThreadTextEncoding() );
211 if ( osl::FileBase::getFileURLFromSystemPath( aFileName
, aFileURL
) != osl::FileBase::E_None
)
212 throw uno::RuntimeException();
214 uno::Sequence
< beans::PropertyValue
> aMediaDescr( 1 );
215 aMediaDescr
[0].Name
= "URL";
216 aMediaDescr
[0].Value
<<= aFileURL
;
218 // TODO: use config helper for type detection
219 uno::Reference
< embed::XEmbeddedObjectCreator
> xEmbCreator
;
220 ::comphelper::MimeConfigurationHelper
aHelper( comphelper::getComponentContext(m_xFactory
) );
222 if ( aHelper
.AddFilterNameCheckOwnFile( aMediaDescr
) )
223 xEmbCreator
= embed::EmbeddedObjectCreator::create( comphelper::getComponentContext(m_xFactory
) );
225 xEmbCreator
= embed::OLEEmbeddedObjectFactory::create( comphelper::getComponentContext(m_xFactory
) );
227 if ( !xEmbCreator
.is() )
228 throw uno::RuntimeException();
230 aObjectInfo
.Object
.set( xEmbCreator
->createInstanceInitFromMediaDescriptor( xStorage
, sEntName
, aMediaDescr
, aObjArgs
),
234 if ( ( io
.dwFlags
& IOF_CHECKDISPLAYASICON
) && io
.hMetaPict
!= nullptr )
236 METAFILEPICT
* pMF
= static_cast<METAFILEPICT
*>(GlobalLock( io
.hMetaPict
));
239 sal_uInt32 nBufSize
= GetMetaFileBitsEx( pMF
->hMF
, 0, nullptr );
240 uno::Sequence
< sal_Int8
> aMetafile( nBufSize
+ 22 );
241 sal_Int8
* pBuf
= aMetafile
.getArray();
242 *reinterpret_cast<long*>( pBuf
) = 0x9ac6cdd7L
;
243 *reinterpret_cast<short*>( pBuf
+6 ) = ( SHORT
) 0;
244 *reinterpret_cast<short*>( pBuf
+8 ) = ( SHORT
) 0;
245 *reinterpret_cast<short*>( pBuf
+10 ) = ( SHORT
) pMF
->xExt
;
246 *reinterpret_cast<short*>( pBuf
+12 ) = ( SHORT
) pMF
->yExt
;
247 *reinterpret_cast<short*>( pBuf
+14 ) = ( USHORT
) 2540;
249 if ( nBufSize
&& nBufSize
== GetMetaFileBitsEx( pMF
->hMF
, nBufSize
, pBuf
+22 ) )
251 datatransfer::DataFlavor
aFlavor(
252 OUString( "application/x-openoffice-wmf;windows_formatname=\"Image WMF\"" ),
253 OUString( "Image WMF" ),
254 cppu::UnoType
<uno::Sequence
< sal_Int8
>>::get() );
256 aObjectInfo
.Options
.realloc( 2 );
257 aObjectInfo
.Options
[0].Name
= "Icon";
258 aObjectInfo
.Options
[0].Value
<<= aMetafile
;
259 aObjectInfo
.Options
[1].Name
= "IconFormat";
260 aObjectInfo
.Options
[1].Value
<<= aFlavor
;
263 GlobalUnlock( io
.hMetaPict
);
268 throw ucb::CommandAbortedException();
270 OSL_ENSURE( aObjectInfo
.Object
.is(), "No object was created!\n" );
271 if ( !aObjectInfo
.Object
.is() )
272 throw uno::RuntimeException();
276 throw lang::NoSupportException(); // TODO:
281 embed::InsertedObjectInfo SAL_CALL
MSOLEDialogObjectCreator::createInstanceInitFromClipboard(
282 const uno::Reference
< embed::XStorage
>& xStorage
,
283 const OUString
& sEntryName
,
284 const uno::Sequence
< beans::PropertyValue
>& aObjectArgs
)
285 throw ( lang::IllegalArgumentException
,
288 uno::RuntimeException
)
290 embed::InsertedObjectInfo aObjectInfo
;
293 if ( !xStorage
.is() )
294 throw lang::IllegalArgumentException( "No parent storage is provided!",
295 static_cast< ::cppu::OWeakObject
* >(this),
298 if ( !sEntryName
.getLength() )
299 throw lang::IllegalArgumentException( "Empty element name is provided!",
300 static_cast< ::cppu::OWeakObject
* >(this),
303 uno::Reference
< embed::XEmbeddedObject
> xResult(
304 static_cast< ::cppu::OWeakObject
* > ( new OleEmbeddedObject( m_xFactory
) ),
307 uno::Reference
< embed::XEmbedPersist
> xPersist( xResult
, uno::UNO_QUERY
);
309 if ( !xPersist
.is() )
310 throw uno::RuntimeException(); // TODO: the interface must be supported by own document objects
312 xPersist
->setPersistentEntry( xStorage
,
314 embed::EntryInitModes::DEFAULT_INIT
,
315 uno::Sequence
< beans::PropertyValue
>(),
318 aObjectInfo
.Object
= xResult
;
320 // TODO/LATER: in case of iconify object the icon should be stored in aObjectInfo
322 OSL_ENSURE( aObjectInfo
.Object
.is(), "No object was created!\n" );
323 if ( !aObjectInfo
.Object
.is() )
324 throw uno::RuntimeException();
328 throw lang::NoSupportException(); // TODO:
333 OUString SAL_CALL
MSOLEDialogObjectCreator::getImplementationName()
334 throw ( uno::RuntimeException
)
336 return impl_staticGetImplementationName();
340 sal_Bool SAL_CALL
MSOLEDialogObjectCreator::supportsService( const OUString
& ServiceName
)
341 throw ( uno::RuntimeException
)
343 return cppu::supportsService(this, ServiceName
);
347 uno::Sequence
< OUString
> SAL_CALL
MSOLEDialogObjectCreator::getSupportedServiceNames()
348 throw ( uno::RuntimeException
)
350 return impl_staticGetSupportedServiceNames();
353 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */