blob: 0a797aec4079f525dbf5822255af11e42c476c4f [file] [log] [blame]
/**************************************************************
*
* 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
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the 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 <tools/diagnose_ex.h>
#include <svl/macitem.hxx>
#include <sfx2/appuno.hxx>
#include <sfx2/objsh.hxx>
#include <sfx2/sfxbasemodel.hxx>
#include <sfx2/evntconf.hxx>
#include <unotools/eventcfg.hxx>
#include <unotools/securityoptions.hxx>
#include <comphelper/processfactory.hxx>
#include <comphelper/namedvaluecollection.hxx>
#include "eventsupplier.hxx"
#include <sfx2/app.hxx>
#include "sfx2/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 )
{
// check for correct type of the element
if ( !::comphelper::NamedValueCollection::canExtractFrom( rElement ) )
throw ILLEGALARGUMENTEXCEPTION();
::comphelper::NamedValueCollection const aEventDescriptor( rElement );
// 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( sal_True );
::comphelper::NamedValueCollection aNormalizedDescriptor;
NormalizeMacro( aEventDescriptor, aNormalizedDescriptor, mpObjShell );
::rtl::OUString sType;
if ( ( aNormalizedDescriptor.size() == 1 )
&& ( aNormalizedDescriptor.has( PROP_EVENT_TYPE ) == 0 )
&& ( aNormalizedDescriptor.get( PROP_EVENT_TYPE ) >>= 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.)
OSL_ENSURE( false, "legacy event assignment format detected" );
aNormalizedDescriptor.clear();
}
if ( !aNormalizedDescriptor.empty() )
{
maEventData[i] <<= aNormalizedDescriptor.getPropertyValues();
}
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, sal_Bool bNormalizeMacro )
{
SvxMacro* pMacro = NULL;
SEQUENCE < PROPERTYVALUE > aProperties;
ANY aAny;
if ( bNormalizeMacro )
NormalizeMacro( 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::NormalizeMacro( const ANY& rEvent, ANY& rRet, SfxObjectShell* pDoc )
{
const ::comphelper::NamedValueCollection aEventDescriptor( rEvent );
::comphelper::NamedValueCollection aEventDescriptorOut;
NormalizeMacro( aEventDescriptor, aEventDescriptorOut, pDoc );
rRet <<= aEventDescriptorOut.getPropertyValues();
}
void SfxEvents_Impl::NormalizeMacro( const ::comphelper::NamedValueCollection& i_eventDescriptor,
::comphelper::NamedValueCollection& o_normalizedDescriptor, SfxObjectShell* i_document )
{
SfxObjectShell* pDoc = i_document;
if ( !pDoc )
pDoc = SfxObjectShell::Current();
::rtl::OUString aType = i_eventDescriptor.getOrDefault( PROP_EVENT_TYPE, ::rtl::OUString() );
::rtl::OUString aScript = i_eventDescriptor.getOrDefault( PROP_SCRIPT, ::rtl::OUString() );
::rtl::OUString aLibrary = i_eventDescriptor.getOrDefault( PROP_LIBRARY, ::rtl::OUString() );
::rtl::OUString aMacroName = i_eventDescriptor.getOrDefault( PROP_MACRO_NAME, ::rtl::OUString() );
if ( aType.getLength() )
o_normalizedDescriptor.put( PROP_EVENT_TYPE, aType );
if ( aScript.getLength() )
o_normalizedDescriptor.put( PROP_SCRIPT, aScript );
if ( aType.compareToAscii( STAR_BASIC ) == 0 )
{
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");
}
o_normalizedDescriptor.put( PROP_SCRIPT, aScript );
o_normalizedDescriptor.put( PROP_LIBRARY, aLibrary );
o_normalizedDescriptor.put( PROP_MACRO_NAME, aMacroName );
}
}
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() && xEvents->hasByName( aEvent.EventName ) )
aAny = xEvents->getByName(aEvent.EventName);
Execute(aAny, aEvent, 0);
}
catch ( css::uno::RuntimeException const & )
{
throw;
}
catch ( css::uno::Exception const & )
{
DBG_UNHANDLED_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;
}