merge the formfield patch from ooo-build
[ooovba.git] / sfx2 / source / notify / eventsupplier.cxx
blob933581c7fdee9d4dd78afce36ac1abfd958d53d7
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: eventsupplier.cxx,v $
10 * $Revision: 1.36.12.5 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sfx2.hxx"
34 //--------------------------------------------------------------------------------------------------------
35 #include <com/sun/star/beans/PropertyValue.hpp>
37 #ifndef _COM_SUN_STAR_UTL_URL_HPP_
38 #include <com/sun/star/util/URL.hpp>
39 #endif
41 #ifndef _COM_SUN_STAR_UTL_XURLTRANSFORMER_HPP_
42 #include <com/sun/star/util/XURLTransformer.hpp>
43 #endif
44 #include <tools/urlobj.hxx>
45 #include <svtools/macitem.hxx>
46 #include <sfx2/appuno.hxx>
47 #include <sfx2/objsh.hxx>
48 #include <sfx2/sfxbasemodel.hxx>
49 #include <sfx2/evntconf.hxx>
50 #include <svtools/eventcfg.hxx>
52 #include <svtools/securityoptions.hxx>
53 #include <comphelper/processfactory.hxx>
54 #include "eventsupplier.hxx"
56 #include <sfx2/app.hxx>
57 #include "sfxresid.hxx"
59 #include <sfx2/sfxsids.hrc>
60 #include "sfxlocal.hrc"
61 #include <sfx2/docfile.hxx>
62 #include <sfx2/viewfrm.hxx>
63 #include <sfx2/frame.hxx>
65 //--------------------------------------------------------------------------------------------------------
67 #define MACRO_PRFIX "macro://"
68 #define MACRO_POSTFIX "()"
70 //--------------------------------------------------------------------------------------------------------
72 #define PROPERTYVALUE ::com::sun::star::beans::PropertyValue
73 #define UNO_QUERY ::com::sun::star::uno::UNO_QUERY
75 namespace css = ::com::sun::star;
76 using ::com::sun::star::uno::Sequence;
77 using ::com::sun::star::beans::PropertyValue;
79 //--------------------------------------------------------------------------------------------------------
80 // --- XNameReplace ---
81 //--------------------------------------------------------------------------------------------------------
82 void SAL_CALL SfxEvents_Impl::replaceByName( const OUSTRING & aName, const ANY & rElement )
83 throw( ILLEGALARGUMENTEXCEPTION, NOSUCHELEMENTEXCEPTION,
84 WRAPPEDTARGETEXCEPTION, RUNTIMEEXCEPTION )
86 ::osl::MutexGuard aGuard( maMutex );
88 // find the event in the list and replace the data
89 long nCount = maEventNames.getLength();
90 for ( long i=0; i<nCount; i++ )
92 if ( maEventNames[i] == aName )
94 Sequence< PropertyValue > aProperties;
95 // check for correct type of the element
96 if ( rElement.hasValue() && !( rElement >>= aProperties ) )
97 throw ILLEGALARGUMENTEXCEPTION();
99 // create Configuration at first, creation might call this method also and that would overwrite everything
100 // we might have stored before!
101 if ( mpObjShell && !mpObjShell->IsLoading() )
102 mpObjShell->SetModified( TRUE );
104 if ( aProperties.getLength() )
106 // "normalize" the macro descriptor
107 ANY aValue;
108 BlowUpMacro( rElement, aValue, mpObjShell );
109 aValue >>= aProperties;
111 ::rtl::OUString sType;
112 if ( ( aProperties.getLength() == 1 )
113 && ( aProperties[0].Name.compareToAscii( PROP_EVENT_TYPE ) == 0 )
114 && ( aProperties[0].Value >>= sType )
115 && ( sType.getLength() == 0 )
118 // An empty event type means no binding. Therefore reset data
119 // to reflect that state.
120 // (that's for compatibility only. Nowadays, the Tools/Customize dialog should
121 // set an empty sequence to indicate the request for resetting the assignment.)
122 aProperties.realloc( 0 );
126 if ( aProperties.getLength() )
128 maEventData[i] = makeAny( aProperties );
130 else
132 maEventData[i].clear();
134 return;
138 throw NOSUCHELEMENTEXCEPTION();
141 //--------------------------------------------------------------------------------------------------------
142 // --- XNameAccess ---
143 //--------------------------------------------------------------------------------------------------------
144 ANY SAL_CALL SfxEvents_Impl::getByName( const OUSTRING& aName )
145 throw( NOSUCHELEMENTEXCEPTION, WRAPPEDTARGETEXCEPTION,
146 RUNTIMEEXCEPTION )
148 ::osl::MutexGuard aGuard( maMutex );
150 // find the event in the list and return the data
152 long nCount = maEventNames.getLength();
154 for ( long i=0; i<nCount; i++ )
156 if ( maEventNames[i] == aName )
157 return maEventData[i];
160 throw NOSUCHELEMENTEXCEPTION();
163 //--------------------------------------------------------------------------------------------------------
164 SEQUENCE< OUSTRING > SAL_CALL SfxEvents_Impl::getElementNames() throw ( RUNTIMEEXCEPTION )
166 return maEventNames;
169 //--------------------------------------------------------------------------------------------------------
170 sal_Bool SAL_CALL SfxEvents_Impl::hasByName( const OUSTRING& aName ) throw ( RUNTIMEEXCEPTION )
172 ::osl::MutexGuard aGuard( maMutex );
174 // find the event in the list and return the data
176 long nCount = maEventNames.getLength();
178 for ( long i=0; i<nCount; i++ )
180 if ( maEventNames[i] == aName )
181 return sal_True;
184 return sal_False;
187 //--------------------------------------------------------------------------------------------------------
188 // --- XElementAccess ( parent of XNameAccess ) ---
189 //--------------------------------------------------------------------------------------------------------
190 UNOTYPE SAL_CALL SfxEvents_Impl::getElementType() throw ( RUNTIMEEXCEPTION )
192 UNOTYPE aElementType = ::getCppuType( (const SEQUENCE < PROPERTYVALUE > *)0 );
193 return aElementType;
196 //--------------------------------------------------------------------------------------------------------
197 sal_Bool SAL_CALL SfxEvents_Impl::hasElements() throw ( RUNTIMEEXCEPTION )
199 ::osl::MutexGuard aGuard( maMutex );
201 if ( maEventNames.getLength() )
202 return sal_True;
203 else
204 return sal_False;
207 static void Execute( ANY& aEventData, const css::document::DocumentEvent& aTrigger, SfxObjectShell* pDoc )
209 SEQUENCE < PROPERTYVALUE > aProperties;
210 if ( aEventData >>= aProperties )
212 OUSTRING aPrefix = OUSTRING( RTL_CONSTASCII_USTRINGPARAM( MACRO_PRFIX ) );
213 OUSTRING aType;
214 OUSTRING aScript;
215 OUSTRING aLibrary;
216 OUSTRING aMacroName;
218 sal_Int32 nCount = aProperties.getLength();
220 if ( !nCount )
221 return;
223 sal_Int32 nIndex = 0;
224 while ( nIndex < nCount )
226 if ( aProperties[ nIndex ].Name.compareToAscii( PROP_EVENT_TYPE ) == 0 )
227 aProperties[ nIndex ].Value >>= aType;
228 else if ( aProperties[ nIndex ].Name.compareToAscii( PROP_SCRIPT ) == 0 )
229 aProperties[ nIndex ].Value >>= aScript;
230 else if ( aProperties[ nIndex ].Name.compareToAscii( PROP_LIBRARY ) == 0 )
231 aProperties[ nIndex ].Value >>= aLibrary;
232 else if ( aProperties[ nIndex ].Name.compareToAscii( PROP_MACRO_NAME ) == 0 )
233 aProperties[ nIndex ].Value >>= aMacroName;
234 else {
235 DBG_ERROR("Unknown property value!");
237 nIndex += 1;
240 if ( aType.compareToAscii( STAR_BASIC ) == 0 && aScript.getLength() )
242 com::sun::star::uno::Any aAny;
243 SfxMacroLoader::loadMacro( aScript, aAny, pDoc );
245 else if ( aType.compareToAscii( "Service" ) == 0 ||
246 aType.compareToAscii( "Script" ) == 0 )
248 if ( aScript.getLength() )
250 SfxViewFrame* pView = pDoc ?
251 SfxViewFrame::GetFirst( pDoc ) :
252 SfxViewFrame::Current();
254 ::com::sun::star::uno::Reference
255 < ::com::sun::star::util::XURLTransformer > xTrans(
256 ::comphelper::getProcessServiceFactory()->createInstance(
257 rtl::OUString::createFromAscii(
258 "com.sun.star.util.URLTransformer" ) ),
259 UNO_QUERY );
261 ::com::sun::star::util::URL aURL;
262 aURL.Complete = aScript;
263 xTrans->parseStrict( aURL );
265 ::com::sun::star::uno::Reference
266 < ::com::sun::star::frame::XDispatchProvider > xProv;
268 if ( pView != NULL )
270 xProv = ::com::sun::star::uno::Reference
271 < ::com::sun::star::frame::XDispatchProvider > (
272 pView->GetFrame()->GetFrameInterface(), UNO_QUERY );
274 else
276 xProv = ::com::sun::star::uno::Reference
277 < ::com::sun::star::frame::XDispatchProvider > (
278 ::comphelper::getProcessServiceFactory()->createInstance(
279 rtl::OUString::createFromAscii(
280 "com.sun.star.frame.Desktop" ) ),
281 UNO_QUERY );
284 ::com::sun::star::uno::Reference < ::com::sun::star::frame::XDispatch > xDisp;
285 if ( xProv.is() )
286 xDisp = xProv->queryDispatch( aURL, ::rtl::OUString(), 0 );
288 if ( xDisp.is() )
290 //::com::sun::star::uno::Sequence < ::com::sun::star::beans::PropertyValue > aArgs(1);
291 //aArgs[0].Name = rtl::OUString::createFromAscii("Referer");
292 //aArs[0].Value <<= ::rtl::OUString( pDoc->GetMedium()->GetName() );
293 //xDisp->dispatch( aURL, aArgs );
295 css::beans::PropertyValue aEventParam;
296 aEventParam.Value <<= aTrigger;
297 css::uno::Sequence< css::beans::PropertyValue > aDispatchArgs( &aEventParam, 1 );
298 xDisp->dispatch( aURL, aDispatchArgs );
302 else if ( aType.getLength() == 0 )
304 // Empty type means no active binding for the event. Just ignore do nothing.
306 else
308 DBG_ERRORFILE( "notifyEvent(): Unsupported event type" );
313 //--------------------------------------------------------------------------------------------------------
314 // --- ::document::XEventListener ---
315 //--------------------------------------------------------------------------------------------------------
316 void SAL_CALL SfxEvents_Impl::notifyEvent( const DOCEVENTOBJECT& aEvent ) throw( RUNTIMEEXCEPTION )
318 ::osl::ClearableMutexGuard aGuard( maMutex );
320 // get the event name, find the coresponding data, execute the data
322 OUSTRING aName = aEvent.EventName;
323 long nCount = maEventNames.getLength();
324 long nIndex = 0;
325 sal_Bool bFound = sal_False;
327 while ( !bFound && ( nIndex < nCount ) )
329 if ( maEventNames[nIndex] == aName )
330 bFound = sal_True;
331 else
332 nIndex += 1;
335 if ( !bFound )
336 return;
338 ANY aEventData = maEventData[ nIndex ];
339 aGuard.clear();
340 Execute( aEventData, css::document::DocumentEvent(aEvent.Source, aEvent.EventName, NULL, css::uno::Any()), mpObjShell );
343 //--------------------------------------------------------------------------------------------------------
344 // --- ::lang::XEventListener ---
345 //--------------------------------------------------------------------------------------------------------
346 void SAL_CALL SfxEvents_Impl::disposing( const EVENTOBJECT& /*Source*/ ) throw( RUNTIMEEXCEPTION )
348 ::osl::MutexGuard aGuard( maMutex );
350 if ( mxBroadcaster.is() )
352 mxBroadcaster->removeEventListener( this );
353 mxBroadcaster = NULL;
357 //--------------------------------------------------------------------------------------------------------
359 //--------------------------------------------------------------------------------------------------------
360 SfxEvents_Impl::SfxEvents_Impl( SfxObjectShell* pShell,
361 REFERENCE< XEVENTBROADCASTER > xBroadcaster )
363 // get the list of supported events and store it
364 if ( pShell )
365 maEventNames = pShell->GetEventNames();
366 else
367 maEventNames = GlobalEventConfig().getElementNames();
369 maEventData = SEQUENCE < ANY > ( maEventNames.getLength() );
371 mpObjShell = pShell;
372 mxBroadcaster = xBroadcaster;
374 if ( mxBroadcaster.is() )
375 mxBroadcaster->addEventListener( this );
378 //--------------------------------------------------------------------------------------------------------
379 SfxEvents_Impl::~SfxEvents_Impl()
383 //--------------------------------------------------------------------------------------------------------
384 SvxMacro* SfxEvents_Impl::ConvertToMacro( const ANY& rElement, SfxObjectShell* pObjShell, BOOL bBlowUp )
386 SvxMacro* pMacro = NULL;
387 SEQUENCE < PROPERTYVALUE > aProperties;
388 ANY aAny;
389 if ( bBlowUp )
390 BlowUpMacro( rElement, aAny, pObjShell );
391 else
392 aAny = rElement;
394 if ( aAny >>= aProperties )
396 OUSTRING aType;
397 OUSTRING aScriptURL;
398 OUSTRING aLibrary;
399 OUSTRING aMacroName;
401 long nCount = aProperties.getLength();
402 long nIndex = 0;
404 if ( !nCount )
405 return pMacro;
407 while ( nIndex < nCount )
409 if ( aProperties[ nIndex ].Name.compareToAscii( PROP_EVENT_TYPE ) == 0 )
410 aProperties[ nIndex ].Value >>= aType;
411 else if ( aProperties[ nIndex ].Name.compareToAscii( PROP_SCRIPT ) == 0 )
412 aProperties[ nIndex ].Value >>= aScriptURL;
413 else if ( aProperties[ nIndex ].Name.compareToAscii( PROP_LIBRARY ) == 0 )
414 aProperties[ nIndex ].Value >>= aLibrary;
415 else if ( aProperties[ nIndex ].Name.compareToAscii( PROP_MACRO_NAME ) == 0 )
416 aProperties[ nIndex ].Value >>= aMacroName;
417 else {
418 DBG_ERROR("Unknown propery value!");
420 nIndex += 1;
423 // Get the type
424 ScriptType eType( STARBASIC );
425 if ( aType.compareToAscii( STAR_BASIC ) == COMPARE_EQUAL )
426 eType = STARBASIC;
427 else if ( aType.compareToAscii( "Script" ) == COMPARE_EQUAL && aScriptURL.getLength() )
428 eType = EXTENDED_STYPE;
429 else if ( aType.compareToAscii( SVX_MACRO_LANGUAGE_JAVASCRIPT ) == COMPARE_EQUAL )
430 eType = JAVASCRIPT;
431 else {
432 DBG_ERRORFILE( "ConvertToMacro: Unknown macro type" );
435 if ( aMacroName.getLength() )
437 if ( aLibrary.compareToAscii("application") == 0 )
438 aLibrary = SFX_APP()->GetName();
439 else
440 aLibrary = ::rtl::OUString();
441 pMacro = new SvxMacro( aMacroName, aLibrary, eType );
443 else if ( eType == EXTENDED_STYPE )
444 pMacro = new SvxMacro( aScriptURL, aType );
447 return pMacro;
450 void SfxEvents_Impl::BlowUpMacro( const ANY& rEvent, ANY& rRet, SfxObjectShell* pDoc )
452 if ( !pDoc )
453 pDoc = SfxObjectShell::Current();
455 SEQUENCE < PROPERTYVALUE > aInProps;
456 SEQUENCE < PROPERTYVALUE > aOutProps(2);
458 if ( !( rEvent >>= aInProps ) )
459 return;
461 sal_Int32 nCount = aInProps.getLength();
463 if ( !nCount )
464 return;
466 OUSTRING aType;
467 OUSTRING aScript;
468 OUSTRING aLibrary;
469 OUSTRING aMacroName;
471 sal_Int32 nIndex = 0;
473 while ( nIndex < nCount )
475 if ( aInProps[ nIndex ].Name.compareToAscii( PROP_EVENT_TYPE ) == 0 )
477 aInProps[nIndex].Value >>= aType;
478 aOutProps[0] = aInProps[nIndex];
480 else if ( aInProps[ nIndex ].Name.compareToAscii( PROP_SCRIPT ) == 0 )
482 aInProps[nIndex].Value >>= aScript;
483 aOutProps[1] = aInProps[nIndex];
485 else if ( aInProps[ nIndex ].Name.compareToAscii( PROP_LIBRARY ) == 0 )
487 aInProps[ nIndex ].Value >>= aLibrary;
489 else if ( aInProps[ nIndex ].Name.compareToAscii( PROP_MACRO_NAME ) == 0 )
491 aInProps[ nIndex ].Value >>= aMacroName;
493 nIndex += 1;
496 if ( aType.compareToAscii( STAR_BASIC ) == 0 )
498 aOutProps.realloc(4);
499 if ( aScript.getLength() )
501 if( ! aMacroName.getLength() || ! aLibrary.getLength() )
503 sal_Int32 nHashPos = aScript.indexOf( '/', 8 );
504 sal_Int32 nArgsPos = aScript.indexOf( '(' );
505 if ( ( nHashPos != STRING_NOTFOUND ) && ( nHashPos < nArgsPos ) )
507 OUSTRING aBasMgrName( INetURLObject::decode( aScript.copy( 8, nHashPos-8 ), INET_HEX_ESCAPE, INetURLObject::DECODE_WITH_CHARSET ) );
508 if ( aBasMgrName.compareToAscii(".") == 0 )
509 aLibrary = pDoc->GetTitle();
511 else if ( aBasMgrName.getLength() )
512 aLibrary = aBasMgrName;
514 else
515 aLibrary = SFX_APP()->GetName();
517 // Get the macro name
518 aMacroName = aScript.copy( nHashPos+1, nArgsPos - nHashPos - 1 );
520 else
522 DBG_ERRORFILE( "ConvertToMacro: Unknown macro url format" );
526 else if ( aMacroName.getLength() )
528 aScript = OUSTRING( RTL_CONSTASCII_USTRINGPARAM( MACRO_PRFIX ) );
529 if ( aLibrary.compareTo( SFX_APP()->GetName() ) != 0 && aLibrary.compareToAscii("StarDesktop") != 0 && aLibrary.compareToAscii("application") != 0 )
530 aScript += String('.');
532 aScript += String('/');
533 aScript += aMacroName;
534 aScript += OUSTRING( RTL_CONSTASCII_USTRINGPARAM( MACRO_POSTFIX ) );
536 else
537 // wrong properties
538 return;
540 if ( aLibrary.compareToAscii("document") != 0 )
542 if ( !aLibrary.getLength() || (pDoc && ( String(aLibrary) == pDoc->GetTitle( SFX_TITLE_APINAME ) || String(aLibrary) == pDoc->GetTitle() )) )
543 aLibrary = String::CreateFromAscii("document");
544 else
545 aLibrary = String::CreateFromAscii("application");
548 aOutProps[1].Name = OUSTRING::createFromAscii( PROP_SCRIPT );
549 aOutProps[1].Value <<= aScript;
550 aOutProps[2].Name = OUSTRING::createFromAscii( PROP_LIBRARY );
551 aOutProps[2].Value <<= aLibrary;
552 aOutProps[3].Name = OUSTRING::createFromAscii( PROP_MACRO_NAME );
553 aOutProps[3].Value <<= aMacroName;
554 rRet <<= aOutProps;
556 else if ( aType.compareToAscii( SVX_MACRO_LANGUAGE_JAVASCRIPT ) == 0 )
558 aOutProps[1] = aInProps[1];
559 rRet <<= aOutProps;
561 else
563 rRet <<= aOutProps;
567 ModelCollectionEnumeration::ModelCollectionEnumeration(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
568 : ModelCollectionMutexBase( )
569 , m_xSMGR (xSMGR )
570 , m_pEnumerationIt (m_lModels.begin())
574 ModelCollectionEnumeration::~ModelCollectionEnumeration()
578 void ModelCollectionEnumeration::setModelList(const TModelList& rList)
580 // SAFE ->
581 ::osl::ResettableMutexGuard aLock(m_aLock);
582 m_lModels = rList;
583 m_pEnumerationIt = m_lModels.begin();
584 aLock.clear();
585 // <- SAFE
588 sal_Bool SAL_CALL ModelCollectionEnumeration::hasMoreElements()
589 throw(css::uno::RuntimeException)
591 // SAFE ->
592 ::osl::ResettableMutexGuard aLock(m_aLock);
593 return (m_pEnumerationIt != m_lModels.end());
594 // <- SAFE
597 css::uno::Any SAL_CALL ModelCollectionEnumeration::nextElement()
598 throw(css::container::NoSuchElementException,
599 css::lang::WrappedTargetException ,
600 css::uno::RuntimeException )
602 // SAFE ->
603 ::osl::ResettableMutexGuard aLock(m_aLock);
604 if (m_pEnumerationIt == m_lModels.end())
605 throw css::container::NoSuchElementException(
606 ::rtl::OUString::createFromAscii("End of model enumeration reached."),
607 static_cast< css::container::XEnumeration* >(this));
608 css::uno::Reference< css::frame::XModel > xModel(*m_pEnumerationIt, UNO_QUERY);
609 ++m_pEnumerationIt;
610 aLock.clear();
611 // <- SAFE
613 return css::uno::makeAny(xModel);
616 SFX_IMPL_XSERVICEINFO( SfxGlobalEvents_Impl, "com.sun.star.frame.GlobalEventBroadcaster", "com.sun.star.comp.sfx2.GlobalEventBroadcaster" )
617 SFX_IMPL_ONEINSTANCEFACTORY( SfxGlobalEvents_Impl );
619 //-----------------------------------------------------------------------------
620 SfxGlobalEvents_Impl::SfxGlobalEvents_Impl( const com::sun::star::uno::Reference < ::com::sun::star::lang::XMultiServiceFactory >& xSMGR)
621 : ModelCollectionMutexBase( )
622 , m_xSMGR (xSMGR )
623 , m_aLegacyListeners (m_aLock)
624 , m_aDocumentListeners (m_aLock)
625 , pImp (0 )
627 m_refCount++;
628 SFX_APP();
629 pImp = new GlobalEventConfig();
630 m_xEvents = pImp;
631 m_xJobExecutorListener = css::uno::Reference< css::document::XEventListener >(
632 xSMGR->createInstance(::rtl::OUString::createFromAscii("com.sun.star.task.JobExecutor")),
633 UNO_QUERY);
634 m_refCount--;
637 //-----------------------------------------------------------------------------
638 SfxGlobalEvents_Impl::~SfxGlobalEvents_Impl()
642 //-----------------------------------------------------------------------------
643 css::uno::Reference< css::container::XNameReplace > SAL_CALL SfxGlobalEvents_Impl::getEvents()
644 throw(css::uno::RuntimeException)
646 // SAFE ->
647 ::osl::ResettableMutexGuard aLock(m_aLock);
648 return m_xEvents;
649 // <- SAFE
652 //-----------------------------------------------------------------------------
653 void SAL_CALL SfxGlobalEvents_Impl::addEventListener(const css::uno::Reference< css::document::XEventListener >& xListener)
654 throw(css::uno::RuntimeException)
656 // container is threadsafe
657 m_aLegacyListeners.addInterface(xListener);
660 //-----------------------------------------------------------------------------
661 void SAL_CALL SfxGlobalEvents_Impl::removeEventListener(const css::uno::Reference< css::document::XEventListener >& xListener)
662 throw(css::uno::RuntimeException)
664 // container is threadsafe
665 m_aLegacyListeners.removeInterface(xListener);
668 //-----------------------------------------------------------------------------
669 void SAL_CALL SfxGlobalEvents_Impl::addDocumentEventListener( const css::uno::Reference< css::document::XDocumentEventListener >& _Listener )
670 throw(css::uno::RuntimeException)
672 m_aDocumentListeners.addInterface( _Listener );
675 //-----------------------------------------------------------------------------
676 void SAL_CALL SfxGlobalEvents_Impl::removeDocumentEventListener( const css::uno::Reference< css::document::XDocumentEventListener >& _Listener )
677 throw(css::uno::RuntimeException)
679 m_aDocumentListeners.removeInterface( _Listener );
682 //-----------------------------------------------------------------------------
683 void SAL_CALL SfxGlobalEvents_Impl::notifyDocumentEvent( const ::rtl::OUString& /*_EventName*/,
684 const css::uno::Reference< css::frame::XController2 >& /*_ViewController*/, const css::uno::Any& /*_Supplement*/ )
685 throw (css::lang::IllegalArgumentException, css::lang::NoSupportException, css::uno::RuntimeException)
687 // we're a multiplexer only, no chance to generate artifical events here
688 throw css::lang::NoSupportException(::rtl::OUString(), *this);
691 //-----------------------------------------------------------------------------
692 void SAL_CALL SfxGlobalEvents_Impl::notifyEvent(const css::document::EventObject& aEvent)
693 throw(css::uno::RuntimeException)
695 css::document::DocumentEvent aDocEvent(aEvent.Source, aEvent.EventName, NULL, css::uno::Any());
696 implts_notifyJobExecution(aEvent);
697 implts_checkAndExecuteEventBindings(aDocEvent);
698 implts_notifyListener(aDocEvent);
701 //-----------------------------------------------------------------------------
702 void SAL_CALL SfxGlobalEvents_Impl::documentEventOccured( const ::css::document::DocumentEvent& _Event )
703 throw (::css::uno::RuntimeException)
705 implts_notifyJobExecution(css::document::EventObject(_Event.Source, _Event.EventName));
706 implts_checkAndExecuteEventBindings(_Event);
707 implts_notifyListener(_Event);
710 //-----------------------------------------------------------------------------
711 void SAL_CALL SfxGlobalEvents_Impl::disposing(const css::lang::EventObject& aEvent)
712 throw(css::uno::RuntimeException)
714 css::uno::Reference< css::frame::XModel > xDoc(aEvent.Source, UNO_QUERY);
716 // SAFE ->
717 ::osl::ResettableMutexGuard aLock(m_aLock);
718 TModelList::iterator pIt = impl_searchDoc(xDoc);
719 if (pIt != m_lModels.end())
720 m_lModels.erase(pIt);
721 aLock.clear();
722 // <- SAFE
725 //-----------------------------------------------------------------------------
726 sal_Bool SAL_CALL SfxGlobalEvents_Impl::has(const css::uno::Any& aElement)
727 throw (css::uno::RuntimeException)
729 css::uno::Reference< css::frame::XModel > xDoc;
730 aElement >>= xDoc;
732 sal_Bool bHas = sal_False;
734 // SAFE ->
735 ::osl::ResettableMutexGuard aLock(m_aLock);
736 TModelList::iterator pIt = impl_searchDoc(xDoc);
737 if (pIt != m_lModels.end())
738 bHas = sal_True;
739 aLock.clear();
740 // <- SAFE
742 return bHas;
745 //-----------------------------------------------------------------------------
746 void SAL_CALL SfxGlobalEvents_Impl::insert( const css::uno::Any& aElement )
747 throw (css::lang::IllegalArgumentException ,
748 css::container::ElementExistException,
749 css::uno::RuntimeException )
751 css::uno::Reference< css::frame::XModel > xDoc;
752 aElement >>= xDoc;
753 if (!xDoc.is())
754 throw css::lang::IllegalArgumentException(
755 ::rtl::OUString::createFromAscii("Cant locate at least the model parameter."),
756 static_cast< css::container::XSet* >(this),
759 // SAFE ->
760 ::osl::ResettableMutexGuard aLock(m_aLock);
761 TModelList::iterator pIt = impl_searchDoc(xDoc);
762 if (pIt != m_lModels.end())
763 throw css::container::ElementExistException(
764 ::rtl::OUString(),
765 static_cast< css::container::XSet* >(this));
766 m_lModels.push_back(xDoc);
767 aLock.clear();
768 // <- SAFE
770 css::uno::Reference< css::document::XDocumentEventBroadcaster > xDocBroadcaster(xDoc, UNO_QUERY );
771 if (xDocBroadcaster.is())
772 xDocBroadcaster->addDocumentEventListener(this);
773 else
775 // try the "legacy version" of XDocumentEventBroadcaster, which is XEventBroadcaster
776 css::uno::Reference< css::document::XEventBroadcaster > xBroadcaster(xDoc, UNO_QUERY);
777 if (xBroadcaster.is())
778 xBroadcaster->addEventListener(static_cast< css::document::XEventListener* >(this));
782 //-----------------------------------------------------------------------------
783 void SAL_CALL SfxGlobalEvents_Impl::remove( const css::uno::Any& aElement )
784 throw (css::lang::IllegalArgumentException ,
785 css::container::NoSuchElementException,
786 css::uno::RuntimeException )
788 css::uno::Reference< css::frame::XModel > xDoc;
789 aElement >>= xDoc;
790 if (!xDoc.is())
791 throw css::lang::IllegalArgumentException(
792 ::rtl::OUString::createFromAscii("Cant locate at least the model parameter."),
793 static_cast< css::container::XSet* >(this),
796 // SAFE ->
797 ::osl::ResettableMutexGuard aLock(m_aLock);
798 TModelList::iterator pIt = impl_searchDoc(xDoc);
799 if (pIt == m_lModels.end())
800 throw css::container::NoSuchElementException(
801 ::rtl::OUString(),
802 static_cast< css::container::XSet* >(this));
803 m_lModels.erase(pIt);
804 aLock.clear();
805 // <- SAFE
807 css::uno::Reference< css::document::XDocumentEventBroadcaster > xDocBroadcaster(xDoc, UNO_QUERY );
808 if (xDocBroadcaster.is())
809 xDocBroadcaster->removeDocumentEventListener(this);
810 else
812 // try the "legacy version" of XDocumentEventBroadcaster, which is XEventBroadcaster
813 css::uno::Reference< css::document::XEventBroadcaster > xBroadcaster(xDoc, UNO_QUERY);
814 if (xBroadcaster.is())
815 xBroadcaster->removeEventListener(static_cast< css::document::XEventListener* >(this));
819 //-----------------------------------------------------------------------------
820 css::uno::Reference< css::container::XEnumeration > SAL_CALL SfxGlobalEvents_Impl::createEnumeration()
821 throw (css::uno::RuntimeException)
823 // SAFE ->
824 ::osl::ResettableMutexGuard aLock(m_aLock);
825 ModelCollectionEnumeration* pEnum = new ModelCollectionEnumeration(m_xSMGR);
826 pEnum->setModelList(m_lModels);
827 css::uno::Reference< css::container::XEnumeration > xEnum(
828 static_cast< css::container::XEnumeration* >(pEnum),
829 UNO_QUERY);
830 aLock.clear();
831 // <- SAFE
833 return xEnum;
836 //-----------------------------------------------------------------------------
837 css::uno::Type SAL_CALL SfxGlobalEvents_Impl::getElementType()
838 throw (css::uno::RuntimeException)
840 return ::getCppuType(static_cast< css::uno::Reference< css::frame::XModel >* >(NULL));
843 //-----------------------------------------------------------------------------
844 sal_Bool SAL_CALL SfxGlobalEvents_Impl::hasElements()
845 throw (css::uno::RuntimeException)
847 // SAFE ->
848 ::osl::ResettableMutexGuard aLock(m_aLock);
849 return (m_lModels.size()>0);
850 // <- SAFE
853 //-----------------------------------------------------------------------------
854 void SfxGlobalEvents_Impl::implts_notifyJobExecution(const css::document::EventObject& aEvent)
858 // SAFE ->
859 ::osl::ResettableMutexGuard aLock(m_aLock);
860 css::uno::Reference< css::document::XEventListener > xJobExecutor(m_xJobExecutorListener);
861 aLock.clear();
862 // <- SAFE
863 if (xJobExecutor.is())
864 xJobExecutor->notifyEvent(aEvent);
866 catch(const css::uno::RuntimeException& exRun)
867 { throw exRun; }
868 catch(const css::uno::Exception&)
872 //-----------------------------------------------------------------------------
873 void SfxGlobalEvents_Impl::implts_checkAndExecuteEventBindings(const css::document::DocumentEvent& aEvent)
877 // SAFE ->
878 ::osl::ResettableMutexGuard aLock(m_aLock);
879 css::uno::Reference< css::container::XNameReplace > xEvents = m_xEvents;
880 aLock.clear();
881 // <- SAFE
883 css::uno::Any aAny;
884 if (xEvents.is())
885 aAny = xEvents->getByName(aEvent.EventName);
886 Execute(aAny, aEvent, 0);
888 catch(const css::uno::RuntimeException& exRun)
889 { throw exRun; }
890 catch(const css::uno::Exception&)
894 //-----------------------------------------------------------------------------
895 void SfxGlobalEvents_Impl::implts_notifyListener(const css::document::DocumentEvent& aEvent)
897 // containers are threadsafe
898 css::document::EventObject aLegacyEvent(aEvent.Source, aEvent.EventName);
899 m_aLegacyListeners.notifyEach( &css::document::XEventListener::notifyEvent, aLegacyEvent );
901 m_aDocumentListeners.notifyEach( &css::document::XDocumentEventListener::documentEventOccured, aEvent );
904 //-----------------------------------------------------------------------------
905 // not threadsafe ... must be locked from outside!
906 TModelList::iterator SfxGlobalEvents_Impl::impl_searchDoc(const css::uno::Reference< css::frame::XModel >& xModel)
908 if (!xModel.is())
909 return m_lModels.end();
911 TModelList::iterator pIt;
912 for ( pIt = m_lModels.begin();
913 pIt != m_lModels.end() ;
914 ++pIt )
916 css::uno::Reference< css::frame::XModel > xContainerDoc(*pIt, UNO_QUERY);
917 if (xContainerDoc == xModel)
918 break;
921 return pIt;