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