xref: /AOO41X/main/comphelper/inc/comphelper/accessiblewrapper.hxx (revision 9877b273795ec465a3ce9c15d738eb34c0455705)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #ifndef COMPHELPER_ACCESSIBLE_WRAPPER_HXX
25 #define COMPHELPER_ACCESSIBLE_WRAPPER_HXX
26 
27 #include <comphelper/proxyaggregation.hxx>
28 #include <com/sun/star/accessibility/XAccessible.hpp>
29 #include <com/sun/star/accessibility/XAccessibleContext.hpp>
30 #include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp>
31 #include <com/sun/star/accessibility/XAccessibleEventListener.hpp>
32 #include <cppuhelper/compbase3.hxx>
33 #include <cppuhelper/compbase2.hxx>
34 #include <com/sun/star/lang/XComponent.hpp>
35 #include <cppuhelper/implbase2.hxx>
36 #include <cppuhelper/implbase1.hxx>
37 #include <comphelper/sequence.hxx>
38 #include <comphelper/uno3.hxx>
39 #include <cppuhelper/interfacecontainer.hxx>
40 #include <comphelper/broadcasthelper.hxx>
41 #include <comphelper/accessibleeventnotifier.hxx>
42 #include <comphelper/stl_types.hxx>
43 #include "comphelper/comphelperdllapi.h"
44 
45 //.............................................................................
46 namespace comphelper
47 {
48 //.............................................................................
49 
50     //=========================================================================
51     //= OAccessibleWrapper
52     //=========================================================================
53 
54     class OAccessibleContextWrapper;
55     class OWrappedAccessibleChildrenManager;
56 
57     struct OAccessibleWrapper_Base :
58         public ::cppu::ImplHelper1 < ::com::sun::star::accessibility::XAccessible >
59     {};
60 
61     /** a class which aggregates a proxy for an XAccessible, and wrapping the context returned by this
62         XAccessible.
63     */
64     class COMPHELPER_DLLPUBLIC OAccessibleWrapper:public OAccessibleWrapper_Base
65                             ,public OComponentProxyAggregation
66 
67     {
68     private:
69         ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
70                 m_xParentAccessible;
71         ::com::sun::star::uno::WeakReference< ::com::sun::star::accessibility::XAccessibleContext >
72                 m_aContext;
73 
74     protected:
75         ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
76                 m_xInnerAccessible;
77 
78     public:
79         /** ctor
80             @param _rxORB
81                 a service factory
82 
83             @param _rxInnerAccessible
84                 the object to wrap
85 
86             @param _rxParentAccessible
87                 The XAccessible which is our parent
88         */
89         OAccessibleWrapper(
90             const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxORB,
91             const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& _rxInnerAccessible,
92             const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& _rxParentAccessible
93         );
94         DECLARE_XINTERFACE()
95         DECLARE_XTYPEPROVIDER()
96 
97         // returns the context without creating it
98         ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >
99                     getContextNoCreate( ) const;
100 
101     protected:
102         virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > SAL_CALL
103                     getAccessibleContext(  ) throw (::com::sun::star::uno::RuntimeException);
104 
105         ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
getParent() const106                     getParent() const { return m_xParentAccessible; }
107 
108         // own overridables
109         virtual OAccessibleContextWrapper* createAccessibleContext(
110                 const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >& _rxInnerContext
111             );
112 
113     protected:
114         ~OAccessibleWrapper( );
115 
116     private:
117         COMPHELPER_DLLPRIVATE OAccessibleWrapper( );                                        // never implemented
118         COMPHELPER_DLLPRIVATE OAccessibleWrapper( const OAccessibleWrapper& );          // never implemented
119         COMPHELPER_DLLPRIVATE OAccessibleWrapper& operator=( const OAccessibleWrapper& );   // never implemented
120     };
121 
122     //=========================================================================
123     //= OAccessibleContextWrapperHelper
124     //=========================================================================
125 
126     typedef ::cppu::ImplHelper1 <   ::com::sun::star::accessibility::XAccessibleEventListener
127                                 >   OAccessibleContextWrapperHelper_Base;
128 
129     /** Helper for wrapping an XAccessibleContext by aggregating a proxy for it.
130 
131         <p>This class does not have own ref counting. In addition, it does not implement
132         the XAccesibleContext interface, but provides all the methods from this interface
133         which must be implemented using the inner context (such as getAccessibleChild*).</p>
134 
135         <p>Children of the aggregated XAccessibleContext are wrapped, too.</p>
136 
137         <p>AccessibleEvents fired by the inner context are multiplexed, especially, any references to
138         children in such events are translated. This means that even in such events, no un-wrapped object
139         will ever leave this class - if the aggregated context notifies an child event, the child passed
140         to the event is wrapped</p>
141 
142         @seealso OAccessibleContextWrapper
143     */
144     class COMPHELPER_DLLPUBLIC OAccessibleContextWrapperHelper
145                 :private OComponentProxyAggregationHelper
146                 ,public OAccessibleContextWrapperHelper_Base
147     {
148     protected:
149         /// the context we're wrapping (properly typed, in opposite to OComponentProxyAggregationHelper::m_xInner)
150         ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >
151                                                             m_xInnerContext;
152         /// the XAccessible which created this context
153         ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
154                                                             m_xOwningAccessible;
155         /// the XAccessible which is to be returned in getAccessibleParent
156         ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
157                                                             m_xParentAccessible;
158 
159         OWrappedAccessibleChildrenManager*                  m_pChildMapper;         // for mapping children from our inner context to our callers
160 
161     protected:
162         /** ctor
163 
164             @param _rxORB
165                 a service factory
166 
167             @param _rxInnerAccessibleContext
168                 the object to wrap
169 
170             @param _rxOwningAccessible
171                 The XAccessible which created this object. This is necessary because children
172                 of our wrapped context meed to be wrapped, too, and if they're asked for a parent,
173                 they of course should return the proper parent<br/>
174                 The object will be held with a hard reference
175 
176             @param _rxParentAccessible
177                 The XAccessible to return in the getAccessibleParent call
178         */
179         OAccessibleContextWrapperHelper(
180             const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxORB,
181             ::cppu::OBroadcastHelper& _rBHelper,
182             const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >& _rxInnerAccessibleContext,
183             const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& _rxOwningAccessible,
184             const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& _rxParentAccessible
185         );
186 
187         /// to be called from within your ctor - does the aggregation of a proxy for m_xInnerContext
188         void aggregateProxy(
189             oslInterlockedCount& _rRefCount,
190             ::cppu::OWeakObject& _rDelegator
191         );
192 
193     protected:
194         // XInterface
195         ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type& _rType ) throw (::com::sun::star::uno::RuntimeException);
196 
197         // XTypeProvider
198         DECLARE_XTYPEPROVIDER( )
199 
200         // XAccessibleContext
201         virtual sal_Int32 SAL_CALL getAccessibleChildCount(  ) throw (::com::sun::star::uno::RuntimeException);
202         virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleChild( sal_Int32 i ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
203         virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleRelationSet > SAL_CALL getAccessibleRelationSet(  ) throw (::com::sun::star::uno::RuntimeException);
204 
205         // XAccessibleEventListener
206         virtual void SAL_CALL notifyEvent( const ::com::sun::star::accessibility::AccessibleEventObject& aEvent ) throw (::com::sun::star::uno::RuntimeException);
207 
208         // XEventListener
209         virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException);
210 
211         // XComponent/OComponentProxyAggregationHelper
212         virtual void SAL_CALL dispose() throw( ::com::sun::star::uno::RuntimeException );
213 
214         // own overridables
215         /** notify an accessible event which has been translated (if necessary)
216 
217             <p>Usually, you derive your clas from both OAccessibleContextWrapperHelper and XAccessibleEventBroadcaster,
218             and simply call all your XAccessibleEventListener with the given event.</p>
219 
220             <p>The mutex of the BroadcastHelper passed to the instance's ctor is <em>not</em> locked when calling
221             into this method</p>
222         */
223         virtual void notifyTranslatedEvent( const ::com::sun::star::accessibility::AccessibleEventObject& _rEvent ) throw (::com::sun::star::uno::RuntimeException) = 0;
224 
225     protected:
226         ~OAccessibleContextWrapperHelper( );
227 
228         OAccessibleContextWrapperHelper( );                                             // never implemented
229         OAccessibleContextWrapperHelper( const OAccessibleContextWrapperHelper& );              // never implemented
230         OAccessibleContextWrapperHelper& operator=( const OAccessibleContextWrapperHelper& );   // never implemented
231     };
232 
233     //=========================================================================
234     //= OAccessibleContextWrapper
235     //=========================================================================
236     typedef ::cppu::WeakComponentImplHelper2<   ::com::sun::star::accessibility::XAccessibleEventBroadcaster
237                                             ,   ::com::sun::star::accessibility::XAccessibleContext
238                                             >   OAccessibleContextWrapper_CBase;
239 
240     class COMPHELPER_DLLPUBLIC OAccessibleContextWrapper
241                     :public OBaseMutex
242                     ,public OAccessibleContextWrapper_CBase
243                     ,public OAccessibleContextWrapperHelper
244     {
245     private:
246         ::comphelper::AccessibleEventNotifier::TClientId    m_nNotifierClient;      // for notifying AccessibleEvents
247 
248     public:
249         /** ctor
250 
251             @param _rxORB
252                 a service factory
253 
254             @param _rxInnerAccessibleContext
255                 the object to wrap
256 
257             @param _rxOwningAccessible
258                 The XAccessible which created this object. This is necessary because children
259                 of our wrapped context meed to be wrapped, too, and if they're asked for a parent,
260                 they of course should return the proper parent<br/>
261                 The object will be held with a hard reference
262 
263             @param _rxParentAccessible
264                 The XAccessible to return in the getAccessibleParent call
265         */
266         OAccessibleContextWrapper(
267             const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxORB,
268             const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >& _rxInnerAccessibleContext,
269             const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& _rxOwningAccessible,
270             const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& _rxParentAccessible
271         );
272 
273         // XInterface
274         DECLARE_XINTERFACE( )
275         // XTypeProvider
276         DECLARE_XTYPEPROVIDER( )
277 
278         // XAccessibleContext
279         virtual sal_Int32 SAL_CALL getAccessibleChildCount(  ) throw (::com::sun::star::uno::RuntimeException);
280         virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleChild( sal_Int32 i ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
281         virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleParent(  ) throw (::com::sun::star::uno::RuntimeException);
282         virtual sal_Int32 SAL_CALL getAccessibleIndexInParent(  ) throw (::com::sun::star::uno::RuntimeException);
283         virtual sal_Int16 SAL_CALL getAccessibleRole(  ) throw (::com::sun::star::uno::RuntimeException);
284         virtual ::rtl::OUString SAL_CALL getAccessibleDescription(  ) throw (::com::sun::star::uno::RuntimeException);
285         virtual ::rtl::OUString SAL_CALL getAccessibleName(  ) throw (::com::sun::star::uno::RuntimeException);
286         virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleRelationSet > SAL_CALL getAccessibleRelationSet(  ) throw (::com::sun::star::uno::RuntimeException);
287         virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleStateSet > SAL_CALL getAccessibleStateSet(  ) throw (::com::sun::star::uno::RuntimeException);
288         virtual ::com::sun::star::lang::Locale SAL_CALL getLocale(  ) throw (::com::sun::star::accessibility::IllegalAccessibleComponentStateException, ::com::sun::star::uno::RuntimeException);
289 
290         // XAccessibleEventBroadcaster
291         using WeakComponentImplHelperBase::addEventListener;
292         virtual void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
293         using WeakComponentImplHelperBase::removeEventListener;
294         virtual void SAL_CALL removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
295 
296         // OAccessibleContextWrapper
297         virtual void notifyTranslatedEvent( const ::com::sun::star::accessibility::AccessibleEventObject& _rEvent ) throw (::com::sun::star::uno::RuntimeException);
298 
299         // XComponent/OComponentProxyAggregationHelper
300         virtual void SAL_CALL dispose() throw( ::com::sun::star::uno::RuntimeException );
301 
302         // OComponentHelper
303         using OAccessibleContextWrapperHelper::disposing;
304         virtual void SAL_CALL disposing()  throw (::com::sun::star::uno::RuntimeException);
305 
306     protected:
307         virtual ~OAccessibleContextWrapper();
308 
309     private:
310         COMPHELPER_DLLPRIVATE OAccessibleContextWrapper();                                              // never implemented
311         COMPHELPER_DLLPRIVATE OAccessibleContextWrapper( const OAccessibleContextWrapper& );                // never implemented
312         COMPHELPER_DLLPRIVATE OAccessibleContextWrapper& operator=( const OAccessibleContextWrapper& ); // never implemented
313     };
314 
315     //=========================================================================
316     //= OWrappedAccessibleChildrenManager
317     //=========================================================================
318 
319     typedef ::std::map  <   ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
320                         ,   ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
321                         ,   OInterfaceCompare< ::com::sun::star::accessibility::XAccessible >
322                         >   AccessibleMap;
323                         // TODO: think about if we should hold these objects weak
324 
325     typedef ::cppu::WeakImplHelper1 <   ::com::sun::star::lang::XEventListener
326                                     >   OWrappedAccessibleChildrenManager_Base;
327     /** manages wrapping XAccessible's to XAccessible's
328     */
329     class COMPHELPER_DLLPUBLIC OWrappedAccessibleChildrenManager : public OWrappedAccessibleChildrenManager_Base
330     {
331     protected:
332         ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >
333                                 m_xORB;
334         ::com::sun::star::uno::WeakReference< ::com::sun::star::accessibility::XAccessible >
335                                 m_aOwningAccessible;    // the XAccessible which belongs to the XAccessibleContext which we work for
336         AccessibleMap           m_aChildrenMap;         // for caching children
337         sal_Bool                m_bTransientChildren;   // are we prohibited to cache our children?
338 
339     public:
340         /// ctor
341         OWrappedAccessibleChildrenManager(
342             const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxORB
343         );
344 
345         /** specifies if the children are to be consideren transient (i.e.: not cached)
346             <p>to be called only once per lifetime</p>
347         */
348         void    setTransientChildren( sal_Bool _bSet = sal_True );
349 
350         /** sets the XAccessible which belongs to the XAccessibleContext which we work for
351             <p>to be called only once per lifetime</p>
352         */
353         void    setOwningAccessible( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& _rxAcc );
354 
355         /// retrieves a wrapper for the given accessible
356         ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
357                 getAccessibleWrapperFor(
358                     const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& _rxKey,
359                     sal_Bool _bCreate = sal_True
360                 );
361 
362         /// erases the given key from the map (if it is present there)
363         void    removeFromCache( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& _rxKey );
364 
365         /// invalidates (i.e. empties) the map
366         void    invalidateAll( );
367 
368         /** disposes (i.e. cleares) the manager
369 
370             <p>Note that the XAccessibleContext's of the mapped XAccessible objects are disposed, too.</p>
371         */
372         void    dispose();
373 
374         /** handles a notification as got from the parent of the children we're managing
375             <p>This applies only to the notifications which have a direct impact on our map.</p>
376         */
377         void    handleChildNotification( const ::com::sun::star::accessibility::AccessibleEventObject& _rEvent );
378 
379         /** translates events as got from the parent of the children we're managing
380             <p>This applies only to the notifications which deal with child objects which we manage.</p>
381         */
382         void    translateAccessibleEvent(
383             const   ::com::sun::star::accessibility::AccessibleEventObject& _rEvent,
384                     ::com::sun::star::accessibility::AccessibleEventObject& _rTranslatedEvent
385         );
386 
387     protected:
388         // XEventListener
389         virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException);
390 
391     protected:
392         void    implTranslateChildEventValue( const ::com::sun::star::uno::Any& _rInValue, ::com::sun::star::uno::Any& _rOutValue );
393 
394     protected:
395         ~OWrappedAccessibleChildrenManager( );
396 
397     private:
398         COMPHELPER_DLLPRIVATE OWrappedAccessibleChildrenManager( );                                                     // never implemented
399         COMPHELPER_DLLPRIVATE OWrappedAccessibleChildrenManager( const OWrappedAccessibleChildrenManager& );                // never implemented
400         COMPHELPER_DLLPRIVATE OWrappedAccessibleChildrenManager& operator=( const OWrappedAccessibleChildrenManager& ); // never implemented
401     };
402 
403 //.............................................................................
404 }   // namespace accessibility
405 //.............................................................................
406 
407 #endif // COMPHELPER_ACCESSIBLE_WRAPPER_HXX
408