diff options
Diffstat (limited to 'sfx2/source/doc/sfxbasemodel.cxx')
-rw-r--r-- | sfx2/source/doc/sfxbasemodel.cxx | 1066 |
1 files changed, 544 insertions, 522 deletions
diff --git a/sfx2/source/doc/sfxbasemodel.cxx b/sfx2/source/doc/sfxbasemodel.cxx index a502931ffd..7a5f630659 100644 --- a/sfx2/source/doc/sfxbasemodel.cxx +++ b/sfx2/source/doc/sfxbasemodel.cxx @@ -70,6 +70,7 @@ #include <cppuhelper/exc_hlp.hxx> #include <comphelper/processfactory.hxx> // can be removed when this is a "real" service #include <comphelper/componentcontext.hxx> +#include <comphelper/namedvaluecollection.hxx> #include <svl/itemset.hxx> #include <svl/stritem.hxx> #include <svl/eitem.hxx> @@ -98,6 +99,9 @@ // includes of my own project //________________________________________________________________________________________________________ +#include <sfx2/sfxbasecontroller.hxx> +#include "viewfac.hxx" +#include "workwin.hxx" #include <sfx2/signaturestate.hxx> #include <sfx2/sfxuno.hxx> #include <objshimp.hxx> @@ -114,7 +118,7 @@ #include <sfx2/evntconf.hxx> #include <sfx2/sfx.hrc> #include <sfx2/app.hxx> -#include <sfx2/topfrm.hxx> +#include <sfx2/viewfrm.hxx> #include "appdata.hxx" #include <sfx2/docfac.hxx> #include <sfx2/fcontnr.hxx> @@ -137,11 +141,19 @@ static const ::rtl::OUString SERVICENAME_DESKTOP = ::rtl::OUString::createFromAs namespace css = ::com::sun::star; using namespace ::com::sun::star; using namespace ::com::sun::star::uno; +using ::com::sun::star::beans::PropertyValue; +using ::com::sun::star::frame::XFrame; +using ::com::sun::star::frame::XController; +using ::com::sun::star::frame::XController2; +using ::com::sun::star::lang::IllegalArgumentException; +using ::com::sun::star::io::IOException; +using ::com::sun::star::lang::WrappedTargetException; +using ::com::sun::star::uno::Type; +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::document::XDocumentRecovery; /** This Listener is used to get notified when the XDocumentProperties of the XModel change. - If several changes are done the "bQuiet" member can be used to - temporarily suppress notifications. */ class SfxDocInfoListener_Impl : public ::cppu::WeakImplHelper1< ::com::sun::star::util::XModifyListener > @@ -149,12 +161,9 @@ class SfxDocInfoListener_Impl : public ::cppu::WeakImplHelper1< public: SfxObjectShell& m_rShell; - bool bQuiet; - bool bGotModified; SfxDocInfoListener_Impl( SfxObjectShell& i_rDoc ) : m_rShell(i_rDoc) - , bQuiet(false) { }; ~SfxDocInfoListener_Impl(); @@ -171,12 +180,9 @@ void SAL_CALL SfxDocInfoListener_Impl::modified( const lang::EventObject& ) throw ( uno::RuntimeException ) { ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); - bGotModified = true; // notify changes to the SfxObjectShell - if ( !bQuiet ) { - m_rShell.FlushDocInfo(); - } + m_rShell.FlushDocInfo(); } void SAL_CALL SfxDocInfoListener_Impl::disposing( const lang::EventObject& ) @@ -212,6 +218,8 @@ struct IMPL_SfxBaseModel_DataContainer : public ::sfx2::IModifiableDocument sal_Bool m_bClosing ; sal_Bool m_bSaving ; sal_Bool m_bSuicide ; + sal_Bool m_bInitialized ; + sal_Bool m_bModifiedSinceLastSave; uno::Reference< com::sun::star::view::XPrintable> m_xPrintable ; uno::Reference< script::provider::XScriptProvider > m_xScriptProvider; uno::Reference< ui::XUIConfigurationManager > m_xUIConfigurationManager; @@ -230,6 +238,8 @@ struct IMPL_SfxBaseModel_DataContainer : public ::sfx2::IModifiableDocument , m_bClosing ( sal_False ) , m_bSaving ( sal_False ) , m_bSuicide ( sal_False ) + , m_bInitialized ( sal_False ) + , m_bModifiedSinceLastSave( sal_False ) , m_pStorageModifyListen ( NULL ) , m_xTitleHelper () , m_xNumberedControllers () @@ -357,41 +367,40 @@ SfxOwnFramesLocker::SfxOwnFramesLocker( SfxObjectShell* pObjectShell ) if ( !pObjectShell ) return; - for ( SfxViewFrame *pFrame = SfxViewFrame::GetFirst(pObjectShell, TYPE(SfxTopViewFrame) ); pFrame; - pFrame = SfxViewFrame::GetNext(*pFrame, pObjectShell, TYPE(SfxTopViewFrame) ) ) + for ( SfxViewFrame *pFrame = SfxViewFrame::GetFirst( pObjectShell ); + pFrame; + pFrame = SfxViewFrame::GetNext( *pFrame, pObjectShell ) + ) { - SfxFrame* pSfxFrame = pFrame->GetFrame(); - if ( pSfxFrame ) + SfxFrame& rSfxFrame = pFrame->GetFrame(); + try { - try + // get vcl window related to the frame and lock it if it is still not locked + uno::Reference< frame::XFrame > xFrame = rSfxFrame.GetFrameInterface(); + Window* pWindow = GetVCLWindow( xFrame ); + if ( !pWindow ) + throw uno::RuntimeException(); + + if ( pWindow->IsEnabled() ) { - // get vcl window related to the frame and lock it if it is still not locked - uno::Reference< frame::XFrame > xFrame = pSfxFrame->GetFrameInterface(); - Window* pWindow = GetVCLWindow( xFrame ); - if ( !pWindow ) - throw uno::RuntimeException(); + pWindow->Disable(); - if ( pWindow->IsEnabled() ) + try { - pWindow->Disable(); - - try - { - sal_Int32 nLen = m_aLockedFrames.getLength(); - m_aLockedFrames.realloc( nLen + 1 ); - m_aLockedFrames[nLen] = xFrame; - } - catch( uno::Exception& ) - { - pWindow->Enable(); - throw; - } + sal_Int32 nLen = m_aLockedFrames.getLength(); + m_aLockedFrames.realloc( nLen + 1 ); + m_aLockedFrames[nLen] = xFrame; + } + catch( uno::Exception& ) + { + pWindow->Enable(); + throw; } } - catch( uno::Exception& ) - { - OSL_ENSURE( sal_False, "Not possible to lock the frame window!\n" ); - } + } + catch( uno::Exception& ) + { + OSL_ENSURE( sal_False, "Not possible to lock the frame window!\n" ); } } } @@ -522,6 +531,7 @@ SfxBaseModel::SfxBaseModel( SfxObjectShell *pObjectShell ) : BaseMutex() , m_pData( new IMPL_SfxBaseModel_DataContainer( m_aMutex, pObjectShell ) ) , m_bSupportEmbeddedScripts( pObjectShell && pObjectShell->Get_Impl() ? !pObjectShell->Get_Impl()->m_bNoBasicCapabilities : false ) +, m_bSupportDocRecovery( pObjectShell && pObjectShell->Get_Impl() ? pObjectShell->Get_Impl()->m_bDocRecoverySupport : false ) { DBG_CTOR(sfx2_SfxBaseModel,NULL); if ( pObjectShell != NULL ) @@ -545,7 +555,9 @@ SfxBaseModel::~SfxBaseModel() uno::Any SAL_CALL SfxBaseModel::queryInterface( const UNOTYPE& rType ) throw( uno::RuntimeException ) { - if ( !m_bSupportEmbeddedScripts && rType.equals( XEMBEDDEDSCRIPTS::static_type() ) ) + if ( ( !m_bSupportEmbeddedScripts && rType.equals( XEMBEDDEDSCRIPTS::static_type() ) ) + || ( !m_bSupportDocRecovery && rType.equals( XDocumentRecovery::static_type() ) ) + ) return Any(); return SfxBaseModel_Base::queryInterface( rType ); @@ -581,21 +593,31 @@ void SAL_CALL SfxBaseModel::release() throw( ) // XTypeProvider //________________________________________________________________________________________________________ -uno::Sequence< UNOTYPE > SAL_CALL SfxBaseModel::getTypes() throw( uno::RuntimeException ) +namespace { - uno::Sequence< UNOTYPE > aTypes( SfxBaseModel_Base::getTypes() ); - if ( !m_bSupportEmbeddedScripts ) + void lcl_stripType( Sequence< Type >& io_rTypes, const Type& i_rTypeToStrip ) { - // remove XEmbeddedScripts type from the sequence - Sequence< UNOTYPE > aStrippedTypes( aTypes.getLength() - 1 ); + Sequence< UNOTYPE > aStrippedTypes( io_rTypes.getLength() - 1 ); ::std::remove_copy_if( - aTypes.getConstArray(), - aTypes.getConstArray() + aTypes.getLength(), + io_rTypes.getConstArray(), + io_rTypes.getConstArray() + io_rTypes.getLength(), aStrippedTypes.getArray(), - ::std::bind2nd( ::std::equal_to< UNOTYPE >(), XEMBEDDEDSCRIPTS::static_type() ) + ::std::bind2nd( ::std::equal_to< Type >(), i_rTypeToStrip ) ); - aTypes = aStrippedTypes; + io_rTypes = aStrippedTypes; } +} + +uno::Sequence< UNOTYPE > SAL_CALL SfxBaseModel::getTypes() throw( uno::RuntimeException ) +{ + uno::Sequence< UNOTYPE > aTypes( SfxBaseModel_Base::getTypes() ); + + if ( !m_bSupportEmbeddedScripts ) + lcl_stripType( aTypes, XEMBEDDEDSCRIPTS::static_type() ); + + if ( !m_bSupportDocRecovery ) + lcl_stripType( aTypes, XDocumentRecovery::static_type() ); + return aTypes; } @@ -648,9 +670,7 @@ uno::Reference< script::XStarBasicAccess > implGetStarBasicAccess( SfxObjectShel uno::Reference< XNAMECONTAINER > SAL_CALL SfxBaseModel::getLibraryContainer() throw( uno::RuntimeException ) { - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); uno::Reference< script::XStarBasicAccess >& rxAccess = m_pData->m_xStarBasicAccess; if( !rxAccess.is() && m_pData->m_pObjectShell.Is() ) @@ -669,9 +689,7 @@ void SAL_CALL SfxBaseModel::createLibrary( const ::rtl::OUString& LibName, const const ::rtl::OUString& ExternalSourceURL, const ::rtl::OUString& LinkTargetURL ) throw(ELEMENTEXISTEXCEPTION, uno::RuntimeException) { - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); uno::Reference< script::XStarBasicAccess >& rxAccess = m_pData->m_xStarBasicAccess; if( !rxAccess.is() && m_pData->m_pObjectShell.Is() ) @@ -688,9 +706,7 @@ void SAL_CALL SfxBaseModel::addModule( const ::rtl::OUString& LibraryName, const const ::rtl::OUString& Language, const ::rtl::OUString& Source ) throw( NOSUCHELEMENTEXCEPTION, uno::RuntimeException) { - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); uno::Reference< script::XStarBasicAccess >& rxAccess = m_pData->m_xStarBasicAccess; if( !rxAccess.is() && m_pData->m_pObjectShell.Is() ) @@ -707,9 +723,7 @@ void SAL_CALL SfxBaseModel::addDialog( const ::rtl::OUString& LibraryName, const const ::com::sun::star::uno::Sequence< sal_Int8 >& Data ) throw(NOSUCHELEMENTEXCEPTION, uno::RuntimeException) { - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); uno::Reference< script::XStarBasicAccess >& rxAccess = m_pData->m_xStarBasicAccess; if( !rxAccess.is() && m_pData->m_pObjectShell.Is() ) @@ -726,9 +740,7 @@ void SAL_CALL SfxBaseModel::addDialog( const ::rtl::OUString& LibraryName, const uno::Reference< uno::XInterface > SAL_CALL SfxBaseModel::getParent() throw( uno::RuntimeException ) { - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); return m_pData->m_xParent; } @@ -739,7 +751,7 @@ uno::Reference< uno::XInterface > SAL_CALL SfxBaseModel::getParent() throw( uno: void SAL_CALL SfxBaseModel::setParent(const uno::Reference< uno::XInterface >& Parent) throw(NOSUPPORTEXCEPTION, uno::RuntimeException) { - ::vos::OGuard aGuard( Application::GetSolarMutex() ); + SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING ); m_pData->m_xParent = Parent; } @@ -749,11 +761,7 @@ void SAL_CALL SfxBaseModel::setParent(const uno::Reference< uno::XInterface >& P void SAL_CALL SfxBaseModel::dispose() throw(::com::sun::star::uno::RuntimeException) { - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - - // object already disposed? - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING ); if ( !m_pData->m_bClosed ) { @@ -812,11 +820,7 @@ void SAL_CALL SfxBaseModel::dispose() throw(::com::sun::star::uno::RuntimeExcept void SAL_CALL SfxBaseModel::addEventListener( const uno::Reference< XEVENTLISTENER >& aListener ) throw(::com::sun::star::uno::RuntimeException) { - // object already disposed? - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - return; - + SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING ); m_pData->m_aInterfaceContainer.addInterface( ::getCppuType((const uno::Reference< XEVENTLISTENER >*)0), aListener ); } @@ -827,11 +831,7 @@ void SAL_CALL SfxBaseModel::addEventListener( const uno::Reference< XEVENTLISTEN void SAL_CALL SfxBaseModel::removeEventListener( const uno::Reference< XEVENTLISTENER >& aListener ) throw(::com::sun::star::uno::RuntimeException) { - // object already disposed? - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - return; - + SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING ); m_pData->m_aInterfaceContainer.removeInterface( ::getCppuType((const uno::Reference< XEVENTLISTENER >*)0), aListener ); } @@ -841,11 +841,7 @@ void SAL_CALL SfxBaseModel::removeEventListener( const uno::Reference< XEVENTLIS uno::Reference< document::XDocumentInfo > SAL_CALL SfxBaseModel::getDocumentInfo() throw(::com::sun::star::uno::RuntimeException) { - // object already disposed? - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); - + SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING ); if ( !m_pData->m_xDocumentInfo.is() ) { // WARNING: this will only work if (when loading a document) the @@ -891,11 +887,7 @@ uno::Reference< document::XDocumentProperties > SAL_CALL SfxBaseModel::getDocumentProperties() throw(::com::sun::star::uno::RuntimeException) { - // object already disposed? - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); - + SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING ); if ( !m_pData->m_xDocumentProperties.is() ) { uno::Reference< lang::XInitialization > xDocProps( @@ -943,10 +935,7 @@ sal_Bool SAL_CALL SfxBaseModel::attachResource( const ::rtl::OUString& const uno::Sequence< beans::PropertyValue >& rArgs ) throw(::com::sun::star::uno::RuntimeException) { - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); - + SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING ); if ( rURL.getLength() == 0 && rArgs.getLength() == 1 && rArgs[0].Name.equalsAscii( "SetEmbedded" ) ) { // allows to set a windowless document to EMBEDDED state @@ -964,53 +953,50 @@ sal_Bool SAL_CALL SfxBaseModel::attachResource( const ::rtl::OUString& if ( m_pData->m_pObjectShell.Is() ) { m_pData->m_sURL = rURL; - uno::Sequence< beans::PropertyValue > aNewSeqArgs( rArgs.getLength() ); - sal_Int32 nNewLen = 0; - for ( sal_Int32 nInd = 0; nInd < rArgs.getLength(); nInd++ ) + SfxObjectShell* pObjectShell = m_pData->m_pObjectShell; + + ::comphelper::NamedValueCollection aArgs( rArgs ); + + Sequence< sal_Int32 > aWinExtent; + if ( ( aArgs.get( "WinExtent" ) >>= aWinExtent )&& ( aWinExtent.getLength() == 4 ) ) { - if ( rArgs[nInd].Name.equalsAscii( "WinExtent" ) ) - { - Sequence< sal_Int32 > aSize; - if ( ( rArgs[nInd].Value >>= aSize ) && aSize.getLength() == 4 ) - { - Rectangle aTmpRect( aSize[0], aSize[1], aSize[2], aSize[3] ); - aTmpRect = OutputDevice::LogicToLogic( aTmpRect, MAP_100TH_MM, m_pData->m_pObjectShell->GetMapUnit() ); - m_pData->m_pObjectShell->SetVisArea( aTmpRect ); - } - } - else if ( rArgs[nInd].Name.equalsAscii( "BreakMacroSignature" ) ) - { - sal_Bool bBreakMacroSign = sal_False; - rArgs[nInd].Value >>= bBreakMacroSign; - m_pData->m_pObjectShell->BreakMacroSign_Impl( bBreakMacroSign ); - } - else if ( !rArgs[nInd].Name.equalsAscii( "Stream" ) && !rArgs[nInd].Name.equalsAscii( "InputStream" ) ) - { - // TODO/LATER: all the parameters that are accepted by ItemSet of the DocShell must be ignored here - aNewSeqArgs[nNewLen++] = rArgs[nInd]; - } + Rectangle aVisArea( aWinExtent[0], aWinExtent[1], aWinExtent[2], aWinExtent[3] ); + aVisArea = OutputDevice::LogicToLogic( aVisArea, MAP_100TH_MM, pObjectShell->GetMapUnit() ); + pObjectShell->SetVisArea( aVisArea ); + } + + sal_Bool bBreakMacroSign = sal_False; + if ( aArgs.get( "BreakMacroSignature" ) >>= bBreakMacroSign ) + { + pObjectShell->BreakMacroSign_Impl( bBreakMacroSign ); } - aNewSeqArgs.realloc( nNewLen ); + aArgs.remove( "WinExtent" ); + aArgs.remove( "BreakMacroSignature" ); + aArgs.remove( "Stream" ); + aArgs.remove( "InputStream" ); - m_pData->m_seqArguments = aNewSeqArgs; + // TODO/LATER: all the parameters that are accepted by ItemSet of the DocShell must be removed here - if( m_pData->m_pObjectShell->GetMedium() ) + m_pData->m_seqArguments = aArgs.getPropertyValues(); + + SfxMedium* pMedium = pObjectShell->GetMedium(); + if ( pMedium ) { - SfxAllItemSet aSet( m_pData->m_pObjectShell->GetPool() ); + SfxAllItemSet aSet( pObjectShell->GetPool() ); TransformParameters( SID_OPENDOC, rArgs, aSet ); - m_pData->m_pObjectShell->GetMedium()->GetItemSet()->Put( aSet ); + pMedium->GetItemSet()->Put( aSet ); SFX_ITEMSET_ARG( &aSet, pItem, SfxStringItem, SID_FILTER_NAME, sal_False ); if ( pItem ) - m_pData->m_pObjectShell->GetMedium()->SetFilter( - m_pData->m_pObjectShell->GetFactory().GetFilterContainer()->GetFilter4FilterName( pItem->GetValue() ) ); + pMedium->SetFilter( + pObjectShell->GetFactory().GetFilterContainer()->GetFilter4FilterName( pItem->GetValue() ) ); SFX_ITEMSET_ARG( &aSet, pTitleItem, SfxStringItem, SID_DOCINFO_TITLE, sal_False ); if ( pTitleItem ) { - SfxViewFrame* pFrame = SfxViewFrame::GetFirst( m_pData->m_pObjectShell ); + SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pObjectShell ); if ( pFrame ) pFrame->UpdateTitle(); } @@ -1026,10 +1012,7 @@ sal_Bool SAL_CALL SfxBaseModel::attachResource( const ::rtl::OUString& ::rtl::OUString SAL_CALL SfxBaseModel::getURL() throw(::com::sun::star::uno::RuntimeException) { - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); - + SfxModelGuard aGuard( *this ); return m_pData->m_sURL ; } @@ -1039,10 +1022,7 @@ sal_Bool SAL_CALL SfxBaseModel::attachResource( const ::rtl::OUString& uno::Sequence< beans::PropertyValue > SAL_CALL SfxBaseModel::getArgs() throw(::com::sun::star::uno::RuntimeException) { - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); - + SfxModelGuard aGuard( *this ); if ( m_pData->m_pObjectShell.Is() ) { uno::Sequence< beans::PropertyValue > seqArgsNew; @@ -1142,9 +1122,10 @@ uno::Sequence< beans::PropertyValue > SAL_CALL SfxBaseModel::getArgs() throw(::c void SAL_CALL SfxBaseModel::connectController( const uno::Reference< frame::XController >& xController ) throw(::com::sun::star::uno::RuntimeException) { - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); + OSL_PRECOND( xController.is(), "SfxBaseModel::connectController: invalid controller!" ); + if ( !xController.is() ) + return; sal_uInt32 nOldCount = m_pData->m_seqControllers.getLength(); uno::Sequence< uno::Reference< frame::XController > > aNewSeq( nOldCount + 1 ); @@ -1152,6 +1133,16 @@ void SAL_CALL SfxBaseModel::connectController( const uno::Reference< frame::XCon aNewSeq.getArray()[n] = m_pData->m_seqControllers.getConstArray()[n]; aNewSeq.getArray()[nOldCount] = xController; m_pData->m_seqControllers = aNewSeq; + + if ( m_pData->m_seqControllers.getLength() == 1 ) + { + SfxViewFrame* pViewFrame = SfxViewFrame::Get( xController, GetObjectShell() ); + ENSURE_OR_THROW( pViewFrame, "SFX document without SFX view!?" ); + pViewFrame->UpdateDocument_Impl(); + const String sDocumentURL = GetObjectShell()->GetMedium()->GetName(); + if ( sDocumentURL.Len() ) + SFX_APP()->Broadcast( SfxStringHint( SID_OPENURL, sDocumentURL ) ); + } } //________________________________________________________________________________________________________ @@ -1160,9 +1151,7 @@ void SAL_CALL SfxBaseModel::connectController( const uno::Reference< frame::XCon void SAL_CALL SfxBaseModel::disconnectController( const uno::Reference< frame::XController >& xController ) throw(::com::sun::star::uno::RuntimeException) { - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); sal_uInt32 nOldCount = m_pData->m_seqControllers.getLength(); if ( !nOldCount ) @@ -1190,9 +1179,8 @@ void SAL_CALL SfxBaseModel::disconnectController( const uno::Reference< frame::X void SAL_CALL SfxBaseModel::lockControllers() throw(::com::sun::star::uno::RuntimeException) { - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); + ++m_pData->m_nControllerLockCount ; } @@ -1202,9 +1190,8 @@ void SAL_CALL SfxBaseModel::lockControllers() throw(::com::sun::star::uno::Runti void SAL_CALL SfxBaseModel::unlockControllers() throw(::com::sun::star::uno::RuntimeException) { - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); + --m_pData->m_nControllerLockCount ; } @@ -1214,9 +1201,7 @@ void SAL_CALL SfxBaseModel::unlockControllers() throw(::com::sun::star::uno::Run sal_Bool SAL_CALL SfxBaseModel::hasControllersLocked() throw(::com::sun::star::uno::RuntimeException) { - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); return ( m_pData->m_nControllerLockCount != 0 ) ; } @@ -1226,10 +1211,7 @@ sal_Bool SAL_CALL SfxBaseModel::hasControllersLocked() throw(::com::sun::star::u uno::Reference< frame::XController > SAL_CALL SfxBaseModel::getCurrentController() throw(::com::sun::star::uno::RuntimeException) { - // object already disposed? - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); // get the last active controller of this model if ( m_pData->m_xCurrent.is() ) @@ -1246,10 +1228,7 @@ uno::Reference< frame::XController > SAL_CALL SfxBaseModel::getCurrentController void SAL_CALL SfxBaseModel::setCurrentController( const uno::Reference< frame::XController >& xCurrentController ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException) { - // object already disposed? - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); m_pData->m_xCurrent = xCurrentController; } @@ -1260,10 +1239,7 @@ void SAL_CALL SfxBaseModel::setCurrentController( const uno::Reference< frame::X uno::Reference< uno::XInterface > SAL_CALL SfxBaseModel::getCurrentSelection() throw(::com::sun::star::uno::RuntimeException) { - // object already disposed? - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); uno::Reference< uno::XInterface > xReturn; uno::Reference< frame::XController > xController = getCurrentController() ; @@ -1287,9 +1263,7 @@ uno::Reference< uno::XInterface > SAL_CALL SfxBaseModel::getCurrentSelection() t sal_Bool SAL_CALL SfxBaseModel::disableSetModified() throw (::com::sun::star::uno::RuntimeException) { - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw DISPOSEDEXCEPTION(); + SfxModelGuard aGuard( *this ); if ( !m_pData->m_pObjectShell.Is() ) throw uno::RuntimeException(); @@ -1302,9 +1276,7 @@ sal_Bool SAL_CALL SfxBaseModel::disableSetModified() throw (::com::sun::star::un sal_Bool SAL_CALL SfxBaseModel::enableSetModified() throw (::com::sun::star::uno::RuntimeException) { - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw DISPOSEDEXCEPTION(); + SfxModelGuard aGuard( *this ); if ( !m_pData->m_pObjectShell.Is() ) throw uno::RuntimeException(); @@ -1317,9 +1289,7 @@ sal_Bool SAL_CALL SfxBaseModel::enableSetModified() throw (::com::sun::star::uno sal_Bool SAL_CALL SfxBaseModel::isSetModifiedEnabled() throw (::com::sun::star::uno::RuntimeException) { - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw DISPOSEDEXCEPTION(); + SfxModelGuard aGuard( *this ); if ( !m_pData->m_pObjectShell.Is() ) throw uno::RuntimeException(); @@ -1333,10 +1303,7 @@ sal_Bool SAL_CALL SfxBaseModel::isSetModifiedEnabled() throw (::com::sun::star:: sal_Bool SAL_CALL SfxBaseModel::isModified() throw(::com::sun::star::uno::RuntimeException) { - // object already disposed? - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); return m_pData->m_pObjectShell.Is() ? m_pData->m_pObjectShell->IsModified() : sal_False; } @@ -1348,10 +1315,7 @@ sal_Bool SAL_CALL SfxBaseModel::isModified() throw(::com::sun::star::uno::Runtim void SAL_CALL SfxBaseModel::setModified( sal_Bool bModified ) throw (::com::sun::star::beans::PropertyVetoException, ::com::sun::star::uno::RuntimeException) { - // object already disposed? - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); if ( m_pData->m_pObjectShell.Is() ) m_pData->m_pObjectShell->SetModified(bModified); @@ -1363,10 +1327,7 @@ void SAL_CALL SfxBaseModel::setModified( sal_Bool bModified ) void SAL_CALL SfxBaseModel::addModifyListener(const uno::Reference< XMODIFYLISTENER >& xListener) throw( uno::RuntimeException ) { - // object already disposed? - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - return; + SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING ); m_pData->m_aInterfaceContainer.addInterface( ::getCppuType((const uno::Reference< XMODIFYLISTENER >*)0),xListener ); } @@ -1377,10 +1338,7 @@ void SAL_CALL SfxBaseModel::addModifyListener(const uno::Reference< XMODIFYLISTE void SAL_CALL SfxBaseModel::removeModifyListener(const uno::Reference< XMODIFYLISTENER >& xListener) throw( uno::RuntimeException ) { - // object already disposed? - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - return; + SfxModelGuard aGuard( *this ); m_pData->m_aInterfaceContainer.removeInterface( ::getCppuType((const uno::Reference< XMODIFYLISTENER >*)0), xListener ); } @@ -1394,7 +1352,7 @@ void SAL_CALL SfxBaseModel::close( sal_Bool bDeliverOwnership ) throw (util::Clo static ::rtl::OUString MSG_1 = ::rtl::OUString::createFromAscii("Cant close while saving."); ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( !m_pData || m_pData->m_bClosed || m_pData->m_bClosing ) + if ( impl_isDisposed() || m_pData->m_bClosed || m_pData->m_bClosing ) return; uno::Reference< uno::XInterface > xSelfHold( static_cast< ::cppu::OWeakObject* >(this) ); @@ -1456,10 +1414,7 @@ void SAL_CALL SfxBaseModel::close( sal_Bool bDeliverOwnership ) throw (util::Clo void SAL_CALL SfxBaseModel::addCloseListener( const uno::Reference< XCLOSELISTENER >& xListener ) throw (uno::RuntimeException) { - // object already disposed? - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - return; + SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING ); m_pData->m_aInterfaceContainer.addInterface( ::getCppuType((const uno::Reference< XCLOSELISTENER >*)0), xListener ); } @@ -1470,10 +1425,7 @@ void SAL_CALL SfxBaseModel::addCloseListener( const uno::Reference< XCLOSELISTEN void SAL_CALL SfxBaseModel::removeCloseListener( const uno::Reference< XCLOSELISTENER >& xListener ) throw (uno::RuntimeException) { - // object already disposed? - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - return; + SfxModelGuard aGuard( *this ); m_pData->m_aInterfaceContainer.removeInterface( ::getCppuType((const uno::Reference< XCLOSELISTENER >*)0), xListener ); } @@ -1484,10 +1436,7 @@ void SAL_CALL SfxBaseModel::removeCloseListener( const uno::Reference< XCLOSELIS uno::Sequence< beans::PropertyValue > SAL_CALL SfxBaseModel::getPrinter() throw(::com::sun::star::uno::RuntimeException) { - // object already disposed? - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); if ( impl_getPrintHelper() ) return m_pData->m_xPrintable->getPrinter(); @@ -1498,10 +1447,7 @@ uno::Sequence< beans::PropertyValue > SAL_CALL SfxBaseModel::getPrinter() throw( void SAL_CALL SfxBaseModel::setPrinter(const uno::Sequence< beans::PropertyValue >& rPrinter) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) { - // object already disposed? - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); if ( impl_getPrintHelper() ) m_pData->m_xPrintable->setPrinter( rPrinter ); @@ -1510,10 +1456,7 @@ void SAL_CALL SfxBaseModel::setPrinter(const uno::Sequence< beans::PropertyValue void SAL_CALL SfxBaseModel::print(const uno::Sequence< beans::PropertyValue >& rOptions) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) { - // object already disposed? - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); if ( impl_getPrintHelper() ) m_pData->m_xPrintable->print( rOptions ); @@ -1525,10 +1468,7 @@ void SAL_CALL SfxBaseModel::print(const uno::Sequence< beans::PropertyValue >& r sal_Bool SAL_CALL SfxBaseModel::hasLocation() throw(::com::sun::star::uno::RuntimeException) { - // object already disposed? - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); return m_pData->m_pObjectShell.Is() ? m_pData->m_pObjectShell->HasName() : sal_False; } @@ -1539,10 +1479,7 @@ sal_Bool SAL_CALL SfxBaseModel::hasLocation() throw(::com::sun::star::uno::Runti ::rtl::OUString SAL_CALL SfxBaseModel::getLocation() throw(::com::sun::star::uno::RuntimeException) { - // object already disposed? - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); if ( m_pData->m_pObjectShell.Is() ) { @@ -1562,10 +1499,7 @@ sal_Bool SAL_CALL SfxBaseModel::hasLocation() throw(::com::sun::star::uno::Runti sal_Bool SAL_CALL SfxBaseModel::isReadonly() throw(::com::sun::star::uno::RuntimeException) { - // object already disposed? - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); return m_pData->m_pObjectShell.Is() ? m_pData->m_pObjectShell->IsReadOnly() : sal_True; } @@ -1581,10 +1515,7 @@ void SAL_CALL SfxBaseModel::storeSelf( const uno::Sequence< beans::PropertyVa { RTL_LOGFILE_PRODUCT_CONTEXT( aPerfLog, "PERFORMANCE - SfxBaseModel::storeSelf" ); - // object already disposed? - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); if ( m_pData->m_pObjectShell.Is() ) { @@ -1682,10 +1613,7 @@ void SAL_CALL SfxBaseModel::storeAsURL( const ::rtl::OUString& { RTL_LOGFILE_PRODUCT_CONTEXT( aPerfLog, "PERFORMANCE - SfxBaseModel::storeAsURL" ); - // object already disposed? - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); if ( m_pData->m_pObjectShell.Is() ) { @@ -1708,10 +1636,7 @@ void SAL_CALL SfxBaseModel::storeToURL( const ::rtl::OUString& const uno::Sequence< beans::PropertyValue >& rArgs ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException) { - // object already disposed? - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); if ( m_pData->m_pObjectShell.Is() ) { @@ -1721,6 +1646,51 @@ void SAL_CALL SfxBaseModel::storeToURL( const ::rtl::OUString& } } +::sal_Bool SAL_CALL SfxBaseModel::wasModifiedSinceLastSave() throw ( RuntimeException ) +{ + SfxModelGuard aGuard( *this ); + return m_pData->m_bModifiedSinceLastSave; +} + +void SAL_CALL SfxBaseModel::storeToRecoveryFile( const ::rtl::OUString& i_TargetLocation, const Sequence< PropertyValue >& i_MediaDescriptor ) throw ( RuntimeException, IOException, WrappedTargetException ) +{ + SfxModelGuard aGuard( *this ); + + // delegate + SfxSaveGuard aSaveGuard( this, m_pData, sal_False ); + impl_store( i_TargetLocation, i_MediaDescriptor, sal_True ); + + // no need for subsequent calls to storeToRecoveryFile, unless we're modified, again + m_pData->m_bModifiedSinceLastSave = sal_False; +} + +void SAL_CALL SfxBaseModel::recoverFromFile( const ::rtl::OUString& i_SourceLocation, const ::rtl::OUString& i_SalvagedFile, const Sequence< PropertyValue >& i_MediaDescriptor ) throw ( RuntimeException, IOException, WrappedTargetException ) +{ + SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING ); + + // delegate to our "load" method + ::comphelper::NamedValueCollection aMediaDescriptor( i_MediaDescriptor ); + + // our load implementation expects the SalvagedFile to be in the media descriptor + OSL_ENSURE( !aMediaDescriptor.has( "SalvagedFile" ) || ( aMediaDescriptor.getOrDefault( "SalvagedFile", ::rtl::OUString() ) == i_SalvagedFile ), + "SfxBaseModel::recoverFromFile: inconsistent information!" ); + aMediaDescriptor.put( "SalvagedFile", i_SalvagedFile ); + + // similar for the to-be-loaded file + OSL_ENSURE( !aMediaDescriptor.has( "URL" ) || ( aMediaDescriptor.getOrDefault( "URL", ::rtl::OUString() ) == i_SourceLocation ), + "SfxBaseModel::recoverFromFile: inconsistent information!" ); + aMediaDescriptor.put( "URL", i_SourceLocation ); + + load( aMediaDescriptor.getPropertyValues() ); + + // Note: The XDocumentRecovery interface specification requires us to do an attachResource after loading. + // However, we will not do this here, as we know that our load implementation (respectively some method + // called from there) already did so. + // In particular, the load process might already have modified some elements of the media + // descriptor, for instance the MacroExecMode (in case the user was involved to decide about it), and we do + // not want to overwrite it with the "old" elements passed to this method here. +} + //________________________________________________________________________________________________________ // XLoadable //________________________________________________________________________________________________________ @@ -1731,10 +1701,9 @@ void SAL_CALL SfxBaseModel::initNew() ::com::sun::star::uno::RuntimeException, ::com::sun::star::uno::Exception) { - // object already disposed? - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING ); + if ( IsInitialized() ) + throw ::com::sun::star::frame::DoubleInitializationException( ::rtl::OUString(), *this ); // the object shell should exist always DBG_ASSERT( m_pData->m_pObjectShell.Is(), "Model is useless without an ObjectShell" ); @@ -1763,10 +1732,9 @@ void SAL_CALL SfxBaseModel::load( const uno::Sequence< beans::PropertyValue >& ::com::sun::star::uno::RuntimeException, ::com::sun::star::uno::Exception) { - // object already disposed? - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING ); + if ( IsInitialized() ) + throw ::com::sun::star::frame::DoubleInitializationException( ::rtl::OUString(), *this ); // the object shell should exist always DBG_ASSERT( m_pData->m_pObjectShell.Is(), "Model is useless without an ObjectShell" ); @@ -1910,6 +1878,13 @@ void SAL_CALL SfxBaseModel::load( const uno::Sequence< beans::PropertyValue >& nError ? nError : ERRCODE_IO_CANTREAD ); } } + + BOOL bHidden = FALSE; + SFX_ITEMSET_ARG( pMedium->GetItemSet(), pHidItem, SfxBoolItem, SID_HIDDEN, sal_False); + if ( pHidItem ) + bHidden = pHidItem->GetValue(); + // !TODO: will be done by Framework! + pMedium->SetUpdatePickList( !bHidden ); } } @@ -1922,10 +1897,7 @@ uno::Any SAL_CALL SfxBaseModel::getTransferData( const DATAFLAVOR& aFlavor ) ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException) { - // object already disposed? - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); uno::Any aAny; @@ -2164,10 +2136,7 @@ uno::Any SAL_CALL SfxBaseModel::getTransferData( const DATAFLAVOR& aFlavor ) uno::Sequence< DATAFLAVOR > SAL_CALL SfxBaseModel::getTransferDataFlavors() throw (::com::sun::star::uno::RuntimeException) { - // object already disposed? - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); sal_Int32 nSuppFlavors = GraphicHelper::supportsMetaFileHandle_Impl() ? 10 : 8; uno::Sequence< DATAFLAVOR > aFlavorSeq( nSuppFlavors ); @@ -2236,10 +2205,7 @@ uno::Sequence< DATAFLAVOR > SAL_CALL SfxBaseModel::getTransferDataFlavors() sal_Bool SAL_CALL SfxBaseModel::isDataFlavorSupported( const DATAFLAVOR& aFlavor ) throw (::com::sun::star::uno::RuntimeException) { - // object already disposed? - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); if ( aFlavor.MimeType.equalsAscii( "application/x-openoffice-gdimetafile;windows_formatname=\"GDIMetaFile\"" ) ) { @@ -2298,10 +2264,7 @@ sal_Bool SAL_CALL SfxBaseModel::isDataFlavorSupported( const DATAFLAVOR& aFlavor uno::Reference< container::XNameReplace > SAL_CALL SfxBaseModel::getEvents() throw( uno::RuntimeException ) { - // object already disposed? - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); if ( ! m_pData->m_xEvents.is() ) { @@ -2317,9 +2280,7 @@ uno::Reference< container::XNameReplace > SAL_CALL SfxBaseModel::getEvents() thr uno::Reference< script::XStorageBasedLibraryContainer > SAL_CALL SfxBaseModel::getBasicLibraries() throw (RuntimeException) { - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); uno::Reference< script::XStorageBasedLibraryContainer > xBasicLibraries; if ( m_pData->m_pObjectShell ) @@ -2329,9 +2290,7 @@ uno::Reference< script::XStorageBasedLibraryContainer > SAL_CALL SfxBaseModel::g uno::Reference< script::XStorageBasedLibraryContainer > SAL_CALL SfxBaseModel::getDialogLibraries() throw (RuntimeException) { - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); uno::Reference< script::XStorageBasedLibraryContainer > xDialogLibraries; if ( m_pData->m_pObjectShell ) @@ -2341,9 +2300,7 @@ uno::Reference< script::XStorageBasedLibraryContainer > SAL_CALL SfxBaseModel::g ::sal_Bool SAL_CALL SfxBaseModel::getAllowMacroExecution() throw (RuntimeException) { - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); if ( m_pData->m_pObjectShell ) return m_pData->m_pObjectShell->AdjustMacroMode( String(), false ); @@ -2356,9 +2313,7 @@ uno::Reference< script::XStorageBasedLibraryContainer > SAL_CALL SfxBaseModel::g Reference< document::XEmbeddedScripts > SAL_CALL SfxBaseModel::getScriptContainer() throw (RuntimeException) { - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); Reference< document::XEmbeddedScripts > xDocumentScripts; @@ -2394,10 +2349,7 @@ Reference< document::XEmbeddedScripts > SAL_CALL SfxBaseModel::getScriptContaine void SAL_CALL SfxBaseModel::addEventListener( const uno::Reference< XDOCEVENTLISTENER >& aListener ) throw( uno::RuntimeException ) { - // object already disposed? - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - return; + SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING ); m_pData->m_aInterfaceContainer.addInterface( ::getCppuType((const uno::Reference< XDOCEVENTLISTENER >*)0), aListener ); } @@ -2408,10 +2360,7 @@ void SAL_CALL SfxBaseModel::addEventListener( const uno::Reference< XDOCEVENTLIS void SAL_CALL SfxBaseModel::removeEventListener( const uno::Reference< XDOCEVENTLISTENER >& aListener ) throw( uno::RuntimeException ) { - // object already disposed? - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - return; + SfxModelGuard aGuard( *this ); m_pData->m_aInterfaceContainer.removeInterface( ::getCppuType((const uno::Reference< XDOCEVENTLISTENER >*)0), aListener ); } @@ -2489,7 +2438,9 @@ void SfxBaseModel::Notify( SfxBroadcaster& rBC , if ( pNamedHint ) { - if ( SFX_EVENT_STORAGECHANGED == pNamedHint->GetEventId() ) + switch ( pNamedHint->GetEventId() ) + { + case SFX_EVENT_STORAGECHANGED: { // for now this event is sent only on creation of a new storage for new document // and in case of reload of medium without document reload @@ -2520,12 +2471,17 @@ void SfxBaseModel::Notify( SfxBroadcaster& rBC , ListenForStorage_Impl( m_pData->m_pObjectShell->GetStorage() ); } - else if ( SFX_EVENT_LOADFINISHED == pNamedHint->GetEventId() ) + break; + + case SFX_EVENT_LOADFINISHED: { impl_getPrintHelper(); ListenForStorage_Impl( m_pData->m_pObjectShell->GetStorage() ); + m_pData->m_bModifiedSinceLastSave = sal_False; } - else if ( SFX_EVENT_SAVEASDOCDONE == pNamedHint->GetEventId() ) + break; + + case SFX_EVENT_SAVEASDOCDONE: { m_pData->m_sURL = m_pData->m_pObjectShell->GetMedium()->GetName(); @@ -2536,9 +2492,20 @@ void SfxBaseModel::Notify( SfxBroadcaster& rBC , addTitle_Impl( aArgs, aTitle ); attachResource( m_pData->m_pObjectShell->GetMedium()->GetName(), aArgs ); } - else if ( SFX_EVENT_DOCCREATED == pNamedHint->GetEventId() ) + break; + + case SFX_EVENT_DOCCREATED: { impl_getPrintHelper(); + m_pData->m_bModifiedSinceLastSave = sal_False; + } + break; + + case SFX_EVENT_MODIFYCHANGED: + { + m_pData->m_bModifiedSinceLastSave = isModified(); + } + break; } postEvent_Impl( pNamedHint->GetEventName() ); @@ -2572,36 +2539,29 @@ void SfxBaseModel::Notify( SfxBroadcaster& rBC , // public impl. //________________________________________________________________________________________________________ +void SfxBaseModel::NotifyModifyListeners_Impl() const +{ + ::cppu::OInterfaceContainerHelper* pIC = m_pData->m_aInterfaceContainer.getContainer( ::getCppuType((const uno::Reference< XMODIFYLISTENER >*)0) ); + if ( pIC ) + { + lang::EventObject aEvent( (frame::XModel *)this ); + pIC->notifyEach( &util::XModifyListener::modified, aEvent ); + } + + // this notification here is done too generously, we cannot simply assume that we're really modified + // now, but we need to check it ... + m_pData->m_bModifiedSinceLastSave = const_cast< SfxBaseModel* >( this )->isModified(); +} + void SfxBaseModel::changing() { - // object already disposed? - // object already disposed? - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - return; + SfxModelGuard aGuard( *this ); // the notification should not be sent if the document can not be modified if ( !m_pData->m_pObjectShell.Is() || !m_pData->m_pObjectShell->IsEnableSetModified() ) return; - ::cppu::OInterfaceContainerHelper* pIC = m_pData->m_aInterfaceContainer.getContainer( ::getCppuType((const uno::Reference< XMODIFYLISTENER >*)0) ); - if( pIC ) - - { - lang::EventObject aEvent( (frame::XModel *)this ); - ::cppu::OInterfaceIteratorHelper aIt( *pIC ); - while( aIt.hasMoreElements() ) - { - try - { - ((XMODIFYLISTENER *)aIt.next())->modified( aEvent ); - } - catch( uno::RuntimeException& ) - { - aIt.remove(); - } - } - } + NotifyModifyListeners_Impl(); } void SfxBaseModel::impl_change() @@ -2610,24 +2570,7 @@ void SfxBaseModel::impl_change() if ( impl_isDisposed() ) return; - ::cppu::OInterfaceContainerHelper* pIC = m_pData->m_aInterfaceContainer.getContainer( ::getCppuType((const uno::Reference< XMODIFYLISTENER >*)0) ); - if( pIC ) - - { - lang::EventObject aEvent( (frame::XModel *)this ); - ::cppu::OInterfaceIteratorHelper aIt( *pIC ); - while( aIt.hasMoreElements() ) - { - try - { - ((XMODIFYLISTENER *)aIt.next())->modified( aEvent ); - } - catch( uno::RuntimeException& ) - { - aIt.remove(); - } - } - } + NotifyModifyListeners_Impl(); } //________________________________________________________________________________________________________ @@ -2653,6 +2596,17 @@ sal_Bool SfxBaseModel::IsDisposed() const return ( m_pData == NULL ) ; } +sal_Bool SfxBaseModel::IsInitialized() const +{ + if ( !m_pData || !m_pData->m_pObjectShell ) + { + OSL_ENSURE( false, "SfxBaseModel::IsInitialized: this should have been caught earlier!" ); + return sal_False; + } + + return m_pData->m_pObjectShell->GetMedium() != NULL; +} + sal_Bool SfxBaseModel::impl_isDisposed() const { return ( m_pData == NULL ) ; @@ -2920,16 +2874,13 @@ void SfxBaseModel::postEvent_Impl( ::rtl::OUString aName ) uno::Reference < container::XIndexAccess > SAL_CALL SfxBaseModel::getViewData() throw(::com::sun::star::uno::RuntimeException) { - // object already disposed? - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); if ( m_pData->m_pObjectShell.Is() && !m_pData->m_contViewData.is() ) { SfxViewFrame *pActFrame = SfxViewFrame::Current(); if ( !pActFrame || pActFrame->GetObjectShell() != m_pData->m_pObjectShell ) - pActFrame = SfxViewFrame::GetFirst(m_pData->m_pObjectShell, TYPE(SfxTopViewFrame)); + pActFrame = SfxViewFrame::GetFirst( m_pData->m_pObjectShell ); if ( !pActFrame || !pActFrame->GetViewShell() ) // currently no frame for this document at all or View is under construction @@ -2950,8 +2901,8 @@ uno::Reference < container::XIndexAccess > SAL_CALL SfxBaseModel::getViewData() sal_Int32 nCount = 0; uno::Sequence < beans::PropertyValue > aSeq; ::com::sun::star::uno::Any aAny; - for ( SfxViewFrame *pFrame = SfxViewFrame::GetFirst(m_pData->m_pObjectShell, TYPE(SfxTopViewFrame) ); pFrame; - pFrame = SfxViewFrame::GetNext(*pFrame, m_pData->m_pObjectShell, TYPE(SfxTopViewFrame) ) ) + for ( SfxViewFrame *pFrame = SfxViewFrame::GetFirst( m_pData->m_pObjectShell ); pFrame; + pFrame = SfxViewFrame::GetNext( *pFrame, m_pData->m_pObjectShell ) ) { BOOL bIsActive = ( pFrame == pActFrame ); pFrame->GetViewShell()->WriteUserDataSequence( aSeq ); @@ -2966,10 +2917,7 @@ uno::Reference < container::XIndexAccess > SAL_CALL SfxBaseModel::getViewData() void SAL_CALL SfxBaseModel::setViewData( const uno::Reference < container::XIndexAccess >& aData ) throw(::com::sun::star::uno::RuntimeException) { - // object already disposed? - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); m_pData->m_contViewData = aData; } @@ -3009,10 +2957,7 @@ sal_Bool SfxBaseModel::hasEventListeners() const void SAL_CALL SfxBaseModel::addPrintJobListener( const uno::Reference< view::XPrintJobListener >& xListener ) throw (uno::RuntimeException) { - // object already disposed? - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - return; + SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING ); if ( impl_getPrintHelper() ) { @@ -3026,10 +2971,7 @@ void SAL_CALL SfxBaseModel::addPrintJobListener( const uno::Reference< view::XPr void SAL_CALL SfxBaseModel::removePrintJobListener( const uno::Reference< view::XPrintJobListener >& xListener ) throw (uno::RuntimeException) { - // object already disposed? - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - return; + SfxModelGuard aGuard( *this ); if ( impl_getPrintHelper() ) { @@ -3048,7 +2990,7 @@ class SvObject; sal_Int64 SAL_CALL SfxBaseModel::getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier ) throw(::com::sun::star::uno::RuntimeException) { ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( !impl_isDisposed() && GetObjectShell() ) + if ( GetObjectShell() ) { SvGlobalName aName( aIdentifier ); if ( aName == SvGlobalName( SO3_GLOBAL_CLASSID ) ) @@ -3082,9 +3024,7 @@ void SfxBaseModel::ListenForStorage_Impl( const uno::Reference< embed::XStorage uno::Reference< XSTORAGE > SAL_CALL SfxBaseModel::getDocumentSubStorage( const ::rtl::OUString& aStorageName, sal_Int32 nMode ) throw ( uno::RuntimeException) { - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); uno::Reference< XSTORAGE > xResult; if ( m_pData->m_pObjectShell.Is() ) @@ -3109,9 +3049,7 @@ Sequence< ::rtl::OUString > SAL_CALL SfxBaseModel::getDocumentSubStoragesNames() throw ( io::IOException, RuntimeException ) { - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); Sequence< ::rtl::OUString > aResult; sal_Int32 nResultSize = 0; @@ -3150,9 +3088,7 @@ Sequence< ::rtl::OUString > SAL_CALL SfxBaseModel::getDocumentSubStoragesNames() uno::Reference< script::provider::XScriptProvider > SAL_CALL SfxBaseModel::getScriptProvider() throw ( uno::RuntimeException ) { - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); uno::Reference< script::provider::XScriptProvider > xScriptProvider; @@ -3258,9 +3194,7 @@ static void ConvertSlotsToCommands( SfxObjectShell* pDoc, uno::Reference< contai uno::Reference< ui::XUIConfigurationManager > SAL_CALL SfxBaseModel::getUIConfigurationManager() throw ( uno::RuntimeException ) { - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); if ( !m_pData->m_xUIConfigurationManager.is() ) { @@ -3376,17 +3310,15 @@ void SAL_CALL SfxBaseModel::setVisualAreaSize( sal_Int64 nAspect, const awt::Siz uno::Exception, uno::RuntimeException ) { - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); if ( !m_pData->m_pObjectShell.Is() ) throw uno::Exception(); // TODO: error handling - SfxViewFrame* pViewFrm = SfxViewFrame::GetFirst( m_pData->m_pObjectShell, 0, sal_False ); - if ( pViewFrm && m_pData->m_pObjectShell->GetCreateMode() == SFX_CREATE_MODE_EMBEDDED && !pViewFrm->GetFrame()->IsInPlace() ) + SfxViewFrame* pViewFrm = SfxViewFrame::GetFirst( m_pData->m_pObjectShell, sal_False ); + if ( pViewFrm && m_pData->m_pObjectShell->GetCreateMode() == SFX_CREATE_MODE_EMBEDDED && !pViewFrm->GetFrame().IsInPlace() ) { - Window* pWindow = VCLUnoHelper::GetWindow( pViewFrm->GetFrame()->GetFrameInterface()->getContainerWindow() ); + Window* pWindow = VCLUnoHelper::GetWindow( pViewFrm->GetFrame().GetFrameInterface()->getContainerWindow() ); Size aWinSize = pWindow->GetSizePixel(); awt::Size aCurrent = getVisualAreaSize( nAspect ); Size aDiff( aSize.Width-aCurrent.Width, aSize.Height-aCurrent.Height ); @@ -3410,9 +3342,7 @@ awt::Size SAL_CALL SfxBaseModel::getVisualAreaSize( sal_Int64 /*nAspect*/ ) uno::Exception, uno::RuntimeException) { - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); if ( !m_pData->m_pObjectShell.Is() ) throw uno::Exception(); // TODO: error handling @@ -3441,9 +3371,7 @@ sal_Int32 SAL_CALL SfxBaseModel::getMapUnit( sal_Int64 /*nAspect*/ ) throw ( uno::Exception, uno::RuntimeException) { - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); if ( !m_pData->m_pObjectShell.Is() ) throw uno::Exception(); // TODO: error handling @@ -3457,9 +3385,7 @@ embed::VisualRepresentation SAL_CALL SfxBaseModel::getPreferredVisualRepresentat uno::Exception, uno::RuntimeException ) { - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); datatransfer::DataFlavor aDataFlavor( ::rtl::OUString::createFromAscii( "application/x-openoffice-gdimetafile;windows_formatname=\"GDIMetaFile\"" ), @@ -3485,44 +3411,34 @@ void SAL_CALL SfxBaseModel::loadFromStorage( const uno::Reference< XSTORAGE >& x EXCEPTION, uno::RuntimeException ) { - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING ); + if ( IsInitialized() ) + throw ::com::sun::star::frame::DoubleInitializationException( ::rtl::OUString(), *this ); - if ( !m_pData->m_pObjectShell.Is() ) - throw IOEXCEPTION(); // TODO: + // after i36090 is fixed the pool from object shell can be used + // SfxAllItemSet aSet( m_pData->m_pObjectShell->GetPool() ); + SfxAllItemSet aSet( SFX_APP()->GetPool() ); - if ( m_pData->m_pObjectShell.Is() ) - { - if( m_pData->m_pObjectShell->GetMedium() ) - // if a Medium is present, the document is already initialized - throw DOUBLEINITIALIZATIONEXCEPTION(); + // the BaseURL is part of the ItemSet + SfxMedium* pMedium = new SfxMedium( xStorage, String() ); + TransformParameters( SID_OPENDOC, aMediaDescriptor, aSet ); + pMedium->GetItemSet()->Put( aSet ); - // after i36090 is fixed the pool from object shell can be used - // SfxAllItemSet aSet( m_pData->m_pObjectShell->GetPool() ); - SfxAllItemSet aSet( SFX_APP()->GetPool() ); + // allow to use an interactionhandler (if there is one) + pMedium->UseInteractionHandler( TRUE ); - // the BaseURL is part of the ItemSet - SfxMedium* pMedium = new SfxMedium( xStorage, String() ); - TransformParameters( SID_OPENDOC, aMediaDescriptor, aSet ); - pMedium->GetItemSet()->Put( aSet ); - - // allow to use an interactionhandler (if there is one) - pMedium->UseInteractionHandler( TRUE ); - - SFX_ITEMSET_ARG( &aSet, pTemplateItem, SfxBoolItem, SID_TEMPLATE, sal_False); - BOOL bTemplate = pTemplateItem && pTemplateItem->GetValue(); - m_pData->m_pObjectShell->SetActivateEvent_Impl( bTemplate ? SFX_EVENT_CREATEDOC : SFX_EVENT_OPENDOC ); - m_pData->m_pObjectShell->Get_Impl()->bOwnsStorage = FALSE; + SFX_ITEMSET_ARG( &aSet, pTemplateItem, SfxBoolItem, SID_TEMPLATE, sal_False); + BOOL bTemplate = pTemplateItem && pTemplateItem->GetValue(); + m_pData->m_pObjectShell->SetActivateEvent_Impl( bTemplate ? SFX_EVENT_CREATEDOC : SFX_EVENT_OPENDOC ); + m_pData->m_pObjectShell->Get_Impl()->bOwnsStorage = FALSE; - // load document - if ( !m_pData->m_pObjectShell->DoLoad(pMedium) ) - { - sal_uInt32 nError = m_pData->m_pObjectShell->GetErrorCode(); - throw task::ErrorCodeIOException( ::rtl::OUString(), - uno::Reference< uno::XInterface >(), - nError ? nError : ERRCODE_IO_CANTREAD ); - } + // load document + if ( !m_pData->m_pObjectShell->DoLoad(pMedium) ) + { + sal_uInt32 nError = m_pData->m_pObjectShell->GetErrorCode(); + throw task::ErrorCodeIOException( ::rtl::OUString(), + uno::Reference< uno::XInterface >(), + nError ? nError : ERRCODE_IO_CANTREAD ); } } @@ -3533,9 +3449,7 @@ void SAL_CALL SfxBaseModel::storeToStorage( const uno::Reference< XSTORAGE >& xS EXCEPTION, uno::RuntimeException ) { - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); uno::Reference< XSTORAGE > xResult; if ( !m_pData->m_pObjectShell.Is() ) @@ -3596,9 +3510,7 @@ void SAL_CALL SfxBaseModel::switchToStorage( const uno::Reference< XSTORAGE >& x EXCEPTION, uno::RuntimeException ) { - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); uno::Reference< XSTORAGE > xResult; if ( !m_pData->m_pObjectShell.Is() ) @@ -3622,9 +3534,7 @@ uno::Reference< XSTORAGE > SAL_CALL SfxBaseModel::getDocumentStorage() EXCEPTION, uno::RuntimeException ) { - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); uno::Reference< XSTORAGE > xResult; if ( !m_pData->m_pObjectShell.Is() ) @@ -3637,9 +3547,7 @@ void SAL_CALL SfxBaseModel::addStorageChangeListener( const uno::Reference< document::XStorageChangeListener >& xListener ) throw ( uno::RuntimeException ) { - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - return; + SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING ); m_pData->m_aInterfaceContainer.addInterface( ::getCppuType((const uno::Reference< document::XStorageChangeListener >*)0), xListener ); @@ -3649,9 +3557,7 @@ void SAL_CALL SfxBaseModel::removeStorageChangeListener( const uno::Reference< document::XStorageChangeListener >& xListener ) throw ( uno::RuntimeException ) { - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - return; + SfxModelGuard aGuard( *this ); m_pData->m_aInterfaceContainer.removeInterface( ::getCppuType((const uno::Reference< document::XStorageChangeListener >*)0), xListener ); @@ -3677,9 +3583,7 @@ bool SfxBaseModel::impl_getPrintHelper() void SAL_CALL SfxBaseModel::setIdentifier(const ::rtl::OUString& Identifier) throw (css::uno::RuntimeException) { - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - return; + SfxModelGuard aGuard( *this ); m_pData->m_sModuleIdentifier = Identifier; } @@ -3688,9 +3592,7 @@ bool SfxBaseModel::impl_getPrintHelper() ::rtl::OUString SAL_CALL SfxBaseModel::getIdentifier() throw (css::uno::RuntimeException) { - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - return ::rtl::OUString(); + SfxModelGuard aGuard( *this ); if (m_pData->m_sModuleIdentifier.getLength() > 0) return m_pData->m_sModuleIdentifier; if (m_pData->m_pObjectShell) @@ -3701,10 +3603,7 @@ bool SfxBaseModel::impl_getPrintHelper() //============================================================================= css::uno::Reference< css::frame::XTitle > SfxBaseModel::impl_getTitleHelper () { - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - - if ( impl_isDisposed() ) - return css::uno::Reference< css::frame::XTitle >(); + SfxModelGuard aGuard( *this ); if ( ! m_pData->m_xTitleHelper.is ()) { @@ -3724,10 +3623,7 @@ css::uno::Reference< css::frame::XTitle > SfxBaseModel::impl_getTitleHelper () //============================================================================= css::uno::Reference< css::frame::XUntitledNumbers > SfxBaseModel::impl_getUntitledHelper () { - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - - if ( impl_isDisposed() ) - return css::uno::Reference< css::frame::XUntitledNumbers >(); + SfxModelGuard aGuard( *this ); if ( ! m_pData->m_xNumberedControllers.is ()) { @@ -3749,10 +3645,7 @@ css::uno::Reference< css::frame::XUntitledNumbers > SfxBaseModel::impl_getUntitl throw (css::uno::RuntimeException) { // SYNCHRONIZED -> - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - - if ( impl_isDisposed() ) - return ::rtl::OUString(); + SfxModelGuard aGuard( *this ); ::rtl::OUString aResult = impl_getTitleHelper()->getTitle (); if ( m_pData->m_pObjectShell ) @@ -3783,10 +3676,7 @@ void SAL_CALL SfxBaseModel::setTitle( const ::rtl::OUString& sTitle ) throw (css::uno::RuntimeException) { // SYNCHRONIZED -> - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - - if ( impl_isDisposed() ) - return; + SfxModelGuard aGuard( *this ); impl_getTitleHelper()->setTitle (sTitle); } @@ -3797,10 +3687,7 @@ void SAL_CALL SfxBaseModel::addTitleChangeListener( const css::uno::Reference< c throw (css::uno::RuntimeException) { // SYNCHRONIZED -> - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - - if ( impl_isDisposed() ) - return; + SfxModelGuard aGuard( *this, SfxModelGuard::E_INITIALIZING ); css::uno::Reference< css::frame::XTitleChangeBroadcaster > xBroadcaster(impl_getTitleHelper(), css::uno::UNO_QUERY); if (xBroadcaster.is ()) @@ -3813,10 +3700,7 @@ void SAL_CALL SfxBaseModel::removeTitleChangeListener( const css::uno::Reference throw (css::uno::RuntimeException) { // SYNCHRONIZED -> - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - - if ( impl_isDisposed() ) - return; + SfxModelGuard aGuard( *this ); css::uno::Reference< css::frame::XTitleChangeBroadcaster > xBroadcaster(impl_getTitleHelper(), css::uno::UNO_QUERY); if (xBroadcaster.is ()) @@ -3829,10 +3713,7 @@ void SAL_CALL SfxBaseModel::removeTitleChangeListener( const css::uno::Reference throw (css::lang::IllegalArgumentException, css::uno::RuntimeException ) { - // object already disposed? - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - return css::frame::UntitledNumbersConst::INVALID_NUMBER; + SfxModelGuard aGuard( *this ); return impl_getUntitledHelper ()->leaseNumber (xComponent); } @@ -3843,11 +3724,7 @@ void SAL_CALL SfxBaseModel::releaseNumber( ::sal_Int32 nNumber ) throw (css::lang::IllegalArgumentException, css::uno::RuntimeException ) { - // object already disposed? - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - return; - + SfxModelGuard aGuard( *this ); impl_getUntitledHelper ()->releaseNumber (nNumber); } @@ -3857,11 +3734,7 @@ void SAL_CALL SfxBaseModel::releaseNumberForComponent( const css::uno::Reference throw (css::lang::IllegalArgumentException, css::uno::RuntimeException ) { - // object already disposed? - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - return; - + SfxModelGuard aGuard( *this ); impl_getUntitledHelper ()->releaseNumberForComponent (xComponent); } @@ -3870,11 +3743,7 @@ void SAL_CALL SfxBaseModel::releaseNumberForComponent( const css::uno::Reference ::rtl::OUString SAL_CALL SfxBaseModel::getUntitledPrefix() throw (css::uno::RuntimeException) { - // object already disposed? - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - return ::rtl::OUString (); - + SfxModelGuard aGuard( *this ); return impl_getUntitledHelper ()->getUntitledPrefix (); } @@ -3883,10 +3752,7 @@ void SAL_CALL SfxBaseModel::releaseNumberForComponent( const css::uno::Reference css::uno::Reference< css::container::XEnumeration > SAL_CALL SfxBaseModel::getControllers() throw (css::uno::RuntimeException) { - // object already disposed? - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - return css::uno::Reference< css::container::XEnumeration >(); + SfxModelGuard aGuard( *this ); sal_Int32 c = m_pData->m_seqControllers.getLength(); sal_Int32 i = 0; @@ -3904,29 +3770,217 @@ css::uno::Reference< css::container::XEnumeration > SAL_CALL SfxBaseModel::getCo css::uno::Sequence< ::rtl::OUString > SAL_CALL SfxBaseModel::getAvailableViewControllerNames() throw (css::uno::RuntimeException) { - return css::uno::Sequence< ::rtl::OUString >(); + SfxModelGuard aGuard( *this ); + + const SfxObjectFactory& rDocumentFactory = GetObjectShell()->GetFactory(); + const sal_Int32 nViewFactoryCount = rDocumentFactory.GetViewFactoryCount(); + + Sequence< ::rtl::OUString > aViewNames( nViewFactoryCount ); + for ( sal_Int32 nViewNo = 0; nViewNo < nViewFactoryCount; ++nViewNo ) + aViewNames[nViewNo] = rDocumentFactory.GetViewFactory( nViewNo ).GetViewName(); + return aViewNames; } //============================================================================= // css::frame::XModel2 -css::uno::Reference< css::frame::XController2 > SAL_CALL SfxBaseModel::createDefaultViewController(const css::uno::Reference< css::frame::XFrame >& /*Frame*/) +css::uno::Reference< css::frame::XController2 > SAL_CALL SfxBaseModel::createDefaultViewController( const css::uno::Reference< css::frame::XFrame >& i_rFrame ) throw (css::uno::RuntimeException , css::lang::IllegalArgumentException, css::uno::Exception ) { - return css::uno::Reference< css::frame::XController2 >(); + SfxModelGuard aGuard( *this ); + + const SfxObjectFactory& rDocumentFactory = GetObjectShell()->GetFactory(); + const ::rtl::OUString sDefaultViewName = rDocumentFactory.GetViewFactory( 0 ).GetViewName(); + + aGuard.clear(); + + return createViewController( sDefaultViewName, Sequence< PropertyValue >(), i_rFrame ); +} + +//============================================================================= +namespace sfx { namespace intern { + + /** a class which, in its dtor, cleans up variuos objects (well, at the moment only the frame) collected during + the creation of a document view, unless the creation was successful. + */ + class SAL_DLLPRIVATE ViewCreationGuard + { + public: + ViewCreationGuard() + :m_bSuccess( false ) + { + } + + ~ViewCreationGuard() + { + if ( !m_bSuccess ) + impl_closeAll(); + } + + void takeFrameOwnership( SfxFrame* i_pFrame ) + { + OSL_PRECOND( !m_aWeakFrame, "ViewCreationGuard::takeFrameOwnership: already have a frame!" ); + OSL_PRECOND( i_pFrame != NULL, "ViewCreationGuard::takeFrameOwnership: invalid frame!" ); + m_aWeakFrame = i_pFrame; + } + + void releaseAll() + { + m_bSuccess = true; + } + + private: + void impl_closeAll() + { + if ( m_aWeakFrame && !m_aWeakFrame->GetCurrentDocument() ) + { + m_aWeakFrame->SetFrameInterface_Impl( NULL ); + m_aWeakFrame->DoClose(); + } + } + + private: + bool m_bSuccess; + SfxFrameWeak m_aWeakFrame; + }; +} } + +//============================================================================= +SfxViewFrame* SfxBaseModel::FindOrCreateViewFrame_Impl( const Reference< XFrame >& i_rFrame, ::sfx::intern::ViewCreationGuard& i_rGuard ) const +{ + SfxViewFrame* pViewFrame = NULL; + for ( pViewFrame = SfxViewFrame::GetFirst( GetObjectShell(), FALSE ); + pViewFrame; + pViewFrame= SfxViewFrame::GetNext( *pViewFrame, GetObjectShell(), FALSE ) + ) + { + if ( pViewFrame->GetFrame().GetFrameInterface() == i_rFrame ) + break; + } + if ( !pViewFrame ) + { + #if OSL_DEBUG_LEVEL > 0 + for ( SfxFrame* pCheckFrame = SfxFrame::GetFirst(); + pCheckFrame; + pCheckFrame = SfxFrame::GetNext( *pCheckFrame ) + ) + { + if ( pCheckFrame->GetFrameInterface() == i_rFrame ) + { + if ( ( pCheckFrame->GetCurrentViewFrame() != NULL ) + || ( pCheckFrame->GetCurrentDocument() != NULL ) + ) + // Note that it is perfectly letgitimate that during loading into an XFrame which already contains + // a document, there exist two SfxFrame instances bound to this XFrame - the old one, which will be + // destroyed later, and the new one, which we're going to create + continue; + + OSL_ENSURE( false, "SfxBaseModel::FindOrCreateViewFrame_Impl: there already is an SfxFrame for the given XFrame, but no view in it!" ); + // nowadays, we're the only instance allowed to create an SfxFrame for an XFrame, so this case here should not happen + break; + } + } + #endif + + SfxFrame* pTargetFrame = SfxFrame::Create( i_rFrame ); + ENSURE_OR_THROW( pTargetFrame, "could not create an SfxFrame" ); + i_rGuard.takeFrameOwnership( pTargetFrame ); + + // prepare it + pTargetFrame->PrepareForDoc_Impl( *GetObjectShell() ); + + // create view frame + pViewFrame = new SfxViewFrame( *pTargetFrame, GetObjectShell() ); + } + return pViewFrame; } //============================================================================= // css::frame::XModel2 -css::uno::Reference< css::frame::XController2 > SAL_CALL SfxBaseModel::createViewController(const ::rtl::OUString& /*ViewName*/, - const css::uno::Sequence< css::beans::PropertyValue >& /*Arguments*/, - const css::uno::Reference< css::frame::XFrame >& /*Frame */) +css::uno::Reference< css::frame::XController2 > SAL_CALL SfxBaseModel::createViewController( + const ::rtl::OUString& i_rViewName, const Sequence< PropertyValue >& i_rArguments, const Reference< XFrame >& i_rFrame ) throw (css::uno::RuntimeException , css::lang::IllegalArgumentException, css::uno::Exception ) { - return css::uno::Reference< css::frame::XController2 >(); + SfxModelGuard aGuard( *this ); + + if ( !i_rFrame.is() ) + throw css::lang::IllegalArgumentException( ::rtl::OUString(), *this, 3 ); + + // find the proper SFX view factory + SfxViewFactory* pViewFactory = GetObjectShell()->GetFactory().GetViewFactoryByViewName( i_rViewName ); + if ( !pViewFactory ) + throw IllegalArgumentException( ::rtl::OUString(), *this, 1 ); + + // determine previous shell (used in some special cases) + Reference< XController > xPreviousController( i_rFrame->getController() ); + const Reference< XModel > xMe( this ); + if ( ( xPreviousController.is() ) + && ( xMe != xPreviousController->getModel() ) + ) + { + xPreviousController.clear(); + } + SfxViewShell* pOldViewShell = SfxViewShell::Get( xPreviousController ); + OSL_ENSURE( !xPreviousController.is() || ( pOldViewShell != NULL ), + "SfxBaseModel::createViewController: invalid old controller!" ); + + // a guard which will clean up in case of failure + ::sfx::intern::ViewCreationGuard aViewCreationGuard; + + // determine the ViewFrame belonging to the given XFrame + SfxViewFrame* pViewFrame = FindOrCreateViewFrame_Impl( i_rFrame, aViewCreationGuard ); + OSL_POSTCOND( pViewFrame, "SfxBaseModel::createViewController: no frame?" ); + + // delegate to SFX' view factory + pViewFrame->GetBindings().ENTERREGISTRATIONS(); + SfxViewShell* pViewShell = pViewFactory->CreateInstance( pViewFrame, pOldViewShell ); + pViewFrame->GetBindings().LEAVEREGISTRATIONS(); + ENSURE_OR_THROW( pViewShell, "invalid view shell provided by factory" ); + + // by setting the ViewShell it is prevented that disposing the Controller will destroy this ViewFrame also + pViewFrame->GetDispatcher()->SetDisableFlags( 0 ); + pViewFrame->SetViewShell_Impl( pViewShell ); + + // remember ViewID + pViewFrame->SetCurViewId_Impl( pViewFactory->GetOrdinal() ); + + // ensure a default controller, if the view shell did not provide an own implementation + if ( !pViewShell->GetController().is() ) + pViewShell->SetController( new SfxBaseController( pViewShell ) ); + + // pass the creation arguments to the controller + SfxBaseController* pBaseController = pViewShell->GetBaseController_Impl(); + ENSURE_OR_THROW( pBaseController, "invalid controller implementation!" ); + pBaseController->SetCreationArguments_Impl( i_rArguments ); + + // some initial view settings, coming from our most recent attachResource call + ::comphelper::NamedValueCollection aDocumentLoadArgs( getArgs() ); + if ( aDocumentLoadArgs.getOrDefault( "ViewOnly", false ) ) + pViewFrame->GetFrame().SetMenuBarOn_Impl( FALSE ); + + const sal_Int16 nPluginMode = aDocumentLoadArgs.getOrDefault( "PluginMode", sal_Int16( 0 ) ); + if ( nPluginMode == 1 ) + { + pViewFrame->ForceOuterResize_Impl( FALSE ); + pViewFrame->GetBindings().HidePopups( TRUE ); + + SfxFrame& rFrame = pViewFrame->GetFrame(); + // MBA: layoutmanager of inplace frame starts locked and invisible + rFrame.GetWorkWindow_Impl()->MakeVisible_Impl( FALSE ); + rFrame.GetWorkWindow_Impl()->Lock_Impl( TRUE ); + + rFrame.GetWindow().SetBorderStyle( WINDOW_BORDER_NOBORDER ); + pViewFrame->GetWindow().SetBorderStyle( WINDOW_BORDER_NOBORDER ); + } + + // tell the guard we were successful + aViewCreationGuard.releaseAll(); + + // outta gere + return pBaseController; } //============================================================================= @@ -3936,9 +3990,7 @@ css::uno::Reference< css::frame::XController2 > SAL_CALL SfxBaseModel::createVie uno::Reference< rdf::XRepository > SAL_CALL SfxBaseModel::getRDFRepository() throw (uno::RuntimeException) { - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); const uno::Reference<rdf::XDocumentMetadataAccess> xDMA(m_pData->GetDMA()); if (!xDMA.is()) { @@ -3953,9 +4005,7 @@ SfxBaseModel::getRDFRepository() throw (uno::RuntimeException) ::rtl::OUString SAL_CALL SfxBaseModel::getStringValue() throw (uno::RuntimeException) { - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); const uno::Reference<rdf::XDocumentMetadataAccess> xDMA(m_pData->GetDMA()); if (!xDMA.is()) { @@ -3970,9 +4020,7 @@ SfxBaseModel::getStringValue() throw (uno::RuntimeException) ::rtl::OUString SAL_CALL SfxBaseModel::getNamespace() throw (uno::RuntimeException) { - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); const uno::Reference<rdf::XDocumentMetadataAccess> xDMA(m_pData->GetDMA()); if (!xDMA.is()) { @@ -3986,9 +4034,7 @@ SfxBaseModel::getNamespace() throw (uno::RuntimeException) ::rtl::OUString SAL_CALL SfxBaseModel::getLocalName() throw (uno::RuntimeException) { - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); const uno::Reference<rdf::XDocumentMetadataAccess> xDMA(m_pData->GetDMA()); if (!xDMA.is()) { @@ -4005,9 +4051,7 @@ SfxBaseModel::getElementByMetadataReference( const ::com::sun::star::beans::StringPair & i_rReference) throw (uno::RuntimeException) { - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); const uno::Reference<rdf::XDocumentMetadataAccess> xDMA(m_pData->GetDMA()); if (!xDMA.is()) { @@ -4022,9 +4066,7 @@ uno::Reference< rdf::XMetadatable > SAL_CALL SfxBaseModel::getElementByURI(const uno::Reference< rdf::XURI > & i_xURI) throw (uno::RuntimeException, lang::IllegalArgumentException) { - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); const uno::Reference<rdf::XDocumentMetadataAccess> xDMA(m_pData->GetDMA()); if (!xDMA.is()) { @@ -4040,9 +4082,7 @@ SfxBaseModel::getMetadataGraphsWithType( const uno::Reference<rdf::XURI> & i_xType) throw (uno::RuntimeException, lang::IllegalArgumentException) { - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); const uno::Reference<rdf::XDocumentMetadataAccess> xDMA(m_pData->GetDMA()); if (!xDMA.is()) { @@ -4059,9 +4099,7 @@ SfxBaseModel::addMetadataFile(const ::rtl::OUString & i_rFileName, throw (uno::RuntimeException, lang::IllegalArgumentException, container::ElementExistException) { - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); const uno::Reference<rdf::XDocumentMetadataAccess> xDMA(m_pData->GetDMA()); if (!xDMA.is()) { @@ -4082,9 +4120,7 @@ throw (uno::RuntimeException, lang::IllegalArgumentException, datatransfer::UnsupportedFlavorException, container::ElementExistException, rdf::ParseException, io::IOException) { - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); const uno::Reference<rdf::XDocumentMetadataAccess> xDMA(m_pData->GetDMA()); if (!xDMA.is()) { @@ -4102,9 +4138,7 @@ SfxBaseModel::removeMetadataFile( throw (uno::RuntimeException, lang::IllegalArgumentException, container::NoSuchElementException) { - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); const uno::Reference<rdf::XDocumentMetadataAccess> xDMA(m_pData->GetDMA()); if (!xDMA.is()) { @@ -4120,9 +4154,7 @@ SfxBaseModel::addContentOrStylesFile(const ::rtl::OUString & i_rFileName) throw (uno::RuntimeException, lang::IllegalArgumentException, container::ElementExistException) { - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); const uno::Reference<rdf::XDocumentMetadataAccess> xDMA(m_pData->GetDMA()); if (!xDMA.is()) { @@ -4138,9 +4170,7 @@ SfxBaseModel::removeContentOrStylesFile(const ::rtl::OUString & i_rFileName) throw (uno::RuntimeException, lang::IllegalArgumentException, container::NoSuchElementException) { - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); const uno::Reference<rdf::XDocumentMetadataAccess> xDMA(m_pData->GetDMA()); if (!xDMA.is()) { @@ -4159,9 +4189,7 @@ SfxBaseModel::loadMetadataFromStorage( throw (uno::RuntimeException, lang::IllegalArgumentException, lang::WrappedTargetException) { - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); const uno::Reference<rdf::XDocumentMetadataAccess> xDMA( m_pData->CreateDMAUninitialized()); @@ -4189,9 +4217,7 @@ SfxBaseModel::storeMetadataToStorage( throw (uno::RuntimeException, lang::IllegalArgumentException, lang::WrappedTargetException) { - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); const uno::Reference<rdf::XDocumentMetadataAccess> xDMA(m_pData->GetDMA()); if (!xDMA.is()) { @@ -4208,9 +4234,7 @@ SfxBaseModel::loadMetadataFromMedium( throw (uno::RuntimeException, lang::IllegalArgumentException, lang::WrappedTargetException) { - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); const uno::Reference<rdf::XDocumentMetadataAccess> xDMA( m_pData->CreateDMAUninitialized()); @@ -4237,9 +4261,7 @@ SfxBaseModel::storeMetadataToMedium( throw (uno::RuntimeException, lang::IllegalArgumentException, lang::WrappedTargetException) { - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( impl_isDisposed() ) - throw lang::DisposedException(); + SfxModelGuard aGuard( *this ); const uno::Reference<rdf::XDocumentMetadataAccess> xDMA(m_pData->GetDMA()); if (!xDMA.is()) { |