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/FormComponentType.hpp>
57 #include <com/sun/star/form/XForm.hpp>
58 #include <com/sun/star/form/XFormController.hpp>
59 #include <com/sun/star/inspection/PropertyControlType.hpp>
60 #include <com/sun/star/lang/NullPointerException.hpp>
61 #include <com/sun/star/script/XEventAttacherManager.hpp>
62 #include <com/sun/star/script/XScriptEventsSupplier.hpp>
63 #include <com/sun/star/util/XModifiable.hpp>
64 #include <com/sun/star/uri/UriReferenceFactory.hpp>
65 #include <com/sun/star/uri/XVndSunStarScriptUrlReference.hpp>
66 /** === end UNO includes === **/
68 #include <comphelper/namedvaluecollection.hxx>
69 #include <comphelper/evtmethodhelper.hxx>
70 #include <comphelper/types.hxx>
71 #include <cppuhelper/implbase1.hxx>
72 #include <rtl/ref.hxx>
73 #include <rtl/ustrbuf.hxx>
74 #include <sfx2/app.hxx>
75 #include <svtools/eitem.hxx>
76 #include <svtools/itemset.hxx>
77 #include <svx/svxdlg.hxx>
78 #include <svx/svxids.hrc>
79 #include <tools/diagnose_ex.h>
84 //------------------------------------------------------------------------
85 extern "C" void SAL_CALL
createRegistryInfo_EventHandler()
87 ::pcr::OAutoRegistration
< ::pcr::EventHandler
> aAutoRegistration
;
90 //........................................................................
93 //........................................................................
95 /** === begin UNO using === **/
96 using ::com::sun::star::uno::Reference
;
97 using ::com::sun::star::uno::XComponentContext
;
98 using ::com::sun::star::beans::XPropertySet
;
99 using ::com::sun::star::uno::Any
;
100 using ::com::sun::star::uno::TypeClass_STRING
;
101 using ::com::sun::star::uno::Type
;
102 using ::com::sun::star::beans::XPropertyChangeListener
;
103 using ::com::sun::star::beans::Property
;
104 using ::com::sun::star::beans::PropertyState
;
105 using ::com::sun::star::beans::PropertyState_DIRECT_VALUE
;
106 using ::com::sun::star::uno::Sequence
;
107 using ::com::sun::star::script::ScriptEventDescriptor
;
108 using ::com::sun::star::script::XScriptEventsSupplier
;
109 using ::com::sun::star::lang::NullPointerException
;
110 using ::com::sun::star::uno::Exception
;
111 using ::com::sun::star::container::XChild
;
112 using ::com::sun::star::container::XIndexAccess
;
113 using ::com::sun::star::script::XEventAttacherManager
;
114 using ::com::sun::star::uno::UNO_QUERY
;
115 using ::com::sun::star::uno::UNO_QUERY_THROW
;
116 using ::com::sun::star::uno::XInterface
;
117 using ::com::sun::star::beans::XIntrospection
;
118 using ::com::sun::star::beans::XIntrospectionAccess
;
119 using ::com::sun::star::container::XNameContainer
;
120 using ::com::sun::star::awt::XTabControllerModel
;
121 using ::com::sun::star::form::XForm
;
122 using ::com::sun::star::form::XFormController
;
123 using ::com::sun::star::beans::UnknownPropertyException
;
124 using ::com::sun::star::uno::makeAny
;
125 using ::com::sun::star::container::NoSuchElementException
;
126 using ::com::sun::star::beans::XPropertySetInfo
;
127 using ::com::sun::star::container::XNameReplace
;
128 using ::com::sun::star::lang::IllegalArgumentException
;
129 using ::com::sun::star::lang::WrappedTargetException
;
130 using ::com::sun::star::uno::RuntimeException
;
131 using ::com::sun::star::beans::PropertyValue
;
132 using ::com::sun::star::inspection::LineDescriptor
;
133 using ::com::sun::star::inspection::XPropertyControlFactory
;
134 using ::com::sun::star::inspection::InteractiveSelectionResult
;
135 using ::com::sun::star::inspection::InteractiveSelectionResult_Cancelled
;
136 using ::com::sun::star::inspection::InteractiveSelectionResult_Success
;
137 using ::com::sun::star::inspection::XObjectInspectorUI
;
138 using ::com::sun::star::util::XModifiable
;
139 using ::com::sun::star::beans::PropertyChangeEvent
;
140 using ::com::sun::star::frame::XFrame
;
141 using ::com::sun::star::frame::XModel
;
142 using ::com::sun::star::frame::XController
;
143 using ::com::sun::star::uno::UNO_SET_THROW
;
144 using com::sun::star::uri::UriReferenceFactory
;
145 using com::sun::star::uri::XUriReferenceFactory
;
146 using com::sun::star::uri::XVndSunStarScriptUrlReference
;
147 using ::com::sun::star::lang::XEventListener
;
148 /** === end UNO using === **/
149 namespace PropertyControlType
= ::com::sun::star::inspection::PropertyControlType
;
150 namespace PropertyAttribute
= ::com::sun::star::beans::PropertyAttribute
;
151 namespace FormComponentType
= ::com::sun::star::form::FormComponentType
;
153 //====================================================================
155 //====================================================================
156 EventDescription::EventDescription( EventId _nId
, const sal_Char
* _pListenerNamespaceAscii
, const sal_Char
* _pListenerClassAsciiName
,
157 const sal_Char
* _pListenerMethodAsciiName
, sal_uInt16 _nDisplayNameResId
, sal_Int32 _nHelpId
, sal_Int32 _nUniqueBrowseId
)
158 :sDisplayName( String( PcrRes( _nDisplayNameResId
) ) )
159 ,sListenerMethodName( ::rtl::OUString::createFromAscii( _pListenerMethodAsciiName
) )
161 ,nUniqueBrowseId( _nUniqueBrowseId
)
164 ::rtl::OUStringBuffer aQualifiedListenerClass
;
165 aQualifiedListenerClass
.appendAscii( "com.sun.star." );
166 aQualifiedListenerClass
.appendAscii( _pListenerNamespaceAscii
);
167 aQualifiedListenerClass
.appendAscii( "." );
168 aQualifiedListenerClass
.appendAscii( _pListenerClassAsciiName
);
169 sListenerClassName
= aQualifiedListenerClass
.makeStringAndClear();
172 //========================================================================
174 //========================================================================
177 //....................................................................
178 #define DESCRIBE_EVENT( asciinamespace, asciilistener, asciimethod, id_postfix ) \
179 s_aKnownEvents.insert( EventMap::value_type( \
180 ::rtl::OUString::createFromAscii( asciimethod ), \
181 EventDescription( ++nEventId, asciinamespace, asciilistener, asciimethod, RID_STR_EVT_##id_postfix, HID_EVT_##id_postfix, UID_BRWEVT_##id_postfix ) ) )
183 //....................................................................
184 bool lcl_getEventDescriptionForMethod( const ::rtl::OUString
& _rMethodName
, EventDescription
& _out_rDescription
)
186 static EventMap s_aKnownEvents
;
187 if ( s_aKnownEvents
.empty() )
189 ::osl::MutexGuard
aGuard( ::osl::Mutex::getGlobalMutex() );
190 if ( s_aKnownEvents
.empty() )
192 static sal_Int32 nEventId
= 0;
194 DESCRIBE_EVENT( "form", "XApproveActionListener", "approveAction", APPROVEACTIONPERFORMED
);
195 DESCRIBE_EVENT( "awt", "XActionListener", "actionPerformed", ACTIONPERFORMED
);
196 DESCRIBE_EVENT( "form", "XChangeListener", "changed", CHANGED
);
197 DESCRIBE_EVENT( "awt", "XTextListener", "textChanged", TEXTCHANGED
);
198 DESCRIBE_EVENT( "awt", "XItemListener", "itemStateChanged", ITEMSTATECHANGED
);
199 DESCRIBE_EVENT( "awt", "XFocusListener", "focusGained", FOCUSGAINED
);
200 DESCRIBE_EVENT( "awt", "XFocusListener", "focusLost", FOCUSLOST
);
201 DESCRIBE_EVENT( "awt", "XKeyListener", "keyPressed", KEYTYPED
);
202 DESCRIBE_EVENT( "awt", "XKeyListener", "keyReleased", KEYUP
);
203 DESCRIBE_EVENT( "awt", "XMouseListener", "mouseEntered", MOUSEENTERED
);
204 DESCRIBE_EVENT( "awt", "XMouseMotionListener", "mouseDragged", MOUSEDRAGGED
);
205 DESCRIBE_EVENT( "awt", "XMouseMotionListener", "mouseMoved", MOUSEMOVED
);
206 DESCRIBE_EVENT( "awt", "XMouseListener", "mousePressed", MOUSEPRESSED
);
207 DESCRIBE_EVENT( "awt", "XMouseListener", "mouseReleased", MOUSERELEASED
);
208 DESCRIBE_EVENT( "awt", "XMouseListener", "mouseExited", MOUSEEXITED
);
209 DESCRIBE_EVENT( "form", "XResetListener", "approveReset", APPROVERESETTED
);
210 DESCRIBE_EVENT( "form", "XResetListener", "resetted", RESETTED
);
211 DESCRIBE_EVENT( "form", "XSubmitListener", "approveSubmit", SUBMITTED
);
212 DESCRIBE_EVENT( "form", "XUpdateListener", "approveUpdate", BEFOREUPDATE
);
213 DESCRIBE_EVENT( "form", "XUpdateListener", "updated", AFTERUPDATE
);
214 DESCRIBE_EVENT( "form", "XLoadListener", "loaded", LOADED
);
215 DESCRIBE_EVENT( "form", "XLoadListener", "reloading", RELOADING
);
216 DESCRIBE_EVENT( "form", "XLoadListener", "reloaded", RELOADED
);
217 DESCRIBE_EVENT( "form", "XLoadListener", "unloading", UNLOADING
);
218 DESCRIBE_EVENT( "form", "XLoadListener", "unloaded", UNLOADED
);
219 DESCRIBE_EVENT( "form", "XConfirmDeleteListener", "confirmDelete", CONFIRMDELETE
);
220 DESCRIBE_EVENT( "sdb", "XRowSetApproveListener", "approveRowChange", APPROVEROWCHANGE
);
221 DESCRIBE_EVENT( "sdbc", "XRowSetListener", "rowChanged", ROWCHANGE
);
222 DESCRIBE_EVENT( "sdb", "XRowSetApproveListener", "approveCursorMove", POSITIONING
);
223 DESCRIBE_EVENT( "sdbc", "XRowSetListener", "cursorMoved", POSITIONED
);
224 DESCRIBE_EVENT( "form", "XDatabaseParameterListener", "approveParameter", APPROVEPARAMETER
);
225 DESCRIBE_EVENT( "sdb", "XSQLErrorListener", "errorOccured", ERROROCCURED
);
226 DESCRIBE_EVENT( "awt", "XAdjustmentListener", "adjustmentValueChanged", ADJUSTMENTVALUECHANGED
);
230 EventMap::const_iterator pos
= s_aKnownEvents
.find( _rMethodName
);
231 if ( pos
== s_aKnownEvents
.end() )
234 _out_rDescription
= pos
->second
;
238 //....................................................................
239 ::rtl::OUString
lcl_getEventPropertyName( const ::rtl::OUString
& _rListenerClassName
, const ::rtl::OUString
& _rMethodName
)
241 ::rtl::OUStringBuffer aPropertyName
;
242 aPropertyName
.append( _rListenerClassName
);
243 aPropertyName
.append( (sal_Unicode
)';' );
244 aPropertyName
.append( _rMethodName
.getStr() );
245 return aPropertyName
.makeStringAndClear();
248 //................................................................
249 ScriptEventDescriptor
lcl_getAssignedScriptEvent( const EventDescription
& _rEvent
, const Sequence
< ScriptEventDescriptor
>& _rAllAssignedMacros
)
251 ScriptEventDescriptor aScriptEvent
;
252 // for the case there is actually no event assigned, initialize at least ListenerType and MethodName,
253 // so this ScriptEventDescriptor properly describes the given event
254 aScriptEvent
.ListenerType
= _rEvent
.sListenerClassName
;
255 aScriptEvent
.EventMethod
= _rEvent
.sListenerMethodName
;
257 const ScriptEventDescriptor
* pAssignedEvent
= _rAllAssignedMacros
.getConstArray();
258 sal_Int32
assignedEventCount( _rAllAssignedMacros
.getLength() );
259 for ( sal_Int32 assignedEvent
= 0; assignedEvent
< assignedEventCount
; ++assignedEvent
, ++pAssignedEvent
)
261 if ( ( pAssignedEvent
->ListenerType
!= _rEvent
.sListenerClassName
)
262 || ( pAssignedEvent
->EventMethod
!= _rEvent
.sListenerMethodName
)
266 if ( ( pAssignedEvent
->ScriptCode
.getLength() == 0 )
267 || ( pAssignedEvent
->ScriptType
.getLength() == 0 )
270 DBG_ERROR( "lcl_getAssignedScriptEvent: me thinks this should not happen!" );
274 aScriptEvent
= *pAssignedEvent
;
276 if ( !aScriptEvent
.ScriptType
.equalsAscii( "StarBasic" ) )
279 // this is an old-style macro specification:
280 // [document|application]:Library.Module.Function
281 // we need to translate this to the new-style macro specification
282 // vnd.sun.star.script:Library.Module.Function?language=Basic&location=[document|application]
284 sal_Int32 nPrefixLen
= aScriptEvent
.ScriptCode
.indexOf( ':' );
285 OSL_ENSURE( nPrefixLen
> 0, "lcl_getAssignedScriptEvent: illegal location!" );
286 ::rtl::OUString sLocation
= aScriptEvent
.ScriptCode
.copy( 0, nPrefixLen
);
287 ::rtl::OUString sMacroPath
= aScriptEvent
.ScriptCode
.copy( nPrefixLen
+ 1 );
289 ::rtl::OUStringBuffer aNewStyleSpec
;
290 aNewStyleSpec
.appendAscii( "vnd.sun.star.script:" );
291 aNewStyleSpec
.append ( sMacroPath
);
292 aNewStyleSpec
.appendAscii( "?language=Basic&location=" );
293 aNewStyleSpec
.append ( sLocation
);
295 aScriptEvent
.ScriptCode
= aNewStyleSpec
.makeStringAndClear();
297 // also, this new-style spec requires the script code to be "Script" instead of "StarBasic"
298 aScriptEvent
.ScriptType
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Script" ) );
303 //................................................................
304 ::rtl::OUString
lcl_getQualifiedKnownListenerName( const ScriptEventDescriptor
& _rFormComponentEventDescriptor
)
306 EventDescription aKnownEvent
;
307 if ( lcl_getEventDescriptionForMethod( _rFormComponentEventDescriptor
.EventMethod
, aKnownEvent
) )
308 return aKnownEvent
.sListenerClassName
;
309 DBG_ERROR( "lcl_getQualifiedKnownListenerName: unknown method name!" );
310 // somebody assigned an script to a form component event which we don't know
311 // Speaking strictly, this is not really an error - it is possible to do
312 // this programmatically -, but it should rarely happen, since it's not possible
314 return _rFormComponentEventDescriptor
.ListenerType
;
317 //................................................................
318 typedef ::std::set
< Type
, TypeLessByName
> TypeBag
;
320 //................................................................
321 void lcl_addListenerTypesFor_throw( const Reference
< XInterface
>& _rxComponent
,
322 const Reference
< XIntrospection
>& _rxIntrospection
, TypeBag
& _out_rTypes
)
324 if ( !_rxComponent
.is() )
326 OSL_PRECOND( _rxIntrospection
.is(), "lcl_addListenerTypesFor_throw: this will crash!" );
328 Reference
< XIntrospectionAccess
> xIntrospectionAccess(
329 _rxIntrospection
->inspect( makeAny( _rxComponent
) ), UNO_QUERY_THROW
);
331 Sequence
< Type
> aListeners( xIntrospectionAccess
->getSupportedListeners() );
333 ::std::copy( aListeners
.getConstArray(), aListeners
.getConstArray() + aListeners
.getLength(),
334 ::std::insert_iterator
< TypeBag
>( _out_rTypes
, _out_rTypes
.begin() ) );
337 //................................................................
338 bool operator ==( const ScriptEventDescriptor _lhs
, const ScriptEventDescriptor _rhs
)
340 return ( ( _lhs
.ListenerType
== _rhs
.ListenerType
)
341 && ( _lhs
.EventMethod
== _rhs
.EventMethod
)
342 && ( _lhs
.AddListenerParam
== _rhs
.AddListenerParam
)
343 && ( _lhs
.ScriptType
== _rhs
.ScriptType
)
344 && ( _lhs
.ScriptCode
== _rhs
.ScriptCode
)
349 //====================================================================
351 //====================================================================
352 typedef ::cppu::WeakImplHelper1
< ::com::sun::star::container::XNameReplace
354 /** a UNO component holding assigned event descriptions, for use with a SvxMacroAssignDlg
356 class EventHolder
: public EventHolder_Base
359 typedef ::std::hash_map
< ::rtl::OUString
, ScriptEventDescriptor
, ::rtl::OUStringHash
> EventMap
;
360 typedef ::std::map
< EventId
, EventMap::iterator
> EventMapIndexAccess
;
362 EventMap m_aEventNameAccess
;
363 EventMapIndexAccess m_aEventIndexAccess
;
368 void addEvent( EventId _nId
, const ::rtl::OUString
& _rEventName
, const ScriptEventDescriptor
& _rScriptEvent
);
370 /** effectively the same as getByName, but instead of converting the ScriptEventDescriptor to the weird
371 format used by the macro assignment dialog, it is returned directly
373 ScriptEventDescriptor
getNormalizedDescriptorByName( const ::rtl::OUString
& _rEventName
) const;
376 virtual void SAL_CALL
replaceByName( const ::rtl::OUString
& _rName
, const Any
& aElement
) throw (IllegalArgumentException
, NoSuchElementException
, WrappedTargetException
, RuntimeException
);
377 virtual Any SAL_CALL
getByName( const ::rtl::OUString
& _rName
) throw (NoSuchElementException
, WrappedTargetException
, RuntimeException
);
378 virtual Sequence
< ::rtl::OUString
> SAL_CALL
getElementNames( ) throw (RuntimeException
);
379 virtual ::sal_Bool SAL_CALL
hasByName( const ::rtl::OUString
& _rName
) throw (RuntimeException
);
380 virtual Type SAL_CALL
getElementType( ) throw (RuntimeException
);
381 virtual ::sal_Bool SAL_CALL
hasElements( ) throw (RuntimeException
);
387 ScriptEventDescriptor
impl_getDescriptor_throw( const ::rtl::OUString
& _rEventName
) const;
390 DBG_NAME( EventHolder
)
391 //------------------------------------------------------------------------
392 EventHolder::EventHolder()
394 DBG_CTOR( EventHolder
, NULL
);
397 //------------------------------------------------------------------------
398 EventHolder::~EventHolder()
400 m_aEventNameAccess
.clear();
401 m_aEventIndexAccess
.clear();
402 DBG_DTOR( EventHolder
, NULL
);
405 //------------------------------------------------------------------------
406 void EventHolder::addEvent( EventId _nId
, const ::rtl::OUString
& _rEventName
, const ScriptEventDescriptor
& _rScriptEvent
)
408 ::std::pair
< EventMap::iterator
, bool > insertionResult
=
409 m_aEventNameAccess
.insert( EventMap::value_type( _rEventName
, _rScriptEvent
) );
410 OSL_ENSURE( insertionResult
.second
, "EventHolder::addEvent: there already was a MacroURL for this event!" );
411 m_aEventIndexAccess
[ _nId
] = insertionResult
.first
;
414 //------------------------------------------------------------------------
415 ScriptEventDescriptor
EventHolder::getNormalizedDescriptorByName( const ::rtl::OUString
& _rEventName
) const
417 return impl_getDescriptor_throw( _rEventName
);
420 //------------------------------------------------------------------------
421 ScriptEventDescriptor
EventHolder::impl_getDescriptor_throw( const ::rtl::OUString
& _rEventName
) const
423 EventMap::const_iterator pos
= m_aEventNameAccess
.find( _rEventName
);
424 if ( pos
== m_aEventNameAccess
.end() )
425 throw NoSuchElementException( ::rtl::OUString(), *const_cast< EventHolder
* >( this ) );
429 //------------------------------------------------------------------------
430 void SAL_CALL
EventHolder::replaceByName( const ::rtl::OUString
& _rName
, const Any
& _rElement
) throw (IllegalArgumentException
, NoSuchElementException
, WrappedTargetException
, RuntimeException
)
432 EventMap::iterator pos
= m_aEventNameAccess
.find( _rName
);
433 if ( pos
== m_aEventNameAccess
.end() )
434 throw NoSuchElementException( ::rtl::OUString(), *this );
436 Sequence
< PropertyValue
> aScriptDescriptor
;
437 OSL_VERIFY( _rElement
>>= aScriptDescriptor
);
439 ::comphelper::NamedValueCollection
aExtractor( aScriptDescriptor
);
441 pos
->second
.ScriptType
= aExtractor
.getOrDefault( "EventType", ::rtl::OUString() );
442 pos
->second
.ScriptCode
= aExtractor
.getOrDefault( "Script", ::rtl::OUString() );
445 //------------------------------------------------------------------------
446 Any SAL_CALL
EventHolder::getByName( const ::rtl::OUString
& _rName
) throw (NoSuchElementException
, WrappedTargetException
, RuntimeException
)
448 ScriptEventDescriptor
aDescriptor( impl_getDescriptor_throw( _rName
) );
451 Sequence
< PropertyValue
> aScriptDescriptor( 2 );
452 aScriptDescriptor
[0].Name
= ::rtl::OUString::createFromAscii( "EventType" );
453 aScriptDescriptor
[0].Value
<<= aDescriptor
.ScriptType
;
454 aScriptDescriptor
[1].Name
= ::rtl::OUString::createFromAscii( "Script" );
455 aScriptDescriptor
[1].Value
<<= aDescriptor
.ScriptCode
;
457 return makeAny( aScriptDescriptor
);
460 //------------------------------------------------------------------------
461 Sequence
< ::rtl::OUString
> SAL_CALL
EventHolder::getElementNames( ) throw (RuntimeException
)
463 Sequence
< ::rtl::OUString
> aReturn( m_aEventIndexAccess
.size() );
464 ::rtl::OUString
* pReturn
= aReturn
.getArray();
466 // SvxMacroAssignDlg has a weird API: It expects a XNameReplace, means a container whose
467 // main access method is by name. In it's UI, it shows the possible events in exactly the
468 // order in which XNameAccess::getElementNames returns them.
469 // However, SvxMacroAssignDlg *also* takes an index for the initial selection, which is
470 // relative to the sequence returned by XNameAccess::getElementNames.
471 // This is IMO weird, since it mixes index access with name access, which decreases efficiency
472 // of the implementation.
473 // Well, it means we're forced to return the events in getElementNames in exactly the same as they
474 // appear in the property browser UI.
475 for ( EventMapIndexAccess::const_iterator loop
= m_aEventIndexAccess
.begin();
476 loop
!= m_aEventIndexAccess
.end();
479 *pReturn
= loop
->second
->first
;
483 //------------------------------------------------------------------------
484 sal_Bool SAL_CALL
EventHolder::hasByName( const ::rtl::OUString
& _rName
) throw (RuntimeException
)
486 EventMap::const_iterator pos
= m_aEventNameAccess
.find( _rName
);
487 return pos
!= m_aEventNameAccess
.end();
490 //------------------------------------------------------------------------
491 Type SAL_CALL
EventHolder::getElementType( ) throw (RuntimeException
)
493 return ::getCppuType( static_cast< Sequence
< PropertyValue
>* >( NULL
) );
496 //------------------------------------------------------------------------
497 sal_Bool SAL_CALL
EventHolder::hasElements( ) throw (RuntimeException
)
499 return !m_aEventNameAccess
.empty();
503 //====================================================================
505 //====================================================================
506 DBG_NAME( EventHandler
)
507 //--------------------------------------------------------------------
508 EventHandler::EventHandler( const Reference
< XComponentContext
>& _rxContext
)
509 :EventHandler_Base( m_aMutex
)
510 ,m_aContext( _rxContext
)
511 ,m_aPropertyListeners( m_aMutex
)
512 ,m_bEventsMapInitialized( false )
513 ,m_bIsDialogElement( false )
514 ,m_nGridColumnType( -1 )
516 DBG_CTOR( EventHandler
, NULL
);
519 //--------------------------------------------------------------------
520 EventHandler::~EventHandler()
522 DBG_DTOR( EventHandler
, NULL
);
525 //--------------------------------------------------------------------
526 ::rtl::OUString SAL_CALL
EventHandler::getImplementationName( ) throw (RuntimeException
)
528 return getImplementationName_static();
531 //--------------------------------------------------------------------
532 ::sal_Bool SAL_CALL
EventHandler::supportsService( const ::rtl::OUString
& ServiceName
) throw (RuntimeException
)
534 StlSyntaxSequence
< ::rtl::OUString
> aAllServices( getSupportedServiceNames() );
535 return ::std::find( aAllServices
.begin(), aAllServices
.end(), ServiceName
) != aAllServices
.end();
538 //--------------------------------------------------------------------
539 Sequence
< ::rtl::OUString
> SAL_CALL
EventHandler::getSupportedServiceNames( ) throw (RuntimeException
)
541 return getSupportedServiceNames_static();
544 //--------------------------------------------------------------------
545 ::rtl::OUString SAL_CALL
EventHandler::getImplementationName_static( ) throw (RuntimeException
)
547 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.extensions.EventHandler" ) );
550 //--------------------------------------------------------------------
551 Sequence
< ::rtl::OUString
> SAL_CALL
EventHandler::getSupportedServiceNames_static( ) throw (RuntimeException
)
553 Sequence
< ::rtl::OUString
> aSupported( 1 );
554 aSupported
[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.form.inspection.EventHandler" ) );
558 //--------------------------------------------------------------------
559 Reference
< XInterface
> SAL_CALL
EventHandler::Create( const Reference
< XComponentContext
>& _rxContext
)
561 return *( new EventHandler( _rxContext
) );
564 //--------------------------------------------------------------------
565 void SAL_CALL
EventHandler::inspect( const Reference
< XInterface
>& _rxIntrospectee
) throw (RuntimeException
, NullPointerException
)
567 ::osl::MutexGuard
aGuard( m_aMutex
);
569 if ( !_rxIntrospectee
.is() )
570 throw NullPointerException();
572 m_xComponent
= Reference
< XPropertySet
>( _rxIntrospectee
, UNO_QUERY_THROW
);
574 m_bEventsMapInitialized
= false;
576 m_aEvents
.swap( aEmpty
);
578 m_bIsDialogElement
= false;
579 m_nGridColumnType
= -1;
582 Reference
< XPropertySetInfo
> xPSI( m_xComponent
->getPropertySetInfo() );
583 m_bIsDialogElement
= xPSI
.is()
584 && xPSI
->hasPropertyByName( PROPERTY_WIDTH
)
585 && xPSI
->hasPropertyByName( PROPERTY_HEIGHT
)
586 && xPSI
->hasPropertyByName( PROPERTY_POSITIONX
)
587 && xPSI
->hasPropertyByName( PROPERTY_POSITIONY
);
589 Reference
< XChild
> xAsChild( _rxIntrospectee
, UNO_QUERY
);
590 if ( xAsChild
.is() && !Reference
< XForm
>( _rxIntrospectee
, UNO_QUERY
).is() )
592 if ( FormComponentType::GRIDCONTROL
== classifyComponent( xAsChild
->getParent() ) )
594 m_nGridColumnType
= classifyComponent( _rxIntrospectee
);
598 catch( const Exception
& )
600 OSL_ENSURE( false, "EventHandler::EventHandler: caught an exception while classifying the component!" );
604 //--------------------------------------------------------------------
605 Any SAL_CALL
EventHandler::getPropertyValue( const ::rtl::OUString
& _rPropertyName
) throw (UnknownPropertyException
, RuntimeException
)
607 ::osl::MutexGuard
aGuard( m_aMutex
);
609 const EventDescription
& rEvent
= impl_getEventForName_throw( _rPropertyName
);
611 Sequence
< ScriptEventDescriptor
> aEvents
;
612 impl_getComponentScriptEvents_nothrow( aEvents
);
614 sal_Int32 nEventCount
= aEvents
.getLength();
615 const ScriptEventDescriptor
* pEvents
= aEvents
.getConstArray();
617 ScriptEventDescriptor aPropertyValue
;
618 for ( sal_Int32 event
= 0; event
< nEventCount
; ++event
, ++pEvents
)
620 if ( rEvent
.sListenerClassName
== pEvents
->ListenerType
621 && rEvent
.sListenerMethodName
== pEvents
->EventMethod
624 aPropertyValue
= *pEvents
;
629 return makeAny( aPropertyValue
);
632 //--------------------------------------------------------------------
633 void SAL_CALL
EventHandler::setPropertyValue( const ::rtl::OUString
& _rPropertyName
, const Any
& _rValue
) throw (UnknownPropertyException
, RuntimeException
)
635 ::osl::MutexGuard
aGuard( m_aMutex
);
637 const EventDescription
& rEvent
= impl_getEventForName_throw( _rPropertyName
);
639 ScriptEventDescriptor aNewScriptEvent
;
640 OSL_VERIFY( _rValue
>>= aNewScriptEvent
);
642 ScriptEventDescriptor aOldScriptEvent
;
643 OSL_VERIFY( getPropertyValue( _rPropertyName
) >>= aOldScriptEvent
);
644 if ( aOldScriptEvent
== aNewScriptEvent
)
647 if ( m_bIsDialogElement
)
648 impl_setDialogElementScriptEvent_nothrow( aNewScriptEvent
);
650 impl_setFormComponentScriptEvent_nothrow( aNewScriptEvent
);
652 Reference
< XModifiable
> xDoc( m_aContext
.getContextValueByAsciiName( "ContextDocument" ), UNO_QUERY
);
654 xDoc
->setModified( sal_True
);
656 PropertyChangeEvent aEvent
;
657 aEvent
.Source
= m_xComponent
;
658 aEvent
.PropertyHandle
= rEvent
.nId
;
659 aEvent
.PropertyName
= _rPropertyName
;
660 aEvent
.OldValue
<<= aOldScriptEvent
;
661 aEvent
.NewValue
<<= aNewScriptEvent
;
662 m_aPropertyListeners
.notify( aEvent
, &XPropertyChangeListener::propertyChange
);
665 //--------------------------------------------------------------------
666 Any SAL_CALL
EventHandler::convertToPropertyValue( const ::rtl::OUString
& _rPropertyName
, const Any
& _rControlValue
) throw (UnknownPropertyException
, RuntimeException
)
668 ::osl::MutexGuard
aGuard( m_aMutex
);
670 ::rtl::OUString sNewScriptCode
;
671 OSL_VERIFY( _rControlValue
>>= sNewScriptCode
);
673 Sequence
< ScriptEventDescriptor
> aAllAssignedEvents
;
674 impl_getComponentScriptEvents_nothrow( aAllAssignedEvents
);
676 const EventDescription
& rEvent
= impl_getEventForName_throw( _rPropertyName
);
677 ScriptEventDescriptor aAssignedScript
= lcl_getAssignedScriptEvent( rEvent
, aAllAssignedEvents
);
679 OSL_ENSURE( !sNewScriptCode
.getLength(), "EventHandler::convertToPropertyValue: cannot convert a non-empty display name!" );
680 // Usually, there is no possibility for the user to change the content of an event binding directly in the
681 // input field, this instead is done with the macro assignment dialog.
682 // The only exception is the user pressing "DEL" while the control has the focus, in this case, we reset the
683 // control content to an empty string. So this is the only scenario where this method is allowed to be called.
685 // Striclty, we would be able to convert the display value to a property value,
686 // using the "name (location, language)" format we used in convertToControlValue. However,
687 // there is no need for this code ...
689 aAssignedScript
.ScriptCode
= sNewScriptCode
;
690 return makeAny( aAssignedScript
);
693 //--------------------------------------------------------------------
694 Any SAL_CALL
EventHandler::convertToControlValue( const ::rtl::OUString
& /*_rPropertyName*/, const Any
& _rPropertyValue
, const Type
& _rControlValueType
) throw (UnknownPropertyException
, RuntimeException
)
696 ::osl::MutexGuard
aGuard( m_aMutex
);
698 ScriptEventDescriptor aScriptEvent
;
699 OSL_VERIFY( _rPropertyValue
>>= aScriptEvent
);
701 OSL_ENSURE( _rControlValueType
.getTypeClass() == TypeClass_STRING
,
702 "EventHandler::convertToControlValue: unexpected ControlValue type class!" );
703 (void)_rControlValueType
;
705 ::rtl::OUString
sScript( aScriptEvent
.ScriptCode
);
706 if ( sScript
.getLength() )
708 // format is: "name (location, language)"
712 Reference
< XUriReferenceFactory
> xUriRefFac
= UriReferenceFactory::create( m_aContext
.getUNOContext() );
713 Reference
< XVndSunStarScriptUrlReference
> xScriptUri( xUriRefFac
->parse( sScript
), UNO_QUERY_THROW
);
715 ::rtl::OUStringBuffer aComposeBuffer
;
718 aComposeBuffer
.append( xScriptUri
->getName() );
721 const ::rtl::OUString
sLocationParamName( RTL_CONSTASCII_USTRINGPARAM( "location" ) );
722 const ::rtl::OUString sLocation
= xScriptUri
->getParameter( sLocationParamName
);
723 const ::rtl::OUString
sLangParamName( RTL_CONSTASCII_USTRINGPARAM( "language" ) );
724 const ::rtl::OUString sLanguage
= xScriptUri
->getParameter( sLangParamName
);
726 if ( sLocation
.getLength() || sLanguage
.getLength() )
728 aComposeBuffer
.appendAscii( " (" );
731 OSL_ENSURE( sLocation
.getLength(), "EventHandler::convertToControlValue: unexpected: no location!" );
732 if ( sLocation
.getLength() )
734 aComposeBuffer
.append( sLocation
);
735 aComposeBuffer
.appendAscii( ", " );
739 if ( sLanguage
.getLength() )
741 aComposeBuffer
.append( sLanguage
);
744 aComposeBuffer
.append( sal_Unicode( ')' ) );
747 sScript
= aComposeBuffer
.makeStringAndClear();
749 catch( const Exception
& )
751 DBG_UNHANDLED_EXCEPTION();
755 return makeAny( sScript
);
758 //--------------------------------------------------------------------
759 PropertyState SAL_CALL
EventHandler::getPropertyState( const ::rtl::OUString
& /*_rPropertyName*/ ) throw (UnknownPropertyException
, RuntimeException
)
761 return PropertyState_DIRECT_VALUE
;
764 //--------------------------------------------------------------------
765 void SAL_CALL
EventHandler::addPropertyChangeListener( const Reference
< XPropertyChangeListener
>& _rxListener
) throw (RuntimeException
)
767 ::osl::MutexGuard
aGuard( m_aMutex
);
768 if ( !_rxListener
.is() )
769 throw NullPointerException();
770 m_aPropertyListeners
.addListener( _rxListener
);
773 //--------------------------------------------------------------------
774 void SAL_CALL
EventHandler::removePropertyChangeListener( const Reference
< XPropertyChangeListener
>& _rxListener
) throw (RuntimeException
)
776 ::osl::MutexGuard
aGuard( m_aMutex
);
777 m_aPropertyListeners
.removeListener( _rxListener
);
780 //--------------------------------------------------------------------
781 Sequence
< Property
> SAL_CALL
EventHandler::getSupportedProperties() throw (RuntimeException
)
783 ::osl::MutexGuard
aGuard( m_aMutex
);
784 if ( !m_bEventsMapInitialized
)
786 const_cast< EventHandler
* >( this )->m_bEventsMapInitialized
= true;
789 Sequence
< Type
> aListeners
;
790 impl_getCopmonentListenerTypes_nothrow( aListeners
);
791 sal_Int32 listenerCount
= aListeners
.getLength();
793 Property aCurrentProperty
;
794 ::rtl::OUString sListenerClassName
;
796 // loop through all listeners and all methods, and see which we can present at the UI
797 const Type
* pListeners
= aListeners
.getConstArray();
798 for ( sal_Int32 listener
= 0; listener
< listenerCount
; ++listener
, ++pListeners
)
800 aCurrentProperty
= Property();
802 // the programmatic name of the listener, to be used as "property" name
803 sListenerClassName
= pListeners
->getTypeName();
804 OSL_ENSURE( sListenerClassName
.getLength(), "EventHandler::getSupportedProperties: strange - no listener name ..." );
805 if ( !sListenerClassName
.getLength() )
808 // loop through all methods
809 Sequence
< ::rtl::OUString
> aMethods( comphelper::getEventMethodsForType( *pListeners
) );
811 const ::rtl::OUString
* pMethods
= aMethods
.getConstArray();
812 sal_uInt32 methodCount
= aMethods
.getLength();
814 for (sal_uInt32 method
= 0 ; method
< methodCount
; ++method
, ++pMethods
)
816 EventDescription aEvent
;
817 if ( !lcl_getEventDescriptionForMethod( *pMethods
, aEvent
) )
820 if ( !impl_filterMethod_nothrow( aEvent
) )
823 const_cast< EventHandler
* >( this )->m_aEvents
.insert( EventMap::value_type(
824 lcl_getEventPropertyName( sListenerClassName
, *pMethods
), aEvent
) );
829 catch( const Exception
& )
831 DBG_ERROR( "EventHandler::getSupportedProperties: caught an exception !" );
835 // sort them by ID - this is the relative ordering in the UI
836 ::std::map
< EventId
, Property
> aOrderedProperties
;
837 for ( EventMap::const_iterator loop
= m_aEvents
.begin();
838 loop
!= m_aEvents
.end();
842 aOrderedProperties
[ loop
->second
.nId
] = Property(
843 loop
->first
, loop
->second
.nId
,
844 ::getCppuType( static_cast< const ::rtl::OUString
* >( NULL
) ),
845 PropertyAttribute::BOUND
);
848 StlSyntaxSequence
< Property
> aReturn( aOrderedProperties
.size() );
849 ::std::transform( aOrderedProperties
.begin(), aOrderedProperties
.end(), aReturn
.begin(),
850 ::std::select2nd
< ::std::map
< EventId
, Property
>::value_type
>() );
854 //--------------------------------------------------------------------
855 Sequence
< ::rtl::OUString
> SAL_CALL
EventHandler::getSupersededProperties( ) throw (RuntimeException
)
858 return Sequence
< ::rtl::OUString
>( );
861 //--------------------------------------------------------------------
862 Sequence
< ::rtl::OUString
> SAL_CALL
EventHandler::getActuatingProperties( ) throw (RuntimeException
)
865 return Sequence
< ::rtl::OUString
>( );
868 //--------------------------------------------------------------------
869 LineDescriptor SAL_CALL
EventHandler::describePropertyLine( const ::rtl::OUString
& _rPropertyName
,
870 const Reference
< XPropertyControlFactory
>& _rxControlFactory
)
871 throw (UnknownPropertyException
, NullPointerException
, RuntimeException
)
873 if ( !_rxControlFactory
.is() )
874 throw NullPointerException();
876 ::osl::MutexGuard
aGuard( m_aMutex
);
878 LineDescriptor aDescriptor
;
880 aDescriptor
.Control
= _rxControlFactory
->createPropertyControl( PropertyControlType::TextField
, sal_True
);
881 Reference
< XEventListener
> xControlExtender
= new PropertyControlExtender( aDescriptor
.Control
);
883 const EventDescription
& rEvent
= impl_getEventForName_throw( _rPropertyName
);
884 aDescriptor
.DisplayName
= rEvent
.sDisplayName
;
885 aDescriptor
.HelpURL
= HelpIdUrl::getHelpURL( rEvent
.nHelpId
);
886 aDescriptor
.PrimaryButtonId
= rEvent
.nUniqueBrowseId
;
887 aDescriptor
.HasPrimaryButton
= sal_True
;
888 aDescriptor
.Category
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Events" ) );
892 //--------------------------------------------------------------------
893 ::sal_Bool SAL_CALL
EventHandler::isComposable( const ::rtl::OUString
& /*_rPropertyName*/ ) throw (UnknownPropertyException
, RuntimeException
)
898 //--------------------------------------------------------------------
899 InteractiveSelectionResult SAL_CALL
EventHandler::onInteractivePropertySelection( const ::rtl::OUString
& _rPropertyName
, sal_Bool
/*_bPrimary*/, Any
& /*_rData*/, const Reference
< XObjectInspectorUI
>& _rxInspectorUI
) throw (UnknownPropertyException
, NullPointerException
, RuntimeException
)
901 if ( !_rxInspectorUI
.is() )
902 throw NullPointerException();
904 ::osl::MutexGuard
aGuard( m_aMutex
);
905 const EventDescription
& rForEvent
= impl_getEventForName_throw( _rPropertyName
);
907 Sequence
< ScriptEventDescriptor
> aAllAssignedEvents
;
908 impl_getComponentScriptEvents_nothrow( aAllAssignedEvents
);
910 // SvxMacroAssignDlg-compatible structure holding all event/assignments
911 ::rtl::Reference
< EventHolder
> pEventHolder( new EventHolder
);
913 for ( EventMap::const_iterator event
= m_aEvents
.begin();
914 event
!= m_aEvents
.end();
918 // the script which is assigned to the current event (if any)
919 ScriptEventDescriptor aAssignedScript
= lcl_getAssignedScriptEvent( event
->second
, aAllAssignedEvents
);
920 pEventHolder
->addEvent( event
->second
.nId
, event
->second
.sListenerMethodName
, aAssignedScript
);
923 // the inital selection in the dialog
924 Sequence
< ::rtl::OUString
> aNames( pEventHolder
->getElementNames() );
925 const ::rtl::OUString
* pChosenEvent
= ::std::find( aNames
.getConstArray(), aNames
.getConstArray() + aNames
.getLength(), rForEvent
.sListenerMethodName
);
926 sal_uInt16 nInitialSelection
= (sal_uInt16
)( pChosenEvent
- aNames
.getConstArray() );
929 SvxAbstractDialogFactory
* pFactory
= SvxAbstractDialogFactory::Create();
931 return InteractiveSelectionResult_Cancelled
;
933 ::std::auto_ptr
< VclAbstractDialog
> pDialog( pFactory
->CreateSvxMacroAssignDlg(
934 PropertyHandlerHelper::getDialogParentWindow( m_aContext
),
935 impl_getContextFrame_nothrow(),
941 if ( !pDialog
.get() )
942 return InteractiveSelectionResult_Cancelled
;
944 // DF definite problem here
945 // OK & Cancel seem to be both returning 0
946 if ( pDialog
->Execute() != 0 )
947 return InteractiveSelectionResult_Cancelled
;
951 for ( EventMap::const_iterator event
= m_aEvents
.begin();
952 event
!= m_aEvents
.end();
956 ScriptEventDescriptor
aScriptDescriptor( pEventHolder
->getNormalizedDescriptorByName( event
->second
.sListenerMethodName
) );
958 // set the new "property value"
960 lcl_getEventPropertyName( event
->second
.sListenerClassName
, event
->second
.sListenerMethodName
),
961 makeAny( aScriptDescriptor
)
965 catch( const Exception
& )
967 DBG_UNHANDLED_EXCEPTION();
970 return InteractiveSelectionResult_Success
;
973 //--------------------------------------------------------------------
974 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
)
976 DBG_ERROR( "EventHandler::actuatingPropertyChanged: no actuating properties -> no callback (well, this is how it *should* be!)" );
979 //--------------------------------------------------------------------
980 IMPLEMENT_FORWARD_XCOMPONENT( EventHandler
, EventHandler_Base
)
982 //--------------------------------------------------------------------
983 void SAL_CALL
EventHandler::disposing()
986 m_aEvents
.swap( aEmpty
);
987 m_xComponent
.clear();
990 //--------------------------------------------------------------------
991 sal_Bool SAL_CALL
EventHandler::suspend( sal_Bool
/*_bSuspend*/ ) throw (RuntimeException
)
996 //------------------------------------------------------------------------
997 Reference
< XFrame
> EventHandler::impl_getContextFrame_nothrow() const
999 Reference
< XFrame
> xContextFrame
;
1003 Reference
< XModel
> xContextDocument( m_aContext
.getContextValueByAsciiName( "ContextDocument" ), UNO_QUERY_THROW
);
1004 Reference
< XController
> xController( xContextDocument
->getCurrentController(), UNO_SET_THROW
);
1005 xContextFrame
.set( xController
->getFrame(), UNO_SET_THROW
);
1007 catch( const Exception
& )
1009 DBG_UNHANDLED_EXCEPTION();
1012 return xContextFrame
;
1015 //--------------------------------------------------------------------
1016 sal_Int32
EventHandler::impl_getComponentIndexInParent_throw() const
1018 Reference
< XChild
> xChild( m_xComponent
, UNO_QUERY_THROW
);
1019 Reference
< XIndexAccess
> xParentAsIndexAccess( xChild
->getParent(), UNO_QUERY_THROW
);
1021 // get the index of the inspected object within it's parent container
1022 sal_Int32 nElements
= xParentAsIndexAccess
->getCount();
1023 for ( sal_Int32 i
=0; i
<nElements
; ++i
)
1025 Reference
< XInterface
> xElement( xParentAsIndexAccess
->getByIndex( i
), UNO_QUERY_THROW
);
1026 if ( xElement
== m_xComponent
)
1029 throw NoSuchElementException();
1032 //--------------------------------------------------------------------
1033 void EventHandler::impl_getFormComponentScriptEvents_nothrow( Sequence
< ScriptEventDescriptor
>& _out_rEvents
) const
1035 _out_rEvents
= Sequence
< ScriptEventDescriptor
>();
1038 Reference
< XChild
> xChild( m_xComponent
, UNO_QUERY_THROW
);
1039 Reference
< XEventAttacherManager
> xEventManager( xChild
->getParent(), UNO_QUERY_THROW
);
1040 _out_rEvents
= xEventManager
->getScriptEvents( impl_getComponentIndexInParent_throw() );
1042 // the form component script API has unqualified listener names, but for normalization
1043 // purpose, we want fully qualified ones
1044 ScriptEventDescriptor
* pEvents
= _out_rEvents
.getArray();
1045 ScriptEventDescriptor
* pEventsEnd
= _out_rEvents
.getArray() + _out_rEvents
.getLength();
1046 while ( pEvents
!= pEventsEnd
)
1048 pEvents
->ListenerType
= lcl_getQualifiedKnownListenerName( *pEvents
);
1052 catch( const Exception
& )
1054 OSL_ENSURE( false, "EventHandler::impl_getFormComponentScriptEvents_nothrow: caught an exception!" );
1058 //--------------------------------------------------------------------
1059 void EventHandler::impl_getCopmonentListenerTypes_nothrow( Sequence
< Type
>& _out_rTypes
) const
1061 _out_rTypes
.realloc( 0 );
1064 // we use a set to avoid duplicates
1067 Reference
< XIntrospection
> xIntrospection( m_aContext
.createComponent( "com.sun.star.beans.Introspection" ), UNO_QUERY_THROW
);
1069 // --- model listeners
1070 lcl_addListenerTypesFor_throw(
1071 m_xComponent
, xIntrospection
, aListeners
);
1073 // --- "secondary component" (usually: "control" listeners)
1075 Reference
< XInterface
> xSecondaryComponent( impl_getSecondaryComponentForEventInspection_throw() );
1076 lcl_addListenerTypesFor_throw( xSecondaryComponent
, xIntrospection
, aListeners
);
1077 ::comphelper::disposeComponent( xSecondaryComponent
);
1080 // now that they're disambiguated, copy these types into our member
1081 _out_rTypes
.realloc( aListeners
.size() );
1082 ::std::copy( aListeners
.begin(), aListeners
.end(), _out_rTypes
.getArray() );
1084 catch( const Exception
& )
1086 OSL_ENSURE( false, "EventHandler::impl_getCopmonentListenerTypes_nothrow: caught an exception!" );
1090 //--------------------------------------------------------------------
1091 void EventHandler::impl_getDialogElementScriptEvents_nothrow( Sequence
< ScriptEventDescriptor
>& _out_rEvents
) const
1093 _out_rEvents
= Sequence
< ScriptEventDescriptor
>();
1096 Reference
< XScriptEventsSupplier
> xEventsSupplier( m_xComponent
, UNO_QUERY_THROW
);
1097 Reference
< XNameContainer
> xEvents( xEventsSupplier
->getEvents(), UNO_QUERY_THROW
);
1098 Sequence
< ::rtl::OUString
> aEventNames( xEvents
->getElementNames() );
1100 sal_Int32 nEventCount
= aEventNames
.getLength();
1101 _out_rEvents
.realloc( nEventCount
);
1103 const ::rtl::OUString
* pNames
= aEventNames
.getConstArray();
1104 ScriptEventDescriptor
* pDescs
= _out_rEvents
.getArray();
1106 for( sal_Int32 i
= 0 ; i
< nEventCount
; ++i
, ++pNames
, ++pDescs
)
1107 OSL_VERIFY( xEvents
->getByName( *pNames
) >>= *pDescs
);
1109 catch( const Exception
& )
1111 OSL_ENSURE( false, "EventHandler::impl_getDialogElementScriptEvents_nothrow: caught an exception!" );
1115 //--------------------------------------------------------------------
1116 Reference
< XInterface
> EventHandler::impl_getSecondaryComponentForEventInspection_throw( ) const
1118 Reference
< XInterface
> xReturn
;
1120 // if it's a form, create a form controller for the additional events
1121 Reference
< XForm
> xComponentAsForm( m_xComponent
, UNO_QUERY
);
1122 if ( xComponentAsForm
.is() )
1124 Reference
< XTabControllerModel
> xComponentAsTCModel( m_xComponent
, UNO_QUERY_THROW
);
1125 Reference
< XFormController
> xController(
1126 m_aContext
.createComponent( (const rtl::OUString
&)SERVICE_FORMCONTROLLER
), UNO_QUERY_THROW
);
1127 xController
->setModel( xComponentAsTCModel
);
1129 xReturn
= xController
.get();
1133 ::rtl::OUString sControlService
;
1134 OSL_VERIFY( m_xComponent
->getPropertyValue( PROPERTY_DEFAULTCONTROL
) >>= sControlService
);
1136 xReturn
= m_aContext
.createComponent( sControlService
);
1141 //--------------------------------------------------------------------
1142 const EventDescription
& EventHandler::impl_getEventForName_throw( const ::rtl::OUString
& _rPropertyName
) const
1144 EventMap::const_iterator pos
= m_aEvents
.find( _rPropertyName
);
1145 if ( pos
== m_aEvents
.end() )
1146 throw UnknownPropertyException();
1150 //--------------------------------------------------------------------
1153 static bool lcl_endsWith( const ::rtl::OUString
& _rText
, const ::rtl::OUString
& _rCheck
)
1155 sal_Int32 nTextLen
= _rText
.getLength();
1156 sal_Int32 nCheckLen
= _rCheck
.getLength();
1157 if ( nCheckLen
> nTextLen
)
1160 return _rText
.indexOf( _rCheck
) == ( nTextLen
- nCheckLen
);
1163 //--------------------------------------------------------------------
1164 void EventHandler::impl_setFormComponentScriptEvent_nothrow( const ScriptEventDescriptor
& _rScriptEvent
)
1168 ::rtl::OUString
sScriptCode( _rScriptEvent
.ScriptCode
);
1169 ::rtl::OUString
sScriptType( _rScriptEvent
.ScriptType
);
1170 bool bResetScript
= ( sScriptCode
.getLength() == 0 );
1172 sal_Int32 nObjectIndex
= impl_getComponentIndexInParent_throw();
1173 Reference
< XChild
> xChild( m_xComponent
, UNO_QUERY_THROW
);
1174 Reference
< XEventAttacherManager
> xEventManager( xChild
->getParent(), UNO_QUERY_THROW
);
1175 Sequence
< ScriptEventDescriptor
> aEvents( xEventManager
->getScriptEvents( nObjectIndex
) );
1177 // is there already a registered script for this event?
1178 ScriptEventDescriptor
* pEvent
= aEvents
.getArray();
1179 sal_Int32 eventCount
= aEvents
.getLength(), event
= 0;
1180 for ( event
= 0; event
< eventCount
; ++event
, ++pEvent
)
1182 if ( ( pEvent
->EventMethod
== _rScriptEvent
.EventMethod
)
1183 && ( lcl_endsWith( _rScriptEvent
.ListenerType
, pEvent
->ListenerType
) )
1184 // (strange enough, the events we get from getScriptEvents are not fully qualified)
1188 if ( !bResetScript
)
1190 // set to something non-empty -> overwrite
1191 pEvent
->ScriptCode
= sScriptCode
;
1192 pEvent
->ScriptType
= sScriptType
;
1196 // set to empty -> remove from sequence
1197 ::std::copy( pEvent
+ 1, aEvents
.getArray() + eventCount
, pEvent
);
1198 aEvents
.realloc( eventCount
- 1 );
1204 if ( ( event
>= eventCount
) && !bResetScript
)
1206 // no, did not find it -> append
1207 aEvents
.realloc( eventCount
+ 1 );
1208 aEvents
[ eventCount
] = _rScriptEvent
;
1211 xEventManager
->revokeScriptEvents( nObjectIndex
);
1212 xEventManager
->registerScriptEvents( nObjectIndex
, aEvents
);
1214 PropertyHandlerHelper::setContextDocumentModified( m_aContext
);
1216 catch( const Exception
& )
1218 OSL_ENSURE( false, "EventHandler::impl_setFormComponentScriptEvent_nothrow: caught an exception!" );
1222 //--------------------------------------------------------------------
1223 void EventHandler::impl_setDialogElementScriptEvent_nothrow( const ScriptEventDescriptor
& _rScriptEvent
)
1227 ::rtl::OUString
sScriptCode( _rScriptEvent
.ScriptCode
);
1228 bool bResetScript
= ( sScriptCode
.getLength() == 0 );
1230 Reference
< XScriptEventsSupplier
> xEventsSupplier( m_xComponent
, UNO_QUERY_THROW
);
1231 Reference
< XNameContainer
> xEvents( xEventsSupplier
->getEvents(), UNO_QUERY_THROW
);
1233 ::rtl::OUStringBuffer aCompleteName
;
1234 aCompleteName
.append( _rScriptEvent
.ListenerType
);
1235 aCompleteName
.appendAscii( "::" );
1236 aCompleteName
.append( _rScriptEvent
.EventMethod
);
1237 ::rtl::OUString
sCompleteName( aCompleteName
.makeStringAndClear() );
1239 bool bExists
= xEvents
->hasByName( sCompleteName
);
1244 xEvents
->removeByName( sCompleteName
);
1248 Any aNewValue
; aNewValue
<<= _rScriptEvent
;
1251 xEvents
->replaceByName( sCompleteName
, aNewValue
);
1253 xEvents
->insertByName( sCompleteName
, aNewValue
);
1256 catch( const Exception
& )
1258 DBG_UNHANDLED_EXCEPTION();
1262 //--------------------------------------------------------------------
1263 bool EventHandler::impl_filterMethod_nothrow( const EventDescription
& _rEvent
) const
1265 // some (control-triggered) events do not make sense for certain grid control columns. However,
1266 // our mechnism to retrieve control-triggered events does not know about this, so we do some
1267 // late filtering here.
1268 switch ( m_nGridColumnType
)
1270 case FormComponentType::COMBOBOX
:
1271 if ( UID_BRWEVT_ACTIONPERFORMED
== _rEvent
.nUniqueBrowseId
)
1274 case FormComponentType::LISTBOX
:
1275 if ( ( UID_BRWEVT_CHANGED
== _rEvent
.nUniqueBrowseId
)
1276 || ( UID_BRWEVT_ACTIONPERFORMED
== _rEvent
.nUniqueBrowseId
)
1285 //........................................................................
1287 //........................................................................