1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: eventhandler.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_extensions.hxx"
34 #include "eventhandler.hxx"
35 #include "extensio.hrc"
36 #include "formbrowsertools.hxx"
37 #include "formresid.hrc"
38 #include "formstrings.hxx"
39 #include "handlerhelper.hxx"
40 #include "modulepcr.hxx"
41 #include "pcrcommon.hxx"
42 #include "pcrstrings.hxx"
43 #include "propertycontrolextender.hxx"
45 /** === begin UNO includes === **/
46 #include <com/sun/star/awt/XTabControllerModel.hpp>
47 #include <com/sun/star/beans/PropertyAttribute.hpp>
48 #include <com/sun/star/beans/UnknownPropertyException.hpp>
49 #include <com/sun/star/beans/XIntrospection.hpp>
50 #include <com/sun/star/beans/XIntrospectionAccess.hpp>
51 #include <com/sun/star/container/NoSuchElementException.hpp>
52 #include <com/sun/star/container/XChild.hpp>
53 #include <com/sun/star/container/XIndexAccess.hpp>
54 #include <com/sun/star/container/XNameContainer.hpp>
55 #include <com/sun/star/container/XNameReplace.hpp>
56 #include <com/sun/star/form/XForm.hpp>
57 #include <com/sun/star/form/XFormController.hpp>
58 #include <com/sun/star/inspection/PropertyControlType.hpp>
59 #include <com/sun/star/lang/NullPointerException.hpp>
60 #include <com/sun/star/script/XEventAttacherManager.hpp>
61 #include <com/sun/star/script/XScriptEventsSupplier.hpp>
62 #include <com/sun/star/util/XModifiable.hpp>
63 #include <com/sun/star/uri/UriReferenceFactory.hpp>
64 #include <com/sun/star/uri/XVndSunStarScriptUrlReference.hpp>
65 /** === end UNO includes === **/
67 #include <comphelper/namedvaluecollection.hxx>
68 #include <comphelper/evtmethodhelper.hxx>
69 #include <comphelper/types.hxx>
70 #include <cppuhelper/implbase1.hxx>
71 #include <rtl/ref.hxx>
72 #include <rtl/ustrbuf.hxx>
73 #include <sfx2/app.hxx>
74 #include <svtools/eitem.hxx>
75 #include <svtools/itemset.hxx>
76 #include <svx/svxdlg.hxx>
77 #include <svx/svxids.hrc>
78 #include <tools/diagnose_ex.h>
83 //------------------------------------------------------------------------
84 extern "C" void SAL_CALL
createRegistryInfo_EventHandler()
86 ::pcr::OAutoRegistration
< ::pcr::EventHandler
> aAutoRegistration
;
89 //........................................................................
92 //........................................................................
94 /** === begin UNO using === **/
95 using ::com::sun::star::uno::Reference
;
96 using ::com::sun::star::uno::XComponentContext
;
97 using ::com::sun::star::beans::XPropertySet
;
98 using ::com::sun::star::uno::Any
;
99 using ::com::sun::star::uno::TypeClass_STRING
;
100 using ::com::sun::star::uno::Type
;
101 using ::com::sun::star::beans::XPropertyChangeListener
;
102 using ::com::sun::star::beans::Property
;
103 using ::com::sun::star::beans::PropertyState
;
104 using ::com::sun::star::beans::PropertyState_DIRECT_VALUE
;
105 using ::com::sun::star::uno::Sequence
;
106 using ::com::sun::star::script::ScriptEventDescriptor
;
107 using ::com::sun::star::script::XScriptEventsSupplier
;
108 using ::com::sun::star::lang::NullPointerException
;
109 using ::com::sun::star::uno::Exception
;
110 using ::com::sun::star::container::XChild
;
111 using ::com::sun::star::container::XIndexAccess
;
112 using ::com::sun::star::script::XEventAttacherManager
;
113 using ::com::sun::star::uno::UNO_QUERY
;
114 using ::com::sun::star::uno::UNO_QUERY_THROW
;
115 using ::com::sun::star::uno::XInterface
;
116 using ::com::sun::star::beans::XIntrospection
;
117 using ::com::sun::star::beans::XIntrospectionAccess
;
118 using ::com::sun::star::container::XNameContainer
;
119 using ::com::sun::star::awt::XTabControllerModel
;
120 using ::com::sun::star::form::XForm
;
121 using ::com::sun::star::form::XFormController
;
122 using ::com::sun::star::beans::UnknownPropertyException
;
123 using ::com::sun::star::uno::makeAny
;
124 using ::com::sun::star::container::NoSuchElementException
;
125 using ::com::sun::star::beans::XPropertySetInfo
;
126 using ::com::sun::star::container::XNameReplace
;
127 using ::com::sun::star::lang::IllegalArgumentException
;
128 using ::com::sun::star::lang::WrappedTargetException
;
129 using ::com::sun::star::uno::RuntimeException
;
130 using ::com::sun::star::beans::PropertyValue
;
131 using ::com::sun::star::inspection::LineDescriptor
;
132 using ::com::sun::star::inspection::XPropertyControlFactory
;
133 using ::com::sun::star::inspection::InteractiveSelectionResult
;
134 using ::com::sun::star::inspection::InteractiveSelectionResult_Cancelled
;
135 using ::com::sun::star::inspection::InteractiveSelectionResult_Success
;
136 using ::com::sun::star::inspection::XObjectInspectorUI
;
137 using ::com::sun::star::util::XModifiable
;
138 using ::com::sun::star::beans::PropertyChangeEvent
;
139 using ::com::sun::star::frame::XFrame
;
140 using ::com::sun::star::frame::XModel
;
141 using ::com::sun::star::frame::XController
;
142 using ::com::sun::star::uno::UNO_SET_THROW
;
143 using com::sun::star::uri::UriReferenceFactory
;
144 using com::sun::star::uri::XUriReferenceFactory
;
145 using com::sun::star::uri::XVndSunStarScriptUrlReference
;
146 using ::com::sun::star::lang::XEventListener
;
147 /** === end UNO using === **/
148 namespace PropertyControlType
= ::com::sun::star::inspection::PropertyControlType
;
149 namespace PropertyAttribute
= ::com::sun::star::beans::PropertyAttribute
;
151 //====================================================================
153 //====================================================================
154 EventDescription::EventDescription( EventId _nId
, const sal_Char
* _pListenerNamespaceAscii
, const sal_Char
* _pListenerClassAsciiName
,
155 const sal_Char
* _pListenerMethodAsciiName
, sal_uInt16 _nDisplayNameResId
, sal_Int32 _nHelpId
, sal_Int32 _nUniqueBrowseId
)
156 :sDisplayName( String( PcrRes( _nDisplayNameResId
) ) )
157 ,sListenerMethodName( ::rtl::OUString::createFromAscii( _pListenerMethodAsciiName
) )
159 ,nUniqueBrowseId( _nUniqueBrowseId
)
162 ::rtl::OUStringBuffer aQualifiedListenerClass
;
163 aQualifiedListenerClass
.appendAscii( "com.sun.star." );
164 aQualifiedListenerClass
.appendAscii( _pListenerNamespaceAscii
);
165 aQualifiedListenerClass
.appendAscii( "." );
166 aQualifiedListenerClass
.appendAscii( _pListenerClassAsciiName
);
167 sListenerClassName
= aQualifiedListenerClass
.makeStringAndClear();
170 //========================================================================
172 //========================================================================
175 //....................................................................
176 #define DESCRIBE_EVENT( asciinamespace, asciilistener, asciimethod, id_postfix ) \
177 s_aKnownEvents.insert( EventMap::value_type( \
178 ::rtl::OUString::createFromAscii( asciimethod ), \
179 EventDescription( ++nEventId, asciinamespace, asciilistener, asciimethod, RID_STR_EVT_##id_postfix, HID_EVT_##id_postfix, UID_BRWEVT_##id_postfix ) ) )
181 //....................................................................
182 bool lcl_getEventDescriptionForMethod( const ::rtl::OUString
& _rMethodName
, EventDescription
& _out_rDescription
)
184 static EventMap s_aKnownEvents
;
185 if ( s_aKnownEvents
.empty() )
187 ::osl::MutexGuard
aGuard( ::osl::Mutex::getGlobalMutex() );
188 if ( s_aKnownEvents
.empty() )
190 static sal_Int32 nEventId
= 0;
192 DESCRIBE_EVENT( "form", "XApproveActionListener", "approveAction", APPROVEACTIONPERFORMED
);
193 DESCRIBE_EVENT( "awt", "XActionListener", "actionPerformed", ACTIONPERFORMED
);
194 DESCRIBE_EVENT( "form", "XChangeListener", "changed", CHANGED
);
195 DESCRIBE_EVENT( "awt", "XTextListener", "textChanged", TEXTCHANGED
);
196 DESCRIBE_EVENT( "awt", "XItemListener", "itemStateChanged", ITEMSTATECHANGED
);
197 DESCRIBE_EVENT( "awt", "XFocusListener", "focusGained", FOCUSGAINED
);
198 DESCRIBE_EVENT( "awt", "XFocusListener", "focusLost", FOCUSLOST
);
199 DESCRIBE_EVENT( "awt", "XKeyListener", "keyPressed", KEYTYPED
);
200 DESCRIBE_EVENT( "awt", "XKeyListener", "keyReleased", KEYUP
);
201 DESCRIBE_EVENT( "awt", "XMouseListener", "mouseEntered", MOUSEENTERED
);
202 DESCRIBE_EVENT( "awt", "XMouseMotionListener", "mouseDragged", MOUSEDRAGGED
);
203 DESCRIBE_EVENT( "awt", "XMouseMotionListener", "mouseMoved", MOUSEMOVED
);
204 DESCRIBE_EVENT( "awt", "XMouseListener", "mousePressed", MOUSEPRESSED
);
205 DESCRIBE_EVENT( "awt", "XMouseListener", "mouseReleased", MOUSERELEASED
);
206 DESCRIBE_EVENT( "awt", "XMouseListener", "mouseExited", MOUSEEXITED
);
207 DESCRIBE_EVENT( "form", "XResetListener", "approveReset", APPROVERESETTED
);
208 DESCRIBE_EVENT( "form", "XResetListener", "resetted", RESETTED
);
209 DESCRIBE_EVENT( "form", "XSubmitListener", "approveSubmit", SUBMITTED
);
210 DESCRIBE_EVENT( "form", "XUpdateListener", "approveUpdate", BEFOREUPDATE
);
211 DESCRIBE_EVENT( "form", "XUpdateListener", "updated", AFTERUPDATE
);
212 DESCRIBE_EVENT( "form", "XLoadListener", "loaded", LOADED
);
213 DESCRIBE_EVENT( "form", "XLoadListener", "reloading", RELOADING
);
214 DESCRIBE_EVENT( "form", "XLoadListener", "reloaded", RELOADED
);
215 DESCRIBE_EVENT( "form", "XLoadListener", "unloading", UNLOADING
);
216 DESCRIBE_EVENT( "form", "XLoadListener", "unloaded", UNLOADED
);
217 DESCRIBE_EVENT( "form", "XConfirmDeleteListener", "confirmDelete", CONFIRMDELETE
);
218 DESCRIBE_EVENT( "sdb", "XRowSetApproveListener", "approveRowChange", APPROVEROWCHANGE
);
219 DESCRIBE_EVENT( "sdbc", "XRowSetListener", "rowChanged", ROWCHANGE
);
220 DESCRIBE_EVENT( "sdb", "XRowSetApproveListener", "approveCursorMove", POSITIONING
);
221 DESCRIBE_EVENT( "sdbc", "XRowSetListener", "cursorMoved", POSITIONED
);
222 DESCRIBE_EVENT( "form", "XDatabaseParameterListener", "approveParameter", APPROVEPARAMETER
);
223 DESCRIBE_EVENT( "sdb", "XSQLErrorListener", "errorOccured", ERROROCCURED
);
224 DESCRIBE_EVENT( "awt", "XAdjustmentListener", "adjustmentValueChanged", ADJUSTMENTVALUECHANGED
);
228 EventMap::const_iterator pos
= s_aKnownEvents
.find( _rMethodName
);
229 if ( pos
== s_aKnownEvents
.end() )
232 _out_rDescription
= pos
->second
;
236 //....................................................................
237 ::rtl::OUString
lcl_getEventPropertyName( const ::rtl::OUString
& _rListenerClassName
, const ::rtl::OUString
& _rMethodName
)
239 ::rtl::OUStringBuffer aPropertyName
;
240 aPropertyName
.append( _rListenerClassName
);
241 aPropertyName
.append( (sal_Unicode
)';' );
242 aPropertyName
.append( _rMethodName
.getStr() );
243 return aPropertyName
.makeStringAndClear();
246 //................................................................
247 ScriptEventDescriptor
lcl_getAssignedScriptEvent( const EventDescription
& _rEvent
, const Sequence
< ScriptEventDescriptor
>& _rAllAssignedMacros
)
249 ScriptEventDescriptor aScriptEvent
;
250 // for the case there is actually no event assigned, initialize at least ListenerType and MethodName,
251 // so this ScriptEventDescriptor properly describes the given event
252 aScriptEvent
.ListenerType
= _rEvent
.sListenerClassName
;
253 aScriptEvent
.EventMethod
= _rEvent
.sListenerMethodName
;
255 const ScriptEventDescriptor
* pAssignedEvent
= _rAllAssignedMacros
.getConstArray();
256 sal_Int32
assignedEventCount( _rAllAssignedMacros
.getLength() );
257 for ( sal_Int32 assignedEvent
= 0; assignedEvent
< assignedEventCount
; ++assignedEvent
, ++pAssignedEvent
)
259 if ( ( pAssignedEvent
->ListenerType
!= _rEvent
.sListenerClassName
)
260 || ( pAssignedEvent
->EventMethod
!= _rEvent
.sListenerMethodName
)
264 if ( ( pAssignedEvent
->ScriptCode
.getLength() == 0 )
265 || ( pAssignedEvent
->ScriptType
.getLength() == 0 )
268 DBG_ERROR( "lcl_getAssignedScriptEvent: me thinks this should not happen!" );
272 aScriptEvent
= *pAssignedEvent
;
274 if ( !aScriptEvent
.ScriptType
.equalsAscii( "StarBasic" ) )
277 // this is an old-style macro specification:
278 // [document|application]:Library.Module.Function
279 // we need to translate this to the new-style macro specification
280 // vnd.sun.star.script:Library.Module.Function?language=Basic&location=[document|application]
282 sal_Int32 nPrefixLen
= aScriptEvent
.ScriptCode
.indexOf( ':' );
283 OSL_ENSURE( nPrefixLen
> 0, "lcl_getAssignedScriptEvent: illegal location!" );
284 ::rtl::OUString sLocation
= aScriptEvent
.ScriptCode
.copy( 0, nPrefixLen
);
285 ::rtl::OUString sMacroPath
= aScriptEvent
.ScriptCode
.copy( nPrefixLen
+ 1 );
287 ::rtl::OUStringBuffer aNewStyleSpec
;
288 aNewStyleSpec
.appendAscii( "vnd.sun.star.script:" );
289 aNewStyleSpec
.append ( sMacroPath
);
290 aNewStyleSpec
.appendAscii( "?language=Basic&location=" );
291 aNewStyleSpec
.append ( sLocation
);
293 aScriptEvent
.ScriptCode
= aNewStyleSpec
.makeStringAndClear();
295 // also, this new-style spec requires the script code to be "Script" instead of "StarBasic"
296 aScriptEvent
.ScriptType
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Script" ) );
301 //................................................................
302 ::rtl::OUString
lcl_getQualifiedKnownListenerName( const ScriptEventDescriptor
& _rFormComponentEventDescriptor
)
304 EventDescription aKnownEvent
;
305 if ( lcl_getEventDescriptionForMethod( _rFormComponentEventDescriptor
.EventMethod
, aKnownEvent
) )
306 return aKnownEvent
.sListenerClassName
;
307 DBG_ERROR( "lcl_getQualifiedKnownListenerName: unknown method name!" );
308 // somebody assigned an script to a form component event which we don't know
309 // Speaking strictly, this is not really an error - it is possible to do
310 // this programmatically -, but it should rarely happen, since it's not possible
312 return _rFormComponentEventDescriptor
.ListenerType
;
315 //................................................................
316 typedef ::std::set
< Type
, TypeLessByName
> TypeBag
;
318 //................................................................
319 void lcl_addListenerTypesFor_throw( const Reference
< XInterface
>& _rxComponent
,
320 const Reference
< XIntrospection
>& _rxIntrospection
, TypeBag
& _out_rTypes
)
322 if ( !_rxComponent
.is() )
324 OSL_PRECOND( _rxIntrospection
.is(), "lcl_addListenerTypesFor_throw: this will crash!" );
326 Reference
< XIntrospectionAccess
> xIntrospectionAccess(
327 _rxIntrospection
->inspect( makeAny( _rxComponent
) ), UNO_QUERY_THROW
);
329 Sequence
< Type
> aListeners( xIntrospectionAccess
->getSupportedListeners() );
331 ::std::copy( aListeners
.getConstArray(), aListeners
.getConstArray() + aListeners
.getLength(),
332 ::std::insert_iterator
< TypeBag
>( _out_rTypes
, _out_rTypes
.begin() ) );
335 //................................................................
336 bool operator ==( const ScriptEventDescriptor _lhs
, const ScriptEventDescriptor _rhs
)
338 return ( ( _lhs
.ListenerType
== _rhs
.ListenerType
)
339 && ( _lhs
.EventMethod
== _rhs
.EventMethod
)
340 && ( _lhs
.AddListenerParam
== _rhs
.AddListenerParam
)
341 && ( _lhs
.ScriptType
== _rhs
.ScriptType
)
342 && ( _lhs
.ScriptCode
== _rhs
.ScriptCode
)
347 //====================================================================
349 //====================================================================
350 typedef ::cppu::WeakImplHelper1
< ::com::sun::star::container::XNameReplace
352 /** a UNO component holding assigned event descriptions, for use with a SvxMacroAssignDlg
354 class EventHolder
: public EventHolder_Base
357 typedef ::std::hash_map
< ::rtl::OUString
, ScriptEventDescriptor
, ::rtl::OUStringHash
> EventMap
;
358 typedef ::std::map
< EventId
, EventMap::iterator
> EventMapIndexAccess
;
360 EventMap m_aEventNameAccess
;
361 EventMapIndexAccess m_aEventIndexAccess
;
366 void addEvent( EventId _nId
, const ::rtl::OUString
& _rEventName
, const ScriptEventDescriptor
& _rScriptEvent
);
368 /** effectively the same as getByName, but instead of converting the ScriptEventDescriptor to the weird
369 format used by the macro assignment dialog, it is returned directly
371 ScriptEventDescriptor
getNormalizedDescriptorByName( const ::rtl::OUString
& _rEventName
) const;
374 virtual void SAL_CALL
replaceByName( const ::rtl::OUString
& _rName
, const Any
& aElement
) throw (IllegalArgumentException
, NoSuchElementException
, WrappedTargetException
, RuntimeException
);
375 virtual Any SAL_CALL
getByName( const ::rtl::OUString
& _rName
) throw (NoSuchElementException
, WrappedTargetException
, RuntimeException
);
376 virtual Sequence
< ::rtl::OUString
> SAL_CALL
getElementNames( ) throw (RuntimeException
);
377 virtual ::sal_Bool SAL_CALL
hasByName( const ::rtl::OUString
& _rName
) throw (RuntimeException
);
378 virtual Type SAL_CALL
getElementType( ) throw (RuntimeException
);
379 virtual ::sal_Bool SAL_CALL
hasElements( ) throw (RuntimeException
);
385 ScriptEventDescriptor
impl_getDescriptor_throw( const ::rtl::OUString
& _rEventName
) const;
388 DBG_NAME( EventHolder
)
389 //------------------------------------------------------------------------
390 EventHolder::EventHolder()
392 DBG_CTOR( EventHolder
, NULL
);
395 //------------------------------------------------------------------------
396 EventHolder::~EventHolder()
398 m_aEventNameAccess
.clear();
399 m_aEventIndexAccess
.clear();
400 DBG_DTOR( EventHolder
, NULL
);
403 //------------------------------------------------------------------------
404 void EventHolder::addEvent( EventId _nId
, const ::rtl::OUString
& _rEventName
, const ScriptEventDescriptor
& _rScriptEvent
)
406 ::std::pair
< EventMap::iterator
, bool > insertionResult
=
407 m_aEventNameAccess
.insert( EventMap::value_type( _rEventName
, _rScriptEvent
) );
408 OSL_ENSURE( insertionResult
.second
, "EventHolder::addEvent: there already was a MacroURL for this event!" );
409 m_aEventIndexAccess
[ _nId
] = insertionResult
.first
;
412 //------------------------------------------------------------------------
413 ScriptEventDescriptor
EventHolder::getNormalizedDescriptorByName( const ::rtl::OUString
& _rEventName
) const
415 return impl_getDescriptor_throw( _rEventName
);
418 //------------------------------------------------------------------------
419 ScriptEventDescriptor
EventHolder::impl_getDescriptor_throw( const ::rtl::OUString
& _rEventName
) const
421 EventMap::const_iterator pos
= m_aEventNameAccess
.find( _rEventName
);
422 if ( pos
== m_aEventNameAccess
.end() )
423 throw NoSuchElementException( ::rtl::OUString(), *const_cast< EventHolder
* >( this ) );
427 //------------------------------------------------------------------------
428 void SAL_CALL
EventHolder::replaceByName( const ::rtl::OUString
& _rName
, const Any
& _rElement
) throw (IllegalArgumentException
, NoSuchElementException
, WrappedTargetException
, RuntimeException
)
430 EventMap::iterator pos
= m_aEventNameAccess
.find( _rName
);
431 if ( pos
== m_aEventNameAccess
.end() )
432 throw NoSuchElementException( ::rtl::OUString(), *this );
434 Sequence
< PropertyValue
> aScriptDescriptor
;
435 OSL_VERIFY( _rElement
>>= aScriptDescriptor
);
437 ::comphelper::NamedValueCollection
aExtractor( aScriptDescriptor
);
439 pos
->second
.ScriptType
= aExtractor
.getOrDefault( "EventType", ::rtl::OUString() );
440 pos
->second
.ScriptCode
= aExtractor
.getOrDefault( "Script", ::rtl::OUString() );
443 //------------------------------------------------------------------------
444 Any SAL_CALL
EventHolder::getByName( const ::rtl::OUString
& _rName
) throw (NoSuchElementException
, WrappedTargetException
, RuntimeException
)
446 ScriptEventDescriptor
aDescriptor( impl_getDescriptor_throw( _rName
) );
449 Sequence
< PropertyValue
> aScriptDescriptor( 2 );
450 aScriptDescriptor
[0].Name
= ::rtl::OUString::createFromAscii( "EventType" );
451 aScriptDescriptor
[0].Value
<<= aDescriptor
.ScriptType
;
452 aScriptDescriptor
[1].Name
= ::rtl::OUString::createFromAscii( "Script" );
453 aScriptDescriptor
[1].Value
<<= aDescriptor
.ScriptCode
;
455 return makeAny( aScriptDescriptor
);
458 //------------------------------------------------------------------------
459 Sequence
< ::rtl::OUString
> SAL_CALL
EventHolder::getElementNames( ) throw (RuntimeException
)
461 Sequence
< ::rtl::OUString
> aReturn( m_aEventIndexAccess
.size() );
462 ::rtl::OUString
* pReturn
= aReturn
.getArray();
464 // SvxMacroAssignDlg has a weird API: It expects a XNameReplace, means a container whose
465 // main access method is by name. In it's UI, it shows the possible events in exactly the
466 // order in which XNameAccess::getElementNames returns them.
467 // However, SvxMacroAssignDlg *also* takes an index for the initial selection, which is
468 // relative to the sequence returned by XNameAccess::getElementNames.
469 // This is IMO weird, since it mixes index access with name access, which decreases efficiency
470 // of the implementation.
471 // Well, it means we're forced to return the events in getElementNames in exactly the same as they
472 // appear in the property browser UI.
473 for ( EventMapIndexAccess::const_iterator loop
= m_aEventIndexAccess
.begin();
474 loop
!= m_aEventIndexAccess
.end();
477 *pReturn
= loop
->second
->first
;
481 //------------------------------------------------------------------------
482 sal_Bool SAL_CALL
EventHolder::hasByName( const ::rtl::OUString
& _rName
) throw (RuntimeException
)
484 EventMap::const_iterator pos
= m_aEventNameAccess
.find( _rName
);
485 return pos
!= m_aEventNameAccess
.end();
488 //------------------------------------------------------------------------
489 Type SAL_CALL
EventHolder::getElementType( ) throw (RuntimeException
)
491 return ::getCppuType( static_cast< Sequence
< PropertyValue
>* >( NULL
) );
494 //------------------------------------------------------------------------
495 sal_Bool SAL_CALL
EventHolder::hasElements( ) throw (RuntimeException
)
497 return !m_aEventNameAccess
.empty();
501 //====================================================================
503 //====================================================================
504 DBG_NAME( EventHandler
)
505 //--------------------------------------------------------------------
506 EventHandler::EventHandler( const Reference
< XComponentContext
>& _rxContext
)
507 :EventHandler_Base( m_aMutex
)
508 ,m_aContext( _rxContext
)
509 ,m_aPropertyListeners( m_aMutex
)
510 ,m_bEventsMapInitialized( false )
511 ,m_bIsDialogElement( false )
513 DBG_CTOR( EventHandler
, NULL
);
516 //--------------------------------------------------------------------
517 EventHandler::~EventHandler()
519 DBG_DTOR( EventHandler
, NULL
);
522 //--------------------------------------------------------------------
523 ::rtl::OUString SAL_CALL
EventHandler::getImplementationName( ) throw (RuntimeException
)
525 return getImplementationName_static();
528 //--------------------------------------------------------------------
529 ::sal_Bool SAL_CALL
EventHandler::supportsService( const ::rtl::OUString
& ServiceName
) throw (RuntimeException
)
531 StlSyntaxSequence
< ::rtl::OUString
> aAllServices( getSupportedServiceNames() );
532 return ::std::find( aAllServices
.begin(), aAllServices
.end(), ServiceName
) != aAllServices
.end();
535 //--------------------------------------------------------------------
536 Sequence
< ::rtl::OUString
> SAL_CALL
EventHandler::getSupportedServiceNames( ) throw (RuntimeException
)
538 return getSupportedServiceNames_static();
541 //--------------------------------------------------------------------
542 ::rtl::OUString SAL_CALL
EventHandler::getImplementationName_static( ) throw (RuntimeException
)
544 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.extensions.EventHandler" ) );
547 //--------------------------------------------------------------------
548 Sequence
< ::rtl::OUString
> SAL_CALL
EventHandler::getSupportedServiceNames_static( ) throw (RuntimeException
)
550 Sequence
< ::rtl::OUString
> aSupported( 1 );
551 aSupported
[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.form.inspection.EventHandler" ) );
555 //--------------------------------------------------------------------
556 Reference
< XInterface
> SAL_CALL
EventHandler::Create( const Reference
< XComponentContext
>& _rxContext
)
558 return *( new EventHandler( _rxContext
) );
561 //--------------------------------------------------------------------
562 void SAL_CALL
EventHandler::inspect( const Reference
< XInterface
>& _rxIntrospectee
) throw (RuntimeException
, NullPointerException
)
564 ::osl::MutexGuard
aGuard( m_aMutex
);
566 if ( !_rxIntrospectee
.is() )
567 throw NullPointerException();
569 m_xComponent
= Reference
< XPropertySet
>( _rxIntrospectee
, UNO_QUERY_THROW
);
571 m_bEventsMapInitialized
= false;
573 m_aEvents
.swap( aEmpty
);
575 m_bIsDialogElement
= false;
578 Reference
< XPropertySetInfo
> xPSI( m_xComponent
->getPropertySetInfo() );
579 m_bIsDialogElement
= xPSI
.is()
580 && xPSI
->hasPropertyByName( PROPERTY_WIDTH
)
581 && xPSI
->hasPropertyByName( PROPERTY_HEIGHT
)
582 && xPSI
->hasPropertyByName( PROPERTY_POSITIONX
)
583 && xPSI
->hasPropertyByName( PROPERTY_POSITIONY
);
585 catch( const Exception
& )
587 OSL_ENSURE( false, "EventHandler::EventHandler: caught an exception while classifying the component!" );
591 //--------------------------------------------------------------------
592 Any SAL_CALL
EventHandler::getPropertyValue( const ::rtl::OUString
& _rPropertyName
) throw (UnknownPropertyException
, RuntimeException
)
594 ::osl::MutexGuard
aGuard( m_aMutex
);
596 const EventDescription
& rEvent
= impl_getEventForName_throw( _rPropertyName
);
598 Sequence
< ScriptEventDescriptor
> aEvents
;
599 impl_getComponentScriptEvents_nothrow( aEvents
);
601 sal_Int32 nEventCount
= aEvents
.getLength();
602 const ScriptEventDescriptor
* pEvents
= aEvents
.getConstArray();
604 ScriptEventDescriptor aPropertyValue
;
605 for ( sal_Int32 event
= 0; event
< nEventCount
; ++event
, ++pEvents
)
607 if ( rEvent
.sListenerClassName
== pEvents
->ListenerType
608 && rEvent
.sListenerMethodName
== pEvents
->EventMethod
611 aPropertyValue
= *pEvents
;
616 return makeAny( aPropertyValue
);
619 //--------------------------------------------------------------------
620 void SAL_CALL
EventHandler::setPropertyValue( const ::rtl::OUString
& _rPropertyName
, const Any
& _rValue
) throw (UnknownPropertyException
, RuntimeException
)
622 ::osl::MutexGuard
aGuard( m_aMutex
);
624 const EventDescription
& rEvent
= impl_getEventForName_throw( _rPropertyName
);
626 ScriptEventDescriptor aNewScriptEvent
;
627 OSL_VERIFY( _rValue
>>= aNewScriptEvent
);
629 ScriptEventDescriptor aOldScriptEvent
;
630 OSL_VERIFY( getPropertyValue( _rPropertyName
) >>= aOldScriptEvent
);
631 if ( aOldScriptEvent
== aNewScriptEvent
)
634 if ( m_bIsDialogElement
)
635 impl_setDialogElementScriptEvent_nothrow( aNewScriptEvent
);
637 impl_setFormComponentScriptEvent_nothrow( aNewScriptEvent
);
639 Reference
< XModifiable
> xDoc( m_aContext
.getContextValueByAsciiName( "ContextDocument" ), UNO_QUERY
);
641 xDoc
->setModified( sal_True
);
643 PropertyChangeEvent aEvent
;
644 aEvent
.Source
= m_xComponent
;
645 aEvent
.PropertyHandle
= rEvent
.nId
;
646 aEvent
.PropertyName
= _rPropertyName
;
647 aEvent
.OldValue
<<= aOldScriptEvent
;
648 aEvent
.NewValue
<<= aNewScriptEvent
;
649 m_aPropertyListeners
.notify( aEvent
, &XPropertyChangeListener::propertyChange
);
652 //--------------------------------------------------------------------
653 Any SAL_CALL
EventHandler::convertToPropertyValue( const ::rtl::OUString
& _rPropertyName
, const Any
& _rControlValue
) throw (UnknownPropertyException
, RuntimeException
)
655 ::osl::MutexGuard
aGuard( m_aMutex
);
657 ::rtl::OUString sNewScriptCode
;
658 OSL_VERIFY( _rControlValue
>>= sNewScriptCode
);
660 Sequence
< ScriptEventDescriptor
> aAllAssignedEvents
;
661 impl_getComponentScriptEvents_nothrow( aAllAssignedEvents
);
663 const EventDescription
& rEvent
= impl_getEventForName_throw( _rPropertyName
);
664 ScriptEventDescriptor aAssignedScript
= lcl_getAssignedScriptEvent( rEvent
, aAllAssignedEvents
);
666 OSL_ENSURE( !sNewScriptCode
.getLength(), "EventHandler::convertToPropertyValue: cannot convert a non-empty display name!" );
667 // Usually, there is no possibility for the user to change the content of an event binding directly in the
668 // input field, this instead is done with the macro assignment dialog.
669 // The only exception is the user pressing "DEL" while the control has the focus, in this case, we reset the
670 // control content to an empty string. So this is the only scenario where this method is allowed to be called.
672 // Striclty, we would be able to convert the display value to a property value,
673 // using the "name (location, language)" format we used in convertToControlValue. However,
674 // there is no need for this code ...
676 aAssignedScript
.ScriptCode
= sNewScriptCode
;
677 return makeAny( aAssignedScript
);
680 //--------------------------------------------------------------------
681 Any SAL_CALL
EventHandler::convertToControlValue( const ::rtl::OUString
& /*_rPropertyName*/, const Any
& _rPropertyValue
, const Type
& _rControlValueType
) throw (UnknownPropertyException
, RuntimeException
)
683 ::osl::MutexGuard
aGuard( m_aMutex
);
685 ScriptEventDescriptor aScriptEvent
;
686 OSL_VERIFY( _rPropertyValue
>>= aScriptEvent
);
688 OSL_ENSURE( _rControlValueType
.getTypeClass() == TypeClass_STRING
,
689 "EventHandler::convertToControlValue: unexpected ControlValue type class!" );
690 (void)_rControlValueType
;
692 ::rtl::OUString
sScript( aScriptEvent
.ScriptCode
);
693 if ( sScript
.getLength() )
695 // format is: "name (location, language)"
699 Reference
< XUriReferenceFactory
> xUriRefFac
= UriReferenceFactory::create( m_aContext
.getUNOContext() );
700 Reference
< XVndSunStarScriptUrlReference
> xScriptUri( xUriRefFac
->parse( sScript
), UNO_QUERY_THROW
);
702 ::rtl::OUStringBuffer aComposeBuffer
;
705 aComposeBuffer
.append( xScriptUri
->getName() );
708 const ::rtl::OUString
sLocationParamName( RTL_CONSTASCII_USTRINGPARAM( "location" ) );
709 const ::rtl::OUString sLocation
= xScriptUri
->getParameter( sLocationParamName
);
710 const ::rtl::OUString
sLangParamName( RTL_CONSTASCII_USTRINGPARAM( "language" ) );
711 const ::rtl::OUString sLanguage
= xScriptUri
->getParameter( sLangParamName
);
713 if ( sLocation
.getLength() || sLanguage
.getLength() )
715 aComposeBuffer
.appendAscii( " (" );
718 OSL_ENSURE( sLocation
.getLength(), "EventHandler::convertToControlValue: unexpected: no location!" );
719 if ( sLocation
.getLength() )
721 aComposeBuffer
.append( sLocation
);
722 aComposeBuffer
.appendAscii( ", " );
726 if ( sLanguage
.getLength() )
728 aComposeBuffer
.append( sLanguage
);
731 aComposeBuffer
.append( sal_Unicode( ')' ) );
734 sScript
= aComposeBuffer
.makeStringAndClear();
736 catch( const Exception
& )
738 DBG_UNHANDLED_EXCEPTION();
742 return makeAny( sScript
);
745 //--------------------------------------------------------------------
746 PropertyState SAL_CALL
EventHandler::getPropertyState( const ::rtl::OUString
& /*_rPropertyName*/ ) throw (UnknownPropertyException
, RuntimeException
)
748 return PropertyState_DIRECT_VALUE
;
751 //--------------------------------------------------------------------
752 void SAL_CALL
EventHandler::addPropertyChangeListener( const Reference
< XPropertyChangeListener
>& _rxListener
) throw (RuntimeException
)
754 ::osl::MutexGuard
aGuard( m_aMutex
);
755 if ( !_rxListener
.is() )
756 throw NullPointerException();
757 m_aPropertyListeners
.addListener( _rxListener
);
760 //--------------------------------------------------------------------
761 void SAL_CALL
EventHandler::removePropertyChangeListener( const Reference
< XPropertyChangeListener
>& _rxListener
) throw (RuntimeException
)
763 ::osl::MutexGuard
aGuard( m_aMutex
);
764 m_aPropertyListeners
.removeListener( _rxListener
);
767 //--------------------------------------------------------------------
768 Sequence
< Property
> SAL_CALL
EventHandler::getSupportedProperties() throw (RuntimeException
)
770 ::osl::MutexGuard
aGuard( m_aMutex
);
771 if ( !m_bEventsMapInitialized
)
773 const_cast< EventHandler
* >( this )->m_bEventsMapInitialized
= true;
776 Sequence
< Type
> aListeners
;
777 impl_getCopmonentListenerTypes_nothrow( aListeners
);
778 sal_Int32 listenerCount
= aListeners
.getLength();
780 Property aCurrentProperty
;
781 ::rtl::OUString sListenerClassName
;
783 // loop through all listeners and all methods, and see which we can present at the UI
784 const Type
* pListeners
= aListeners
.getConstArray();
785 for ( sal_Int32 listener
= 0; listener
< listenerCount
; ++listener
, ++pListeners
)
787 aCurrentProperty
= Property();
789 // the programmatic name of the listener, to be used as "property" name
790 sListenerClassName
= pListeners
->getTypeName();
791 OSL_ENSURE( sListenerClassName
.getLength(), "EventHandler::getSupportedProperties: strange - no listener name ..." );
792 if ( !sListenerClassName
.getLength() )
795 // loop through all methods
796 Sequence
< ::rtl::OUString
> aMethods( comphelper::getEventMethodsForType( *pListeners
) );
798 const ::rtl::OUString
* pMethods
= aMethods
.getConstArray();
799 sal_uInt32 methodCount
= aMethods
.getLength();
801 for (sal_uInt32 method
= 0 ; method
< methodCount
; method
++,++pMethods
)
803 EventDescription aEvent
;
804 if ( !lcl_getEventDescriptionForMethod( *pMethods
, aEvent
) )
807 const_cast< EventHandler
* >( this )->m_aEvents
.insert( EventMap::value_type(
808 lcl_getEventPropertyName( sListenerClassName
, *pMethods
), aEvent
) );
813 catch( const Exception
& )
815 DBG_ERROR( "EventHandler::getSupportedProperties: caught an exception !" );
819 // sort them by ID - this is the relative ordering in the UI
820 ::std::map
< EventId
, Property
> aOrderedProperties
;
821 for ( EventMap::const_iterator loop
= m_aEvents
.begin();
822 loop
!= m_aEvents
.end();
826 aOrderedProperties
[ loop
->second
.nId
] = Property(
827 loop
->first
, loop
->second
.nId
,
828 ::getCppuType( static_cast< const ::rtl::OUString
* >( NULL
) ),
829 PropertyAttribute::BOUND
);
832 StlSyntaxSequence
< Property
> aReturn( aOrderedProperties
.size() );
833 ::std::transform( aOrderedProperties
.begin(), aOrderedProperties
.end(), aReturn
.begin(),
834 ::std::select2nd
< ::std::map
< EventId
, Property
>::value_type
>() );
838 //--------------------------------------------------------------------
839 Sequence
< ::rtl::OUString
> SAL_CALL
EventHandler::getSupersededProperties( ) throw (RuntimeException
)
842 return Sequence
< ::rtl::OUString
>( );
845 //--------------------------------------------------------------------
846 Sequence
< ::rtl::OUString
> SAL_CALL
EventHandler::getActuatingProperties( ) throw (RuntimeException
)
849 return Sequence
< ::rtl::OUString
>( );
852 //--------------------------------------------------------------------
853 LineDescriptor SAL_CALL
EventHandler::describePropertyLine( const ::rtl::OUString
& _rPropertyName
,
854 const Reference
< XPropertyControlFactory
>& _rxControlFactory
)
855 throw (UnknownPropertyException
, NullPointerException
, RuntimeException
)
857 if ( !_rxControlFactory
.is() )
858 throw NullPointerException();
860 ::osl::MutexGuard
aGuard( m_aMutex
);
862 LineDescriptor aDescriptor
;
864 aDescriptor
.Control
= _rxControlFactory
->createPropertyControl( PropertyControlType::TextField
, sal_True
);
865 Reference
< XEventListener
> xControlExtender
= new PropertyControlExtender( aDescriptor
.Control
);
867 const EventDescription
& rEvent
= impl_getEventForName_throw( _rPropertyName
);
868 aDescriptor
.DisplayName
= rEvent
.sDisplayName
;
869 aDescriptor
.HelpURL
= HelpIdUrl::getHelpURL( rEvent
.nHelpId
);
870 aDescriptor
.PrimaryButtonId
= rEvent
.nUniqueBrowseId
;
871 aDescriptor
.HasPrimaryButton
= sal_True
;
872 aDescriptor
.Category
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Events" ) );
876 //--------------------------------------------------------------------
877 ::sal_Bool SAL_CALL
EventHandler::isComposable( const ::rtl::OUString
& /*_rPropertyName*/ ) throw (UnknownPropertyException
, RuntimeException
)
882 //--------------------------------------------------------------------
883 InteractiveSelectionResult SAL_CALL
EventHandler::onInteractivePropertySelection( const ::rtl::OUString
& _rPropertyName
, sal_Bool
/*_bPrimary*/, Any
& /*_rData*/, const Reference
< XObjectInspectorUI
>& _rxInspectorUI
) throw (UnknownPropertyException
, NullPointerException
, RuntimeException
)
885 if ( !_rxInspectorUI
.is() )
886 throw NullPointerException();
888 ::osl::MutexGuard
aGuard( m_aMutex
);
889 const EventDescription
& rForEvent
= impl_getEventForName_throw( _rPropertyName
);
891 Sequence
< ScriptEventDescriptor
> aAllAssignedEvents
;
892 impl_getComponentScriptEvents_nothrow( aAllAssignedEvents
);
894 // SvxMacroAssignDlg-compatible structure holding all event/assignments
895 ::rtl::Reference
< EventHolder
> pEventHolder( new EventHolder
);
897 for ( EventMap::const_iterator event
= m_aEvents
.begin();
898 event
!= m_aEvents
.end();
902 // the script which is assigned to the current event (if any)
903 ScriptEventDescriptor aAssignedScript
= lcl_getAssignedScriptEvent( event
->second
, aAllAssignedEvents
);
904 pEventHolder
->addEvent( event
->second
.nId
, event
->second
.sListenerMethodName
, aAssignedScript
);
907 // the inital selection in the dialog
908 Sequence
< ::rtl::OUString
> aNames( pEventHolder
->getElementNames() );
909 const ::rtl::OUString
* pChosenEvent
= ::std::find( aNames
.getConstArray(), aNames
.getConstArray() + aNames
.getLength(), rForEvent
.sListenerMethodName
);
910 sal_uInt16 nInitialSelection
= (sal_uInt16
)( pChosenEvent
- aNames
.getConstArray() );
913 SvxAbstractDialogFactory
* pFactory
= SvxAbstractDialogFactory::Create();
915 return InteractiveSelectionResult_Cancelled
;
917 ::std::auto_ptr
< VclAbstractDialog
> pDialog( pFactory
->CreateSvxMacroAssignDlg(
918 PropertyHandlerHelper::getDialogParentWindow( m_aContext
),
919 impl_getContextFrame_nothrow(),
925 if ( !pDialog
.get() )
926 return InteractiveSelectionResult_Cancelled
;
928 // DF definite problem here
929 // OK & Cancel seem to be both returning 0
930 if ( pDialog
->Execute() != 0 )
931 return InteractiveSelectionResult_Cancelled
;
935 for ( EventMap::const_iterator event
= m_aEvents
.begin();
936 event
!= m_aEvents
.end();
940 ScriptEventDescriptor
aScriptDescriptor( pEventHolder
->getNormalizedDescriptorByName( event
->second
.sListenerMethodName
) );
942 // set the new "property value"
944 lcl_getEventPropertyName( event
->second
.sListenerClassName
, event
->second
.sListenerMethodName
),
945 makeAny( aScriptDescriptor
)
949 catch( const Exception
& )
951 DBG_UNHANDLED_EXCEPTION();
954 return InteractiveSelectionResult_Success
;
957 //--------------------------------------------------------------------
958 void SAL_CALL
EventHandler::actuatingPropertyChanged( const ::rtl::OUString
& /*_rActuatingPropertyName*/, const Any
& /*_rNewValue*/, const Any
& /*_rOldValue*/, const Reference
< XObjectInspectorUI
>& /*_rxInspectorUI*/, sal_Bool
/*_bFirstTimeInit*/ ) throw (NullPointerException
, RuntimeException
)
960 DBG_ERROR( "EventHandler::actuatingPropertyChanged: no actuating properties -> no callback (well, this is how it *should* be!)" );
963 //--------------------------------------------------------------------
964 IMPLEMENT_FORWARD_XCOMPONENT( EventHandler
, EventHandler_Base
)
966 //--------------------------------------------------------------------
967 void SAL_CALL
EventHandler::disposing()
970 m_aEvents
.swap( aEmpty
);
971 m_xComponent
.clear();
974 //--------------------------------------------------------------------
975 sal_Bool SAL_CALL
EventHandler::suspend( sal_Bool
/*_bSuspend*/ ) throw (RuntimeException
)
980 //------------------------------------------------------------------------
981 Reference
< XFrame
> EventHandler::impl_getContextFrame_nothrow() const
983 Reference
< XFrame
> xContextFrame
;
987 Reference
< XModel
> xContextDocument( m_aContext
.getContextValueByAsciiName( "ContextDocument" ), UNO_QUERY_THROW
);
988 Reference
< XController
> xController( xContextDocument
->getCurrentController(), UNO_SET_THROW
);
989 xContextFrame
.set( xController
->getFrame(), UNO_SET_THROW
);
991 catch( const Exception
& )
993 DBG_UNHANDLED_EXCEPTION();
996 return xContextFrame
;
999 //--------------------------------------------------------------------
1000 sal_Int32
EventHandler::impl_getComponentIndexInParent_throw() const
1002 Reference
< XChild
> xChild( m_xComponent
, UNO_QUERY_THROW
);
1003 Reference
< XIndexAccess
> xParentAsIndexAccess( xChild
->getParent(), UNO_QUERY_THROW
);
1005 // get the index of the inspected object within it's parent container
1006 sal_Int32 nElements
= xParentAsIndexAccess
->getCount();
1007 for ( sal_Int32 i
=0; i
<nElements
; ++i
)
1009 Reference
< XInterface
> xElement( xParentAsIndexAccess
->getByIndex( i
), UNO_QUERY_THROW
);
1010 if ( xElement
== m_xComponent
)
1013 throw NoSuchElementException();
1016 //--------------------------------------------------------------------
1017 void EventHandler::impl_getFormComponentScriptEvents_nothrow( Sequence
< ScriptEventDescriptor
>& _out_rEvents
) const
1019 _out_rEvents
= Sequence
< ScriptEventDescriptor
>();
1022 Reference
< XChild
> xChild( m_xComponent
, UNO_QUERY_THROW
);
1023 Reference
< XEventAttacherManager
> xEventManager( xChild
->getParent(), UNO_QUERY_THROW
);
1024 _out_rEvents
= xEventManager
->getScriptEvents( impl_getComponentIndexInParent_throw() );
1026 // the form component script API has unqualified listener names, but for normalization
1027 // purpose, we want fully qualified ones
1028 ScriptEventDescriptor
* pEvents
= _out_rEvents
.getArray();
1029 ScriptEventDescriptor
* pEventsEnd
= _out_rEvents
.getArray() + _out_rEvents
.getLength();
1030 while ( pEvents
!= pEventsEnd
)
1032 pEvents
->ListenerType
= lcl_getQualifiedKnownListenerName( *pEvents
);
1036 catch( const Exception
& )
1038 OSL_ENSURE( false, "EventHandler::impl_getFormComponentScriptEvents_nothrow: caught an exception!" );
1042 //--------------------------------------------------------------------
1043 void EventHandler::impl_getCopmonentListenerTypes_nothrow( Sequence
< Type
>& _out_rTypes
) const
1045 _out_rTypes
.realloc( 0 );
1048 // we use a set to avoid duplicates
1051 Reference
< XIntrospection
> xIntrospection( m_aContext
.createComponent( "com.sun.star.beans.Introspection" ), UNO_QUERY_THROW
);
1053 // --- model listeners
1054 lcl_addListenerTypesFor_throw(
1055 m_xComponent
, xIntrospection
, aListeners
);
1057 // --- "secondary component" (usually: "control" listeners)
1059 Reference
< XInterface
> xSecondaryComponent( impl_getSecondaryComponentForEventInspection_throw() );
1060 lcl_addListenerTypesFor_throw( xSecondaryComponent
, xIntrospection
, aListeners
);
1061 ::comphelper::disposeComponent( xSecondaryComponent
);
1064 // now that they're disambiguated, copy these types into our member
1065 _out_rTypes
.realloc( aListeners
.size() );
1066 ::std::copy( aListeners
.begin(), aListeners
.end(), _out_rTypes
.getArray() );
1068 catch( const Exception
& )
1070 OSL_ENSURE( false, "EventHandler::impl_getCopmonentListenerTypes_nothrow: caught an exception!" );
1074 //--------------------------------------------------------------------
1075 void EventHandler::impl_getDialogElementScriptEvents_nothrow( Sequence
< ScriptEventDescriptor
>& _out_rEvents
) const
1077 _out_rEvents
= Sequence
< ScriptEventDescriptor
>();
1080 Reference
< XScriptEventsSupplier
> xEventsSupplier( m_xComponent
, UNO_QUERY_THROW
);
1081 Reference
< XNameContainer
> xEvents( xEventsSupplier
->getEvents(), UNO_QUERY_THROW
);
1082 Sequence
< ::rtl::OUString
> aEventNames( xEvents
->getElementNames() );
1084 sal_Int32 nEventCount
= aEventNames
.getLength();
1085 _out_rEvents
.realloc( nEventCount
);
1087 const ::rtl::OUString
* pNames
= aEventNames
.getConstArray();
1088 ScriptEventDescriptor
* pDescs
= _out_rEvents
.getArray();
1090 for( sal_Int32 i
= 0 ; i
< nEventCount
; ++i
, ++pNames
, ++pDescs
)
1091 OSL_VERIFY( xEvents
->getByName( *pNames
) >>= *pDescs
);
1093 catch( const Exception
& )
1095 OSL_ENSURE( false, "EventHandler::impl_getDialogElementScriptEvents_nothrow: caught an exception!" );
1099 //--------------------------------------------------------------------
1100 Reference
< XInterface
> EventHandler::impl_getSecondaryComponentForEventInspection_throw( ) const
1102 Reference
< XInterface
> xReturn
;
1104 // if it's a form, create a form controller for the additional events
1105 Reference
< XForm
> xComponentAsForm( m_xComponent
, UNO_QUERY
);
1106 if ( xComponentAsForm
.is() )
1108 Reference
< XTabControllerModel
> xComponentAsTCModel( m_xComponent
, UNO_QUERY_THROW
);
1109 Reference
< XFormController
> xController(
1110 m_aContext
.createComponent( (const rtl::OUString
&)SERVICE_FORMCONTROLLER
), UNO_QUERY_THROW
);
1111 xController
->setModel( xComponentAsTCModel
);
1113 xReturn
= xController
.get();
1117 ::rtl::OUString sControlService
;
1118 OSL_VERIFY( m_xComponent
->getPropertyValue( PROPERTY_DEFAULTCONTROL
) >>= sControlService
);
1120 xReturn
= m_aContext
.createComponent( sControlService
);
1125 //--------------------------------------------------------------------
1126 const EventDescription
& EventHandler::impl_getEventForName_throw( const ::rtl::OUString
& _rPropertyName
) const
1128 EventMap::const_iterator pos
= m_aEvents
.find( _rPropertyName
);
1129 if ( pos
== m_aEvents
.end() )
1130 throw UnknownPropertyException();
1134 //--------------------------------------------------------------------
1137 static bool lcl_endsWith( const ::rtl::OUString
& _rText
, const ::rtl::OUString
& _rCheck
)
1139 sal_Int32 nTextLen
= _rText
.getLength();
1140 sal_Int32 nCheckLen
= _rCheck
.getLength();
1141 if ( nCheckLen
> nTextLen
)
1144 return _rText
.indexOf( _rCheck
) == ( nTextLen
- nCheckLen
);
1147 //--------------------------------------------------------------------
1148 void EventHandler::impl_setFormComponentScriptEvent_nothrow( const ScriptEventDescriptor
& _rScriptEvent
)
1152 ::rtl::OUString
sScriptCode( _rScriptEvent
.ScriptCode
);
1153 ::rtl::OUString
sScriptType( _rScriptEvent
.ScriptType
);
1154 bool bResetScript
= ( sScriptCode
.getLength() == 0 );
1156 sal_Int32 nObjectIndex
= impl_getComponentIndexInParent_throw();
1157 Reference
< XChild
> xChild( m_xComponent
, UNO_QUERY_THROW
);
1158 Reference
< XEventAttacherManager
> xEventManager( xChild
->getParent(), UNO_QUERY_THROW
);
1159 Sequence
< ScriptEventDescriptor
> aEvents( xEventManager
->getScriptEvents( nObjectIndex
) );
1161 // is there already a registered script for this event?
1162 ScriptEventDescriptor
* pEvent
= aEvents
.getArray();
1163 sal_Int32 eventCount
= aEvents
.getLength(), event
= 0;
1164 for ( event
= 0; event
< eventCount
; ++event
, ++pEvent
)
1166 if ( ( pEvent
->EventMethod
== _rScriptEvent
.EventMethod
)
1167 && ( lcl_endsWith( _rScriptEvent
.ListenerType
, pEvent
->ListenerType
) )
1168 // (strange enough, the events we get from getScriptEvents are not fully qualified)
1172 if ( !bResetScript
)
1174 // set to something non-empty -> overwrite
1175 pEvent
->ScriptCode
= sScriptCode
;
1176 pEvent
->ScriptType
= sScriptType
;
1180 // set to empty -> remove from sequence
1181 ::std::copy( pEvent
+ 1, aEvents
.getArray() + eventCount
, pEvent
);
1182 aEvents
.realloc( eventCount
- 1 );
1188 if ( ( event
>= eventCount
) && !bResetScript
)
1190 // no, did not find it -> append
1191 aEvents
.realloc( eventCount
+ 1 );
1192 aEvents
[ eventCount
] = _rScriptEvent
;
1195 xEventManager
->revokeScriptEvents( nObjectIndex
);
1196 xEventManager
->registerScriptEvents( nObjectIndex
, aEvents
);
1198 PropertyHandlerHelper::setContextDocumentModified( m_aContext
);
1200 catch( const Exception
& )
1202 OSL_ENSURE( false, "EventHandler::impl_setFormComponentScriptEvent_nothrow: caught an exception!" );
1206 //--------------------------------------------------------------------
1207 void EventHandler::impl_setDialogElementScriptEvent_nothrow( const ScriptEventDescriptor
& _rScriptEvent
)
1211 ::rtl::OUString
sScriptCode( _rScriptEvent
.ScriptCode
);
1212 bool bResetScript
= ( sScriptCode
.getLength() == 0 );
1214 Reference
< XScriptEventsSupplier
> xEventsSupplier( m_xComponent
, UNO_QUERY_THROW
);
1215 Reference
< XNameContainer
> xEvents( xEventsSupplier
->getEvents(), UNO_QUERY_THROW
);
1217 ::rtl::OUStringBuffer aCompleteName
;
1218 aCompleteName
.append( _rScriptEvent
.ListenerType
);
1219 aCompleteName
.appendAscii( "::" );
1220 aCompleteName
.append( _rScriptEvent
.EventMethod
);
1221 ::rtl::OUString
sCompleteName( aCompleteName
.makeStringAndClear() );
1223 bool bExists
= xEvents
->hasByName( sCompleteName
);
1228 xEvents
->removeByName( sCompleteName
);
1232 Any aNewValue
; aNewValue
<<= _rScriptEvent
;
1235 xEvents
->replaceByName( sCompleteName
, aNewValue
);
1237 xEvents
->insertByName( sCompleteName
, aNewValue
);
1240 catch( const Exception
& )
1242 DBG_UNHANDLED_EXCEPTION();
1246 //........................................................................
1248 //........................................................................