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

Generated by: LCOV version 1.10