Bump version to 4.1-6
[LibreOffice.git] / sfx2 / source / notify / eventsupplier.cxx
blobd760a30385e4c521d2372971c353a19da21794bd
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <com/sun/star/beans/PropertyValue.hpp>
22 #include <com/sun/star/util/URL.hpp>
24 #include <com/sun/star/frame/Desktop.hpp>
25 #include <com/sun/star/task/JobExecutor.hpp>
26 #include <com/sun/star/util/URLTransformer.hpp>
27 #include <com/sun/star/util/XURLTransformer.hpp>
28 #include <tools/urlobj.hxx>
29 #include <tools/diagnose_ex.h>
30 #include <svl/macitem.hxx>
31 #include <sfx2/appuno.hxx>
32 #include <sfx2/objsh.hxx>
33 #include <sfx2/sfxbasemodel.hxx>
34 #include <sfx2/evntconf.hxx>
35 #include <unotools/eventcfg.hxx>
37 #include <unotools/securityoptions.hxx>
38 #include <comphelper/processfactory.hxx>
39 #include <comphelper/namedvaluecollection.hxx>
40 #include "eventsupplier.hxx"
42 #include <sfx2/app.hxx>
43 #include "sfx2/sfxresid.hxx"
45 #include <sfx2/sfxsids.hrc>
46 #include "sfxlocal.hrc"
47 #include <sfx2/docfile.hxx>
48 #include <sfx2/viewfrm.hxx>
49 #include <sfx2/frame.hxx>
51 //--------------------------------------------------------------------------------------------------------
53 #define MACRO_PRFIX "macro://"
54 #define MACRO_POSTFIX "()"
56 using namespace css;
58 //--------------------------------------------------------------------------------------------------------
59 // --- XNameReplace ---
60 //--------------------------------------------------------------------------------------------------------
61 void SAL_CALL SfxEvents_Impl::replaceByName( const OUString & aName, const uno::Any & rElement )
62 throw( lang::IllegalArgumentException, container::NoSuchElementException,
63 lang::WrappedTargetException, uno::RuntimeException )
65 ::osl::MutexGuard aGuard( maMutex );
67 // find the event in the list and replace the data
68 long nCount = maEventNames.getLength();
69 for ( long i=0; i<nCount; i++ )
71 if ( maEventNames[i] == aName )
73 // check for correct type of the element
74 if ( !::comphelper::NamedValueCollection::canExtractFrom( rElement ) )
75 throw lang::IllegalArgumentException();
76 ::comphelper::NamedValueCollection const aEventDescriptor( rElement );
78 // create Configuration at first, creation might call this method also and that would overwrite everything
79 // we might have stored before!
80 if ( mpObjShell && !mpObjShell->IsLoading() )
81 mpObjShell->SetModified( sal_True );
83 ::comphelper::NamedValueCollection aNormalizedDescriptor;
84 NormalizeMacro( aEventDescriptor, aNormalizedDescriptor, mpObjShell );
86 OUString sType;
87 if ( ( aNormalizedDescriptor.size() == 1 )
88 && ( aNormalizedDescriptor.has( PROP_EVENT_TYPE) == 0 )
89 && ( aNormalizedDescriptor.get( PROP_EVENT_TYPE ) >>= sType )
90 && ( sType.isEmpty() )
93 // An empty event type means no binding. Therefore reset data
94 // to reflect that state.
95 // (that's for compatibility only. Nowadays, the Tools/Customize dialog should
96 // set an empty sequence to indicate the request for resetting the assignment.)
97 OSL_ENSURE( false, "legacy event assignment format detected" );
98 aNormalizedDescriptor.clear();
101 if ( !aNormalizedDescriptor.empty() )
103 maEventData[i] <<= aNormalizedDescriptor.getPropertyValues();
105 else
107 maEventData[i].clear();
109 return;
113 throw container::NoSuchElementException();
116 //--------------------------------------------------------------------------------------------------------
117 // --- XNameAccess ---
118 //--------------------------------------------------------------------------------------------------------
119 uno::Any SAL_CALL SfxEvents_Impl::getByName( const OUString& aName )
120 throw( container::NoSuchElementException, lang::WrappedTargetException,
121 uno::RuntimeException )
123 ::osl::MutexGuard aGuard( maMutex );
125 // find the event in the list and return the data
127 long nCount = maEventNames.getLength();
129 for ( long i=0; i<nCount; i++ )
131 if ( maEventNames[i] == aName )
132 return maEventData[i];
135 throw container::NoSuchElementException();
138 //--------------------------------------------------------------------------------------------------------
139 uno::Sequence< OUString > SAL_CALL SfxEvents_Impl::getElementNames() throw ( uno::RuntimeException )
141 return maEventNames;
144 //--------------------------------------------------------------------------------------------------------
145 sal_Bool SAL_CALL SfxEvents_Impl::hasByName( const OUString& aName ) throw ( uno::RuntimeException )
147 ::osl::MutexGuard aGuard( maMutex );
149 // find the event in the list and return the data
151 long nCount = maEventNames.getLength();
153 for ( long i=0; i<nCount; i++ )
155 if ( maEventNames[i] == aName )
156 return sal_True;
159 return sal_False;
162 //--------------------------------------------------------------------------------------------------------
163 // --- XElementAccess ( parent of XNameAccess ) ---
164 //--------------------------------------------------------------------------------------------------------
165 uno::Type SAL_CALL SfxEvents_Impl::getElementType() throw ( uno::RuntimeException )
167 uno::Type aElementType = ::getCppuType( (const uno::Sequence < beans::PropertyValue > *)0 );
168 return aElementType;
171 //--------------------------------------------------------------------------------------------------------
172 sal_Bool SAL_CALL SfxEvents_Impl::hasElements() throw ( uno::RuntimeException )
174 ::osl::MutexGuard aGuard( maMutex );
176 if ( maEventNames.getLength() )
177 return sal_True;
178 else
179 return sal_False;
182 static void Execute( uno::Any& aEventData, const document::DocumentEvent& aTrigger, SfxObjectShell* pDoc )
184 uno::Sequence < beans::PropertyValue > aProperties;
185 if ( aEventData >>= aProperties )
187 OUString aType;
188 OUString aScript;
189 OUString aLibrary;
190 OUString aMacroName;
192 sal_Int32 nCount = aProperties.getLength();
194 if ( !nCount )
195 return;
197 sal_Int32 nIndex = 0;
198 while ( nIndex < nCount )
200 if ( aProperties[ nIndex ].Name == PROP_EVENT_TYPE )
201 aProperties[ nIndex ].Value >>= aType;
202 else if ( aProperties[ nIndex ].Name == PROP_SCRIPT )
203 aProperties[ nIndex ].Value >>= aScript;
204 else if ( aProperties[ nIndex ].Name == PROP_LIBRARY )
205 aProperties[ nIndex ].Value >>= aLibrary;
206 else if ( aProperties[ nIndex ].Name == PROP_MACRO_NAME )
207 aProperties[ nIndex ].Value >>= aMacroName;
208 else {
209 OSL_FAIL("Unknown property value!");
211 nIndex += 1;
214 if (aType.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(STAR_BASIC)) && !aScript.isEmpty())
216 uno::Any aAny;
217 SfxMacroLoader::loadMacro( aScript, aAny, pDoc );
219 else if (aType.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("Service")) ||
220 aType.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("Script")))
222 if ( !aScript.isEmpty() )
224 SfxViewFrame* pView = pDoc ?
225 SfxViewFrame::GetFirst( pDoc ) :
226 SfxViewFrame::Current();
228 uno::Reference < util::XURLTransformer > xTrans( util::URLTransformer::create( ::comphelper::getProcessComponentContext() ) );
230 util::URL aURL;
231 aURL.Complete = aScript;
232 xTrans->parseStrict( aURL );
234 uno::Reference
235 < frame::XDispatchProvider > xProv;
237 if ( pView != NULL )
239 xProv = uno::Reference
240 < frame::XDispatchProvider > (
241 pView->GetFrame().GetFrameInterface(), uno::UNO_QUERY );
243 else
245 xProv = uno::Reference< frame::XDispatchProvider > (
246 frame::Desktop::create( ::comphelper::getProcessComponentContext() ),
247 uno::UNO_QUERY );
250 uno::Reference < frame::XDispatch > xDisp;
251 if ( xProv.is() )
252 xDisp = xProv->queryDispatch( aURL, OUString(), 0 );
254 if ( xDisp.is() )
257 beans::PropertyValue aEventParam;
258 aEventParam.Value <<= aTrigger;
259 uno::Sequence< beans::PropertyValue > aDispatchArgs( &aEventParam, 1 );
260 xDisp->dispatch( aURL, aDispatchArgs );
264 else if ( aType.isEmpty() )
266 // Empty type means no active binding for the event. Just ignore do nothing.
268 else
270 SAL_WARN( "sfx2.notify", "notifyEvent(): Unsupported event type" );
275 //--------------------------------------------------------------------------------------------------------
276 // --- ::document::XEventListener ---
277 //--------------------------------------------------------------------------------------------------------
278 void SAL_CALL SfxEvents_Impl::notifyEvent( const document::EventObject& aEvent ) throw( uno::RuntimeException )
280 ::osl::ClearableMutexGuard aGuard( maMutex );
282 // get the event name, find the coresponding data, execute the data
284 OUString aName = aEvent.EventName;
285 long nCount = maEventNames.getLength();
286 long nIndex = 0;
287 sal_Bool bFound = sal_False;
289 while ( !bFound && ( nIndex < nCount ) )
291 if ( maEventNames[nIndex] == aName )
292 bFound = sal_True;
293 else
294 nIndex += 1;
297 if ( !bFound )
298 return;
300 uno::Any aEventData = maEventData[ nIndex ];
301 aGuard.clear();
302 Execute( aEventData, document::DocumentEvent(aEvent.Source, aEvent.EventName, NULL, uno::Any()), mpObjShell );
305 //--------------------------------------------------------------------------------------------------------
306 // --- ::lang::XEventListener ---
307 //--------------------------------------------------------------------------------------------------------
308 void SAL_CALL SfxEvents_Impl::disposing( const lang::EventObject& /*Source*/ ) throw( uno::RuntimeException )
310 ::osl::MutexGuard aGuard( maMutex );
312 if ( mxBroadcaster.is() )
314 mxBroadcaster->removeEventListener( this );
315 mxBroadcaster = NULL;
319 //--------------------------------------------------------------------------------------------------------
320 //--------------------------------------------------------------------------------------------------------
321 SfxEvents_Impl::SfxEvents_Impl( SfxObjectShell* pShell,
322 uno::Reference< document::XEventBroadcaster > xBroadcaster )
324 // get the list of supported events and store it
325 if ( pShell )
326 maEventNames = pShell->GetEventNames();
327 else
328 maEventNames = GlobalEventConfig().getElementNames();
330 maEventData = uno::Sequence < uno::Any > ( maEventNames.getLength() );
332 mpObjShell = pShell;
333 mxBroadcaster = xBroadcaster;
335 if ( mxBroadcaster.is() )
336 mxBroadcaster->addEventListener( this );
339 //--------------------------------------------------------------------------------------------------------
340 SfxEvents_Impl::~SfxEvents_Impl()
344 //--------------------------------------------------------------------------------------------------------
345 SvxMacro* SfxEvents_Impl::ConvertToMacro( const uno::Any& rElement, SfxObjectShell* pObjShell, sal_Bool bNormalizeMacro )
347 SvxMacro* pMacro = NULL;
348 uno::Sequence < beans::PropertyValue > aProperties;
349 uno::Any aAny;
350 if ( bNormalizeMacro )
351 NormalizeMacro( rElement, aAny, pObjShell );
352 else
353 aAny = rElement;
355 if ( aAny >>= aProperties )
357 OUString aType;
358 OUString aScriptURL;
359 OUString aLibrary;
360 OUString aMacroName;
362 long nCount = aProperties.getLength();
363 long nIndex = 0;
365 if ( !nCount )
366 return pMacro;
368 while ( nIndex < nCount )
370 if ( aProperties[ nIndex ].Name == PROP_EVENT_TYPE )
371 aProperties[ nIndex ].Value >>= aType;
372 else if ( aProperties[ nIndex ].Name == PROP_SCRIPT )
373 aProperties[ nIndex ].Value >>= aScriptURL;
374 else if ( aProperties[ nIndex ].Name == PROP_LIBRARY )
375 aProperties[ nIndex ].Value >>= aLibrary;
376 else if ( aProperties[ nIndex ].Name == PROP_MACRO_NAME )
377 aProperties[ nIndex ].Value >>= aMacroName;
378 else {
379 OSL_FAIL("Unknown propery value!");
381 nIndex += 1;
384 // Get the type
385 ScriptType eType( STARBASIC );
386 if ( aType == STAR_BASIC )
387 eType = STARBASIC;
388 else if (aType.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("Script")) && !aScriptURL.isEmpty())
389 eType = EXTENDED_STYPE;
390 else if ( aType == SVX_MACRO_LANGUAGE_JAVASCRIPT )
391 eType = JAVASCRIPT;
392 else {
393 SAL_WARN( "sfx2.notify", "ConvertToMacro: Unknown macro type" );
396 if ( !aMacroName.isEmpty() )
398 if ( aLibrary == "application" )
399 aLibrary = SFX_APP()->GetName();
400 else
401 aLibrary = OUString();
402 pMacro = new SvxMacro( aMacroName, aLibrary, eType );
404 else if ( eType == EXTENDED_STYPE )
405 pMacro = new SvxMacro( aScriptURL, aType );
408 return pMacro;
411 void SfxEvents_Impl::NormalizeMacro( const uno::Any& rEvent, uno::Any& rRet, SfxObjectShell* pDoc )
413 const ::comphelper::NamedValueCollection aEventDescriptor( rEvent );
414 ::comphelper::NamedValueCollection aEventDescriptorOut;
416 NormalizeMacro( aEventDescriptor, aEventDescriptorOut, pDoc );
418 rRet <<= aEventDescriptorOut.getPropertyValues();
421 void SfxEvents_Impl::NormalizeMacro( const ::comphelper::NamedValueCollection& i_eventDescriptor,
422 ::comphelper::NamedValueCollection& o_normalizedDescriptor, SfxObjectShell* i_document )
424 SfxObjectShell* pDoc = i_document;
425 if ( !pDoc )
426 pDoc = SfxObjectShell::Current();
428 OUString aType = i_eventDescriptor.getOrDefault( PROP_EVENT_TYPE, OUString() );
429 OUString aScript = i_eventDescriptor.getOrDefault( PROP_SCRIPT, OUString() );
430 OUString aLibrary = i_eventDescriptor.getOrDefault( PROP_LIBRARY, OUString() );
431 OUString aMacroName = i_eventDescriptor.getOrDefault( PROP_MACRO_NAME, OUString() );
433 if ( !aType.isEmpty() )
434 o_normalizedDescriptor.put( PROP_EVENT_TYPE, aType );
435 if ( !aScript.isEmpty() )
436 o_normalizedDescriptor.put( PROP_SCRIPT, aScript );
438 if ( aType == STAR_BASIC )
440 if ( !aScript.isEmpty() )
442 if ( aMacroName.isEmpty() || aLibrary.isEmpty() )
444 sal_Int32 nHashPos = aScript.indexOf( '/', 8 );
445 sal_Int32 nArgsPos = aScript.indexOf( '(' );
446 if ( ( nHashPos != STRING_NOTFOUND ) && ( nHashPos < nArgsPos ) )
448 OUString aBasMgrName( INetURLObject::decode( aScript.copy( 8, nHashPos-8 ), INET_HEX_ESCAPE, INetURLObject::DECODE_WITH_CHARSET ) );
449 if ( aBasMgrName == "." )
450 aLibrary = pDoc->GetTitle();
451 else
452 aLibrary = SFX_APP()->GetName();
454 // Get the macro name
455 aMacroName = aScript.copy( nHashPos+1, nArgsPos - nHashPos - 1 );
457 else
459 SAL_WARN( "sfx2.notify", "ConvertToMacro: Unknown macro url format" );
463 else if ( !aMacroName.isEmpty() )
465 aScript = OUString( MACRO_PRFIX );
466 if ( aLibrary.compareTo( SFX_APP()->GetName() ) != 0 && !aLibrary.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("StarDesktop")) && !aLibrary.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("application")) )
467 aScript += OUString('.');
469 aScript += OUString('/');
470 aScript += aMacroName;
471 aScript += OUString( MACRO_POSTFIX );
473 else
474 // wrong properties
475 return;
477 if (!aLibrary.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("document")))
479 if ( aLibrary.isEmpty() || (pDoc && ( String(aLibrary) == pDoc->GetTitle( SFX_TITLE_APINAME ) || String(aLibrary) == pDoc->GetTitle() )) )
480 aLibrary = OUString("document");
481 else
482 aLibrary = OUString("application");
485 o_normalizedDescriptor.put( PROP_SCRIPT, aScript );
486 o_normalizedDescriptor.put( PROP_LIBRARY, aLibrary );
487 o_normalizedDescriptor.put( PROP_MACRO_NAME, aMacroName );
491 ModelCollectionEnumeration::ModelCollectionEnumeration()
492 : ModelCollectionMutexBase( )
493 , m_pEnumerationIt (m_lModels.begin())
497 ModelCollectionEnumeration::~ModelCollectionEnumeration()
501 void ModelCollectionEnumeration::setModelList(const TModelList& rList)
503 // SAFE ->
504 ::osl::ResettableMutexGuard aLock(m_aLock);
505 m_lModels = rList;
506 m_pEnumerationIt = m_lModels.begin();
507 aLock.clear();
508 // <- SAFE
511 sal_Bool SAL_CALL ModelCollectionEnumeration::hasMoreElements()
512 throw(uno::RuntimeException)
514 // SAFE ->
515 ::osl::ResettableMutexGuard aLock(m_aLock);
516 return (m_pEnumerationIt != m_lModels.end());
517 // <- SAFE
520 uno::Any SAL_CALL ModelCollectionEnumeration::nextElement()
521 throw(container::NoSuchElementException,
522 lang::WrappedTargetException ,
523 uno::RuntimeException )
525 // SAFE ->
526 ::osl::ResettableMutexGuard aLock(m_aLock);
527 if (m_pEnumerationIt == m_lModels.end())
528 throw container::NoSuchElementException(
529 OUString("End of model enumeration reached."),
530 static_cast< container::XEnumeration* >(this));
531 uno::Reference< frame::XModel > xModel(*m_pEnumerationIt, uno::UNO_QUERY);
532 ++m_pEnumerationIt;
533 aLock.clear();
534 // <- SAFE
536 return uno::makeAny(xModel);
539 SFX_IMPL_XSERVICEINFO_CTX( SfxGlobalEvents_Impl, "com.sun.star.frame.GlobalEventBroadcaster", "com.sun.star.comp.sfx2.GlobalEventBroadcaster" )
540 SFX_IMPL_ONEINSTANCEFACTORY( SfxGlobalEvents_Impl );
542 //-----------------------------------------------------------------------------
543 SfxGlobalEvents_Impl::SfxGlobalEvents_Impl( const uno::Reference < uno::XComponentContext >& rxContext)
544 : ModelCollectionMutexBase( )
545 , m_xJobExecutorListener( task::JobExecutor::create( rxContext ), uno::UNO_QUERY_THROW )
546 , m_aLegacyListeners (m_aLock)
547 , m_aDocumentListeners (m_aLock)
548 , pImp (0 )
550 m_refCount++;
551 SFX_APP();
552 pImp = new GlobalEventConfig();
553 m_xEvents = pImp;
554 m_refCount--;
557 //-----------------------------------------------------------------------------
558 SfxGlobalEvents_Impl::~SfxGlobalEvents_Impl()
562 //-----------------------------------------------------------------------------
563 uno::Reference< container::XNameReplace > SAL_CALL SfxGlobalEvents_Impl::getEvents()
564 throw(uno::RuntimeException)
566 // SAFE ->
567 ::osl::ResettableMutexGuard aLock(m_aLock);
568 return m_xEvents;
569 // <- SAFE
572 //-----------------------------------------------------------------------------
573 void SAL_CALL SfxGlobalEvents_Impl::addEventListener(const uno::Reference< document::XEventListener >& xListener)
574 throw(uno::RuntimeException)
576 // container is threadsafe
577 m_aLegacyListeners.addInterface(xListener);
580 //-----------------------------------------------------------------------------
581 void SAL_CALL SfxGlobalEvents_Impl::removeEventListener(const uno::Reference< document::XEventListener >& xListener)
582 throw(uno::RuntimeException)
584 // container is threadsafe
585 m_aLegacyListeners.removeInterface(xListener);
588 //-----------------------------------------------------------------------------
589 void SAL_CALL SfxGlobalEvents_Impl::addDocumentEventListener( const uno::Reference< document::XDocumentEventListener >& _Listener )
590 throw(uno::RuntimeException)
592 m_aDocumentListeners.addInterface( _Listener );
595 //-----------------------------------------------------------------------------
596 void SAL_CALL SfxGlobalEvents_Impl::removeDocumentEventListener( const uno::Reference< document::XDocumentEventListener >& _Listener )
597 throw(uno::RuntimeException)
599 m_aDocumentListeners.removeInterface( _Listener );
602 //-----------------------------------------------------------------------------
603 void SAL_CALL SfxGlobalEvents_Impl::notifyDocumentEvent( const OUString& /*_EventName*/,
604 const uno::Reference< frame::XController2 >& /*_ViewController*/, const uno::Any& /*_Supplement*/ )
605 throw (lang::IllegalArgumentException, lang::NoSupportException, uno::RuntimeException)
607 // we're a multiplexer only, no chance to generate artifical events here
608 throw lang::NoSupportException(OUString(), *this);
611 //-----------------------------------------------------------------------------
612 void SAL_CALL SfxGlobalEvents_Impl::notifyEvent(const document::EventObject& aEvent)
613 throw(uno::RuntimeException)
615 document::DocumentEvent aDocEvent(aEvent.Source, aEvent.EventName, NULL, uno::Any());
616 implts_notifyJobExecution(aEvent);
617 implts_checkAndExecuteEventBindings(aDocEvent);
618 implts_notifyListener(aDocEvent);
621 //-----------------------------------------------------------------------------
622 void SAL_CALL SfxGlobalEvents_Impl::documentEventOccured( const document::DocumentEvent& _Event )
623 throw (uno::RuntimeException)
625 implts_notifyJobExecution(document::EventObject(_Event.Source, _Event.EventName));
626 implts_checkAndExecuteEventBindings(_Event);
627 implts_notifyListener(_Event);
630 //-----------------------------------------------------------------------------
631 void SAL_CALL SfxGlobalEvents_Impl::disposing(const lang::EventObject& aEvent)
632 throw(uno::RuntimeException)
634 uno::Reference< frame::XModel > xDoc(aEvent.Source, uno::UNO_QUERY);
636 // SAFE ->
637 ::osl::ResettableMutexGuard aLock(m_aLock);
638 TModelList::iterator pIt = impl_searchDoc(xDoc);
639 if (pIt != m_lModels.end())
640 m_lModels.erase(pIt);
641 aLock.clear();
642 // <- SAFE
645 //-----------------------------------------------------------------------------
646 sal_Bool SAL_CALL SfxGlobalEvents_Impl::has(const uno::Any& aElement)
647 throw (uno::RuntimeException)
649 uno::Reference< frame::XModel > xDoc;
650 aElement >>= xDoc;
652 sal_Bool bHas = sal_False;
654 // SAFE ->
655 ::osl::ResettableMutexGuard aLock(m_aLock);
656 TModelList::iterator pIt = impl_searchDoc(xDoc);
657 if (pIt != m_lModels.end())
658 bHas = sal_True;
659 aLock.clear();
660 // <- SAFE
662 return bHas;
665 //-----------------------------------------------------------------------------
666 void SAL_CALL SfxGlobalEvents_Impl::insert( const uno::Any& aElement )
667 throw (lang::IllegalArgumentException ,
668 container::ElementExistException,
669 uno::RuntimeException )
671 uno::Reference< frame::XModel > xDoc;
672 aElement >>= xDoc;
673 if (!xDoc.is())
674 throw lang::IllegalArgumentException(
675 OUString("Cant locate at least the model parameter."),
676 static_cast< container::XSet* >(this),
679 // SAFE ->
680 ::osl::ResettableMutexGuard aLock(m_aLock);
681 TModelList::iterator pIt = impl_searchDoc(xDoc);
682 if (pIt != m_lModels.end())
683 throw container::ElementExistException(
684 OUString(),
685 static_cast< container::XSet* >(this));
686 m_lModels.push_back(xDoc);
687 aLock.clear();
688 // <- SAFE
690 uno::Reference< document::XDocumentEventBroadcaster > xDocBroadcaster(xDoc, uno::UNO_QUERY );
691 if (xDocBroadcaster.is())
692 xDocBroadcaster->addDocumentEventListener(this);
693 else
695 // try the "legacy version" of XDocumentEventBroadcaster, which is XEventBroadcaster
696 uno::Reference< document::XEventBroadcaster > xBroadcaster(xDoc, uno::UNO_QUERY);
697 if (xBroadcaster.is())
698 xBroadcaster->addEventListener(static_cast< document::XEventListener* >(this));
702 //-----------------------------------------------------------------------------
703 void SAL_CALL SfxGlobalEvents_Impl::remove( const uno::Any& aElement )
704 throw (lang::IllegalArgumentException ,
705 container::NoSuchElementException,
706 uno::RuntimeException )
708 uno::Reference< frame::XModel > xDoc;
709 aElement >>= xDoc;
710 if (!xDoc.is())
711 throw lang::IllegalArgumentException(
712 OUString("Cant locate at least the model parameter."),
713 static_cast< container::XSet* >(this),
716 // SAFE ->
717 ::osl::ResettableMutexGuard aLock(m_aLock);
718 TModelList::iterator pIt = impl_searchDoc(xDoc);
719 if (pIt == m_lModels.end())
720 throw container::NoSuchElementException(
721 OUString(),
722 static_cast< container::XSet* >(this));
723 m_lModels.erase(pIt);
724 aLock.clear();
725 // <- SAFE
727 uno::Reference< document::XDocumentEventBroadcaster > xDocBroadcaster(xDoc, uno::UNO_QUERY );
728 if (xDocBroadcaster.is())
729 xDocBroadcaster->removeDocumentEventListener(this);
730 else
732 // try the "legacy version" of XDocumentEventBroadcaster, which is XEventBroadcaster
733 uno::Reference< document::XEventBroadcaster > xBroadcaster(xDoc, uno::UNO_QUERY);
734 if (xBroadcaster.is())
735 xBroadcaster->removeEventListener(static_cast< document::XEventListener* >(this));
739 //-----------------------------------------------------------------------------
740 uno::Reference< container::XEnumeration > SAL_CALL SfxGlobalEvents_Impl::createEnumeration()
741 throw (uno::RuntimeException)
743 // SAFE ->
744 ::osl::ResettableMutexGuard aLock(m_aLock);
745 ModelCollectionEnumeration* pEnum = new ModelCollectionEnumeration();
746 pEnum->setModelList(m_lModels);
747 uno::Reference< container::XEnumeration > xEnum(
748 static_cast< container::XEnumeration* >(pEnum),
749 uno::UNO_QUERY);
750 aLock.clear();
751 // <- SAFE
753 return xEnum;
756 //-----------------------------------------------------------------------------
757 uno::Type SAL_CALL SfxGlobalEvents_Impl::getElementType()
758 throw (uno::RuntimeException)
760 return ::getCppuType(static_cast< uno::Reference< frame::XModel >* >(NULL));
763 //-----------------------------------------------------------------------------
764 sal_Bool SAL_CALL SfxGlobalEvents_Impl::hasElements()
765 throw (uno::RuntimeException)
767 // SAFE ->
768 ::osl::ResettableMutexGuard aLock(m_aLock);
769 return (m_lModels.size()>0);
770 // <- SAFE
773 //-----------------------------------------------------------------------------
774 void SfxGlobalEvents_Impl::implts_notifyJobExecution(const document::EventObject& aEvent)
778 m_xJobExecutorListener->notifyEvent(aEvent);
780 catch(const uno::RuntimeException&)
781 { throw; }
782 catch(const uno::Exception&)
786 //-----------------------------------------------------------------------------
787 void SfxGlobalEvents_Impl::implts_checkAndExecuteEventBindings(const document::DocumentEvent& aEvent)
791 // SAFE ->
792 ::osl::ResettableMutexGuard aLock(m_aLock);
793 uno::Reference< container::XNameReplace > xEvents = m_xEvents;
794 aLock.clear();
795 // <- SAFE
797 uno::Any aAny;
798 if ( xEvents.is() && xEvents->hasByName( aEvent.EventName ) )
799 aAny = xEvents->getByName(aEvent.EventName);
800 Execute(aAny, aEvent, 0);
802 catch ( uno::RuntimeException const & )
804 throw;
806 catch ( uno::Exception const & )
808 DBG_UNHANDLED_EXCEPTION();
812 //-----------------------------------------------------------------------------
813 void SfxGlobalEvents_Impl::implts_notifyListener(const document::DocumentEvent& aEvent)
815 // containers are threadsafe
816 document::EventObject aLegacyEvent(aEvent.Source, aEvent.EventName);
817 m_aLegacyListeners.notifyEach( &document::XEventListener::notifyEvent, aLegacyEvent );
819 m_aDocumentListeners.notifyEach( &document::XDocumentEventListener::documentEventOccured, aEvent );
822 //-----------------------------------------------------------------------------
823 // not threadsafe ... must be locked from outside!
824 TModelList::iterator SfxGlobalEvents_Impl::impl_searchDoc(const uno::Reference< frame::XModel >& xModel)
826 if (!xModel.is())
827 return m_lModels.end();
829 TModelList::iterator pIt;
830 for ( pIt = m_lModels.begin();
831 pIt != m_lModels.end() ;
832 ++pIt )
834 uno::Reference< frame::XModel > xContainerDoc(*pIt, uno::UNO_QUERY);
835 if (xContainerDoc == xModel)
836 break;
839 return pIt;
842 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */