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