1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "eventhandler.hxx"
22 #include "propctrlr.hrc"
23 #include "formbrowsertools.hxx"
24 #include "formresid.hrc"
25 #include "formstrings.hxx"
26 #include "handlerhelper.hxx"
27 #include "modulepcr.hxx"
28 #include "pcrcommon.hxx"
29 #include "pcrstrings.hxx"
30 #include "propertycontrolextender.hxx"
32 #include <com/sun/star/awt/XTabControllerModel.hpp>
33 #include <com/sun/star/beans/PropertyAttribute.hpp>
34 #include <com/sun/star/beans/UnknownPropertyException.hpp>
35 #include <com/sun/star/beans/Introspection.hpp>
36 #include <com/sun/star/beans/XIntrospectionAccess.hpp>
37 #include <com/sun/star/container/NoSuchElementException.hpp>
38 #include <com/sun/star/container/XChild.hpp>
39 #include <com/sun/star/container/XIndexAccess.hpp>
40 #include <com/sun/star/container/XNameContainer.hpp>
41 #include <com/sun/star/container/XNameReplace.hpp>
42 #include <com/sun/star/form/FormComponentType.hpp>
43 #include <com/sun/star/form/XForm.hpp>
44 #include <com/sun/star/form/runtime/FormController.hpp>
45 #include <com/sun/star/inspection/PropertyControlType.hpp>
46 #include <com/sun/star/lang/NullPointerException.hpp>
47 #include <com/sun/star/script/XEventAttacherManager.hpp>
48 #include <com/sun/star/script/XScriptEventsSupplier.hpp>
49 #include <com/sun/star/util/XModifiable.hpp>
50 #include <com/sun/star/uri/UriReferenceFactory.hpp>
51 #include <com/sun/star/uri/XVndSunStarScriptUrlReference.hpp>
53 #include <comphelper/namedvaluecollection.hxx>
54 #include <comphelper/evtmethodhelper.hxx>
55 #include <comphelper/types.hxx>
56 #include <cppuhelper/implbase1.hxx>
57 #include <rtl/ref.hxx>
58 #include <rtl/ustrbuf.hxx>
59 #include <sfx2/app.hxx>
60 #include <svl/eitem.hxx>
61 #include <svl/itemset.hxx>
62 #include <svx/svxdlg.hxx>
63 #include <svx/svxids.hrc>
64 #include <tools/diagnose_ex.h>
65 #include <vcl/msgbox.hxx>
69 #include <o3tl/compat_functional.hxx>
71 //------------------------------------------------------------------------
72 extern "C" void SAL_CALL
createRegistryInfo_EventHandler()
74 ::pcr::OAutoRegistration
< ::pcr::EventHandler
> aAutoRegistration
;
77 //........................................................................
80 //........................................................................
82 using ::com::sun::star::uno::Reference
;
83 using ::com::sun::star::uno::XComponentContext
;
84 using ::com::sun::star::beans::XPropertySet
;
85 using ::com::sun::star::uno::Any
;
86 using ::com::sun::star::uno::TypeClass_STRING
;
87 using ::com::sun::star::uno::Type
;
88 using ::com::sun::star::beans::Introspection
;
89 using ::com::sun::star::beans::XPropertyChangeListener
;
90 using ::com::sun::star::beans::Property
;
91 using ::com::sun::star::beans::PropertyState
;
92 using ::com::sun::star::beans::PropertyState_DIRECT_VALUE
;
93 using ::com::sun::star::uno::Sequence
;
94 using ::com::sun::star::script::ScriptEventDescriptor
;
95 using ::com::sun::star::script::XScriptEventsSupplier
;
96 using ::com::sun::star::lang::NullPointerException
;
97 using ::com::sun::star::uno::Exception
;
98 using ::com::sun::star::container::XChild
;
99 using ::com::sun::star::container::XIndexAccess
;
100 using ::com::sun::star::script::XEventAttacherManager
;
101 using ::com::sun::star::uno::UNO_QUERY
;
102 using ::com::sun::star::uno::UNO_QUERY_THROW
;
103 using ::com::sun::star::uno::XInterface
;
104 using ::com::sun::star::beans::XIntrospection
;
105 using ::com::sun::star::beans::XIntrospectionAccess
;
106 using ::com::sun::star::container::XNameContainer
;
107 using ::com::sun::star::awt::XTabControllerModel
;
108 using ::com::sun::star::form::XForm
;
109 using ::com::sun::star::form::runtime::FormController
;
110 using ::com::sun::star::form::runtime::XFormController
;
111 using ::com::sun::star::beans::UnknownPropertyException
;
112 using ::com::sun::star::uno::makeAny
;
113 using ::com::sun::star::container::NoSuchElementException
;
114 using ::com::sun::star::beans::XPropertySetInfo
;
115 using ::com::sun::star::container::XNameReplace
;
116 using ::com::sun::star::lang::IllegalArgumentException
;
117 using ::com::sun::star::lang::WrappedTargetException
;
118 using ::com::sun::star::uno::RuntimeException
;
119 using ::com::sun::star::beans::PropertyValue
;
120 using ::com::sun::star::inspection::LineDescriptor
;
121 using ::com::sun::star::inspection::XPropertyControlFactory
;
122 using ::com::sun::star::inspection::InteractiveSelectionResult
;
123 using ::com::sun::star::inspection::InteractiveSelectionResult_Cancelled
;
124 using ::com::sun::star::inspection::InteractiveSelectionResult_Success
;
125 using ::com::sun::star::inspection::XObjectInspectorUI
;
126 using ::com::sun::star::util::XModifiable
;
127 using ::com::sun::star::beans::PropertyChangeEvent
;
128 using ::com::sun::star::frame::XFrame
;
129 using ::com::sun::star::frame::XModel
;
130 using ::com::sun::star::frame::XController
;
131 using ::com::sun::star::uno::UNO_SET_THROW
;
132 using com::sun::star::uri::UriReferenceFactory
;
133 using com::sun::star::uri::XUriReferenceFactory
;
134 using com::sun::star::uri::XVndSunStarScriptUrlReference
;
135 using ::com::sun::star::lang::XEventListener
;
137 namespace PropertyControlType
= ::com::sun::star::inspection::PropertyControlType
;
138 namespace PropertyAttribute
= ::com::sun::star::beans::PropertyAttribute
;
139 namespace FormComponentType
= ::com::sun::star::form::FormComponentType
;
141 //====================================================================
143 //====================================================================
144 EventDescription::EventDescription( EventId _nId
, const sal_Char
* _pListenerNamespaceAscii
, const sal_Char
* _pListenerClassAsciiName
,
145 const sal_Char
* _pListenerMethodAsciiName
, sal_uInt16 _nDisplayNameResId
, const OString
& _sHelpId
, const OString
& _sUniqueBrowseId
)
146 :sDisplayName( String( PcrRes( _nDisplayNameResId
) ) )
147 ,sListenerMethodName( OUString::createFromAscii( _pListenerMethodAsciiName
) )
149 ,sUniqueBrowseId( _sUniqueBrowseId
)
152 OUStringBuffer aQualifiedListenerClass
;
153 aQualifiedListenerClass
.appendAscii( "com.sun.star." );
154 aQualifiedListenerClass
.appendAscii( _pListenerNamespaceAscii
);
155 aQualifiedListenerClass
.appendAscii( "." );
156 aQualifiedListenerClass
.appendAscii( _pListenerClassAsciiName
);
157 sListenerClassName
= aQualifiedListenerClass
.makeStringAndClear();
160 //========================================================================
162 //========================================================================
165 //....................................................................
166 #define DESCRIBE_EVENT( asciinamespace, asciilistener, asciimethod, id_postfix ) \
167 s_aKnownEvents.insert( EventMap::value_type( \
168 OUString::createFromAscii( asciimethod ), \
169 EventDescription( ++nEventId, asciinamespace, asciilistener, asciimethod, RID_STR_EVT_##id_postfix, HID_EVT_##id_postfix, UID_BRWEVT_##id_postfix ) ) )
171 //....................................................................
172 bool lcl_getEventDescriptionForMethod( const OUString
& _rMethodName
, EventDescription
& _out_rDescription
)
174 static EventMap s_aKnownEvents
;
175 if ( s_aKnownEvents
.empty() )
177 ::osl::MutexGuard
aGuard( ::osl::Mutex::getGlobalMutex() );
178 if ( s_aKnownEvents
.empty() )
180 static sal_Int32 nEventId
= 0;
182 DESCRIBE_EVENT( "form", "XApproveActionListener", "approveAction", APPROVEACTIONPERFORMED
);
183 DESCRIBE_EVENT( "awt", "XActionListener", "actionPerformed", ACTIONPERFORMED
);
184 DESCRIBE_EVENT( "form", "XChangeListener", "changed", CHANGED
);
185 DESCRIBE_EVENT( "awt", "XTextListener", "textChanged", TEXTCHANGED
);
186 DESCRIBE_EVENT( "awt", "XItemListener", "itemStateChanged", ITEMSTATECHANGED
);
187 DESCRIBE_EVENT( "awt", "XFocusListener", "focusGained", FOCUSGAINED
);
188 DESCRIBE_EVENT( "awt", "XFocusListener", "focusLost", FOCUSLOST
);
189 DESCRIBE_EVENT( "awt", "XKeyListener", "keyPressed", KEYTYPED
);
190 DESCRIBE_EVENT( "awt", "XKeyListener", "keyReleased", KEYUP
);
191 DESCRIBE_EVENT( "awt", "XMouseListener", "mouseEntered", MOUSEENTERED
);
192 DESCRIBE_EVENT( "awt", "XMouseMotionListener", "mouseDragged", MOUSEDRAGGED
);
193 DESCRIBE_EVENT( "awt", "XMouseMotionListener", "mouseMoved", MOUSEMOVED
);
194 DESCRIBE_EVENT( "awt", "XMouseListener", "mousePressed", MOUSEPRESSED
);
195 DESCRIBE_EVENT( "awt", "XMouseListener", "mouseReleased", MOUSERELEASED
);
196 DESCRIBE_EVENT( "awt", "XMouseListener", "mouseExited", MOUSEEXITED
);
197 DESCRIBE_EVENT( "form", "XResetListener", "approveReset", APPROVERESETTED
);
198 DESCRIBE_EVENT( "form", "XResetListener", "resetted", RESETTED
);
199 DESCRIBE_EVENT( "form", "XSubmitListener", "approveSubmit", SUBMITTED
);
200 DESCRIBE_EVENT( "form", "XUpdateListener", "approveUpdate", BEFOREUPDATE
);
201 DESCRIBE_EVENT( "form", "XUpdateListener", "updated", AFTERUPDATE
);
202 DESCRIBE_EVENT( "form", "XLoadListener", "loaded", LOADED
);
203 DESCRIBE_EVENT( "form", "XLoadListener", "reloading", RELOADING
);
204 DESCRIBE_EVENT( "form", "XLoadListener", "reloaded", RELOADED
);
205 DESCRIBE_EVENT( "form", "XLoadListener", "unloading", UNLOADING
);
206 DESCRIBE_EVENT( "form", "XLoadListener", "unloaded", UNLOADED
);
207 DESCRIBE_EVENT( "form", "XConfirmDeleteListener", "confirmDelete", CONFIRMDELETE
);
208 DESCRIBE_EVENT( "sdb", "XRowSetApproveListener", "approveRowChange", APPROVEROWCHANGE
);
209 DESCRIBE_EVENT( "sdbc", "XRowSetListener", "rowChanged", ROWCHANGE
);
210 DESCRIBE_EVENT( "sdb", "XRowSetApproveListener", "approveCursorMove", POSITIONING
);
211 DESCRIBE_EVENT( "sdbc", "XRowSetListener", "cursorMoved", POSITIONED
);
212 DESCRIBE_EVENT( "form", "XDatabaseParameterListener", "approveParameter", APPROVEPARAMETER
);
213 DESCRIBE_EVENT( "sdb", "XSQLErrorListener", "errorOccured", ERROROCCURRED
);
214 DESCRIBE_EVENT( "awt", "XAdjustmentListener", "adjustmentValueChanged", ADJUSTMENTVALUECHANGED
);
218 EventMap::const_iterator pos
= s_aKnownEvents
.find( _rMethodName
);
219 if ( pos
== s_aKnownEvents
.end() )
222 _out_rDescription
= pos
->second
;
226 //....................................................................
227 OUString
lcl_getEventPropertyName( const OUString
& _rListenerClassName
, const OUString
& _rMethodName
)
229 OUStringBuffer aPropertyName
;
230 aPropertyName
.append( _rListenerClassName
);
231 aPropertyName
.append( (sal_Unicode
)';' );
232 aPropertyName
.append( _rMethodName
.getStr() );
233 return aPropertyName
.makeStringAndClear();
236 //................................................................
237 ScriptEventDescriptor
lcl_getAssignedScriptEvent( const EventDescription
& _rEvent
, const Sequence
< ScriptEventDescriptor
>& _rAllAssignedMacros
)
239 ScriptEventDescriptor aScriptEvent
;
240 // for the case there is actually no event assigned, initialize at least ListenerType and MethodName,
241 // so this ScriptEventDescriptor properly describes the given event
242 aScriptEvent
.ListenerType
= _rEvent
.sListenerClassName
;
243 aScriptEvent
.EventMethod
= _rEvent
.sListenerMethodName
;
245 const ScriptEventDescriptor
* pAssignedEvent
= _rAllAssignedMacros
.getConstArray();
246 sal_Int32
assignedEventCount( _rAllAssignedMacros
.getLength() );
247 for ( sal_Int32 assignedEvent
= 0; assignedEvent
< assignedEventCount
; ++assignedEvent
, ++pAssignedEvent
)
249 if ( ( pAssignedEvent
->ListenerType
!= _rEvent
.sListenerClassName
)
250 || ( pAssignedEvent
->EventMethod
!= _rEvent
.sListenerMethodName
)
254 if ( ( pAssignedEvent
->ScriptCode
.isEmpty() )
255 || ( pAssignedEvent
->ScriptType
.isEmpty() )
258 OSL_FAIL( "lcl_getAssignedScriptEvent: me thinks this should not happen!" );
262 aScriptEvent
= *pAssignedEvent
;
264 if ( aScriptEvent
.ScriptType
!= "StarBasic" )
267 // this is an old-style macro specification:
268 // [document|application]:Library.Module.Function
269 // we need to translate this to the new-style macro specification
270 // vnd.sun.star.script:Library.Module.Function?language=Basic&location=[document|application]
272 sal_Int32 nPrefixLen
= aScriptEvent
.ScriptCode
.indexOf( ':' );
273 OSL_ENSURE( nPrefixLen
> 0, "lcl_getAssignedScriptEvent: illegal location!" );
274 OUString sLocation
= aScriptEvent
.ScriptCode
.copy( 0, nPrefixLen
);
275 OUString sMacroPath
= aScriptEvent
.ScriptCode
.copy( nPrefixLen
+ 1 );
277 OUStringBuffer aNewStyleSpec
;
278 aNewStyleSpec
.appendAscii( "vnd.sun.star.script:" );
279 aNewStyleSpec
.append ( sMacroPath
);
280 aNewStyleSpec
.appendAscii( "?language=Basic&location=" );
281 aNewStyleSpec
.append ( sLocation
);
283 aScriptEvent
.ScriptCode
= aNewStyleSpec
.makeStringAndClear();
285 // also, this new-style spec requires the script code to be "Script" instead of "StarBasic"
286 aScriptEvent
.ScriptType
= OUString( "Script" );
291 //................................................................
292 OUString
lcl_getQualifiedKnownListenerName( const ScriptEventDescriptor
& _rFormComponentEventDescriptor
)
294 EventDescription aKnownEvent
;
295 if ( lcl_getEventDescriptionForMethod( _rFormComponentEventDescriptor
.EventMethod
, aKnownEvent
) )
296 return aKnownEvent
.sListenerClassName
;
297 OSL_FAIL( "lcl_getQualifiedKnownListenerName: unknown method name!" );
298 // somebody assigned an script to a form component event which we don't know
299 // Speaking strictly, this is not really an error - it is possible to do
300 // this programmatically -, but it should rarely happen, since it's not possible
302 return _rFormComponentEventDescriptor
.ListenerType
;
305 //................................................................
306 typedef ::std::set
< Type
, TypeLessByName
> TypeBag
;
308 //................................................................
309 void lcl_addListenerTypesFor_throw( const Reference
< XInterface
>& _rxComponent
,
310 const Reference
< XIntrospection
>& _rxIntrospection
, TypeBag
& _out_rTypes
)
312 if ( !_rxComponent
.is() )
314 OSL_PRECOND( _rxIntrospection
.is(), "lcl_addListenerTypesFor_throw: this will crash!" );
316 Reference
< XIntrospectionAccess
> xIntrospectionAccess(
317 _rxIntrospection
->inspect( makeAny( _rxComponent
) ), UNO_QUERY_THROW
);
319 Sequence
< Type
> aListeners( xIntrospectionAccess
->getSupportedListeners() );
321 ::std::copy( aListeners
.getConstArray(), aListeners
.getConstArray() + aListeners
.getLength(),
322 ::std::insert_iterator
< TypeBag
>( _out_rTypes
, _out_rTypes
.begin() ) );
325 //................................................................
326 bool operator ==( const ScriptEventDescriptor _lhs
, const ScriptEventDescriptor _rhs
)
328 return ( ( _lhs
.ListenerType
== _rhs
.ListenerType
)
329 && ( _lhs
.EventMethod
== _rhs
.EventMethod
)
330 && ( _lhs
.AddListenerParam
== _rhs
.AddListenerParam
)
331 && ( _lhs
.ScriptType
== _rhs
.ScriptType
)
332 && ( _lhs
.ScriptCode
== _rhs
.ScriptCode
)
337 //====================================================================
339 //====================================================================
340 typedef ::cppu::WeakImplHelper1
< ::com::sun::star::container::XNameReplace
342 /** a UNO component holding assigned event descriptions, for use with a SvxMacroAssignDlg
344 class EventHolder
: public EventHolder_Base
347 typedef ::boost::unordered_map
< OUString
, ScriptEventDescriptor
, OUStringHash
> EventMap
;
348 typedef ::std::map
< EventId
, EventMap::iterator
> EventMapIndexAccess
;
350 EventMap m_aEventNameAccess
;
351 EventMapIndexAccess m_aEventIndexAccess
;
356 void addEvent( EventId _nId
, const OUString
& _rEventName
, const ScriptEventDescriptor
& _rScriptEvent
);
358 /** effectively the same as getByName, but instead of converting the ScriptEventDescriptor to the weird
359 format used by the macro assignment dialog, it is returned directly
361 ScriptEventDescriptor
getNormalizedDescriptorByName( const OUString
& _rEventName
) const;
364 virtual void SAL_CALL
replaceByName( const OUString
& _rName
, const Any
& aElement
) throw (IllegalArgumentException
, NoSuchElementException
, WrappedTargetException
, RuntimeException
);
365 virtual Any SAL_CALL
getByName( const OUString
& _rName
) throw (NoSuchElementException
, WrappedTargetException
, RuntimeException
);
366 virtual Sequence
< OUString
> SAL_CALL
getElementNames( ) throw (RuntimeException
);
367 virtual ::sal_Bool SAL_CALL
hasByName( const OUString
& _rName
) throw (RuntimeException
);
368 virtual Type SAL_CALL
getElementType( ) throw (RuntimeException
);
369 virtual ::sal_Bool SAL_CALL
hasElements( ) throw (RuntimeException
);
375 ScriptEventDescriptor
impl_getDescriptor_throw( const OUString
& _rEventName
) const;
378 DBG_NAME( EventHolder
)
379 //------------------------------------------------------------------------
380 EventHolder::EventHolder()
382 DBG_CTOR( EventHolder
, NULL
);
385 //------------------------------------------------------------------------
386 EventHolder::~EventHolder()
388 m_aEventNameAccess
.clear();
389 m_aEventIndexAccess
.clear();
390 DBG_DTOR( EventHolder
, NULL
);
393 //------------------------------------------------------------------------
394 void EventHolder::addEvent( EventId _nId
, const OUString
& _rEventName
, const ScriptEventDescriptor
& _rScriptEvent
)
396 ::std::pair
< EventMap::iterator
, bool > insertionResult
=
397 m_aEventNameAccess
.insert( EventMap::value_type( _rEventName
, _rScriptEvent
) );
398 OSL_ENSURE( insertionResult
.second
, "EventHolder::addEvent: there already was a MacroURL for this event!" );
399 m_aEventIndexAccess
[ _nId
] = insertionResult
.first
;
402 //------------------------------------------------------------------------
403 ScriptEventDescriptor
EventHolder::getNormalizedDescriptorByName( const OUString
& _rEventName
) const
405 return impl_getDescriptor_throw( _rEventName
);
408 //------------------------------------------------------------------------
409 ScriptEventDescriptor
EventHolder::impl_getDescriptor_throw( const OUString
& _rEventName
) const
411 EventMap::const_iterator pos
= m_aEventNameAccess
.find( _rEventName
);
412 if ( pos
== m_aEventNameAccess
.end() )
413 throw NoSuchElementException( OUString(), *const_cast< EventHolder
* >( this ) );
417 //------------------------------------------------------------------------
418 void SAL_CALL
EventHolder::replaceByName( const OUString
& _rName
, const Any
& _rElement
) throw (IllegalArgumentException
, NoSuchElementException
, WrappedTargetException
, RuntimeException
)
420 EventMap::iterator pos
= m_aEventNameAccess
.find( _rName
);
421 if ( pos
== m_aEventNameAccess
.end() )
422 throw NoSuchElementException( OUString(), *this );
424 Sequence
< PropertyValue
> aScriptDescriptor
;
425 OSL_VERIFY( _rElement
>>= aScriptDescriptor
);
427 ::comphelper::NamedValueCollection
aExtractor( aScriptDescriptor
);
429 pos
->second
.ScriptType
= aExtractor
.getOrDefault( "EventType", OUString() );
430 pos
->second
.ScriptCode
= aExtractor
.getOrDefault( "Script", OUString() );
433 //------------------------------------------------------------------------
434 Any SAL_CALL
EventHolder::getByName( const OUString
& _rName
) throw (NoSuchElementException
, WrappedTargetException
, RuntimeException
)
436 ScriptEventDescriptor
aDescriptor( impl_getDescriptor_throw( _rName
) );
439 Sequence
< PropertyValue
> aScriptDescriptor( 2 );
440 aScriptDescriptor
[0].Name
= OUString("EventType");
441 aScriptDescriptor
[0].Value
<<= aDescriptor
.ScriptType
;
442 aScriptDescriptor
[1].Name
= OUString("Script");
443 aScriptDescriptor
[1].Value
<<= aDescriptor
.ScriptCode
;
445 return makeAny( aScriptDescriptor
);
448 //------------------------------------------------------------------------
449 Sequence
< OUString
> SAL_CALL
EventHolder::getElementNames( ) throw (RuntimeException
)
451 Sequence
< OUString
> aReturn( m_aEventIndexAccess
.size() );
452 OUString
* pReturn
= aReturn
.getArray();
454 // SvxMacroAssignDlg has a weird API: It expects a XNameReplace, means a container whose
455 // main access method is by name. In it's UI, it shows the possible events in exactly the
456 // order in which XNameAccess::getElementNames returns them.
457 // However, SvxMacroAssignDlg *also* takes an index for the initial selection, which is
458 // relative to the sequence returned by XNameAccess::getElementNames.
459 // This is IMO weird, since it mixes index access with name access, which decreases efficiency
460 // of the implementation.
461 // Well, it means we're forced to return the events in getElementNames in exactly the same as they
462 // appear in the property browser UI.
463 for ( EventMapIndexAccess::const_iterator loop
= m_aEventIndexAccess
.begin();
464 loop
!= m_aEventIndexAccess
.end();
467 *pReturn
= loop
->second
->first
;
471 //------------------------------------------------------------------------
472 sal_Bool SAL_CALL
EventHolder::hasByName( const OUString
& _rName
) throw (RuntimeException
)
474 EventMap::const_iterator pos
= m_aEventNameAccess
.find( _rName
);
475 return pos
!= m_aEventNameAccess
.end();
478 //------------------------------------------------------------------------
479 Type SAL_CALL
EventHolder::getElementType( ) throw (RuntimeException
)
481 return ::getCppuType( static_cast< Sequence
< PropertyValue
>* >( NULL
) );
484 //------------------------------------------------------------------------
485 sal_Bool SAL_CALL
EventHolder::hasElements( ) throw (RuntimeException
)
487 return !m_aEventNameAccess
.empty();
491 //====================================================================
493 //====================================================================
494 DBG_NAME( EventHandler
)
495 //--------------------------------------------------------------------
496 EventHandler::EventHandler( const Reference
< XComponentContext
>& _rxContext
)
497 :EventHandler_Base( m_aMutex
)
498 ,m_aContext( _rxContext
)
499 ,m_aPropertyListeners( m_aMutex
)
500 ,m_bEventsMapInitialized( false )
501 ,m_bIsDialogElement( false )
502 ,m_nGridColumnType( -1 )
504 DBG_CTOR( EventHandler
, NULL
);
507 //--------------------------------------------------------------------
508 EventHandler::~EventHandler()
510 DBG_DTOR( EventHandler
, NULL
);
513 //--------------------------------------------------------------------
514 OUString SAL_CALL
EventHandler::getImplementationName( ) throw (RuntimeException
)
516 return getImplementationName_static();
519 //--------------------------------------------------------------------
520 ::sal_Bool SAL_CALL
EventHandler::supportsService( const OUString
& ServiceName
) throw (RuntimeException
)
522 StlSyntaxSequence
< OUString
> aAllServices( getSupportedServiceNames() );
523 return ::std::find( aAllServices
.begin(), aAllServices
.end(), ServiceName
) != aAllServices
.end();
526 //--------------------------------------------------------------------
527 Sequence
< OUString
> SAL_CALL
EventHandler::getSupportedServiceNames( ) throw (RuntimeException
)
529 return getSupportedServiceNames_static();
532 //--------------------------------------------------------------------
533 OUString SAL_CALL
EventHandler::getImplementationName_static( ) throw (RuntimeException
)
535 return OUString( "com.sun.star.comp.extensions.EventHandler" );
538 //--------------------------------------------------------------------
539 Sequence
< OUString
> SAL_CALL
EventHandler::getSupportedServiceNames_static( ) throw (RuntimeException
)
541 Sequence
< OUString
> aSupported( 1 );
542 aSupported
[0] = OUString( "com.sun.star.form.inspection.EventHandler" );
546 //--------------------------------------------------------------------
547 Reference
< XInterface
> SAL_CALL
EventHandler::Create( const Reference
< XComponentContext
>& _rxContext
)
549 return *( new EventHandler( _rxContext
) );
552 //--------------------------------------------------------------------
553 void SAL_CALL
EventHandler::inspect( const Reference
< XInterface
>& _rxIntrospectee
) throw (RuntimeException
, NullPointerException
)
555 ::osl::MutexGuard
aGuard( m_aMutex
);
557 if ( !_rxIntrospectee
.is() )
558 throw NullPointerException();
560 m_xComponent
= Reference
< XPropertySet
>( _rxIntrospectee
, UNO_QUERY_THROW
);
562 m_bEventsMapInitialized
= false;
564 m_aEvents
.swap( aEmpty
);
566 m_bIsDialogElement
= false;
567 m_nGridColumnType
= -1;
570 Reference
< XPropertySetInfo
> xPSI( m_xComponent
->getPropertySetInfo() );
571 m_bIsDialogElement
= xPSI
.is()
572 && xPSI
->hasPropertyByName( PROPERTY_WIDTH
)
573 && xPSI
->hasPropertyByName( PROPERTY_HEIGHT
)
574 && xPSI
->hasPropertyByName( PROPERTY_POSITIONX
)
575 && xPSI
->hasPropertyByName( PROPERTY_POSITIONY
);
577 Reference
< XChild
> xAsChild( _rxIntrospectee
, UNO_QUERY
);
578 if ( xAsChild
.is() && !Reference
< XForm
>( _rxIntrospectee
, UNO_QUERY
).is() )
580 if ( FormComponentType::GRIDCONTROL
== classifyComponent( xAsChild
->getParent() ) )
582 m_nGridColumnType
= classifyComponent( _rxIntrospectee
);
586 catch( const Exception
& )
588 DBG_UNHANDLED_EXCEPTION();
592 //--------------------------------------------------------------------
593 Any SAL_CALL
EventHandler::getPropertyValue( const OUString
& _rPropertyName
) throw (UnknownPropertyException
, RuntimeException
)
595 ::osl::MutexGuard
aGuard( m_aMutex
);
597 const EventDescription
& rEvent
= impl_getEventForName_throw( _rPropertyName
);
599 Sequence
< ScriptEventDescriptor
> aEvents
;
600 impl_getComponentScriptEvents_nothrow( aEvents
);
602 sal_Int32 nEventCount
= aEvents
.getLength();
603 const ScriptEventDescriptor
* pEvents
= aEvents
.getConstArray();
605 ScriptEventDescriptor aPropertyValue
;
606 for ( sal_Int32 event
= 0; event
< nEventCount
; ++event
, ++pEvents
)
608 if ( rEvent
.sListenerClassName
== pEvents
->ListenerType
609 && rEvent
.sListenerMethodName
== pEvents
->EventMethod
612 aPropertyValue
= *pEvents
;
617 return makeAny( aPropertyValue
);
620 //--------------------------------------------------------------------
621 void SAL_CALL
EventHandler::setPropertyValue( const OUString
& _rPropertyName
, const Any
& _rValue
) throw (UnknownPropertyException
, RuntimeException
)
623 ::osl::MutexGuard
aGuard( m_aMutex
);
625 const EventDescription
& rEvent
= impl_getEventForName_throw( _rPropertyName
);
627 ScriptEventDescriptor aNewScriptEvent
;
628 OSL_VERIFY( _rValue
>>= aNewScriptEvent
);
630 ScriptEventDescriptor aOldScriptEvent
;
631 OSL_VERIFY( getPropertyValue( _rPropertyName
) >>= aOldScriptEvent
);
632 if ( aOldScriptEvent
== aNewScriptEvent
)
635 if ( m_bIsDialogElement
)
636 impl_setDialogElementScriptEvent_nothrow( aNewScriptEvent
);
638 impl_setFormComponentScriptEvent_nothrow( aNewScriptEvent
);
640 Reference
< XModifiable
> xDoc( m_aContext
.getContextValueByAsciiName( "ContextDocument" ), UNO_QUERY
);
642 xDoc
->setModified( sal_True
);
644 PropertyChangeEvent aEvent
;
645 aEvent
.Source
= m_xComponent
;
646 aEvent
.PropertyHandle
= rEvent
.nId
;
647 aEvent
.PropertyName
= _rPropertyName
;
648 aEvent
.OldValue
<<= aOldScriptEvent
;
649 aEvent
.NewValue
<<= aNewScriptEvent
;
650 m_aPropertyListeners
.notify( aEvent
, &XPropertyChangeListener::propertyChange
);
653 //--------------------------------------------------------------------
654 Any SAL_CALL
EventHandler::convertToPropertyValue( const OUString
& _rPropertyName
, const Any
& _rControlValue
) throw (UnknownPropertyException
, RuntimeException
)
656 ::osl::MutexGuard
aGuard( m_aMutex
);
658 OUString sNewScriptCode
;
659 OSL_VERIFY( _rControlValue
>>= sNewScriptCode
);
661 Sequence
< ScriptEventDescriptor
> aAllAssignedEvents
;
662 impl_getComponentScriptEvents_nothrow( aAllAssignedEvents
);
664 const EventDescription
& rEvent
= impl_getEventForName_throw( _rPropertyName
);
665 ScriptEventDescriptor aAssignedScript
= lcl_getAssignedScriptEvent( rEvent
, aAllAssignedEvents
);
667 OSL_ENSURE( sNewScriptCode
.isEmpty(), "EventHandler::convertToPropertyValue: cannot convert a non-empty display name!" );
668 // Usually, there is no possibility for the user to change the content of an event binding directly in the
669 // input field, this instead is done with the macro assignment dialog.
670 // The only exception is the user pressing "DEL" while the control has the focus, in this case, we reset the
671 // control content to an empty string. So this is the only scenario where this method is allowed to be called.
673 // Striclty, we would be able to convert the display value to a property value,
674 // using the "name (location, language)" format we used in convertToControlValue. However,
675 // there is no need for this code ...
677 aAssignedScript
.ScriptCode
= sNewScriptCode
;
678 return makeAny( aAssignedScript
);
681 //--------------------------------------------------------------------
682 Any SAL_CALL
EventHandler::convertToControlValue( const OUString
& /*_rPropertyName*/, const Any
& _rPropertyValue
, const Type
& _rControlValueType
) throw (UnknownPropertyException
, RuntimeException
)
684 ::osl::MutexGuard
aGuard( m_aMutex
);
686 ScriptEventDescriptor aScriptEvent
;
687 OSL_VERIFY( _rPropertyValue
>>= aScriptEvent
);
689 OSL_ENSURE( _rControlValueType
.getTypeClass() == TypeClass_STRING
,
690 "EventHandler::convertToControlValue: unexpected ControlValue type class!" );
691 (void)_rControlValueType
;
693 OUString
sScript( aScriptEvent
.ScriptCode
);
694 if ( !sScript
.isEmpty() )
696 // format is: "name (location, language)"
700 Reference
< XUriReferenceFactory
> xUriRefFac
= UriReferenceFactory::create( m_aContext
.getUNOContext() );
701 Reference
< XVndSunStarScriptUrlReference
> xScriptUri( xUriRefFac
->parse( sScript
), UNO_QUERY_THROW
);
703 OUStringBuffer aComposeBuffer
;
706 aComposeBuffer
.append( xScriptUri
->getName() );
709 const OUString
sLocationParamName( "location" );
710 const OUString sLocation
= xScriptUri
->getParameter( sLocationParamName
);
711 const OUString
sLangParamName( "language" );
712 const OUString sLanguage
= xScriptUri
->getParameter( sLangParamName
);
714 if ( !(sLocation
.isEmpty() && sLanguage
.isEmpty()) )
716 aComposeBuffer
.appendAscii( " (" );
719 OSL_ENSURE( !sLocation
.isEmpty(), "EventHandler::convertToControlValue: unexpected: no location!" );
720 if ( !sLocation
.isEmpty() )
722 aComposeBuffer
.append( sLocation
);
723 aComposeBuffer
.appendAscii( ", " );
727 if ( !sLanguage
.isEmpty() )
729 aComposeBuffer
.append( sLanguage
);
732 aComposeBuffer
.append( sal_Unicode( ')' ) );
735 sScript
= aComposeBuffer
.makeStringAndClear();
737 catch( const Exception
& )
739 DBG_UNHANDLED_EXCEPTION();
743 return makeAny( sScript
);
746 //--------------------------------------------------------------------
747 PropertyState SAL_CALL
EventHandler::getPropertyState( const OUString
& /*_rPropertyName*/ ) throw (UnknownPropertyException
, RuntimeException
)
749 return PropertyState_DIRECT_VALUE
;
752 //--------------------------------------------------------------------
753 void SAL_CALL
EventHandler::addPropertyChangeListener( const Reference
< XPropertyChangeListener
>& _rxListener
) throw (RuntimeException
)
755 ::osl::MutexGuard
aGuard( m_aMutex
);
756 if ( !_rxListener
.is() )
757 throw NullPointerException();
758 m_aPropertyListeners
.addListener( _rxListener
);
761 //--------------------------------------------------------------------
762 void SAL_CALL
EventHandler::removePropertyChangeListener( const Reference
< XPropertyChangeListener
>& _rxListener
) throw (RuntimeException
)
764 ::osl::MutexGuard
aGuard( m_aMutex
);
765 m_aPropertyListeners
.removeListener( _rxListener
);
768 //--------------------------------------------------------------------
769 Sequence
< Property
> SAL_CALL
EventHandler::getSupportedProperties() throw (RuntimeException
)
771 ::osl::MutexGuard
aGuard( m_aMutex
);
772 if ( !m_bEventsMapInitialized
)
774 const_cast< EventHandler
* >( this )->m_bEventsMapInitialized
= true;
777 Sequence
< Type
> aListeners
;
778 impl_getCopmonentListenerTypes_nothrow( aListeners
);
779 sal_Int32 listenerCount
= aListeners
.getLength();
781 Property aCurrentProperty
;
782 OUString sListenerClassName
;
784 // loop through all listeners and all methods, and see which we can present at the UI
785 const Type
* pListeners
= aListeners
.getConstArray();
786 for ( sal_Int32 listener
= 0; listener
< listenerCount
; ++listener
, ++pListeners
)
788 aCurrentProperty
= Property();
790 // the programmatic name of the listener, to be used as "property" name
791 sListenerClassName
= pListeners
->getTypeName();
792 OSL_ENSURE( !sListenerClassName
.isEmpty(), "EventHandler::getSupportedProperties: strange - no listener name ..." );
793 if ( sListenerClassName
.isEmpty() )
796 // loop through all methods
797 Sequence
< OUString
> aMethods( comphelper::getEventMethodsForType( *pListeners
) );
799 const OUString
* pMethods
= aMethods
.getConstArray();
800 sal_uInt32 methodCount
= aMethods
.getLength();
802 for (sal_uInt32 method
= 0 ; method
< methodCount
; ++method
, ++pMethods
)
804 EventDescription aEvent
;
805 if ( !lcl_getEventDescriptionForMethod( *pMethods
, aEvent
) )
808 if ( !impl_filterMethod_nothrow( aEvent
) )
811 const_cast< EventHandler
* >( this )->m_aEvents
.insert( EventMap::value_type(
812 lcl_getEventPropertyName( sListenerClassName
, *pMethods
), aEvent
) );
817 catch( const Exception
& )
819 DBG_UNHANDLED_EXCEPTION();
823 // sort them by ID - this is the relative ordering in the UI
824 ::std::map
< EventId
, Property
> aOrderedProperties
;
825 for ( EventMap::const_iterator loop
= m_aEvents
.begin();
826 loop
!= m_aEvents
.end();
830 aOrderedProperties
[ loop
->second
.nId
] = Property(
831 loop
->first
, loop
->second
.nId
,
832 ::getCppuType( static_cast< const OUString
* >( NULL
) ),
833 PropertyAttribute::BOUND
);
836 StlSyntaxSequence
< Property
> aReturn( aOrderedProperties
.size() );
837 ::std::transform( aOrderedProperties
.begin(), aOrderedProperties
.end(), aReturn
.begin(),
838 ::o3tl::select2nd
< ::std::map
< EventId
, Property
>::value_type
>() );
842 //--------------------------------------------------------------------
843 Sequence
< OUString
> SAL_CALL
EventHandler::getSupersededProperties( ) throw (RuntimeException
)
846 return Sequence
< OUString
>( );
849 //--------------------------------------------------------------------
850 Sequence
< OUString
> SAL_CALL
EventHandler::getActuatingProperties( ) throw (RuntimeException
)
853 return Sequence
< OUString
>( );
856 //--------------------------------------------------------------------
857 LineDescriptor SAL_CALL
EventHandler::describePropertyLine( const OUString
& _rPropertyName
,
858 const Reference
< XPropertyControlFactory
>& _rxControlFactory
)
859 throw (UnknownPropertyException
, NullPointerException
, RuntimeException
)
861 if ( !_rxControlFactory
.is() )
862 throw NullPointerException();
864 ::osl::MutexGuard
aGuard( m_aMutex
);
866 LineDescriptor aDescriptor
;
868 aDescriptor
.Control
= _rxControlFactory
->createPropertyControl( PropertyControlType::TextField
, sal_True
);
869 Reference
< XEventListener
> xControlExtender
= new PropertyControlExtender( aDescriptor
.Control
);
871 const EventDescription
& rEvent
= impl_getEventForName_throw( _rPropertyName
);
872 aDescriptor
.DisplayName
= rEvent
.sDisplayName
;
873 aDescriptor
.HelpURL
= HelpIdUrl::getHelpURL( rEvent
.sHelpId
);
874 aDescriptor
.PrimaryButtonId
= OStringToOUString(rEvent
.sUniqueBrowseId
, RTL_TEXTENCODING_UTF8
);
875 aDescriptor
.HasPrimaryButton
= sal_True
;
876 aDescriptor
.Category
= OUString( "Events" );
880 //--------------------------------------------------------------------
881 ::sal_Bool SAL_CALL
EventHandler::isComposable( const OUString
& /*_rPropertyName*/ ) throw (UnknownPropertyException
, RuntimeException
)
886 //--------------------------------------------------------------------
887 InteractiveSelectionResult SAL_CALL
EventHandler::onInteractivePropertySelection( const OUString
& _rPropertyName
, sal_Bool
/*_bPrimary*/, Any
& /*_rData*/, const Reference
< XObjectInspectorUI
>& _rxInspectorUI
) throw (UnknownPropertyException
, NullPointerException
, RuntimeException
)
889 if ( !_rxInspectorUI
.is() )
890 throw NullPointerException();
892 ::osl::MutexGuard
aGuard( m_aMutex
);
893 const EventDescription
& rForEvent
= impl_getEventForName_throw( _rPropertyName
);
895 Sequence
< ScriptEventDescriptor
> aAllAssignedEvents
;
896 impl_getComponentScriptEvents_nothrow( aAllAssignedEvents
);
898 // SvxMacroAssignDlg-compatible structure holding all event/assignments
899 ::rtl::Reference
< EventHolder
> pEventHolder( new EventHolder
);
901 for ( EventMap::const_iterator event
= m_aEvents
.begin();
902 event
!= m_aEvents
.end();
906 // the script which is assigned to the current event (if any)
907 ScriptEventDescriptor aAssignedScript
= lcl_getAssignedScriptEvent( event
->second
, aAllAssignedEvents
);
908 pEventHolder
->addEvent( event
->second
.nId
, event
->second
.sListenerMethodName
, aAssignedScript
);
911 // the initial selection in the dialog
912 Sequence
< OUString
> aNames( pEventHolder
->getElementNames() );
913 const OUString
* pChosenEvent
= ::std::find( aNames
.getConstArray(), aNames
.getConstArray() + aNames
.getLength(), rForEvent
.sListenerMethodName
);
914 sal_uInt16 nInitialSelection
= (sal_uInt16
)( pChosenEvent
- aNames
.getConstArray() );
917 SvxAbstractDialogFactory
* pFactory
= SvxAbstractDialogFactory::Create();
919 return InteractiveSelectionResult_Cancelled
;
921 ::std::auto_ptr
< VclAbstractDialog
> pDialog( pFactory
->CreateSvxMacroAssignDlg(
922 PropertyHandlerHelper::getDialogParentWindow( m_aContext
),
923 impl_getContextFrame_nothrow(),
929 if ( !pDialog
.get() )
930 return InteractiveSelectionResult_Cancelled
;
932 // DF definite problem here
933 // OK & Cancel seem to be both returning 0
934 if ( pDialog
->Execute() == RET_CANCEL
)
935 return InteractiveSelectionResult_Cancelled
;
939 for ( EventMap::const_iterator event
= m_aEvents
.begin();
940 event
!= m_aEvents
.end();
944 ScriptEventDescriptor
aScriptDescriptor( pEventHolder
->getNormalizedDescriptorByName( event
->second
.sListenerMethodName
) );
946 // set the new "property value"
948 lcl_getEventPropertyName( event
->second
.sListenerClassName
, event
->second
.sListenerMethodName
),
949 makeAny( aScriptDescriptor
)
953 catch( const Exception
& )
955 DBG_UNHANDLED_EXCEPTION();
958 return InteractiveSelectionResult_Success
;
961 //--------------------------------------------------------------------
962 void SAL_CALL
EventHandler::actuatingPropertyChanged( const OUString
& /*_rActuatingPropertyName*/, const Any
& /*_rNewValue*/, const Any
& /*_rOldValue*/, const Reference
< XObjectInspectorUI
>& /*_rxInspectorUI*/, sal_Bool
/*_bFirstTimeInit*/ ) throw (NullPointerException
, RuntimeException
)
964 OSL_FAIL( "EventHandler::actuatingPropertyChanged: no actuating properties -> no callback (well, this is how it *should* be!)" );
967 //--------------------------------------------------------------------
968 IMPLEMENT_FORWARD_XCOMPONENT( EventHandler
, EventHandler_Base
)
970 //--------------------------------------------------------------------
971 void SAL_CALL
EventHandler::disposing()
974 m_aEvents
.swap( aEmpty
);
975 m_xComponent
.clear();
978 //--------------------------------------------------------------------
979 sal_Bool SAL_CALL
EventHandler::suspend( sal_Bool
/*_bSuspend*/ ) throw (RuntimeException
)
984 //------------------------------------------------------------------------
985 Reference
< XFrame
> EventHandler::impl_getContextFrame_nothrow() const
987 Reference
< XFrame
> xContextFrame
;
991 Reference
< XModel
> xContextDocument( m_aContext
.getContextValueByAsciiName( "ContextDocument" ), UNO_QUERY_THROW
);
992 Reference
< XController
> xController( xContextDocument
->getCurrentController(), UNO_SET_THROW
);
993 xContextFrame
.set( xController
->getFrame(), UNO_SET_THROW
);
995 catch( const Exception
& )
997 DBG_UNHANDLED_EXCEPTION();
1000 return xContextFrame
;
1003 //--------------------------------------------------------------------
1004 sal_Int32
EventHandler::impl_getComponentIndexInParent_throw() const
1006 Reference
< XChild
> xChild( m_xComponent
, UNO_QUERY_THROW
);
1007 Reference
< XIndexAccess
> xParentAsIndexAccess( xChild
->getParent(), UNO_QUERY_THROW
);
1009 // get the index of the inspected object within it's parent container
1010 sal_Int32 nElements
= xParentAsIndexAccess
->getCount();
1011 for ( sal_Int32 i
=0; i
<nElements
; ++i
)
1013 Reference
< XInterface
> xElement( xParentAsIndexAccess
->getByIndex( i
), UNO_QUERY_THROW
);
1014 if ( xElement
== m_xComponent
)
1017 throw NoSuchElementException();
1020 //--------------------------------------------------------------------
1021 void EventHandler::impl_getFormComponentScriptEvents_nothrow( Sequence
< ScriptEventDescriptor
>& _out_rEvents
) const
1023 _out_rEvents
= Sequence
< ScriptEventDescriptor
>();
1026 Reference
< XChild
> xChild( m_xComponent
, UNO_QUERY_THROW
);
1027 Reference
< XEventAttacherManager
> xEventManager( xChild
->getParent(), UNO_QUERY_THROW
);
1028 _out_rEvents
= xEventManager
->getScriptEvents( impl_getComponentIndexInParent_throw() );
1030 // the form component script API has unqualified listener names, but for normalization
1031 // purpose, we want fully qualified ones
1032 ScriptEventDescriptor
* pEvents
= _out_rEvents
.getArray();
1033 ScriptEventDescriptor
* pEventsEnd
= _out_rEvents
.getArray() + _out_rEvents
.getLength();
1034 while ( pEvents
!= pEventsEnd
)
1036 pEvents
->ListenerType
= lcl_getQualifiedKnownListenerName( *pEvents
);
1040 catch( const Exception
& )
1042 DBG_UNHANDLED_EXCEPTION();
1046 //--------------------------------------------------------------------
1047 void EventHandler::impl_getCopmonentListenerTypes_nothrow( Sequence
< Type
>& _out_rTypes
) const
1049 _out_rTypes
.realloc( 0 );
1052 // we use a set to avoid duplicates
1055 Reference
< XIntrospection
> xIntrospection
= Introspection::create( m_aContext
.getUNOContext() );
1057 // --- model listeners
1058 lcl_addListenerTypesFor_throw(
1059 m_xComponent
, xIntrospection
, aListeners
);
1061 // --- "secondary component" (usually: "control" listeners)
1063 Reference
< XInterface
> xSecondaryComponent( impl_getSecondaryComponentForEventInspection_throw() );
1064 lcl_addListenerTypesFor_throw( xSecondaryComponent
, xIntrospection
, aListeners
);
1065 ::comphelper::disposeComponent( xSecondaryComponent
);
1068 // now that they're disambiguated, copy these types into our member
1069 _out_rTypes
.realloc( aListeners
.size() );
1070 ::std::copy( aListeners
.begin(), aListeners
.end(), _out_rTypes
.getArray() );
1072 catch( const Exception
& )
1074 DBG_UNHANDLED_EXCEPTION();
1078 //--------------------------------------------------------------------
1079 void EventHandler::impl_getDialogElementScriptEvents_nothrow( Sequence
< ScriptEventDescriptor
>& _out_rEvents
) const
1081 _out_rEvents
= Sequence
< ScriptEventDescriptor
>();
1084 Reference
< XScriptEventsSupplier
> xEventsSupplier( m_xComponent
, UNO_QUERY_THROW
);
1085 Reference
< XNameContainer
> xEvents( xEventsSupplier
->getEvents(), UNO_QUERY_THROW
);
1086 Sequence
< OUString
> aEventNames( xEvents
->getElementNames() );
1088 sal_Int32 nEventCount
= aEventNames
.getLength();
1089 _out_rEvents
.realloc( nEventCount
);
1091 const OUString
* pNames
= aEventNames
.getConstArray();
1092 ScriptEventDescriptor
* pDescs
= _out_rEvents
.getArray();
1094 for( sal_Int32 i
= 0 ; i
< nEventCount
; ++i
, ++pNames
, ++pDescs
)
1095 OSL_VERIFY( xEvents
->getByName( *pNames
) >>= *pDescs
);
1097 catch( const Exception
& )
1099 DBG_UNHANDLED_EXCEPTION();
1103 //--------------------------------------------------------------------
1104 Reference
< XInterface
> EventHandler::impl_getSecondaryComponentForEventInspection_throw( ) const
1106 Reference
< XInterface
> xReturn
;
1108 // if it's a form, create a form controller for the additional events
1109 Reference
< XForm
> xComponentAsForm( m_xComponent
, UNO_QUERY
);
1110 if ( xComponentAsForm
.is() )
1112 Reference
< XTabControllerModel
> xComponentAsTCModel( m_xComponent
, UNO_QUERY_THROW
);
1113 Reference
< XFormController
> xController
= FormController::create( m_aContext
.getUNOContext() );
1114 xController
->setModel( xComponentAsTCModel
);
1116 xReturn
= xController
;
1120 OUString sControlService
;
1121 OSL_VERIFY( m_xComponent
->getPropertyValue( PROPERTY_DEFAULTCONTROL
) >>= sControlService
);
1123 xReturn
= m_aContext
.createComponent( sControlService
);
1128 //--------------------------------------------------------------------
1129 const EventDescription
& EventHandler::impl_getEventForName_throw( const OUString
& _rPropertyName
) const
1131 EventMap::const_iterator pos
= m_aEvents
.find( _rPropertyName
);
1132 if ( pos
== m_aEvents
.end() )
1133 throw UnknownPropertyException();
1137 //--------------------------------------------------------------------
1140 static bool lcl_endsWith( const OUString
& _rText
, const OUString
& _rCheck
)
1142 sal_Int32 nTextLen
= _rText
.getLength();
1143 sal_Int32 nCheckLen
= _rCheck
.getLength();
1144 if ( nCheckLen
> nTextLen
)
1147 return _rText
.indexOf( _rCheck
) == ( nTextLen
- nCheckLen
);
1150 //--------------------------------------------------------------------
1151 void EventHandler::impl_setFormComponentScriptEvent_nothrow( const ScriptEventDescriptor
& _rScriptEvent
)
1155 OUString
sScriptCode( _rScriptEvent
.ScriptCode
);
1156 OUString
sScriptType( _rScriptEvent
.ScriptType
);
1157 bool bResetScript
= sScriptCode
.isEmpty();
1159 sal_Int32 nObjectIndex
= impl_getComponentIndexInParent_throw();
1160 Reference
< XChild
> xChild( m_xComponent
, UNO_QUERY_THROW
);
1161 Reference
< XEventAttacherManager
> xEventManager( xChild
->getParent(), UNO_QUERY_THROW
);
1162 Sequence
< ScriptEventDescriptor
> aEvents( xEventManager
->getScriptEvents( nObjectIndex
) );
1164 // is there already a registered script for this event?
1165 ScriptEventDescriptor
* pEvent
= aEvents
.getArray();
1166 sal_Int32 eventCount
= aEvents
.getLength(), event
= 0;
1167 for ( event
= 0; event
< eventCount
; ++event
, ++pEvent
)
1169 if ( ( pEvent
->EventMethod
== _rScriptEvent
.EventMethod
)
1170 && ( lcl_endsWith( _rScriptEvent
.ListenerType
, pEvent
->ListenerType
) )
1171 // (strange enough, the events we get from getScriptEvents are not fully qualified)
1175 if ( !bResetScript
)
1177 // set to something non-empty -> overwrite
1178 pEvent
->ScriptCode
= sScriptCode
;
1179 pEvent
->ScriptType
= sScriptType
;
1183 // set to empty -> remove from sequence
1184 ::std::copy( pEvent
+ 1, aEvents
.getArray() + eventCount
, pEvent
);
1185 aEvents
.realloc( eventCount
- 1 );
1191 if ( ( event
>= eventCount
) && !bResetScript
)
1193 // no, did not find it -> append
1194 aEvents
.realloc( eventCount
+ 1 );
1195 aEvents
[ eventCount
] = _rScriptEvent
;
1198 xEventManager
->revokeScriptEvents( nObjectIndex
);
1199 xEventManager
->registerScriptEvents( nObjectIndex
, aEvents
);
1201 PropertyHandlerHelper::setContextDocumentModified( m_aContext
);
1203 catch( const Exception
& )
1205 DBG_UNHANDLED_EXCEPTION();
1209 //--------------------------------------------------------------------
1210 void EventHandler::impl_setDialogElementScriptEvent_nothrow( const ScriptEventDescriptor
& _rScriptEvent
)
1214 OUString
sScriptCode( _rScriptEvent
.ScriptCode
);
1215 bool bResetScript
= sScriptCode
.isEmpty();
1217 Reference
< XScriptEventsSupplier
> xEventsSupplier( m_xComponent
, UNO_QUERY_THROW
);
1218 Reference
< XNameContainer
> xEvents( xEventsSupplier
->getEvents(), UNO_QUERY_THROW
);
1220 OUStringBuffer aCompleteName
;
1221 aCompleteName
.append( _rScriptEvent
.ListenerType
);
1222 aCompleteName
.appendAscii( "::" );
1223 aCompleteName
.append( _rScriptEvent
.EventMethod
);
1224 OUString
sCompleteName( aCompleteName
.makeStringAndClear() );
1226 bool bExists
= xEvents
->hasByName( sCompleteName
);
1231 xEvents
->removeByName( sCompleteName
);
1235 Any aNewValue
; aNewValue
<<= _rScriptEvent
;
1238 xEvents
->replaceByName( sCompleteName
, aNewValue
);
1240 xEvents
->insertByName( sCompleteName
, aNewValue
);
1243 catch( const Exception
& )
1245 DBG_UNHANDLED_EXCEPTION();
1249 //--------------------------------------------------------------------
1250 bool EventHandler::impl_filterMethod_nothrow( const EventDescription
& _rEvent
) const
1252 // some (control-triggered) events do not make sense for certain grid control columns. However,
1253 // our mechnism to retrieve control-triggered events does not know about this, so we do some
1254 // late filtering here.
1255 switch ( m_nGridColumnType
)
1257 case FormComponentType::COMBOBOX
:
1258 if ( UID_BRWEVT_ACTIONPERFORMED
== _rEvent
.sUniqueBrowseId
)
1261 case FormComponentType::LISTBOX
:
1262 if ( ( UID_BRWEVT_CHANGED
== _rEvent
.sUniqueBrowseId
)
1263 || ( UID_BRWEVT_ACTIONPERFORMED
== _rEvent
.sUniqueBrowseId
)
1272 //........................................................................
1274 //........................................................................
1276 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */