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

Generated by: LCOV version 1.10