summaryrefslogtreecommitdiff
path: root/sfx2/source/notify/eventsupplier.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sfx2/source/notify/eventsupplier.cxx')
-rw-r--r--sfx2/source/notify/eventsupplier.cxx923
1 files changed, 923 insertions, 0 deletions
diff --git a/sfx2/source/notify/eventsupplier.cxx b/sfx2/source/notify/eventsupplier.cxx
new file mode 100644
index 000000000000..a01b1df73c82
--- /dev/null
+++ b/sfx2/source/notify/eventsupplier.cxx
@@ -0,0 +1,923 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: eventsupplier.cxx,v $
+ * $Revision: 1.36.12.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sfx2.hxx"
+
+//--------------------------------------------------------------------------------------------------------
+#include <com/sun/star/beans/PropertyValue.hpp>
+
+#ifndef _COM_SUN_STAR_UTL_URL_HPP_
+#include <com/sun/star/util/URL.hpp>
+#endif
+
+#ifndef _COM_SUN_STAR_UTL_XURLTRANSFORMER_HPP_
+#include <com/sun/star/util/XURLTransformer.hpp>
+#endif
+#include <tools/urlobj.hxx>
+#include <svtools/macitem.hxx>
+#include <sfx2/appuno.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/sfxbasemodel.hxx>
+#include <sfx2/evntconf.hxx>
+#include <svtools/eventcfg.hxx>
+
+#include <svtools/securityoptions.hxx>
+#include <comphelper/processfactory.hxx>
+#include "eventsupplier.hxx"
+
+#include <sfx2/app.hxx>
+#include "sfxresid.hxx"
+
+#include <sfx2/sfxsids.hrc>
+#include "sfxlocal.hrc"
+#include <sfx2/docfile.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/frame.hxx>
+
+//--------------------------------------------------------------------------------------------------------
+
+#define MACRO_PRFIX "macro://"
+#define MACRO_POSTFIX "()"
+
+//--------------------------------------------------------------------------------------------------------
+
+#define PROPERTYVALUE ::com::sun::star::beans::PropertyValue
+#define UNO_QUERY ::com::sun::star::uno::UNO_QUERY
+
+namespace css = ::com::sun::star;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::beans::PropertyValue;
+
+//--------------------------------------------------------------------------------------------------------
+ // --- XNameReplace ---
+//--------------------------------------------------------------------------------------------------------
+void SAL_CALL SfxEvents_Impl::replaceByName( const OUSTRING & aName, const ANY & rElement )
+ throw( ILLEGALARGUMENTEXCEPTION, NOSUCHELEMENTEXCEPTION,
+ WRAPPEDTARGETEXCEPTION, RUNTIMEEXCEPTION )
+{
+ ::osl::MutexGuard aGuard( maMutex );
+
+ // find the event in the list and replace the data
+ long nCount = maEventNames.getLength();
+ for ( long i=0; i<nCount; i++ )
+ {
+ if ( maEventNames[i] == aName )
+ {
+ Sequence< PropertyValue > aProperties;
+ // check for correct type of the element
+ if ( rElement.hasValue() && !( rElement >>= aProperties ) )
+ throw ILLEGALARGUMENTEXCEPTION();
+
+ // create Configuration at first, creation might call this method also and that would overwrite everything
+ // we might have stored before!
+ if ( mpObjShell && !mpObjShell->IsLoading() )
+ mpObjShell->SetModified( TRUE );
+
+ if ( aProperties.getLength() )
+ {
+ // "normalize" the macro descriptor
+ ANY aValue;
+ BlowUpMacro( rElement, aValue, mpObjShell );
+ aValue >>= aProperties;
+
+ ::rtl::OUString sType;
+ if ( ( aProperties.getLength() == 1 )
+ && ( aProperties[0].Name.compareToAscii( PROP_EVENT_TYPE ) == 0 )
+ && ( aProperties[0].Value >>= sType )
+ && ( sType.getLength() == 0 )
+ )
+ {
+ // An empty event type means no binding. Therefore reset data
+ // to reflect that state.
+ // (that's for compatibility only. Nowadays, the Tools/Customize dialog should
+ // set an empty sequence to indicate the request for resetting the assignment.)
+ aProperties.realloc( 0 );
+ }
+ }
+
+ if ( aProperties.getLength() )
+ {
+ maEventData[i] = makeAny( aProperties );
+ }
+ else
+ {
+ maEventData[i].clear();
+ }
+ return;
+ }
+ }
+
+ throw NOSUCHELEMENTEXCEPTION();
+}
+
+//--------------------------------------------------------------------------------------------------------
+// --- XNameAccess ---
+//--------------------------------------------------------------------------------------------------------
+ANY SAL_CALL SfxEvents_Impl::getByName( const OUSTRING& aName )
+ throw( NOSUCHELEMENTEXCEPTION, WRAPPEDTARGETEXCEPTION,
+ RUNTIMEEXCEPTION )
+{
+ ::osl::MutexGuard aGuard( maMutex );
+
+ // find the event in the list and return the data
+
+ long nCount = maEventNames.getLength();
+
+ for ( long i=0; i<nCount; i++ )
+ {
+ if ( maEventNames[i] == aName )
+ return maEventData[i];
+ }
+
+ throw NOSUCHELEMENTEXCEPTION();
+}
+
+//--------------------------------------------------------------------------------------------------------
+SEQUENCE< OUSTRING > SAL_CALL SfxEvents_Impl::getElementNames() throw ( RUNTIMEEXCEPTION )
+{
+ return maEventNames;
+}
+
+//--------------------------------------------------------------------------------------------------------
+sal_Bool SAL_CALL SfxEvents_Impl::hasByName( const OUSTRING& aName ) throw ( RUNTIMEEXCEPTION )
+{
+ ::osl::MutexGuard aGuard( maMutex );
+
+ // find the event in the list and return the data
+
+ long nCount = maEventNames.getLength();
+
+ for ( long i=0; i<nCount; i++ )
+ {
+ if ( maEventNames[i] == aName )
+ return sal_True;
+ }
+
+ return sal_False;
+}
+
+//--------------------------------------------------------------------------------------------------------
+// --- XElementAccess ( parent of XNameAccess ) ---
+//--------------------------------------------------------------------------------------------------------
+UNOTYPE SAL_CALL SfxEvents_Impl::getElementType() throw ( RUNTIMEEXCEPTION )
+{
+ UNOTYPE aElementType = ::getCppuType( (const SEQUENCE < PROPERTYVALUE > *)0 );
+ return aElementType;
+}
+
+//--------------------------------------------------------------------------------------------------------
+sal_Bool SAL_CALL SfxEvents_Impl::hasElements() throw ( RUNTIMEEXCEPTION )
+{
+ ::osl::MutexGuard aGuard( maMutex );
+
+ if ( maEventNames.getLength() )
+ return sal_True;
+ else
+ return sal_False;
+}
+
+static void Execute( ANY& aEventData, const css::document::DocumentEvent& aTrigger, SfxObjectShell* pDoc )
+{
+ SEQUENCE < PROPERTYVALUE > aProperties;
+ if ( aEventData >>= aProperties )
+ {
+ OUSTRING aPrefix = OUSTRING( RTL_CONSTASCII_USTRINGPARAM( MACRO_PRFIX ) );
+ OUSTRING aType;
+ OUSTRING aScript;
+ OUSTRING aLibrary;
+ OUSTRING aMacroName;
+
+ sal_Int32 nCount = aProperties.getLength();
+
+ if ( !nCount )
+ return;
+
+ sal_Int32 nIndex = 0;
+ while ( nIndex < nCount )
+ {
+ if ( aProperties[ nIndex ].Name.compareToAscii( PROP_EVENT_TYPE ) == 0 )
+ aProperties[ nIndex ].Value >>= aType;
+ else if ( aProperties[ nIndex ].Name.compareToAscii( PROP_SCRIPT ) == 0 )
+ aProperties[ nIndex ].Value >>= aScript;
+ else if ( aProperties[ nIndex ].Name.compareToAscii( PROP_LIBRARY ) == 0 )
+ aProperties[ nIndex ].Value >>= aLibrary;
+ else if ( aProperties[ nIndex ].Name.compareToAscii( PROP_MACRO_NAME ) == 0 )
+ aProperties[ nIndex ].Value >>= aMacroName;
+ else {
+ DBG_ERROR("Unknown property value!");
+ }
+ nIndex += 1;
+ }
+
+ if ( aType.compareToAscii( STAR_BASIC ) == 0 && aScript.getLength() )
+ {
+ com::sun::star::uno::Any aAny;
+ SfxMacroLoader::loadMacro( aScript, aAny, pDoc );
+ }
+ else if ( aType.compareToAscii( "Service" ) == 0 ||
+ aType.compareToAscii( "Script" ) == 0 )
+ {
+ if ( aScript.getLength() )
+ {
+ SfxViewFrame* pView = pDoc ?
+ SfxViewFrame::GetFirst( pDoc ) :
+ SfxViewFrame::Current();
+
+ ::com::sun::star::uno::Reference
+ < ::com::sun::star::util::XURLTransformer > xTrans(
+ ::comphelper::getProcessServiceFactory()->createInstance(
+ rtl::OUString::createFromAscii(
+ "com.sun.star.util.URLTransformer" ) ),
+ UNO_QUERY );
+
+ ::com::sun::star::util::URL aURL;
+ aURL.Complete = aScript;
+ xTrans->parseStrict( aURL );
+
+ ::com::sun::star::uno::Reference
+ < ::com::sun::star::frame::XDispatchProvider > xProv;
+
+ if ( pView != NULL )
+ {
+ xProv = ::com::sun::star::uno::Reference
+ < ::com::sun::star::frame::XDispatchProvider > (
+ pView->GetFrame()->GetFrameInterface(), UNO_QUERY );
+ }
+ else
+ {
+ xProv = ::com::sun::star::uno::Reference
+ < ::com::sun::star::frame::XDispatchProvider > (
+ ::comphelper::getProcessServiceFactory()->createInstance(
+ rtl::OUString::createFromAscii(
+ "com.sun.star.frame.Desktop" ) ),
+ UNO_QUERY );
+ }
+
+ ::com::sun::star::uno::Reference < ::com::sun::star::frame::XDispatch > xDisp;
+ if ( xProv.is() )
+ xDisp = xProv->queryDispatch( aURL, ::rtl::OUString(), 0 );
+
+ if ( xDisp.is() )
+ {
+ //::com::sun::star::uno::Sequence < ::com::sun::star::beans::PropertyValue > aArgs(1);
+ //aArgs[0].Name = rtl::OUString::createFromAscii("Referer");
+ //aArs[0].Value <<= ::rtl::OUString( pDoc->GetMedium()->GetName() );
+ //xDisp->dispatch( aURL, aArgs );
+
+ css::beans::PropertyValue aEventParam;
+ aEventParam.Value <<= aTrigger;
+ css::uno::Sequence< css::beans::PropertyValue > aDispatchArgs( &aEventParam, 1 );
+ xDisp->dispatch( aURL, aDispatchArgs );
+ }
+ }
+ }
+ else if ( aType.getLength() == 0 )
+ {
+ // Empty type means no active binding for the event. Just ignore do nothing.
+ }
+ else
+ {
+ DBG_ERRORFILE( "notifyEvent(): Unsupported event type" );
+ }
+ }
+}
+
+//--------------------------------------------------------------------------------------------------------
+// --- ::document::XEventListener ---
+//--------------------------------------------------------------------------------------------------------
+void SAL_CALL SfxEvents_Impl::notifyEvent( const DOCEVENTOBJECT& aEvent ) throw( RUNTIMEEXCEPTION )
+{
+ ::osl::ClearableMutexGuard aGuard( maMutex );
+
+ // get the event name, find the coresponding data, execute the data
+
+ OUSTRING aName = aEvent.EventName;
+ long nCount = maEventNames.getLength();
+ long nIndex = 0;
+ sal_Bool bFound = sal_False;
+
+ while ( !bFound && ( nIndex < nCount ) )
+ {
+ if ( maEventNames[nIndex] == aName )
+ bFound = sal_True;
+ else
+ nIndex += 1;
+ }
+
+ if ( !bFound )
+ return;
+
+ ANY aEventData = maEventData[ nIndex ];
+ aGuard.clear();
+ Execute( aEventData, css::document::DocumentEvent(aEvent.Source, aEvent.EventName, NULL, css::uno::Any()), mpObjShell );
+}
+
+//--------------------------------------------------------------------------------------------------------
+// --- ::lang::XEventListener ---
+//--------------------------------------------------------------------------------------------------------
+void SAL_CALL SfxEvents_Impl::disposing( const EVENTOBJECT& /*Source*/ ) throw( RUNTIMEEXCEPTION )
+{
+ ::osl::MutexGuard aGuard( maMutex );
+
+ if ( mxBroadcaster.is() )
+ {
+ mxBroadcaster->removeEventListener( this );
+ mxBroadcaster = NULL;
+ }
+}
+
+//--------------------------------------------------------------------------------------------------------
+//
+//--------------------------------------------------------------------------------------------------------
+SfxEvents_Impl::SfxEvents_Impl( SfxObjectShell* pShell,
+ REFERENCE< XEVENTBROADCASTER > xBroadcaster )
+{
+ // get the list of supported events and store it
+ if ( pShell )
+ maEventNames = pShell->GetEventNames();
+ else
+ maEventNames = GlobalEventConfig().getElementNames();
+
+ maEventData = SEQUENCE < ANY > ( maEventNames.getLength() );
+
+ mpObjShell = pShell;
+ mxBroadcaster = xBroadcaster;
+
+ if ( mxBroadcaster.is() )
+ mxBroadcaster->addEventListener( this );
+}
+
+//--------------------------------------------------------------------------------------------------------
+SfxEvents_Impl::~SfxEvents_Impl()
+{
+}
+
+//--------------------------------------------------------------------------------------------------------
+SvxMacro* SfxEvents_Impl::ConvertToMacro( const ANY& rElement, SfxObjectShell* pObjShell, BOOL bBlowUp )
+{
+ SvxMacro* pMacro = NULL;
+ SEQUENCE < PROPERTYVALUE > aProperties;
+ ANY aAny;
+ if ( bBlowUp )
+ BlowUpMacro( rElement, aAny, pObjShell );
+ else
+ aAny = rElement;
+
+ if ( aAny >>= aProperties )
+ {
+ OUSTRING aType;
+ OUSTRING aScriptURL;
+ OUSTRING aLibrary;
+ OUSTRING aMacroName;
+
+ long nCount = aProperties.getLength();
+ long nIndex = 0;
+
+ if ( !nCount )
+ return pMacro;
+
+ while ( nIndex < nCount )
+ {
+ if ( aProperties[ nIndex ].Name.compareToAscii( PROP_EVENT_TYPE ) == 0 )
+ aProperties[ nIndex ].Value >>= aType;
+ else if ( aProperties[ nIndex ].Name.compareToAscii( PROP_SCRIPT ) == 0 )
+ aProperties[ nIndex ].Value >>= aScriptURL;
+ else if ( aProperties[ nIndex ].Name.compareToAscii( PROP_LIBRARY ) == 0 )
+ aProperties[ nIndex ].Value >>= aLibrary;
+ else if ( aProperties[ nIndex ].Name.compareToAscii( PROP_MACRO_NAME ) == 0 )
+ aProperties[ nIndex ].Value >>= aMacroName;
+ else {
+ DBG_ERROR("Unknown propery value!");
+ }
+ nIndex += 1;
+ }
+
+ // Get the type
+ ScriptType eType( STARBASIC );
+ if ( aType.compareToAscii( STAR_BASIC ) == COMPARE_EQUAL )
+ eType = STARBASIC;
+ else if ( aType.compareToAscii( "Script" ) == COMPARE_EQUAL && aScriptURL.getLength() )
+ eType = EXTENDED_STYPE;
+ else if ( aType.compareToAscii( SVX_MACRO_LANGUAGE_JAVASCRIPT ) == COMPARE_EQUAL )
+ eType = JAVASCRIPT;
+ else {
+ DBG_ERRORFILE( "ConvertToMacro: Unknown macro type" );
+ }
+
+ if ( aMacroName.getLength() )
+ {
+ if ( aLibrary.compareToAscii("application") == 0 )
+ aLibrary = SFX_APP()->GetName();
+ else
+ aLibrary = ::rtl::OUString();
+ pMacro = new SvxMacro( aMacroName, aLibrary, eType );
+ }
+ else if ( eType == EXTENDED_STYPE )
+ pMacro = new SvxMacro( aScriptURL, aType );
+ }
+
+ return pMacro;
+}
+
+void SfxEvents_Impl::BlowUpMacro( const ANY& rEvent, ANY& rRet, SfxObjectShell* pDoc )
+{
+ if ( !pDoc )
+ pDoc = SfxObjectShell::Current();
+
+ SEQUENCE < PROPERTYVALUE > aInProps;
+ SEQUENCE < PROPERTYVALUE > aOutProps(2);
+
+ if ( !( rEvent >>= aInProps ) )
+ return;
+
+ sal_Int32 nCount = aInProps.getLength();
+
+ if ( !nCount )
+ return;
+
+ OUSTRING aType;
+ OUSTRING aScript;
+ OUSTRING aLibrary;
+ OUSTRING aMacroName;
+
+ sal_Int32 nIndex = 0;
+
+ while ( nIndex < nCount )
+ {
+ if ( aInProps[ nIndex ].Name.compareToAscii( PROP_EVENT_TYPE ) == 0 )
+ {
+ aInProps[nIndex].Value >>= aType;
+ aOutProps[0] = aInProps[nIndex];
+ }
+ else if ( aInProps[ nIndex ].Name.compareToAscii( PROP_SCRIPT ) == 0 )
+ {
+ aInProps[nIndex].Value >>= aScript;
+ aOutProps[1] = aInProps[nIndex];
+ }
+ else if ( aInProps[ nIndex ].Name.compareToAscii( PROP_LIBRARY ) == 0 )
+ {
+ aInProps[ nIndex ].Value >>= aLibrary;
+ }
+ else if ( aInProps[ nIndex ].Name.compareToAscii( PROP_MACRO_NAME ) == 0 )
+ {
+ aInProps[ nIndex ].Value >>= aMacroName;
+ }
+ nIndex += 1;
+ }
+
+ if ( aType.compareToAscii( STAR_BASIC ) == 0 )
+ {
+ aOutProps.realloc(4);
+ if ( aScript.getLength() )
+ {
+ if( ! aMacroName.getLength() || ! aLibrary.getLength() )
+ {
+ sal_Int32 nHashPos = aScript.indexOf( '/', 8 );
+ sal_Int32 nArgsPos = aScript.indexOf( '(' );
+ if ( ( nHashPos != STRING_NOTFOUND ) && ( nHashPos < nArgsPos ) )
+ {
+ OUSTRING aBasMgrName( INetURLObject::decode( aScript.copy( 8, nHashPos-8 ), INET_HEX_ESCAPE, INetURLObject::DECODE_WITH_CHARSET ) );
+ if ( aBasMgrName.compareToAscii(".") == 0 )
+ aLibrary = pDoc->GetTitle();
+/*
+ else if ( aBasMgrName.getLength() )
+ aLibrary = aBasMgrName;
+ */
+ else
+ aLibrary = SFX_APP()->GetName();
+
+ // Get the macro name
+ aMacroName = aScript.copy( nHashPos+1, nArgsPos - nHashPos - 1 );
+ }
+ else
+ {
+ DBG_ERRORFILE( "ConvertToMacro: Unknown macro url format" );
+ }
+ }
+ }
+ else if ( aMacroName.getLength() )
+ {
+ aScript = OUSTRING( RTL_CONSTASCII_USTRINGPARAM( MACRO_PRFIX ) );
+ if ( aLibrary.compareTo( SFX_APP()->GetName() ) != 0 && aLibrary.compareToAscii("StarDesktop") != 0 && aLibrary.compareToAscii("application") != 0 )
+ aScript += String('.');
+
+ aScript += String('/');
+ aScript += aMacroName;
+ aScript += OUSTRING( RTL_CONSTASCII_USTRINGPARAM( MACRO_POSTFIX ) );
+ }
+ else
+ // wrong properties
+ return;
+
+ if ( aLibrary.compareToAscii("document") != 0 )
+ {
+ if ( !aLibrary.getLength() || (pDoc && ( String(aLibrary) == pDoc->GetTitle( SFX_TITLE_APINAME ) || String(aLibrary) == pDoc->GetTitle() )) )
+ aLibrary = String::CreateFromAscii("document");
+ else
+ aLibrary = String::CreateFromAscii("application");
+ }
+
+ aOutProps[1].Name = OUSTRING::createFromAscii( PROP_SCRIPT );
+ aOutProps[1].Value <<= aScript;
+ aOutProps[2].Name = OUSTRING::createFromAscii( PROP_LIBRARY );
+ aOutProps[2].Value <<= aLibrary;
+ aOutProps[3].Name = OUSTRING::createFromAscii( PROP_MACRO_NAME );
+ aOutProps[3].Value <<= aMacroName;
+ rRet <<= aOutProps;
+ }
+ else if ( aType.compareToAscii( SVX_MACRO_LANGUAGE_JAVASCRIPT ) == 0 )
+ {
+ aOutProps[1] = aInProps[1];
+ rRet <<= aOutProps;
+ }
+ else
+ {
+ rRet <<= aOutProps;
+ }
+}
+
+ModelCollectionEnumeration::ModelCollectionEnumeration(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
+ : ModelCollectionMutexBase( )
+ , m_xSMGR (xSMGR )
+ , 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(css::uno::RuntimeException)
+{
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+ return (m_pEnumerationIt != m_lModels.end());
+ // <- SAFE
+}
+
+css::uno::Any SAL_CALL ModelCollectionEnumeration::nextElement()
+ throw(css::container::NoSuchElementException,
+ css::lang::WrappedTargetException ,
+ css::uno::RuntimeException )
+{
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+ if (m_pEnumerationIt == m_lModels.end())
+ throw css::container::NoSuchElementException(
+ ::rtl::OUString::createFromAscii("End of model enumeration reached."),
+ static_cast< css::container::XEnumeration* >(this));
+ css::uno::Reference< css::frame::XModel > xModel(*m_pEnumerationIt, UNO_QUERY);
+ ++m_pEnumerationIt;
+ aLock.clear();
+ // <- SAFE
+
+ return css::uno::makeAny(xModel);
+}
+
+SFX_IMPL_XSERVICEINFO( SfxGlobalEvents_Impl, "com.sun.star.frame.GlobalEventBroadcaster", "com.sun.star.comp.sfx2.GlobalEventBroadcaster" )
+SFX_IMPL_ONEINSTANCEFACTORY( SfxGlobalEvents_Impl );
+
+//-----------------------------------------------------------------------------
+SfxGlobalEvents_Impl::SfxGlobalEvents_Impl( const com::sun::star::uno::Reference < ::com::sun::star::lang::XMultiServiceFactory >& xSMGR)
+ : ModelCollectionMutexBase( )
+ , m_xSMGR (xSMGR )
+ , m_aLegacyListeners (m_aLock)
+ , m_aDocumentListeners (m_aLock)
+ , pImp (0 )
+{
+ m_refCount++;
+ SFX_APP();
+ pImp = new GlobalEventConfig();
+ m_xEvents = pImp;
+ m_xJobExecutorListener = css::uno::Reference< css::document::XEventListener >(
+ xSMGR->createInstance(::rtl::OUString::createFromAscii("com.sun.star.task.JobExecutor")),
+ UNO_QUERY);
+ m_refCount--;
+}
+
+//-----------------------------------------------------------------------------
+SfxGlobalEvents_Impl::~SfxGlobalEvents_Impl()
+{
+}
+
+//-----------------------------------------------------------------------------
+css::uno::Reference< css::container::XNameReplace > SAL_CALL SfxGlobalEvents_Impl::getEvents()
+ throw(css::uno::RuntimeException)
+{
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+ return m_xEvents;
+ // <- SAFE
+}
+
+//-----------------------------------------------------------------------------
+void SAL_CALL SfxGlobalEvents_Impl::addEventListener(const css::uno::Reference< css::document::XEventListener >& xListener)
+ throw(css::uno::RuntimeException)
+{
+ // container is threadsafe
+ m_aLegacyListeners.addInterface(xListener);
+}
+
+//-----------------------------------------------------------------------------
+void SAL_CALL SfxGlobalEvents_Impl::removeEventListener(const css::uno::Reference< css::document::XEventListener >& xListener)
+ throw(css::uno::RuntimeException)
+{
+ // container is threadsafe
+ m_aLegacyListeners.removeInterface(xListener);
+}
+
+//-----------------------------------------------------------------------------
+void SAL_CALL SfxGlobalEvents_Impl::addDocumentEventListener( const css::uno::Reference< css::document::XDocumentEventListener >& _Listener )
+ throw(css::uno::RuntimeException)
+{
+ m_aDocumentListeners.addInterface( _Listener );
+}
+
+//-----------------------------------------------------------------------------
+void SAL_CALL SfxGlobalEvents_Impl::removeDocumentEventListener( const css::uno::Reference< css::document::XDocumentEventListener >& _Listener )
+ throw(css::uno::RuntimeException)
+{
+ m_aDocumentListeners.removeInterface( _Listener );
+}
+
+//-----------------------------------------------------------------------------
+void SAL_CALL SfxGlobalEvents_Impl::notifyDocumentEvent( const ::rtl::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)
+{
+ // we're a multiplexer only, no chance to generate artifical events here
+ throw css::lang::NoSupportException(::rtl::OUString(), *this);
+}
+
+//-----------------------------------------------------------------------------
+void SAL_CALL SfxGlobalEvents_Impl::notifyEvent(const css::document::EventObject& aEvent)
+ throw(css::uno::RuntimeException)
+{
+ css::document::DocumentEvent aDocEvent(aEvent.Source, aEvent.EventName, NULL, css::uno::Any());
+ implts_notifyJobExecution(aEvent);
+ implts_checkAndExecuteEventBindings(aDocEvent);
+ implts_notifyListener(aDocEvent);
+}
+
+//-----------------------------------------------------------------------------
+void SAL_CALL SfxGlobalEvents_Impl::documentEventOccured( const ::css::document::DocumentEvent& _Event )
+ throw (::css::uno::RuntimeException)
+{
+ implts_notifyJobExecution(css::document::EventObject(_Event.Source, _Event.EventName));
+ implts_checkAndExecuteEventBindings(_Event);
+ implts_notifyListener(_Event);
+}
+
+//-----------------------------------------------------------------------------
+void SAL_CALL SfxGlobalEvents_Impl::disposing(const css::lang::EventObject& aEvent)
+ throw(css::uno::RuntimeException)
+{
+ css::uno::Reference< css::frame::XModel > xDoc(aEvent.Source, 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 css::uno::Any& aElement)
+ throw (css::uno::RuntimeException)
+{
+ css::uno::Reference< css::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 css::uno::Any& aElement )
+ throw (css::lang::IllegalArgumentException ,
+ css::container::ElementExistException,
+ css::uno::RuntimeException )
+{
+ css::uno::Reference< css::frame::XModel > xDoc;
+ aElement >>= xDoc;
+ if (!xDoc.is())
+ throw css::lang::IllegalArgumentException(
+ ::rtl::OUString::createFromAscii("Cant locate at least the model parameter."),
+ static_cast< css::container::XSet* >(this),
+ 0);
+
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+ TModelList::iterator pIt = impl_searchDoc(xDoc);
+ if (pIt != m_lModels.end())
+ throw css::container::ElementExistException(
+ ::rtl::OUString(),
+ static_cast< css::container::XSet* >(this));
+ m_lModels.push_back(xDoc);
+ aLock.clear();
+ // <- SAFE
+
+ css::uno::Reference< css::document::XDocumentEventBroadcaster > xDocBroadcaster(xDoc, UNO_QUERY );
+ if (xDocBroadcaster.is())
+ xDocBroadcaster->addDocumentEventListener(this);
+ else
+ {
+ // try the "legacy version" of XDocumentEventBroadcaster, which is XEventBroadcaster
+ css::uno::Reference< css::document::XEventBroadcaster > xBroadcaster(xDoc, UNO_QUERY);
+ if (xBroadcaster.is())
+ xBroadcaster->addEventListener(static_cast< css::document::XEventListener* >(this));
+ }
+}
+
+//-----------------------------------------------------------------------------
+void SAL_CALL SfxGlobalEvents_Impl::remove( const css::uno::Any& aElement )
+ throw (css::lang::IllegalArgumentException ,
+ css::container::NoSuchElementException,
+ css::uno::RuntimeException )
+{
+ css::uno::Reference< css::frame::XModel > xDoc;
+ aElement >>= xDoc;
+ if (!xDoc.is())
+ throw css::lang::IllegalArgumentException(
+ ::rtl::OUString::createFromAscii("Cant locate at least the model parameter."),
+ static_cast< css::container::XSet* >(this),
+ 0);
+
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+ TModelList::iterator pIt = impl_searchDoc(xDoc);
+ if (pIt == m_lModels.end())
+ throw css::container::NoSuchElementException(
+ ::rtl::OUString(),
+ static_cast< css::container::XSet* >(this));
+ m_lModels.erase(pIt);
+ aLock.clear();
+ // <- SAFE
+
+ css::uno::Reference< css::document::XDocumentEventBroadcaster > xDocBroadcaster(xDoc, UNO_QUERY );
+ if (xDocBroadcaster.is())
+ xDocBroadcaster->removeDocumentEventListener(this);
+ else
+ {
+ // try the "legacy version" of XDocumentEventBroadcaster, which is XEventBroadcaster
+ css::uno::Reference< css::document::XEventBroadcaster > xBroadcaster(xDoc, UNO_QUERY);
+ if (xBroadcaster.is())
+ xBroadcaster->removeEventListener(static_cast< css::document::XEventListener* >(this));
+ }
+}
+
+//-----------------------------------------------------------------------------
+css::uno::Reference< css::container::XEnumeration > SAL_CALL SfxGlobalEvents_Impl::createEnumeration()
+ throw (css::uno::RuntimeException)
+{
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+ ModelCollectionEnumeration* pEnum = new ModelCollectionEnumeration(m_xSMGR);
+ pEnum->setModelList(m_lModels);
+ css::uno::Reference< css::container::XEnumeration > xEnum(
+ static_cast< css::container::XEnumeration* >(pEnum),
+ UNO_QUERY);
+ aLock.clear();
+ // <- SAFE
+
+ return xEnum;
+}
+
+//-----------------------------------------------------------------------------
+css::uno::Type SAL_CALL SfxGlobalEvents_Impl::getElementType()
+ throw (css::uno::RuntimeException)
+{
+ return ::getCppuType(static_cast< css::uno::Reference< css::frame::XModel >* >(NULL));
+}
+
+//-----------------------------------------------------------------------------
+sal_Bool SAL_CALL SfxGlobalEvents_Impl::hasElements()
+ throw (css::uno::RuntimeException)
+{
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+ return (m_lModels.size()>0);
+ // <- SAFE
+}
+
+//-----------------------------------------------------------------------------
+void SfxGlobalEvents_Impl::implts_notifyJobExecution(const css::document::EventObject& aEvent)
+{
+ try
+ {
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+ css::uno::Reference< css::document::XEventListener > xJobExecutor(m_xJobExecutorListener);
+ aLock.clear();
+ // <- SAFE
+ if (xJobExecutor.is())
+ xJobExecutor->notifyEvent(aEvent);
+ }
+ catch(const css::uno::RuntimeException& exRun)
+ { throw exRun; }
+ catch(const css::uno::Exception&)
+ {}
+}
+
+//-----------------------------------------------------------------------------
+void SfxGlobalEvents_Impl::implts_checkAndExecuteEventBindings(const css::document::DocumentEvent& aEvent)
+{
+ try
+ {
+ // SAFE ->
+ ::osl::ResettableMutexGuard aLock(m_aLock);
+ css::uno::Reference< css::container::XNameReplace > xEvents = m_xEvents;
+ aLock.clear();
+ // <- SAFE
+
+ css::uno::Any aAny;
+ if (xEvents.is())
+ aAny = xEvents->getByName(aEvent.EventName);
+ Execute(aAny, aEvent, 0);
+ }
+ catch(const css::uno::RuntimeException& exRun)
+ { throw exRun; }
+ catch(const css::uno::Exception&)
+ {}
+}
+
+//-----------------------------------------------------------------------------
+void SfxGlobalEvents_Impl::implts_notifyListener(const css::document::DocumentEvent& aEvent)
+{
+ // containers are threadsafe
+ css::document::EventObject aLegacyEvent(aEvent.Source, aEvent.EventName);
+ m_aLegacyListeners.notifyEach( &css::document::XEventListener::notifyEvent, aLegacyEvent );
+
+ m_aDocumentListeners.notifyEach( &css::document::XDocumentEventListener::documentEventOccured, aEvent );
+}
+
+//-----------------------------------------------------------------------------
+// not threadsafe ... must be locked from outside!
+TModelList::iterator SfxGlobalEvents_Impl::impl_searchDoc(const css::uno::Reference< css::frame::XModel >& xModel)
+{
+ if (!xModel.is())
+ return m_lModels.end();
+
+ TModelList::iterator pIt;
+ for ( pIt = m_lModels.begin();
+ pIt != m_lModels.end() ;
+ ++pIt )
+ {
+ css::uno::Reference< css::frame::XModel > xContainerDoc(*pIt, UNO_QUERY);
+ if (xContainerDoc == xModel)
+ break;
+ }
+
+ return pIt;
+}
+