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: 57 InitializedOleGuard() 58 { 59 if ( !SUCCEEDED( OleInitialize( NULL ) ) ) 60 throw ::com::sun::star::uno::RuntimeException(); 61 } 62 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 //------------------------------------------------------------------------- 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 //------------------------------------------------------------------------- 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 //------------------------------------------------------------------------- 124 ::rtl::OUString SAL_CALL MSOLEDialogObjectCreator::impl_staticGetImplementationName() 125 { 126 return ::rtl::OUString::createFromAscii("com.sun.star.comp.embed.MSOLEObjectSystemCreator"); 127 } 128 129 //------------------------------------------------------------------------- 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 //------------------------------------------------------------------------- 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 //------------------------------------------------------------------------- 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 //------------------------------------------------------------------------- 356 ::rtl::OUString SAL_CALL MSOLEDialogObjectCreator::getImplementationName() 357 throw ( uno::RuntimeException ) 358 { 359 return impl_staticGetImplementationName(); 360 } 361 362 //------------------------------------------------------------------------- 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 //------------------------------------------------------------------------- 376 uno::Sequence< ::rtl::OUString > SAL_CALL MSOLEDialogObjectCreator::getSupportedServiceNames() 377 throw ( uno::RuntimeException ) 378 { 379 return impl_staticGetSupportedServiceNames(); 380 } 381 382