xref: /trunk/main/accessibility/inc/accessibility/extended/AccessibleBrowseBoxBase.hxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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 
25 #ifndef ACCESSIBILITY_EXT_ACCESSIBLEBROWSEBOXBASE_HXX
26 #define ACCESSIBILITY_EXT_ACCESSIBLEBROWSEBOXBASE_HXX
27 
28 #include <svtools/AccessibleBrowseBoxObjType.hxx>
29 #include <tools/debug.hxx>
30 #include <rtl/ustring.hxx>
31 #include <tools/gen.hxx>
32 #include <vcl/svapp.hxx>
33 #include <cppuhelper/compbase5.hxx>
34 #include <comphelper/broadcasthelper.hxx>
35 #include <unotools/accessiblestatesethelper.hxx>
36 #include <toolkit/helper/convert.hxx>
37 #include <com/sun/star/lang/XServiceInfo.hpp>
38 #include <com/sun/star/lang/DisposedException.hpp>
39 #include <com/sun/star/awt/XWindow.hpp>
40 #include <com/sun/star/accessibility/XAccessible.hpp>
41 #include <com/sun/star/accessibility/XAccessibleContext.hpp>
42 #include <com/sun/star/accessibility/XAccessibleComponent.hpp>
43 #include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp>
44 #include <com/sun/star/accessibility/AccessibleRole.hpp>
45 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
46 #include <com/sun/star/awt/XFocusListener.hpp>
47 #include <comphelper/accessibleeventnotifier.hxx>
48 #include <comphelper/uno3.hxx>
49 
50 // ============================================================================
51 
52 class Window;
53 
54 namespace utl {
55     class AccessibleStateSetHelper;
56 }
57 
58 namespace svt {
59     class IAccessibleTableProvider;
60 }
61 
62 // ============================================================================
63 
64 namespace accessibility {
65 
66 // ============================================================================
67 
68 /** Acquire the solar mutex. */
69 class BBSolarGuard : public ::vos::OGuard
70 {
71 public:
BBSolarGuard()72     inline BBSolarGuard() : ::vos::OGuard( Application::GetSolarMutex() ) {}
73 };
74 
75 // ============================================================================
76 
77 typedef ::cppu::WeakAggComponentImplHelper5<
78             ::com::sun::star::accessibility::XAccessibleContext,
79             ::com::sun::star::accessibility::XAccessibleComponent,
80             ::com::sun::star::accessibility::XAccessibleEventBroadcaster,
81         ::com::sun::star::awt::XFocusListener,
82             ::com::sun::star::lang::XServiceInfo >
83         AccessibleBrowseBoxImplHelper;
84 
85 /** The BrowseBox accessible objects inherit from this base class. It
86     implements basic functionality for various Accessibility interfaces and
87     the event broadcaster and contains the ::osl::Mutex. */
88 class AccessibleBrowseBoxBase :
89     public ::comphelper::OBaseMutex,
90     public AccessibleBrowseBoxImplHelper
91 {
92 public:
93     /** Constructor sets specified name and description. If the constant of a
94         text is BBTEXT_NONE, the derived class has to set the text via
95         implSetName() and implSetDescription() (in Ctor) or later via
96         setAccessibleName() and setAccessibleDescription() (these methods
97         notify the listeners about the change).
98         @param rxParent  XAccessible interface of the parent object.
99         @param rBrowseBox  The BrowseBox control.
100         @param eNameText  The constant for the name text.
101         @param eDescrText  The constant for the description text. */
102     AccessibleBrowseBoxBase(
103         const ::com::sun::star::uno::Reference<
104             ::com::sun::star::accessibility::XAccessible >& rxParent,
105         ::svt::IAccessibleTableProvider&                  rBrowseBox,
106         const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow >& _xFocusWindow,
107         ::svt::AccessibleBrowseBoxObjType  eObjType );
108 
109     /** Constructor sets specified name and description.
110         @param rxParent  XAccessible interface of the parent object.
111         @param rBrowseBox  The BrowseBox control.
112         @param rName  The name of this object.
113         @param rDescription  The description text of this object. */
114     AccessibleBrowseBoxBase(
115         const ::com::sun::star::uno::Reference<
116             ::com::sun::star::accessibility::XAccessible >& rxParent,
117         ::svt::IAccessibleTableProvider&                  rBrowseBox,
118         const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow >& _xFocusWindow,
119         ::svt::AccessibleBrowseBoxObjType  eObjType,
120         const ::rtl::OUString&      rName,
121         const ::rtl::OUString&      rDescription );
122 
123 protected:
124     virtual ~AccessibleBrowseBoxBase();
125 
126     /** Commits DeFunc event to listeners and cleans up members. */
127     virtual void SAL_CALL disposing();
128 
129 public:
130     // XAccessibleContext -----------------------------------------------------
131 
132     /** @return  A reference to the parent accessible object. */
133     virtual ::com::sun::star::uno::Reference<
134         ::com::sun::star::accessibility::XAccessible > SAL_CALL
135     getAccessibleParent();
136 
137     /** @return  The index of this object among the parent's children. */
138     virtual sal_Int32 SAL_CALL getAccessibleIndexInParent();
139 
140     /** @return
141             The description of this object.
142     */
143     virtual ::rtl::OUString SAL_CALL getAccessibleDescription();
144 
145     /** @return
146             The name of this object.
147     */
148     virtual ::rtl::OUString SAL_CALL getAccessibleName();
149 
150     /** @return
151             The relation set (the BrowseBox does not have one).
152     */
153     virtual ::com::sun::star::uno::Reference<
154         ::com::sun::star::accessibility::XAccessibleRelationSet > SAL_CALL
155     getAccessibleRelationSet();
156 
157     /** @return  The set of current states. */
158     virtual ::com::sun::star::uno::Reference<
159         ::com::sun::star::accessibility::XAccessibleStateSet > SAL_CALL
160     getAccessibleStateSet();
161 
162     /** @return  The parent's locale. */
163     virtual ::com::sun::star::lang::Locale SAL_CALL getLocale();
164 
165     /** @return
166             The role of this object. Panel, ROWHEADER, COLUMNHEADER, TABLE, TABLE_CELL are supported.
167     */
168     virtual sal_Int16 SAL_CALL getAccessibleRole();
169 
170     /*  Derived classes have to implement:
171         -   getAccessibleChildCount,
172         -   getAccessibleChild,
173         -   getAccessibleRole.
174         Derived classes may overwrite getAccessibleIndexInParent to increase
175         performance. */
176 
177     // XAccessibleComponent ---------------------------------------------------
178 
179     /** @return
180         <TRUE/>, if the point lies within the bounding box of this object. */
181     virtual sal_Bool SAL_CALL containsPoint( const ::com::sun::star::awt::Point& rPoint );
182 
183     /** @return  The bounding box of this object. */
184     virtual ::com::sun::star::awt::Rectangle SAL_CALL getBounds();
185 
186     /** @return
187         The upper left corner of the bounding box relative to the parent. */
188     virtual ::com::sun::star::awt::Point SAL_CALL getLocation();
189 
190     /** @return
191         The upper left corner of the bounding box in screen coordinates. */
192     virtual ::com::sun::star::awt::Point SAL_CALL getLocationOnScreen();
193 
194     /** @return  The size of the bounding box. */
195     virtual ::com::sun::star::awt::Size SAL_CALL getSize();
196 
197     /** @return  <TRUE/>, if the object is showing. */
198     virtual sal_Bool SAL_CALL isShowing();
199 
200     /** @return  <TRUE/>, if the object is visible. */
201     virtual sal_Bool SAL_CALL isVisible();
202 
203     /** @return  <TRUE/>, if the object can accept the focus. */
204     virtual sal_Bool SAL_CALL isFocusTraversable();
205 
206     virtual sal_Int32 SAL_CALL getForeground(  );
207     virtual sal_Int32 SAL_CALL getBackground(  );
208 
209     // XFocusListener
210     virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source );
211     virtual void SAL_CALL focusGained( const ::com::sun::star::awt::FocusEvent& e );
212     virtual void SAL_CALL focusLost( const ::com::sun::star::awt::FocusEvent& e );
213 
214     /*  Derived classes have to implement:
215         -   getAccessibleAt,
216         -   grabFocus,
217         -   getAccessibleKeyBinding. */
218 
219     /** @return
220         No key bindings supported by default.
221     */
222     virtual ::com::sun::star::uno::Any SAL_CALL getAccessibleKeyBinding();
223     /** @return
224             The accessible child rendered under the given point.
225     */
226     virtual ::com::sun::star::uno::Reference<
227         ::com::sun::star::accessibility::XAccessible > SAL_CALL
228     getAccessibleAtPoint( const ::com::sun::star::awt::Point& rPoint );
229 
230     // XAccessibleEventBroadcaster --------------------------------------------
231 
232     /** Adds a new event listener */
233     using cppu::WeakAggComponentImplHelperBase::addEventListener;
234     virtual void SAL_CALL addEventListener(
235             const ::com::sun::star::uno::Reference<
236                 ::com::sun::star::accessibility::XAccessibleEventListener>& rxListener );
237 
238     /** Removes an event listener. */
239     using cppu::WeakAggComponentImplHelperBase::removeEventListener;
240     virtual void SAL_CALL removeEventListener(
241             const ::com::sun::star::uno::Reference<
242                 ::com::sun::star::accessibility::XAccessibleEventListener>& rxListener );
243 
244     // XTypeProvider ----------------------------------------------------------
245 
246     /** @return  An unique implementation ID. */
247     virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId();
248 
249     // XServiceInfo -----------------------------------------------------------
250 
251     /** @return  Whether the specified service is supported by this class. */
252     virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& rServiceName );
253 
254     /** @return  A list of all supported services. */
255     virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL
256     getSupportedServiceNames();
257 
258     /*  Derived classes have to implement:
259         -   getImplementationName. */
260 
261     // helper methods ---------------------------------------------------------
262 
263     /** @return  The BrowseBox object type. */
264     inline ::svt::AccessibleBrowseBoxObjType getType() const;
265 
266     /** Changes the name of the object and notifies listeners. */
267     void setAccessibleName( const ::rtl::OUString& rName );
268     /** Changes the description of the object and notifies listeners. */
269     void setAccessibleDescription( const ::rtl::OUString& rDescription );
270 
271     /** Commits an event to all listeners. */
272     void commitEvent(
273             sal_Int16 nEventId,
274             const ::com::sun::star::uno::Any& rNewValue,
275 
276     const ::com::sun::star::uno::Any& rOldValue );
277     /** @return  <TRUE/>, if the object is not disposed or disposing. */
278     sal_Bool isAlive() const;
279 
280 protected:
281     // internal virtual methods -----------------------------------------------
282 
283     /** Determines whether the BrowseBox control is really showing inside of
284         its parent accessible window. Derived classes may implement different
285         behaviour.
286         @attention  This method requires locked mutex's and a living object.
287         @return  <TRUE/>, if the object is really showing. */
288     virtual sal_Bool implIsShowing();
289 
290     /** Derived classes return the bounding box relative to the parent window.
291         @attention  This method requires locked mutex's and a living object.
292         @return  The bounding box (VCL rect.) relative to the parent window. */
293     virtual Rectangle implGetBoundingBox() = 0;
294     /** Derived classes return the bounding box in screen coordinates.
295         @attention  This method requires locked mutex's and a living object.
296         @return  The bounding box (VCL rect.) in screen coordinates. */
297     virtual Rectangle implGetBoundingBoxOnScreen() = 0;
298 
299     /** Creates a new AccessibleStateSetHelper and fills it with states of the
300         current object. This method calls FillStateSet at the BrowseBox which
301         fills it with more states depending on the object type. Derived classes
302         may overwrite this method and add more states.
303         @attention  This method requires locked mutex's.
304         @return  A filled AccessibleStateSetHelper. */
305     virtual ::utl::AccessibleStateSetHelper* implCreateStateSetHelper();
306 
307     // internal helper methods ------------------------------------------------
308 
309     /** @throws <type>DisposedException</type>  If the object is not alive. */
310     void ensureIsAlive() const;
311 
312     /** @return  The ::osl::Mutex member provided by the class OBaseMutex. */
313     inline ::osl::Mutex& getOslMutex();
314     /** @return  Pointer to the global ::osl::Mutex. */
315     static inline ::osl::Mutex* getOslGlobalMutex();
316 
317     /** Changes the name of the object (flat assignment, no notify).
318         @attention  This method requires a locked mutex. */
319     inline void implSetName( const ::rtl::OUString& rName );
320     /** Changes the description of the object (flat assignment, no notify).
321         @attention  This method requires a locked mutex. */
322     inline void implSetDescription( const ::rtl::OUString& rDescription );
323 
324     /** Locks all mutex's and calculates the bounding box relative to the
325         parent window.
326         @return  The bounding box (VCL rect.) relative to the parent object. */
327     Rectangle getBoundingBox();
328     /** Locks all mutex's and calculates the bounding box in screen
329         coordinates.
330         @return  The bounding box (VCL rect.) in screen coordinates. */
331     Rectangle getBoundingBoxOnScreen();
332 
333     /** Creates a new UUID, if rId is empty.
334         @attention  This method requires locked global mutex to prevent double
335                     creation of an UUID. */
336     static void implCreateUuid( ::com::sun::star::uno::Sequence< sal_Int8 >& rId );
337 
getClientId() const338     ::comphelper::AccessibleEventNotifier::TClientId getClientId() const { return m_aClientId; }
setClientId(::comphelper::AccessibleEventNotifier::TClientId _aNewClientId)339     void setClientId(::comphelper::AccessibleEventNotifier::TClientId _aNewClientId) { m_aClientId = _aNewClientId; }
340 
341 public:
342     // public versions of internal helper methods, with access control
AccessControlaccessibility::AccessibleBrowseBoxBase::AccessControl343     struct AccessControl { friend class SolarMethodGuard; private: AccessControl() { } };
344 
getMutex(const AccessControl &)345     inline ::osl::Mutex&    getMutex( const AccessControl& ) { return getOslMutex(); }
ensureIsAlive(const AccessControl &)346     inline void             ensureIsAlive( const AccessControl& ) { ensureIsAlive(); }
347 
348 protected:
349     // members ----------------------------------------------------------------
350 
351     /** The parent accessible object. */
352     ::com::sun::star::uno::Reference<
353         ::com::sun::star::accessibility::XAccessible > mxParent;
354     /** The VCL BrowseBox control. */
355     ::svt::IAccessibleTableProvider* mpBrowseBox;
356 
357     /** This is the window which get all the nice focus events
358     */
359     ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow > m_xFocusWindow;
360 
361 private:
362     /** Localized name. */
363     ::rtl::OUString maName;
364     /** Localized description text. */
365     ::rtl::OUString maDescription;
366 
367     /** The type of this object (for names, descriptions, state sets, ...). */
368     ::svt::AccessibleBrowseBoxObjType meObjType;
369 
370     ::comphelper::AccessibleEventNotifier::TClientId    m_aClientId;
371 };
372 
373 // ============================================================================
374 // a version of AccessibleBrowseBoxBase which implements not only the XAccessibleContext,
375 // but also the XAccessible
376 
377 typedef ::cppu::ImplHelper1 <   ::com::sun::star::accessibility::XAccessible
378                             >   BrowseBoxAccessibleElement_Base;
379 
380 class BrowseBoxAccessibleElement
381             :public AccessibleBrowseBoxBase
382             ,public BrowseBoxAccessibleElement_Base
383 {
384 protected:
385     /** Constructor sets specified name and description. If the constant of a
386         text is BBTEXT_NONE, the derived class has to set the text via
387         implSetName() and implSetDescription() (in Ctor) or later via
388         setAccessibleName() and setAccessibleDescription() (these methods
389         notify the listeners about the change).
390 
391         @param rxParent  XAccessible interface of the parent object.
392         @param rBrowseBox  The BrowseBox control.
393         @param eNameText  The constant for the name text.
394         @param eDescrText  The constant for the description text.
395     */
396     BrowseBoxAccessibleElement(
397         const ::com::sun::star::uno::Reference<
398             ::com::sun::star::accessibility::XAccessible >& rxParent,
399         ::svt::IAccessibleTableProvider&                  rBrowseBox,
400         const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow >& _xFocusWindow,
401         ::svt::AccessibleBrowseBoxObjType  eObjType );
402 
403     /** Constructor sets specified name and description.
404 
405         @param rxParent  XAccessible interface of the parent object.
406         @param rBrowseBox  The BrowseBox control.
407         @param rName  The name of this object.
408         @param rDescription  The description text of this object.
409     */
410     BrowseBoxAccessibleElement(
411         const ::com::sun::star::uno::Reference<
412             ::com::sun::star::accessibility::XAccessible >& rxParent,
413         ::svt::IAccessibleTableProvider&                  rBrowseBox,
414         const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow >& _xFocusWindow,
415         ::svt::AccessibleBrowseBoxObjType  eObjType,
416         const ::rtl::OUString&      rName,
417         const ::rtl::OUString&      rDescription );
418 
419 public:
420     // XInterface
421     DECLARE_XINTERFACE( )
422     // XTypeProvider
423     DECLARE_XTYPEPROVIDER( )
424 
425 protected:
426     virtual ~BrowseBoxAccessibleElement();
427 
428 protected:
429     // XAccessible ------------------------------------------------------------
430 
431     /** @return  The XAccessibleContext interface of this object. */
432     virtual ::com::sun::star::uno::Reference<
433         ::com::sun::star::accessibility::XAccessibleContext > SAL_CALL
434     getAccessibleContext();
435 
436 private:
437     BrowseBoxAccessibleElement();                                               // never implemented
438     BrowseBoxAccessibleElement( const BrowseBoxAccessibleElement& );            // never implemented
439     BrowseBoxAccessibleElement& operator=( const BrowseBoxAccessibleElement& ); // never implemented
440 };
441 
442 // ============================================================================
443 // a helper class for protecting methods which need to lock the solar mutex in addition to the own mutex
444 
445 typedef ::osl::MutexGuard OslMutexGuard;
446 
447 class SolarMethodGuard : public BBSolarGuard, public OslMutexGuard
448 {
449 public:
SolarMethodGuard(AccessibleBrowseBoxBase & _rOwner,bool _bEnsureAlive=true)450     inline SolarMethodGuard( AccessibleBrowseBoxBase& _rOwner, bool _bEnsureAlive = true )
451         :BBSolarGuard( )
452         ,OslMutexGuard( _rOwner.getMutex( AccessibleBrowseBoxBase::AccessControl() ) )
453     {
454         if ( _bEnsureAlive )
455             _rOwner.ensureIsAlive( AccessibleBrowseBoxBase::AccessControl() );
456     }
457 };
458 
459 // inlines --------------------------------------------------------------------
460 
getType() const461 inline ::svt::AccessibleBrowseBoxObjType AccessibleBrowseBoxBase::getType() const
462 {
463     return meObjType;
464 }
465 
getOslMutex()466 inline ::osl::Mutex& AccessibleBrowseBoxBase::getOslMutex()
467 {
468     return m_aMutex;
469 }
470 
getOslGlobalMutex()471 inline ::osl::Mutex* AccessibleBrowseBoxBase::getOslGlobalMutex()
472 {
473     return ::osl::Mutex::getGlobalMutex();
474 }
475 
implSetName(const::rtl::OUString & rName)476 inline void AccessibleBrowseBoxBase::implSetName(
477         const ::rtl::OUString& rName )
478 {
479     maName = rName;
480 }
481 
implSetDescription(const::rtl::OUString & rDescription)482 inline void AccessibleBrowseBoxBase::implSetDescription(
483         const ::rtl::OUString& rDescription )
484 {
485     maDescription = rDescription;
486 }
487 
488 // ============================================================================
489 
490 } // namespace accessibility
491 
492 // ============================================================================
493 
494 #endif
495