Tag: cws_dev300_odbmacros3 User: fs Date: 2008-07-28 06:25:03+0000 Modified: dba/dbaccess/source/core/dataaccess/databasedocument.cxx dba/dbaccess/source/core/dataaccess/databasedocument.hxx
Log: #i76128# event notifications File Changes: Directory: /dba/dbaccess/source/core/dataaccess/ ================================================ File [changed]: databasedocument.cxx Url: http://dba.openoffice.org/source/browse/dba/dbaccess/source/core/dataaccess/databasedocument.cxx?r1=1.40.6.11&r2=1.40.6.12 Delta lines: +200 -170 ----------------------- --- databasedocument.cxx 2008-07-24 05:34:15+0000 1.40.6.11 +++ databasedocument.cxx 2008-07-28 06:25:00+0000 1.40.6.12 @@ -7,7 +7,7 @@ * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: databasedocument.cxx,v $ - * $Revision: 1.40.6.11 $ + * $Revision: 1.40.6.12 $ * * This file is part of OpenOffice.org. * @@ -105,7 +105,40 @@ //........................................................................ //============================================================ -//= ODatabaseContext +//= ViewMonitor +//============================================================ +//-------------------------------------------------------------------------- +bool ViewMonitor::onControllerConnected( const Reference< XController >& _rxController ) +{ + bool bFirstControllerEver = ( m_bEverHadController == false ); + m_bEverHadController = true; + + m_xLastConnectedController = _rxController; + m_bLastIsFirstEverController = bFirstControllerEver; + + return bFirstControllerEver; +} + +//-------------------------------------------------------------------------- +void ViewMonitor::onSetCurrentController( const Reference< XController >& _rxController ) +{ + // we interpret this as "creation of a new view has been finished", if and only if + // the controller is the same which was recently connected to the document + bool bViewCreated = ( _rxController == m_xLastConnectedController ); + + // also, we interpret this as "loading the document (including UI) is finished", + // if and only if this was the first-ever controller + bool bLoadFinished = bViewCreated && m_bLastIsFirstEverController; + + // notify the respective events + if ( bLoadFinished ) + m_rEventNotifier.notifyDocumentEventAsync( "OnLoad" ); + if ( bViewCreated ) + m_rEventNotifier.notifyDocumentEventAsync( "OnViewCreated" ); +} + +//============================================================ +//= ODatabaseDocument //============================================================ DBG_NAME(ODatabaseDocument) //-------------------------------------------------------------------------- @@ -120,10 +153,11 @@ ,ODatabaseDocument_OfficeDocument( getMutex() ) ,m_aModifyListeners( getMutex() ) ,m_aCloseListener( getMutex() ) - ,m_aDocEventListeners( getMutex() ) ,m_aStorageListeners( getMutex() ) ,m_pEventContainer( new DocumentEvents( *this, getMutex() ) ) ,m_pEventExecutor( NULL ) // initialized below, ref-count-protected + ,m_aEventNotifier( *this, getMutex() ) + ,m_aViewMonitor( m_aEventNotifier ) { DBG_CTOR(ODatabaseDocument,NULL); @@ -309,10 +343,8 @@ } // ----------------------------------------------------------------------------- -bool ODatabaseDocument::impl_import_throw( const ::comphelper::NamedValueCollection& _rResource ) +void ODatabaseDocument::impl_import_throw( const ::comphelper::NamedValueCollection& _rResource ) { - try - { Sequence< Any > aFilterArgs; Reference< XStatusIndicator > xStatusIndicator; lcl_extractAndStartStatusIndicator( _rResource, xStatusIndicator, aFilterArgs ); @@ -329,21 +361,12 @@ if ( xStatusIndicator.is() ) xStatusIndicator->end(); - } - catch( const RuntimeException& e ) - { - throw e; - } - catch( const Exception& ) - { - return false; - } - return true; } // ----------------------------------------------------------------------------- void SAL_CALL ODatabaseDocument::initNew( ) throw (DoubleInitializationException, IOException, Exception, RuntimeException) { + // SYNCHRONIZED -> ModelMethodGuard aGuard( *this, ModelMethodGuard::InitMethod ); impl_reset_nothrow(); @@ -362,13 +385,18 @@ m_pImpl->setInitialized(); - impl_setModified_throw( sal_False, aGuard ); + impl_setModified_nothrow( sal_False, aGuard ); + // <- SYNCHRONIZED + + m_aEventNotifier.notifyDocumentEvent( "OnCreate" ); + impl_notifyStorageChange_nolck_nothrow( xTempStor ); } // ----------------------------------------------------------------------------- void SAL_CALL ODatabaseDocument::load( const Sequence< PropertyValue >& _Arguments ) throw (DoubleInitializationException, IOException, Exception, RuntimeException) { + // SYNCHRONIZED -> ModelMethodGuard aGuard( *this, ModelMethodGuard::InitMethod ); impl_reset_nothrow(); @@ -383,25 +411,34 @@ m_pImpl->setInitializing(); try { - if ( !impl_import_throw( aResource ) ) - impl_reset_nothrow(); + impl_import_throw( aResource ); } catch( const Exception& ) { impl_reset_nothrow(); throw; } - m_pImpl->setInitialized(); + // note that we do *not* call m_pImpl->setInitialized here: The initialization is only complete + // when the XModel::attachResource has been called, not sooner. - impl_setModified_throw( sal_False, aGuard ); + impl_setModified_nothrow( sal_False, aGuard ); + // <- SYNCHRONIZED } // ----------------------------------------------------------------------------- // XModel sal_Bool SAL_CALL ODatabaseDocument::attachResource( const ::rtl::OUString& _rURL, const Sequence< PropertyValue >& _rArguments ) throw (RuntimeException) { - ModelMethodGuard aGuard( *this ); + ModelMethodGuard aGuard( *this, ModelMethodGuard::MethodUsedDuringInit ); m_pImpl->attachResource( _rURL, _rArguments ); + + if ( m_pImpl->isInitializing() ) + { // this means we've just been loaded, and this is the attachResource call which follows + // the load call. + m_pImpl->setInitialized(); + m_aEventNotifier.notifyDocumentEvent( "OnLoadFinished" ); + } + return sal_True; } @@ -426,23 +463,11 @@ m_aControllers.push_back( _xController ); - if ( m_aControllers.size() != 1 ) + bool bFirstControllerEver = m_aViewMonitor.onControllerConnected( _xController ); + if ( !bFirstControllerEver ) return; - // it's the first controller - - // check/adjust our macro mode. Note: This is only temporary. When we fully support the - // XEmbeddedScripts interface, plus related functionality, then the controller is able - // to do this itself, since we'll then have a UNO method for this. - // - // Also, the same has to happen in the loader then, since the checks must be made - // *before* OnLoad events are triggered - finally, the user can bind events to OnLoad ... - // (This, at the latest, implies we need a UNO equivalent for checkMacrosOnLoading, else - // the loader can't call it.) - // - // For now, as long as we do not have own macros, but only those in the embedded - // forms/reports, it's sufficient to do the check here. - // + // check/adjust our macro mode. m_pImpl->checkMacrosOnLoading(); } @@ -450,7 +475,6 @@ void SAL_CALL ODatabaseDocument::disconnectController( const Reference< XController >& _xController ) throw (RuntimeException) { ModelMethodGuard aGuard( *this ); - OSL_ENSURE(m_pImpl.is(),"Impl is NULL"); Controllers::iterator pos = ::std::find( m_aControllers.begin(), m_aControllers.end(), _xController ); OSL_ENSURE( pos != m_aControllers.end(), "ODatabaseDocument::disconnectController: don't know this controller!" ); @@ -484,7 +508,6 @@ void SAL_CALL ODatabaseDocument::lockControllers( ) throw (RuntimeException) { ModelMethodGuard aGuard( *this ); - OSL_ENSURE(m_pImpl.is(),"Impl is NULL"); ++m_pImpl->m_nControllerLockCount; } @@ -493,7 +516,6 @@ void SAL_CALL ODatabaseDocument::unlockControllers( ) throw (RuntimeException) { ModelMethodGuard aGuard( *this ); - OSL_ENSURE(m_pImpl.is(),"Impl is NULL"); --m_pImpl->m_nControllerLockCount; } @@ -502,7 +524,6 @@ sal_Bool SAL_CALL ODatabaseDocument::hasControllersLocked( ) throw (RuntimeException) { ModelMethodGuard aGuard( *this ); - OSL_ENSURE(m_pImpl.is(),"Impl is NULL"); return m_pImpl->m_nControllerLockCount != 0; } @@ -511,7 +532,6 @@ Reference< XController > SAL_CALL ODatabaseDocument::getCurrentController() throw (RuntimeException) { ModelMethodGuard aGuard( *this ); - OSL_ENSURE(m_pImpl.is(),"Impl is NULL"); return m_xCurrentController.is() ? m_xCurrentController : ( m_aControllers.empty() ? Reference< XController >() : *m_aControllers.begin() ); } @@ -520,15 +540,15 @@ void SAL_CALL ODatabaseDocument::setCurrentController( const Reference< XController >& _xController ) throw (NoSuchElementException, RuntimeException) { ModelMethodGuard aGuard( *this ); - OSL_ENSURE(m_pImpl.is(),"Impl is NULL"); m_xCurrentController = _xController; + + m_aViewMonitor.onSetCurrentController( _xController ); } // ----------------------------------------------------------------------------- Reference< XInterface > SAL_CALL ODatabaseDocument::getCurrentSelection( ) throw (RuntimeException) { ModelMethodGuard aGuard( *this ); - OSL_ENSURE(m_pImpl.is(),"Impl is NULL"); Reference< XInterface > xRet; Reference< XSelectionSupplier > xDocView( getCurrentController(), UNO_QUERY ); @@ -555,7 +575,6 @@ sal_Bool SAL_CALL ODatabaseDocument::isReadonly( ) throw (RuntimeException) { ModelMethodGuard aGuard( *this ); - OSL_ENSURE(m_pImpl.is(),"Impl is NULL"); return m_pImpl->m_bDocumentReadOnly; } @@ -568,16 +587,27 @@ if ( m_pImpl->m_bDocumentReadOnly ) throw IOException(); - impl_storeAs_throw( m_pImpl->getURL(), m_pImpl->getResource(), "OnSaveDone", aGuard ); + impl_storeAs_throw( m_pImpl->getURL(), m_pImpl->getResource(), SAVE, aGuard ); } // ----------------------------------------------------------------------------- void ODatabaseDocument::impl_storeAs_throw( const ::rtl::OUString& _rURL, const Sequence< PropertyValue>& _rArguments, - const sal_Char* _pAsciiDocumentEventName, ModelMethodGuard& _rGuard ) + const StoreType _eType, ModelMethodGuard& _rGuard ) { + OSL_PRECOND( ( _eType == SAVE ) || ( _eType == SAVE_AS ), + "ODatabaseDocument::impl_storeAs_throw: you introduced a new type which cannot be handled here!" ); + + { + _rGuard.clear(); + m_aEventNotifier.notifyDocumentEvent( _eType == SAVE ? "OnSave" : "OnSaveAs" ); + _rGuard.reset(); + } + Reference< XStorage > xNewRootStorage; // will be non-NULL if our storage changed + try + { sal_Bool bLocationChanged = ( _rURL != m_pImpl->getLocation() ); if ( bLocationChanged ) { @@ -611,18 +641,22 @@ // success - tell our impl m_pImpl->attachResource( _rURL, aMediaDescriptor ); - // create a document event (mutex still locked) - document::EventObject aEvent( *this, ::rtl::OUString::createFromAscii( _pAsciiDocumentEventName ) ); - // if we are in an initialization process, then this is finished, now that we stored the document if ( m_pImpl->isInitializing() ) m_pImpl->setInitialized(); - - // reset our "modified" flag, and clear the guard - impl_setModified_throw( sal_False, _rGuard ); + } + catch( const Exception& ) + { + // notify the failure + m_aEventNotifier.notifyDocumentEventAsync( _eType == SAVE ? "OnSaveFailed" : "OnSaveAsFailed" ); + throw; + } // notify the document event - impl_notifyEvent_nolck_nothrow( aEvent ); + m_aEventNotifier.notifyDocumentEventAsync( _eType == SAVE ? "OnSaveDone" : "OnSaveAsDone" ); + + // reset our "modified" flag, and clear the guard + impl_setModified_nothrow( sal_False, _rGuard ); // notify storage listeners impl_notifyStorageChange_nolck_nothrow( xNewRootStorage ); @@ -642,27 +676,33 @@ // ----------------------------------------------------------------------------- void SAL_CALL ODatabaseDocument::storeAsURL( const ::rtl::OUString& _rURL, const Sequence< PropertyValue >& _rArguments ) throw (IOException, RuntimeException) { + // SYNCHRONIZED -> ModelMethodGuard aGuard( *this, ModelMethodGuard::MethodWithoutInit ); // Normally, a document initialization is done via XLoadable::load or XLoadable::initNew. For convenience // reasons, and to not break existing API clients, it's allowed to call storeAsURL without having initialized // the document, in which case the initialization will be done implicitly. - if ( m_pImpl->isInitializing() ) + bool bImplicitInitialization = !m_pImpl->isInitialized(); // implicit initialization while another initialization is just running is not possible + if ( bImplicitInitialization && m_pImpl->isInitializing() ) throw DoubleInitializationException(); - if ( !m_pImpl->isInitialized() ) + if ( bImplicitInitialization ) m_pImpl->setInitializing(); try { - impl_storeAs_throw( _rURL, _rArguments, "OnSaveAsDone", aGuard ); + impl_storeAs_throw( _rURL, _rArguments, SAVE_AS, aGuard ); } catch( const Exception& ) { impl_reset_nothrow(); throw; } + // <- SYNCHRONIZED + + if ( bImplicitInitialization ) + m_aEventNotifier.notifyDocumentEvent( "OnCreate" ); } // ----------------------------------------------------------------------------- @@ -723,14 +763,14 @@ // XModifyBroadcaster void SAL_CALL ODatabaseDocument::addModifyListener( const Reference< XModifyListener >& _xListener ) throw (RuntimeException) { - ::connectivity::checkDisposed(ODatabaseDocument_OfficeDocument::rBHelper.bDisposed); + ModelMethodGuard aGuard( *this ); m_aModifyListeners.addInterface(_xListener); } // ----------------------------------------------------------------------------- void SAL_CALL ODatabaseDocument::removeModifyListener( const Reference< XModifyListener >& _xListener ) throw (RuntimeException) { - ::connectivity::checkDisposed(ODatabaseDocument_OfficeDocument::rBHelper.bDisposed); + ModelMethodGuard aGuard( *this ); m_aModifyListeners.removeInterface(_xListener); } @@ -739,7 +779,6 @@ sal_Bool SAL_CALL ODatabaseDocument::isModified( ) throw (RuntimeException) { ModelMethodGuard aGuard( *this ); - OSL_ENSURE(m_pImpl.is(),"Impl is NULL"); return m_pImpl->m_bModified; } @@ -748,11 +787,11 @@ void SAL_CALL ODatabaseDocument::setModified( sal_Bool _bModified ) throw (PropertyVetoException, RuntimeException) { ModelMethodGuard aGuard( *this, ModelMethodGuard::MethodUsedDuringInit ); - impl_setModified_throw( _bModified, aGuard ); + impl_setModified_nothrow( _bModified, aGuard ); } // ----------------------------------------------------------------------------- -void ODatabaseDocument::impl_setModified_throw( sal_Bool _bModified, ModelMethodGuard& _rGuard ) +void ODatabaseDocument::impl_setModified_nothrow( sal_Bool _bModified, ModelMethodGuard& _rGuard ) { if ( m_pImpl->m_bModified == _bModified ) return; @@ -762,26 +801,26 @@ m_pImpl->m_bModified = _bModified; - document::EventObject aEvent( *this, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OnModifyChanged" ) ) ); - _rGuard.clear(); + m_aEventNotifier.notifyDocumentEventAsync( "OnModifyChanged" ); - m_aModifyListeners.notifyEach( &XModifyListener::modified, (const lang::EventObject&)aEvent ); - impl_notifyEvent_nolck_nothrow( aEvent ); + _rGuard.clear(); + lang::EventObject aEvent( *this ); + m_aModifyListeners.notifyEach( &XModifyListener::modified, aEvent ); } // ----------------------------------------------------------------------------- // ::com::sun::star::document::XEventBroadcaster -void SAL_CALL ODatabaseDocument::addEventListener(const uno::Reference< document::XEventListener >& _xListener ) throw (uno::RuntimeException) +void SAL_CALL ODatabaseDocument::addEventListener(const uno::Reference< document::XEventListener >& _Listener ) throw (uno::RuntimeException) { - ::connectivity::checkDisposed(ODatabaseDocument_OfficeDocument::rBHelper.bDisposed); - m_aDocEventListeners.addInterface(_xListener); + ModelMethodGuard aGuard( *this, ModelMethodGuard::MethodWithoutInit ); + m_aEventNotifier.addDocumentEventListener( _Listener ); } // ----------------------------------------------------------------------------- -void SAL_CALL ODatabaseDocument::removeEventListener( const uno::Reference< document::XEventListener >& _xListener ) throw (uno::RuntimeException) +void SAL_CALL ODatabaseDocument::removeEventListener( const uno::Reference< document::XEventListener >& _Listener ) throw (uno::RuntimeException) { - ::connectivity::checkDisposed(ODatabaseDocument_OfficeDocument::rBHelper.bDisposed); - m_aDocEventListeners.removeInterface(_xListener); + ModelMethodGuard aGuard( *this, ModelMethodGuard::MethodWithoutInit ); + m_aEventNotifier.removeDocumentEventListener( _Listener ); } // ----------------------------------------------------------------------------- @@ -841,7 +880,7 @@ } // ----------------------------------------------------------------------------- -void ODatabaseDocument::impl_closeControllerFrames( sal_Bool _bDeliverOwnership ) +void ODatabaseDocument::impl_closeControllerFrames_nolck_throw( sal_Bool _bDeliverOwnership ) { Controllers aCopy = m_aControllers; @@ -893,40 +932,38 @@ } // ----------------------------------------------------------------------------- -void SAL_CALL ODatabaseDocument::close( sal_Bool _bDeliverOwnership ) throw (::com::sun::star::util::CloseVetoException, RuntimeException) +void SAL_CALL ODatabaseDocument::close( sal_Bool _bDeliverOwnership ) throw (CloseVetoException, RuntimeException) { + // everything below can/must be done without our mutex locked, the below is just for + // the checks for being disposed and the like + { ModelMethodGuard aGuard( *this ); + } - document::EventObject aEvent( *this, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OnUnload" ) ) ); - - { - aGuard.clear(); + // allow listeners to veto + lang::EventObject aEvent( *this ); m_aCloseListener.forEach< XCloseListener >( boost::bind( &XCloseListener::queryClosing, _1, boost::cref( aEvent ), boost::cref( _bDeliverOwnership ) ) ); - aGuard.reset(); - } - impl_closeControllerFrames( _bDeliverOwnership ); + // notify that we're going to unload + m_aEventNotifier.notifyDocumentEvent( "OnPrepareUnload" ); - aGuard.clear(); + impl_closeControllerFrames_nolck_throw( _bDeliverOwnership ); m_aCloseListener.notifyEach( &XCloseListener::notifyClosing, (const lang::EventObject&)aEvent ); - // notify the OnUnload at the earliest possibility - which is here and now - impl_notifyEvent_nolck_nothrow( aEvent ); - dispose(); } // ----------------------------------------------------------------------------- void SAL_CALL ODatabaseDocument::addCloseListener( const Reference< ::com::sun::star::util::XCloseListener >& Listener ) throw (RuntimeException) { - ::connectivity::checkDisposed(ODatabaseDocument_OfficeDocument::rBHelper.bDisposed); + ModelMethodGuard aGuard( *this ); m_aCloseListener.addInterface(Listener); } // ----------------------------------------------------------------------------- void SAL_CALL ODatabaseDocument::removeCloseListener( const Reference< ::com::sun::star::util::XCloseListener >& Listener ) throw (RuntimeException) { - ::connectivity::checkDisposed(ODatabaseDocument_OfficeDocument::rBHelper.bDisposed); + ModelMethodGuard aGuard( *this ); m_aCloseListener.removeInterface(Listener); } // ----------------------------------------------------------------------------- @@ -1043,7 +1080,6 @@ Reference< XUIConfigurationManager > SAL_CALL ODatabaseDocument::getUIConfigurationManager( ) throw (RuntimeException) { ModelMethodGuard aGuard( *this ); - OSL_ENSURE(m_pImpl.is(),"Impl is NULL"); if ( !m_xUIConfigurationManager.is() ) { @@ -1093,19 +1129,6 @@ return xStorageAccess->getDocumentSubStoragesNames(); } -// ----------------------------------------------------------------------------- -void ODatabaseDocument::impl_notifyEvent_nolck_nothrow( const document::EventObject& _rEvent ) -{ - try - { - m_aDocEventListeners.notifyEach( &document::XEventListener::notifyEvent, _rEvent ); - } - catch(const Exception&) - { - DBG_UNHANDLED_EXCEPTION(); - } -} - //------------------------------------------------------------------------------ void ODatabaseDocument::impl_notifyStorageChange_nolck_nothrow( const Reference< XStorage >& _rxNewRootStorage ) { @@ -1125,18 +1148,24 @@ return; } - DBG_ASSERT( m_aControllers.empty(), "ODatabaseDocument::disposing: there still are controllers!" ); - // normally, nobody should explicitly dispose, but only XCloseable::close the document. And upon - // closing, our controllers are closed, too + m_aEventNotifier.notifyDocumentEvent( "OnUnload" ); Reference< XModel > xHoldAlive( this ); - { + + m_aEventNotifier.disposing(); + lang::EventObject aDisposeEvent(static_cast<XWeak*>(this)); m_aModifyListeners.disposeAndClear( aDisposeEvent ); m_aCloseListener.disposeAndClear( aDisposeEvent ); - m_aDocEventListeners.disposeAndClear( aDisposeEvent ); m_aStorageListeners.disposeAndClear( aDisposeEvent ); + // SYNCHRONIZED -> + ::osl::MutexGuard aGuard( m_xMutex->getMutex() ); + + DBG_ASSERT( m_aControllers.empty(), "ODatabaseDocument::disposing: there still are controllers!" ); + // normally, nobody should explicitly dispose, but only XCloseable::close the document. And upon + // closing, our controllers are closed, too + m_xUIConfigurationManager = NULL; clearObjectContainer( m_xForms ); @@ -1148,11 +1177,12 @@ // expected to listen for our disposal, and disconnect then DBG_ASSERT( m_aControllers.empty(), "ODatabaseDocument::disposing: there still are controllers!" ); impl_disposeControllerFrames_nothrow(); + m_xModuleManager.clear(); m_xTitleHelper.clear(); - } m_pImpl.clear(); + // <- SYNCHRONIZED } // ----------------------------------------------------------------------------- // XComponent @@ -1257,7 +1287,7 @@ Reference< XStorage > SAL_CALL ODatabaseDocument::getDocumentStorage( ) throw (IOException, Exception, RuntimeException) { ModelMethodGuard aGuard( *this ); - return m_pImpl->getRootStorage(); + return m_pImpl->getOrCreateRootStorage(); } // ----------------------------------------------------------------------------- File [changed]: databasedocument.hxx Url: http://dba.openoffice.org/source/browse/dba/dbaccess/source/core/dataaccess/databasedocument.hxx?r1=1.20.2.6&r2=1.20.2.7 Delta lines: +61 -13 --------------------- --- databasedocument.hxx 2008-07-24 05:34:15+0000 1.20.2.6 +++ databasedocument.hxx 2008-07-28 06:25:00+0000 1.20.2.7 @@ -7,7 +7,7 @@ * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: databasedocument.hxx,v $ - * $Revision: 1.20.2.6 $ + * $Revision: 1.20.2.7 $ * * This file is part of OpenOffice.org. * @@ -31,6 +31,7 @@ #define _DBA_COREDATAACCESS_DATABASEDOCUMENT_HXX_ #include "ModelImpl.hxx" +#include "documenteventnotifier.hxx" /** === begin UNO includes === **/ #include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp> @@ -86,6 +87,45 @@ typedef ::std::vector< ::com::sun::star::uno::Reference< ::com::sun::star::frame::XController > > Controllers; //============================================================ +//= ViewMonitor +//============================================================ +/** helper class monitoring the views of a document, and firing appropriate events + when views are attached / detached +*/ +class ViewMonitor +{ +public: + ViewMonitor( DocumentEventNotifier& _rEventNotifier ) + :m_rEventNotifier( _rEventNotifier ) + ,m_bEverHadController( false ) + ,m_bLastIsFirstEverController( false ) + ,m_xLastConnectedController() + { + } + + /** to be called when a view (aka controller) has been connected to the document + @return + <TRUE/> if and only if this was the first-ever controller connected to the document + */ + bool onControllerConnected( + const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XController >& _rxController + ); + + /** to be called when a controller is set as current controller + */ + void onSetCurrentController( + const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XController >& _rxController + ); + +private: + DocumentEventNotifier& m_rEventNotifier; + bool m_bEverHadController; + bool m_bLastIsFirstEverController; + ::com::sun::star::uno::Reference< ::com::sun::star::frame::XController > + m_xLastConnectedController; +}; + +//============================================================ //= ODatabaseDocument //============================================================ typedef ::comphelper::WeakComponentImplHelper15 < ::com::sun::star::frame::XModel2 @@ -119,13 +159,15 @@ ::cppu::OInterfaceContainerHelper m_aModifyListeners; ::cppu::OInterfaceContainerHelper m_aCloseListener; - ::cppu::OInterfaceContainerHelper m_aDocEventListeners; ::cppu::OInterfaceContainerHelper m_aStorageListeners; - ::com::sun::star::uno::Reference< ::com::sun::star::frame::XController > m_xCurrentController; - Controllers m_aControllers; DocumentEvents* m_pEventContainer; ::rtl::Reference< DocumentEventExecutor > m_pEventExecutor; + DocumentEventNotifier m_aEventNotifier; + + ::com::sun::star::uno::Reference< ::com::sun::star::frame::XController > m_xCurrentController; + Controllers m_aControllers; + ViewMonitor m_aViewMonitor; ::com::sun::star::uno::WeakReference< ::com::sun::star::container::XNameAccess > m_xForms; ::com::sun::star::uno::WeakReference< ::com::sun::star::container::XNameAccess > m_xReports; @@ -136,21 +178,27 @@ ::com::sun::star::uno::Reference< ::com::sun::star::frame::XTitle > m_xTitleHelper; TNumberedController m_aNumberedControllers; + enum StoreType { SAVE, SAVE_AS }; /** stores the document to the given URL, rebases it to the respective new storage, if necessary, resets the modified flag, and notifies any listeners as required + + @param _rURL + the URL to store the document to + @param _rArguments + arguments for storing the document (MediaDescriptor) + @param _eType + the type of the store process (Save or SaveAs). The method will automatically + notify the proper events for this type. + @param _rGuard + the instance lock to be released before doing synchronous notifications */ void impl_storeAs_throw( const ::rtl::OUString& _rURL, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue>& _rArguments, - const sal_Char* _pAsciiDocumentEventName, + const StoreType _eType, ModelMethodGuard& _rGuard ); - /** notifies the global event broadcaster - The method must be called without our mutex locked - */ - void impl_notifyEvent_nolck_nothrow( const ::com::sun::star::document::EventObject& _rEvent ); - /** notifies our storage change listeners that our underlying storage changed @param _rxNewRootStorage @@ -376,7 +424,7 @@ @raises ::com::sun::star::util::CloseVetoException if the closing was vetoed by any instance */ - void impl_closeControllerFrames( sal_Bool _bDeliverOwnership ); + void impl_closeControllerFrames_nolck_throw( sal_Bool _bDeliverOwnership ); /** disposes the frames of all controllers which are still left in m_aControllers. */ @@ -409,7 +457,7 @@ /** imports the document from the given resource. */ - bool impl_import_throw( const ::comphelper::NamedValueCollection& _rResource ); + void impl_import_throw( const ::comphelper::NamedValueCollection& _rResource ); /** creates a storage for the given URL, truncating it if a file with this name already exists @@ -426,7 +474,7 @@ /** clears the guard before notifying. */ - void impl_setModified_throw( sal_Bool _bModified, ModelMethodGuard& _rGuard ); + void impl_setModified_nothrow( sal_Bool _bModified, ModelMethodGuard& _rGuard ); /** stores the document to the given storage --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
