LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/sfx2/source/notify - eventsupplier.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 246 384 64.1 %
Date: 2013-07-09 Functions: 38 52 73.1 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       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/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      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 .
      18             :  */
      19             : 
      20             : #include <com/sun/star/beans/PropertyValue.hpp>
      21             : 
      22             : #include <com/sun/star/util/URL.hpp>
      23             : 
      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>
      36             : 
      37             : #include <unotools/securityoptions.hxx>
      38             : #include <comphelper/processfactory.hxx>
      39             : #include <comphelper/namedvaluecollection.hxx>
      40             : #include "eventsupplier.hxx"
      41             : 
      42             : #include <sfx2/app.hxx>
      43             : #include "sfx2/sfxresid.hxx"
      44             : 
      45             : #include <sfx2/sfxsids.hrc>
      46             : #include "sfxlocal.hrc"
      47             : #include <sfx2/docfile.hxx>
      48             : #include <sfx2/viewfrm.hxx>
      49             : #include <sfx2/frame.hxx>
      50             : 
      51             : //--------------------------------------------------------------------------------------------------------
      52             : 
      53             : #define MACRO_PRFIX         "macro://"
      54             : #define MACRO_POSTFIX       "()"
      55             : 
      56             : using namespace css;
      57             : 
      58             : //--------------------------------------------------------------------------------------------------------
      59             :     //  --- XNameReplace ---
      60             : //--------------------------------------------------------------------------------------------------------
      61           1 : void SAL_CALL SfxEvents_Impl::replaceByName( const OUString & aName, const uno::Any & rElement )
      62             :                                 throw( lang::IllegalArgumentException, container::NoSuchElementException,
      63             :                                        lang::WrappedTargetException, uno::RuntimeException )
      64             : {
      65           1 :     ::osl::MutexGuard aGuard( maMutex );
      66             : 
      67             :     // find the event in the list and replace the data
      68           1 :     long nCount = maEventNames.getLength();
      69          21 :     for ( long i=0; i<nCount; i++ )
      70             :     {
      71          21 :         if ( maEventNames[i] == aName )
      72             :         {
      73             :             // check for correct type of the element
      74           1 :             if ( !::comphelper::NamedValueCollection::canExtractFrom( rElement ) )
      75           0 :                 throw lang::IllegalArgumentException();
      76           1 :             ::comphelper::NamedValueCollection const aEventDescriptor( rElement );
      77             : 
      78             :             // create Configuration at first, creation might call this method also and that would overwrite everything
      79             :             // we might have stored before!
      80           1 :             if ( mpObjShell && !mpObjShell->IsLoading() )
      81           1 :                 mpObjShell->SetModified( sal_True );
      82             : 
      83           2 :             ::comphelper::NamedValueCollection aNormalizedDescriptor;
      84           1 :             NormalizeMacro( aEventDescriptor, aNormalizedDescriptor, mpObjShell );
      85             : 
      86           2 :             OUString sType;
      87           2 :             if  (   ( aNormalizedDescriptor.size() == 1 )
      88           0 :                 &&  ( aNormalizedDescriptor.has( PROP_EVENT_TYPE) == 0 )
      89           0 :                 &&  ( aNormalizedDescriptor.get( PROP_EVENT_TYPE ) >>= sType )
      90           1 :                 &&  ( sType.isEmpty() )
      91             :                 )
      92             :             {
      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           0 :                 aNormalizedDescriptor.clear();
      99             :             }
     100             : 
     101           1 :             if ( !aNormalizedDescriptor.empty() )
     102             :             {
     103           1 :                 maEventData[i] <<= aNormalizedDescriptor.getPropertyValues();
     104             :             }
     105             :             else
     106             :             {
     107           0 :                 maEventData[i].clear();
     108             :             }
     109           3 :             return;
     110             :         }
     111             :     }
     112             : 
     113           1 :     throw container::NoSuchElementException();
     114             : }
     115             : 
     116             : //--------------------------------------------------------------------------------------------------------
     117             : //  --- XNameAccess ---
     118             : //--------------------------------------------------------------------------------------------------------
     119         944 : uno::Any SAL_CALL SfxEvents_Impl::getByName( const OUString& aName )
     120             :                                 throw( container::NoSuchElementException, lang::WrappedTargetException,
     121             :                                        uno::RuntimeException )
     122             : {
     123         944 :     ::osl::MutexGuard aGuard( maMutex );
     124             : 
     125             :     // find the event in the list and return the data
     126             : 
     127         944 :     long nCount = maEventNames.getLength();
     128             : 
     129       15304 :     for ( long i=0; i<nCount; i++ )
     130             :     {
     131       15304 :         if ( maEventNames[i] == aName )
     132        1888 :             return maEventData[i];
     133             :     }
     134             : 
     135         944 :     throw container::NoSuchElementException();
     136             : }
     137             : 
     138             : //--------------------------------------------------------------------------------------------------------
     139          32 : uno::Sequence< OUString > SAL_CALL SfxEvents_Impl::getElementNames() throw ( uno::RuntimeException )
     140             : {
     141          32 :     return maEventNames;
     142             : }
     143             : 
     144             : //--------------------------------------------------------------------------------------------------------
     145           0 : sal_Bool SAL_CALL SfxEvents_Impl::hasByName( const OUString& aName ) throw ( uno::RuntimeException )
     146             : {
     147           0 :     ::osl::MutexGuard aGuard( maMutex );
     148             : 
     149             :     // find the event in the list and return the data
     150             : 
     151           0 :     long nCount = maEventNames.getLength();
     152             : 
     153           0 :     for ( long i=0; i<nCount; i++ )
     154             :     {
     155           0 :         if ( maEventNames[i] == aName )
     156           0 :             return sal_True;
     157             :     }
     158             : 
     159           0 :     return sal_False;
     160             : }
     161             : 
     162             : //--------------------------------------------------------------------------------------------------------
     163             : //  --- XElementAccess ( parent of XNameAccess ) ---
     164             : //--------------------------------------------------------------------------------------------------------
     165           0 : uno::Type SAL_CALL SfxEvents_Impl::getElementType() throw ( uno::RuntimeException )
     166             : {
     167           0 :     uno::Type aElementType = ::getCppuType( (const uno::Sequence < beans::PropertyValue > *)0 );
     168           0 :     return aElementType;
     169             : }
     170             : 
     171             : //--------------------------------------------------------------------------------------------------------
     172           0 : sal_Bool SAL_CALL SfxEvents_Impl::hasElements() throw ( uno::RuntimeException )
     173             : {
     174           0 :     ::osl::MutexGuard aGuard( maMutex );
     175             : 
     176           0 :     if ( maEventNames.getLength() )
     177           0 :         return sal_True;
     178             :     else
     179           0 :         return sal_False;
     180             : }
     181             : 
     182       17540 : static void Execute( uno::Any& aEventData, const document::DocumentEvent& aTrigger, SfxObjectShell* pDoc )
     183             : {
     184       17540 :     uno::Sequence < beans::PropertyValue > aProperties;
     185       17540 :     if ( aEventData >>= aProperties )
     186             :     {
     187       16580 :         OUString aType;
     188       33160 :         OUString aScript;
     189       33160 :         OUString aLibrary;
     190       33160 :         OUString aMacroName;
     191             : 
     192       16580 :         sal_Int32 nCount = aProperties.getLength();
     193             : 
     194       16580 :         if ( !nCount )
     195       17540 :             return;
     196             : 
     197       16580 :         sal_Int32 nIndex = 0;
     198       66320 :         while ( nIndex < nCount )
     199             :         {
     200       33160 :             if ( aProperties[ nIndex ].Name == PROP_EVENT_TYPE )
     201       16580 :                 aProperties[ nIndex ].Value >>= aType;
     202       16580 :             else if ( aProperties[ nIndex ].Name == PROP_SCRIPT )
     203       16580 :                 aProperties[ nIndex ].Value >>= aScript;
     204           0 :             else if ( aProperties[ nIndex ].Name == PROP_LIBRARY )
     205           0 :                 aProperties[ nIndex ].Value >>= aLibrary;
     206           0 :             else if ( aProperties[ nIndex ].Name == PROP_MACRO_NAME )
     207           0 :                 aProperties[ nIndex ].Value >>= aMacroName;
     208             :             else {
     209             :                 OSL_FAIL("Unknown property value!");
     210             :             }
     211       33160 :             nIndex += 1;
     212             :         }
     213             : 
     214       16580 :         if (aType.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(STAR_BASIC)) && !aScript.isEmpty())
     215             :         {
     216           0 :             uno::Any aAny;
     217           0 :             SfxMacroLoader::loadMacro( aScript, aAny, pDoc );
     218             :         }
     219       33160 :         else if (aType.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("Service")) ||
     220       16580 :                   aType.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("Script")))
     221             :         {
     222       16580 :             if ( !aScript.isEmpty() )
     223             :             {
     224             :                 SfxViewFrame* pView = pDoc ?
     225             :                     SfxViewFrame::GetFirst( pDoc ) :
     226           1 :                     SfxViewFrame::Current();
     227             : 
     228           1 :                 uno::Reference < util::XURLTransformer > xTrans( util::URLTransformer::create( ::comphelper::getProcessComponentContext() ) );
     229             : 
     230           2 :                 util::URL aURL;
     231           1 :                 aURL.Complete = aScript;
     232           1 :                 xTrans->parseStrict( aURL );
     233             : 
     234             :                 uno::Reference
     235           2 :                     < frame::XDispatchProvider > xProv;
     236             : 
     237           1 :                 if ( pView != NULL )
     238             :                 {
     239           2 :                     xProv = uno::Reference
     240             :                         < frame::XDispatchProvider > (
     241           2 :                             pView->GetFrame().GetFrameInterface(), uno::UNO_QUERY );
     242             :                 }
     243             :                 else
     244             :                 {
     245           0 :                     xProv = uno::Reference< frame::XDispatchProvider > (
     246             :                                 frame::Desktop::create( ::comphelper::getProcessComponentContext() ),
     247           0 :                                 uno::UNO_QUERY );
     248             :                 }
     249             : 
     250           2 :                 uno::Reference < frame::XDispatch > xDisp;
     251           1 :                 if ( xProv.is() )
     252           1 :                     xDisp = xProv->queryDispatch( aURL, OUString(), 0 );
     253             : 
     254           1 :                 if ( xDisp.is() )
     255             :                 {
     256             : 
     257           1 :                     beans::PropertyValue aEventParam;
     258           1 :                     aEventParam.Value <<= aTrigger;
     259           2 :                     uno::Sequence< beans::PropertyValue > aDispatchArgs( &aEventParam, 1 );
     260           2 :                     xDisp->dispatch( aURL, aDispatchArgs );
     261           1 :                 }
     262             :             }
     263             :         }
     264           0 :         else if ( aType.isEmpty() )
     265             :         {
     266             :             // Empty type means no active binding for the event. Just ignore do nothing.
     267             :         }
     268             :         else
     269             :         {
     270             :             SAL_WARN( "sfx2.notify", "notifyEvent(): Unsupported event type" );
     271       16580 :         }
     272       17540 :     }
     273             : }
     274             : 
     275             : //--------------------------------------------------------------------------------------------------------
     276             : // --- ::document::XEventListener ---
     277             : //--------------------------------------------------------------------------------------------------------
     278         165 : void SAL_CALL SfxEvents_Impl::notifyEvent( const document::EventObject& aEvent ) throw( uno::RuntimeException )
     279             : {
     280         165 :     ::osl::ClearableMutexGuard aGuard( maMutex );
     281             : 
     282             :     // get the event name, find the coresponding data, execute the data
     283             : 
     284         330 :     OUString aName   = aEvent.EventName;
     285         165 :     long        nCount  = maEventNames.getLength();
     286         165 :     long        nIndex  = 0;
     287         165 :     sal_Bool    bFound  = sal_False;
     288             : 
     289        3671 :     while ( !bFound && ( nIndex < nCount ) )
     290             :     {
     291        3341 :         if ( maEventNames[nIndex] == aName )
     292         165 :             bFound = sal_True;
     293             :         else
     294        3176 :             nIndex += 1;
     295             :     }
     296             : 
     297         165 :     if ( !bFound )
     298         165 :         return;
     299             : 
     300         330 :     uno::Any aEventData = maEventData[ nIndex ];
     301         165 :     aGuard.clear();
     302         330 :     Execute( aEventData, document::DocumentEvent(aEvent.Source, aEvent.EventName, NULL, uno::Any()), mpObjShell );
     303             : }
     304             : 
     305             : //--------------------------------------------------------------------------------------------------------
     306             : // --- ::lang::XEventListener ---
     307             : //--------------------------------------------------------------------------------------------------------
     308          30 : void SAL_CALL SfxEvents_Impl::disposing( const lang::EventObject& /*Source*/ ) throw( uno::RuntimeException )
     309             : {
     310          30 :     ::osl::MutexGuard aGuard( maMutex );
     311             : 
     312          30 :     if ( mxBroadcaster.is() )
     313             :     {
     314          30 :         mxBroadcaster->removeEventListener( this );
     315          30 :         mxBroadcaster = NULL;
     316          30 :     }
     317          30 : }
     318             : 
     319             : //--------------------------------------------------------------------------------------------------------
     320             : //--------------------------------------------------------------------------------------------------------
     321          30 : SfxEvents_Impl::SfxEvents_Impl( SfxObjectShell* pShell,
     322          30 :                                 uno::Reference< document::XEventBroadcaster > xBroadcaster )
     323             : {
     324             :     // get the list of supported events and store it
     325          30 :     if ( pShell )
     326          30 :         maEventNames = pShell->GetEventNames();
     327             :     else
     328           0 :         maEventNames = GlobalEventConfig().getElementNames();
     329             : 
     330          30 :     maEventData = uno::Sequence < uno::Any > ( maEventNames.getLength() );
     331             : 
     332          30 :     mpObjShell      = pShell;
     333          30 :     mxBroadcaster   = xBroadcaster;
     334             : 
     335          30 :     if ( mxBroadcaster.is() )
     336          30 :         mxBroadcaster->addEventListener( this );
     337          30 : }
     338             : 
     339             : //--------------------------------------------------------------------------------------------------------
     340          60 : SfxEvents_Impl::~SfxEvents_Impl()
     341             : {
     342          60 : }
     343             : 
     344             : //--------------------------------------------------------------------------------------------------------
     345           8 : SvxMacro* SfxEvents_Impl::ConvertToMacro( const uno::Any& rElement, SfxObjectShell* pObjShell, sal_Bool bNormalizeMacro )
     346             : {
     347           8 :     SvxMacro* pMacro = NULL;
     348           8 :     uno::Sequence < beans::PropertyValue > aProperties;
     349          16 :     uno::Any aAny;
     350           8 :     if ( bNormalizeMacro )
     351           8 :         NormalizeMacro( rElement, aAny, pObjShell );
     352             :     else
     353           0 :         aAny = rElement;
     354             : 
     355           8 :     if ( aAny >>= aProperties )
     356             :     {
     357           8 :         OUString aType;
     358           8 :         OUString aScriptURL;
     359           8 :         OUString aLibrary;
     360           8 :         OUString aMacroName;
     361             : 
     362           8 :         long nCount = aProperties.getLength();
     363           8 :         long nIndex = 0;
     364             : 
     365           8 :         if ( !nCount )
     366           8 :             return pMacro;
     367             : 
     368           0 :         while ( nIndex < nCount )
     369             :         {
     370           0 :             if ( aProperties[ nIndex ].Name == PROP_EVENT_TYPE )
     371           0 :                 aProperties[ nIndex ].Value >>= aType;
     372           0 :             else if ( aProperties[ nIndex ].Name == PROP_SCRIPT )
     373           0 :                 aProperties[ nIndex ].Value >>= aScriptURL;
     374           0 :             else if ( aProperties[ nIndex ].Name == PROP_LIBRARY )
     375           0 :                 aProperties[ nIndex ].Value >>= aLibrary;
     376           0 :             else if ( aProperties[ nIndex ].Name == PROP_MACRO_NAME )
     377           0 :                 aProperties[ nIndex ].Value >>= aMacroName;
     378             :             else {
     379             :                 OSL_FAIL("Unknown propery value!");
     380             :             }
     381           0 :             nIndex += 1;
     382             :         }
     383             : 
     384             :         // Get the type
     385           0 :         ScriptType  eType( STARBASIC );
     386           0 :         if ( aType == STAR_BASIC )
     387           0 :             eType = STARBASIC;
     388           0 :         else if (aType.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("Script")) && !aScriptURL.isEmpty())
     389           0 :             eType = EXTENDED_STYPE;
     390           0 :         else if ( aType == SVX_MACRO_LANGUAGE_JAVASCRIPT )
     391           0 :             eType = JAVASCRIPT;
     392             :         else {
     393             :             SAL_WARN( "sfx2.notify", "ConvertToMacro: Unknown macro type" );
     394             :         }
     395             : 
     396           0 :         if ( !aMacroName.isEmpty() )
     397             :         {
     398           0 :             if ( aLibrary == "application" )
     399           0 :                 aLibrary = SFX_APP()->GetName();
     400             :             else
     401           0 :                 aLibrary = OUString();
     402           0 :             pMacro = new SvxMacro( aMacroName, aLibrary, eType );
     403             :         }
     404           0 :         else if ( eType == EXTENDED_STYPE )
     405           0 :             pMacro = new SvxMacro( aScriptURL, aType );
     406             :     }
     407             : 
     408           8 :     return pMacro;
     409             : }
     410             : 
     411           8 : void SfxEvents_Impl::NormalizeMacro( const uno::Any& rEvent, uno::Any& rRet, SfxObjectShell* pDoc )
     412             : {
     413           8 :     const ::comphelper::NamedValueCollection aEventDescriptor( rEvent );
     414          16 :     ::comphelper::NamedValueCollection aEventDescriptorOut;
     415             : 
     416           8 :     NormalizeMacro( aEventDescriptor, aEventDescriptorOut, pDoc );
     417             : 
     418          16 :     rRet <<= aEventDescriptorOut.getPropertyValues();
     419           8 : }
     420             : 
     421           9 : void SfxEvents_Impl::NormalizeMacro( const ::comphelper::NamedValueCollection& i_eventDescriptor,
     422             :         ::comphelper::NamedValueCollection& o_normalizedDescriptor, SfxObjectShell* i_document )
     423             : {
     424           9 :     SfxObjectShell* pDoc = i_document;
     425           9 :     if ( !pDoc )
     426           0 :         pDoc = SfxObjectShell::Current();
     427             : 
     428           9 :     OUString aType = i_eventDescriptor.getOrDefault( PROP_EVENT_TYPE, OUString() );
     429          18 :     OUString aScript = i_eventDescriptor.getOrDefault( PROP_SCRIPT, OUString() );
     430          18 :     OUString aLibrary = i_eventDescriptor.getOrDefault( PROP_LIBRARY, OUString() );
     431          18 :     OUString aMacroName = i_eventDescriptor.getOrDefault( PROP_MACRO_NAME, OUString() );
     432             : 
     433           9 :     if ( !aType.isEmpty() )
     434           1 :         o_normalizedDescriptor.put( PROP_EVENT_TYPE, aType );
     435           9 :     if ( !aScript.isEmpty() )
     436           1 :         o_normalizedDescriptor.put( PROP_SCRIPT, aScript );
     437             : 
     438           9 :     if ( aType == STAR_BASIC )
     439             :     {
     440           0 :         if ( !aScript.isEmpty() )
     441             :         {
     442           0 :             if ( aMacroName.isEmpty() || aLibrary.isEmpty() )
     443             :             {
     444           0 :                 sal_Int32 nHashPos = aScript.indexOf( '/', 8 );
     445           0 :                 sal_Int32 nArgsPos = aScript.indexOf( '(' );
     446           0 :                 if ( ( nHashPos != STRING_NOTFOUND ) && ( nHashPos < nArgsPos ) )
     447             :                 {
     448           0 :                     OUString aBasMgrName( INetURLObject::decode( aScript.copy( 8, nHashPos-8 ), INET_HEX_ESCAPE, INetURLObject::DECODE_WITH_CHARSET ) );
     449           0 :                     if ( aBasMgrName == "." )
     450           0 :                         aLibrary = pDoc->GetTitle();
     451             :                     else
     452           0 :                         aLibrary = SFX_APP()->GetName();
     453             : 
     454             :                     // Get the macro name
     455           0 :                     aMacroName = aScript.copy( nHashPos+1, nArgsPos - nHashPos - 1 );
     456             :                 }
     457             :                 else
     458             :                 {
     459             :                     SAL_WARN( "sfx2.notify", "ConvertToMacro: Unknown macro url format" );
     460             :                 }
     461             :             }
     462             :         }
     463           0 :         else if ( !aMacroName.isEmpty() )
     464             :         {
     465           0 :             aScript = OUString( MACRO_PRFIX  );
     466           0 :             if ( aLibrary.compareTo( SFX_APP()->GetName() ) != 0 && !aLibrary.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("StarDesktop")) && !aLibrary.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("application")) )
     467           0 :                 aScript += OUString('.');
     468             : 
     469           0 :             aScript += OUString('/');
     470           0 :             aScript += aMacroName;
     471           0 :             aScript += OUString( MACRO_POSTFIX  );
     472             :         }
     473             :         else
     474             :             // wrong properties
     475           9 :             return;
     476             : 
     477           0 :         if (!aLibrary.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("document")))
     478             :         {
     479           0 :             if ( aLibrary.isEmpty() || (pDoc && ( String(aLibrary) == pDoc->GetTitle( SFX_TITLE_APINAME ) || String(aLibrary) == pDoc->GetTitle() )) )
     480           0 :                 aLibrary = OUString("document");
     481             :             else
     482           0 :                 aLibrary = OUString("application");
     483             :         }
     484             : 
     485           0 :         o_normalizedDescriptor.put( PROP_SCRIPT, aScript );
     486           0 :         o_normalizedDescriptor.put( PROP_LIBRARY, aLibrary );
     487           0 :         o_normalizedDescriptor.put( PROP_MACRO_NAME, aMacroName );
     488           9 :     }
     489             : }
     490             : 
     491          33 : ModelCollectionEnumeration::ModelCollectionEnumeration()
     492             :     : ModelCollectionMutexBase(                 )
     493          33 :     , m_pEnumerationIt        (m_lModels.begin())
     494             : {
     495          33 : }
     496             : 
     497          66 : ModelCollectionEnumeration::~ModelCollectionEnumeration()
     498             : {
     499          66 : }
     500             : 
     501          33 : void ModelCollectionEnumeration::setModelList(const TModelList& rList)
     502             : {
     503             :     // SAFE ->
     504          33 :     ::osl::ResettableMutexGuard aLock(m_aLock);
     505          33 :     m_lModels        = rList;
     506          33 :     m_pEnumerationIt = m_lModels.begin();
     507          33 :     aLock.clear();
     508             :     // <- SAFE
     509          33 : }
     510             : 
     511          44 : sal_Bool SAL_CALL ModelCollectionEnumeration::hasMoreElements()
     512             :     throw(uno::RuntimeException)
     513             : {
     514             :     // SAFE ->
     515          44 :     ::osl::ResettableMutexGuard aLock(m_aLock);
     516          44 :     return (m_pEnumerationIt != m_lModels.end());
     517             :     // <- SAFE
     518             : }
     519             : 
     520          11 : uno::Any SAL_CALL ModelCollectionEnumeration::nextElement()
     521             :     throw(container::NoSuchElementException,
     522             :           lang::WrappedTargetException     ,
     523             :           uno::RuntimeException            )
     524             : {
     525             :     // SAFE ->
     526          11 :     ::osl::ResettableMutexGuard aLock(m_aLock);
     527          11 :     if (m_pEnumerationIt == m_lModels.end())
     528             :         throw container::NoSuchElementException(
     529             :                     OUString("End of model enumeration reached."),
     530           0 :                     static_cast< container::XEnumeration* >(this));
     531          22 :     uno::Reference< frame::XModel > xModel(*m_pEnumerationIt, uno::UNO_QUERY);
     532          11 :     ++m_pEnumerationIt;
     533          11 :     aLock.clear();
     534             :     // <- SAFE
     535             : 
     536          22 :     return uno::makeAny(xModel);
     537             : }
     538             : 
     539         647 : SFX_IMPL_XSERVICEINFO_CTX( SfxGlobalEvents_Impl, "com.sun.star.frame.GlobalEventBroadcaster", "com.sun.star.comp.sfx2.GlobalEventBroadcaster" )
     540         121 : SFX_IMPL_ONEINSTANCEFACTORY( SfxGlobalEvents_Impl );
     541             : 
     542             : //-----------------------------------------------------------------------------
     543         121 : 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         121 :     , pImp                    (0      )
     549             : {
     550         121 :     m_refCount++;
     551         121 :     SFX_APP();
     552         121 :     pImp                   = new GlobalEventConfig();
     553         121 :     m_xEvents              = pImp;
     554         121 :     m_refCount--;
     555         121 : }
     556             : 
     557             : //-----------------------------------------------------------------------------
     558         168 : SfxGlobalEvents_Impl::~SfxGlobalEvents_Impl()
     559             : {
     560         168 : }
     561             : 
     562             : //-----------------------------------------------------------------------------
     563           0 : uno::Reference< container::XNameReplace > SAL_CALL SfxGlobalEvents_Impl::getEvents()
     564             :     throw(uno::RuntimeException)
     565             : {
     566             :     // SAFE ->
     567           0 :     ::osl::ResettableMutexGuard aLock(m_aLock);
     568           0 :     return m_xEvents;
     569             :     // <- SAFE
     570             : }
     571             : 
     572             : //-----------------------------------------------------------------------------
     573         148 : void SAL_CALL SfxGlobalEvents_Impl::addEventListener(const uno::Reference< document::XEventListener >& xListener)
     574             :     throw(uno::RuntimeException)
     575             : {
     576             :     // container is threadsafe
     577         148 :     m_aLegacyListeners.addInterface(xListener);
     578         148 : }
     579             : 
     580             : //-----------------------------------------------------------------------------
     581         115 : void SAL_CALL SfxGlobalEvents_Impl::removeEventListener(const uno::Reference< document::XEventListener >& xListener)
     582             :     throw(uno::RuntimeException)
     583             : {
     584             :     // container is threadsafe
     585         115 :     m_aLegacyListeners.removeInterface(xListener);
     586         115 : }
     587             : 
     588             : //-----------------------------------------------------------------------------
     589           0 : void SAL_CALL SfxGlobalEvents_Impl::addDocumentEventListener( const uno::Reference< document::XDocumentEventListener >& _Listener )
     590             :     throw(uno::RuntimeException)
     591             : {
     592           0 :     m_aDocumentListeners.addInterface( _Listener );
     593           0 : }
     594             : 
     595             : //-----------------------------------------------------------------------------
     596           0 : void SAL_CALL SfxGlobalEvents_Impl::removeDocumentEventListener( const uno::Reference< document::XDocumentEventListener >& _Listener )
     597             :     throw(uno::RuntimeException)
     598             : {
     599           0 :     m_aDocumentListeners.removeInterface( _Listener );
     600           0 : }
     601             : 
     602             : //-----------------------------------------------------------------------------
     603           0 : 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)
     606             : {
     607             :     // we're a multiplexer only, no chance to generate artifical events here
     608           0 :     throw lang::NoSupportException(OUString(), *this);
     609             : }
     610             : 
     611             : //-----------------------------------------------------------------------------
     612         249 : void SAL_CALL SfxGlobalEvents_Impl::notifyEvent(const document::EventObject& aEvent)
     613             :     throw(uno::RuntimeException)
     614             : {
     615         249 :     document::DocumentEvent aDocEvent(aEvent.Source, aEvent.EventName, NULL, uno::Any());
     616         249 :     implts_notifyJobExecution(aEvent);
     617         249 :     implts_checkAndExecuteEventBindings(aDocEvent);
     618         249 :     implts_notifyListener(aDocEvent);
     619         249 : }
     620             : 
     621             : //-----------------------------------------------------------------------------
     622       17126 : void SAL_CALL SfxGlobalEvents_Impl::documentEventOccured( const document::DocumentEvent& _Event )
     623             :     throw (uno::RuntimeException)
     624             : {
     625       17126 :     implts_notifyJobExecution(document::EventObject(_Event.Source, _Event.EventName));
     626       17126 :     implts_checkAndExecuteEventBindings(_Event);
     627       17126 :     implts_notifyListener(_Event);
     628       17126 : }
     629             : 
     630             : //-----------------------------------------------------------------------------
     631        1526 : void SAL_CALL SfxGlobalEvents_Impl::disposing(const lang::EventObject& aEvent)
     632             :     throw(uno::RuntimeException)
     633             : {
     634        1526 :     uno::Reference< frame::XModel > xDoc(aEvent.Source, uno::UNO_QUERY);
     635             : 
     636             :     // SAFE ->
     637        3052 :     ::osl::ResettableMutexGuard aLock(m_aLock);
     638        1526 :     TModelList::iterator pIt = impl_searchDoc(xDoc);
     639        1526 :     if (pIt != m_lModels.end())
     640        1526 :         m_lModels.erase(pIt);
     641        3052 :     aLock.clear();
     642             :     // <- SAFE
     643        1526 : }
     644             : 
     645             : //-----------------------------------------------------------------------------
     646           0 : sal_Bool SAL_CALL SfxGlobalEvents_Impl::has(const uno::Any& aElement)
     647             :     throw (uno::RuntimeException)
     648             : {
     649           0 :     uno::Reference< frame::XModel > xDoc;
     650           0 :     aElement >>= xDoc;
     651             : 
     652           0 :     sal_Bool bHas = sal_False;
     653             : 
     654             :     // SAFE ->
     655           0 :     ::osl::ResettableMutexGuard aLock(m_aLock);
     656           0 :     TModelList::iterator pIt = impl_searchDoc(xDoc);
     657           0 :     if (pIt != m_lModels.end())
     658           0 :         bHas = sal_True;
     659           0 :     aLock.clear();
     660             :     // <- SAFE
     661             : 
     662           0 :     return bHas;
     663             : }
     664             : 
     665             : //-----------------------------------------------------------------------------
     666        1557 : void SAL_CALL SfxGlobalEvents_Impl::insert( const uno::Any& aElement )
     667             :     throw (lang::IllegalArgumentException  ,
     668             :            container::ElementExistException,
     669             :            uno::RuntimeException           )
     670             : {
     671        1557 :     uno::Reference< frame::XModel > xDoc;
     672        1557 :     aElement >>= xDoc;
     673        1557 :     if (!xDoc.is())
     674             :         throw lang::IllegalArgumentException(
     675             :                 OUString("Cant locate at least the model parameter."),
     676             :                 static_cast< container::XSet* >(this),
     677           0 :                 0);
     678             : 
     679             :     // SAFE ->
     680        3114 :     ::osl::ResettableMutexGuard aLock(m_aLock);
     681        1557 :     TModelList::iterator pIt = impl_searchDoc(xDoc);
     682        1557 :     if (pIt != m_lModels.end())
     683             :         throw container::ElementExistException(
     684             :                 OUString(),
     685           0 :                 static_cast< container::XSet* >(this));
     686        1557 :     m_lModels.push_back(xDoc);
     687        1557 :     aLock.clear();
     688             :     // <- SAFE
     689             : 
     690        3114 :     uno::Reference< document::XDocumentEventBroadcaster > xDocBroadcaster(xDoc, uno::UNO_QUERY );
     691        1557 :     if (xDocBroadcaster.is())
     692        1557 :         xDocBroadcaster->addDocumentEventListener(this);
     693             :     else
     694             :     {
     695             :         // try the "legacy version" of XDocumentEventBroadcaster, which is XEventBroadcaster
     696           0 :         uno::Reference< document::XEventBroadcaster > xBroadcaster(xDoc, uno::UNO_QUERY);
     697           0 :         if (xBroadcaster.is())
     698           0 :             xBroadcaster->addEventListener(static_cast< document::XEventListener* >(this));
     699        1557 :     }
     700        1557 : }
     701             : 
     702             : //-----------------------------------------------------------------------------
     703           0 : void SAL_CALL SfxGlobalEvents_Impl::remove( const uno::Any& aElement )
     704             :     throw (lang::IllegalArgumentException   ,
     705             :            container::NoSuchElementException,
     706             :            uno::RuntimeException            )
     707             : {
     708           0 :     uno::Reference< frame::XModel > xDoc;
     709           0 :     aElement >>= xDoc;
     710           0 :     if (!xDoc.is())
     711             :         throw lang::IllegalArgumentException(
     712             :                 OUString("Cant locate at least the model parameter."),
     713             :                 static_cast< container::XSet* >(this),
     714           0 :                 0);
     715             : 
     716             :     // SAFE ->
     717           0 :     ::osl::ResettableMutexGuard aLock(m_aLock);
     718           0 :     TModelList::iterator pIt = impl_searchDoc(xDoc);
     719           0 :     if (pIt == m_lModels.end())
     720             :         throw container::NoSuchElementException(
     721             :                 OUString(),
     722           0 :                 static_cast< container::XSet* >(this));
     723           0 :     m_lModels.erase(pIt);
     724           0 :     aLock.clear();
     725             :     // <- SAFE
     726             : 
     727           0 :     uno::Reference< document::XDocumentEventBroadcaster > xDocBroadcaster(xDoc, uno::UNO_QUERY );
     728           0 :     if (xDocBroadcaster.is())
     729           0 :         xDocBroadcaster->removeDocumentEventListener(this);
     730             :     else
     731             :     {
     732             :         // try the "legacy version" of XDocumentEventBroadcaster, which is XEventBroadcaster
     733           0 :         uno::Reference< document::XEventBroadcaster > xBroadcaster(xDoc, uno::UNO_QUERY);
     734           0 :         if (xBroadcaster.is())
     735           0 :             xBroadcaster->removeEventListener(static_cast< document::XEventListener* >(this));
     736           0 :     }
     737           0 : }
     738             : 
     739             : //-----------------------------------------------------------------------------
     740          33 : uno::Reference< container::XEnumeration > SAL_CALL SfxGlobalEvents_Impl::createEnumeration()
     741             :     throw (uno::RuntimeException)
     742             : {
     743             :     // SAFE ->
     744          33 :     ::osl::ResettableMutexGuard aLock(m_aLock);
     745          33 :     ModelCollectionEnumeration* pEnum = new ModelCollectionEnumeration();
     746          33 :     pEnum->setModelList(m_lModels);
     747             :     uno::Reference< container::XEnumeration > xEnum(
     748          33 :         static_cast< container::XEnumeration* >(pEnum),
     749          33 :         uno::UNO_QUERY);
     750          33 :     aLock.clear();
     751             :     // <- SAFE
     752             : 
     753          33 :     return xEnum;
     754             : }
     755             : 
     756             : //-----------------------------------------------------------------------------
     757           0 : uno::Type SAL_CALL SfxGlobalEvents_Impl::getElementType()
     758             :     throw (uno::RuntimeException)
     759             : {
     760           0 :     return ::getCppuType(static_cast< uno::Reference< frame::XModel >* >(NULL));
     761             : }
     762             : 
     763             : //-----------------------------------------------------------------------------
     764           0 : sal_Bool SAL_CALL SfxGlobalEvents_Impl::hasElements()
     765             :     throw (uno::RuntimeException)
     766             : {
     767             :     // SAFE ->
     768           0 :     ::osl::ResettableMutexGuard aLock(m_aLock);
     769           0 :     return (m_lModels.size()>0);
     770             :     // <- SAFE
     771             : }
     772             : 
     773             : //-----------------------------------------------------------------------------
     774       17374 : void SfxGlobalEvents_Impl::implts_notifyJobExecution(const document::EventObject& aEvent)
     775             : {
     776             :     try
     777             :     {
     778       17374 :         m_xJobExecutorListener->notifyEvent(aEvent);
     779             :     }
     780           0 :     catch(const uno::RuntimeException&)
     781           0 :         { throw; }
     782           0 :     catch(const uno::Exception&)
     783             :         {}
     784       17375 : }
     785             : 
     786             : //-----------------------------------------------------------------------------
     787       17375 : void SfxGlobalEvents_Impl::implts_checkAndExecuteEventBindings(const document::DocumentEvent& aEvent)
     788             : {
     789             :     try
     790             :     {
     791             :         // SAFE ->
     792       17375 :         ::osl::ResettableMutexGuard aLock(m_aLock);
     793       34750 :         uno::Reference< container::XNameReplace > xEvents = m_xEvents;
     794       17375 :         aLock.clear();
     795             :         // <- SAFE
     796             : 
     797       34750 :         uno::Any aAny;
     798       17375 :         if ( xEvents.is() && xEvents->hasByName( aEvent.EventName ) )
     799       16579 :             aAny = xEvents->getByName(aEvent.EventName);
     800       34750 :         Execute(aAny, aEvent, 0);
     801             :     }
     802           0 :     catch ( uno::RuntimeException const & )
     803             :     {
     804           0 :         throw;
     805             :     }
     806           0 :     catch ( uno::Exception const & )
     807             :     {
     808             :        DBG_UNHANDLED_EXCEPTION();
     809             :     }
     810       17375 : }
     811             : 
     812             : //-----------------------------------------------------------------------------
     813       17375 : void SfxGlobalEvents_Impl::implts_notifyListener(const document::DocumentEvent& aEvent)
     814             : {
     815             :     // containers are threadsafe
     816       17375 :     document::EventObject aLegacyEvent(aEvent.Source, aEvent.EventName);
     817       17375 :     m_aLegacyListeners.notifyEach( &document::XEventListener::notifyEvent, aLegacyEvent );
     818             : 
     819       17375 :     m_aDocumentListeners.notifyEach( &document::XDocumentEventListener::documentEventOccured, aEvent );
     820       17375 : }
     821             : 
     822             : //-----------------------------------------------------------------------------
     823             : // not threadsafe ... must be locked from outside!
     824        3083 : TModelList::iterator SfxGlobalEvents_Impl::impl_searchDoc(const uno::Reference< frame::XModel >& xModel)
     825             : {
     826        3083 :     if (!xModel.is())
     827           0 :         return m_lModels.end();
     828             : 
     829        3083 :     TModelList::iterator pIt;
     830       14898 :     for (  pIt  = m_lModels.begin();
     831        9932 :            pIt != m_lModels.end()  ;
     832             :          ++pIt                     )
     833             :     {
     834        3409 :         uno::Reference< frame::XModel > xContainerDoc(*pIt, uno::UNO_QUERY);
     835        3409 :         if (xContainerDoc == xModel)
     836        1526 :             break;
     837        1883 :     }
     838             : 
     839        3083 :     return pIt;
     840         408 : }
     841             : 
     842             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10