Branch data 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/util/URLTransformer.hpp>
25 : : #include <com/sun/star/util/XURLTransformer.hpp>
26 : : #include <tools/urlobj.hxx>
27 : : #include <tools/diagnose_ex.h>
28 : : #include <svl/macitem.hxx>
29 : : #include <sfx2/appuno.hxx>
30 : : #include <sfx2/objsh.hxx>
31 : : #include <sfx2/sfxbasemodel.hxx>
32 : : #include <sfx2/evntconf.hxx>
33 : : #include <unotools/eventcfg.hxx>
34 : :
35 : : #include <unotools/securityoptions.hxx>
36 : : #include <comphelper/processfactory.hxx>
37 : : #include <comphelper/namedvaluecollection.hxx>
38 : : #include "eventsupplier.hxx"
39 : :
40 : : #include <sfx2/app.hxx>
41 : : #include "sfx2/sfxresid.hxx"
42 : :
43 : : #include <sfx2/sfxsids.hrc>
44 : : #include "sfxlocal.hrc"
45 : : #include <sfx2/docfile.hxx>
46 : : #include <sfx2/viewfrm.hxx>
47 : : #include <sfx2/frame.hxx>
48 : :
49 : : //--------------------------------------------------------------------------------------------------------
50 : :
51 : : #define MACRO_PRFIX "macro://"
52 : : #define MACRO_POSTFIX "()"
53 : :
54 : : //--------------------------------------------------------------------------------------------------------
55 : :
56 : : #define PROPERTYVALUE ::com::sun::star::beans::PropertyValue
57 : : #define UNO_QUERY ::com::sun::star::uno::UNO_QUERY
58 : :
59 : : namespace css = ::com::sun::star;
60 : : using ::com::sun::star::uno::Sequence;
61 : : using ::com::sun::star::beans::PropertyValue;
62 : :
63 : : //--------------------------------------------------------------------------------------------------------
64 : : // --- XNameReplace ---
65 : : //--------------------------------------------------------------------------------------------------------
66 : 2 : void SAL_CALL SfxEvents_Impl::replaceByName( const rtl::OUString & aName, const ANY & rElement )
67 : : throw( ILLEGALARGUMENTEXCEPTION, NOSUCHELEMENTEXCEPTION,
68 : : WRAPPEDTARGETEXCEPTION, RUNTIMEEXCEPTION )
69 : : {
70 [ + - ]: 2 : ::osl::MutexGuard aGuard( maMutex );
71 : :
72 : : // find the event in the list and replace the data
73 : 2 : long nCount = maEventNames.getLength();
74 [ + - ]: 42 : for ( long i=0; i<nCount; i++ )
75 : : {
76 [ + - ][ + + ]: 42 : if ( maEventNames[i] == aName )
77 : : {
78 : : // check for correct type of the element
79 [ + - ][ - + ]: 2 : if ( !::comphelper::NamedValueCollection::canExtractFrom( rElement ) )
80 [ # # ]: 0 : throw ILLEGALARGUMENTEXCEPTION();
81 [ + - ]: 2 : ::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 [ + - ][ + - ]: 2 : if ( mpObjShell && !mpObjShell->IsLoading() )
[ + - ][ + - ]
86 [ + - ]: 2 : mpObjShell->SetModified( sal_True );
87 : :
88 [ + - ]: 2 : ::comphelper::NamedValueCollection aNormalizedDescriptor;
89 [ + - ]: 2 : NormalizeMacro( aEventDescriptor, aNormalizedDescriptor, mpObjShell );
90 : :
91 : 2 : ::rtl::OUString sType;
92 [ - + ][ # # : 2 : 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 [ + - ][ + - ]: 2 : if ( !aNormalizedDescriptor.empty() )
107 : : {
108 [ + - ][ + - ]: 2 : maEventData[i] <<= aNormalizedDescriptor.getPropertyValues();
[ + - ][ + - ]
109 : : }
110 : : else
111 : : {
112 [ # # ]: 0 : maEventData[i].clear();
113 : : }
114 [ + - ][ + - ]: 4 : return;
115 : : }
116 : : }
117 : :
118 [ + - ][ # # ]: 2 : throw NOSUCHELEMENTEXCEPTION();
119 : : }
120 : :
121 : : //--------------------------------------------------------------------------------------------------------
122 : : // --- XNameAccess ---
123 : : //--------------------------------------------------------------------------------------------------------
124 : 1170 : ANY SAL_CALL SfxEvents_Impl::getByName( const rtl::OUString& aName )
125 : : throw( NOSUCHELEMENTEXCEPTION, WRAPPEDTARGETEXCEPTION,
126 : : RUNTIMEEXCEPTION )
127 : : {
128 [ + - ]: 1170 : ::osl::MutexGuard aGuard( maMutex );
129 : :
130 : : // find the event in the list and return the data
131 : :
132 : 1170 : long nCount = maEventNames.getLength();
133 : :
134 [ + - ]: 19091 : for ( long i=0; i<nCount; i++ )
135 : : {
136 [ + - ][ + + ]: 19091 : if ( maEventNames[i] == aName )
137 [ + - ]: 2340 : return maEventData[i];
138 : : }
139 : :
140 [ # # ][ + - ]: 1170 : throw NOSUCHELEMENTEXCEPTION();
141 : : }
142 : :
143 : : //--------------------------------------------------------------------------------------------------------
144 : 40 : SEQUENCE< rtl::OUString > SAL_CALL SfxEvents_Impl::getElementNames() throw ( RUNTIMEEXCEPTION )
145 : : {
146 : 40 : 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 : 33334 : static void Execute( ANY& aEventData, const css::document::DocumentEvent& aTrigger, SfxObjectShell* pDoc )
188 : : {
189 [ + - ]: 33334 : SEQUENCE < PROPERTYVALUE > aProperties;
190 [ + - ][ + + ]: 33334 : if ( aEventData >>= aProperties )
191 : : {
192 : 30767 : rtl::OUString aType;
193 : 30767 : rtl::OUString aScript;
194 : 30767 : rtl::OUString aLibrary;
195 : 30767 : rtl::OUString aMacroName;
196 : :
197 : 30767 : sal_Int32 nCount = aProperties.getLength();
198 : :
199 [ - + ]: 30767 : if ( !nCount )
200 : 33334 : return;
201 : :
202 : 30767 : sal_Int32 nIndex = 0;
203 [ + + ]: 92301 : while ( nIndex < nCount )
204 : : {
205 [ + - ][ + + ]: 61534 : if ( aProperties[ nIndex ].Name == PROP_EVENT_TYPE )
206 [ + - ]: 30767 : aProperties[ nIndex ].Value >>= aType;
207 [ + - ][ + - ]: 30767 : else if ( aProperties[ nIndex ].Name == PROP_SCRIPT )
208 [ + - ]: 30767 : 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 : 61534 : nIndex += 1;
217 : : }
218 : :
219 [ - + ][ # # ]: 30767 : 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 [ + - + - ]: 61534 : else if (aType.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("Service")) ||
[ + - ]
225 : 30767 : aType.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("Script")))
226 : : {
227 [ + + ]: 30767 : if ( !aScript.isEmpty() )
228 : : {
229 : : SfxViewFrame* pView = pDoc ?
230 : : SfxViewFrame::GetFirst( pDoc ) :
231 [ + - ][ + - ]: 2 : SfxViewFrame::Current();
[ # # ]
232 : :
233 [ + - ][ + - ]: 2 : ::com::sun::star::uno::Reference < ::com::sun::star::util::XURLTransformer > xTrans( ::com::sun::star::util::URLTransformer::create( ::comphelper::getProcessComponentContext() ) );
234 : :
235 : 2 : ::com::sun::star::util::URL aURL;
236 : 2 : aURL.Complete = aScript;
237 [ + - ][ + - ]: 2 : xTrans->parseStrict( aURL );
238 : :
239 : : ::com::sun::star::uno::Reference
240 : 2 : < ::com::sun::star::frame::XDispatchProvider > xProv;
241 : :
242 [ + - ]: 2 : if ( pView != NULL )
243 : : {
244 : : xProv = ::com::sun::star::uno::Reference
245 : : < ::com::sun::star::frame::XDispatchProvider > (
246 [ + - ][ + - ]: 2 : 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 : 2 : ::com::sun::star::uno::Reference < ::com::sun::star::frame::XDispatch > xDisp;
259 [ + - ]: 2 : if ( xProv.is() )
260 [ + - ][ + - ]: 2 : xDisp = xProv->queryDispatch( aURL, ::rtl::OUString(), 0 );
[ + - ]
261 : :
262 [ + - ]: 2 : if ( xDisp.is() )
263 : : {
264 : :
265 : 2 : css::beans::PropertyValue aEventParam;
266 [ + - ]: 2 : aEventParam.Value <<= aTrigger;
267 [ + - ]: 2 : css::uno::Sequence< css::beans::PropertyValue > aDispatchArgs( &aEventParam, 1 );
268 [ + - ][ + - ]: 2 : xDisp->dispatch( aURL, aDispatchArgs );
[ + - ]
269 : 2 : }
270 : : }
271 : : }
272 : 30767 : 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 [ - + ][ - + ]: 33334 : }
[ - + ][ + - ]
280 [ + - ][ + - ]: 33334 : }
281 : : }
282 : :
283 : : //--------------------------------------------------------------------------------------------------------
284 : : // --- ::document::XEventListener ---
285 : : //--------------------------------------------------------------------------------------------------------
286 : 257 : void SAL_CALL SfxEvents_Impl::notifyEvent( const DOCEVENTOBJECT& aEvent ) throw( RUNTIMEEXCEPTION )
287 : : {
288 [ + - ]: 257 : ::osl::ClearableMutexGuard aGuard( maMutex );
289 : :
290 : : // get the event name, find the coresponding data, execute the data
291 : :
292 : 257 : rtl::OUString aName = aEvent.EventName;
293 : 257 : long nCount = maEventNames.getLength();
294 : 257 : long nIndex = 0;
295 : 257 : sal_Bool bFound = sal_False;
296 : :
297 [ + + ][ + - ]: 5567 : while ( !bFound && ( nIndex < nCount ) )
[ + + ]
298 : : {
299 [ + - ][ + + ]: 5310 : if ( maEventNames[nIndex] == aName )
300 : 257 : bFound = sal_True;
301 : : else
302 : 5053 : nIndex += 1;
303 : : }
304 : :
305 [ - + ]: 257 : if ( !bFound )
306 : 257 : return;
307 : :
308 [ + - ]: 257 : ANY aEventData = maEventData[ nIndex ];
309 [ + - ]: 257 : aGuard.clear();
310 [ + - ][ + - ]: 257 : Execute( aEventData, css::document::DocumentEvent(aEvent.Source, aEvent.EventName, NULL, css::uno::Any()), mpObjShell );
[ + - ][ + - ]
[ - + ][ + - ]
[ + - ]
311 : : }
312 : :
313 : : //--------------------------------------------------------------------------------------------------------
314 : : // --- ::lang::XEventListener ---
315 : : //--------------------------------------------------------------------------------------------------------
316 : 34 : void SAL_CALL SfxEvents_Impl::disposing( const EVENTOBJECT& /*Source*/ ) throw( RUNTIMEEXCEPTION )
317 : : {
318 [ + - ]: 34 : ::osl::MutexGuard aGuard( maMutex );
319 : :
320 [ + - ]: 34 : if ( mxBroadcaster.is() )
321 : : {
322 [ + - ][ + - ]: 34 : mxBroadcaster->removeEventListener( this );
[ + - ]
323 [ + - ]: 34 : mxBroadcaster = NULL;
324 [ + - ]: 34 : }
325 : 34 : }
326 : :
327 : : //--------------------------------------------------------------------------------------------------------
328 : : //--------------------------------------------------------------------------------------------------------
329 : 34 : SfxEvents_Impl::SfxEvents_Impl( SfxObjectShell* pShell,
330 [ + - ][ + - ]: 34 : REFERENCE< XEVENTBROADCASTER > xBroadcaster )
[ + - ]
331 : : {
332 : : // get the list of supported events and store it
333 [ + - ]: 34 : if ( pShell )
334 [ + - ][ + - ]: 34 : maEventNames = pShell->GetEventNames();
[ + - ]
335 : : else
336 [ # # ][ # # ]: 0 : maEventNames = GlobalEventConfig().getElementNames();
[ # # ][ # # ]
[ # # ]
337 : :
338 [ + - ][ + - ]: 34 : maEventData = SEQUENCE < ANY > ( maEventNames.getLength() );
[ + - ]
339 : :
340 : 34 : mpObjShell = pShell;
341 [ + - ]: 34 : mxBroadcaster = xBroadcaster;
342 : :
343 [ + - ]: 34 : if ( mxBroadcaster.is() )
344 [ + - ][ + - ]: 34 : mxBroadcaster->addEventListener( this );
[ + - ]
345 : 34 : }
346 : :
347 : : //--------------------------------------------------------------------------------------------------------
348 [ + - ][ + - ]: 34 : SfxEvents_Impl::~SfxEvents_Impl()
[ + - ]
349 : : {
350 [ - + ]: 68 : }
351 : :
352 : : //--------------------------------------------------------------------------------------------------------
353 : 8 : SvxMacro* SfxEvents_Impl::ConvertToMacro( const ANY& rElement, SfxObjectShell* pObjShell, sal_Bool bNormalizeMacro )
354 : : {
355 : 8 : SvxMacro* pMacro = NULL;
356 [ + - ]: 8 : SEQUENCE < PROPERTYVALUE > aProperties;
357 : 8 : ANY aAny;
358 [ + - ]: 8 : if ( bNormalizeMacro )
359 [ + - ]: 8 : NormalizeMacro( rElement, aAny, pObjShell );
360 : : else
361 : 0 : aAny = rElement;
362 : :
363 [ + - ][ + - ]: 8 : if ( aAny >>= aProperties )
364 : : {
365 : 8 : rtl::OUString aType;
366 : 8 : rtl::OUString aScriptURL;
367 : 8 : rtl::OUString aLibrary;
368 : 8 : rtl::OUString aMacroName;
369 : :
370 : 8 : long nCount = aProperties.getLength();
371 : 8 : long nIndex = 0;
372 : :
373 [ + - ]: 8 : if ( !nCount )
374 : 8 : 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 [ # # ][ # # ]: 8 : pMacro = new SvxMacro( aScriptURL, aType );
[ + - ][ + - ]
[ + - ][ - + ]
414 : : }
415 : :
416 [ + - ]: 8 : return pMacro;
417 : : }
418 : :
419 : 8 : void SfxEvents_Impl::NormalizeMacro( const ANY& rEvent, ANY& rRet, SfxObjectShell* pDoc )
420 : : {
421 [ + - ]: 8 : const ::comphelper::NamedValueCollection aEventDescriptor( rEvent );
422 [ + - ]: 8 : ::comphelper::NamedValueCollection aEventDescriptorOut;
423 : :
424 [ + - ]: 8 : NormalizeMacro( aEventDescriptor, aEventDescriptorOut, pDoc );
425 : :
426 [ + - ][ + - ]: 8 : rRet <<= aEventDescriptorOut.getPropertyValues();
[ + - ][ + - ]
[ + - ]
427 : 8 : }
428 : :
429 : 10 : void SfxEvents_Impl::NormalizeMacro( const ::comphelper::NamedValueCollection& i_eventDescriptor,
430 : : ::comphelper::NamedValueCollection& o_normalizedDescriptor, SfxObjectShell* i_document )
431 : : {
432 : 10 : SfxObjectShell* pDoc = i_document;
433 [ - + ]: 10 : if ( !pDoc )
434 [ # # ]: 0 : pDoc = SfxObjectShell::Current();
435 : :
436 [ + - ]: 10 : ::rtl::OUString aType = i_eventDescriptor.getOrDefault( PROP_EVENT_TYPE, ::rtl::OUString() );
437 [ + - ]: 10 : ::rtl::OUString aScript = i_eventDescriptor.getOrDefault( PROP_SCRIPT, ::rtl::OUString() );
438 [ + - ]: 10 : ::rtl::OUString aLibrary = i_eventDescriptor.getOrDefault( PROP_LIBRARY, ::rtl::OUString() );
439 [ + - ]: 10 : ::rtl::OUString aMacroName = i_eventDescriptor.getOrDefault( PROP_MACRO_NAME, ::rtl::OUString() );
440 : :
441 [ + + ]: 10 : if ( !aType.isEmpty() )
442 [ + - ]: 2 : o_normalizedDescriptor.put( PROP_EVENT_TYPE, aType );
443 [ + + ]: 10 : if ( !aScript.isEmpty() )
444 [ + - ]: 2 : o_normalizedDescriptor.put( PROP_SCRIPT, aScript );
445 : :
446 [ - + ]: 10 : 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 : 10 : 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 [ # # ]: 10 : o_normalizedDescriptor.put( PROP_MACRO_NAME, aMacroName );
496 [ - + ][ - + ]: 10 : }
[ - + ][ + - ]
497 : : }
498 : :
499 : 21 : ModelCollectionEnumeration::ModelCollectionEnumeration(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
500 : : : ModelCollectionMutexBase( )
501 : : , m_xSMGR (xSMGR )
502 [ + - ][ + - ]: 21 : , m_pEnumerationIt (m_lModels.begin())
503 : : {
504 : 21 : }
505 : :
506 [ + - ]: 21 : ModelCollectionEnumeration::~ModelCollectionEnumeration()
507 : : {
508 [ - + ]: 42 : }
509 : :
510 : 21 : void ModelCollectionEnumeration::setModelList(const TModelList& rList)
511 : : {
512 : : // SAFE ->
513 [ + - ]: 21 : ::osl::ResettableMutexGuard aLock(m_aLock);
514 [ + - ]: 21 : m_lModels = rList;
515 : 21 : m_pEnumerationIt = m_lModels.begin();
516 [ + - ][ + - ]: 21 : aLock.clear();
517 : : // <- SAFE
518 : 21 : }
519 : :
520 : 44 : sal_Bool SAL_CALL ModelCollectionEnumeration::hasMoreElements()
521 : : throw(css::uno::RuntimeException)
522 : : {
523 : : // SAFE ->
524 [ + - ]: 44 : ::osl::ResettableMutexGuard aLock(m_aLock);
525 [ + - ][ + - ]: 44 : return (m_pEnumerationIt != m_lModels.end());
526 : : // <- SAFE
527 : : }
528 : :
529 : 23 : css::uno::Any SAL_CALL ModelCollectionEnumeration::nextElement()
530 : : throw(css::container::NoSuchElementException,
531 : : css::lang::WrappedTargetException ,
532 : : css::uno::RuntimeException )
533 : : {
534 : : // SAFE ->
535 [ + - ]: 23 : ::osl::ResettableMutexGuard aLock(m_aLock);
536 [ + - ][ - + ]: 23 : if (m_pEnumerationIt == m_lModels.end())
537 : : throw css::container::NoSuchElementException(
538 : : ::rtl::OUString("End of model enumeration reached."),
539 [ # # ][ # # ]: 0 : static_cast< css::container::XEnumeration* >(this));
540 [ + - ]: 23 : css::uno::Reference< css::frame::XModel > xModel(*m_pEnumerationIt, UNO_QUERY);
541 : 23 : ++m_pEnumerationIt;
542 [ + - ]: 23 : aLock.clear();
543 : : // <- SAFE
544 : :
545 [ + - ][ + - ]: 23 : return css::uno::makeAny(xModel);
546 : : }
547 : :
548 [ + - ][ + - ]: 1236 : SFX_IMPL_XSERVICEINFO( SfxGlobalEvents_Impl, "com.sun.star.frame.GlobalEventBroadcaster", "com.sun.star.comp.sfx2.GlobalEventBroadcaster" )
[ # # ][ # # ]
[ # # ][ # # ]
549 [ + - ][ + - ]: 230 : SFX_IMPL_ONEINSTANCEFACTORY( SfxGlobalEvents_Impl );
550 : :
551 : : //-----------------------------------------------------------------------------
552 : 230 : SfxGlobalEvents_Impl::SfxGlobalEvents_Impl( const com::sun::star::uno::Reference < ::com::sun::star::lang::XMultiServiceFactory >& xSMGR)
553 : : : ModelCollectionMutexBase( )
554 : : , m_xSMGR (xSMGR )
555 : : , m_aLegacyListeners (m_aLock)
556 : : , m_aDocumentListeners (m_aLock)
557 [ + - ][ + - ]: 230 : , pImp (0 )
[ + - ][ + - ]
[ + - ]
558 : : {
559 : 230 : m_refCount++;
560 [ + - ]: 230 : SFX_APP();
561 [ + - ]: 230 : pImp = new GlobalEventConfig();
562 [ + - ][ + - ]: 230 : m_xEvents = pImp;
563 : : m_xJobExecutorListener = css::uno::Reference< css::document::XEventListener >(
564 [ + - ]: 230 : xSMGR->createInstance(::rtl::OUString("com.sun.star.task.JobExecutor")),
565 [ + - ][ + - ]: 230 : UNO_QUERY);
[ + - ]
566 : 230 : m_refCount--;
567 : 230 : }
568 : :
569 : : //-----------------------------------------------------------------------------
570 [ + - ][ + - ]: 161 : SfxGlobalEvents_Impl::~SfxGlobalEvents_Impl()
[ + - ][ + - ]
571 : : {
572 [ - + ]: 322 : }
573 : :
574 : : //-----------------------------------------------------------------------------
575 : 0 : css::uno::Reference< css::container::XNameReplace > SAL_CALL SfxGlobalEvents_Impl::getEvents()
576 : : throw(css::uno::RuntimeException)
577 : : {
578 : : // SAFE ->
579 [ # # ]: 0 : ::osl::ResettableMutexGuard aLock(m_aLock);
580 [ # # ]: 0 : return m_xEvents;
581 : : // <- SAFE
582 : : }
583 : :
584 : : //-----------------------------------------------------------------------------
585 : 240 : void SAL_CALL SfxGlobalEvents_Impl::addEventListener(const css::uno::Reference< css::document::XEventListener >& xListener)
586 : : throw(css::uno::RuntimeException)
587 : : {
588 : : // container is threadsafe
589 : 240 : m_aLegacyListeners.addInterface(xListener);
590 : 240 : }
591 : :
592 : : //-----------------------------------------------------------------------------
593 : 187 : void SAL_CALL SfxGlobalEvents_Impl::removeEventListener(const css::uno::Reference< css::document::XEventListener >& xListener)
594 : : throw(css::uno::RuntimeException)
595 : : {
596 : : // container is threadsafe
597 : 187 : m_aLegacyListeners.removeInterface(xListener);
598 : 187 : }
599 : :
600 : : //-----------------------------------------------------------------------------
601 : 0 : void SAL_CALL SfxGlobalEvents_Impl::addDocumentEventListener( const css::uno::Reference< css::document::XDocumentEventListener >& _Listener )
602 : : throw(css::uno::RuntimeException)
603 : : {
604 : 0 : m_aDocumentListeners.addInterface( _Listener );
605 : 0 : }
606 : :
607 : : //-----------------------------------------------------------------------------
608 : 0 : void SAL_CALL SfxGlobalEvents_Impl::removeDocumentEventListener( const css::uno::Reference< css::document::XDocumentEventListener >& _Listener )
609 : : throw(css::uno::RuntimeException)
610 : : {
611 : 0 : m_aDocumentListeners.removeInterface( _Listener );
612 : 0 : }
613 : :
614 : : //-----------------------------------------------------------------------------
615 : 0 : void SAL_CALL SfxGlobalEvents_Impl::notifyDocumentEvent( const ::rtl::OUString& /*_EventName*/,
616 : : const css::uno::Reference< css::frame::XController2 >& /*_ViewController*/, const css::uno::Any& /*_Supplement*/ )
617 : : throw (css::lang::IllegalArgumentException, css::lang::NoSupportException, css::uno::RuntimeException)
618 : : {
619 : : // we're a multiplexer only, no chance to generate artifical events here
620 [ # # ][ # # ]: 0 : throw css::lang::NoSupportException(::rtl::OUString(), *this);
621 : : }
622 : :
623 : : //-----------------------------------------------------------------------------
624 : 474 : void SAL_CALL SfxGlobalEvents_Impl::notifyEvent(const css::document::EventObject& aEvent)
625 : : throw(css::uno::RuntimeException)
626 : : {
627 [ + - ][ + - ]: 474 : css::document::DocumentEvent aDocEvent(aEvent.Source, aEvent.EventName, NULL, css::uno::Any());
628 [ + - ]: 474 : implts_notifyJobExecution(aEvent);
629 [ + - ]: 474 : implts_checkAndExecuteEventBindings(aDocEvent);
630 [ + - ][ + - ]: 474 : implts_notifyListener(aDocEvent);
631 : 474 : }
632 : :
633 : : //-----------------------------------------------------------------------------
634 : 32603 : void SAL_CALL SfxGlobalEvents_Impl::documentEventOccured( const ::css::document::DocumentEvent& _Event )
635 : : throw (::css::uno::RuntimeException)
636 : : {
637 [ + - ]: 32603 : implts_notifyJobExecution(css::document::EventObject(_Event.Source, _Event.EventName));
638 : 32603 : implts_checkAndExecuteEventBindings(_Event);
639 : 32603 : implts_notifyListener(_Event);
640 : 32603 : }
641 : :
642 : : //-----------------------------------------------------------------------------
643 : 2574 : void SAL_CALL SfxGlobalEvents_Impl::disposing(const css::lang::EventObject& aEvent)
644 : : throw(css::uno::RuntimeException)
645 : : {
646 [ + - ]: 2574 : css::uno::Reference< css::frame::XModel > xDoc(aEvent.Source, UNO_QUERY);
647 : :
648 : : // SAFE ->
649 [ + - ]: 2574 : ::osl::ResettableMutexGuard aLock(m_aLock);
650 [ + - ]: 2574 : TModelList::iterator pIt = impl_searchDoc(xDoc);
651 [ + - ][ + - ]: 2574 : if (pIt != m_lModels.end())
652 [ + - ]: 2574 : m_lModels.erase(pIt);
653 [ + - ][ + - ]: 2574 : aLock.clear();
654 : : // <- SAFE
655 : 2574 : }
656 : :
657 : : //-----------------------------------------------------------------------------
658 : 0 : sal_Bool SAL_CALL SfxGlobalEvents_Impl::has(const css::uno::Any& aElement)
659 : : throw (css::uno::RuntimeException)
660 : : {
661 : 0 : css::uno::Reference< css::frame::XModel > xDoc;
662 [ # # ]: 0 : aElement >>= xDoc;
663 : :
664 : 0 : sal_Bool bHas = sal_False;
665 : :
666 : : // SAFE ->
667 [ # # ]: 0 : ::osl::ResettableMutexGuard aLock(m_aLock);
668 [ # # ]: 0 : TModelList::iterator pIt = impl_searchDoc(xDoc);
669 [ # # ][ # # ]: 0 : if (pIt != m_lModels.end())
670 : 0 : bHas = sal_True;
671 [ # # ]: 0 : aLock.clear();
672 : : // <- SAFE
673 : :
674 [ # # ]: 0 : return bHas;
675 : : }
676 : :
677 : : //-----------------------------------------------------------------------------
678 : 2762 : void SAL_CALL SfxGlobalEvents_Impl::insert( const css::uno::Any& aElement )
679 : : throw (css::lang::IllegalArgumentException ,
680 : : css::container::ElementExistException,
681 : : css::uno::RuntimeException )
682 : : {
683 : 2762 : css::uno::Reference< css::frame::XModel > xDoc;
684 [ + - ]: 2762 : aElement >>= xDoc;
685 [ - + ]: 2762 : if (!xDoc.is())
686 : : throw css::lang::IllegalArgumentException(
687 : : ::rtl::OUString("Cant locate at least the model parameter."),
688 : : static_cast< css::container::XSet* >(this),
689 [ # # ][ # # ]: 0 : 0);
690 : :
691 : : // SAFE ->
692 [ + - ]: 2762 : ::osl::ResettableMutexGuard aLock(m_aLock);
693 [ + - ]: 2762 : TModelList::iterator pIt = impl_searchDoc(xDoc);
694 [ + - ][ - + ]: 2762 : if (pIt != m_lModels.end())
695 : : throw css::container::ElementExistException(
696 : : ::rtl::OUString(),
697 [ # # ][ # # ]: 0 : static_cast< css::container::XSet* >(this));
698 [ + - ]: 2762 : m_lModels.push_back(xDoc);
699 [ + - ]: 2762 : aLock.clear();
700 : : // <- SAFE
701 : :
702 [ + - ]: 2762 : css::uno::Reference< css::document::XDocumentEventBroadcaster > xDocBroadcaster(xDoc, UNO_QUERY );
703 [ + - ]: 2762 : if (xDocBroadcaster.is())
704 [ + - ][ + - ]: 2762 : xDocBroadcaster->addDocumentEventListener(this);
[ + - ]
705 : : else
706 : : {
707 : : // try the "legacy version" of XDocumentEventBroadcaster, which is XEventBroadcaster
708 [ # # ]: 0 : css::uno::Reference< css::document::XEventBroadcaster > xBroadcaster(xDoc, UNO_QUERY);
709 [ # # ]: 0 : if (xBroadcaster.is())
710 [ # # ][ # # ]: 0 : xBroadcaster->addEventListener(static_cast< css::document::XEventListener* >(this));
[ # # ]
711 [ + - ]: 2762 : }
712 : 2762 : }
713 : :
714 : : //-----------------------------------------------------------------------------
715 : 0 : void SAL_CALL SfxGlobalEvents_Impl::remove( const css::uno::Any& aElement )
716 : : throw (css::lang::IllegalArgumentException ,
717 : : css::container::NoSuchElementException,
718 : : css::uno::RuntimeException )
719 : : {
720 : 0 : css::uno::Reference< css::frame::XModel > xDoc;
721 [ # # ]: 0 : aElement >>= xDoc;
722 [ # # ]: 0 : if (!xDoc.is())
723 : : throw css::lang::IllegalArgumentException(
724 : : ::rtl::OUString("Cant locate at least the model parameter."),
725 : : static_cast< css::container::XSet* >(this),
726 [ # # ][ # # ]: 0 : 0);
727 : :
728 : : // SAFE ->
729 [ # # ]: 0 : ::osl::ResettableMutexGuard aLock(m_aLock);
730 [ # # ]: 0 : TModelList::iterator pIt = impl_searchDoc(xDoc);
731 [ # # ][ # # ]: 0 : if (pIt == m_lModels.end())
732 : : throw css::container::NoSuchElementException(
733 : : ::rtl::OUString(),
734 [ # # ][ # # ]: 0 : static_cast< css::container::XSet* >(this));
735 [ # # ]: 0 : m_lModels.erase(pIt);
736 [ # # ]: 0 : aLock.clear();
737 : : // <- SAFE
738 : :
739 [ # # ]: 0 : css::uno::Reference< css::document::XDocumentEventBroadcaster > xDocBroadcaster(xDoc, UNO_QUERY );
740 [ # # ]: 0 : if (xDocBroadcaster.is())
741 [ # # ][ # # ]: 0 : xDocBroadcaster->removeDocumentEventListener(this);
[ # # ]
742 : : else
743 : : {
744 : : // try the "legacy version" of XDocumentEventBroadcaster, which is XEventBroadcaster
745 [ # # ]: 0 : css::uno::Reference< css::document::XEventBroadcaster > xBroadcaster(xDoc, UNO_QUERY);
746 [ # # ]: 0 : if (xBroadcaster.is())
747 [ # # ][ # # ]: 0 : xBroadcaster->removeEventListener(static_cast< css::document::XEventListener* >(this));
[ # # ]
748 [ # # ]: 0 : }
749 : 0 : }
750 : :
751 : : //-----------------------------------------------------------------------------
752 : 21 : css::uno::Reference< css::container::XEnumeration > SAL_CALL SfxGlobalEvents_Impl::createEnumeration()
753 : : throw (css::uno::RuntimeException)
754 : : {
755 : : // SAFE ->
756 [ + - ]: 21 : ::osl::ResettableMutexGuard aLock(m_aLock);
757 [ + - ]: 21 : ModelCollectionEnumeration* pEnum = new ModelCollectionEnumeration(m_xSMGR);
758 [ + - ]: 21 : pEnum->setModelList(m_lModels);
759 : : css::uno::Reference< css::container::XEnumeration > xEnum(
760 [ + - ]: 21 : static_cast< css::container::XEnumeration* >(pEnum),
761 [ + - ]: 21 : UNO_QUERY);
762 [ + - ]: 21 : aLock.clear();
763 : : // <- SAFE
764 : :
765 [ + - ]: 21 : return xEnum;
766 : : }
767 : :
768 : : //-----------------------------------------------------------------------------
769 : 0 : css::uno::Type SAL_CALL SfxGlobalEvents_Impl::getElementType()
770 : : throw (css::uno::RuntimeException)
771 : : {
772 : 0 : return ::getCppuType(static_cast< css::uno::Reference< css::frame::XModel >* >(NULL));
773 : : }
774 : :
775 : : //-----------------------------------------------------------------------------
776 : 0 : sal_Bool SAL_CALL SfxGlobalEvents_Impl::hasElements()
777 : : throw (css::uno::RuntimeException)
778 : : {
779 : : // SAFE ->
780 [ # # ]: 0 : ::osl::ResettableMutexGuard aLock(m_aLock);
781 [ # # ]: 0 : return (m_lModels.size()>0);
782 : : // <- SAFE
783 : : }
784 : :
785 : : //-----------------------------------------------------------------------------
786 : 33077 : void SfxGlobalEvents_Impl::implts_notifyJobExecution(const css::document::EventObject& aEvent)
787 : : {
788 : : try
789 : : {
790 : : // SAFE ->
791 [ + - ]: 33077 : ::osl::ResettableMutexGuard aLock(m_aLock);
792 [ + - ]: 33077 : css::uno::Reference< css::document::XEventListener > xJobExecutor(m_xJobExecutorListener);
793 [ + - ]: 33077 : aLock.clear();
794 : : // <- SAFE
795 [ + - ]: 33077 : if (xJobExecutor.is())
796 [ + - ][ + - ]: 33077 : xJobExecutor->notifyEvent(aEvent);
[ + - ]
797 : : }
798 [ # # # ]: 0 : catch(const css::uno::RuntimeException&)
799 : 0 : { throw; }
800 : 0 : catch(const css::uno::Exception&)
801 : : {}
802 : 33077 : }
803 : :
804 : : //-----------------------------------------------------------------------------
805 : 33077 : void SfxGlobalEvents_Impl::implts_checkAndExecuteEventBindings(const css::document::DocumentEvent& aEvent)
806 : : {
807 : : try
808 : : {
809 : : // SAFE ->
810 [ + - ]: 33077 : ::osl::ResettableMutexGuard aLock(m_aLock);
811 : 33077 : css::uno::Reference< css::container::XNameReplace > xEvents = m_xEvents;
812 [ + - ]: 33077 : aLock.clear();
813 : : // <- SAFE
814 : :
815 : 33077 : css::uno::Any aAny;
816 [ + - ][ + - ]: 33077 : if ( xEvents.is() && xEvents->hasByName( aEvent.EventName ) )
[ + + ][ + + ]
[ + - ]
817 [ + - ][ + - ]: 30765 : aAny = xEvents->getByName(aEvent.EventName);
818 [ + - ][ + - ]: 33077 : Execute(aAny, aEvent, 0);
819 : : }
820 [ # # # ]: 0 : catch ( css::uno::RuntimeException const & )
821 : : {
822 : 0 : throw;
823 : : }
824 : 0 : catch ( css::uno::Exception const & )
825 : : {
826 : : DBG_UNHANDLED_EXCEPTION();
827 : : }
828 : 33077 : }
829 : :
830 : : //-----------------------------------------------------------------------------
831 : 33077 : void SfxGlobalEvents_Impl::implts_notifyListener(const css::document::DocumentEvent& aEvent)
832 : : {
833 : : // containers are threadsafe
834 [ + - ]: 33077 : css::document::EventObject aLegacyEvent(aEvent.Source, aEvent.EventName);
835 [ + - ]: 33077 : m_aLegacyListeners.notifyEach( &css::document::XEventListener::notifyEvent, aLegacyEvent );
836 : :
837 [ + - ][ + - ]: 33077 : m_aDocumentListeners.notifyEach( &css::document::XDocumentEventListener::documentEventOccured, aEvent );
838 : 33077 : }
839 : :
840 : : //-----------------------------------------------------------------------------
841 : : // not threadsafe ... must be locked from outside!
842 : 5336 : TModelList::iterator SfxGlobalEvents_Impl::impl_searchDoc(const css::uno::Reference< css::frame::XModel >& xModel)
843 : : {
844 [ - + ]: 5336 : if (!xModel.is())
845 : 0 : return m_lModels.end();
846 : :
847 : 5336 : TModelList::iterator pIt;
848 [ + - ][ + + ]: 47582 : for ( pIt = m_lModels.begin();
849 : 22504 : pIt != m_lModels.end() ;
850 : : ++pIt )
851 : : {
852 [ + - ]: 19742 : css::uno::Reference< css::frame::XModel > xContainerDoc(*pIt, UNO_QUERY);
853 [ + - ][ + + ]: 19742 : if (xContainerDoc == xModel)
854 : : break;
855 [ + + ]: 19742 : }
856 : :
857 : 5336 : return pIt;
858 : : }
859 : :
860 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|