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>
81 //------------------------------------------------------------------------
82 extern "C" void SAL_CALL
createRegistryInfo_EventHandler()
84 ::pcr::OAutoRegistration
< ::pcr::EventHandler
> aAutoRegistration
;
87 //........................................................................
90 //........................................................................
92 /** === begin UNO using === **/
93 using ::com::sun::star::uno::Reference
;
94 using ::com::sun::star::uno::XComponentContext
;
95 using ::com::sun::star::beans::XPropertySet
;
96 using ::com::sun::star::uno::Any
;
97 using ::com::sun::star::uno::TypeClass_STRING
;
98 using ::com::sun::star::uno::Type
;
99 using ::com::sun::star::beans::XPropertyChangeListener
;
100 using ::com::sun::star::beans::Property
;
101 using ::com::sun::star::beans::PropertyState
;
102 using ::com::sun::star::beans::PropertyState_DIRECT_VALUE
;
103 using ::com::sun::star::uno::Sequence
;
104 using ::com::sun::star::script::ScriptEventDescriptor
;
105 using ::com::sun::star::script::XScriptEventsSupplier
;
106 using ::com::sun::star::lang::NullPointerException
;
107 using ::com::sun::star::uno::Exception
;
108 using ::com::sun::star::container::XChild
;
109 using ::com::sun::star::container::XIndexAccess
;
110 using ::com::sun::star::script::XEventAttacherManager
;
111 using ::com::sun::star::uno::UNO_QUERY
;
112 using ::com::sun::star::uno::UNO_QUERY_THROW
;
113 using ::com::sun::star::uno::XInterface
;
114 using ::com::sun::star::beans::XIntrospection
;
115 using ::com::sun::star::beans::XIntrospectionAccess
;
116 using ::com::sun::star::container::XNameContainer
;
117 using ::com::sun::star::awt::XTabControllerModel
;
118 using ::com::sun::star::form::XForm
;
119 using ::com::sun::star::form::runtime::XFormController
;
120 using ::com::sun::star::beans::UnknownPropertyException
;
121 using ::com::sun::star::uno::makeAny
;
122 using ::com::sun::star::container::NoSuchElementException
;
123 using ::com::sun::star::beans::XPropertySetInfo
;
124 using ::com::sun::star::container::XNameReplace
;
125 using ::com::sun::star::lang::IllegalArgumentException
;
126 using ::com::sun::star::lang::WrappedTargetException
;
127 using ::com::sun::star::uno::RuntimeException
;
128 using ::com::sun::star::beans::PropertyValue
;
129 using ::com::sun::star::inspection::LineDescriptor
;
130 using ::com::sun::star::inspection::XPropertyControlFactory
;
131 using ::com::sun::star::inspection::InteractiveSelectionResult
;
132 using ::com::sun::star::inspection::InteractiveSelectionResult_Cancelled
;
133 using ::com::sun::star::inspection::InteractiveSelectionResult_Success
;
134 using ::com::sun::star::inspection::XObjectInspectorUI
;
135 using ::com::sun::star::util::XModifiable
;
136 using ::com::sun::star::beans::PropertyChangeEvent
;
137 using ::com::sun::star::frame::XFrame
;
138 using ::com::sun::star::frame::XModel
;
139 using ::com::sun::star::frame::XController
;
140 using ::com::sun::star::uno::UNO_SET_THROW
;
141 using com::sun::star::uri::UriReferenceFactory
;
142 using com::sun::star::uri::XUriReferenceFactory
;
143 using com::sun::star::uri::XVndSunStarScriptUrlReference
;
144 using ::com::sun::star::lang::XEventListener
;
145 /** === end UNO using === **/
146 namespace PropertyControlType
= ::com::sun::star::inspection::PropertyControlType
;
147 namespace PropertyAttribute
= ::com::sun::star::beans::PropertyAttribute
;
148 namespace FormComponentType
= ::com::sun::star::form::FormComponentType
;
150 //====================================================================
152 //====================================================================
153 EventDescription::EventDescription( EventId _nId
, const sal_Char
* _pListenerNamespaceAscii
, const sal_Char
* _pListenerClassAsciiName
,
154 const sal_Char
* _pListenerMethodAsciiName
, sal_uInt16 _nDisplayNameResId
, sal_Int32 _nHelpId
, sal_Int32 _nUniqueBrowseId
)
155 :sDisplayName( String( PcrRes( _nDisplayNameResId
) ) )
156 ,sListenerMethodName( ::rtl::OUString::createFromAscii( _pListenerMethodAsciiName
) )
158 ,nUniqueBrowseId( _nUniqueBrowseId
)
161 ::rtl::OUStringBuffer aQualifiedListenerClass
;
162 aQualifiedListenerClass
.appendAscii( "com.sun.star." );
163 aQualifiedListenerClass
.appendAscii( _pListenerNamespaceAscii
);
164 aQualifiedListenerClass
.appendAscii( "." );
165 aQualifiedListenerClass
.appendAscii( _pListenerClassAsciiName
);
166 sListenerClassName
= aQualifiedListenerClass
.makeStringAndClear();
169 //========================================================================
171 //========================================================================
174 //....................................................................
175 #define DESCRIBE_EVENT( asciinamespace, asciilistener, asciimethod, id_postfix ) \
176 s_aKnownEvents.insert( EventMap::value_type( \
177 ::rtl::OUString::createFromAscii( asciimethod ), \
178 EventDescription( ++nEventId, asciinamespace, asciilistener, asciimethod, RID_STR_EVT_##id_postfix, HID_EVT_##id_postfix, UID_BRWEVT_##id_postfix ) ) )
180 //....................................................................
181 bool lcl_getEventDescriptionForMethod( const ::rtl::OUString
& _rMethodName
, EventDescription
& _out_rDescription
)
183 static EventMap s_aKnownEvents
;
184 if ( s_aKnownEvents
.empty() )
186 ::osl::MutexGuard
aGuard( ::osl::Mutex::getGlobalMutex() );
187 if ( s_aKnownEvents
.empty() )
189 static sal_Int32 nEventId
= 0;
191 DESCRIBE_EVENT( "form", "XApproveActionListener", "approveAction", APPROVEACTIONPERFORMED
);
192 DESCRIBE_EVENT( "awt", "XActionListener", "actionPerformed", ACTIONPERFORMED
);
193 DESCRIBE_EVENT( "form", "XChangeListener", "changed", CHANGED
);
194 DESCRIBE_EVENT( "awt", "XTextListener", "textChanged", TEXTCHANGED
);
195 DESCRIBE_EVENT( "awt", "XItemListener", "itemStateChanged", ITEMSTATECHANGED
);
196 DESCRIBE_EVENT( "awt", "XFocusListener", "focusGained", FOCUSGAINED
);
197 DESCRIBE_EVENT( "awt", "XFocusListener", "focusLost", FOCUSLOST
);
198 DESCRIBE_EVENT( "awt", "XKeyListener", "keyPressed", KEYTYPED
);
199 DESCRIBE_EVENT( "awt", "XKeyListener", "keyReleased", KEYUP
);
200 DESCRIBE_EVENT( "awt", "XMouseListener", "mouseEntered", MOUSEENTERED
);
201 DESCRIBE_EVENT( "awt", "XMouseMotionListener", "mouseDragged", MOUSEDRAGGED
);
202 DESCRIBE_EVENT( "awt", "XMouseMotionListener", "mouseMoved", MOUSEMOVED
);
203 DESCRIBE_EVENT( "awt", "XMouseListener", "mousePressed", MOUSEPRESSED
);
204 DESCRIBE_EVENT( "awt", "XMouseListener", "mouseReleased", MOUSERELEASED
);
205 DESCRIBE_EVENT( "awt", "XMouseListener", "mouseExited", MOUSEEXITED
);
206 DESCRIBE_EVENT( "form", "XResetListener", "approveReset", APPROVERESETTED
);
207 DESCRIBE_EVENT( "form", "XResetListener", "resetted", RESETTED
);
208 DESCRIBE_EVENT( "form", "XSubmitListener", "approveSubmit", SUBMITTED
);
209 DESCRIBE_EVENT( "form", "XUpdateListener", "approveUpdate", BEFOREUPDATE
);
210 DESCRIBE_EVENT( "form", "XUpdateListener", "updated", AFTERUPDATE
);
211 DESCRIBE_EVENT( "form", "XLoadListener", "loaded", LOADED
);
212 DESCRIBE_EVENT( "form", "XLoadListener", "reloading", RELOADING
);
213 DESCRIBE_EVENT( "form", "XLoadListener", "reloaded", RELOADED
);
214 DESCRIBE_EVENT( "form", "XLoadListener", "unloading", UNLOADING
);
215 DESCRIBE_EVENT( "form", "XLoadListener", "unloaded", UNLOADED
);
216 DESCRIBE_EVENT( "form", "XConfirmDeleteListener", "confirmDelete", CONFIRMDELETE
);
217 DESCRIBE_EVENT( "sdb", "XRowSetApproveListener", "approveRowChange", APPROVEROWCHANGE
);
218 DESCRIBE_EVENT( "sdbc", "XRowSetListener", "rowChanged", ROWCHANGE
);
219 DESCRIBE_EVENT( "sdb", "XRowSetApproveListener", "approveCursorMove", POSITIONING
);
220 DESCRIBE_EVENT( "sdbc", "XRowSetListener", "cursorMoved", POSITIONED
);
221 DESCRIBE_EVENT( "form", "XDatabaseParameterListener", "approveParameter", APPROVEPARAMETER
);
222 DESCRIBE_EVENT( "sdb", "XSQLErrorListener", "errorOccured", ERROROCCURED
);
223 DESCRIBE_EVENT( "awt", "XAdjustmentListener", "adjustmentValueChanged", ADJUSTMENTVALUECHANGED
);
227 EventMap::const_iterator pos
= s_aKnownEvents
.find( _rMethodName
);
228 if ( pos
== s_aKnownEvents
.end() )
231 _out_rDescription
= pos
->second
;
235 //....................................................................
236 ::rtl::OUString
lcl_getEventPropertyName( const ::rtl::OUString
& _rListenerClassName
, const ::rtl::OUString
& _rMethodName
)
238 ::rtl::OUStringBuffer aPropertyName
;
239 aPropertyName
.append( _rListenerClassName
);
240 aPropertyName
.append( (sal_Unicode
)';' );
241 aPropertyName
.append( _rMethodName
.getStr() );
242 return aPropertyName
.makeStringAndClear();
245 //................................................................
246 ScriptEventDescriptor
lcl_getAssignedScriptEvent( const EventDescription
& _rEvent
, const Sequence
< ScriptEventDescriptor
>& _rAllAssignedMacros
)
248 ScriptEventDescriptor aScriptEvent
;
249 // for the case there is actually no event assigned, initialize at least ListenerType and MethodName,
250 // so this ScriptEventDescriptor properly describes the given event
251 aScriptEvent
.ListenerType
= _rEvent
.sListenerClassName
;
252 aScriptEvent
.EventMethod
= _rEvent
.sListenerMethodName
;
254 const ScriptEventDescriptor
* pAssignedEvent
= _rAllAssignedMacros
.getConstArray();
255 sal_Int32
assignedEventCount( _rAllAssignedMacros
.getLength() );
256 for ( sal_Int32 assignedEvent
= 0; assignedEvent
< assignedEventCount
; ++assignedEvent
, ++pAssignedEvent
)
258 if ( ( pAssignedEvent
->ListenerType
!= _rEvent
.sListenerClassName
)
259 || ( pAssignedEvent
->EventMethod
!= _rEvent
.sListenerMethodName
)
263 if ( ( pAssignedEvent
->ScriptCode
.getLength() == 0 )
264 || ( pAssignedEvent
->ScriptType
.getLength() == 0 )
267 DBG_ERROR( "lcl_getAssignedScriptEvent: me thinks this should not happen!" );
271 aScriptEvent
= *pAssignedEvent
;
273 if ( !aScriptEvent
.ScriptType
.equalsAscii( "StarBasic" ) )
276 // this is an old-style macro specification:
277 // [document|application]:Library.Module.Function
278 // we need to translate this to the new-style macro specification
279 // vnd.sun.star.script:Library.Module.Function?language=Basic&location=[document|application]
281 sal_Int32 nPrefixLen
= aScriptEvent
.ScriptCode
.indexOf( ':' );
282 OSL_ENSURE( nPrefixLen
> 0, "lcl_getAssignedScriptEvent: illegal location!" );
283 ::rtl::OUString sLocation
= aScriptEvent
.ScriptCode
.copy( 0, nPrefixLen
);
284 ::rtl::OUString sMacroPath
= aScriptEvent
.ScriptCode
.copy( nPrefixLen
+ 1 );
286 ::rtl::OUStringBuffer aNewStyleSpec
;
287 aNewStyleSpec
.appendAscii( "vnd.sun.star.script:" );
288 aNewStyleSpec
.append ( sMacroPath
);
289 aNewStyleSpec
.appendAscii( "?language=Basic&location=" );
290 aNewStyleSpec
.append ( sLocation
);
292 aScriptEvent
.ScriptCode
= aNewStyleSpec
.makeStringAndClear();
294 // also, this new-style spec requires the script code to be "Script" instead of "StarBasic"
295 aScriptEvent
.ScriptType
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Script" ) );
300 //................................................................
301 ::rtl::OUString
lcl_getQualifiedKnownListenerName( const ScriptEventDescriptor
& _rFormComponentEventDescriptor
)
303 EventDescription aKnownEvent
;
304 if ( lcl_getEventDescriptionForMethod( _rFormComponentEventDescriptor
.EventMethod
, aKnownEvent
) )
305 return aKnownEvent
.sListenerClassName
;
306 DBG_ERROR( "lcl_getQualifiedKnownListenerName: unknown method name!" );
307 // somebody assigned an script to a form component event which we don't know
308 // Speaking strictly, this is not really an error - it is possible to do
309 // this programmatically -, but it should rarely happen, since it's not possible
311 return _rFormComponentEventDescriptor
.ListenerType
;
314 //................................................................
315 typedef ::std::set
< Type
, TypeLessByName
> TypeBag
;
317 //................................................................
318 void lcl_addListenerTypesFor_throw( const Reference
< XInterface
>& _rxComponent
,
319 const Reference
< XIntrospection
>& _rxIntrospection
, TypeBag
& _out_rTypes
)
321 if ( !_rxComponent
.is() )
323 OSL_PRECOND( _rxIntrospection
.is(), "lcl_addListenerTypesFor_throw: this will crash!" );
325 Reference
< XIntrospectionAccess
> xIntrospectionAccess(
326 _rxIntrospection
->inspect( makeAny( _rxComponent
) ), UNO_QUERY_THROW
);
328 Sequence
< Type
> aListeners( xIntrospectionAccess
->getSupportedListeners() );
330 ::std::copy( aListeners
.getConstArray(), aListeners
.getConstArray() + aListeners
.getLength(),
331 ::std::insert_iterator
< TypeBag
>( _out_rTypes
, _out_rTypes
.begin() ) );
334 //................................................................
335 bool operator ==( const ScriptEventDescriptor _lhs
, const ScriptEventDescriptor _rhs
)
337 return ( ( _lhs
.ListenerType
== _rhs
.ListenerType
)
338 && ( _lhs
.EventMethod
== _rhs
.EventMethod
)
339 && ( _lhs
.AddListenerParam
== _rhs
.AddListenerParam
)
340 && ( _lhs
.ScriptType
== _rhs
.ScriptType
)
341 && ( _lhs
.ScriptCode
== _rhs
.ScriptCode
)
346 //====================================================================
348 //====================================================================
349 typedef ::cppu::WeakImplHelper1
< ::com::sun::star::container::XNameReplace
351 /** a UNO component holding assigned event descriptions, for use with a SvxMacroAssignDlg
353 class EventHolder
: public EventHolder_Base
356 typedef ::std::hash_map
< ::rtl::OUString
, ScriptEventDescriptor
, ::rtl::OUStringHash
> EventMap
;
357 typedef ::std::map
< EventId
, EventMap::iterator
> EventMapIndexAccess
;
359 EventMap m_aEventNameAccess
;
360 EventMapIndexAccess m_aEventIndexAccess
;
365 void addEvent( EventId _nId
, const ::rtl::OUString
& _rEventName
, const ScriptEventDescriptor
& _rScriptEvent
);
367 /** effectively the same as getByName, but instead of converting the ScriptEventDescriptor to the weird
368 format used by the macro assignment dialog, it is returned directly
370 ScriptEventDescriptor
getNormalizedDescriptorByName( const ::rtl::OUString
& _rEventName
) const;
373 virtual void SAL_CALL
replaceByName( const ::rtl::OUString
& _rName
, const Any
& aElement
) throw (IllegalArgumentException
, NoSuchElementException
, WrappedTargetException
, RuntimeException
);
374 virtual Any SAL_CALL
getByName( const ::rtl::OUString
& _rName
) throw (NoSuchElementException
, WrappedTargetException
, RuntimeException
);
375 virtual Sequence
< ::rtl::OUString
> SAL_CALL
getElementNames( ) throw (RuntimeException
);
376 virtual ::sal_Bool SAL_CALL
hasByName( const ::rtl::OUString
& _rName
) throw (RuntimeException
);
377 virtual Type SAL_CALL
getElementType( ) throw (RuntimeException
);
378 virtual ::sal_Bool SAL_CALL
hasElements( ) throw (RuntimeException
);
384 ScriptEventDescriptor
impl_getDescriptor_throw( const ::rtl::OUString
& _rEventName
) const;
387 DBG_NAME( EventHolder
)
388 //------------------------------------------------------------------------
389 EventHolder::EventHolder()
391 DBG_CTOR( EventHolder
, NULL
);
394 //------------------------------------------------------------------------
395 EventHolder::~EventHolder()
397 m_aEventNameAccess
.clear();
398 m_aEventIndexAccess
.clear();
399 DBG_DTOR( EventHolder
, NULL
);
402 //------------------------------------------------------------------------
403 void EventHolder::addEvent( EventId _nId
, const ::rtl::OUString
& _rEventName
, const ScriptEventDescriptor
& _rScriptEvent
)
405 ::std::pair
< EventMap::iterator
, bool > insertionResult
=
406 m_aEventNameAccess
.insert( EventMap::value_type( _rEventName
, _rScriptEvent
) );
407 OSL_ENSURE( insertionResult
.second
, "EventHolder::addEvent: there already was a MacroURL for this event!" );
408 m_aEventIndexAccess
[ _nId
] = insertionResult
.first
;
411 //------------------------------------------------------------------------
412 ScriptEventDescriptor
EventHolder::getNormalizedDescriptorByName( const ::rtl::OUString
& _rEventName
) const
414 return impl_getDescriptor_throw( _rEventName
);
417 //------------------------------------------------------------------------
418 ScriptEventDescriptor
EventHolder::impl_getDescriptor_throw( const ::rtl::OUString
& _rEventName
) const
420 EventMap::const_iterator pos
= m_aEventNameAccess
.find( _rEventName
);
421 if ( pos
== m_aEventNameAccess
.end() )
422 throw NoSuchElementException( ::rtl::OUString(), *const_cast< EventHolder
* >( this ) );
426 //------------------------------------------------------------------------
427 void SAL_CALL
EventHolder::replaceByName( const ::rtl::OUString
& _rName
, const Any
& _rElement
) throw (IllegalArgumentException
, NoSuchElementException
, WrappedTargetException
, RuntimeException
)
429 EventMap::iterator pos
= m_aEventNameAccess
.find( _rName
);
430 if ( pos
== m_aEventNameAccess
.end() )
431 throw NoSuchElementException( ::rtl::OUString(), *this );
433 Sequence
< PropertyValue
> aScriptDescriptor
;
434 OSL_VERIFY( _rElement
>>= aScriptDescriptor
);
436 ::comphelper::NamedValueCollection
aExtractor( aScriptDescriptor
);
438 pos
->second
.ScriptType
= aExtractor
.getOrDefault( "EventType", ::rtl::OUString() );
439 pos
->second
.ScriptCode
= aExtractor
.getOrDefault( "Script", ::rtl::OUString() );
442 //------------------------------------------------------------------------
443 Any SAL_CALL
EventHolder::getByName( const ::rtl::OUString
& _rName
) throw (NoSuchElementException
, WrappedTargetException
, RuntimeException
)
445 ScriptEventDescriptor
aDescriptor( impl_getDescriptor_throw( _rName
) );
448 Sequence
< PropertyValue
> aScriptDescriptor( 2 );
449 aScriptDescriptor
[0].Name
= ::rtl::OUString::createFromAscii( "EventType" );
450 aScriptDescriptor
[0].Value
<<= aDescriptor
.ScriptType
;
451 aScriptDescriptor
[1].Name
= ::rtl::OUString::createFromAscii( "Script" );
452 aScriptDescriptor
[1].Value
<<= aDescriptor
.ScriptCode
;
454 return makeAny( aScriptDescriptor
);
457 //------------------------------------------------------------------------
458 Sequence
< ::rtl::OUString
> SAL_CALL
EventHolder::getElementNames( ) throw (RuntimeException
)
460 Sequence
< ::rtl::OUString
> aReturn( m_aEventIndexAccess
.size() );
461 ::rtl::OUString
* pReturn
= aReturn
.getArray();
463 // SvxMacroAssignDlg has a weird API: It expects a XNameReplace, means a container whose
464 // main access method is by name. In it's UI, it shows the possible events in exactly the
465 // order in which XNameAccess::getElementNames returns them.
466 // However, SvxMacroAssignDlg *also* takes an index for the initial selection, which is
467 // relative to the sequence returned by XNameAccess::getElementNames.
468 // This is IMO weird, since it mixes index access with name access, which decreases efficiency
469 // of the implementation.
470 // Well, it means we're forced to return the events in getElementNames in exactly the same as they
471 // appear in the property browser UI.
472 for ( EventMapIndexAccess::const_iterator loop
= m_aEventIndexAccess
.begin();
473 loop
!= m_aEventIndexAccess
.end();
476 *pReturn
= loop
->second
->first
;
480 //------------------------------------------------------------------------
481 sal_Bool SAL_CALL
EventHolder::hasByName( const ::rtl::OUString
& _rName
) throw (RuntimeException
)
483 EventMap::const_iterator pos
= m_aEventNameAccess
.find( _rName
);
484 return pos
!= m_aEventNameAccess
.end();
487 //------------------------------------------------------------------------
488 Type SAL_CALL
EventHolder::getElementType( ) throw (RuntimeException
)
490 return ::getCppuType( static_cast< Sequence
< PropertyValue
>* >( NULL
) );
493 //------------------------------------------------------------------------
494 sal_Bool SAL_CALL
EventHolder::hasElements( ) throw (RuntimeException
)
496 return !m_aEventNameAccess
.empty();
500 //====================================================================
502 //====================================================================
503 DBG_NAME( EventHandler
)
504 //--------------------------------------------------------------------
505 EventHandler::EventHandler( const Reference
< XComponentContext
>& _rxContext
)
506 :EventHandler_Base( m_aMutex
)
507 ,m_aContext( _rxContext
)
508 ,m_aPropertyListeners( m_aMutex
)
509 ,m_bEventsMapInitialized( false )
510 ,m_bIsDialogElement( false )
511 ,m_nGridColumnType( -1 )
513 DBG_CTOR( EventHandler
, NULL
);
516 //--------------------------------------------------------------------
517 EventHandler::~EventHandler()
519 DBG_DTOR( EventHandler
, NULL
);
522 //--------------------------------------------------------------------
523 ::rtl::OUString SAL_CALL
EventHandler::getImplementationName( ) throw (RuntimeException
)
525 return getImplementationName_static();
528 //--------------------------------------------------------------------
529 ::sal_Bool SAL_CALL
EventHandler::supportsService( const ::rtl::OUString
& ServiceName
) throw (RuntimeException
)
531 StlSyntaxSequence
< ::rtl::OUString
> aAllServices( getSupportedServiceNames() );
532 return ::std::find( aAllServices
.begin(), aAllServices
.end(), ServiceName
) != aAllServices
.end();
535 //--------------------------------------------------------------------
536 Sequence
< ::rtl::OUString
> SAL_CALL
EventHandler::getSupportedServiceNames( ) throw (RuntimeException
)
538 return getSupportedServiceNames_static();
541 //--------------------------------------------------------------------
542 ::rtl::OUString SAL_CALL
EventHandler::getImplementationName_static( ) throw (RuntimeException
)
544 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.extensions.EventHandler" ) );
547 //--------------------------------------------------------------------
548 Sequence
< ::rtl::OUString
> SAL_CALL
EventHandler::getSupportedServiceNames_static( ) throw (RuntimeException
)
550 Sequence
< ::rtl::OUString
> aSupported( 1 );
551 aSupported
[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.form.inspection.EventHandler" ) );
555 //--------------------------------------------------------------------
556 Reference
< XInterface
> SAL_CALL
EventHandler::Create( const Reference
< XComponentContext
>& _rxContext
)
558 return *( new EventHandler( _rxContext
) );
561 //--------------------------------------------------------------------
562 void SAL_CALL
EventHandler::inspect( const Reference
< XInterface
>& _rxIntrospectee
) throw (RuntimeException
, NullPointerException
)
564 ::osl::MutexGuard
aGuard( m_aMutex
);
566 if ( !_rxIntrospectee
.is() )
567 throw NullPointerException();
569 m_xComponent
= Reference
< XPropertySet
>( _rxIntrospectee
, UNO_QUERY_THROW
);
571 m_bEventsMapInitialized
= false;
573 m_aEvents
.swap( aEmpty
);
575 m_bIsDialogElement
= false;
576 m_nGridColumnType
= -1;
579 Reference
< XPropertySetInfo
> xPSI( m_xComponent
->getPropertySetInfo() );
580 m_bIsDialogElement
= xPSI
.is()
581 && xPSI
->hasPropertyByName( PROPERTY_WIDTH
)
582 && xPSI
->hasPropertyByName( PROPERTY_HEIGHT
)
583 && xPSI
->hasPropertyByName( PROPERTY_POSITIONX
)
584 && xPSI
->hasPropertyByName( PROPERTY_POSITIONY
);
586 Reference
< XChild
> xAsChild( _rxIntrospectee
, UNO_QUERY
);
587 if ( xAsChild
.is() && !Reference
< XForm
>( _rxIntrospectee
, UNO_QUERY
).is() )
589 if ( FormComponentType::GRIDCONTROL
== classifyComponent( xAsChild
->getParent() ) )
591 m_nGridColumnType
= classifyComponent( _rxIntrospectee
);
595 catch( const Exception
& )
597 DBG_UNHANDLED_EXCEPTION();
601 //--------------------------------------------------------------------
602 Any SAL_CALL
EventHandler::getPropertyValue( const ::rtl::OUString
& _rPropertyName
) throw (UnknownPropertyException
, RuntimeException
)
604 ::osl::MutexGuard
aGuard( m_aMutex
);
606 const EventDescription
& rEvent
= impl_getEventForName_throw( _rPropertyName
);
608 Sequence
< ScriptEventDescriptor
> aEvents
;
609 impl_getComponentScriptEvents_nothrow( aEvents
);
611 sal_Int32 nEventCount
= aEvents
.getLength();
612 const ScriptEventDescriptor
* pEvents
= aEvents
.getConstArray();
614 ScriptEventDescriptor aPropertyValue
;
615 for ( sal_Int32 event
= 0; event
< nEventCount
; ++event
, ++pEvents
)
617 if ( rEvent
.sListenerClassName
== pEvents
->ListenerType
618 && rEvent
.sListenerMethodName
== pEvents
->EventMethod
621 aPropertyValue
= *pEvents
;
626 return makeAny( aPropertyValue
);
629 //--------------------------------------------------------------------
630 void SAL_CALL
EventHandler::setPropertyValue( const ::rtl::OUString
& _rPropertyName
, const Any
& _rValue
) throw (UnknownPropertyException
, RuntimeException
)
632 ::osl::MutexGuard
aGuard( m_aMutex
);
634 const EventDescription
& rEvent
= impl_getEventForName_throw( _rPropertyName
);
636 ScriptEventDescriptor aNewScriptEvent
;
637 OSL_VERIFY( _rValue
>>= aNewScriptEvent
);
639 ScriptEventDescriptor aOldScriptEvent
;
640 OSL_VERIFY( getPropertyValue( _rPropertyName
) >>= aOldScriptEvent
);
641 if ( aOldScriptEvent
== aNewScriptEvent
)
644 if ( m_bIsDialogElement
)
645 impl_setDialogElementScriptEvent_nothrow( aNewScriptEvent
);
647 impl_setFormComponentScriptEvent_nothrow( aNewScriptEvent
);
649 Reference
< XModifiable
> xDoc( m_aContext
.getContextValueByAsciiName( "ContextDocument" ), UNO_QUERY
);
651 xDoc
->setModified( sal_True
);
653 PropertyChangeEvent aEvent
;
654 aEvent
.Source
= m_xComponent
;
655 aEvent
.PropertyHandle
= rEvent
.nId
;
656 aEvent
.PropertyName
= _rPropertyName
;
657 aEvent
.OldValue
<<= aOldScriptEvent
;
658 aEvent
.NewValue
<<= aNewScriptEvent
;
659 m_aPropertyListeners
.notify( aEvent
, &XPropertyChangeListener::propertyChange
);
662 //--------------------------------------------------------------------
663 Any SAL_CALL
EventHandler::convertToPropertyValue( const ::rtl::OUString
& _rPropertyName
, const Any
& _rControlValue
) throw (UnknownPropertyException
, RuntimeException
)
665 ::osl::MutexGuard
aGuard( m_aMutex
);
667 ::rtl::OUString sNewScriptCode
;
668 OSL_VERIFY( _rControlValue
>>= sNewScriptCode
);
670 Sequence
< ScriptEventDescriptor
> aAllAssignedEvents
;
671 impl_getComponentScriptEvents_nothrow( aAllAssignedEvents
);
673 const EventDescription
& rEvent
= impl_getEventForName_throw( _rPropertyName
);
674 ScriptEventDescriptor aAssignedScript
= lcl_getAssignedScriptEvent( rEvent
, aAllAssignedEvents
);
676 OSL_ENSURE( !sNewScriptCode
.getLength(), "EventHandler::convertToPropertyValue: cannot convert a non-empty display name!" );
677 // Usually, there is no possibility for the user to change the content of an event binding directly in the
678 // input field, this instead is done with the macro assignment dialog.
679 // The only exception is the user pressing "DEL" while the control has the focus, in this case, we reset the
680 // control content to an empty string. So this is the only scenario where this method is allowed to be called.
682 // Striclty, we would be able to convert the display value to a property value,
683 // using the "name (location, language)" format we used in convertToControlValue. However,
684 // there is no need for this code ...
686 aAssignedScript
.ScriptCode
= sNewScriptCode
;
687 return makeAny( aAssignedScript
);
690 //--------------------------------------------------------------------
691 Any SAL_CALL
EventHandler::convertToControlValue( const ::rtl::OUString
& /*_rPropertyName*/, const Any
& _rPropertyValue
, const Type
& _rControlValueType
) throw (UnknownPropertyException
, RuntimeException
)
693 ::osl::MutexGuard
aGuard( m_aMutex
);
695 ScriptEventDescriptor aScriptEvent
;
696 OSL_VERIFY( _rPropertyValue
>>= aScriptEvent
);
698 OSL_ENSURE( _rControlValueType
.getTypeClass() == TypeClass_STRING
,
699 "EventHandler::convertToControlValue: unexpected ControlValue type class!" );
700 (void)_rControlValueType
;
702 ::rtl::OUString
sScript( aScriptEvent
.ScriptCode
);
703 if ( sScript
.getLength() )
705 // format is: "name (location, language)"
709 Reference
< XUriReferenceFactory
> xUriRefFac
= UriReferenceFactory::create( m_aContext
.getUNOContext() );
710 Reference
< XVndSunStarScriptUrlReference
> xScriptUri( xUriRefFac
->parse( sScript
), UNO_QUERY_THROW
);
712 ::rtl::OUStringBuffer aComposeBuffer
;
715 aComposeBuffer
.append( xScriptUri
->getName() );
718 const ::rtl::OUString
sLocationParamName( RTL_CONSTASCII_USTRINGPARAM( "location" ) );
719 const ::rtl::OUString sLocation
= xScriptUri
->getParameter( sLocationParamName
);
720 const ::rtl::OUString
sLangParamName( RTL_CONSTASCII_USTRINGPARAM( "language" ) );
721 const ::rtl::OUString sLanguage
= xScriptUri
->getParameter( sLangParamName
);
723 if ( sLocation
.getLength() || sLanguage
.getLength() )
725 aComposeBuffer
.appendAscii( " (" );
728 OSL_ENSURE( sLocation
.getLength(), "EventHandler::convertToControlValue: unexpected: no location!" );
729 if ( sLocation
.getLength() )
731 aComposeBuffer
.append( sLocation
);
732 aComposeBuffer
.appendAscii( ", " );
736 if ( sLanguage
.getLength() )
738 aComposeBuffer
.append( sLanguage
);
741 aComposeBuffer
.append( sal_Unicode( ')' ) );
744 sScript
= aComposeBuffer
.makeStringAndClear();
746 catch( const Exception
& )
748 DBG_UNHANDLED_EXCEPTION();
752 return makeAny( sScript
);
755 //--------------------------------------------------------------------
756 PropertyState SAL_CALL
EventHandler::getPropertyState( const ::rtl::OUString
& /*_rPropertyName*/ ) throw (UnknownPropertyException
, RuntimeException
)
758 return PropertyState_DIRECT_VALUE
;
761 //--------------------------------------------------------------------
762 void SAL_CALL
EventHandler::addPropertyChangeListener( const Reference
< XPropertyChangeListener
>& _rxListener
) throw (RuntimeException
)
764 ::osl::MutexGuard
aGuard( m_aMutex
);
765 if ( !_rxListener
.is() )
766 throw NullPointerException();
767 m_aPropertyListeners
.addListener( _rxListener
);
770 //--------------------------------------------------------------------
771 void SAL_CALL
EventHandler::removePropertyChangeListener( const Reference
< XPropertyChangeListener
>& _rxListener
) throw (RuntimeException
)
773 ::osl::MutexGuard
aGuard( m_aMutex
);
774 m_aPropertyListeners
.removeListener( _rxListener
);
777 //--------------------------------------------------------------------
778 Sequence
< Property
> SAL_CALL
EventHandler::getSupportedProperties() throw (RuntimeException
)
780 ::osl::MutexGuard
aGuard( m_aMutex
);
781 if ( !m_bEventsMapInitialized
)
783 const_cast< EventHandler
* >( this )->m_bEventsMapInitialized
= true;
786 Sequence
< Type
> aListeners
;
787 impl_getCopmonentListenerTypes_nothrow( aListeners
);
788 sal_Int32 listenerCount
= aListeners
.getLength();
790 Property aCurrentProperty
;
791 ::rtl::OUString sListenerClassName
;
793 // loop through all listeners and all methods, and see which we can present at the UI
794 const Type
* pListeners
= aListeners
.getConstArray();
795 for ( sal_Int32 listener
= 0; listener
< listenerCount
; ++listener
, ++pListeners
)
797 aCurrentProperty
= Property();
799 // the programmatic name of the listener, to be used as "property" name
800 sListenerClassName
= pListeners
->getTypeName();
801 OSL_ENSURE( sListenerClassName
.getLength(), "EventHandler::getSupportedProperties: strange - no listener name ..." );
802 if ( !sListenerClassName
.getLength() )
805 // loop through all methods
806 Sequence
< ::rtl::OUString
> aMethods( comphelper::getEventMethodsForType( *pListeners
) );
808 const ::rtl::OUString
* pMethods
= aMethods
.getConstArray();
809 sal_uInt32 methodCount
= aMethods
.getLength();
811 for (sal_uInt32 method
= 0 ; method
< methodCount
; ++method
, ++pMethods
)
813 EventDescription aEvent
;
814 if ( !lcl_getEventDescriptionForMethod( *pMethods
, aEvent
) )
817 if ( !impl_filterMethod_nothrow( aEvent
) )
820 const_cast< EventHandler
* >( this )->m_aEvents
.insert( EventMap::value_type(
821 lcl_getEventPropertyName( sListenerClassName
, *pMethods
), aEvent
) );
826 catch( const Exception
& )
828 DBG_UNHANDLED_EXCEPTION();
832 // sort them by ID - this is the relative ordering in the UI
833 ::std::map
< EventId
, Property
> aOrderedProperties
;
834 for ( EventMap::const_iterator loop
= m_aEvents
.begin();
835 loop
!= m_aEvents
.end();
839 aOrderedProperties
[ loop
->second
.nId
] = Property(
840 loop
->first
, loop
->second
.nId
,
841 ::getCppuType( static_cast< const ::rtl::OUString
* >( NULL
) ),
842 PropertyAttribute::BOUND
);
845 StlSyntaxSequence
< Property
> aReturn( aOrderedProperties
.size() );
846 ::std::transform( aOrderedProperties
.begin(), aOrderedProperties
.end(), aReturn
.begin(),
847 ::std::select2nd
< ::std::map
< EventId
, Property
>::value_type
>() );
851 //--------------------------------------------------------------------
852 Sequence
< ::rtl::OUString
> SAL_CALL
EventHandler::getSupersededProperties( ) throw (RuntimeException
)
855 return Sequence
< ::rtl::OUString
>( );
858 //--------------------------------------------------------------------
859 Sequence
< ::rtl::OUString
> SAL_CALL
EventHandler::getActuatingProperties( ) throw (RuntimeException
)
862 return Sequence
< ::rtl::OUString
>( );
865 //--------------------------------------------------------------------
866 LineDescriptor SAL_CALL
EventHandler::describePropertyLine( const ::rtl::OUString
& _rPropertyName
,
867 const Reference
< XPropertyControlFactory
>& _rxControlFactory
)
868 throw (UnknownPropertyException
, NullPointerException
, RuntimeException
)
870 if ( !_rxControlFactory
.is() )
871 throw NullPointerException();
873 ::osl::MutexGuard
aGuard( m_aMutex
);
875 LineDescriptor aDescriptor
;
877 aDescriptor
.Control
= _rxControlFactory
->createPropertyControl( PropertyControlType::TextField
, sal_True
);
878 Reference
< XEventListener
> xControlExtender
= new PropertyControlExtender( aDescriptor
.Control
);
880 const EventDescription
& rEvent
= impl_getEventForName_throw( _rPropertyName
);
881 aDescriptor
.DisplayName
= rEvent
.sDisplayName
;
882 aDescriptor
.HelpURL
= HelpIdUrl::getHelpURL( rEvent
.nHelpId
);
883 aDescriptor
.PrimaryButtonId
= rEvent
.nUniqueBrowseId
;
884 aDescriptor
.HasPrimaryButton
= sal_True
;
885 aDescriptor
.Category
= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Events" ) );
889 //--------------------------------------------------------------------
890 ::sal_Bool SAL_CALL
EventHandler::isComposable( const ::rtl::OUString
& /*_rPropertyName*/ ) throw (UnknownPropertyException
, RuntimeException
)
895 //--------------------------------------------------------------------
896 InteractiveSelectionResult SAL_CALL
EventHandler::onInteractivePropertySelection( const ::rtl::OUString
& _rPropertyName
, sal_Bool
/*_bPrimary*/, Any
& /*_rData*/, const Reference
< XObjectInspectorUI
>& _rxInspectorUI
) throw (UnknownPropertyException
, NullPointerException
, RuntimeException
)
898 if ( !_rxInspectorUI
.is() )
899 throw NullPointerException();
901 ::osl::MutexGuard
aGuard( m_aMutex
);
902 const EventDescription
& rForEvent
= impl_getEventForName_throw( _rPropertyName
);
904 Sequence
< ScriptEventDescriptor
> aAllAssignedEvents
;
905 impl_getComponentScriptEvents_nothrow( aAllAssignedEvents
);
907 // SvxMacroAssignDlg-compatible structure holding all event/assignments
908 ::rtl::Reference
< EventHolder
> pEventHolder( new EventHolder
);
910 for ( EventMap::const_iterator event
= m_aEvents
.begin();
911 event
!= m_aEvents
.end();
915 // the script which is assigned to the current event (if any)
916 ScriptEventDescriptor aAssignedScript
= lcl_getAssignedScriptEvent( event
->second
, aAllAssignedEvents
);
917 pEventHolder
->addEvent( event
->second
.nId
, event
->second
.sListenerMethodName
, aAssignedScript
);
920 // the inital selection in the dialog
921 Sequence
< ::rtl::OUString
> aNames( pEventHolder
->getElementNames() );
922 const ::rtl::OUString
* pChosenEvent
= ::std::find( aNames
.getConstArray(), aNames
.getConstArray() + aNames
.getLength(), rForEvent
.sListenerMethodName
);
923 sal_uInt16 nInitialSelection
= (sal_uInt16
)( pChosenEvent
- aNames
.getConstArray() );
926 SvxAbstractDialogFactory
* pFactory
= SvxAbstractDialogFactory::Create();
928 return InteractiveSelectionResult_Cancelled
;
930 ::std::auto_ptr
< VclAbstractDialog
> pDialog( pFactory
->CreateSvxMacroAssignDlg(
931 PropertyHandlerHelper::getDialogParentWindow( m_aContext
),
932 impl_getContextFrame_nothrow(),
938 if ( !pDialog
.get() )
939 return InteractiveSelectionResult_Cancelled
;
941 // DF definite problem here
942 // OK & Cancel seem to be both returning 0
943 if ( pDialog
->Execute() != 0 )
944 return InteractiveSelectionResult_Cancelled
;
948 for ( EventMap::const_iterator event
= m_aEvents
.begin();
949 event
!= m_aEvents
.end();
953 ScriptEventDescriptor
aScriptDescriptor( pEventHolder
->getNormalizedDescriptorByName( event
->second
.sListenerMethodName
) );
955 // set the new "property value"
957 lcl_getEventPropertyName( event
->second
.sListenerClassName
, event
->second
.sListenerMethodName
),
958 makeAny( aScriptDescriptor
)
962 catch( const Exception
& )
964 DBG_UNHANDLED_EXCEPTION();
967 return InteractiveSelectionResult_Success
;
970 //--------------------------------------------------------------------
971 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
)
973 DBG_ERROR( "EventHandler::actuatingPropertyChanged: no actuating properties -> no callback (well, this is how it *should* be!)" );
976 //--------------------------------------------------------------------
977 IMPLEMENT_FORWARD_XCOMPONENT( EventHandler
, EventHandler_Base
)
979 //--------------------------------------------------------------------
980 void SAL_CALL
EventHandler::disposing()
983 m_aEvents
.swap( aEmpty
);
984 m_xComponent
.clear();
987 //--------------------------------------------------------------------
988 sal_Bool SAL_CALL
EventHandler::suspend( sal_Bool
/*_bSuspend*/ ) throw (RuntimeException
)
993 //------------------------------------------------------------------------
994 Reference
< XFrame
> EventHandler::impl_getContextFrame_nothrow() const
996 Reference
< XFrame
> xContextFrame
;
1000 Reference
< XModel
> xContextDocument( m_aContext
.getContextValueByAsciiName( "ContextDocument" ), UNO_QUERY_THROW
);
1001 Reference
< XController
> xController( xContextDocument
->getCurrentController(), UNO_SET_THROW
);
1002 xContextFrame
.set( xController
->getFrame(), UNO_SET_THROW
);
1004 catch( const Exception
& )
1006 DBG_UNHANDLED_EXCEPTION();
1009 return xContextFrame
;
1012 //--------------------------------------------------------------------
1013 sal_Int32
EventHandler::impl_getComponentIndexInParent_throw() const
1015 Reference
< XChild
> xChild( m_xComponent
, UNO_QUERY_THROW
);
1016 Reference
< XIndexAccess
> xParentAsIndexAccess( xChild
->getParent(), UNO_QUERY_THROW
);
1018 // get the index of the inspected object within it's parent container
1019 sal_Int32 nElements
= xParentAsIndexAccess
->getCount();
1020 for ( sal_Int32 i
=0; i
<nElements
; ++i
)
1022 Reference
< XInterface
> xElement( xParentAsIndexAccess
->getByIndex( i
), UNO_QUERY_THROW
);
1023 if ( xElement
== m_xComponent
)
1026 throw NoSuchElementException();
1029 //--------------------------------------------------------------------
1030 void EventHandler::impl_getFormComponentScriptEvents_nothrow( Sequence
< ScriptEventDescriptor
>& _out_rEvents
) const
1032 _out_rEvents
= Sequence
< ScriptEventDescriptor
>();
1035 Reference
< XChild
> xChild( m_xComponent
, UNO_QUERY_THROW
);
1036 Reference
< XEventAttacherManager
> xEventManager( xChild
->getParent(), UNO_QUERY_THROW
);
1037 _out_rEvents
= xEventManager
->getScriptEvents( impl_getComponentIndexInParent_throw() );
1039 // the form component script API has unqualified listener names, but for normalization
1040 // purpose, we want fully qualified ones
1041 ScriptEventDescriptor
* pEvents
= _out_rEvents
.getArray();
1042 ScriptEventDescriptor
* pEventsEnd
= _out_rEvents
.getArray() + _out_rEvents
.getLength();
1043 while ( pEvents
!= pEventsEnd
)
1045 pEvents
->ListenerType
= lcl_getQualifiedKnownListenerName( *pEvents
);
1049 catch( const Exception
& )
1051 DBG_UNHANDLED_EXCEPTION();
1055 //--------------------------------------------------------------------
1056 void EventHandler::impl_getCopmonentListenerTypes_nothrow( Sequence
< Type
>& _out_rTypes
) const
1058 _out_rTypes
.realloc( 0 );
1061 // we use a set to avoid duplicates
1064 Reference
< XIntrospection
> xIntrospection( m_aContext
.createComponent( "com.sun.star.beans.Introspection" ), UNO_QUERY_THROW
);
1066 // --- model listeners
1067 lcl_addListenerTypesFor_throw(
1068 m_xComponent
, xIntrospection
, aListeners
);
1070 // --- "secondary component" (usually: "control" listeners)
1072 Reference
< XInterface
> xSecondaryComponent( impl_getSecondaryComponentForEventInspection_throw() );
1073 lcl_addListenerTypesFor_throw( xSecondaryComponent
, xIntrospection
, aListeners
);
1074 ::comphelper::disposeComponent( xSecondaryComponent
);
1077 // now that they're disambiguated, copy these types into our member
1078 _out_rTypes
.realloc( aListeners
.size() );
1079 ::std::copy( aListeners
.begin(), aListeners
.end(), _out_rTypes
.getArray() );
1081 catch( const Exception
& )
1083 DBG_UNHANDLED_EXCEPTION();
1087 //--------------------------------------------------------------------
1088 void EventHandler::impl_getDialogElementScriptEvents_nothrow( Sequence
< ScriptEventDescriptor
>& _out_rEvents
) const
1090 _out_rEvents
= Sequence
< ScriptEventDescriptor
>();
1093 Reference
< XScriptEventsSupplier
> xEventsSupplier( m_xComponent
, UNO_QUERY_THROW
);
1094 Reference
< XNameContainer
> xEvents( xEventsSupplier
->getEvents(), UNO_QUERY_THROW
);
1095 Sequence
< ::rtl::OUString
> aEventNames( xEvents
->getElementNames() );
1097 sal_Int32 nEventCount
= aEventNames
.getLength();
1098 _out_rEvents
.realloc( nEventCount
);
1100 const ::rtl::OUString
* pNames
= aEventNames
.getConstArray();
1101 ScriptEventDescriptor
* pDescs
= _out_rEvents
.getArray();
1103 for( sal_Int32 i
= 0 ; i
< nEventCount
; ++i
, ++pNames
, ++pDescs
)
1104 OSL_VERIFY( xEvents
->getByName( *pNames
) >>= *pDescs
);
1106 catch( const Exception
& )
1108 DBG_UNHANDLED_EXCEPTION();
1112 //--------------------------------------------------------------------
1113 Reference
< XInterface
> EventHandler::impl_getSecondaryComponentForEventInspection_throw( ) const
1115 Reference
< XInterface
> xReturn
;
1117 // if it's a form, create a form controller for the additional events
1118 Reference
< XForm
> xComponentAsForm( m_xComponent
, UNO_QUERY
);
1119 if ( xComponentAsForm
.is() )
1121 Reference
< XTabControllerModel
> xComponentAsTCModel( m_xComponent
, UNO_QUERY_THROW
);
1122 Reference
< XFormController
> xController(
1123 m_aContext
.createComponent( "com.sun.star.form.runtime.FormController" ), UNO_QUERY_THROW
);
1124 xController
->setModel( xComponentAsTCModel
);
1126 xReturn
= xController
;
1130 ::rtl::OUString sControlService
;
1131 OSL_VERIFY( m_xComponent
->getPropertyValue( PROPERTY_DEFAULTCONTROL
) >>= sControlService
);
1133 xReturn
= m_aContext
.createComponent( sControlService
);
1138 //--------------------------------------------------------------------
1139 const EventDescription
& EventHandler::impl_getEventForName_throw( const ::rtl::OUString
& _rPropertyName
) const
1141 EventMap::const_iterator pos
= m_aEvents
.find( _rPropertyName
);
1142 if ( pos
== m_aEvents
.end() )
1143 throw UnknownPropertyException();
1147 //--------------------------------------------------------------------
1150 static bool lcl_endsWith( const ::rtl::OUString
& _rText
, const ::rtl::OUString
& _rCheck
)
1152 sal_Int32 nTextLen
= _rText
.getLength();
1153 sal_Int32 nCheckLen
= _rCheck
.getLength();
1154 if ( nCheckLen
> nTextLen
)
1157 return _rText
.indexOf( _rCheck
) == ( nTextLen
- nCheckLen
);
1160 //--------------------------------------------------------------------
1161 void EventHandler::impl_setFormComponentScriptEvent_nothrow( const ScriptEventDescriptor
& _rScriptEvent
)
1165 ::rtl::OUString
sScriptCode( _rScriptEvent
.ScriptCode
);
1166 ::rtl::OUString
sScriptType( _rScriptEvent
.ScriptType
);
1167 bool bResetScript
= ( sScriptCode
.getLength() == 0 );
1169 sal_Int32 nObjectIndex
= impl_getComponentIndexInParent_throw();
1170 Reference
< XChild
> xChild( m_xComponent
, UNO_QUERY_THROW
);
1171 Reference
< XEventAttacherManager
> xEventManager( xChild
->getParent(), UNO_QUERY_THROW
);
1172 Sequence
< ScriptEventDescriptor
> aEvents( xEventManager
->getScriptEvents( nObjectIndex
) );
1174 // is there already a registered script for this event?
1175 ScriptEventDescriptor
* pEvent
= aEvents
.getArray();
1176 sal_Int32 eventCount
= aEvents
.getLength(), event
= 0;
1177 for ( event
= 0; event
< eventCount
; ++event
, ++pEvent
)
1179 if ( ( pEvent
->EventMethod
== _rScriptEvent
.EventMethod
)
1180 && ( lcl_endsWith( _rScriptEvent
.ListenerType
, pEvent
->ListenerType
) )
1181 // (strange enough, the events we get from getScriptEvents are not fully qualified)
1185 if ( !bResetScript
)
1187 // set to something non-empty -> overwrite
1188 pEvent
->ScriptCode
= sScriptCode
;
1189 pEvent
->ScriptType
= sScriptType
;
1193 // set to empty -> remove from sequence
1194 ::std::copy( pEvent
+ 1, aEvents
.getArray() + eventCount
, pEvent
);
1195 aEvents
.realloc( eventCount
- 1 );
1201 if ( ( event
>= eventCount
) && !bResetScript
)
1203 // no, did not find it -> append
1204 aEvents
.realloc( eventCount
+ 1 );
1205 aEvents
[ eventCount
] = _rScriptEvent
;
1208 xEventManager
->revokeScriptEvents( nObjectIndex
);
1209 xEventManager
->registerScriptEvents( nObjectIndex
, aEvents
);
1211 PropertyHandlerHelper::setContextDocumentModified( m_aContext
);
1213 catch( const Exception
& )
1215 DBG_UNHANDLED_EXCEPTION();
1219 //--------------------------------------------------------------------
1220 void EventHandler::impl_setDialogElementScriptEvent_nothrow( const ScriptEventDescriptor
& _rScriptEvent
)
1224 ::rtl::OUString
sScriptCode( _rScriptEvent
.ScriptCode
);
1225 bool bResetScript
= ( sScriptCode
.getLength() == 0 );
1227 Reference
< XScriptEventsSupplier
> xEventsSupplier( m_xComponent
, UNO_QUERY_THROW
);
1228 Reference
< XNameContainer
> xEvents( xEventsSupplier
->getEvents(), UNO_QUERY_THROW
);
1230 ::rtl::OUStringBuffer aCompleteName
;
1231 aCompleteName
.append( _rScriptEvent
.ListenerType
);
1232 aCompleteName
.appendAscii( "::" );
1233 aCompleteName
.append( _rScriptEvent
.EventMethod
);
1234 ::rtl::OUString
sCompleteName( aCompleteName
.makeStringAndClear() );
1236 bool bExists
= xEvents
->hasByName( sCompleteName
);
1241 xEvents
->removeByName( sCompleteName
);
1245 Any aNewValue
; aNewValue
<<= _rScriptEvent
;
1248 xEvents
->replaceByName( sCompleteName
, aNewValue
);
1250 xEvents
->insertByName( sCompleteName
, aNewValue
);
1253 catch( const Exception
& )
1255 DBG_UNHANDLED_EXCEPTION();
1259 //--------------------------------------------------------------------
1260 bool EventHandler::impl_filterMethod_nothrow( const EventDescription
& _rEvent
) const
1262 // some (control-triggered) events do not make sense for certain grid control columns. However,
1263 // our mechnism to retrieve control-triggered events does not know about this, so we do some
1264 // late filtering here.
1265 switch ( m_nGridColumnType
)
1267 case FormComponentType::COMBOBOX
:
1268 if ( UID_BRWEVT_ACTIONPERFORMED
== _rEvent
.nUniqueBrowseId
)
1271 case FormComponentType::LISTBOX
:
1272 if ( ( UID_BRWEVT_CHANGED
== _rEvent
.nUniqueBrowseId
)
1273 || ( UID_BRWEVT_ACTIONPERFORMED
== _rEvent
.nUniqueBrowseId
)
1282 //........................................................................
1284 //........................................................................