From ef37781683e28d1837cfce86de990e59d2c10c5f Mon Sep 17 00:00:00 2001 From: Matúš Kukan Date: Wed, 15 Jan 2014 21:43:55 +0100 Subject: Revert "sfx: Use constructor feature for SfxGlobalEvents_Impl." This reverts commit 9b73d3a4cd9c1aea29b51b1b23d0a44c34f2f8a2 because it breaks unit tests. Conflicts: sfx2/source/appl/appuno.cxx Change-Id: I7b2d2dc6ff8ade2c8dd29602827313c7bb01f97d --- sfx2/Library_sfx.mk | 1 - sfx2/source/appl/appuno.cxx | 2 + sfx2/source/inc/eventsupplier.hxx | 137 ++++++++- sfx2/source/notify/eventsupplier.cxx | 353 ++++++++++++++++++++++- sfx2/source/notify/globalevents.cxx | 542 ----------------------------------- sfx2/util/sfx.component | 3 +- 6 files changed, 489 insertions(+), 549 deletions(-) delete mode 100644 sfx2/source/notify/globalevents.cxx (limited to 'sfx2') diff --git a/sfx2/Library_sfx.mk b/sfx2/Library_sfx.mk index f4eafa2f9483..bdd68121a8e1 100644 --- a/sfx2/Library_sfx.mk +++ b/sfx2/Library_sfx.mk @@ -236,7 +236,6 @@ $(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 9f7b3e738ab7..1741f3c4bc4b 100644 --- a/sfx2/source/appl/appuno.cxx +++ b/sfx2/source/appl/appuno.cxx @@ -23,6 +23,7 @@ #include "backingcomp.hxx" #include "SfxDocumentMetaData.hxx" +#include "eventsupplier.hxx" #include "fltoptint.hxx" #include "objshimp.hxx" #include @@ -1793,6 +1794,7 @@ SFX2_DLLPUBLIC void* SAL_CALL sfx_component_getFactory( // Write no ";" at end of line and dont forget "else" ! (see macro) //============================================================================= IF_NAME_CREATECOMPONENTFACTORY( BackingComp ) + IF_NAME_CREATECOMPONENTFACTORY( SfxGlobalEvents_Impl ) IF_NAME_CREATECOMPONENTFACTORY( ShutdownIcon ) #ifdef TEST_HANDLERS IF_NAME_CREATECOMPONENTFACTORY( TestKeyHandler ) diff --git a/sfx2/source/inc/eventsupplier.hxx b/sfx2/source/inc/eventsupplier.hxx index d8d2a8d124da..2465ca8919fa 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 - +#include #include +#include #include #include #include @@ -32,7 +32,11 @@ #include #include #include +#include +#include +#include #include +#include #include #include #include @@ -94,7 +98,134 @@ public: const ::comphelper::NamedValueCollection& i_eventDescriptor, ::comphelper::NamedValueCollection& o_normalizedDescriptor, SfxObjectShell* i_document ); - static void Execute( css::uno::Any& aEventData, const css::document::DocumentEvent& aTrigger, SfxObjectShell* pDoc ); +}; + +//============================================================================= +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); }; #endif diff --git a/sfx2/source/notify/eventsupplier.cxx b/sfx2/source/notify/eventsupplier.cxx index 067ae2154abd..418f35d3b867 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; } -void SfxEvents_Impl::Execute( uno::Any& aEventData, const document::DocumentEvent& aTrigger, SfxObjectShell* pDoc ) +static void Execute( uno::Any& aEventData, const document::DocumentEvent& aTrigger, SfxObjectShell* pDoc ) { uno::Sequence < beans::PropertyValue > aProperties; if ( aEventData >>= aProperties ) @@ -488,4 +488,355 @@ 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 deleted file mode 100644 index b8f5c428798b..000000000000 --- a/sfx2/source/notify/globalevents.cxx +++ /dev/null @@ -1,542 +0,0 @@ -/* -*- 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 - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -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 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 const &) -{ - rtl::Reference x(new SfxGlobalEvents_Impl(context)); - x->acquire(); - return static_cast(x.get()); -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sfx2/util/sfx.component b/sfx2/util/sfx.component index 286c202897b0..4a7d699b5aa6 100644 --- a/sfx2/util/sfx.component +++ b/sfx2/util/sfx.component @@ -64,8 +64,7 @@ constructor="com_sun_star_comp_sfx2_DocumentTemplates_get_implementation"> - +