Update to m13
[ooovba.git] / sfx2 / source / notify / eventsupplier.cxx
bloba99ed9ca76bff2d1b73a291690a3e1ecc03f1469
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 USHORT nID = (USHORT) SfxEventConfiguration::GetEventId_Impl( aName );
102 OSL_ENSURE( nID, "SfxEvents_Impl::replaceByName: no ID for the given event!" );
103 if ( !nID )
104 // throw?
105 return;
107 if ( mpObjShell && !mpObjShell->IsLoading() )
108 mpObjShell->SetModified( TRUE );
110 if ( aProperties.getLength() )
112 // "normalize" the macro descriptor
113 ANY aValue;
114 BlowUpMacro( rElement, aValue, mpObjShell );
115 aValue >>= aProperties;
117 ::rtl::OUString sType;
118 if ( ( aProperties.getLength() == 1 )
119 && ( aProperties[0].Name.compareToAscii( PROP_EVENT_TYPE ) == 0 )
120 && ( aProperties[0].Value >>= sType )
121 && ( sType.getLength() == 0 )
124 // An empty event type means no binding. Therefore reset data
125 // to reflect that state.
126 // (that's for compatibility only. Nowadays, the Tools/Customize dialog should
127 // set an empty sequence to indicate the request for resetting the assignment.)
128 aProperties.realloc( 0 );
132 if ( aProperties.getLength() )
134 maEventData[i] = makeAny( aProperties );
136 else
138 maEventData[i].clear();
140 return;
144 throw NOSUCHELEMENTEXCEPTION();
147 //--------------------------------------------------------------------------------------------------------
148 // --- XNameAccess ---
149 //--------------------------------------------------------------------------------------------------------
150 ANY SAL_CALL SfxEvents_Impl::getByName( const OUSTRING& aName )
151 throw( NOSUCHELEMENTEXCEPTION, WRAPPEDTARGETEXCEPTION,
152 RUNTIMEEXCEPTION )
154 ::osl::MutexGuard aGuard( maMutex );
156 // find the event in the list and return the data
158 long nCount = maEventNames.getLength();
160 for ( long i=0; i<nCount; i++ )
162 if ( maEventNames[i] == aName )
163 return maEventData[i];
166 throw NOSUCHELEMENTEXCEPTION();
169 //--------------------------------------------------------------------------------------------------------
170 SEQUENCE< OUSTRING > SAL_CALL SfxEvents_Impl::getElementNames() throw ( RUNTIMEEXCEPTION )
172 return maEventNames;
175 //--------------------------------------------------------------------------------------------------------
176 sal_Bool SAL_CALL SfxEvents_Impl::hasByName( const OUSTRING& aName ) throw ( RUNTIMEEXCEPTION )
178 ::osl::MutexGuard aGuard( maMutex );
180 // find the event in the list and return the data
182 long nCount = maEventNames.getLength();
184 for ( long i=0; i<nCount; i++ )
186 if ( maEventNames[i] == aName )
187 return sal_True;
190 return sal_False;
193 //--------------------------------------------------------------------------------------------------------
194 // --- XElementAccess ( parent of XNameAccess ) ---
195 //--------------------------------------------------------------------------------------------------------
196 UNOTYPE SAL_CALL SfxEvents_Impl::getElementType() throw ( RUNTIMEEXCEPTION )
198 UNOTYPE aElementType = ::getCppuType( (const SEQUENCE < PROPERTYVALUE > *)0 );
199 return aElementType;
202 //--------------------------------------------------------------------------------------------------------
203 sal_Bool SAL_CALL SfxEvents_Impl::hasElements() throw ( RUNTIMEEXCEPTION )
205 ::osl::MutexGuard aGuard( maMutex );
207 if ( maEventNames.getLength() )
208 return sal_True;
209 else
210 return sal_False;
213 static void Execute( ANY& aEventData, const css::document::DocumentEvent& aTrigger, SfxObjectShell* pDoc )
215 SEQUENCE < PROPERTYVALUE > aProperties;
216 if ( aEventData >>= aProperties )
218 OUSTRING aPrefix = OUSTRING( RTL_CONSTASCII_USTRINGPARAM( MACRO_PRFIX ) );
219 OUSTRING aType;
220 OUSTRING aScript;
221 OUSTRING aLibrary;
222 OUSTRING aMacroName;
224 sal_Int32 nCount = aProperties.getLength();
226 if ( !nCount )
227 return;
229 sal_Int32 nIndex = 0;
230 while ( nIndex < nCount )
232 if ( aProperties[ nIndex ].Name.compareToAscii( PROP_EVENT_TYPE ) == 0 )
233 aProperties[ nIndex ].Value >>= aType;
234 else if ( aProperties[ nIndex ].Name.compareToAscii( PROP_SCRIPT ) == 0 )
235 aProperties[ nIndex ].Value >>= aScript;
236 else if ( aProperties[ nIndex ].Name.compareToAscii( PROP_LIBRARY ) == 0 )
237 aProperties[ nIndex ].Value >>= aLibrary;
238 else if ( aProperties[ nIndex ].Name.compareToAscii( PROP_MACRO_NAME ) == 0 )
239 aProperties[ nIndex ].Value >>= aMacroName;
240 else {
241 DBG_ERROR("Unknown property value!");
243 nIndex += 1;
246 if ( aType.compareToAscii( STAR_BASIC ) == 0 && aScript.getLength() )
248 com::sun::star::uno::Any aAny;
249 SfxMacroLoader::loadMacro( aScript, aAny, pDoc );
251 else if ( aType.compareToAscii( "Service" ) == 0 ||
252 aType.compareToAscii( "Script" ) == 0 )
254 if ( aScript.getLength() )
256 SfxViewFrame* pView = pDoc ?
257 SfxViewFrame::GetFirst( pDoc ) :
258 SfxViewFrame::Current();
260 ::com::sun::star::uno::Reference
261 < ::com::sun::star::util::XURLTransformer > xTrans(
262 ::comphelper::getProcessServiceFactory()->createInstance(
263 rtl::OUString::createFromAscii(
264 "com.sun.star.util.URLTransformer" ) ),
265 UNO_QUERY );
267 ::com::sun::star::util::URL aURL;
268 aURL.Complete = aScript;
269 xTrans->parseStrict( aURL );
271 ::com::sun::star::uno::Reference
272 < ::com::sun::star::frame::XDispatchProvider > xProv;
274 if ( pView != NULL )
276 xProv = ::com::sun::star::uno::Reference
277 < ::com::sun::star::frame::XDispatchProvider > (
278 pView->GetFrame()->GetFrameInterface(), UNO_QUERY );
280 else
282 xProv = ::com::sun::star::uno::Reference
283 < ::com::sun::star::frame::XDispatchProvider > (
284 ::comphelper::getProcessServiceFactory()->createInstance(
285 rtl::OUString::createFromAscii(
286 "com.sun.star.frame.Desktop" ) ),
287 UNO_QUERY );
290 ::com::sun::star::uno::Reference < ::com::sun::star::frame::XDispatch > xDisp;
291 if ( xProv.is() )
292 xDisp = xProv->queryDispatch( aURL, ::rtl::OUString(), 0 );
294 if ( xDisp.is() )
296 //::com::sun::star::uno::Sequence < ::com::sun::star::beans::PropertyValue > aArgs(1);
297 //aArgs[0].Name = rtl::OUString::createFromAscii("Referer");
298 //aArs[0].Value <<= ::rtl::OUString( pDoc->GetMedium()->GetName() );
299 //xDisp->dispatch( aURL, aArgs );
301 css::beans::PropertyValue aEventParam;
302 aEventParam.Value <<= aTrigger;
303 css::uno::Sequence< css::beans::PropertyValue > aDispatchArgs( &aEventParam, 1 );
304 xDisp->dispatch( aURL, aDispatchArgs );
308 else if ( aType.getLength() == 0 )
310 // Empty type means no active binding for the event. Just ignore do nothing.
312 else
314 DBG_ERRORFILE( "notifyEvent(): Unsupported event type" );
319 //--------------------------------------------------------------------------------------------------------
320 // --- ::document::XEventListener ---
321 //--------------------------------------------------------------------------------------------------------
322 void SAL_CALL SfxEvents_Impl::notifyEvent( const DOCEVENTOBJECT& aEvent ) throw( RUNTIMEEXCEPTION )
324 ::osl::ClearableMutexGuard aGuard( maMutex );
326 // get the event name, find the coresponding data, execute the data
328 OUSTRING aName = aEvent.EventName;
329 long nCount = maEventNames.getLength();
330 long nIndex = 0;
331 sal_Bool bFound = sal_False;
333 while ( !bFound && ( nIndex < nCount ) )
335 if ( maEventNames[nIndex] == aName )
336 bFound = sal_True;
337 else
338 nIndex += 1;
341 if ( !bFound )
342 return;
344 ANY aEventData = maEventData[ nIndex ];
345 aGuard.clear();
346 Execute( aEventData, css::document::DocumentEvent(aEvent.Source, aEvent.EventName, NULL, css::uno::Any()), mpObjShell );
349 //--------------------------------------------------------------------------------------------------------
350 // --- ::lang::XEventListener ---
351 //--------------------------------------------------------------------------------------------------------
352 void SAL_CALL SfxEvents_Impl::disposing( const EVENTOBJECT& /*Source*/ ) throw( RUNTIMEEXCEPTION )
354 ::osl::MutexGuard aGuard( maMutex );
356 if ( mxBroadcaster.is() )
358 mxBroadcaster->removeEventListener( this );
359 mxBroadcaster = NULL;
363 //--------------------------------------------------------------------------------------------------------
365 //--------------------------------------------------------------------------------------------------------
366 SfxEvents_Impl::SfxEvents_Impl( SfxObjectShell* pShell,
367 REFERENCE< XEVENTBROADCASTER > xBroadcaster )
369 // get the list of supported events and store it
370 if ( pShell )
371 maEventNames = pShell->GetEventNames();
372 else
373 maEventNames = SfxObjectShell::GetEventNames_Impl();
375 maEventData = SEQUENCE < ANY > ( maEventNames.getLength() );
377 mpObjShell = pShell;
378 mxBroadcaster = xBroadcaster;
380 if ( mxBroadcaster.is() )
381 mxBroadcaster->addEventListener( this );
384 //--------------------------------------------------------------------------------------------------------
385 SfxEvents_Impl::~SfxEvents_Impl()
389 //--------------------------------------------------------------------------------------------------------
390 SvxMacro* SfxEvents_Impl::ConvertToMacro( const ANY& rElement, SfxObjectShell* pObjShell, BOOL bBlowUp )
392 SvxMacro* pMacro = NULL;
393 SEQUENCE < PROPERTYVALUE > aProperties;
394 ANY aAny;
395 if ( bBlowUp )
396 BlowUpMacro( rElement, aAny, pObjShell );
397 else
398 aAny = rElement;
400 if ( aAny >>= aProperties )
402 OUSTRING aType;
403 OUSTRING aScriptURL;
404 OUSTRING aLibrary;
405 OUSTRING aMacroName;
407 long nCount = aProperties.getLength();
408 long nIndex = 0;
410 if ( !nCount )
411 return pMacro;
413 while ( nIndex < nCount )
415 if ( aProperties[ nIndex ].Name.compareToAscii( PROP_EVENT_TYPE ) == 0 )
416 aProperties[ nIndex ].Value >>= aType;
417 else if ( aProperties[ nIndex ].Name.compareToAscii( PROP_SCRIPT ) == 0 )
418 aProperties[ nIndex ].Value >>= aScriptURL;
419 else if ( aProperties[ nIndex ].Name.compareToAscii( PROP_LIBRARY ) == 0 )
420 aProperties[ nIndex ].Value >>= aLibrary;
421 else if ( aProperties[ nIndex ].Name.compareToAscii( PROP_MACRO_NAME ) == 0 )
422 aProperties[ nIndex ].Value >>= aMacroName;
423 else {
424 DBG_ERROR("Unknown propery value!");
426 nIndex += 1;
429 // Get the type
430 ScriptType eType( STARBASIC );
431 if ( aType.compareToAscii( STAR_BASIC ) == COMPARE_EQUAL )
432 eType = STARBASIC;
433 else if ( aType.compareToAscii( "Script" ) == COMPARE_EQUAL && aScriptURL.getLength() )
434 eType = EXTENDED_STYPE;
435 else if ( aType.compareToAscii( SVX_MACRO_LANGUAGE_JAVASCRIPT ) == COMPARE_EQUAL )
436 eType = JAVASCRIPT;
437 else {
438 DBG_ERRORFILE( "ConvertToMacro: Unknown macro type" );
441 if ( aMacroName.getLength() )
443 if ( aLibrary.compareToAscii("application") == 0 )
444 aLibrary = SFX_APP()->GetName();
445 else
446 aLibrary = ::rtl::OUString();
447 pMacro = new SvxMacro( aMacroName, aLibrary, eType );
449 else if ( eType == EXTENDED_STYPE )
450 pMacro = new SvxMacro( aScriptURL, aType );
453 return pMacro;
456 void SfxEvents_Impl::BlowUpMacro( const ANY& rEvent, ANY& rRet, SfxObjectShell* pDoc )
458 if ( !pDoc )
459 pDoc = SfxObjectShell::Current();
461 SEQUENCE < PROPERTYVALUE > aInProps;
462 SEQUENCE < PROPERTYVALUE > aOutProps(2);
464 if ( !( rEvent >>= aInProps ) )
465 return;
467 sal_Int32 nCount = aInProps.getLength();
469 if ( !nCount )
470 return;
472 OUSTRING aType;
473 OUSTRING aScript;
474 OUSTRING aLibrary;
475 OUSTRING aMacroName;
477 sal_Int32 nIndex = 0;
479 while ( nIndex < nCount )
481 if ( aInProps[ nIndex ].Name.compareToAscii( PROP_EVENT_TYPE ) == 0 )
483 aInProps[nIndex].Value >>= aType;
484 aOutProps[0] = aInProps[nIndex];
486 else if ( aInProps[ nIndex ].Name.compareToAscii( PROP_SCRIPT ) == 0 )
488 aInProps[nIndex].Value >>= aScript;
489 aOutProps[1] = aInProps[nIndex];
491 else if ( aInProps[ nIndex ].Name.compareToAscii( PROP_LIBRARY ) == 0 )
493 aInProps[ nIndex ].Value >>= aLibrary;
495 else if ( aInProps[ nIndex ].Name.compareToAscii( PROP_MACRO_NAME ) == 0 )
497 aInProps[ nIndex ].Value >>= aMacroName;
499 nIndex += 1;
502 if ( aType.compareToAscii( STAR_BASIC ) == 0 )
504 aOutProps.realloc(4);
505 if ( aScript.getLength() )
507 if( ! aMacroName.getLength() || ! aLibrary.getLength() )
509 sal_Int32 nHashPos = aScript.indexOf( '/', 8 );
510 sal_Int32 nArgsPos = aScript.indexOf( '(' );
511 if ( ( nHashPos != STRING_NOTFOUND ) && ( nHashPos < nArgsPos ) )
513 OUSTRING aBasMgrName( INetURLObject::decode( aScript.copy( 8, nHashPos-8 ), INET_HEX_ESCAPE, INetURLObject::DECODE_WITH_CHARSET ) );
514 if ( aBasMgrName.compareToAscii(".") == 0 )
515 aLibrary = pDoc->GetTitle();
517 else if ( aBasMgrName.getLength() )
518 aLibrary = aBasMgrName;
520 else
521 aLibrary = SFX_APP()->GetName();
523 // Get the macro name
524 aMacroName = aScript.copy( nHashPos+1, nArgsPos - nHashPos - 1 );
526 else
528 DBG_ERRORFILE( "ConvertToMacro: Unknown macro url format" );
532 else if ( aMacroName.getLength() )
534 aScript = OUSTRING( RTL_CONSTASCII_USTRINGPARAM( MACRO_PRFIX ) );
535 if ( aLibrary.compareTo( SFX_APP()->GetName() ) != 0 && aLibrary.compareToAscii("StarDesktop") != 0 && aLibrary.compareToAscii("application") != 0 )
536 aScript += String('.');
538 aScript += String('/');
539 aScript += aMacroName;
540 aScript += OUSTRING( RTL_CONSTASCII_USTRINGPARAM( MACRO_POSTFIX ) );
542 else
543 // wrong properties
544 return;
546 if ( aLibrary.compareToAscii("document") != 0 )
548 if ( !aLibrary.getLength() || (pDoc && ( String(aLibrary) == pDoc->GetTitle( SFX_TITLE_APINAME ) || String(aLibrary) == pDoc->GetTitle() )) )
549 aLibrary = String::CreateFromAscii("document");
550 else
551 aLibrary = String::CreateFromAscii("application");
554 aOutProps[1].Name = OUSTRING::createFromAscii( PROP_SCRIPT );
555 aOutProps[1].Value <<= aScript;
556 aOutProps[2].Name = OUSTRING::createFromAscii( PROP_LIBRARY );
557 aOutProps[2].Value <<= aLibrary;
558 aOutProps[3].Name = OUSTRING::createFromAscii( PROP_MACRO_NAME );
559 aOutProps[3].Value <<= aMacroName;
560 rRet <<= aOutProps;
562 else if ( aType.compareToAscii( SVX_MACRO_LANGUAGE_JAVASCRIPT ) == 0 )
564 aOutProps[1] = aInProps[1];
565 rRet <<= aOutProps;
567 else
569 rRet <<= aOutProps;
573 ModelCollectionEnumeration::ModelCollectionEnumeration(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
574 : ModelCollectionMutexBase( )
575 , m_xSMGR (xSMGR )
576 , m_pEnumerationIt (m_lModels.begin())
580 ModelCollectionEnumeration::~ModelCollectionEnumeration()
584 void ModelCollectionEnumeration::setModelList(const TModelList& rList)
586 // SAFE ->
587 ::osl::ResettableMutexGuard aLock(m_aLock);
588 m_lModels = rList;
589 m_pEnumerationIt = m_lModels.begin();
590 aLock.clear();
591 // <- SAFE
594 sal_Bool SAL_CALL ModelCollectionEnumeration::hasMoreElements()
595 throw(css::uno::RuntimeException)
597 // SAFE ->
598 ::osl::ResettableMutexGuard aLock(m_aLock);
599 return (m_pEnumerationIt != m_lModels.end());
600 // <- SAFE
603 css::uno::Any SAL_CALL ModelCollectionEnumeration::nextElement()
604 throw(css::container::NoSuchElementException,
605 css::lang::WrappedTargetException ,
606 css::uno::RuntimeException )
608 // SAFE ->
609 ::osl::ResettableMutexGuard aLock(m_aLock);
610 if (m_pEnumerationIt == m_lModels.end())
611 throw css::container::NoSuchElementException(
612 ::rtl::OUString::createFromAscii("End of model enumeration reached."),
613 static_cast< css::container::XEnumeration* >(this));
614 css::uno::Reference< css::frame::XModel > xModel(*m_pEnumerationIt, UNO_QUERY);
615 ++m_pEnumerationIt;
616 aLock.clear();
617 // <- SAFE
619 return css::uno::makeAny(xModel);
622 SFX_IMPL_XSERVICEINFO( SfxGlobalEvents_Impl, "com.sun.star.frame.GlobalEventBroadcaster", "com.sun.star.comp.sfx2.GlobalEventBroadcaster" )
623 SFX_IMPL_ONEINSTANCEFACTORY( SfxGlobalEvents_Impl );
625 //-----------------------------------------------------------------------------
626 SfxGlobalEvents_Impl::SfxGlobalEvents_Impl( const com::sun::star::uno::Reference < ::com::sun::star::lang::XMultiServiceFactory >& xSMGR)
627 : ModelCollectionMutexBase( )
628 , m_xSMGR (xSMGR )
629 , m_aLegacyListeners (m_aLock)
630 , m_aDocumentListeners (m_aLock)
631 , pImp (0 )
633 m_refCount++;
634 SFX_APP();
635 pImp = new GlobalEventConfig();
636 m_xEvents = pImp;
637 m_xJobExecutorListener = css::uno::Reference< css::document::XEventListener >(
638 xSMGR->createInstance(::rtl::OUString::createFromAscii("com.sun.star.task.JobExecutor")),
639 UNO_QUERY);
640 m_refCount--;
643 //-----------------------------------------------------------------------------
644 SfxGlobalEvents_Impl::~SfxGlobalEvents_Impl()
648 //-----------------------------------------------------------------------------
649 void SfxGlobalEvents_Impl::Notify( SfxBroadcaster& /*aBC*/, const SfxHint& aHint )
651 SfxEventHint* pNamedHint = PTR_CAST(SfxEventHint, &aHint);
652 if (!pNamedHint)
653 return;
655 css::uno::Reference< css::document::XEventsSupplier > xSup;
657 ::rtl::OUString sName = SfxEventConfiguration::GetEventName_Impl(pNamedHint->GetEventId());
658 SfxObjectShell* pShell = pNamedHint->GetObjShell();
659 if (pShell)
660 xSup = css::uno::Reference< css::document::XEventsSupplier >(pShell->GetModel(), UNO_QUERY);
662 css::document::EventObject aEvent(xSup, sName);
663 notifyEvent(aEvent);
666 //-----------------------------------------------------------------------------
667 css::uno::Reference< css::container::XNameReplace > SAL_CALL SfxGlobalEvents_Impl::getEvents()
668 throw(css::uno::RuntimeException)
670 // SAFE ->
671 ::osl::ResettableMutexGuard aLock(m_aLock);
672 return m_xEvents;
673 // <- SAFE
676 //-----------------------------------------------------------------------------
677 void SAL_CALL SfxGlobalEvents_Impl::addEventListener(const css::uno::Reference< css::document::XEventListener >& xListener)
678 throw(css::uno::RuntimeException)
680 // container is threadsafe
681 m_aLegacyListeners.addInterface(xListener);
684 //-----------------------------------------------------------------------------
685 void SAL_CALL SfxGlobalEvents_Impl::removeEventListener(const css::uno::Reference< css::document::XEventListener >& xListener)
686 throw(css::uno::RuntimeException)
688 // container is threadsafe
689 m_aLegacyListeners.removeInterface(xListener);
692 //-----------------------------------------------------------------------------
693 void SAL_CALL SfxGlobalEvents_Impl::addDocumentEventListener( const css::uno::Reference< css::document::XDocumentEventListener >& _Listener )
694 throw(css::uno::RuntimeException)
696 m_aDocumentListeners.addInterface( _Listener );
699 //-----------------------------------------------------------------------------
700 void SAL_CALL SfxGlobalEvents_Impl::removeDocumentEventListener( const css::uno::Reference< css::document::XDocumentEventListener >& _Listener )
701 throw(css::uno::RuntimeException)
703 m_aDocumentListeners.removeInterface( _Listener );
706 //-----------------------------------------------------------------------------
707 void SAL_CALL SfxGlobalEvents_Impl::notifyDocumentEvent( const ::rtl::OUString& /*_EventName*/,
708 const css::uno::Reference< css::frame::XController2 >& /*_ViewController*/, const css::uno::Any& /*_Supplement*/ )
709 throw (css::lang::IllegalArgumentException, css::lang::NoSupportException, css::uno::RuntimeException)
711 // we're a multiplexer only, no change to generate artifical events here
712 throw css::lang::NoSupportException(::rtl::OUString(), *this);
715 //-----------------------------------------------------------------------------
716 void SAL_CALL SfxGlobalEvents_Impl::notifyEvent(const css::document::EventObject& aEvent)
717 throw(css::uno::RuntimeException)
719 css::document::DocumentEvent aDocEvent(aEvent.Source, aEvent.EventName, NULL, css::uno::Any());
720 implts_notifyJobExecution(aEvent);
721 implts_checkAndExecuteEventBindings(aDocEvent);
722 implts_notifyListener(aDocEvent);
725 //-----------------------------------------------------------------------------
726 void SAL_CALL SfxGlobalEvents_Impl::documentEventOccured( const ::css::document::DocumentEvent& _Event )
727 throw (::css::uno::RuntimeException)
729 implts_notifyJobExecution(css::document::EventObject(_Event.Source, _Event.EventName));
730 implts_checkAndExecuteEventBindings(_Event);
731 implts_notifyListener(_Event);
734 //-----------------------------------------------------------------------------
735 void SAL_CALL SfxGlobalEvents_Impl::disposing(const css::lang::EventObject& aEvent)
736 throw(css::uno::RuntimeException)
738 css::uno::Reference< css::frame::XModel > xDoc(aEvent.Source, UNO_QUERY);
740 // SAFE ->
741 ::osl::ResettableMutexGuard aLock(m_aLock);
742 TModelList::iterator pIt = impl_searchDoc(xDoc);
743 if (pIt != m_lModels.end())
744 m_lModels.erase(pIt);
745 aLock.clear();
746 // <- SAFE
749 //-----------------------------------------------------------------------------
750 sal_Bool SAL_CALL SfxGlobalEvents_Impl::has(const css::uno::Any& aElement)
751 throw (css::uno::RuntimeException)
753 css::uno::Reference< css::frame::XModel > xDoc;
754 aElement >>= xDoc;
756 sal_Bool bHas = sal_False;
758 // SAFE ->
759 ::osl::ResettableMutexGuard aLock(m_aLock);
760 TModelList::iterator pIt = impl_searchDoc(xDoc);
761 if (pIt != m_lModels.end())
762 bHas = sal_True;
763 aLock.clear();
764 // <- SAFE
766 return bHas;
769 //-----------------------------------------------------------------------------
770 void SAL_CALL SfxGlobalEvents_Impl::insert( const css::uno::Any& aElement )
771 throw (css::lang::IllegalArgumentException ,
772 css::container::ElementExistException,
773 css::uno::RuntimeException )
775 css::uno::Reference< css::frame::XModel > xDoc;
776 aElement >>= xDoc;
777 if (!xDoc.is())
778 throw css::lang::IllegalArgumentException(
779 ::rtl::OUString::createFromAscii("Cant locate at least the model parameter."),
780 static_cast< css::container::XSet* >(this),
783 // SAFE ->
784 ::osl::ResettableMutexGuard aLock(m_aLock);
785 TModelList::iterator pIt = impl_searchDoc(xDoc);
786 if (pIt != m_lModels.end())
787 throw css::container::ElementExistException(
788 ::rtl::OUString(),
789 static_cast< css::container::XSet* >(this));
790 m_lModels.push_back(xDoc);
791 aLock.clear();
792 // <- SAFE
794 css::uno::Reference< css::document::XDocumentEventBroadcaster > xDocBroadcaster(xDoc, UNO_QUERY );
795 if (xDocBroadcaster.is())
796 xDocBroadcaster->addDocumentEventListener(this);
797 else
799 // try the "legacy version" of XDocumentEventBroadcaster, which is XEventBroadcaster
800 css::uno::Reference< css::document::XEventBroadcaster > xBroadcaster(xDoc, UNO_QUERY);
801 if (xBroadcaster.is())
802 xBroadcaster->addEventListener(static_cast< css::document::XEventListener* >(this));
806 //-----------------------------------------------------------------------------
807 void SAL_CALL SfxGlobalEvents_Impl::remove( const css::uno::Any& aElement )
808 throw (css::lang::IllegalArgumentException ,
809 css::container::NoSuchElementException,
810 css::uno::RuntimeException )
812 css::uno::Reference< css::frame::XModel > xDoc;
813 aElement >>= xDoc;
814 if (!xDoc.is())
815 throw css::lang::IllegalArgumentException(
816 ::rtl::OUString::createFromAscii("Cant locate at least the model parameter."),
817 static_cast< css::container::XSet* >(this),
820 // SAFE ->
821 ::osl::ResettableMutexGuard aLock(m_aLock);
822 TModelList::iterator pIt = impl_searchDoc(xDoc);
823 if (pIt == m_lModels.end())
824 throw css::container::NoSuchElementException(
825 ::rtl::OUString(),
826 static_cast< css::container::XSet* >(this));
827 m_lModels.erase(pIt);
828 aLock.clear();
829 // <- SAFE
831 css::uno::Reference< css::document::XDocumentEventBroadcaster > xDocBroadcaster(xDoc, UNO_QUERY );
832 if (xDocBroadcaster.is())
833 xDocBroadcaster->removeDocumentEventListener(this);
834 else
836 // try the "legacy version" of XDocumentEventBroadcaster, which is XEventBroadcaster
837 css::uno::Reference< css::document::XEventBroadcaster > xBroadcaster(xDoc, UNO_QUERY);
838 if (xBroadcaster.is())
839 xBroadcaster->removeEventListener(static_cast< css::document::XEventListener* >(this));
843 //-----------------------------------------------------------------------------
844 css::uno::Reference< css::container::XEnumeration > SAL_CALL SfxGlobalEvents_Impl::createEnumeration()
845 throw (css::uno::RuntimeException)
847 // SAFE ->
848 ::osl::ResettableMutexGuard aLock(m_aLock);
849 ModelCollectionEnumeration* pEnum = new ModelCollectionEnumeration(m_xSMGR);
850 pEnum->setModelList(m_lModels);
851 css::uno::Reference< css::container::XEnumeration > xEnum(
852 static_cast< css::container::XEnumeration* >(pEnum),
853 UNO_QUERY);
854 aLock.clear();
855 // <- SAFE
857 return xEnum;
860 //-----------------------------------------------------------------------------
861 css::uno::Type SAL_CALL SfxGlobalEvents_Impl::getElementType()
862 throw (css::uno::RuntimeException)
864 return ::getCppuType(static_cast< css::uno::Reference< css::frame::XModel >* >(NULL));
867 //-----------------------------------------------------------------------------
868 sal_Bool SAL_CALL SfxGlobalEvents_Impl::hasElements()
869 throw (css::uno::RuntimeException)
871 // SAFE ->
872 ::osl::ResettableMutexGuard aLock(m_aLock);
873 return (m_lModels.size()>0);
874 // <- SAFE
877 //-----------------------------------------------------------------------------
878 void SfxGlobalEvents_Impl::implts_notifyJobExecution(const css::document::EventObject& aEvent)
882 // SAFE ->
883 ::osl::ResettableMutexGuard aLock(m_aLock);
884 css::uno::Reference< css::document::XEventListener > xJobExecutor(m_xJobExecutorListener);
885 aLock.clear();
886 // <- SAFE
887 if (xJobExecutor.is())
888 xJobExecutor->notifyEvent(aEvent);
890 catch(const css::uno::RuntimeException& exRun)
891 { throw exRun; }
892 catch(const css::uno::Exception&)
896 //-----------------------------------------------------------------------------
897 void SfxGlobalEvents_Impl::implts_checkAndExecuteEventBindings(const css::document::DocumentEvent& aEvent)
901 // SAFE ->
902 ::osl::ResettableMutexGuard aLock(m_aLock);
903 css::uno::Reference< css::container::XNameReplace > xEvents = m_xEvents;
904 aLock.clear();
905 // <- SAFE
907 css::uno::Any aAny;
908 if (xEvents.is())
909 aAny = xEvents->getByName(aEvent.EventName);
910 Execute(aAny, aEvent, 0);
912 catch(const css::uno::RuntimeException& exRun)
913 { throw exRun; }
914 catch(const css::uno::Exception&)
918 //-----------------------------------------------------------------------------
919 void SfxGlobalEvents_Impl::implts_notifyListener(const css::document::DocumentEvent& aEvent)
921 // containers are threadsafe
922 css::document::EventObject aLegacyEvent(aEvent.Source, aEvent.EventName);
923 m_aLegacyListeners.notifyEach( &css::document::XEventListener::notifyEvent, aLegacyEvent );
925 m_aDocumentListeners.notifyEach( &css::document::XDocumentEventListener::documentEventOccured, aEvent );
928 //-----------------------------------------------------------------------------
929 // not threadsafe ... must be locked from outside!
930 TModelList::iterator SfxGlobalEvents_Impl::impl_searchDoc(const css::uno::Reference< css::frame::XModel >& xModel)
932 if (!xModel.is())
933 return m_lModels.end();
935 TModelList::iterator pIt;
936 for ( pIt = m_lModels.begin();
937 pIt != m_lModels.end() ;
938 ++pIt )
940 css::uno::Reference< css::frame::XModel > xContainerDoc(*pIt, UNO_QUERY);
941 if (xContainerDoc == xModel)
942 break;
945 return pIt;