1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_extensions.hxx"
31 #include "eventhandler.hxx"
32 #include "propctrlr.hrc"
33 #include "formbrowsertools.hxx"
34 #include "formresid.hrc"
35 #include "formstrings.hxx"
36 #include "handlerhelper.hxx"
37 #include "modulepcr.hxx"
38 #include "pcrcommon.hxx"
39 #include "pcrstrings.hxx"
40 #include "propertycontrolextender.hxx"
42 /** === begin UNO includes === **/
43 #include <com/sun/star/awt/XTabControllerModel.hpp>
44 #include <com/sun/star/beans/PropertyAttribute.hpp>
45 #include <com/sun/star/beans/UnknownPropertyException.hpp>
46 #include <com/sun/star/beans/XIntrospection.hpp>
47 #include <com/sun/star/beans/XIntrospectionAccess.hpp>
48 #include <com/sun/star/container/NoSuchElementException.hpp>
49 #include <com/sun/star/container/XChild.hpp>
50 #include <com/sun/star/container/XIndexAccess.hpp>
51 #include <com/sun/star/container/XNameContainer.hpp>
52 #include <com/sun/star/container/XNameReplace.hpp>
53 #include <com/sun/star/form/FormComponentType.hpp>
54 #include <com/sun/star/form/XForm.hpp>
55 #include <com/sun/star/form/runtime/XFormController.hpp>
56 #include <com/sun/star/inspection/PropertyControlType.hpp>
57 #include <com/sun/star/lang/NullPointerException.hpp>
58 #include <com/sun/star/script/XEventAttacherManager.hpp>
59 #include <com/sun/star/script/XScriptEventsSupplier.hpp>
60 #include <com/sun/star/util/XModifiable.hpp>
61 #include <com/sun/star/uri/UriReferenceFactory.hpp>
62 #include <com/sun/star/uri/XVndSunStarScriptUrlReference.hpp>
63 /** === end UNO includes === **/
65 #include <comphelper/namedvaluecollection.hxx>
66 #include <comphelper/evtmethodhelper.hxx>
67 #include <comphelper/types.hxx>
68 #include <cppuhelper/implbase1.hxx>
69 #include <rtl/ref.hxx>
70 #include <rtl/ustrbuf.hxx>
71 #include <sfx2/app.hxx>
72 #include <svl/eitem.hxx>
73 #include <svl/itemset.hxx>
74 #include <svx/svxdlg.hxx>
75 #include <svx/svxids.hrc>
76 #include <tools/diagnose_ex.h>
77 #include <vcl/msgbox.hxx>
82 //------------------------------------------------------------------------
83 extern "C" void SAL_CALL
createRegistryInfo_EventHandler()
85 ::pcr::OAutoRegistration
< ::pcr::EventHandler
> aAutoRegistration
;
88 //........................................................................
91 //........................................................................
93 /** === begin UNO using === **/
94 using ::com::sun::star::uno::Reference
;
95 using ::com::sun::star::uno::XComponentContext
;
96 using ::com::sun::star::beans::XPropertySet
;
97 using ::com::sun::star::uno::Any
;
98 using ::com::sun::star::uno::TypeClass_STRING
;
99 using ::com::sun::star::uno::Type
;
100 using ::com::sun::star::beans::XPropertyChangeListener
;
101 using ::com::sun::star::beans::Property
;
102 using ::com::sun::star::beans::PropertyState
;
103 using ::com::sun::star::beans::PropertyState_DIRECT_VALUE
;
104 using ::com::sun::star::uno::Sequence
;
105 using ::com::sun::star::script::ScriptEventDescriptor
;
106 using ::com::sun::star::script::XScriptEventsSupplier
;
107 using ::com::sun::star::lang::NullPointerException
;
108 using ::com::sun::star::uno::Exception
;
109 using ::com::sun::star::container::XChild
;
110 using ::com::sun::star::container::XIndexAccess
;
111 using ::com::sun::star::script::XEventAttacherManager
;
112 using ::com::sun::star::uno::UNO_QUERY
;
113 using ::com::sun::star::uno::UNO_QUERY_THROW
;
114 using ::com::sun::star::uno::XInterface
;
115 using ::com::sun::star::beans::XIntrospection
;
116 using ::com::sun::star::beans::XIntrospectionAccess
;
117 using ::com::sun::star::container::XNameContainer
;
118 using ::com::sun::star::awt::XTabControllerModel
;
119 using ::com::sun::star::form::XForm
;
120 using ::com::sun::star::form::runtime::XFormController
;
121 using ::com::sun::star::beans::UnknownPropertyException
;
122 using ::com::sun::star::uno::makeAny
;
123 using ::com::sun::star::container::NoSuchElementException
;
124 using ::com::sun::star::beans::XPropertySetInfo
;
125 using ::com::sun::star::container::XNameReplace
;
126 using ::com::sun::star::lang::IllegalArgumentException
;
127 using ::com::sun::star::lang::WrappedTargetException
;
128 using ::com::sun::star::uno::RuntimeException
;
129 using ::com::sun::star::beans::PropertyValue
;
130 using ::com::sun::star::inspection::LineDescriptor
;
131 using ::com::sun::star::inspection::XPropertyControlFactory
;
132 using ::com::sun::star::inspection::InteractiveSelectionResult
;
133 using ::com::sun::star::inspection::InteractiveSelectionResult_Cancelled
;
134 using ::com::sun::star::inspection::InteractiveSelectionResult_Success
;
135 using ::com::sun::star::inspection::XObjectInspectorUI
;
136 using ::com::sun::star::util::XModifiable
;
137 using ::com::sun::star::beans::PropertyChangeEvent
;
138 using ::com::sun::star::frame::XFrame
;
139 using ::com::sun::star::frame::XModel
;
140 using ::com::sun::star::frame::XController
;
141 using ::com::sun::star::uno::UNO_SET_THROW
;
142 using com::sun::star::uri::UriReferenceFactory
;
143 using com::sun::star::uri::XUriReferenceFactory
;
144 using com::sun::star::uri::XVndSunStarScriptUrlReference
;
145 using ::com::sun::star::lang::XEventListener
;
146 /** === end UNO using === **/
147 namespace PropertyControlType
= ::com::sun::star::inspection::PropertyControlType
;
148 namespace PropertyAttribute
= ::com::sun::star::beans::PropertyAttribute
;
149 namespace FormComponentType
= ::com::sun::star::form::FormComponentType
;
151 //====================================================================
153 //====================================================================
154 EventDescription::EventDescription( EventId _nId
, const sal_Char
* _pListenerNamespaceAscii
, const sal_Char
* _pListenerClassAsciiName
,
155 const sal_Char
* _pListenerMethodAsciiName
, sal_uInt16 _nDisplayNameResId
, const rtl::OString
& _sHelpId
, const rtl::OString
& _sUniqueBrowseId
)
156 :sDisplayName( String( PcrRes( _nDisplayNameResId
) ) )
157 ,sListenerMethodName( ::rtl::OUString::createFromAscii( _pListenerMethodAsciiName
) )
159 ,sUniqueBrowseId( _sUniqueBrowseId
)
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 )
512 ,m_nGridColumnType( -1 )
514 DBG_CTOR( EventHandler
, NULL
);
517 //--------------------------------------------------------------------
518 EventHandler::~EventHandler()
520 DBG_DTOR( EventHandler
, NULL
);
523 //--------------------------------------------------------------------
524 ::rtl::OUString SAL_CALL
EventHandler::getImplementationName( ) throw (RuntimeException
)
526 return getImplementationName_static();
529 //--------------------------------------------------------------------
530 ::sal_Bool SAL_CALL
EventHandler::supportsService( const ::rtl::OUString
& ServiceName
) throw (RuntimeException
)
532 StlSyntaxSequence
< ::rtl::OUString
> aAllServices( getSupportedServiceNames() );
533 return ::std::find( aAllServices
.begin(), aAllServices
.end(), ServiceName
) != aAllServices
.end();
536 //--------------------------------------------------------------------
537 Sequence
< ::rtl::OUString
> SAL_CALL
EventHandler::getSupportedServiceNames( ) throw (RuntimeException
)
539 return getSupportedServiceNames_static();
542 //--------------------------------------------------------------------
543 ::rtl::OUString SAL_CALL
EventHandler::getImplementationName_static( ) throw (RuntimeException
)
545 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.extensions.EventHandler" ) );
548 //--------------------------------------------------------------------
549 Sequence
< ::rtl::OUString
> SAL_CALL
EventHandler::getSupportedServiceNames_static( ) throw (RuntimeException
)
551 Sequence
< ::rtl::OUString
> aSupported( 1 );
552 aSupported
[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.form.inspection.EventHandler" ) );
556 //--------------------------------------------------------------------
557 Reference
< XInterface
> SAL_CALL
EventHandler::Create( const Reference
< XComponentContext
>& _rxContext
)
559 return *( new EventHandler( _rxContext
) );
562 //--------------------------------------------------------------------
563 void SAL_CALL
EventHandler::inspect( const Reference
< XInterface
>& _rxIntrospectee
) throw (RuntimeException
, NullPointerException
)
565 ::osl::MutexGuard
aGuard( m_aMutex
);
567 if ( !_rxIntrospectee
.is() )
568 throw NullPointerException();
570 m_xComponent
= Reference
< XPropertySet
>( _rxIntrospectee
, UNO_QUERY_THROW
);
572 m_bEventsMapInitialized
= false;
574 m_aEvents
.swap( aEmpty
);
576 m_bIsDialogElement
= false;
577 m_nGridColumnType
= -1;
580 Reference
< XPropertySetInfo
> xPSI( m_xComponent
->getPropertySetInfo() );
581 m_bIsDialogElement
= xPSI
.is()
582 && xPSI
->hasPropertyByName( PROPERTY_WIDTH
)
583 && xPSI
->hasPropertyByName( PROPERTY_HEIGHT
)
584 && xPSI
->hasPropertyByName( PROPERTY_POSITIONX
)
585 && xPSI
->hasPropertyByName( PROPERTY_POSITIONY
);
587 Reference
< XChild
> xAsChild( _rxIntrospectee
, UNO_QUERY
);
588 if ( xAsChild
.is() && !Reference
< XForm
>( _rxIntrospectee
, UNO_QUERY
).is() )
590 if ( FormComponentType::GRIDCONTROL
== classifyComponent( xAsChild
->getParent() ) )
592 m_nGridColumnType
= classifyComponent( _rxIntrospectee
);
596 catch( const Exception
& )
598 DBG_UNHANDLED_EXCEPTION();
602 //--------------------------------------------------------------------
603 Any SAL_CALL
EventHandler::getPropertyValue( const ::rtl::OUString
& _rPropertyName
) throw (UnknownPropertyException
, RuntimeException
)
605 ::osl::MutexGuard
aGuard( m_aMutex
);
607 const EventDescription
& rEvent
= impl_getEventForName_throw( _rPropertyName
);
609 Sequence
< ScriptEventDescriptor
> aEvents
;
610 impl_getComponentScriptEvents_nothrow( aEvents
);
612 sal_Int32 nEventCount
= aEvents
.getLength();
613 const ScriptEventDescriptor
* pEvents
= aEvents
.getConstArray();
615 ScriptEventDescriptor aPropertyValue
;
616 for ( sal_Int32 event
= 0; event
< nEventCount
; ++event
, ++pEvents
)
618 if ( rEvent
.sListenerClassName
== pEvents
->ListenerType
619 && rEvent
.sListenerMethodName
== pEvents
->EventMethod
622 aPropertyValue
= *pEvents
;
627 return makeAny( aPropertyValue
);
630 //--------------------------------------------------------------------
631 void SAL_CALL
EventHandler::setPropertyValue( const ::rtl::OUString
& _rPropertyName
, const Any
& _rValue
) throw (UnknownPropertyException
, RuntimeException
)
633 ::osl::MutexGuard
aGuard( m_aMutex
);
635 const EventDescription
& rEvent
= impl_getEventForName_throw( _rPropertyName
);
637 ScriptEventDescriptor aNewScriptEvent
;
638 OSL_VERIFY( _rValue
>>= aNewScriptEvent
);
640 ScriptEventDescriptor aOldScriptEvent
;
641 OSL_VERIFY( getPropertyValue( _rPropertyName
) >>= aOldScriptEvent
);
642 if ( aOldScriptEvent
== aNewScriptEvent
)
645 if ( m_bIsDialogElement
)
646 impl_setDialogElementScriptEvent_nothrow( aNewScriptEvent
);
648 impl_setFormComponentScriptEvent_nothrow( aNewScriptEvent
);
650 Reference
< XModifiable
> xDoc( m_aContext
.getContextValueByAsciiName( "ContextDocument" ), UNO_QUERY
);
652 xDoc
->setModified( sal_True
);
654 PropertyChangeEvent aEvent
;
655 aEvent
.Source
= m_xComponent
;
656 aEvent
.PropertyHandle
= rEvent
.nId
;
657 aEvent
.PropertyName
= _rPropertyName
;
658 aEvent
.OldValue
<<= aOldScriptEvent
;
659 aEvent
.NewValue
<<= aNewScriptEvent
;
660 m_aPropertyListeners
.notify( aEvent
, &XPropertyChangeListener::propertyChange
);
663 //--------------------------------------------------------------------
664 Any SAL_CALL
EventHandler::convertToPropertyValue( const ::rtl::OUString
& _rPropertyName
, const Any
& _rControlValue
) throw (UnknownPropertyException
, RuntimeException
)
666 ::osl::MutexGuard
aGuard( m_aMutex
);
668 ::rtl::OUString sNewScriptCode
;
669 OSL_VERIFY( _rControlValue
>>= sNewScriptCode
);
671 Sequence
< ScriptEventDescriptor
> aAllAssignedEvents
;
672 impl_getComponentScriptEvents_nothrow( aAllAssignedEvents
);
674 const EventDescription
& rEvent
= impl_getEventForName_throw( _rPropertyName
);
675 ScriptEventDescriptor aAssignedScript
= lcl_getAssignedScriptEvent( rEvent
, aAllAssignedEvents
);
677 OSL_ENSURE( !sNewScriptCode
.getLength(), "EventHandler::convertToPropertyValue: cannot convert a non-empty display name!" );
678 // Usually, there is no possibility for the user to change the content of an event binding directly in the
679 // input field, this instead is done with the macro assignment dialog.
680 // The only exception is the user pressing "DEL" while the control has the focus, in this case, we reset the
681 // control content to an empty string. So this is the only scenario where this method is allowed to be called.
683 // Striclty, we would be able to convert the display value to a property value,
684 // using the "name (location, language)" format we used in convertToControlValue. However,
685 // there is no need for this code ...
687 aAssignedScript
.ScriptCode
= sNewScriptCode
;
688 return makeAny( aAssignedScript
);
691 //--------------------------------------------------------------------
692 Any SAL_CALL
EventHandler::convertToControlValue( const ::rtl::OUString
& /*_rPropertyName*/, const Any
& _rPropertyValue
, const Type
& _rControlValueType
) throw (UnknownPropertyException
, RuntimeException
)
694 ::osl::MutexGuard
aGuard( m_aMutex
);
696 ScriptEventDescriptor aScriptEvent
;
697 OSL_VERIFY( _rPropertyValue
>>= aScriptEvent
);
699 OSL_ENSURE( _rControlValueType
.getTypeClass() == TypeClass_STRING
,
700 "EventHandler::convertToControlValue: unexpected ControlValue type class!" );
701 (void)_rControlValueType
;
703 ::rtl::OUString
sScript( aScriptEvent
.ScriptCode
);
704 if ( sScript
.getLength() )
706 // format is: "name (location, language)"
710 Reference
< XUriReferenceFactory
> xUriRefFac
= UriReferenceFactory::create( m_aContext
.getUNOContext() );
711 Reference
< XVndSunStarScriptUrlReference
> xScriptUri( xUriRefFac
->parse( sScript
), UNO_QUERY_THROW
);
713 ::rtl::OUStringBuffer aComposeBuffer
;
716 aComposeBuffer
.append( xScriptUri
->getName() );
719 const ::rtl::OUString
sLocationParamName( RTL_CONSTASCII_USTRINGPARAM( "location" ) );
720 const ::rtl::OUString sLocation
= xScriptUri
->getParameter( sLocationParamName
);
721 const ::rtl::OUString
sLangParamName( RTL_CONSTASCII_USTRINGPARAM( "language" ) );
722 const ::rtl::OUString sLanguage
= xScriptUri
->getParameter( sLangParamName
);
724 if ( sLocation
.getLength() || sLanguage
.getLength() )
726 aComposeBuffer
.appendAscii( " (" );
729 OSL_ENSURE( sLocation
.getLength(), "EventHandler::convertToControlValue: unexpected: no location!" );
730 if ( sLocation
.getLength() )
732 aComposeBuffer
.append( sLocation
);
733 aComposeBuffer
.appendAscii( ", " );
737 if ( sLanguage
.getLength() )
739 aComposeBuffer
.append( sLanguage
);
742 aComposeBuffer
.append( sal_Unicode( ')' ) );
745 sScript
= aComposeBuffer
.makeStringAndClear();
747 catch( const Exception
& )
749 DBG_UNHANDLED_EXCEPTION();
753 return makeAny( sScript
);
756 //--------------------------------------------------------------------
757 PropertyState SAL_CALL
EventHandler::getPropertyState( const ::rtl::OUString
& /*_rPropertyName*/ ) throw (UnknownPropertyException
, RuntimeException
)
759 return PropertyState_DIRECT_VALUE
;
762 //--------------------------------------------------------------------
763 void SAL_CALL
EventHandler::addPropertyChangeListener( const Reference
< XPropertyChangeListener
>& _rxListener
) throw (RuntimeException
)
765 ::osl::MutexGuard
aGuard( m_aMutex
);
766 if ( !_rxListener
.is() )
767 throw NullPointerException();
768 m_aPropertyListeners
.addListener( _rxListener
);
771 //--------------------------------------------------------------------
772 void SAL_CALL
EventHandler::removePropertyChangeListener( const Reference
< XPropertyChangeListener
>& _rxListener
) throw (RuntimeException
)
774 ::osl::MutexGuard
aGuard( m_aMutex
);
775 m_aPropertyListeners
.removeListener( _rxListener
);
778 //--------------------------------------------------------------------
779 Sequence
< Property
> SAL_CALL
EventHandler::getSupportedProperties() throw (RuntimeException
)
781 ::osl::MutexGuard
aGuard( m_aMutex
);
782 if ( !m_bEventsMapInitialized
)
784 const_cast< EventHandler
* >( this )->m_bEventsMapInitialized
= true;
787 Sequence
< Type
> aListeners
;
788 impl_getCopmonentListenerTypes_nothrow( aListeners
);
789 sal_Int32 listenerCount
= aListeners
.getLength();
791 Property aCurrentProperty
;
792 ::rtl::OUString sListenerClassName
;
794 // loop through all listeners and all methods, and see which we can present at the UI
795 const Type
* pListeners
= aListeners
.getConstArray();
796 for ( sal_Int32 listener
= 0; listener
< listenerCount
; ++listener
, ++pListeners
)
798 aCurrentProperty
= Property();
800 // the programmatic name of the listener, to be used as "property" name
801 sListenerClassName
= pListeners
->getTypeName();
802 OSL_ENSURE( sListenerClassName
.getLength(), "EventHandler::getSupportedProperties: strange - no listener name ..." );
803 if ( !sListenerClassName
.getLength() )
806 // loop through all methods
807 Sequence
< ::rtl::OUString
> aMethods( comphelper::getEventMethodsForType( *pListeners
) );
809 const ::rtl::OUString
* pMethods
= aMethods
.getConstArray();
810 sal_uInt32 methodCount
= aMethods
.getLength();
812 for (sal_uInt32 method
= 0 ; method
< methodCount
; ++method
, ++pMethods
)
814 EventDescription aEvent
;
815 if ( !lcl_getEventDescriptionForMethod( *pMethods
, aEvent
) )
818 if ( !impl_filterMethod_nothrow( aEvent
) )
821 const_cast< EventHandler
* >( this )->m_aEvents
.insert( EventMap::value_type(
822 lcl_getEventPropertyName( sListenerClassName
, *pMethods
), aEvent
) );
827 catch( const Exception
& )
829 DBG_UNHANDLED_EXCEPTION();
833 // sort them by ID - this is the relative ordering in the UI
834 ::std::map
< EventId
, Property
> aOrderedProperties
;
835 for ( EventMap::const_iterator loop
= m_aEvents
.begin();
836 loop
!= m_aEvents
.end();
840 aOrderedProperties
[ loop
->second
.nId
] = Property(
841 loop
->first
, loop
->second
.nId
,
842 ::getCppuType( static_cast< const ::rtl::OUString
* >( NULL
) ),
843 PropertyAttribute::BOUND
);
846 StlSyntaxSequence
< Property
> aReturn( aOrderedProperties
.size() );
847 ::std::transform( aOrderedProperties
.begin(), aOrderedProperties
.end(), aReturn
.begin(),
848 ::std::select2nd
< ::std::map
< EventId
, Property
>::value_type
>() );
852 //--------------------------------------------------------------------
853 Sequence
< ::rtl::OUString
> SAL_CALL
EventHandler::getSupersededProperties( ) throw (RuntimeException
)
856 return Sequence
< ::rtl::OUString
>( );
859 //--------------------------------------------------------------------
860 Sequence
< ::rtl::OUString
> SAL_CALL
EventHandler::getActuatingProperties( ) throw (RuntimeException
)
863 return Sequence
< ::rtl::OUString
>( );
866 //--------------------------------------------------------------------
867 LineDescriptor SAL_CALL
EventHandler::describePropertyLine( const ::rtl::OUString
& _rPropertyName
,
868 const Reference
< XPropertyControlFactory
>& _rxControlFactory
)
869 throw (UnknownPropertyException
, NullPointerException
, RuntimeException
)
871 if ( !_rxControlFactory
.is() )
872 throw NullPointerException();
874 ::osl::MutexGuard
aGuard( m_aMutex
);
876 LineDescriptor aDescriptor
;
878 aDescriptor
.Control
= _rxControlFactory
->createPropertyControl( PropertyControlType::TextField
, sal_True
);
879 Reference
< XEventListener
> xControlExtender
= new PropertyControlExtender( aDescriptor
.Control
);
881 const EventDescription
& rEvent
= impl_getEventForName_throw( _rPropertyName
);
882 aDescriptor
.DisplayName
= rEvent
.sDisplayName
;
883 aDescriptor
.HelpURL
= HelpIdUrl::getHelpURL( rEvent
.sHelpId
);
884 aDescriptor
.PrimaryButtonId
= rtl::OStringToOUString(rEvent
.sUniqueBrowseId
, RTL_TEXTENCODING_UTF8
);
885 aDescriptor
.HasPrimaryButton
= sal_True
;
886 aDescriptor
.Category
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Events" ) );
890 //--------------------------------------------------------------------
891 ::sal_Bool SAL_CALL
EventHandler::isComposable( const ::rtl::OUString
& /*_rPropertyName*/ ) throw (UnknownPropertyException
, RuntimeException
)
896 //--------------------------------------------------------------------
897 InteractiveSelectionResult SAL_CALL
EventHandler::onInteractivePropertySelection( const ::rtl::OUString
& _rPropertyName
, sal_Bool
/*_bPrimary*/, Any
& /*_rData*/, const Reference
< XObjectInspectorUI
>& _rxInspectorUI
) throw (UnknownPropertyException
, NullPointerException
, RuntimeException
)
899 if ( !_rxInspectorUI
.is() )
900 throw NullPointerException();
902 ::osl::MutexGuard
aGuard( m_aMutex
);
903 const EventDescription
& rForEvent
= impl_getEventForName_throw( _rPropertyName
);
905 Sequence
< ScriptEventDescriptor
> aAllAssignedEvents
;
906 impl_getComponentScriptEvents_nothrow( aAllAssignedEvents
);
908 // SvxMacroAssignDlg-compatible structure holding all event/assignments
909 ::rtl::Reference
< EventHolder
> pEventHolder( new EventHolder
);
911 for ( EventMap::const_iterator event
= m_aEvents
.begin();
912 event
!= m_aEvents
.end();
916 // the script which is assigned to the current event (if any)
917 ScriptEventDescriptor aAssignedScript
= lcl_getAssignedScriptEvent( event
->second
, aAllAssignedEvents
);
918 pEventHolder
->addEvent( event
->second
.nId
, event
->second
.sListenerMethodName
, aAssignedScript
);
921 // the inital selection in the dialog
922 Sequence
< ::rtl::OUString
> aNames( pEventHolder
->getElementNames() );
923 const ::rtl::OUString
* pChosenEvent
= ::std::find( aNames
.getConstArray(), aNames
.getConstArray() + aNames
.getLength(), rForEvent
.sListenerMethodName
);
924 sal_uInt16 nInitialSelection
= (sal_uInt16
)( pChosenEvent
- aNames
.getConstArray() );
927 SvxAbstractDialogFactory
* pFactory
= SvxAbstractDialogFactory::Create();
929 return InteractiveSelectionResult_Cancelled
;
931 ::std::auto_ptr
< VclAbstractDialog
> pDialog( pFactory
->CreateSvxMacroAssignDlg(
932 PropertyHandlerHelper::getDialogParentWindow( m_aContext
),
933 impl_getContextFrame_nothrow(),
939 if ( !pDialog
.get() )
940 return InteractiveSelectionResult_Cancelled
;
942 // DF definite problem here
943 // OK & Cancel seem to be both returning 0
944 if ( pDialog
->Execute() == RET_CANCEL
)
945 return InteractiveSelectionResult_Cancelled
;
949 for ( EventMap::const_iterator event
= m_aEvents
.begin();
950 event
!= m_aEvents
.end();
954 ScriptEventDescriptor
aScriptDescriptor( pEventHolder
->getNormalizedDescriptorByName( event
->second
.sListenerMethodName
) );
956 // set the new "property value"
958 lcl_getEventPropertyName( event
->second
.sListenerClassName
, event
->second
.sListenerMethodName
),
959 makeAny( aScriptDescriptor
)
963 catch( const Exception
& )
965 DBG_UNHANDLED_EXCEPTION();
968 return InteractiveSelectionResult_Success
;
971 //--------------------------------------------------------------------
972 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
)
974 DBG_ERROR( "EventHandler::actuatingPropertyChanged: no actuating properties -> no callback (well, this is how it *should* be!)" );
977 //--------------------------------------------------------------------
978 IMPLEMENT_FORWARD_XCOMPONENT( EventHandler
, EventHandler_Base
)
980 //--------------------------------------------------------------------
981 void SAL_CALL
EventHandler::disposing()
984 m_aEvents
.swap( aEmpty
);
985 m_xComponent
.clear();
988 //--------------------------------------------------------------------
989 sal_Bool SAL_CALL
EventHandler::suspend( sal_Bool
/*_bSuspend*/ ) throw (RuntimeException
)
994 //------------------------------------------------------------------------
995 Reference
< XFrame
> EventHandler::impl_getContextFrame_nothrow() const
997 Reference
< XFrame
> xContextFrame
;
1001 Reference
< XModel
> xContextDocument( m_aContext
.getContextValueByAsciiName( "ContextDocument" ), UNO_QUERY_THROW
);
1002 Reference
< XController
> xController( xContextDocument
->getCurrentController(), UNO_SET_THROW
);
1003 xContextFrame
.set( xController
->getFrame(), UNO_SET_THROW
);
1005 catch( const Exception
& )
1007 DBG_UNHANDLED_EXCEPTION();
1010 return xContextFrame
;
1013 //--------------------------------------------------------------------
1014 sal_Int32
EventHandler::impl_getComponentIndexInParent_throw() const
1016 Reference
< XChild
> xChild( m_xComponent
, UNO_QUERY_THROW
);
1017 Reference
< XIndexAccess
> xParentAsIndexAccess( xChild
->getParent(), UNO_QUERY_THROW
);
1019 // get the index of the inspected object within it's parent container
1020 sal_Int32 nElements
= xParentAsIndexAccess
->getCount();
1021 for ( sal_Int32 i
=0; i
<nElements
; ++i
)
1023 Reference
< XInterface
> xElement( xParentAsIndexAccess
->getByIndex( i
), UNO_QUERY_THROW
);
1024 if ( xElement
== m_xComponent
)
1027 throw NoSuchElementException();
1030 //--------------------------------------------------------------------
1031 void EventHandler::impl_getFormComponentScriptEvents_nothrow( Sequence
< ScriptEventDescriptor
>& _out_rEvents
) const
1033 _out_rEvents
= Sequence
< ScriptEventDescriptor
>();
1036 Reference
< XChild
> xChild( m_xComponent
, UNO_QUERY_THROW
);
1037 Reference
< XEventAttacherManager
> xEventManager( xChild
->getParent(), UNO_QUERY_THROW
);
1038 _out_rEvents
= xEventManager
->getScriptEvents( impl_getComponentIndexInParent_throw() );
1040 // the form component script API has unqualified listener names, but for normalization
1041 // purpose, we want fully qualified ones
1042 ScriptEventDescriptor
* pEvents
= _out_rEvents
.getArray();
1043 ScriptEventDescriptor
* pEventsEnd
= _out_rEvents
.getArray() + _out_rEvents
.getLength();
1044 while ( pEvents
!= pEventsEnd
)
1046 pEvents
->ListenerType
= lcl_getQualifiedKnownListenerName( *pEvents
);
1050 catch( const Exception
& )
1052 DBG_UNHANDLED_EXCEPTION();
1056 //--------------------------------------------------------------------
1057 void EventHandler::impl_getCopmonentListenerTypes_nothrow( Sequence
< Type
>& _out_rTypes
) const
1059 _out_rTypes
.realloc( 0 );
1062 // we use a set to avoid duplicates
1065 Reference
< XIntrospection
> xIntrospection( m_aContext
.createComponent( "com.sun.star.beans.Introspection" ), UNO_QUERY_THROW
);
1067 // --- model listeners
1068 lcl_addListenerTypesFor_throw(
1069 m_xComponent
, xIntrospection
, aListeners
);
1071 // --- "secondary component" (usually: "control" listeners)
1073 Reference
< XInterface
> xSecondaryComponent( impl_getSecondaryComponentForEventInspection_throw() );
1074 lcl_addListenerTypesFor_throw( xSecondaryComponent
, xIntrospection
, aListeners
);
1075 ::comphelper::disposeComponent( xSecondaryComponent
);
1078 // now that they're disambiguated, copy these types into our member
1079 _out_rTypes
.realloc( aListeners
.size() );
1080 ::std::copy( aListeners
.begin(), aListeners
.end(), _out_rTypes
.getArray() );
1082 catch( const Exception
& )
1084 DBG_UNHANDLED_EXCEPTION();
1088 //--------------------------------------------------------------------
1089 void EventHandler::impl_getDialogElementScriptEvents_nothrow( Sequence
< ScriptEventDescriptor
>& _out_rEvents
) const
1091 _out_rEvents
= Sequence
< ScriptEventDescriptor
>();
1094 Reference
< XScriptEventsSupplier
> xEventsSupplier( m_xComponent
, UNO_QUERY_THROW
);
1095 Reference
< XNameContainer
> xEvents( xEventsSupplier
->getEvents(), UNO_QUERY_THROW
);
1096 Sequence
< ::rtl::OUString
> aEventNames( xEvents
->getElementNames() );
1098 sal_Int32 nEventCount
= aEventNames
.getLength();
1099 _out_rEvents
.realloc( nEventCount
);
1101 const ::rtl::OUString
* pNames
= aEventNames
.getConstArray();
1102 ScriptEventDescriptor
* pDescs
= _out_rEvents
.getArray();
1104 for( sal_Int32 i
= 0 ; i
< nEventCount
; ++i
, ++pNames
, ++pDescs
)
1105 OSL_VERIFY( xEvents
->getByName( *pNames
) >>= *pDescs
);
1107 catch( const Exception
& )
1109 DBG_UNHANDLED_EXCEPTION();
1113 //--------------------------------------------------------------------
1114 Reference
< XInterface
> EventHandler::impl_getSecondaryComponentForEventInspection_throw( ) const
1116 Reference
< XInterface
> xReturn
;
1118 // if it's a form, create a form controller for the additional events
1119 Reference
< XForm
> xComponentAsForm( m_xComponent
, UNO_QUERY
);
1120 if ( xComponentAsForm
.is() )
1122 Reference
< XTabControllerModel
> xComponentAsTCModel( m_xComponent
, UNO_QUERY_THROW
);
1123 Reference
< XFormController
> xController(
1124 m_aContext
.createComponent( "com.sun.star.form.runtime.FormController" ), UNO_QUERY_THROW
);
1125 xController
->setModel( xComponentAsTCModel
);
1127 xReturn
= xController
;
1131 ::rtl::OUString sControlService
;
1132 OSL_VERIFY( m_xComponent
->getPropertyValue( PROPERTY_DEFAULTCONTROL
) >>= sControlService
);
1134 xReturn
= m_aContext
.createComponent( sControlService
);
1139 //--------------------------------------------------------------------
1140 const EventDescription
& EventHandler::impl_getEventForName_throw( const ::rtl::OUString
& _rPropertyName
) const
1142 EventMap::const_iterator pos
= m_aEvents
.find( _rPropertyName
);
1143 if ( pos
== m_aEvents
.end() )
1144 throw UnknownPropertyException();
1148 //--------------------------------------------------------------------
1151 static bool lcl_endsWith( const ::rtl::OUString
& _rText
, const ::rtl::OUString
& _rCheck
)
1153 sal_Int32 nTextLen
= _rText
.getLength();
1154 sal_Int32 nCheckLen
= _rCheck
.getLength();
1155 if ( nCheckLen
> nTextLen
)
1158 return _rText
.indexOf( _rCheck
) == ( nTextLen
- nCheckLen
);
1161 //--------------------------------------------------------------------
1162 void EventHandler::impl_setFormComponentScriptEvent_nothrow( const ScriptEventDescriptor
& _rScriptEvent
)
1166 ::rtl::OUString
sScriptCode( _rScriptEvent
.ScriptCode
);
1167 ::rtl::OUString
sScriptType( _rScriptEvent
.ScriptType
);
1168 bool bResetScript
= ( sScriptCode
.getLength() == 0 );
1170 sal_Int32 nObjectIndex
= impl_getComponentIndexInParent_throw();
1171 Reference
< XChild
> xChild( m_xComponent
, UNO_QUERY_THROW
);
1172 Reference
< XEventAttacherManager
> xEventManager( xChild
->getParent(), UNO_QUERY_THROW
);
1173 Sequence
< ScriptEventDescriptor
> aEvents( xEventManager
->getScriptEvents( nObjectIndex
) );
1175 // is there already a registered script for this event?
1176 ScriptEventDescriptor
* pEvent
= aEvents
.getArray();
1177 sal_Int32 eventCount
= aEvents
.getLength(), event
= 0;
1178 for ( event
= 0; event
< eventCount
; ++event
, ++pEvent
)
1180 if ( ( pEvent
->EventMethod
== _rScriptEvent
.EventMethod
)
1181 && ( lcl_endsWith( _rScriptEvent
.ListenerType
, pEvent
->ListenerType
) )
1182 // (strange enough, the events we get from getScriptEvents are not fully qualified)
1186 if ( !bResetScript
)
1188 // set to something non-empty -> overwrite
1189 pEvent
->ScriptCode
= sScriptCode
;
1190 pEvent
->ScriptType
= sScriptType
;
1194 // set to empty -> remove from sequence
1195 ::std::copy( pEvent
+ 1, aEvents
.getArray() + eventCount
, pEvent
);
1196 aEvents
.realloc( eventCount
- 1 );
1202 if ( ( event
>= eventCount
) && !bResetScript
)
1204 // no, did not find it -> append
1205 aEvents
.realloc( eventCount
+ 1 );
1206 aEvents
[ eventCount
] = _rScriptEvent
;
1209 xEventManager
->revokeScriptEvents( nObjectIndex
);
1210 xEventManager
->registerScriptEvents( nObjectIndex
, aEvents
);
1212 PropertyHandlerHelper::setContextDocumentModified( m_aContext
);
1214 catch( const Exception
& )
1216 DBG_UNHANDLED_EXCEPTION();
1220 //--------------------------------------------------------------------
1221 void EventHandler::impl_setDialogElementScriptEvent_nothrow( const ScriptEventDescriptor
& _rScriptEvent
)
1225 ::rtl::OUString
sScriptCode( _rScriptEvent
.ScriptCode
);
1226 bool bResetScript
= ( sScriptCode
.getLength() == 0 );
1228 Reference
< XScriptEventsSupplier
> xEventsSupplier( m_xComponent
, UNO_QUERY_THROW
);
1229 Reference
< XNameContainer
> xEvents( xEventsSupplier
->getEvents(), UNO_QUERY_THROW
);
1231 ::rtl::OUStringBuffer aCompleteName
;
1232 aCompleteName
.append( _rScriptEvent
.ListenerType
);
1233 aCompleteName
.appendAscii( "::" );
1234 aCompleteName
.append( _rScriptEvent
.EventMethod
);
1235 ::rtl::OUString
sCompleteName( aCompleteName
.makeStringAndClear() );
1237 bool bExists
= xEvents
->hasByName( sCompleteName
);
1242 xEvents
->removeByName( sCompleteName
);
1246 Any aNewValue
; aNewValue
<<= _rScriptEvent
;
1249 xEvents
->replaceByName( sCompleteName
, aNewValue
);
1251 xEvents
->insertByName( sCompleteName
, aNewValue
);
1254 catch( const Exception
& )
1256 DBG_UNHANDLED_EXCEPTION();
1260 //--------------------------------------------------------------------
1261 bool EventHandler::impl_filterMethod_nothrow( const EventDescription
& _rEvent
) const
1263 // some (control-triggered) events do not make sense for certain grid control columns. However,
1264 // our mechnism to retrieve control-triggered events does not know about this, so we do some
1265 // late filtering here.
1266 switch ( m_nGridColumnType
)
1268 case FormComponentType::COMBOBOX
:
1269 if ( UID_BRWEVT_ACTIONPERFORMED
== _rEvent
.sUniqueBrowseId
)
1272 case FormComponentType::LISTBOX
:
1273 if ( ( UID_BRWEVT_CHANGED
== _rEvent
.sUniqueBrowseId
)
1274 || ( UID_BRWEVT_ACTIONPERFORMED
== _rEvent
.sUniqueBrowseId
)
1283 //........................................................................
1285 //........................................................................