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 throw( uno::RuntimeException ) 365 { 366 uno::Any aReturn; 367 368 if ( rType == ::getCppuType( (uno::Reference< embed::XEmbeddedObject > const *)0 )) 369 { 370 void * p = static_cast< embed::XEmbeddedObject * >( this ); 371 return uno::Any( &p, rType ); 372 } 373 else 374 aReturn <<= ::cppu::queryInterface( 375 rType, 376 static_cast< embed::XInplaceObject* >( this ), 377 static_cast< embed::XVisualObject* >( this ), 378 static_cast< embed::XCommonEmbedPersist* >( static_cast< embed::XEmbedPersist* >( this ) ), 379 static_cast< embed::XEmbedPersist* >( this ), 380 static_cast< embed::XLinkageSupport* >( this ), 381 static_cast< embed::XStateChangeBroadcaster* >( this ), 382 static_cast< embed::XClassifiedObject* >( this ), 383 static_cast< embed::XComponentSupplier* >( this ), 384 static_cast< util::XCloseable* >( this ), 385 static_cast< container::XChild* >( this ), 386 static_cast< chart2::XDefaultSizeTransmitter* >( this ), 387 static_cast< document::XEventBroadcaster* >( this ) ); 388 389 if ( aReturn.hasValue() ) 390 return aReturn; 391 else 392 return ::cppu::OWeakObject::queryInterface( rType ) ; 393 394 } 395 396 //------------------------------------------------------ 397 void SAL_CALL OCommonEmbeddedObject::acquire() 398 throw() 399 { 400 ::cppu::OWeakObject::acquire() ; 401 } 402 403 //------------------------------------------------------ 404 void SAL_CALL OCommonEmbeddedObject::release() 405 throw() 406 { 407 ::cppu::OWeakObject::release() ; 408 } 409 410 //------------------------------------------------------ 411 uno::Sequence< uno::Type > SAL_CALL OCommonEmbeddedObject::getTypes() 412 throw( uno::RuntimeException ) 413 { 414 static ::cppu::OTypeCollection* pTypeCollection = NULL; 415 416 if ( !pTypeCollection ) 417 { 418 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); 419 if ( !pTypeCollection ) 420 { 421 if ( m_bIsLink ) 422 { 423 static ::cppu::OTypeCollection aTypeCollection( 424 ::getCppuType( (const uno::Reference< lang::XTypeProvider >*)NULL ), 425 ::getCppuType( (const uno::Reference< embed::XEmbeddedObject >*)NULL ), 426 ::getCppuType( (const uno::Reference< embed::XInplaceObject >*)NULL ), 427 ::getCppuType( (const uno::Reference< embed::XCommonEmbedPersist >*)NULL ), 428 ::getCppuType( (const uno::Reference< container::XChild >*)NULL ), 429 ::getCppuType( (const uno::Reference< embed::XLinkageSupport >*)NULL ) ); 430 431 pTypeCollection = &aTypeCollection ; 432 } 433 else 434 { 435 static ::cppu::OTypeCollection aTypeCollection( 436 ::getCppuType( (const uno::Reference< lang::XTypeProvider >*)NULL ), 437 ::getCppuType( (const uno::Reference< embed::XEmbeddedObject >*)NULL ), 438 ::getCppuType( (const uno::Reference< embed::XInplaceObject >*)NULL ), 439 ::getCppuType( (const uno::Reference< embed::XCommonEmbedPersist >*)NULL ), 440 ::getCppuType( (const uno::Reference< container::XChild >*)NULL ), 441 ::getCppuType( (const uno::Reference< embed::XEmbedPersist >*)NULL ) ); 442 443 pTypeCollection = &aTypeCollection ; 444 } 445 } 446 } 447 448 return pTypeCollection->getTypes() ; 449 450 } 451 452 //------------------------------------------------------ 453 uno::Sequence< sal_Int8 > SAL_CALL OCommonEmbeddedObject::getImplementationId() 454 throw( uno::RuntimeException ) 455 { 456 static ::cppu::OImplementationId* pID = NULL ; 457 458 if ( !pID ) 459 { 460 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ) ; 461 if ( !pID ) 462 { 463 static ::cppu::OImplementationId aID( sal_False ) ; 464 pID = &aID ; 465 } 466 } 467 468 return pID->getImplementationId() ; 469 } 470 471 //------------------------------------------------------ 472 uno::Sequence< sal_Int8 > SAL_CALL OCommonEmbeddedObject::getClassID() 473 throw ( uno::RuntimeException ) 474 { 475 if ( m_bDisposed ) 476 throw lang::DisposedException(); 477 478 return m_aClassID; 479 } 480 481 //------------------------------------------------------ 482 ::rtl::OUString SAL_CALL OCommonEmbeddedObject::getClassName() 483 throw ( uno::RuntimeException ) 484 { 485 if ( m_bDisposed ) 486 throw lang::DisposedException(); 487 488 return m_aClassName; 489 } 490 491 //------------------------------------------------------ 492 void SAL_CALL OCommonEmbeddedObject::setClassInfo( 493 const uno::Sequence< sal_Int8 >& /*aClassID*/, const ::rtl::OUString& /*aClassName*/ ) 494 throw ( lang::NoSupportException, 495 uno::RuntimeException ) 496 { 497 // the object class info can not be changed explicitly 498 throw lang::NoSupportException(); //TODO: 499 } 500 501 //------------------------------------------------------ 502 uno::Reference< util::XCloseable > SAL_CALL OCommonEmbeddedObject::getComponent() 503 throw ( uno::RuntimeException ) 504 { 505 ::osl::MutexGuard aGuard( m_aMutex ); 506 if ( m_bDisposed ) 507 throw lang::DisposedException(); // TODO 508 509 // add an exception 510 if ( m_nObjectState == -1 ) 511 { 512 // the object is still not loaded 513 throw uno::RuntimeException( ::rtl::OUString::createFromAscii( "Can't store object without persistence!\n" ), 514 uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) ); 515 } 516 517 // if ( m_bWaitSaveCompleted ) 518 // throw embed::WrongStateException( 519 // ::rtl::OUString::createFromAscii( "The object waits for saveCompleted() call!\n" ), 520 // uno::Reference< uno::XInterface >( reinterpret_cast< ::cppu::OWeakObject* >(this) ) ); 521 522 return uno::Reference< util::XCloseable >( m_pDocHolder->GetComponent(), uno::UNO_QUERY ); 523 } 524 525 //---------------------------------------------- 526 void SAL_CALL OCommonEmbeddedObject::addStateChangeListener( const uno::Reference< embed::XStateChangeListener >& xListener ) 527 throw ( uno::RuntimeException ) 528 { 529 ::osl::MutexGuard aGuard( m_aMutex ); 530 if ( m_bDisposed ) 531 throw lang::DisposedException(); // TODO 532 533 if ( !m_pInterfaceContainer ) 534 m_pInterfaceContainer = new ::cppu::OMultiTypeInterfaceContainerHelper( m_aMutex ); 535 536 m_pInterfaceContainer->addInterface( ::getCppuType( (const uno::Reference< embed::XStateChangeListener >*)0 ), 537 xListener ); 538 } 539 540 //---------------------------------------------- 541 void SAL_CALL OCommonEmbeddedObject::removeStateChangeListener( 542 const uno::Reference< embed::XStateChangeListener >& xListener ) 543 throw (uno::RuntimeException) 544 { 545 ::osl::MutexGuard aGuard( m_aMutex ); 546 if ( m_pInterfaceContainer ) 547 m_pInterfaceContainer->removeInterface( ::getCppuType( (const uno::Reference< embed::XStateChangeListener >*)0 ), 548 xListener ); 549 } 550 551 //---------------------------------------------- 552 void SAL_CALL OCommonEmbeddedObject::close( sal_Bool bDeliverOwnership ) 553 throw ( util::CloseVetoException, 554 uno::RuntimeException ) 555 { 556 ::osl::MutexGuard aGuard( m_aMutex ); 557 if ( m_bClosed ) 558 throw lang::DisposedException(); // TODO 559 560 uno::Reference< uno::XInterface > xSelfHold( static_cast< ::cppu::OWeakObject* >( this ) ); 561 lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >( this ) ); 562 563 if ( m_pInterfaceContainer ) 564 { 565 ::cppu::OInterfaceContainerHelper* pContainer = 566 m_pInterfaceContainer->getContainer( ::getCppuType( ( const uno::Reference< util::XCloseListener >*) NULL ) ); 567 if ( pContainer != NULL ) 568 { 569 ::cppu::OInterfaceIteratorHelper pIterator(*pContainer); 570 while (pIterator.hasMoreElements()) 571 { 572 try 573 { 574 ((util::XCloseListener*)pIterator.next())->queryClosing( aSource, bDeliverOwnership ); 575 } 576 catch( uno::RuntimeException& ) 577 { 578 pIterator.remove(); 579 } 580 } 581 } 582 583 pContainer = m_pInterfaceContainer->getContainer( 584 ::getCppuType( ( const uno::Reference< util::XCloseListener >*) NULL ) ); 585 if ( pContainer != NULL ) 586 { 587 ::cppu::OInterfaceIteratorHelper pCloseIterator(*pContainer); 588 while (pCloseIterator.hasMoreElements()) 589 { 590 try 591 { 592 ((util::XCloseListener*)pCloseIterator.next())->notifyClosing( aSource ); 593 } 594 catch( uno::RuntimeException& ) 595 { 596 pCloseIterator.remove(); 597 } 598 } 599 } 600 601 m_pInterfaceContainer->disposeAndClear( aSource ); 602 } 603 604 m_bDisposed = sal_True; // the object is disposed now for outside 605 606 // it is possible that the document can not be closed, in this case if the argument is false 607 // the exception will be thrown otherwise in addition to exception the object must register itself 608 // as termination listener and listen for document events 609 610 if ( m_pDocHolder ) 611 { 612 m_pDocHolder->CloseFrame(); 613 614 try { 615 m_pDocHolder->CloseDocument( bDeliverOwnership, bDeliverOwnership ); 616 } 617 catch( uno::Exception& ) 618 { 619 if ( bDeliverOwnership ) 620 { 621 m_pDocHolder->release(); 622 m_pDocHolder = NULL; 623 m_bClosed = sal_True; 624 } 625 626 throw; 627 } 628 629 m_pDocHolder->FreeOffice(); 630 631 m_pDocHolder->release(); 632 m_pDocHolder = NULL; 633 } 634 635 // TODO: for now the storage will be disposed by the object, but after the document 636 // will use the storage, the storage will be disposed by the document and recreated by the object 637 if ( m_xObjectStorage.is() ) 638 { 639 uno::Reference< lang::XComponent > xComp( m_xObjectStorage, uno::UNO_QUERY ); 640 OSL_ENSURE( xComp.is(), "Storage does not support XComponent!\n" ); 641 642 if ( xComp.is() ) 643 { 644 try { 645 xComp->dispose(); 646 } catch ( uno::Exception& ) {} 647 } 648 649 m_xObjectStorage.clear(); 650 m_xRecoveryStorage.clear(); 651 } 652 653 m_bClosed = sal_True; // the closing succeeded 654 } 655 656 //---------------------------------------------- 657 void SAL_CALL OCommonEmbeddedObject::addCloseListener( const uno::Reference< util::XCloseListener >& xListener ) 658 throw ( uno::RuntimeException ) 659 { 660 ::osl::MutexGuard aGuard( m_aMutex ); 661 if ( m_bDisposed ) 662 throw lang::DisposedException(); // TODO 663 664 if ( !m_pInterfaceContainer ) 665 m_pInterfaceContainer = new ::cppu::OMultiTypeInterfaceContainerHelper( m_aMutex ); 666 667 m_pInterfaceContainer->addInterface( ::getCppuType( (const uno::Reference< util::XCloseListener >*)0 ), xListener ); 668 } 669 670 //---------------------------------------------- 671 void SAL_CALL OCommonEmbeddedObject::removeCloseListener( const uno::Reference< util::XCloseListener >& xListener ) 672 throw (uno::RuntimeException) 673 { 674 ::osl::MutexGuard aGuard( m_aMutex ); 675 if ( m_pInterfaceContainer ) 676 m_pInterfaceContainer->removeInterface( ::getCppuType( (const uno::Reference< util::XCloseListener >*)0 ), 677 xListener ); 678 } 679 680 //------------------------------------------------------ 681 void SAL_CALL OCommonEmbeddedObject::addEventListener( const uno::Reference< document::XEventListener >& xListener ) 682 throw ( uno::RuntimeException ) 683 { 684 ::osl::MutexGuard aGuard( m_aMutex ); 685 if ( m_bDisposed ) 686 throw lang::DisposedException(); // TODO 687 688 if ( !m_pInterfaceContainer ) 689 m_pInterfaceContainer = new ::cppu::OMultiTypeInterfaceContainerHelper( m_aMutex ); 690 691 m_pInterfaceContainer->addInterface( ::getCppuType( (const uno::Reference< document::XEventListener >*)0 ), xListener ); 692 } 693 694 //------------------------------------------------------ 695 void SAL_CALL OCommonEmbeddedObject::removeEventListener( const uno::Reference< document::XEventListener >& xListener ) 696 throw ( uno::RuntimeException ) 697 { 698 ::osl::MutexGuard aGuard( m_aMutex ); 699 if ( m_pInterfaceContainer ) 700 m_pInterfaceContainer->removeInterface( ::getCppuType( (const uno::Reference< document::XEventListener >*)0 ), 701 xListener ); 702 } 703 704