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 31 #include <commonembobj.hxx> 32 #include <com/sun/star/embed/EmbedStates.hpp> 33 #include <com/sun/star/embed/EmbedVerbs.hpp> 34 #include <com/sun/star/embed/XStorage.hpp> 35 #include <com/sun/star/embed/EmbedUpdateModes.hpp> 36 #include <com/sun/star/embed/XInplaceClient.hpp> 37 #include <com/sun/star/lang/DisposedException.hpp> 38 #include <com/sun/star/beans/NamedValue.hpp> 39 40 #include <cppuhelper/typeprovider.hxx> 41 #include <cppuhelper/interfacecontainer.h> 42 #include <comphelper/mimeconfighelper.hxx> 43 44 #include "closepreventer.hxx" 45 #include "intercept.hxx" 46 47 using namespace ::com::sun::star; 48 49 50 uno::Sequence< beans::PropertyValue > GetValuableArgs_Impl( const uno::Sequence< beans::PropertyValue >& aMedDescr, 51 sal_Bool bCanUseDocumentBaseURL ); 52 53 //------------------------------------------------------ 54 OCommonEmbeddedObject::OCommonEmbeddedObject( const uno::Reference< lang::XMultiServiceFactory >& xFactory, 55 const uno::Sequence< beans::NamedValue >& aObjProps ) 56 : m_pDocHolder( NULL ) 57 , m_pInterfaceContainer( NULL ) 58 , m_bReadOnly( sal_False ) 59 , m_bDisposed( sal_False ) 60 , m_bClosed( sal_False ) 61 , m_nObjectState( -1 ) 62 , m_nTargetState( -1 ) 63 , m_nUpdateMode ( embed::EmbedUpdateModes::ALWAYS_UPDATE ) 64 , m_xFactory( xFactory ) 65 , m_nMiscStatus( 0 ) 66 , m_bEmbeddedScriptSupport( sal_True ) 67 , m_bDocumentRecoverySupport( sal_True ) 68 , m_bWaitSaveCompleted( sal_False ) 69 , m_bIsLink( sal_False ) 70 , m_bLinkHasPassword( sal_False ) 71 , m_bHasClonedSize( sal_False ) 72 , m_nClonedMapUnit( 0 ) 73 { 74 CommonInit_Impl( aObjProps ); 75 } 76 77 //------------------------------------------------------ 78 OCommonEmbeddedObject::OCommonEmbeddedObject( 79 const uno::Reference< lang::XMultiServiceFactory >& xFactory, 80 const uno::Sequence< beans::NamedValue >& aObjProps, 81 const uno::Sequence< beans::PropertyValue >& aMediaDescr, 82 const uno::Sequence< beans::PropertyValue >& aObjectDescr ) 83 : m_pDocHolder( NULL ) 84 , m_pInterfaceContainer( NULL ) 85 , m_bReadOnly( sal_False ) 86 , m_bDisposed( sal_False ) 87 , m_bClosed( sal_False ) 88 , m_nObjectState( embed::EmbedStates::LOADED ) 89 , m_nTargetState( -1 ) 90 , m_nUpdateMode ( embed::EmbedUpdateModes::ALWAYS_UPDATE ) 91 , m_xFactory( xFactory ) 92 , m_nMiscStatus( 0 ) 93 , m_bEmbeddedScriptSupport( sal_True ) 94 , m_bDocumentRecoverySupport( sal_True ) 95 , m_bWaitSaveCompleted( sal_False ) 96 , m_bIsLink( sal_True ) 97 , m_bLinkHasPassword( sal_False ) 98 , m_bHasClonedSize( sal_False ) 99 , m_nClonedMapUnit( 0 ) 100 { 101 // linked object has no own persistence so it is in loaded state starting from creation 102 LinkInit_Impl( aObjProps, aMediaDescr, aObjectDescr ); 103 } 104 105 //------------------------------------------------------ 106 void OCommonEmbeddedObject::CommonInit_Impl( const uno::Sequence< beans::NamedValue >& aObjectProps ) 107 { 108 OSL_ENSURE( m_xFactory.is(), "No ServiceFactory is provided!\n" ); 109 if ( !m_xFactory.is() ) 110 throw uno::RuntimeException(); 111 112 m_pDocHolder = new DocumentHolder( m_xFactory, this ); 113 m_pDocHolder->acquire(); 114 115 // parse configuration entries 116 // TODO/LATER: in future UI names can be also provided here 117 for ( sal_Int32 nInd = 0; nInd < aObjectProps.getLength(); nInd++ ) 118 { 119 if ( aObjectProps[nInd].Name.equalsAscii( "ClassID" ) ) 120 aObjectProps[nInd].Value >>= m_aClassID; 121 else if ( aObjectProps[nInd].Name.equalsAscii( "ObjectDocumentServiceName" ) ) 122 aObjectProps[nInd].Value >>= m_aDocServiceName; 123 else if ( aObjectProps[nInd].Name.equalsAscii( "ObjectDocumentFilterName" ) ) 124 aObjectProps[nInd].Value >>= m_aPresetFilterName; 125 else if ( aObjectProps[nInd].Name.equalsAscii( "ObjectMiscStatus" ) ) 126 aObjectProps[nInd].Value >>= m_nMiscStatus; 127 else if ( aObjectProps[nInd].Name.equalsAscii( "ObjectVerbs" ) ) 128 aObjectProps[nInd].Value >>= m_aObjectVerbs; 129 } 130 131 if ( m_aClassID.getLength() != 16 /*|| !m_aDocServiceName.getLength()*/ ) 132 throw uno::RuntimeException(); // something goes really wrong 133 134 // accepted states 135 m_aAcceptedStates.realloc( NUM_SUPPORTED_STATES ); 136 137 m_aAcceptedStates[0] = embed::EmbedStates::LOADED; 138 m_aAcceptedStates[1] = embed::EmbedStates::RUNNING; 139 m_aAcceptedStates[2] = embed::EmbedStates::INPLACE_ACTIVE; 140 m_aAcceptedStates[3] = embed::EmbedStates::UI_ACTIVE; 141 m_aAcceptedStates[4] = embed::EmbedStates::ACTIVE; 142 143 144 // intermediate states 145 // In the following table the first index points to starting state, 146 // the second one to the target state, and the sequence referenced by 147 // first two indexes contains intermediate states, that should be 148 // passed by object to reach the target state. 149 // If the sequence is empty that means that indirect switch from start 150 // state to the target state is forbidden, only if direct switch is possible 151 // the state can be reached. 152 153 m_pIntermediateStatesSeqs[0][2].realloc( 1 ); 154 m_pIntermediateStatesSeqs[0][2][0] = embed::EmbedStates::RUNNING; 155 156 m_pIntermediateStatesSeqs[0][3].realloc( 2 ); 157 m_pIntermediateStatesSeqs[0][3][0] = embed::EmbedStates::RUNNING; 158 m_pIntermediateStatesSeqs[0][3][1] = embed::EmbedStates::INPLACE_ACTIVE; 159 160 m_pIntermediateStatesSeqs[0][4].realloc( 1 ); 161 m_pIntermediateStatesSeqs[0][4][0] = embed::EmbedStates::RUNNING; 162 163 m_pIntermediateStatesSeqs[1][3].realloc( 1 ); 164 m_pIntermediateStatesSeqs[1][3][0] = embed::EmbedStates::INPLACE_ACTIVE; 165 166 m_pIntermediateStatesSeqs[2][0].realloc( 1 ); 167 m_pIntermediateStatesSeqs[2][0][0] = embed::EmbedStates::RUNNING; 168 169 m_pIntermediateStatesSeqs[3][0].realloc( 2 ); 170 m_pIntermediateStatesSeqs[3][0][0] = embed::EmbedStates::INPLACE_ACTIVE; 171 m_pIntermediateStatesSeqs[3][0][1] = embed::EmbedStates::RUNNING; 172 173 m_pIntermediateStatesSeqs[3][1].realloc( 1 ); 174 m_pIntermediateStatesSeqs[3][1][0] = embed::EmbedStates::INPLACE_ACTIVE; 175 176 m_pIntermediateStatesSeqs[4][0].realloc( 1 ); 177 m_pIntermediateStatesSeqs[4][0][0] = embed::EmbedStates::RUNNING; 178 179 // verbs table 180 sal_Int32 nVerbTableSize = 0; 181 for ( sal_Int32 nVerbInd = 0; nVerbInd < m_aObjectVerbs.getLength(); nVerbInd++ ) 182 { 183 if ( m_aObjectVerbs[nVerbInd].VerbID == embed::EmbedVerbs::MS_OLEVERB_PRIMARY ) 184 { 185 m_aVerbTable.realloc( ++nVerbTableSize ); 186 m_aVerbTable[nVerbTableSize - 1].realloc( 2 ); 187 m_aVerbTable[nVerbTableSize - 1][0] = m_aObjectVerbs[nVerbInd].VerbID; 188 m_aVerbTable[nVerbTableSize - 1][1] = embed::EmbedStates::UI_ACTIVE; 189 } 190 else if ( m_aObjectVerbs[nVerbInd].VerbID == embed::EmbedVerbs::MS_OLEVERB_SHOW ) 191 { 192 m_aVerbTable.realloc( ++nVerbTableSize ); 193 m_aVerbTable[nVerbTableSize - 1].realloc( 2 ); 194 m_aVerbTable[nVerbTableSize - 1][0] = m_aObjectVerbs[nVerbInd].VerbID; 195 m_aVerbTable[nVerbTableSize - 1][1] = embed::EmbedStates::UI_ACTIVE; 196 } 197 else if ( m_aObjectVerbs[nVerbInd].VerbID == embed::EmbedVerbs::MS_OLEVERB_OPEN ) 198 { 199 m_aVerbTable.realloc( ++nVerbTableSize ); 200 m_aVerbTable[nVerbTableSize - 1].realloc( 2 ); 201 m_aVerbTable[nVerbTableSize - 1][0] = m_aObjectVerbs[nVerbInd].VerbID; 202 m_aVerbTable[nVerbTableSize - 1][1] = embed::EmbedStates::ACTIVE; 203 } 204 else if ( m_aObjectVerbs[nVerbInd].VerbID == embed::EmbedVerbs::MS_OLEVERB_IPACTIVATE ) 205 { 206 m_aVerbTable.realloc( ++nVerbTableSize ); 207 m_aVerbTable[nVerbTableSize - 1].realloc( 2 ); 208 m_aVerbTable[nVerbTableSize - 1][0] = m_aObjectVerbs[nVerbInd].VerbID; 209 m_aVerbTable[nVerbTableSize - 1][1] = embed::EmbedStates::INPLACE_ACTIVE; 210 } 211 else if ( m_aObjectVerbs[nVerbInd].VerbID == embed::EmbedVerbs::MS_OLEVERB_UIACTIVATE ) 212 { 213 m_aVerbTable.realloc( ++nVerbTableSize ); 214 m_aVerbTable[nVerbTableSize - 1].realloc( 2 ); 215 m_aVerbTable[nVerbTableSize - 1][0] = m_aObjectVerbs[nVerbInd].VerbID; 216 m_aVerbTable[nVerbTableSize - 1][1] = embed::EmbedStates::UI_ACTIVE; 217 } 218 else if ( m_aObjectVerbs[nVerbInd].VerbID == embed::EmbedVerbs::MS_OLEVERB_HIDE ) 219 { 220 m_aVerbTable.realloc( ++nVerbTableSize ); 221 m_aVerbTable[nVerbTableSize - 1].realloc( 2 ); 222 m_aVerbTable[nVerbTableSize - 1][0] = m_aObjectVerbs[nVerbInd].VerbID; 223 m_aVerbTable[nVerbTableSize - 1][1] = embed::EmbedStates::RUNNING; 224 } 225 } 226 } 227 228 //------------------------------------------------------ 229 void OCommonEmbeddedObject::LinkInit_Impl( 230 const uno::Sequence< beans::NamedValue >& aObjectProps, 231 const uno::Sequence< beans::PropertyValue >& aMediaDescr, 232 const uno::Sequence< beans::PropertyValue >& aObjectDescr ) 233 { 234 // setPersistance has no effect on own links, so the complete initialization must be done here 235 236 for ( sal_Int32 nInd = 0; nInd < aMediaDescr.getLength(); nInd++ ) 237 if ( aMediaDescr[nInd].Name.equalsAscii( "URL" ) ) 238 aMediaDescr[nInd].Value >>= m_aLinkURL; 239 else if ( aMediaDescr[nInd].Name.equalsAscii( "FilterName" ) ) 240 aMediaDescr[nInd].Value >>= m_aLinkFilterName; 241 242 OSL_ENSURE( m_aLinkURL.getLength() && m_aLinkFilterName.getLength(), "Filter and URL must be provided!\n" ); 243 244 m_bReadOnly = sal_True; 245 if ( m_aLinkFilterName.getLength() ) 246 { 247 ::comphelper::MimeConfigurationHelper aHelper( m_xFactory ); 248 ::rtl::OUString aExportFilterName = aHelper.GetExportFilterFromImportFilter( m_aLinkFilterName ); 249 m_bReadOnly = !( aExportFilterName.equals( m_aLinkFilterName ) ); 250 } 251 252 m_aDocMediaDescriptor = GetValuableArgs_Impl( aMediaDescr, sal_False ); 253 254 uno::Reference< frame::XDispatchProviderInterceptor > xDispatchInterceptor; 255 for ( sal_Int32 nObjInd = 0; nObjInd < aObjectDescr.getLength(); nObjInd++ ) 256 if ( aObjectDescr[nObjInd].Name.equalsAscii( "OutplaceDispatchInterceptor" ) ) 257 { 258 aObjectDescr[nObjInd].Value >>= xDispatchInterceptor; 259 break; 260 } 261 else if ( aObjectDescr[nObjInd].Name.equalsAscii( "Parent" ) ) 262 { 263 aObjectDescr[nObjInd].Value >>= m_xParent; 264 } 265 266 CommonInit_Impl( aObjectProps ); 267 268 if ( xDispatchInterceptor.is() ) 269 m_pDocHolder->SetOutplaceDispatchInterceptor( xDispatchInterceptor ); 270 } 271 272 //------------------------------------------------------ 273 OCommonEmbeddedObject::~OCommonEmbeddedObject() 274 { 275 if ( m_pInterfaceContainer || m_pDocHolder ) 276 { 277 m_refCount++; 278 try { 279 lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >( this ) ); 280 281 if ( m_pInterfaceContainer ) 282 { 283 m_pInterfaceContainer->disposeAndClear( aSource ); 284 285 delete m_pInterfaceContainer; 286 m_pInterfaceContainer = NULL; 287 } 288 } catch( uno::Exception& ) {} 289 290 try { 291 if ( m_pDocHolder ) 292 { 293 m_pDocHolder->CloseFrame(); 294 try { 295 m_pDocHolder->CloseDocument( sal_True, sal_True ); 296 } catch ( uno::Exception& ) {} 297 m_pDocHolder->FreeOffice(); 298 299 m_pDocHolder->release(); 300 m_pDocHolder = NULL; 301 } 302 } catch( uno::Exception& ) {} 303 } 304 } 305 306 //------------------------------------------------------ 307 void OCommonEmbeddedObject::requestPositioning( const awt::Rectangle& aRect ) 308 { 309 // the method is called in case object is inplace active and the object window was resized 310 311 OSL_ENSURE( m_xClientSite.is(), "The client site must be set for inplace active object!\n" ); 312 if ( m_xClientSite.is() ) 313 { 314 uno::Reference< embed::XInplaceClient > xInplaceClient( m_xClientSite, uno::UNO_QUERY ); 315 316 OSL_ENSURE( xInplaceClient.is(), "The client site must support XInplaceClient to allow inplace activation!\n" ); 317 if ( xInplaceClient.is() ) 318 { 319 try { 320 xInplaceClient->changedPlacement( aRect ); 321 } 322 catch( uno::Exception& ) 323 { 324 OSL_ENSURE( sal_False, "Exception on request to resize!\n" ); 325 } 326 } 327 } 328 } 329 330 //------------------------------------------------------ 331 void OCommonEmbeddedObject::PostEvent_Impl( const ::rtl::OUString& aEventName, 332 const uno::Reference< uno::XInterface >& /*xSource*/ ) 333 { 334 if ( m_pInterfaceContainer ) 335 { 336 ::cppu::OInterfaceContainerHelper* pIC = m_pInterfaceContainer->getContainer( 337 ::getCppuType((const uno::Reference< document::XEventListener >*)0) ); 338 if( pIC ) 339 { 340 document::EventObject aEvent; 341 aEvent.EventName = aEventName; 342 aEvent.Source = uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >( this ) ); 343 // For now all the events are sent as object events 344 // aEvent.Source = ( xSource.is() ? xSource 345 // : uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >( this ) ) ); 346 ::cppu::OInterfaceIteratorHelper aIt( *pIC ); 347 while( aIt.hasMoreElements() ) 348 { 349 try 350 { 351 ((document::XEventListener *)aIt.next())->notifyEvent( aEvent ); 352 } 353 catch( uno::RuntimeException& ) 354 { 355 aIt.remove(); 356 } 357 358 // the listener could dispose the object. 359 if ( m_bDisposed ) 360 return; 361 } 362 } 363 } 364 } 365 366 //------------------------------------------------------ 367 uno::Any SAL_CALL OCommonEmbeddedObject::queryInterface( const uno::Type& rType ) 368 throw( uno::RuntimeException ) 369 { 370 uno::Any aReturn; 371 372 if ( rType == ::getCppuType( (uno::Reference< embed::XEmbeddedObject > const *)0 )) 373 { 374 void * p = static_cast< embed::XEmbeddedObject * >( this ); 375 return uno::Any( &p, rType ); 376 } 377 else 378 aReturn <<= ::cppu::queryInterface( 379 rType, 380 static_cast< embed::XInplaceObject* >( this ), 381 static_cast< embed::XVisualObject* >( this ), 382 static_cast< embed::XCommonEmbedPersist* >( static_cast< embed::XEmbedPersist* >( this ) ), 383 static_cast< embed::XEmbedPersist* >( this ), 384 static_cast< embed::XLinkageSupport* >( this ), 385 static_cast< embed::XStateChangeBroadcaster* >( this ), 386 static_cast< embed::XClassifiedObject* >( this ), 387 static_cast< embed::XComponentSupplier* >( this ), 388 static_cast< util::XCloseable* >( this ), 389 static_cast< container::XChild* >( this ), 390 static_cast< chart2::XDefaultSizeTransmitter* >( this ), 391 static_cast< document::XEventBroadcaster* >( this ) ); 392 393 if ( aReturn.hasValue() ) 394 return aReturn; 395 else 396 return ::cppu::OWeakObject::queryInterface( rType ) ; 397 398 } 399 400 //------------------------------------------------------ 401 void SAL_CALL OCommonEmbeddedObject::acquire() 402 throw() 403 { 404 ::cppu::OWeakObject::acquire() ; 405 } 406 407 //------------------------------------------------------ 408 void SAL_CALL OCommonEmbeddedObject::release() 409 throw() 410 { 411 ::cppu::OWeakObject::release() ; 412 } 413 414 //------------------------------------------------------ 415 uno::Sequence< uno::Type > SAL_CALL OCommonEmbeddedObject::getTypes() 416 throw( uno::RuntimeException ) 417 { 418 static ::cppu::OTypeCollection* pTypeCollection = NULL; 419 420 if ( !pTypeCollection ) 421 { 422 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); 423 if ( !pTypeCollection ) 424 { 425 if ( m_bIsLink ) 426 { 427 static ::cppu::OTypeCollection aTypeCollection( 428 ::getCppuType( (const uno::Reference< lang::XTypeProvider >*)NULL ), 429 ::getCppuType( (const uno::Reference< embed::XEmbeddedObject >*)NULL ), 430 ::getCppuType( (const uno::Reference< embed::XInplaceObject >*)NULL ), 431 ::getCppuType( (const uno::Reference< embed::XCommonEmbedPersist >*)NULL ), 432 ::getCppuType( (const uno::Reference< container::XChild >*)NULL ), 433 ::getCppuType( (const uno::Reference< embed::XLinkageSupport >*)NULL ) ); 434 435 pTypeCollection = &aTypeCollection ; 436 } 437 else 438 { 439 static ::cppu::OTypeCollection aTypeCollection( 440 ::getCppuType( (const uno::Reference< lang::XTypeProvider >*)NULL ), 441 ::getCppuType( (const uno::Reference< embed::XEmbeddedObject >*)NULL ), 442 ::getCppuType( (const uno::Reference< embed::XInplaceObject >*)NULL ), 443 ::getCppuType( (const uno::Reference< embed::XCommonEmbedPersist >*)NULL ), 444 ::getCppuType( (const uno::Reference< container::XChild >*)NULL ), 445 ::getCppuType( (const uno::Reference< embed::XEmbedPersist >*)NULL ) ); 446 447 pTypeCollection = &aTypeCollection ; 448 } 449 } 450 } 451 452 return pTypeCollection->getTypes() ; 453 454 } 455 456 //------------------------------------------------------ 457 uno::Sequence< sal_Int8 > SAL_CALL OCommonEmbeddedObject::getImplementationId() 458 throw( uno::RuntimeException ) 459 { 460 static ::cppu::OImplementationId* pID = NULL ; 461 462 if ( !pID ) 463 { 464 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ) ; 465 if ( !pID ) 466 { 467 static ::cppu::OImplementationId aID( sal_False ) ; 468 pID = &aID ; 469 } 470 } 471 472 return pID->getImplementationId() ; 473 } 474 475 //------------------------------------------------------ 476 uno::Sequence< sal_Int8 > SAL_CALL OCommonEmbeddedObject::getClassID() 477 throw ( uno::RuntimeException ) 478 { 479 if ( m_bDisposed ) 480 throw lang::DisposedException(); 481 482 return m_aClassID; 483 } 484 485 //------------------------------------------------------ 486 ::rtl::OUString SAL_CALL OCommonEmbeddedObject::getClassName() 487 throw ( uno::RuntimeException ) 488 { 489 if ( m_bDisposed ) 490 throw lang::DisposedException(); 491 492 return m_aClassName; 493 } 494 495 //------------------------------------------------------ 496 void SAL_CALL OCommonEmbeddedObject::setClassInfo( 497 const uno::Sequence< sal_Int8 >& /*aClassID*/, const ::rtl::OUString& /*aClassName*/ ) 498 throw ( lang::NoSupportException, 499 uno::RuntimeException ) 500 { 501 // the object class info can not be changed explicitly 502 throw lang::NoSupportException(); //TODO: 503 } 504 505 //------------------------------------------------------ 506 uno::Reference< util::XCloseable > SAL_CALL OCommonEmbeddedObject::getComponent() 507 throw ( uno::RuntimeException ) 508 { 509 ::osl::MutexGuard aGuard( m_aMutex ); 510 if ( m_bDisposed ) 511 throw lang::DisposedException(); // TODO 512 513 // add an exception 514 if ( m_nObjectState == -1 ) 515 { 516 // the object is still not loaded 517 throw uno::RuntimeException( ::rtl::OUString::createFromAscii( "Can't store object without persistence!\n" ), 518 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) ); 519 } 520 521 // if ( m_bWaitSaveCompleted ) 522 // throw embed::WrongStateException( 523 // ::rtl::OUString::createFromAscii( "The object waits for saveCompleted() call!\n" ), 524 // uno::Reference< uno::XInterface >( reinterpret_cast< ::cppu::OWeakObject* >(this) ) ); 525 526 return uno::Reference< util::XCloseable >( m_pDocHolder->GetComponent(), uno::UNO_QUERY ); 527 } 528 529 //---------------------------------------------- 530 void SAL_CALL OCommonEmbeddedObject::addStateChangeListener( const uno::Reference< embed::XStateChangeListener >& xListener ) 531 throw ( uno::RuntimeException ) 532 { 533 ::osl::MutexGuard aGuard( m_aMutex ); 534 if ( m_bDisposed ) 535 throw lang::DisposedException(); // TODO 536 537 if ( !m_pInterfaceContainer ) 538 m_pInterfaceContainer = new ::cppu::OMultiTypeInterfaceContainerHelper( m_aMutex ); 539 540 m_pInterfaceContainer->addInterface( ::getCppuType( (const uno::Reference< embed::XStateChangeListener >*)0 ), 541 xListener ); 542 } 543 544 //---------------------------------------------- 545 void SAL_CALL OCommonEmbeddedObject::removeStateChangeListener( 546 const uno::Reference< embed::XStateChangeListener >& xListener ) 547 throw (uno::RuntimeException) 548 { 549 ::osl::MutexGuard aGuard( m_aMutex ); 550 if ( m_pInterfaceContainer ) 551 m_pInterfaceContainer->removeInterface( ::getCppuType( (const uno::Reference< embed::XStateChangeListener >*)0 ), 552 xListener ); 553 } 554 555 //---------------------------------------------- 556 void SAL_CALL OCommonEmbeddedObject::close( sal_Bool bDeliverOwnership ) 557 throw ( util::CloseVetoException, 558 uno::RuntimeException ) 559 { 560 ::osl::MutexGuard aGuard( m_aMutex ); 561 if ( m_bClosed ) 562 throw lang::DisposedException(); // TODO 563 564 uno::Reference< uno::XInterface > xSelfHold( static_cast< ::cppu::OWeakObject* >( this ) ); 565 lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >( this ) ); 566 567 if ( m_pInterfaceContainer ) 568 { 569 ::cppu::OInterfaceContainerHelper* pContainer = 570 m_pInterfaceContainer->getContainer( ::getCppuType( ( const uno::Reference< util::XCloseListener >*) NULL ) ); 571 if ( pContainer != NULL ) 572 { 573 ::cppu::OInterfaceIteratorHelper pIterator(*pContainer); 574 while (pIterator.hasMoreElements()) 575 { 576 try 577 { 578 ((util::XCloseListener*)pIterator.next())->queryClosing( aSource, bDeliverOwnership ); 579 } 580 catch( uno::RuntimeException& ) 581 { 582 pIterator.remove(); 583 } 584 } 585 } 586 587 pContainer = m_pInterfaceContainer->getContainer( 588 ::getCppuType( ( const uno::Reference< util::XCloseListener >*) NULL ) ); 589 if ( pContainer != NULL ) 590 { 591 ::cppu::OInterfaceIteratorHelper pCloseIterator(*pContainer); 592 while (pCloseIterator.hasMoreElements()) 593 { 594 try 595 { 596 ((util::XCloseListener*)pCloseIterator.next())->notifyClosing( aSource ); 597 } 598 catch( uno::RuntimeException& ) 599 { 600 pCloseIterator.remove(); 601 } 602 } 603 } 604 605 m_pInterfaceContainer->disposeAndClear( aSource ); 606 } 607 608 m_bDisposed = sal_True; // the object is disposed now for outside 609 610 // it is possible that the document can not be closed, in this case if the argument is false 611 // the exception will be thrown otherwise in addition to exception the object must register itself 612 // as termination listener and listen for document events 613 614 if ( m_pDocHolder ) 615 { 616 m_pDocHolder->CloseFrame(); 617 618 try { 619 m_pDocHolder->CloseDocument( bDeliverOwnership, bDeliverOwnership ); 620 } 621 catch( uno::Exception& ) 622 { 623 if ( bDeliverOwnership ) 624 { 625 m_pDocHolder->release(); 626 m_pDocHolder = NULL; 627 m_bClosed = sal_True; 628 } 629 630 throw; 631 } 632 633 m_pDocHolder->FreeOffice(); 634 635 m_pDocHolder->release(); 636 m_pDocHolder = NULL; 637 } 638 639 // TODO: for now the storage will be disposed by the object, but after the document 640 // will use the storage, the storage will be disposed by the document and recreated by the object 641 if ( m_xObjectStorage.is() ) 642 { 643 uno::Reference< lang::XComponent > xComp( m_xObjectStorage, uno::UNO_QUERY ); 644 OSL_ENSURE( xComp.is(), "Storage does not support XComponent!\n" ); 645 646 if ( xComp.is() ) 647 { 648 try { 649 xComp->dispose(); 650 } catch ( uno::Exception& ) {} 651 } 652 653 m_xObjectStorage.clear(); 654 m_xRecoveryStorage.clear(); 655 } 656 657 m_bClosed = sal_True; // the closing succeeded 658 } 659 660 //---------------------------------------------- 661 void SAL_CALL OCommonEmbeddedObject::addCloseListener( const uno::Reference< util::XCloseListener >& xListener ) 662 throw ( uno::RuntimeException ) 663 { 664 ::osl::MutexGuard aGuard( m_aMutex ); 665 if ( m_bDisposed ) 666 throw lang::DisposedException(); // TODO 667 668 if ( !m_pInterfaceContainer ) 669 m_pInterfaceContainer = new ::cppu::OMultiTypeInterfaceContainerHelper( m_aMutex ); 670 671 m_pInterfaceContainer->addInterface( ::getCppuType( (const uno::Reference< util::XCloseListener >*)0 ), xListener ); 672 } 673 674 //---------------------------------------------- 675 void SAL_CALL OCommonEmbeddedObject::removeCloseListener( const uno::Reference< util::XCloseListener >& xListener ) 676 throw (uno::RuntimeException) 677 { 678 ::osl::MutexGuard aGuard( m_aMutex ); 679 if ( m_pInterfaceContainer ) 680 m_pInterfaceContainer->removeInterface( ::getCppuType( (const uno::Reference< util::XCloseListener >*)0 ), 681 xListener ); 682 } 683 684 //------------------------------------------------------ 685 void SAL_CALL OCommonEmbeddedObject::addEventListener( const uno::Reference< document::XEventListener >& xListener ) 686 throw ( uno::RuntimeException ) 687 { 688 ::osl::MutexGuard aGuard( m_aMutex ); 689 if ( m_bDisposed ) 690 throw lang::DisposedException(); // TODO 691 692 if ( !m_pInterfaceContainer ) 693 m_pInterfaceContainer = new ::cppu::OMultiTypeInterfaceContainerHelper( m_aMutex ); 694 695 m_pInterfaceContainer->addInterface( ::getCppuType( (const uno::Reference< document::XEventListener >*)0 ), xListener ); 696 } 697 698 //------------------------------------------------------ 699 void SAL_CALL OCommonEmbeddedObject::removeEventListener( const uno::Reference< document::XEventListener >& xListener ) 700 throw ( uno::RuntimeException ) 701 { 702 ::osl::MutexGuard aGuard( m_aMutex ); 703 if ( m_pInterfaceContainer ) 704 m_pInterfaceContainer->removeInterface( ::getCppuType( (const uno::Reference< document::XEventListener >*)0 ), 705 xListener ); 706 } 707 708