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 /** Aquire 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         throw ( ::com::sun::star::uno::RuntimeException );
137 
138     /** @return  The index of this object among the parent's children. */
139     virtual sal_Int32 SAL_CALL getAccessibleIndexInParent()
140         throw ( ::com::sun::star::uno::RuntimeException );
141 
142     /** @return
143 			The description of this object.
144 	*/
145     virtual ::rtl::OUString SAL_CALL getAccessibleDescription()
146         throw ( ::com::sun::star::uno::RuntimeException );
147 
148     /** @return
149 			The name of this object.
150 	*/
151     virtual ::rtl::OUString SAL_CALL getAccessibleName()
152         throw ( ::com::sun::star::uno::RuntimeException );
153 
154     /** @return
155 			The relation set (the BrowseBox does not have one).
156 	*/
157 	virtual ::com::sun::star::uno::Reference<
158         ::com::sun::star::accessibility::XAccessibleRelationSet > SAL_CALL
159     getAccessibleRelationSet()
160         throw ( ::com::sun::star::uno::RuntimeException );
161 
162     /** @return  The set of current states. */
163 	virtual ::com::sun::star::uno::Reference<
164         ::com::sun::star::accessibility::XAccessibleStateSet > SAL_CALL
165     getAccessibleStateSet()
166         throw ( ::com::sun::star::uno::RuntimeException );
167 
168     /** @return  The parent's locale. */
169     virtual ::com::sun::star::lang::Locale SAL_CALL getLocale()
170         throw ( ::com::sun::star::accessibility::IllegalAccessibleComponentStateException,
171                 ::com::sun::star::uno::RuntimeException );
172 
173 	/** @return
174 			The role of this object. Panel, ROWHEADER, COLUMNHEADER, TABLE, TABLE_CELL are supported.
175 	*/
176     virtual sal_Int16 SAL_CALL getAccessibleRole()
177         throw ( ::com::sun::star::uno::RuntimeException );
178 
179     /*  Derived classes have to implement:
180         -   getAccessibleChildCount,
181         -   getAccessibleChild,
182         -   getAccessibleRole.
183         Derived classes may overwrite getAccessibleIndexInParent to increase
184         performance. */
185 
186     // XAccessibleComponent ---------------------------------------------------
187 
188     /** @return
189         <TRUE/>, if the point lies within the bounding box of this object. */
190     virtual sal_Bool SAL_CALL containsPoint( const ::com::sun::star::awt::Point& rPoint )
191         throw ( ::com::sun::star::uno::RuntimeException );
192 
193     /** @return  The bounding box of this object. */
194     virtual ::com::sun::star::awt::Rectangle SAL_CALL getBounds()
195         throw ( ::com::sun::star::uno::RuntimeException );
196 
197     /** @return
198         The upper left corner of the bounding box relative to the parent. */
199     virtual ::com::sun::star::awt::Point SAL_CALL getLocation()
200         throw ( ::com::sun::star::uno::RuntimeException );
201 
202     /** @return
203         The upper left corner of the bounding box in screen coordinates. */
204     virtual ::com::sun::star::awt::Point SAL_CALL getLocationOnScreen()
205         throw ( ::com::sun::star::uno::RuntimeException );
206 
207     /** @return  The size of the bounding box. */
208     virtual ::com::sun::star::awt::Size SAL_CALL getSize()
209         throw ( ::com::sun::star::uno::RuntimeException );
210 
211     /** @return  <TRUE/>, if the object is showing. */
212     virtual sal_Bool SAL_CALL isShowing()
213         throw ( ::com::sun::star::uno::RuntimeException );
214 
215     /** @return  <TRUE/>, if the object is visible. */
216     virtual sal_Bool SAL_CALL isVisible()
217         throw ( ::com::sun::star::uno::RuntimeException );
218 
219     /** @return  <TRUE/>, if the object can accept the focus. */
220     virtual sal_Bool SAL_CALL isFocusTraversable()
221         throw ( ::com::sun::star::uno::RuntimeException );
222 
223 	virtual sal_Int32 SAL_CALL getForeground(  ) throw (::com::sun::star::uno::RuntimeException);
224 	virtual sal_Int32 SAL_CALL getBackground(  ) throw (::com::sun::star::uno::RuntimeException);
225 
226 	// XFocusListener
227 	virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException);
228     virtual void SAL_CALL focusGained( const ::com::sun::star::awt::FocusEvent& e ) throw (::com::sun::star::uno::RuntimeException);
229     virtual void SAL_CALL focusLost( const ::com::sun::star::awt::FocusEvent& e ) throw (::com::sun::star::uno::RuntimeException);
230 
231     /*  Derived classes have to implement:
232         -   getAccessibleAt,
233         -   grabFocus,
234         -   getAccessibleKeyBinding. */
235 
236 	/** @return
237 		No key bindings supported by default.
238 	*/
239     virtual ::com::sun::star::uno::Any SAL_CALL getAccessibleKeyBinding()
240         throw ( ::com::sun::star::uno::RuntimeException );
241 	/** @return
242 			The accessible child rendered under the given point.
243 	*/
244     virtual ::com::sun::star::uno::Reference<
245         ::com::sun::star::accessibility::XAccessible > SAL_CALL
246     getAccessibleAtPoint( const ::com::sun::star::awt::Point& rPoint )
247         throw ( ::com::sun::star::uno::RuntimeException );
248 
249     // XAccessibleEventBroadcaster --------------------------------------------
250 
251     /** Adds a new event listener */
252     using cppu::WeakAggComponentImplHelperBase::addEventListener;
253     virtual void SAL_CALL addEventListener(
254             const ::com::sun::star::uno::Reference<
255                 ::com::sun::star::accessibility::XAccessibleEventListener>& rxListener )
256         throw ( ::com::sun::star::uno::RuntimeException );
257 
258     /** Removes an event listener. */
259     using cppu::WeakAggComponentImplHelperBase::removeEventListener;
260     virtual void SAL_CALL removeEventListener(
261 			const ::com::sun::star::uno::Reference<
262                 ::com::sun::star::accessibility::XAccessibleEventListener>& rxListener )
263         throw ( ::com::sun::star::uno::RuntimeException );
264 
265     // XTypeProvider ----------------------------------------------------------
266 
267     /** @return  An unique implementation ID. */
268     virtual ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId()
269         throw ( ::com::sun::star::uno::RuntimeException );
270 
271     // XServiceInfo -----------------------------------------------------------
272 
273     /** @return  Whether the specified service is supported by this class. */
274     virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& rServiceName )
275         throw ( ::com::sun::star::uno::RuntimeException );
276 
277     /** @return  A list of all supported services. */
278     virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL
279     getSupportedServiceNames()
280         throw ( ::com::sun::star::uno::RuntimeException );
281 
282     /*  Derived classes have to implement:
283         -   getImplementationName. */
284 
285     // helper methods ---------------------------------------------------------
286 
287     /** @return  The BrowseBox object type. */
288     inline ::svt::AccessibleBrowseBoxObjType getType() const;
289 
290     /** Changes the name of the object and notifies listeners. */
291     void setAccessibleName( const ::rtl::OUString& rName );
292     /** Changes the description of the object and notifies listeners. */
293     void setAccessibleDescription( const ::rtl::OUString& rDescription );
294 
295 	/** Commits an event to all listeners. */
296     void commitEvent(
297             sal_Int16 nEventId,
298             const ::com::sun::star::uno::Any& rNewValue,
299 
300     const ::com::sun::star::uno::Any& rOldValue );
301     /** @return  <TRUE/>, if the object is not disposed or disposing. */
302     sal_Bool isAlive() const;
303 
304 protected:
305     // internal virtual methods -----------------------------------------------
306 
307     /** Determines whether the BrowseBox control is really showing inside of
308         its parent accessible window. Derived classes may implement different
309         behaviour.
310         @attention  This method requires locked mutex's and a living object.
311         @return  <TRUE/>, if the object is really showing. */
312     virtual sal_Bool implIsShowing();
313 
314     /** Derived classes return the bounding box relative to the parent window.
315         @attention  This method requires locked mutex's and a living object.
316         @return  The bounding box (VCL rect.) relative to the parent window. */
317     virtual Rectangle implGetBoundingBox() = 0;
318     /** Derived classes return the bounding box in screen coordinates.
319         @attention  This method requires locked mutex's and a living object.
320         @return  The bounding box (VCL rect.) in screen coordinates. */
321     virtual Rectangle implGetBoundingBoxOnScreen() = 0;
322 
323     /** Creates a new AccessibleStateSetHelper and fills it with states of the
324         current object. This method calls FillStateSet at the BrowseBox which
325         fills it with more states depending on the object type. Derived classes
326         may overwrite this method and add more states.
327         @attention  This method requires locked mutex's.
328         @return  A filled AccessibleStateSetHelper. */
329     virtual ::utl::AccessibleStateSetHelper* implCreateStateSetHelper();
330 
331     // internal helper methods ------------------------------------------------
332 
333     /** @throws <type>DisposedException</type>  If the object is not alive. */
334     void ensureIsAlive() const
335         throw ( ::com::sun::star::lang::DisposedException );
336 
337     /** @return  The ::osl::Mutex member provided by the class OBaseMutex. */
338     inline ::osl::Mutex& getOslMutex();
339     /** @return  Pointer to the global ::osl::Mutex. */
340     static inline ::osl::Mutex* getOslGlobalMutex();
341 
342     /** Changes the name of the object (flat assignment, no notify).
343         @attention  This method requires a locked mutex. */
344     inline void implSetName( const ::rtl::OUString& rName );
345     /** Changes the description of the object (flat assignment, no notify).
346         @attention  This method requires a locked mutex. */
347     inline void implSetDescription( const ::rtl::OUString& rDescription );
348 
349     /** Locks all mutex's and calculates the bounding box relative to the
350         parent window.
351         @return  The bounding box (VCL rect.) relative to the parent object. */
352     Rectangle getBoundingBox()
353         throw ( ::com::sun::star::lang::DisposedException );
354     /** Locks all mutex's and calculates the bounding box in screen
355         coordinates.
356         @return  The bounding box (VCL rect.) in screen coordinates. */
357     Rectangle getBoundingBoxOnScreen()
358         throw ( ::com::sun::star::lang::DisposedException );
359 
360     /** Creates a new UUID, if rId is empty.
361         @attention  This method requires locked global mutex to prevent double
362                     creation of an UUID. */
363     static void implCreateUuid( ::com::sun::star::uno::Sequence< sal_Int8 >& rId );
364 
getClientId() const365 	::comphelper::AccessibleEventNotifier::TClientId getClientId() const { return m_aClientId; }
setClientId(::comphelper::AccessibleEventNotifier::TClientId _aNewClientId)366 	void setClientId(::comphelper::AccessibleEventNotifier::TClientId _aNewClientId) { m_aClientId = _aNewClientId; }
367 
368 public:
369 	// public versions of internal helper methods, with access control
AccessControlaccessibility::AccessibleBrowseBoxBase::AccessControl370 	struct AccessControl { friend class SolarMethodGuard; private: AccessControl() { } };
371 
getMutex(const AccessControl &)372 	inline ::osl::Mutex&	getMutex( const AccessControl& ) { return getOslMutex(); }
ensureIsAlive(const AccessControl &)373 	inline void             ensureIsAlive( const AccessControl& ) { ensureIsAlive(); }
374 
375 protected:
376     // members ----------------------------------------------------------------
377 
378     /** The parent accessible object. */
379     ::com::sun::star::uno::Reference<
380         ::com::sun::star::accessibility::XAccessible > mxParent;
381     /** The VCL BrowseBox control. */
382     ::svt::IAccessibleTableProvider* mpBrowseBox;
383 
384 	/** This is the window which get all the nice focus events
385 	*/
386 	::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow > m_xFocusWindow;
387 
388 private:
389     /** Localized name. */
390     ::rtl::OUString maName;
391     /** Localized description text. */
392     ::rtl::OUString maDescription;
393 
394     /** The type of this object (for names, descriptions, state sets, ...). */
395     ::svt::AccessibleBrowseBoxObjType meObjType;
396 
397 	::comphelper::AccessibleEventNotifier::TClientId	m_aClientId;
398 };
399 
400 // ============================================================================
401 // a version of AccessibleBrowseBoxBase which implements not only the XAccessibleContext,
402 // but also the XAccessible
403 
404 typedef ::cppu::ImplHelper1	<	::com::sun::star::accessibility::XAccessible
405 							>	BrowseBoxAccessibleElement_Base;
406 
407 class BrowseBoxAccessibleElement
408 			:public AccessibleBrowseBoxBase
409 			,public BrowseBoxAccessibleElement_Base
410 {
411 protected:
412     /** Constructor sets specified name and description. If the constant of a
413         text is BBTEXT_NONE, the derived class has to set the text via
414         implSetName() and implSetDescription() (in Ctor) or later via
415         setAccessibleName() and setAccessibleDescription() (these methods
416         notify the listeners about the change).
417 
418 		@param rxParent  XAccessible interface of the parent object.
419         @param rBrowseBox  The BrowseBox control.
420         @param eNameText  The constant for the name text.
421         @param eDescrText  The constant for the description text.
422 	*/
423     BrowseBoxAccessibleElement(
424         const ::com::sun::star::uno::Reference<
425             ::com::sun::star::accessibility::XAccessible >& rxParent,
426         ::svt::IAccessibleTableProvider&                  rBrowseBox,
427 		const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow >& _xFocusWindow,
428         ::svt::AccessibleBrowseBoxObjType  eObjType );
429 
430     /** Constructor sets specified name and description.
431 
432 		@param rxParent  XAccessible interface of the parent object.
433         @param rBrowseBox  The BrowseBox control.
434         @param rName  The name of this object.
435         @param rDescription  The description text of this object.
436 	*/
437     BrowseBoxAccessibleElement(
438         const ::com::sun::star::uno::Reference<
439             ::com::sun::star::accessibility::XAccessible >& rxParent,
440         ::svt::IAccessibleTableProvider&                  rBrowseBox,
441 		const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow >& _xFocusWindow,
442         ::svt::AccessibleBrowseBoxObjType  eObjType,
443         const ::rtl::OUString&      rName,
444         const ::rtl::OUString&      rDescription );
445 
446 public:
447 	// XInterface
448 	DECLARE_XINTERFACE( )
449 	// XTypeProvider
450 	DECLARE_XTYPEPROVIDER( )
451 
452 protected:
453     virtual ~BrowseBoxAccessibleElement();
454 
455 protected:
456 	// XAccessible ------------------------------------------------------------
457 
458 	/** @return  The XAccessibleContext interface of this object. */
459 	virtual ::com::sun::star::uno::Reference<
460 		::com::sun::star::accessibility::XAccessibleContext > SAL_CALL
461 	getAccessibleContext()
462 		throw ( ::com::sun::star::uno::RuntimeException );
463 
464 private:
465 	BrowseBoxAccessibleElement();												// never implemented
466 	BrowseBoxAccessibleElement( const BrowseBoxAccessibleElement& );			// never implemented
467 	BrowseBoxAccessibleElement& operator=( const BrowseBoxAccessibleElement& );	// never implemented
468 };
469 
470 // ============================================================================
471 // a helper class for protecting methods which need to lock the solar mutex in addition to the own mutex
472 
473 typedef ::osl::MutexGuard OslMutexGuard;
474 
475 class SolarMethodGuard : public BBSolarGuard, public OslMutexGuard
476 {
477 public:
SolarMethodGuard(AccessibleBrowseBoxBase & _rOwner,bool _bEnsureAlive=true)478 	inline SolarMethodGuard( AccessibleBrowseBoxBase& _rOwner, bool _bEnsureAlive = true )
479 		:BBSolarGuard( )
480 		,OslMutexGuard( _rOwner.getMutex( AccessibleBrowseBoxBase::AccessControl() ) )
481 	{
482 		if ( _bEnsureAlive )
483 			_rOwner.ensureIsAlive( AccessibleBrowseBoxBase::AccessControl() );
484 	}
485 };
486 
487 // inlines --------------------------------------------------------------------
488 
getType() const489 inline ::svt::AccessibleBrowseBoxObjType AccessibleBrowseBoxBase::getType() const
490 {
491     return meObjType;
492 }
493 
getOslMutex()494 inline ::osl::Mutex& AccessibleBrowseBoxBase::getOslMutex()
495 {
496     return m_aMutex;
497 }
498 
getOslGlobalMutex()499 inline ::osl::Mutex* AccessibleBrowseBoxBase::getOslGlobalMutex()
500 {
501     return ::osl::Mutex::getGlobalMutex();
502 }
503 
implSetName(const::rtl::OUString & rName)504 inline void AccessibleBrowseBoxBase::implSetName(
505         const ::rtl::OUString& rName )
506 {
507     maName = rName;
508 }
509 
implSetDescription(const::rtl::OUString & rDescription)510 inline void AccessibleBrowseBoxBase::implSetDescription(
511         const ::rtl::OUString& rDescription )
512 {
513     maDescription = rDescription;
514 }
515 
516 // ============================================================================
517 
518 } // namespace accessibility
519 
520 // ============================================================================
521 
522 #endif
523 
524