diff options
Diffstat (limited to 'embeddedobj/source/commonembedding/miscobj.cxx')
-rw-r--r-- | embeddedobj/source/commonembedding/miscobj.cxx | 707 |
1 files changed, 707 insertions, 0 deletions
diff --git a/embeddedobj/source/commonembedding/miscobj.cxx b/embeddedobj/source/commonembedding/miscobj.cxx new file mode 100644 index 000000000000..f4c0c90162ed --- /dev/null +++ b/embeddedobj/source/commonembedding/miscobj.cxx @@ -0,0 +1,707 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_embeddedobj.hxx" + +#include <commonembobj.hxx> +#include <com/sun/star/embed/EmbedStates.hpp> +#include <com/sun/star/embed/EmbedVerbs.hpp> +#include <com/sun/star/embed/XStorage.hpp> +#include <com/sun/star/embed/EmbedUpdateModes.hpp> +#include <com/sun/star/embed/XInplaceClient.hpp> +#include <com/sun/star/lang/DisposedException.hpp> +#include <com/sun/star/beans/NamedValue.hpp> + +#include <cppuhelper/typeprovider.hxx> +#include <cppuhelper/interfacecontainer.h> +#include <comphelper/mimeconfighelper.hxx> + +#include "closepreventer.hxx" +#include "intercept.hxx" + +using namespace ::com::sun::star; + + +uno::Sequence< beans::PropertyValue > GetValuableArgs_Impl( const uno::Sequence< beans::PropertyValue >& aMedDescr, + sal_Bool bCanUseDocumentBaseURL ); + +//------------------------------------------------------ +OCommonEmbeddedObject::OCommonEmbeddedObject( const uno::Reference< lang::XMultiServiceFactory >& xFactory, + const uno::Sequence< beans::NamedValue >& aObjProps ) +: m_pDocHolder( NULL ) +, m_pInterfaceContainer( NULL ) +, m_bReadOnly( sal_False ) +, m_bDisposed( sal_False ) +, m_bClosed( sal_False ) +, m_nObjectState( -1 ) +, m_nTargetState( -1 ) +, m_nUpdateMode ( embed::EmbedUpdateModes::ALWAYS_UPDATE ) +, m_xFactory( xFactory ) +, m_nMiscStatus( 0 ) +, m_bEmbeddedScriptSupport( sal_True ) +, m_bDocumentRecoverySupport( sal_True ) +, m_bWaitSaveCompleted( sal_False ) +, m_bIsLink( sal_False ) +, m_bLinkHasPassword( sal_False ) +, m_bHasClonedSize( sal_False ) +, m_nClonedMapUnit( 0 ) +{ + CommonInit_Impl( aObjProps ); +} + +//------------------------------------------------------ +OCommonEmbeddedObject::OCommonEmbeddedObject( + const uno::Reference< lang::XMultiServiceFactory >& xFactory, + const uno::Sequence< beans::NamedValue >& aObjProps, + const uno::Sequence< beans::PropertyValue >& aMediaDescr, + const uno::Sequence< beans::PropertyValue >& aObjectDescr ) +: m_pDocHolder( NULL ) +, m_pInterfaceContainer( NULL ) +, m_bReadOnly( sal_False ) +, m_bDisposed( sal_False ) +, m_bClosed( sal_False ) +, m_nObjectState( embed::EmbedStates::LOADED ) +, m_nTargetState( -1 ) +, m_nUpdateMode ( embed::EmbedUpdateModes::ALWAYS_UPDATE ) +, m_xFactory( xFactory ) +, m_nMiscStatus( 0 ) +, m_bEmbeddedScriptSupport( sal_True ) +, m_bDocumentRecoverySupport( sal_True ) +, m_bWaitSaveCompleted( sal_False ) +, m_bIsLink( sal_True ) +, m_bLinkHasPassword( sal_False ) +, m_bHasClonedSize( sal_False ) +, m_nClonedMapUnit( 0 ) +{ + // linked object has no own persistence so it is in loaded state starting from creation + LinkInit_Impl( aObjProps, aMediaDescr, aObjectDescr ); +} + +//------------------------------------------------------ +void OCommonEmbeddedObject::CommonInit_Impl( const uno::Sequence< beans::NamedValue >& aObjectProps ) +{ + OSL_ENSURE( m_xFactory.is(), "No ServiceFactory is provided!\n" ); + if ( !m_xFactory.is() ) + throw uno::RuntimeException(); + + m_pDocHolder = new DocumentHolder( m_xFactory, this ); + m_pDocHolder->acquire(); + + // parse configuration entries + // TODO/LATER: in future UI names can be also provided here + for ( sal_Int32 nInd = 0; nInd < aObjectProps.getLength(); nInd++ ) + { + if ( aObjectProps[nInd].Name.equalsAscii( "ClassID" ) ) + aObjectProps[nInd].Value >>= m_aClassID; + else if ( aObjectProps[nInd].Name.equalsAscii( "ObjectDocumentServiceName" ) ) + aObjectProps[nInd].Value >>= m_aDocServiceName; + else if ( aObjectProps[nInd].Name.equalsAscii( "ObjectDocumentFilterName" ) ) + aObjectProps[nInd].Value >>= m_aPresetFilterName; + else if ( aObjectProps[nInd].Name.equalsAscii( "ObjectMiscStatus" ) ) + aObjectProps[nInd].Value >>= m_nMiscStatus; + else if ( aObjectProps[nInd].Name.equalsAscii( "ObjectVerbs" ) ) + aObjectProps[nInd].Value >>= m_aObjectVerbs; + } + + if ( m_aClassID.getLength() != 16 /*|| !m_aDocServiceName.getLength()*/ ) + throw uno::RuntimeException(); // something goes really wrong + + // accepted states + m_aAcceptedStates.realloc( NUM_SUPPORTED_STATES ); + + m_aAcceptedStates[0] = embed::EmbedStates::LOADED; + m_aAcceptedStates[1] = embed::EmbedStates::RUNNING; + m_aAcceptedStates[2] = embed::EmbedStates::INPLACE_ACTIVE; + m_aAcceptedStates[3] = embed::EmbedStates::UI_ACTIVE; + m_aAcceptedStates[4] = embed::EmbedStates::ACTIVE; + + + // intermediate states + // In the following table the first index points to starting state, + // the second one to the target state, and the sequence referenced by + // first two indexes contains intermediate states, that should be + // passed by object to reach the target state. + // If the sequence is empty that means that indirect switch from start + // state to the target state is forbidden, only if direct switch is possible + // the state can be reached. + + m_pIntermediateStatesSeqs[0][2].realloc( 1 ); + m_pIntermediateStatesSeqs[0][2][0] = embed::EmbedStates::RUNNING; + + m_pIntermediateStatesSeqs[0][3].realloc( 2 ); + m_pIntermediateStatesSeqs[0][3][0] = embed::EmbedStates::RUNNING; + m_pIntermediateStatesSeqs[0][3][1] = embed::EmbedStates::INPLACE_ACTIVE; + + m_pIntermediateStatesSeqs[0][4].realloc( 1 ); + m_pIntermediateStatesSeqs[0][4][0] = embed::EmbedStates::RUNNING; + + m_pIntermediateStatesSeqs[1][3].realloc( 1 ); + m_pIntermediateStatesSeqs[1][3][0] = embed::EmbedStates::INPLACE_ACTIVE; + + m_pIntermediateStatesSeqs[2][0].realloc( 1 ); + m_pIntermediateStatesSeqs[2][0][0] = embed::EmbedStates::RUNNING; + + m_pIntermediateStatesSeqs[3][0].realloc( 2 ); + m_pIntermediateStatesSeqs[3][0][0] = embed::EmbedStates::INPLACE_ACTIVE; + m_pIntermediateStatesSeqs[3][0][1] = embed::EmbedStates::RUNNING; + + m_pIntermediateStatesSeqs[3][1].realloc( 1 ); + m_pIntermediateStatesSeqs[3][1][0] = embed::EmbedStates::INPLACE_ACTIVE; + + m_pIntermediateStatesSeqs[4][0].realloc( 1 ); + m_pIntermediateStatesSeqs[4][0][0] = embed::EmbedStates::RUNNING; + + // verbs table + sal_Int32 nVerbTableSize = 0; + for ( sal_Int32 nVerbInd = 0; nVerbInd < m_aObjectVerbs.getLength(); nVerbInd++ ) + { + if ( m_aObjectVerbs[nVerbInd].VerbID == embed::EmbedVerbs::MS_OLEVERB_PRIMARY ) + { + m_aVerbTable.realloc( ++nVerbTableSize ); + m_aVerbTable[nVerbTableSize - 1].realloc( 2 ); + m_aVerbTable[nVerbTableSize - 1][0] = m_aObjectVerbs[nVerbInd].VerbID; + m_aVerbTable[nVerbTableSize - 1][1] = embed::EmbedStates::UI_ACTIVE; + } + else if ( m_aObjectVerbs[nVerbInd].VerbID == embed::EmbedVerbs::MS_OLEVERB_SHOW ) + { + m_aVerbTable.realloc( ++nVerbTableSize ); + m_aVerbTable[nVerbTableSize - 1].realloc( 2 ); + m_aVerbTable[nVerbTableSize - 1][0] = m_aObjectVerbs[nVerbInd].VerbID; + m_aVerbTable[nVerbTableSize - 1][1] = embed::EmbedStates::UI_ACTIVE; + } + else if ( m_aObjectVerbs[nVerbInd].VerbID == embed::EmbedVerbs::MS_OLEVERB_OPEN ) + { + m_aVerbTable.realloc( ++nVerbTableSize ); + m_aVerbTable[nVerbTableSize - 1].realloc( 2 ); + m_aVerbTable[nVerbTableSize - 1][0] = m_aObjectVerbs[nVerbInd].VerbID; + m_aVerbTable[nVerbTableSize - 1][1] = embed::EmbedStates::ACTIVE; + } + else if ( m_aObjectVerbs[nVerbInd].VerbID == embed::EmbedVerbs::MS_OLEVERB_IPACTIVATE ) + { + m_aVerbTable.realloc( ++nVerbTableSize ); + m_aVerbTable[nVerbTableSize - 1].realloc( 2 ); + m_aVerbTable[nVerbTableSize - 1][0] = m_aObjectVerbs[nVerbInd].VerbID; + m_aVerbTable[nVerbTableSize - 1][1] = embed::EmbedStates::INPLACE_ACTIVE; + } + else if ( m_aObjectVerbs[nVerbInd].VerbID == embed::EmbedVerbs::MS_OLEVERB_UIACTIVATE ) + { + m_aVerbTable.realloc( ++nVerbTableSize ); + m_aVerbTable[nVerbTableSize - 1].realloc( 2 ); + m_aVerbTable[nVerbTableSize - 1][0] = m_aObjectVerbs[nVerbInd].VerbID; + m_aVerbTable[nVerbTableSize - 1][1] = embed::EmbedStates::UI_ACTIVE; + } + else if ( m_aObjectVerbs[nVerbInd].VerbID == embed::EmbedVerbs::MS_OLEVERB_HIDE ) + { + m_aVerbTable.realloc( ++nVerbTableSize ); + m_aVerbTable[nVerbTableSize - 1].realloc( 2 ); + m_aVerbTable[nVerbTableSize - 1][0] = m_aObjectVerbs[nVerbInd].VerbID; + m_aVerbTable[nVerbTableSize - 1][1] = embed::EmbedStates::RUNNING; + } + } +} + +//------------------------------------------------------ +void OCommonEmbeddedObject::LinkInit_Impl( + const uno::Sequence< beans::NamedValue >& aObjectProps, + const uno::Sequence< beans::PropertyValue >& aMediaDescr, + const uno::Sequence< beans::PropertyValue >& aObjectDescr ) +{ + // setPersistance has no effect on own links, so the complete initialization must be done here + + for ( sal_Int32 nInd = 0; nInd < aMediaDescr.getLength(); nInd++ ) + if ( aMediaDescr[nInd].Name.equalsAscii( "URL" ) ) + aMediaDescr[nInd].Value >>= m_aLinkURL; + else if ( aMediaDescr[nInd].Name.equalsAscii( "FilterName" ) ) + aMediaDescr[nInd].Value >>= m_aLinkFilterName; + + OSL_ENSURE( m_aLinkURL.getLength() && m_aLinkFilterName.getLength(), "Filter and URL must be provided!\n" ); + + m_bReadOnly = sal_True; + if ( m_aLinkFilterName.getLength() ) + { + ::comphelper::MimeConfigurationHelper aHelper( m_xFactory ); + ::rtl::OUString aExportFilterName = aHelper.GetExportFilterFromImportFilter( m_aLinkFilterName ); + m_bReadOnly = !( aExportFilterName.equals( m_aLinkFilterName ) ); + } + + m_aDocMediaDescriptor = GetValuableArgs_Impl( aMediaDescr, sal_False ); + + uno::Reference< frame::XDispatchProviderInterceptor > xDispatchInterceptor; + for ( sal_Int32 nObjInd = 0; nObjInd < aObjectDescr.getLength(); nObjInd++ ) + if ( aObjectDescr[nObjInd].Name.equalsAscii( "OutplaceDispatchInterceptor" ) ) + { + aObjectDescr[nObjInd].Value >>= xDispatchInterceptor; + break; + } + else if ( aObjectDescr[nObjInd].Name.equalsAscii( "Parent" ) ) + { + aObjectDescr[nObjInd].Value >>= m_xParent; + } + + CommonInit_Impl( aObjectProps ); + + if ( xDispatchInterceptor.is() ) + m_pDocHolder->SetOutplaceDispatchInterceptor( xDispatchInterceptor ); +} + +//------------------------------------------------------ +OCommonEmbeddedObject::~OCommonEmbeddedObject() +{ + if ( m_pInterfaceContainer || m_pDocHolder ) + { + m_refCount++; + try { + lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >( this ) ); + + if ( m_pInterfaceContainer ) + { + m_pInterfaceContainer->disposeAndClear( aSource ); + + delete m_pInterfaceContainer; + m_pInterfaceContainer = NULL; + } + } catch( uno::Exception& ) {} + + try { + if ( m_pDocHolder ) + { + m_pDocHolder->CloseFrame(); + try { + m_pDocHolder->CloseDocument( sal_True, sal_True ); + } catch ( uno::Exception& ) {} + m_pDocHolder->FreeOffice(); + + m_pDocHolder->release(); + m_pDocHolder = NULL; + } + } catch( uno::Exception& ) {} + } +} + +//------------------------------------------------------ +void OCommonEmbeddedObject::requestPositioning( const awt::Rectangle& aRect ) +{ + // the method is called in case object is inplace active and the object window was resized + + OSL_ENSURE( m_xClientSite.is(), "The client site must be set for inplace active object!\n" ); + if ( m_xClientSite.is() ) + { + uno::Reference< embed::XInplaceClient > xInplaceClient( m_xClientSite, uno::UNO_QUERY ); + + OSL_ENSURE( xInplaceClient.is(), "The client site must support XInplaceClient to allow inplace activation!\n" ); + if ( xInplaceClient.is() ) + { + try { + xInplaceClient->changedPlacement( aRect ); + } + catch( uno::Exception& ) + { + OSL_ENSURE( sal_False, "Exception on request to resize!\n" ); + } + } + } +} + +//------------------------------------------------------ +void OCommonEmbeddedObject::PostEvent_Impl( const ::rtl::OUString& aEventName, + const uno::Reference< uno::XInterface >& /*xSource*/ ) +{ + if ( m_pInterfaceContainer ) + { + ::cppu::OInterfaceContainerHelper* pIC = m_pInterfaceContainer->getContainer( + ::getCppuType((const uno::Reference< document::XEventListener >*)0) ); + if( pIC ) + { + document::EventObject aEvent; + aEvent.EventName = aEventName; + aEvent.Source = uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >( this ) ); + // For now all the events are sent as object events + // aEvent.Source = ( xSource.is() ? xSource + // : uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >( this ) ) ); + ::cppu::OInterfaceIteratorHelper aIt( *pIC ); + while( aIt.hasMoreElements() ) + { + try + { + ((document::XEventListener *)aIt.next())->notifyEvent( aEvent ); + } + catch( uno::RuntimeException& ) + { + aIt.remove(); + } + + // the listener could dispose the object. + if ( m_bDisposed ) + return; + } + } + } +} + +//------------------------------------------------------ +uno::Any SAL_CALL OCommonEmbeddedObject::queryInterface( const uno::Type& rType ) + throw( uno::RuntimeException ) +{ + uno::Any aReturn; + + if ( rType == ::getCppuType( (uno::Reference< embed::XEmbeddedObject > const *)0 )) + { + void * p = static_cast< embed::XEmbeddedObject * >( this ); + return uno::Any( &p, rType ); + } + else + aReturn <<= ::cppu::queryInterface( + rType, + static_cast< embed::XInplaceObject* >( this ), + static_cast< embed::XVisualObject* >( this ), + static_cast< embed::XCommonEmbedPersist* >( static_cast< embed::XEmbedPersist* >( this ) ), + static_cast< embed::XEmbedPersist* >( this ), + static_cast< embed::XLinkageSupport* >( this ), + static_cast< embed::XStateChangeBroadcaster* >( this ), + static_cast< embed::XClassifiedObject* >( this ), + static_cast< embed::XComponentSupplier* >( this ), + static_cast< util::XCloseable* >( this ), + static_cast< container::XChild* >( this ), + static_cast< chart2::XDefaultSizeTransmitter* >( this ), + static_cast< document::XEventBroadcaster* >( this ) ); + + if ( aReturn.hasValue() ) + return aReturn; + else + return ::cppu::OWeakObject::queryInterface( rType ) ; + +} + +//------------------------------------------------------ +void SAL_CALL OCommonEmbeddedObject::acquire() + throw() +{ + ::cppu::OWeakObject::acquire() ; +} + +//------------------------------------------------------ +void SAL_CALL OCommonEmbeddedObject::release() + throw() +{ + ::cppu::OWeakObject::release() ; +} + +//------------------------------------------------------ +uno::Sequence< uno::Type > SAL_CALL OCommonEmbeddedObject::getTypes() + throw( uno::RuntimeException ) +{ + static ::cppu::OTypeCollection* pTypeCollection = NULL; + + if ( !pTypeCollection ) + { + ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); + if ( !pTypeCollection ) + { + if ( m_bIsLink ) + { + static ::cppu::OTypeCollection aTypeCollection( + ::getCppuType( (const uno::Reference< lang::XTypeProvider >*)NULL ), + ::getCppuType( (const uno::Reference< embed::XEmbeddedObject >*)NULL ), + ::getCppuType( (const uno::Reference< embed::XInplaceObject >*)NULL ), + ::getCppuType( (const uno::Reference< embed::XCommonEmbedPersist >*)NULL ), + ::getCppuType( (const uno::Reference< container::XChild >*)NULL ), + ::getCppuType( (const uno::Reference< embed::XLinkageSupport >*)NULL ) ); + + pTypeCollection = &aTypeCollection ; + } + else + { + static ::cppu::OTypeCollection aTypeCollection( + ::getCppuType( (const uno::Reference< lang::XTypeProvider >*)NULL ), + ::getCppuType( (const uno::Reference< embed::XEmbeddedObject >*)NULL ), + ::getCppuType( (const uno::Reference< embed::XInplaceObject >*)NULL ), + ::getCppuType( (const uno::Reference< embed::XCommonEmbedPersist >*)NULL ), + ::getCppuType( (const uno::Reference< container::XChild >*)NULL ), + ::getCppuType( (const uno::Reference< embed::XEmbedPersist >*)NULL ) ); + + pTypeCollection = &aTypeCollection ; + } + } + } + + return pTypeCollection->getTypes() ; + +} + +//------------------------------------------------------ +uno::Sequence< sal_Int8 > SAL_CALL OCommonEmbeddedObject::getImplementationId() + throw( uno::RuntimeException ) +{ + static ::cppu::OImplementationId* pID = NULL ; + + if ( !pID ) + { + ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ) ; + if ( !pID ) + { + static ::cppu::OImplementationId aID( sal_False ) ; + pID = &aID ; + } + } + + return pID->getImplementationId() ; +} + +//------------------------------------------------------ +uno::Sequence< sal_Int8 > SAL_CALL OCommonEmbeddedObject::getClassID() + throw ( uno::RuntimeException ) +{ + if ( m_bDisposed ) + throw lang::DisposedException(); + + return m_aClassID; +} + +//------------------------------------------------------ +::rtl::OUString SAL_CALL OCommonEmbeddedObject::getClassName() + throw ( uno::RuntimeException ) +{ + if ( m_bDisposed ) + throw lang::DisposedException(); + + return m_aClassName; +} + +//------------------------------------------------------ +void SAL_CALL OCommonEmbeddedObject::setClassInfo( + const uno::Sequence< sal_Int8 >& /*aClassID*/, const ::rtl::OUString& /*aClassName*/ ) + throw ( lang::NoSupportException, + uno::RuntimeException ) +{ + // the object class info can not be changed explicitly + throw lang::NoSupportException(); //TODO: +} + +//------------------------------------------------------ +uno::Reference< util::XCloseable > SAL_CALL OCommonEmbeddedObject::getComponent() + throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + if ( m_bDisposed ) + throw lang::DisposedException(); // TODO + + // add an exception + if ( m_nObjectState == -1 ) + { + // the object is still not loaded + throw uno::RuntimeException( ::rtl::OUString::createFromAscii( "Can't store object without persistence!\n" ), + uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ) ); + } + + // if ( m_bWaitSaveCompleted ) + // throw embed::WrongStateException( + // ::rtl::OUString::createFromAscii( "The object waits for saveCompleted() call!\n" ), + // uno::Reference< uno::XInterface >( reinterpret_cast< ::cppu::OWeakObject* >(this) ) ); + + return uno::Reference< util::XCloseable >( m_pDocHolder->GetComponent(), uno::UNO_QUERY ); +} + +//---------------------------------------------- +void SAL_CALL OCommonEmbeddedObject::addStateChangeListener( const uno::Reference< embed::XStateChangeListener >& xListener ) + throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + if ( m_bDisposed ) + throw lang::DisposedException(); // TODO + + if ( !m_pInterfaceContainer ) + m_pInterfaceContainer = new ::cppu::OMultiTypeInterfaceContainerHelper( m_aMutex ); + + m_pInterfaceContainer->addInterface( ::getCppuType( (const uno::Reference< embed::XStateChangeListener >*)0 ), + xListener ); +} + +//---------------------------------------------- +void SAL_CALL OCommonEmbeddedObject::removeStateChangeListener( + const uno::Reference< embed::XStateChangeListener >& xListener ) + throw (uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + if ( m_pInterfaceContainer ) + m_pInterfaceContainer->removeInterface( ::getCppuType( (const uno::Reference< embed::XStateChangeListener >*)0 ), + xListener ); +} + +//---------------------------------------------- +void SAL_CALL OCommonEmbeddedObject::close( sal_Bool bDeliverOwnership ) + throw ( util::CloseVetoException, + uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + if ( m_bClosed ) + throw lang::DisposedException(); // TODO + + uno::Reference< uno::XInterface > xSelfHold( static_cast< ::cppu::OWeakObject* >( this ) ); + lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >( this ) ); + + if ( m_pInterfaceContainer ) + { + ::cppu::OInterfaceContainerHelper* pContainer = + m_pInterfaceContainer->getContainer( ::getCppuType( ( const uno::Reference< util::XCloseListener >*) NULL ) ); + if ( pContainer != NULL ) + { + ::cppu::OInterfaceIteratorHelper pIterator(*pContainer); + while (pIterator.hasMoreElements()) + { + try + { + ((util::XCloseListener*)pIterator.next())->queryClosing( aSource, bDeliverOwnership ); + } + catch( uno::RuntimeException& ) + { + pIterator.remove(); + } + } + } + + pContainer = m_pInterfaceContainer->getContainer( + ::getCppuType( ( const uno::Reference< util::XCloseListener >*) NULL ) ); + if ( pContainer != NULL ) + { + ::cppu::OInterfaceIteratorHelper pCloseIterator(*pContainer); + while (pCloseIterator.hasMoreElements()) + { + try + { + ((util::XCloseListener*)pCloseIterator.next())->notifyClosing( aSource ); + } + catch( uno::RuntimeException& ) + { + pCloseIterator.remove(); + } + } + } + + m_pInterfaceContainer->disposeAndClear( aSource ); + } + + m_bDisposed = sal_True; // the object is disposed now for outside + + // it is possible that the document can not be closed, in this case if the argument is false + // the exception will be thrown otherwise in addition to exception the object must register itself + // as termination listener and listen for document events + + if ( m_pDocHolder ) + { + m_pDocHolder->CloseFrame(); + + try { + m_pDocHolder->CloseDocument( bDeliverOwnership, bDeliverOwnership ); + } + catch( uno::Exception& ) + { + if ( bDeliverOwnership ) + { + m_pDocHolder->release(); + m_pDocHolder = NULL; + m_bClosed = sal_True; + } + + throw; + } + + m_pDocHolder->FreeOffice(); + + m_pDocHolder->release(); + m_pDocHolder = NULL; + } + + // TODO: for now the storage will be disposed by the object, but after the document + // will use the storage, the storage will be disposed by the document and recreated by the object + if ( m_xObjectStorage.is() ) + { + uno::Reference< lang::XComponent > xComp( m_xObjectStorage, uno::UNO_QUERY ); + OSL_ENSURE( xComp.is(), "Storage does not support XComponent!\n" ); + + if ( xComp.is() ) + { + try { + xComp->dispose(); + } catch ( uno::Exception& ) {} + } + + m_xObjectStorage.clear(); + m_xRecoveryStorage.clear(); + } + + m_bClosed = sal_True; // the closing succeeded +} + +//---------------------------------------------- +void SAL_CALL OCommonEmbeddedObject::addCloseListener( const uno::Reference< util::XCloseListener >& xListener ) + throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + if ( m_bDisposed ) + throw lang::DisposedException(); // TODO + + if ( !m_pInterfaceContainer ) + m_pInterfaceContainer = new ::cppu::OMultiTypeInterfaceContainerHelper( m_aMutex ); + + m_pInterfaceContainer->addInterface( ::getCppuType( (const uno::Reference< util::XCloseListener >*)0 ), xListener ); +} + +//---------------------------------------------- +void SAL_CALL OCommonEmbeddedObject::removeCloseListener( const uno::Reference< util::XCloseListener >& xListener ) + throw (uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + if ( m_pInterfaceContainer ) + m_pInterfaceContainer->removeInterface( ::getCppuType( (const uno::Reference< util::XCloseListener >*)0 ), + xListener ); +} + +//------------------------------------------------------ +void SAL_CALL OCommonEmbeddedObject::addEventListener( const uno::Reference< document::XEventListener >& xListener ) + throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + if ( m_bDisposed ) + throw lang::DisposedException(); // TODO + + if ( !m_pInterfaceContainer ) + m_pInterfaceContainer = new ::cppu::OMultiTypeInterfaceContainerHelper( m_aMutex ); + + m_pInterfaceContainer->addInterface( ::getCppuType( (const uno::Reference< document::XEventListener >*)0 ), xListener ); +} + +//------------------------------------------------------ +void SAL_CALL OCommonEmbeddedObject::removeEventListener( const uno::Reference< document::XEventListener >& xListener ) + throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( m_aMutex ); + if ( m_pInterfaceContainer ) + m_pInterfaceContainer->removeInterface( ::getCppuType( (const uno::Reference< document::XEventListener >*)0 ), + xListener ); +} + |