diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2014-01-16 09:25:21 +0100 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2014-01-16 18:40:06 +0100 |
commit | 3557c07899e363a9b7e1cceca632ad9112d039a2 (patch) | |
tree | 0aab96a0360f038c5b51a9a8e993fd489c31f247 /sfx2 | |
parent | 62951cdd17530f6218232f3d482bfd4ddd8a95ec (diff) |
Revert "Revert "sfx: Use constructor feature for SfxGlobalEvents_Impl.""
This reverts commit ef37781683e28d1837cfce86de990e59d2c10c5f, now that
constructor function support for singleton implementations is in place and the
proper singleton theGlobalEventBroadcaster has been introduced (and drops
sfx_component_getFactory completely, which had become unused except for
SfxGlobalEvents_Impl in the meantime).
Change-Id: I2d587989dd0a1fbea6fe75f7dc2af954ac81c4ed
Diffstat (limited to 'sfx2')
-rw-r--r-- | sfx2/Library_sfx.mk | 1 | ||||
-rw-r--r-- | sfx2/source/appl/appuno.cxx | 45 | ||||
-rw-r--r-- | sfx2/source/inc/eventsupplier.hxx | 137 | ||||
-rw-r--r-- | sfx2/source/notify/eventsupplier.cxx | 353 | ||||
-rw-r--r-- | sfx2/source/notify/globalevents.cxx | 542 | ||||
-rw-r--r-- | sfx2/util/sfx.component | 3 |
6 files changed, 549 insertions, 532 deletions
diff --git a/sfx2/Library_sfx.mk b/sfx2/Library_sfx.mk index bdd68121a8e1..f4eafa2f9483 100644 --- a/sfx2/Library_sfx.mk +++ b/sfx2/Library_sfx.mk @@ -236,6 +236,7 @@ $(eval $(call gb_Library_add_exception_objects,sfx,\ sfx2/source/menu/thessubmenu \ sfx2/source/menu/virtmenu \ sfx2/source/notify/eventsupplier \ + sfx2/source/notify/globalevents \ sfx2/source/notify/hintpost \ sfx2/source/sidebar/Sidebar \ sfx2/source/sidebar/SidebarChildWindow \ diff --git a/sfx2/source/appl/appuno.cxx b/sfx2/source/appl/appuno.cxx index 778ec14f47d5..a642ce5860ba 100644 --- a/sfx2/source/appl/appuno.cxx +++ b/sfx2/source/appl/appuno.cxx @@ -21,7 +21,6 @@ #pragma warning( disable : 4290 ) #endif -#include "eventsupplier.hxx" #include "fltoptint.hxx" #include "objshimp.hxx" #include <sfx2/app.hxx> @@ -1693,50 +1692,6 @@ void TransformItems( sal_uInt16 nSlotId, const SfxItemSet& rSet, uno::Sequence<b rArgs = aSequ; } -// ----------------------------------------------------------------------- - -extern "C" { - -SFX2_DLLPUBLIC void* SAL_CALL sfx_component_getFactory( - const sal_Char* pImplementationName , - void* pServiceManager , - void* ) -{ - // Set default return value for this operation - if it failed. - void* pReturn = NULL ; - - if ( - ( pImplementationName != NULL ) && - ( pServiceManager != NULL ) - ) - { - // Define variables which are used in following macros. - uno::Reference<uno::XInterface> xFactory; - uno::Reference<lang::XMultiServiceFactory> xServiceManager( reinterpret_cast<lang::XMultiServiceFactory*>( pServiceManager ) ) ; - - //============================================================================= - // Add new macro line to handle new service. - // !!! ATTENTION !!! - // Write no ";" at end of line and dont forget "else" ! (see macro) - //============================================================================= - IF_NAME_CREATECOMPONENTFACTORY( SfxGlobalEvents_Impl ) - - // Factory is valid - service was found. - - // Factory is valid - service was found. - if ( xFactory.is() ) - { - xFactory->acquire(); - pReturn = xFactory.get(); - } - } - // Return with result of this operation. - return pReturn ; -} -} // extern "C" - -//========================================================================= - void SAL_CALL FilterOptionsContinuation::setFilterOptions( const uno::Sequence<beans::PropertyValue>& rProps ) throw (uno::RuntimeException) diff --git a/sfx2/source/inc/eventsupplier.hxx b/sfx2/source/inc/eventsupplier.hxx index 2465ca8919fa..d8d2a8d124da 100644 --- a/sfx2/source/inc/eventsupplier.hxx +++ b/sfx2/source/inc/eventsupplier.hxx @@ -20,9 +20,9 @@ #ifndef INCLUDED_SFX2_SOURCE_INC_EVENTSUPPLIER_HXX #define INCLUDED_SFX2_SOURCE_INC_EVENTSUPPLIER_HXX -#include <com/sun/star/lang/XTypeProvider.hpp> +#include <sal/types.h> + #include <com/sun/star/container/XNameReplace.hpp> -#include <com/sun/star/container/XSet.hpp> #include <com/sun/star/document/XEventListener.hpp> #include <com/sun/star/document/XEventBroadcaster.hpp> #include <com/sun/star/document/XDocumentEventListener.hpp> @@ -32,11 +32,7 @@ #include <com/sun/star/task/XJobExecutor.hpp> #include <com/sun/star/uno/Reference.hxx> #include <com/sun/star/uno/Type.hxx> -#include <sal/types.h> -#include <osl/mutex.hxx> -#include <cppuhelper/implbase1.hxx> #include <cppuhelper/implbase2.hxx> -#include <cppuhelper/implbase3.hxx> #include <comphelper/sequenceashashmap.hxx> #include <comphelper/sequenceasvector.hxx> #include <sfx2/sfxuno.hxx> @@ -98,134 +94,7 @@ public: const ::comphelper::NamedValueCollection& i_eventDescriptor, ::comphelper::NamedValueCollection& o_normalizedDescriptor, SfxObjectShell* i_document ); -}; - -//============================================================================= -struct ModelCollectionMutexBase -{ - public: - ::osl::Mutex m_aLock; -}; - -//============================================================================= -typedef ::std::vector< css::uno::Reference< css::frame::XModel > > TModelList; - -//============================================================================= -class ModelCollectionEnumeration : public ModelCollectionMutexBase - , public ::cppu::WeakImplHelper1< css::container::XEnumeration > -{ - - //------------------------------------------------------------------------- - // member - //------------------------------------------------------------------------- - private: - TModelList m_lModels; - TModelList::iterator m_pEnumerationIt; - - //------------------------------------------------------------------------- - // native interface - //------------------------------------------------------------------------- - public: - ModelCollectionEnumeration(); - virtual ~ModelCollectionEnumeration(); - void setModelList(const TModelList& rList); - - //------------------------------------------------------------------------- - // uno interface - //------------------------------------------------------------------------- - public: - - // css.container.XEnumeration - virtual sal_Bool SAL_CALL hasMoreElements() - throw(css::uno::RuntimeException); - - virtual css::uno::Any SAL_CALL nextElement() - throw(css::container::NoSuchElementException, - css::lang::WrappedTargetException , - css::uno::RuntimeException ); -}; - -//============================================================================= -//TODO: remove support of obsolete document::XEventBroadcaster/Listener -class SfxGlobalEvents_Impl : public ModelCollectionMutexBase - , public ::cppu::WeakImplHelper3< css::lang::XServiceInfo - , css::frame::XGlobalEventBroadcaster - , css::document::XEventListener - > -{ - css::uno::Reference< css::container::XNameReplace > m_xEvents; - css::uno::Reference< css::document::XEventListener > m_xJobExecutorListener; - ::cppu::OInterfaceContainerHelper m_aLegacyListeners; - ::cppu::OInterfaceContainerHelper m_aDocumentListeners; - TModelList m_lModels; - GlobalEventConfig* pImp; - -public: - SfxGlobalEvents_Impl(const css::uno::Reference < css::uno::XComponentContext >& rxContext); - virtual ~SfxGlobalEvents_Impl(); - - SFX_DECL_XSERVICEINFO - - // css.document.XEventBroadcaster - virtual css::uno::Reference< css::container::XNameReplace > SAL_CALL getEvents() - throw(css::uno::RuntimeException); - - virtual void SAL_CALL addEventListener(const css::uno::Reference< css::document::XEventListener >& xListener) - throw(css::uno::RuntimeException); - - virtual void SAL_CALL removeEventListener( const css::uno::Reference< css::document::XEventListener >& xListener) - throw(css::uno::RuntimeException); - - // css.document.XDocumentEventBroadcaster - virtual void SAL_CALL addDocumentEventListener( const css::uno::Reference< css::document::XDocumentEventListener >& _Listener ) throw (css::uno::RuntimeException); - virtual void SAL_CALL removeDocumentEventListener( const css::uno::Reference< css::document::XDocumentEventListener >& _Listener ) throw (css::uno::RuntimeException); - virtual void SAL_CALL notifyDocumentEvent( const OUString& _EventName, const css::uno::Reference< css::frame::XController2 >& _ViewController, const css::uno::Any& _Supplement ) throw (css::lang::IllegalArgumentException, css::lang::NoSupportException, css::uno::RuntimeException); - - // css.document.XEventListener - virtual void SAL_CALL notifyEvent(const css::document::EventObject& aEvent) - throw(css::uno::RuntimeException); - - // css.document.XDocumentEventListener - virtual void SAL_CALL documentEventOccured( const css::document::DocumentEvent& Event ) throw (css::uno::RuntimeException); - - // css.container.XSet - virtual sal_Bool SAL_CALL has(const css::uno::Any& aElement) - throw(css::uno::RuntimeException); - - virtual void SAL_CALL insert(const css::uno::Any& aElement) - throw(css::lang::IllegalArgumentException , - css::container::ElementExistException, - css::uno::RuntimeException ); - - virtual void SAL_CALL remove(const css::uno::Any& aElement) - throw(css::lang::IllegalArgumentException , - css::container::NoSuchElementException, - css::uno::RuntimeException ); - - // css.container.XEnumerationAccess - virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() - throw(css::uno::RuntimeException); - - // css.container.XElementAccess - virtual css::uno::Type SAL_CALL getElementType() - throw(css::uno::RuntimeException); - - virtual sal_Bool SAL_CALL hasElements() - throw(css::uno::RuntimeException); - - // css.lang.XEventListener - virtual void SAL_CALL disposing(const css::lang::EventObject& aEvent) - throw(css::uno::RuntimeException); - -private: - - // threadsafe - void implts_notifyJobExecution(const css::document::EventObject& aEvent); - void implts_checkAndExecuteEventBindings(const css::document::DocumentEvent& aEvent); - void implts_notifyListener(const css::document::DocumentEvent& aEvent); - - // not threadsafe - TModelList::iterator impl_searchDoc(const css::uno::Reference< css::frame::XModel >& xModel); + static void Execute( css::uno::Any& aEventData, const css::document::DocumentEvent& aTrigger, SfxObjectShell* pDoc ); }; #endif diff --git a/sfx2/source/notify/eventsupplier.cxx b/sfx2/source/notify/eventsupplier.cxx index 418f35d3b867..067ae2154abd 100644 --- a/sfx2/source/notify/eventsupplier.cxx +++ b/sfx2/source/notify/eventsupplier.cxx @@ -179,7 +179,7 @@ sal_Bool SAL_CALL SfxEvents_Impl::hasElements() throw ( uno::RuntimeException ) return sal_False; } -static void Execute( uno::Any& aEventData, const document::DocumentEvent& aTrigger, SfxObjectShell* pDoc ) +void SfxEvents_Impl::Execute( uno::Any& aEventData, const document::DocumentEvent& aTrigger, SfxObjectShell* pDoc ) { uno::Sequence < beans::PropertyValue > aProperties; if ( aEventData >>= aProperties ) @@ -488,355 +488,4 @@ void SfxEvents_Impl::NormalizeMacro( const ::comphelper::NamedValueCollection& i } } -ModelCollectionEnumeration::ModelCollectionEnumeration() - : ModelCollectionMutexBase( ) - , m_pEnumerationIt (m_lModels.begin()) -{ -} - -ModelCollectionEnumeration::~ModelCollectionEnumeration() -{ -} - -void ModelCollectionEnumeration::setModelList(const TModelList& rList) -{ - // SAFE -> - ::osl::ResettableMutexGuard aLock(m_aLock); - m_lModels = rList; - m_pEnumerationIt = m_lModels.begin(); - aLock.clear(); - // <- SAFE -} - -sal_Bool SAL_CALL ModelCollectionEnumeration::hasMoreElements() - throw(uno::RuntimeException) -{ - // SAFE -> - ::osl::ResettableMutexGuard aLock(m_aLock); - return (m_pEnumerationIt != m_lModels.end()); - // <- SAFE -} - -uno::Any SAL_CALL ModelCollectionEnumeration::nextElement() - throw(container::NoSuchElementException, - lang::WrappedTargetException , - uno::RuntimeException ) -{ - // SAFE -> - ::osl::ResettableMutexGuard aLock(m_aLock); - if (m_pEnumerationIt == m_lModels.end()) - throw container::NoSuchElementException( - OUString("End of model enumeration reached."), - static_cast< container::XEnumeration* >(this)); - uno::Reference< frame::XModel > xModel(*m_pEnumerationIt, uno::UNO_QUERY); - ++m_pEnumerationIt; - aLock.clear(); - // <- SAFE - - return uno::makeAny(xModel); -} - -SFX_IMPL_XSERVICEINFO_CTX( SfxGlobalEvents_Impl, "com.sun.star.frame.GlobalEventBroadcaster", "com.sun.star.comp.sfx2.GlobalEventBroadcaster" ) -SFX_IMPL_ONEINSTANCEFACTORY( SfxGlobalEvents_Impl ); - -//----------------------------------------------------------------------------- -SfxGlobalEvents_Impl::SfxGlobalEvents_Impl( const uno::Reference < uno::XComponentContext >& rxContext) - : ModelCollectionMutexBase( ) - , m_xJobExecutorListener( task::JobExecutor::create( rxContext ), uno::UNO_QUERY_THROW ) - , m_aLegacyListeners (m_aLock) - , m_aDocumentListeners (m_aLock) - , pImp (0 ) -{ - m_refCount++; - SFX_APP(); - pImp = new GlobalEventConfig(); - m_xEvents = pImp; - m_refCount--; -} - -//----------------------------------------------------------------------------- -SfxGlobalEvents_Impl::~SfxGlobalEvents_Impl() -{ -} - -//----------------------------------------------------------------------------- -uno::Reference< container::XNameReplace > SAL_CALL SfxGlobalEvents_Impl::getEvents() - throw(uno::RuntimeException) -{ - // SAFE -> - ::osl::ResettableMutexGuard aLock(m_aLock); - return m_xEvents; - // <- SAFE -} - -//----------------------------------------------------------------------------- -void SAL_CALL SfxGlobalEvents_Impl::addEventListener(const uno::Reference< document::XEventListener >& xListener) - throw(uno::RuntimeException) -{ - // container is threadsafe - m_aLegacyListeners.addInterface(xListener); -} - -//----------------------------------------------------------------------------- -void SAL_CALL SfxGlobalEvents_Impl::removeEventListener(const uno::Reference< document::XEventListener >& xListener) - throw(uno::RuntimeException) -{ - // container is threadsafe - m_aLegacyListeners.removeInterface(xListener); -} - -//----------------------------------------------------------------------------- -void SAL_CALL SfxGlobalEvents_Impl::addDocumentEventListener( const uno::Reference< document::XDocumentEventListener >& _Listener ) - throw(uno::RuntimeException) -{ - m_aDocumentListeners.addInterface( _Listener ); -} - -//----------------------------------------------------------------------------- -void SAL_CALL SfxGlobalEvents_Impl::removeDocumentEventListener( const uno::Reference< document::XDocumentEventListener >& _Listener ) - throw(uno::RuntimeException) -{ - m_aDocumentListeners.removeInterface( _Listener ); -} - -//----------------------------------------------------------------------------- -void SAL_CALL SfxGlobalEvents_Impl::notifyDocumentEvent( const OUString& /*_EventName*/, - const uno::Reference< frame::XController2 >& /*_ViewController*/, const uno::Any& /*_Supplement*/ ) - throw (lang::IllegalArgumentException, lang::NoSupportException, uno::RuntimeException) -{ - // we're a multiplexer only, no chance to generate artifical events here - throw lang::NoSupportException(OUString(), *this); -} - -//----------------------------------------------------------------------------- -void SAL_CALL SfxGlobalEvents_Impl::notifyEvent(const document::EventObject& aEvent) - throw(uno::RuntimeException) -{ - document::DocumentEvent aDocEvent(aEvent.Source, aEvent.EventName, NULL, uno::Any()); - implts_notifyJobExecution(aEvent); - implts_checkAndExecuteEventBindings(aDocEvent); - implts_notifyListener(aDocEvent); -} - -//----------------------------------------------------------------------------- -void SAL_CALL SfxGlobalEvents_Impl::documentEventOccured( const document::DocumentEvent& _Event ) - throw (uno::RuntimeException) -{ - implts_notifyJobExecution(document::EventObject(_Event.Source, _Event.EventName)); - implts_checkAndExecuteEventBindings(_Event); - implts_notifyListener(_Event); -} - -//----------------------------------------------------------------------------- -void SAL_CALL SfxGlobalEvents_Impl::disposing(const lang::EventObject& aEvent) - throw(uno::RuntimeException) -{ - uno::Reference< frame::XModel > xDoc(aEvent.Source, uno::UNO_QUERY); - - // SAFE -> - ::osl::ResettableMutexGuard aLock(m_aLock); - TModelList::iterator pIt = impl_searchDoc(xDoc); - if (pIt != m_lModels.end()) - m_lModels.erase(pIt); - aLock.clear(); - // <- SAFE -} - -//----------------------------------------------------------------------------- -sal_Bool SAL_CALL SfxGlobalEvents_Impl::has(const uno::Any& aElement) - throw (uno::RuntimeException) -{ - uno::Reference< frame::XModel > xDoc; - aElement >>= xDoc; - - sal_Bool bHas = sal_False; - - // SAFE -> - ::osl::ResettableMutexGuard aLock(m_aLock); - TModelList::iterator pIt = impl_searchDoc(xDoc); - if (pIt != m_lModels.end()) - bHas = sal_True; - aLock.clear(); - // <- SAFE - - return bHas; -} - -//----------------------------------------------------------------------------- -void SAL_CALL SfxGlobalEvents_Impl::insert( const uno::Any& aElement ) - throw (lang::IllegalArgumentException , - container::ElementExistException, - uno::RuntimeException ) -{ - uno::Reference< frame::XModel > xDoc; - aElement >>= xDoc; - if (!xDoc.is()) - throw lang::IllegalArgumentException( - OUString("Cant locate at least the model parameter."), - static_cast< container::XSet* >(this), - 0); - - // SAFE -> - ::osl::ResettableMutexGuard aLock(m_aLock); - TModelList::iterator pIt = impl_searchDoc(xDoc); - if (pIt != m_lModels.end()) - throw container::ElementExistException( - OUString(), - static_cast< container::XSet* >(this)); - m_lModels.push_back(xDoc); - aLock.clear(); - // <- SAFE - - uno::Reference< document::XDocumentEventBroadcaster > xDocBroadcaster(xDoc, uno::UNO_QUERY ); - if (xDocBroadcaster.is()) - xDocBroadcaster->addDocumentEventListener(this); - else - { - // try the "legacy version" of XDocumentEventBroadcaster, which is XEventBroadcaster - uno::Reference< document::XEventBroadcaster > xBroadcaster(xDoc, uno::UNO_QUERY); - if (xBroadcaster.is()) - xBroadcaster->addEventListener(static_cast< document::XEventListener* >(this)); - } -} - -//----------------------------------------------------------------------------- -void SAL_CALL SfxGlobalEvents_Impl::remove( const uno::Any& aElement ) - throw (lang::IllegalArgumentException , - container::NoSuchElementException, - uno::RuntimeException ) -{ - uno::Reference< frame::XModel > xDoc; - aElement >>= xDoc; - if (!xDoc.is()) - throw lang::IllegalArgumentException( - OUString("Cant locate at least the model parameter."), - static_cast< container::XSet* >(this), - 0); - - // SAFE -> - ::osl::ResettableMutexGuard aLock(m_aLock); - TModelList::iterator pIt = impl_searchDoc(xDoc); - if (pIt == m_lModels.end()) - throw container::NoSuchElementException( - OUString(), - static_cast< container::XSet* >(this)); - m_lModels.erase(pIt); - aLock.clear(); - // <- SAFE - - uno::Reference< document::XDocumentEventBroadcaster > xDocBroadcaster(xDoc, uno::UNO_QUERY ); - if (xDocBroadcaster.is()) - xDocBroadcaster->removeDocumentEventListener(this); - else - { - // try the "legacy version" of XDocumentEventBroadcaster, which is XEventBroadcaster - uno::Reference< document::XEventBroadcaster > xBroadcaster(xDoc, uno::UNO_QUERY); - if (xBroadcaster.is()) - xBroadcaster->removeEventListener(static_cast< document::XEventListener* >(this)); - } -} - -//----------------------------------------------------------------------------- -uno::Reference< container::XEnumeration > SAL_CALL SfxGlobalEvents_Impl::createEnumeration() - throw (uno::RuntimeException) -{ - // SAFE -> - ::osl::ResettableMutexGuard aLock(m_aLock); - ModelCollectionEnumeration* pEnum = new ModelCollectionEnumeration(); - pEnum->setModelList(m_lModels); - uno::Reference< container::XEnumeration > xEnum( - static_cast< container::XEnumeration* >(pEnum), - uno::UNO_QUERY); - aLock.clear(); - // <- SAFE - - return xEnum; -} - -//----------------------------------------------------------------------------- -uno::Type SAL_CALL SfxGlobalEvents_Impl::getElementType() - throw (uno::RuntimeException) -{ - return ::getCppuType(static_cast< uno::Reference< frame::XModel >* >(NULL)); -} - -//----------------------------------------------------------------------------- -sal_Bool SAL_CALL SfxGlobalEvents_Impl::hasElements() - throw (uno::RuntimeException) -{ - // SAFE -> - ::osl::ResettableMutexGuard aLock(m_aLock); - return (m_lModels.size()>0); - // <- SAFE -} - -//----------------------------------------------------------------------------- -void SfxGlobalEvents_Impl::implts_notifyJobExecution(const document::EventObject& aEvent) -{ - try - { - m_xJobExecutorListener->notifyEvent(aEvent); - } - catch(const uno::RuntimeException&) - { throw; } - catch(const uno::Exception&) - {} -} - -//----------------------------------------------------------------------------- -void SfxGlobalEvents_Impl::implts_checkAndExecuteEventBindings(const document::DocumentEvent& aEvent) -{ - try - { - // SAFE -> - ::osl::ResettableMutexGuard aLock(m_aLock); - uno::Reference< container::XNameReplace > xEvents = m_xEvents; - aLock.clear(); - // <- SAFE - - uno::Any aAny; - if ( xEvents.is() && xEvents->hasByName( aEvent.EventName ) ) - aAny = xEvents->getByName(aEvent.EventName); - Execute(aAny, aEvent, 0); - } - catch ( uno::RuntimeException const & ) - { - throw; - } - catch ( uno::Exception const & ) - { - DBG_UNHANDLED_EXCEPTION(); - } -} - -//----------------------------------------------------------------------------- -void SfxGlobalEvents_Impl::implts_notifyListener(const document::DocumentEvent& aEvent) -{ - // containers are threadsafe - document::EventObject aLegacyEvent(aEvent.Source, aEvent.EventName); - m_aLegacyListeners.notifyEach( &document::XEventListener::notifyEvent, aLegacyEvent ); - - m_aDocumentListeners.notifyEach( &document::XDocumentEventListener::documentEventOccured, aEvent ); -} - -//----------------------------------------------------------------------------- -// not threadsafe ... must be locked from outside! -TModelList::iterator SfxGlobalEvents_Impl::impl_searchDoc(const uno::Reference< frame::XModel >& xModel) -{ - if (!xModel.is()) - return m_lModels.end(); - - TModelList::iterator pIt; - for ( pIt = m_lModels.begin(); - pIt != m_lModels.end() ; - ++pIt ) - { - uno::Reference< frame::XModel > xContainerDoc(*pIt, uno::UNO_QUERY); - if (xContainerDoc == xModel) - break; - } - - return pIt; -} - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sfx2/source/notify/globalevents.cxx b/sfx2/source/notify/globalevents.cxx new file mode 100644 index 000000000000..b8f5c428798b --- /dev/null +++ b/sfx2/source/notify/globalevents.cxx @@ -0,0 +1,542 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <sal/types.h> + +#include <com/sun/star/task/JobExecutor.hpp> +#include <com/sun/star/container/XNameReplace.hpp> +#include <com/sun/star/container/XSet.hpp> +#include <com/sun/star/document/XEventListener.hpp> +#include <com/sun/star/document/XEventBroadcaster.hpp> +#include <com/sun/star/document/XDocumentEventListener.hpp> +#include <com/sun/star/frame/XGlobalEventBroadcaster.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/uno/Type.hxx> + +#include <cppuhelper/implbase1.hxx> +#include <cppuhelper/implbase3.hxx> +#include <cppuhelper/interfacecontainer.hxx> +#include <cppuhelper/supportsservice.hxx> +#include <rtl/ref.hxx> +#include <sfx2/app.hxx> +#include <sfx2/objsh.hxx> +#include <sfx2/sfxbasemodel.hxx> +#include <sfx2/evntconf.hxx> +#include <tools/diagnose_ex.h> +#include <unotools/eventcfg.hxx> +#include <eventsupplier.hxx> + +#include <vector> + +using namespace css; + +namespace { + +struct ModelCollectionMutexBase +{ +public: + osl::Mutex m_aLock; +}; + +typedef ::std::vector< css::uno::Reference< css::frame::XModel > > TModelList; + +class ModelCollectionEnumeration : public ModelCollectionMutexBase + , public ::cppu::WeakImplHelper1< css::container::XEnumeration > +{ +private: + TModelList m_lModels; + TModelList::iterator m_pEnumerationIt; + +public: + ModelCollectionEnumeration(); + virtual ~ModelCollectionEnumeration(); + void setModelList(const TModelList& rList); + + // css.container.XEnumeration + virtual sal_Bool SAL_CALL hasMoreElements() + throw(css::uno::RuntimeException); + + virtual css::uno::Any SAL_CALL nextElement() + throw(css::container::NoSuchElementException, + css::lang::WrappedTargetException , + css::uno::RuntimeException ); +}; + +//============================================================================= +//TODO: remove support of obsolete document::XEventBroadcaster/Listener +class SfxGlobalEvents_Impl : public ModelCollectionMutexBase + , public ::cppu::WeakImplHelper3< css::lang::XServiceInfo + , css::frame::XGlobalEventBroadcaster + , css::document::XEventListener + > +{ + css::uno::Reference< css::container::XNameReplace > m_xEvents; + css::uno::Reference< css::document::XEventListener > m_xJobExecutorListener; + ::cppu::OInterfaceContainerHelper m_aLegacyListeners; + ::cppu::OInterfaceContainerHelper m_aDocumentListeners; + TModelList m_lModels; + GlobalEventConfig* pImp; + +public: + SfxGlobalEvents_Impl(const css::uno::Reference < css::uno::XComponentContext >& rxContext); + virtual ~SfxGlobalEvents_Impl(); + + virtual OUString SAL_CALL getImplementationName() + throw (css::uno::RuntimeException) + { + return OUString("com.sun.star.comp.sfx2.GlobalEventBroadcaster"); + } + + virtual sal_Bool SAL_CALL supportsService(OUString const & ServiceName) + throw (css::uno::RuntimeException) + { + return cppu::supportsService(this, ServiceName); + } + + virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() + throw (css::uno::RuntimeException) + { + css::uno::Sequence< OUString > aSeq(1); + aSeq[0] = OUString("com.sun.star.frame.GlobalEventBroadcaster"); + return aSeq; + } + + // css.document.XEventBroadcaster + virtual css::uno::Reference< css::container::XNameReplace > SAL_CALL getEvents() + throw(css::uno::RuntimeException); + + virtual void SAL_CALL addEventListener(const css::uno::Reference< css::document::XEventListener >& xListener) + throw(css::uno::RuntimeException); + + virtual void SAL_CALL removeEventListener( const css::uno::Reference< css::document::XEventListener >& xListener) + throw(css::uno::RuntimeException); + + // css.document.XDocumentEventBroadcaster + virtual void SAL_CALL addDocumentEventListener( const css::uno::Reference< css::document::XDocumentEventListener >& _Listener ) throw (css::uno::RuntimeException); + virtual void SAL_CALL removeDocumentEventListener( const css::uno::Reference< css::document::XDocumentEventListener >& _Listener ) throw (css::uno::RuntimeException); + virtual void SAL_CALL notifyDocumentEvent( const OUString& _EventName, const css::uno::Reference< css::frame::XController2 >& _ViewController, const css::uno::Any& _Supplement ) throw (css::lang::IllegalArgumentException, css::lang::NoSupportException, css::uno::RuntimeException); + + // css.document.XEventListener + virtual void SAL_CALL notifyEvent(const css::document::EventObject& aEvent) + throw(css::uno::RuntimeException); + + // css.document.XDocumentEventListener + virtual void SAL_CALL documentEventOccured( const css::document::DocumentEvent& Event ) throw (css::uno::RuntimeException); + + // css.container.XSet + virtual sal_Bool SAL_CALL has(const css::uno::Any& aElement) + throw(css::uno::RuntimeException); + + virtual void SAL_CALL insert(const css::uno::Any& aElement) + throw(css::lang::IllegalArgumentException , + css::container::ElementExistException, + css::uno::RuntimeException ); + + virtual void SAL_CALL remove(const css::uno::Any& aElement) + throw(css::lang::IllegalArgumentException , + css::container::NoSuchElementException, + css::uno::RuntimeException ); + + // css.container.XEnumerationAccess + virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() + throw(css::uno::RuntimeException); + + // css.container.XElementAccess + virtual css::uno::Type SAL_CALL getElementType() + throw(css::uno::RuntimeException); + + virtual sal_Bool SAL_CALL hasElements() + throw(css::uno::RuntimeException); + + // css.lang.XEventListener + virtual void SAL_CALL disposing(const css::lang::EventObject& aEvent) + throw(css::uno::RuntimeException); + +private: + + // threadsafe + void implts_notifyJobExecution(const css::document::EventObject& aEvent); + void implts_checkAndExecuteEventBindings(const css::document::DocumentEvent& aEvent); + void implts_notifyListener(const css::document::DocumentEvent& aEvent); + + // not threadsafe + TModelList::iterator impl_searchDoc(const css::uno::Reference< css::frame::XModel >& xModel); +}; + +ModelCollectionEnumeration::ModelCollectionEnumeration() + : ModelCollectionMutexBase( ) + , m_pEnumerationIt (m_lModels.begin()) +{ +} + +ModelCollectionEnumeration::~ModelCollectionEnumeration() +{ +} + +void ModelCollectionEnumeration::setModelList(const TModelList& rList) +{ + // SAFE -> + ::osl::ResettableMutexGuard aLock(m_aLock); + m_lModels = rList; + m_pEnumerationIt = m_lModels.begin(); + aLock.clear(); + // <- SAFE +} + +sal_Bool SAL_CALL ModelCollectionEnumeration::hasMoreElements() + throw(uno::RuntimeException) +{ + // SAFE -> + ::osl::ResettableMutexGuard aLock(m_aLock); + return (m_pEnumerationIt != m_lModels.end()); + // <- SAFE +} + +uno::Any SAL_CALL ModelCollectionEnumeration::nextElement() + throw(container::NoSuchElementException, + lang::WrappedTargetException , + uno::RuntimeException ) +{ + // SAFE -> + ::osl::ResettableMutexGuard aLock(m_aLock); + if (m_pEnumerationIt == m_lModels.end()) + throw container::NoSuchElementException( + OUString("End of model enumeration reached."), + static_cast< container::XEnumeration* >(this)); + uno::Reference< frame::XModel > xModel(*m_pEnumerationIt, uno::UNO_QUERY); + ++m_pEnumerationIt; + aLock.clear(); + // <- SAFE + + return uno::makeAny(xModel); +} + +//----------------------------------------------------------------------------- +SfxGlobalEvents_Impl::SfxGlobalEvents_Impl( const uno::Reference < uno::XComponentContext >& rxContext) + : ModelCollectionMutexBase( ) + , m_xJobExecutorListener( task::JobExecutor::create( rxContext ), uno::UNO_QUERY_THROW ) + , m_aLegacyListeners (m_aLock) + , m_aDocumentListeners (m_aLock) + , pImp (0 ) +{ + m_refCount++; + SFX_APP(); + pImp = new GlobalEventConfig(); + m_xEvents = pImp; + m_refCount--; +} + +//----------------------------------------------------------------------------- +SfxGlobalEvents_Impl::~SfxGlobalEvents_Impl() +{ +} + +//----------------------------------------------------------------------------- +uno::Reference< container::XNameReplace > SAL_CALL SfxGlobalEvents_Impl::getEvents() + throw(uno::RuntimeException) +{ + // SAFE -> + ::osl::ResettableMutexGuard aLock(m_aLock); + return m_xEvents; + // <- SAFE +} + +//----------------------------------------------------------------------------- +void SAL_CALL SfxGlobalEvents_Impl::addEventListener(const uno::Reference< document::XEventListener >& xListener) + throw(uno::RuntimeException) +{ + // container is threadsafe + m_aLegacyListeners.addInterface(xListener); +} + +//----------------------------------------------------------------------------- +void SAL_CALL SfxGlobalEvents_Impl::removeEventListener(const uno::Reference< document::XEventListener >& xListener) + throw(uno::RuntimeException) +{ + // container is threadsafe + m_aLegacyListeners.removeInterface(xListener); +} + +//----------------------------------------------------------------------------- +void SAL_CALL SfxGlobalEvents_Impl::addDocumentEventListener( const uno::Reference< document::XDocumentEventListener >& _Listener ) + throw(uno::RuntimeException) +{ + m_aDocumentListeners.addInterface( _Listener ); +} + +//----------------------------------------------------------------------------- +void SAL_CALL SfxGlobalEvents_Impl::removeDocumentEventListener( const uno::Reference< document::XDocumentEventListener >& _Listener ) + throw(uno::RuntimeException) +{ + m_aDocumentListeners.removeInterface( _Listener ); +} + +//----------------------------------------------------------------------------- +void SAL_CALL SfxGlobalEvents_Impl::notifyDocumentEvent( const OUString& /*_EventName*/, + const uno::Reference< frame::XController2 >& /*_ViewController*/, const uno::Any& /*_Supplement*/ ) + throw (lang::IllegalArgumentException, lang::NoSupportException, uno::RuntimeException) +{ + // we're a multiplexer only, no chance to generate artifical events here + throw lang::NoSupportException(OUString(), *this); +} + +//----------------------------------------------------------------------------- +void SAL_CALL SfxGlobalEvents_Impl::notifyEvent(const document::EventObject& aEvent) + throw(uno::RuntimeException) +{ + document::DocumentEvent aDocEvent(aEvent.Source, aEvent.EventName, NULL, uno::Any()); + implts_notifyJobExecution(aEvent); + implts_checkAndExecuteEventBindings(aDocEvent); + implts_notifyListener(aDocEvent); +} + +//----------------------------------------------------------------------------- +void SAL_CALL SfxGlobalEvents_Impl::documentEventOccured( const document::DocumentEvent& _Event ) + throw (uno::RuntimeException) +{ + implts_notifyJobExecution(document::EventObject(_Event.Source, _Event.EventName)); + implts_checkAndExecuteEventBindings(_Event); + implts_notifyListener(_Event); +} + +//----------------------------------------------------------------------------- +void SAL_CALL SfxGlobalEvents_Impl::disposing(const lang::EventObject& aEvent) + throw(uno::RuntimeException) +{ + uno::Reference< frame::XModel > xDoc(aEvent.Source, uno::UNO_QUERY); + + // SAFE -> + ::osl::ResettableMutexGuard aLock(m_aLock); + TModelList::iterator pIt = impl_searchDoc(xDoc); + if (pIt != m_lModels.end()) + m_lModels.erase(pIt); + aLock.clear(); + // <- SAFE +} + +//----------------------------------------------------------------------------- +sal_Bool SAL_CALL SfxGlobalEvents_Impl::has(const uno::Any& aElement) + throw (uno::RuntimeException) +{ + uno::Reference< frame::XModel > xDoc; + aElement >>= xDoc; + + sal_Bool bHas = sal_False; + + // SAFE -> + ::osl::ResettableMutexGuard aLock(m_aLock); + TModelList::iterator pIt = impl_searchDoc(xDoc); + if (pIt != m_lModels.end()) + bHas = sal_True; + aLock.clear(); + // <- SAFE + + return bHas; +} + +//----------------------------------------------------------------------------- +void SAL_CALL SfxGlobalEvents_Impl::insert( const uno::Any& aElement ) + throw (lang::IllegalArgumentException , + container::ElementExistException, + uno::RuntimeException ) +{ + uno::Reference< frame::XModel > xDoc; + aElement >>= xDoc; + if (!xDoc.is()) + throw lang::IllegalArgumentException( + OUString("Cant locate at least the model parameter."), + static_cast< container::XSet* >(this), + 0); + + // SAFE -> + ::osl::ResettableMutexGuard aLock(m_aLock); + TModelList::iterator pIt = impl_searchDoc(xDoc); + if (pIt != m_lModels.end()) + throw container::ElementExistException( + OUString(), + static_cast< container::XSet* >(this)); + m_lModels.push_back(xDoc); + aLock.clear(); + // <- SAFE + + uno::Reference< document::XDocumentEventBroadcaster > xDocBroadcaster(xDoc, uno::UNO_QUERY ); + if (xDocBroadcaster.is()) + xDocBroadcaster->addDocumentEventListener(this); + else + { + // try the "legacy version" of XDocumentEventBroadcaster, which is XEventBroadcaster + uno::Reference< document::XEventBroadcaster > xBroadcaster(xDoc, uno::UNO_QUERY); + if (xBroadcaster.is()) + xBroadcaster->addEventListener(static_cast< document::XEventListener* >(this)); + } +} + +//----------------------------------------------------------------------------- +void SAL_CALL SfxGlobalEvents_Impl::remove( const uno::Any& aElement ) + throw (lang::IllegalArgumentException , + container::NoSuchElementException, + uno::RuntimeException ) +{ + uno::Reference< frame::XModel > xDoc; + aElement >>= xDoc; + if (!xDoc.is()) + throw lang::IllegalArgumentException( + OUString("Cant locate at least the model parameter."), + static_cast< container::XSet* >(this), + 0); + + // SAFE -> + ::osl::ResettableMutexGuard aLock(m_aLock); + TModelList::iterator pIt = impl_searchDoc(xDoc); + if (pIt == m_lModels.end()) + throw container::NoSuchElementException( + OUString(), + static_cast< container::XSet* >(this)); + m_lModels.erase(pIt); + aLock.clear(); + // <- SAFE + + uno::Reference< document::XDocumentEventBroadcaster > xDocBroadcaster(xDoc, uno::UNO_QUERY ); + if (xDocBroadcaster.is()) + xDocBroadcaster->removeDocumentEventListener(this); + else + { + // try the "legacy version" of XDocumentEventBroadcaster, which is XEventBroadcaster + uno::Reference< document::XEventBroadcaster > xBroadcaster(xDoc, uno::UNO_QUERY); + if (xBroadcaster.is()) + xBroadcaster->removeEventListener(static_cast< document::XEventListener* >(this)); + } +} + +//----------------------------------------------------------------------------- +uno::Reference< container::XEnumeration > SAL_CALL SfxGlobalEvents_Impl::createEnumeration() + throw (uno::RuntimeException) +{ + // SAFE -> + ::osl::ResettableMutexGuard aLock(m_aLock); + ModelCollectionEnumeration* pEnum = new ModelCollectionEnumeration(); + pEnum->setModelList(m_lModels); + uno::Reference< container::XEnumeration > xEnum( + static_cast< container::XEnumeration* >(pEnum), + uno::UNO_QUERY); + aLock.clear(); + // <- SAFE + + return xEnum; +} + +//----------------------------------------------------------------------------- +uno::Type SAL_CALL SfxGlobalEvents_Impl::getElementType() + throw (uno::RuntimeException) +{ + return ::getCppuType(static_cast< uno::Reference< frame::XModel >* >(NULL)); +} + +//----------------------------------------------------------------------------- +sal_Bool SAL_CALL SfxGlobalEvents_Impl::hasElements() + throw (uno::RuntimeException) +{ + // SAFE -> + ::osl::ResettableMutexGuard aLock(m_aLock); + return (m_lModels.size()>0); + // <- SAFE +} + +//----------------------------------------------------------------------------- +void SfxGlobalEvents_Impl::implts_notifyJobExecution(const document::EventObject& aEvent) +{ + try + { + m_xJobExecutorListener->notifyEvent(aEvent); + } + catch(const uno::RuntimeException&) + { throw; } + catch(const uno::Exception&) + {} +} + +//----------------------------------------------------------------------------- +void SfxGlobalEvents_Impl::implts_checkAndExecuteEventBindings(const document::DocumentEvent& aEvent) +{ + try + { + // SAFE -> + ::osl::ResettableMutexGuard aLock(m_aLock); + uno::Reference< container::XNameReplace > xEvents = m_xEvents; + aLock.clear(); + // <- SAFE + + uno::Any aAny; + if ( xEvents.is() && xEvents->hasByName( aEvent.EventName ) ) + aAny = xEvents->getByName(aEvent.EventName); + SfxEvents_Impl::Execute(aAny, aEvent, 0); + } + catch ( uno::RuntimeException const & ) + { + throw; + } + catch ( uno::Exception const & ) + { + DBG_UNHANDLED_EXCEPTION(); + } +} + +//----------------------------------------------------------------------------- +void SfxGlobalEvents_Impl::implts_notifyListener(const document::DocumentEvent& aEvent) +{ + // containers are threadsafe + document::EventObject aLegacyEvent(aEvent.Source, aEvent.EventName); + m_aLegacyListeners.notifyEach( &document::XEventListener::notifyEvent, aLegacyEvent ); + + m_aDocumentListeners.notifyEach( &document::XDocumentEventListener::documentEventOccured, aEvent ); +} + +//----------------------------------------------------------------------------- +// not threadsafe ... must be locked from outside! +TModelList::iterator SfxGlobalEvents_Impl::impl_searchDoc(const uno::Reference< frame::XModel >& xModel) +{ + if (!xModel.is()) + return m_lModels.end(); + + TModelList::iterator pIt; + for ( pIt = m_lModels.begin(); + pIt != m_lModels.end() ; + ++pIt ) + { + uno::Reference< frame::XModel > xContainerDoc(*pIt, uno::UNO_QUERY); + if (xContainerDoc == xModel) + break; + } + + return pIt; +} + +} + +extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL +com_sun_star_comp_sfx2_GlobalEventBroadcaster_get_implementation( + css::uno::XComponentContext *context, + css::uno::Sequence<css::uno::Any> const &) +{ + rtl::Reference<SfxGlobalEvents_Impl> x(new SfxGlobalEvents_Impl(context)); + x->acquire(); + return static_cast<cppu::OWeakObject *>(x.get()); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sfx2/util/sfx.component b/sfx2/util/sfx.component index 30cd3fc698bb..e0fb72b44a8e 100644 --- a/sfx2/util/sfx.component +++ b/sfx2/util/sfx.component @@ -68,7 +68,8 @@ constructor="com_sun_star_comp_sfx2_DocumentTemplates_get_implementation"> <service name="com.sun.star.frame.DocumentTemplates"/> </implementation> - <implementation name="com.sun.star.comp.sfx2.GlobalEventBroadcaster"> + <implementation name="com.sun.star.comp.sfx2.GlobalEventBroadcaster" + constructor="com_sun_star_comp_sfx2_GlobalEventBroadcaster_get_implementation"> <service name="com.sun.star.frame.GlobalEventBroadcaster"/> <singleton name="com.sun.star.frame.theGlobalEventBroadcaster"/> </implementation> |