xref: /trunk/main/svx/source/accessibility/svxrectctaccessiblecontext.cxx (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 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_svx.hxx"
26 
27 
28 #include "svxrectctaccessiblecontext.hxx"
29 #include <com/sun/star/accessibility/AccessibleRole.hpp>
30 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
31 #include <unotools/accessiblestatesethelper.hxx>
32 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
33 #include <com/sun/star/beans/PropertyChangeEvent.hpp>
34 #include <com/sun/star/awt/XWindow.hpp>
35 #include <cppuhelper/typeprovider.hxx>
36 #include <toolkit/helper/vclunohelper.hxx>
37 #include <toolkit/helper/convert.hxx>
38 #include <vcl/svapp.hxx>
39 #include <osl/mutex.hxx>
40 #include <rtl/uuid.h>
41 #include <tools/debug.hxx>
42 #include <tools/gen.hxx>
43 
44 #include <svx/dialogs.hrc>
45 #include "accessibility.hrc"
46 #include <svx/dlgctrl.hxx>
47 #include <svx/dialmgr.hxx>
48 #include <comphelper/accessibleeventnotifier.hxx>
49 #ifndef _COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLERELATIONTYPE_HPP_
50 #include <com/sun/star/accessibility/AccessibleRelationType.hpp>
51 #endif
52 #ifndef _UTL_ACCESSIBLERELATIONSETHELPER_HXX_
53 #include <unotools/accessiblerelationsethelper.hxx>
54 #endif
55 
56 using namespace ::cppu;
57 using namespace ::osl;
58 using namespace ::com::sun::star;
59 using namespace ::com::sun::star::uno;
60 using namespace ::com::sun::star::accessibility;
61 
62 using namespace ::com::sun::star::lang;
63 
64 #define MAX_NUM_OF_CHILDS   9
65 #define NOCHILDSELECTED     -1
66 
67 
68 DBG_NAME( SvxRectCtlAccessibleContext )
69 
70 
71 //=====  internal  ============================================================
72 
73 namespace
74 {
75     struct ChildIndexToPointData
76     {
77         short       nResIdName;
78         short       nResIdDescr;
79         RECT_POINT  ePoint;
80     };
81 }
82 
83 
IndexToPoint(long nIndex,sal_Bool bAngleControl)84 static const ChildIndexToPointData* IndexToPoint( long nIndex, sal_Bool bAngleControl )
85 {
86     DBG_ASSERT( nIndex < ( bAngleControl? 8 : 9 ) && nIndex >= 0, "-IndexToPoint(): invalid child index! You have been warned..." );
87 
88     // angles are counted reverse counter clock wise
89     static const ChildIndexToPointData  pAngleData[] =
90     {                                                   // index
91         {   RID_SVXSTR_RECTCTL_ACC_CHLD_A000,   RID_SVXSTR_RECTCTL_ACC_CHLD_A000,   RP_RM },    //  0
92         {   RID_SVXSTR_RECTCTL_ACC_CHLD_A045,   RID_SVXSTR_RECTCTL_ACC_CHLD_A045,   RP_RT },    //  1
93         {   RID_SVXSTR_RECTCTL_ACC_CHLD_A090,   RID_SVXSTR_RECTCTL_ACC_CHLD_A090,   RP_MT },    //  2
94         {   RID_SVXSTR_RECTCTL_ACC_CHLD_A135,   RID_SVXSTR_RECTCTL_ACC_CHLD_A135,   RP_LT },    //  3
95         {   RID_SVXSTR_RECTCTL_ACC_CHLD_A180,   RID_SVXSTR_RECTCTL_ACC_CHLD_A180,   RP_LM },    //  4
96         {   RID_SVXSTR_RECTCTL_ACC_CHLD_A225,   RID_SVXSTR_RECTCTL_ACC_CHLD_A225,   RP_LB },    //  5
97         {   RID_SVXSTR_RECTCTL_ACC_CHLD_A270,   RID_SVXSTR_RECTCTL_ACC_CHLD_A270,   RP_MB },    //  6
98         {   RID_SVXSTR_RECTCTL_ACC_CHLD_A315,   RID_SVXSTR_RECTCTL_ACC_CHLD_A315,   RP_RB }     //  7
99     };
100 
101     // corners are counted from left to right and top to bottom
102     static const ChildIndexToPointData  pCornerData[] =
103     {                                                                   // index
104         {   RID_SVXSTR_RECTCTL_ACC_CHLD_LT, RID_SVXSTR_RECTCTL_ACC_CHLD_LT, RP_LT },    //  0
105         {   RID_SVXSTR_RECTCTL_ACC_CHLD_MT, RID_SVXSTR_RECTCTL_ACC_CHLD_MT, RP_MT },    //  1
106         {   RID_SVXSTR_RECTCTL_ACC_CHLD_RT, RID_SVXSTR_RECTCTL_ACC_CHLD_RT, RP_RT },    //  2
107         {   RID_SVXSTR_RECTCTL_ACC_CHLD_LM, RID_SVXSTR_RECTCTL_ACC_CHLD_LM, RP_LM },    //  3
108         {   RID_SVXSTR_RECTCTL_ACC_CHLD_MM, RID_SVXSTR_RECTCTL_ACC_CHLD_MM, RP_MM },    //  4
109         {   RID_SVXSTR_RECTCTL_ACC_CHLD_RM, RID_SVXSTR_RECTCTL_ACC_CHLD_RM, RP_RM },    //  5
110         {   RID_SVXSTR_RECTCTL_ACC_CHLD_LB, RID_SVXSTR_RECTCTL_ACC_CHLD_LB, RP_LB },    //  6
111         {   RID_SVXSTR_RECTCTL_ACC_CHLD_MB, RID_SVXSTR_RECTCTL_ACC_CHLD_MB, RP_MB },    //  7
112         {   RID_SVXSTR_RECTCTL_ACC_CHLD_RB, RID_SVXSTR_RECTCTL_ACC_CHLD_RB, RP_RB }     //  8
113     };
114 
115     return ( bAngleControl? pAngleData : pCornerData ) + nIndex;
116 }
117 
118 
PointToIndex(RECT_POINT ePoint,sal_Bool bAngleControl)119 static long PointToIndex( RECT_POINT ePoint, sal_Bool bAngleControl )
120 {
121     long    nRet( (long) ePoint );
122     if( bAngleControl )
123     {   // angle control
124         // angles are counted reverse counter clock wise
125         switch( ePoint )
126         {
127             case RP_LT: nRet = 3;               break;
128             case RP_MT: nRet = 2;               break;
129             case RP_RT: nRet = 1;               break;
130             case RP_LM: nRet = 4;               break;
131             case RP_MM: nRet = NOCHILDSELECTED; break;
132             case RP_RM: nRet = 0;               break;
133             case RP_LB: nRet = 5;               break;
134             case RP_MB: nRet = 6;               break;
135             case RP_RB: nRet = 7;               break;
136         }
137     }
138     else
139     {   // corner control
140         // corners are counted from left to right and top to bottom
141         DBG_ASSERT( RP_LT == 0 && RP_MT == 1 && RP_RT == 2 && RP_LM == 3 && RP_MM == 4 && RP_RM == 5 &&
142                     RP_LB == 6 && RP_MB == 7 && RP_RB == 8, "*PointToIndex(): unexpected enum value!" );
143 
144         nRet = ( long ) ePoint;
145     }
146 
147     return nRet;
148 }
149 
150 
SvxRectCtlAccessibleContext(const Reference<XAccessible> & rxParent,SvxRectCtl & rRepr,const::rtl::OUString * pName,const::rtl::OUString * pDesc)151 SvxRectCtlAccessibleContext::SvxRectCtlAccessibleContext(
152     const Reference< XAccessible >&     rxParent,
153     SvxRectCtl&                         rRepr,
154     const ::rtl::OUString*                      pName,
155     const ::rtl::OUString*                      pDesc ) :
156 
157     SvxRectCtlAccessibleContext_Base( m_aMutex ),
158     mxParent( rxParent ),
159     mpRepr( &rRepr ),
160     mpChilds( NULL ),
161     mnClientId( 0 ),
162     mnSelectedChild( NOCHILDSELECTED ),
163     mbAngleMode( rRepr.GetNumOfChilds() == 8 )
164 {
165     DBG_CTOR( SvxRectCtlAccessibleContext, NULL );
166 
167     if( pName )
168         msName = *pName;
169     else
170     {
171         ::vos::OGuard   aSolarGuard( Application::GetSolarMutex() );
172         msName = SVX_RESSTR( mbAngleMode? RID_SVXSTR_RECTCTL_ACC_ANGL_NAME : RID_SVXSTR_RECTCTL_ACC_CORN_NAME );
173     }
174 
175     if( pDesc )
176         msDescription = *pDesc;
177     else
178     {
179         ::vos::OGuard   aSolarGuard( Application::GetSolarMutex() );
180         msDescription = SVX_RESSTR( mbAngleMode? RID_SVXSTR_RECTCTL_ACC_ANGL_DESCR : RID_SVXSTR_RECTCTL_ACC_CORN_DESCR );
181     }
182 
183     mpChilds = new SvxRectCtlChildAccessibleContext*[ MAX_NUM_OF_CHILDS ];
184 
185     SvxRectCtlChildAccessibleContext**  p = mpChilds;
186     for( int i = MAX_NUM_OF_CHILDS ; i ; --i, ++p )
187         *p = NULL;
188 }
189 
190 
~SvxRectCtlAccessibleContext()191 SvxRectCtlAccessibleContext::~SvxRectCtlAccessibleContext()
192 {
193     DBG_DTOR( SvxRectCtlAccessibleContext, NULL );
194 
195     if( IsAlive() )
196     {
197         osl_incrementInterlockedCount( &m_refCount );
198         dispose();      // set mpRepr = NULL & release all childs
199     }
200 }
201 
202 //=====  XAccessible  =========================================================
203 
getAccessibleContext(void)204 Reference< XAccessibleContext > SAL_CALL SvxRectCtlAccessibleContext::getAccessibleContext( void )
205 {
206     return this;
207 }
208 
209 //=====  XAccessibleComponent  ================================================
210 
containsPoint(const awt::Point & rPoint)211 sal_Bool SAL_CALL SvxRectCtlAccessibleContext::containsPoint( const awt::Point& rPoint )
212 {
213     // no guard -> done in getBounds()
214 //  return GetBoundingBox().IsInside( VCLPoint( rPoint ) );
215     return Rectangle( Point( 0, 0 ), GetBoundingBox().GetSize() ).IsInside( VCLPoint( rPoint ) );
216 }
217 
getAccessibleAtPoint(const awt::Point & rPoint)218 Reference< XAccessible > SAL_CALL SvxRectCtlAccessibleContext::getAccessibleAtPoint( const awt::Point& rPoint )
219 {
220     ::osl::MutexGuard           aGuard( m_aMutex );
221 
222     ThrowExceptionIfNotAlive();
223 
224     Reference< XAccessible >    xRet;
225 
226     long                        nChild = PointToIndex( mpRepr->GetApproxRPFromPixPt( rPoint ), mbAngleMode );
227 
228     if( nChild != NOCHILDSELECTED )
229         xRet = getAccessibleChild( nChild );
230 
231     return xRet;
232 }
233 
getBounds()234 awt::Rectangle SAL_CALL SvxRectCtlAccessibleContext::getBounds()
235 {
236     // no guard -> done in GetBoundingBox()
237     return AWTRectangle( GetBoundingBox() );
238 }
239 
getLocation()240 awt::Point SAL_CALL SvxRectCtlAccessibleContext::getLocation()
241 {
242     // no guard -> done in GetBoundingBox()
243     return AWTPoint( GetBoundingBox().TopLeft() );
244 }
245 
getLocationOnScreen()246 awt::Point SAL_CALL SvxRectCtlAccessibleContext::getLocationOnScreen()
247 {
248     // no guard -> done in GetBoundingBoxOnScreen()
249     return AWTPoint( GetBoundingBoxOnScreen().TopLeft() );
250 }
251 
getSize()252 awt::Size SAL_CALL SvxRectCtlAccessibleContext::getSize()
253 {
254     // no guard -> done in GetBoundingBox()
255     return AWTSize( GetBoundingBox().GetSize() );
256 }
257 
isShowing()258 sal_Bool SAL_CALL SvxRectCtlAccessibleContext::isShowing()
259 {
260     return sal_True;
261 }
262 
isVisible()263 sal_Bool SAL_CALL SvxRectCtlAccessibleContext::isVisible()
264 {
265     ::osl::MutexGuard           aGuard( m_aMutex );
266 
267     ThrowExceptionIfNotAlive();
268 
269     return mpRepr->IsVisible();
270 }
271 
isFocusTraversable()272 sal_Bool SAL_CALL SvxRectCtlAccessibleContext::isFocusTraversable()
273 {
274     return sal_True;
275 }
276 
277 //=====  XAccessibleContext  ==================================================
278 
getAccessibleChildCount(void)279 sal_Int32 SAL_CALL SvxRectCtlAccessibleContext::getAccessibleChildCount( void )
280 {
281     ::osl::MutexGuard   aGuard( m_aMutex );
282 
283     ThrowExceptionIfNotAlive();
284 
285     return mpRepr->GetNumOfChilds();
286 }
287 
getAccessibleChild(sal_Int32 nIndex)288 Reference< XAccessible > SAL_CALL SvxRectCtlAccessibleContext::getAccessibleChild( sal_Int32 nIndex )
289 {
290     checkChildIndex( nIndex );
291 
292     Reference< XAccessible >    xChild = mpChilds[ nIndex ];
293     if( !xChild.is() )
294     {
295         ::vos::OGuard       aSolarGuard( Application::GetSolarMutex() );
296 
297         ::osl::MutexGuard   aGuard( m_aMutex );
298 
299         ThrowExceptionIfNotAlive();
300 
301         xChild = mpChilds[ nIndex ];
302 
303         if( !xChild.is() )
304         {
305             const ChildIndexToPointData*    p = IndexToPoint( nIndex, mbAngleMode );
306             UniString       tmp = SVX_RESSTR( p->nResIdName );
307             ::rtl::OUString     aName( tmp );
308                         tmp = SVX_RESSTR( p->nResIdDescr );
309             ::rtl::OUString     aDescr( tmp );
310 
311             Rectangle       aFocusRect( mpRepr->CalculateFocusRectangle( p->ePoint ) );
312 
313             Rectangle       aBoundingBoxOnScreen( mpRepr->OutputToScreenPixel( aFocusRect.TopLeft() ), aFocusRect.GetSize() );
314 
315             SvxRectCtlChildAccessibleContext*   pChild = new SvxRectCtlChildAccessibleContext(
316                                                     this, *mpRepr, aName, aDescr, aFocusRect, nIndex );
317             xChild = mpChilds[ nIndex ] = pChild;
318             pChild->acquire();
319 
320             // set actual state
321             if( mnSelectedChild == nIndex )
322                 pChild->setStateChecked( sal_True );
323         }
324     }
325 
326     return xChild;
327 }
328 
getAccessibleParent(void)329 Reference< XAccessible > SAL_CALL SvxRectCtlAccessibleContext::getAccessibleParent( void )
330 {
331     return mxParent;
332 }
333 
getAccessibleIndexInParent(void)334 sal_Int32 SAL_CALL SvxRectCtlAccessibleContext::getAccessibleIndexInParent( void )
335 {
336     ::osl::MutexGuard   aGuard( m_aMutex );
337     //  Use a simple but slow solution for now.  Optimize later.
338 
339     //  Iterate over all the parent's children and search for this object.
340     if( mxParent.is() )
341     {
342         Reference< XAccessibleContext >     xParentContext( mxParent->getAccessibleContext() );
343         if( xParentContext.is() )
344         {
345             sal_Int32                       nChildCount = xParentContext->getAccessibleChildCount();
346             for( sal_Int32 i = 0 ; i < nChildCount ; ++i )
347             {
348                 Reference< XAccessible >    xChild( xParentContext->getAccessibleChild( i ) );
349                 if( xChild.get() == ( XAccessible* ) this )
350                     return i;
351             }
352         }
353    }
354 
355    //   Return -1 to indicate that this object's parent does not know about the
356    //   object.
357    return -1;
358 }
359 
getAccessibleRole(void)360 sal_Int16 SAL_CALL SvxRectCtlAccessibleContext::getAccessibleRole( void )
361 {
362     //return AccessibleRole::GROUP_BOX;
363     return AccessibleRole::PANEL;
364 }
365 
getAccessibleDescription(void)366 ::rtl::OUString SAL_CALL SvxRectCtlAccessibleContext::getAccessibleDescription( void )
367 {
368     ::osl::MutexGuard   aGuard( m_aMutex );
369     return msDescription +::rtl::OUString::createFromAscii(" Please use arrow key to selection.");
370 }
371 
getAccessibleName(void)372 ::rtl::OUString SAL_CALL SvxRectCtlAccessibleContext::getAccessibleName( void )
373 {
374     ::osl::MutexGuard   aGuard( m_aMutex );
375     return msName;
376 }
377 
378 /** Return empty reference to indicate that the relation set is not
379     supported.
380 */
getAccessibleRelationSet(void)381 Reference< XAccessibleRelationSet > SAL_CALL SvxRectCtlAccessibleContext::getAccessibleRelationSet( void )
382 {
383     utl::AccessibleRelationSetHelper* pRelationSetHelper = new utl::AccessibleRelationSetHelper;
384     uno::Reference< accessibility::XAccessibleRelationSet > xSet = pRelationSetHelper;
385     Window* pWindow = mpRepr;
386     if ( pWindow )
387     {
388         // Window *pLabeledBy = pWindow->GetAccRelationLabeledBy();
389         Window *pLabeledBy = pWindow->GetAccessibleRelationLabeledBy();
390         if ( pLabeledBy && pLabeledBy != pWindow )
391         {
392             uno::Sequence< uno::Reference< uno::XInterface > > aSequence(1);
393             aSequence[0] = pLabeledBy->GetAccessible();
394             pRelationSetHelper->AddRelation( accessibility::AccessibleRelation( accessibility::AccessibleRelationType::LABELED_BY, aSequence ) );
395         }
396         Window* pMemberOf = pWindow->GetAccessibleRelationMemberOf();
397         if ( pMemberOf && pMemberOf != pWindow )
398         {
399             uno::Sequence< uno::Reference< uno::XInterface > > aSequence(1);
400             aSequence[0] = pMemberOf->GetAccessible();
401             pRelationSetHelper->AddRelation( accessibility::AccessibleRelation( accessibility::AccessibleRelationType::MEMBER_OF, aSequence ) );
402         }
403     }
404     return xSet;
405 }
406 //Solution:Add the event handling method
FireAccessibleEvent(short nEventId,const::com::sun::star::uno::Any & rOld,const::com::sun::star::uno::Any & rNew)407 void SvxRectCtlAccessibleContext::FireAccessibleEvent (short nEventId, const ::com::sun::star::uno::Any& rOld, const ::com::sun::star::uno::Any& rNew)
408 {
409     const Reference< XInterface >   xSource( *this );
410     CommitChange( AccessibleEventObject( xSource, nEventId, rNew,rOld ) );
411 }
getAccessibleStateSet(void)412 Reference< XAccessibleStateSet > SAL_CALL SvxRectCtlAccessibleContext::getAccessibleStateSet( void )
413 {
414     ::osl::MutexGuard                       aGuard( m_aMutex );
415     utl::AccessibleStateSetHelper*          pStateSetHelper = new utl::AccessibleStateSetHelper;
416 
417     if( IsAlive() )
418     {
419         pStateSetHelper->AddState( AccessibleStateType::ENABLED );
420         // pStateSetHelper->AddState( AccessibleStateType::SENSITIVE );
421         pStateSetHelper->AddState( AccessibleStateType::FOCUSABLE );
422         if( mpRepr->HasFocus() )
423             pStateSetHelper->AddState( AccessibleStateType::FOCUSED );
424         pStateSetHelper->AddState( AccessibleStateType::OPAQUE );
425 
426         if( isShowing() )
427             pStateSetHelper->AddState( AccessibleStateType::SHOWING );
428 
429         if( isVisible() )
430             pStateSetHelper->AddState( AccessibleStateType::VISIBLE );
431     }
432     else
433         pStateSetHelper->AddState( AccessibleStateType::DEFUNC );
434 
435     return pStateSetHelper;
436 }
437 
getLocale(void)438 lang::Locale SAL_CALL SvxRectCtlAccessibleContext::getLocale( void )
439 {
440     ::osl::MutexGuard                           aGuard( m_aMutex );
441     if( mxParent.is() )
442     {
443         Reference< XAccessibleContext > xParentContext( mxParent->getAccessibleContext() );
444         if( xParentContext.is() )
445             return xParentContext->getLocale();
446     }
447 
448     //  No parent.  Therefore throw exception to indicate this cluelessness.
449     throw IllegalAccessibleComponentStateException();
450 }
451 
addEventListener(const Reference<XAccessibleEventListener> & xListener)452 void SAL_CALL SvxRectCtlAccessibleContext::addEventListener( const Reference< XAccessibleEventListener >& xListener )
453 {
454     if (xListener.is())
455     {
456         ::osl::MutexGuard   aGuard( m_aMutex );
457         if (!mnClientId)
458             mnClientId = comphelper::AccessibleEventNotifier::registerClient( );
459         comphelper::AccessibleEventNotifier::addEventListener( mnClientId, xListener );
460     }
461 }
462 
removeEventListener(const Reference<XAccessibleEventListener> & xListener)463 void SAL_CALL SvxRectCtlAccessibleContext::removeEventListener( const Reference< XAccessibleEventListener >& xListener )
464 {
465     if (xListener.is())
466     {
467         ::osl::MutexGuard   aGuard( m_aMutex );
468 
469         sal_Int32 nListenerCount = comphelper::AccessibleEventNotifier::removeEventListener( mnClientId, xListener );
470         if ( !nListenerCount )
471         {
472             // no listeners anymore
473             // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client),
474             // and at least to us not firing any events anymore, in case somebody calls
475             // NotifyAccessibleEvent, again
476             comphelper::AccessibleEventNotifier::revokeClient( mnClientId );
477             mnClientId = 0;
478         }
479     }
480 }
481 
addFocusListener(const Reference<awt::XFocusListener> & xListener)482 void SAL_CALL SvxRectCtlAccessibleContext::addFocusListener( const Reference< awt::XFocusListener >& xListener )
483 {
484     if( xListener.is() )
485     {
486         ::osl::MutexGuard   aGuard( m_aMutex );
487 
488         ThrowExceptionIfNotAlive();
489 
490         Reference< awt::XWindow >   xWindow = VCLUnoHelper::GetInterface( mpRepr );
491         if( xWindow.is() )
492             xWindow->addFocusListener( xListener );
493     }
494 }
495 
removeFocusListener(const Reference<awt::XFocusListener> & xListener)496 void SAL_CALL SvxRectCtlAccessibleContext::removeFocusListener( const Reference< awt::XFocusListener >& xListener )
497 {
498     if( xListener.is() )
499     {
500         ::osl::MutexGuard   aGuard( m_aMutex );
501 
502         ThrowExceptionIfNotAlive();
503 
504         Reference< awt::XWindow >   xWindow = VCLUnoHelper::GetInterface( mpRepr );
505         if( xWindow.is() )
506             xWindow->removeFocusListener( xListener );
507     }
508 }
509 
grabFocus()510 void SAL_CALL SvxRectCtlAccessibleContext::grabFocus()
511 {
512     ::vos::OGuard       aSolarGuard( Application::GetSolarMutex() );
513     ::osl::MutexGuard   aGuard( m_aMutex );
514 
515     ThrowExceptionIfNotAlive();
516 
517     mpRepr->GrabFocus();
518 }
519 
getAccessibleKeyBinding()520 Any SAL_CALL SvxRectCtlAccessibleContext::getAccessibleKeyBinding()
521 {
522     // here is no implementation, because here are no KeyBindings for every object
523     return Any();
524 }
525 
getForeground()526 sal_Int32 SvxRectCtlAccessibleContext::getForeground(  )
527 {
528     ::vos::OGuard       aSolarGuard( Application::GetSolarMutex() );
529     ::osl::MutexGuard   aGuard( m_aMutex );
530     ThrowExceptionIfNotAlive();
531 
532     return mpRepr->GetControlForeground().GetColor();
533 }
getBackground()534 sal_Int32 SvxRectCtlAccessibleContext::getBackground(  )
535 {
536     ::vos::OGuard       aSolarGuard( Application::GetSolarMutex() );
537     ::osl::MutexGuard   aGuard( m_aMutex );
538     ThrowExceptionIfNotAlive();
539 
540     return mpRepr->GetControlBackground().GetColor();
541 }
542 
543 //=====  XServiceInfo  ========================================================
544 
getImplementationName(void)545 ::rtl::OUString SAL_CALL SvxRectCtlAccessibleContext::getImplementationName( void )
546 {
547     return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.ui.SvxRectCtlAccessibleContext" ) );
548 }
549 
supportsService(const::rtl::OUString & sServiceName)550 sal_Bool SAL_CALL SvxRectCtlAccessibleContext::supportsService( const ::rtl::OUString& sServiceName )
551 {
552     ::osl::MutexGuard   aGuard( m_aMutex );
553     //  Iterate over all supported service names and return true if on of them
554     //  matches the given name.
555     Sequence< ::rtl::OUString > aSupportedServices( getSupportedServiceNames() );
556     int                     nLength = aSupportedServices.getLength();
557     const ::rtl::OUString*          pStr = aSupportedServices.getConstArray();
558 
559     for( int i = nLength ; i ; --i, ++pStr )
560     {
561         if( sServiceName == *pStr )
562             return sal_True;
563     }
564 
565     return sal_False;
566 }
567 
getSupportedServiceNames(void)568 Sequence< ::rtl::OUString > SAL_CALL SvxRectCtlAccessibleContext::getSupportedServiceNames( void )
569 {
570     const ::rtl::OUString sServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.accessibility.AccessibleContext" ) );
571     return Sequence< ::rtl::OUString >( &sServiceName, 1 );
572 }
573 
574 //=====  XTypeProvider  =======================================================
575 
getImplementationId(void)576 Sequence< sal_Int8 > SAL_CALL SvxRectCtlAccessibleContext::getImplementationId( void )
577 {
578     return getUniqueId();
579 }
580 
581 //=====  XAccessibleSelection =============================================
582 
selectAccessibleChild(sal_Int32 nIndex)583 void SAL_CALL SvxRectCtlAccessibleContext::selectAccessibleChild( sal_Int32 nIndex )
584 {
585     ::vos::OGuard       aSolarGuard( Application::GetSolarMutex() );
586 
587     ::osl::MutexGuard   aGuard( m_aMutex );
588 
589     checkChildIndex( nIndex );
590 
591     ThrowExceptionIfNotAlive();
592 
593     const ChildIndexToPointData*    pData = IndexToPoint( nIndex, mbAngleMode );
594 
595     DBG_ASSERT( pData,
596         "SvxRectCtlAccessibleContext::selectAccessibleChild(): this is an impossible state! Or at least should be..." );
597 
598     // this does all which is needed, including the change of the child's state!
599     mpRepr->SetActualRP( pData->ePoint );
600 }
601 
isAccessibleChildSelected(sal_Int32 nIndex)602 sal_Bool SAL_CALL SvxRectCtlAccessibleContext::isAccessibleChildSelected( sal_Int32 nIndex )
603 {
604     ::osl::MutexGuard   aGuard( m_aMutex );
605 
606     checkChildIndex( nIndex );
607 
608     return nIndex == mnSelectedChild;
609 }
610 
clearAccessibleSelection()611 void SAL_CALL SvxRectCtlAccessibleContext::clearAccessibleSelection()
612 {
613     DBG_ASSERT( sal_False, "SvxRectCtlAccessibleContext::clearAccessibleSelection() is not possible!" );
614 }
615 
selectAllAccessibleChildren()616 void SAL_CALL SvxRectCtlAccessibleContext::selectAllAccessibleChildren()
617 {
618     // guard in selectAccessibleChild()!
619 
620     selectAccessibleChild( 0 );     // default per definition
621 }
622 
getSelectedAccessibleChildCount()623 sal_Int32 SAL_CALL SvxRectCtlAccessibleContext::getSelectedAccessibleChildCount()
624 {
625     ::osl::MutexGuard   aGuard( m_aMutex );
626 
627     return mnSelectedChild == NOCHILDSELECTED? 0 : 1;
628 }
629 
getSelectedAccessibleChild(sal_Int32 nIndex)630 Reference< XAccessible > SAL_CALL SvxRectCtlAccessibleContext::getSelectedAccessibleChild( sal_Int32 nIndex )
631 {
632     ::osl::MutexGuard   aGuard( m_aMutex );
633 
634     checkChildIndexOnSelection( nIndex );
635 
636     return getAccessibleChild( mnSelectedChild );
637 }
638 
deselectAccessibleChild(sal_Int32)639 void SAL_CALL SvxRectCtlAccessibleContext::deselectAccessibleChild( sal_Int32 /*nIndex*/ )
640 {
641     ::rtl::OUString aMessage( RTL_CONSTASCII_USTRINGPARAM( "deselectAccessibleChild is not possible in this context" ) );
642 
643     DBG_ASSERT( sal_False, "SvxRectCtlAccessibleContext::deselectAccessibleChild() is not possible!" );
644 
645     throw lang::IndexOutOfBoundsException( aMessage, *this );   // never possible
646 }
647 
648 //=====  internals ========================================================
649 
checkChildIndex(long nIndex)650 void SvxRectCtlAccessibleContext::checkChildIndex( long nIndex )
651 {
652     if( nIndex < 0 || nIndex >= getAccessibleChildCount() )
653         throw lang::IndexOutOfBoundsException();
654 }
655 
checkChildIndexOnSelection(long nIndex)656 void SvxRectCtlAccessibleContext::checkChildIndexOnSelection( long nIndex )
657 {
658     if( nIndex || mnSelectedChild == NOCHILDSELECTED )
659         // in our case only for the first (0) _selected_ child this is a valid request
660         throw lang::IndexOutOfBoundsException();
661 }
FireChildFocus(RECT_POINT eButton)662 void SvxRectCtlAccessibleContext::FireChildFocus( RECT_POINT eButton )
663 {
664     ::osl::MutexGuard   aGuard( m_aMutex );
665     long nNew = PointToIndex( eButton, mbAngleMode );
666     long    nNumOfChilds = getAccessibleChildCount();
667     if( nNew < nNumOfChilds )
668     {
669         // select new child
670         SvxRectCtlChildAccessibleContext*   pChild;
671         mnSelectedChild = nNew;
672         if( nNew != NOCHILDSELECTED )
673         {
674             pChild = mpChilds[ nNew ];
675             if( pChild )
676             {
677                 pChild->FireFocusEvent();
678             }
679         }
680         else
681         {
682             const Reference< XInterface >   xSource( *this );
683             Any                             aOld;
684             Any                             aNew;
685             aNew <<= AccessibleStateType::FOCUSED;
686             CommitChange( AccessibleEventObject( xSource, AccessibleEventId::STATE_CHANGED, aNew, aOld ) );
687         }
688     }
689     else
690         mnSelectedChild = NOCHILDSELECTED;
691 }
selectChild(long nNew,sal_Bool bFireFocus)692 void SvxRectCtlAccessibleContext::selectChild( long nNew, sal_Bool bFireFocus )
693 {
694     ::osl::MutexGuard   aGuard( m_aMutex );
695     if( nNew != mnSelectedChild )
696     {
697         long    nNumOfChilds = getAccessibleChildCount();
698         if( nNew < nNumOfChilds )
699         {   // valid index
700             SvxRectCtlChildAccessibleContext*   pChild;
701             if( mnSelectedChild != NOCHILDSELECTED )
702             {   // deselect old selected child if one is selected
703                 pChild = mpChilds[ mnSelectedChild ];
704                 if( pChild )
705                     pChild->setStateChecked( sal_False, bFireFocus );
706             }
707 
708             // select new child
709             mnSelectedChild = nNew;
710 
711             if( nNew != NOCHILDSELECTED )
712             {
713                 pChild = mpChilds[ nNew ];
714                 if( pChild )
715                     pChild->setStateChecked( sal_True, bFireFocus );
716             }
717         }
718         else
719             mnSelectedChild = NOCHILDSELECTED;
720     }
721 }
722 
selectChild(RECT_POINT eButton,sal_Bool bFireFocus)723 void SvxRectCtlAccessibleContext::selectChild( RECT_POINT eButton , sal_Bool bFireFocus)
724 {
725     // no guard -> is done in next selectChild
726     selectChild( PointToIndex( eButton, mbAngleMode ) , bFireFocus);
727 }
setName(const::rtl::OUString & rName)728 void SvxRectCtlAccessibleContext::setName( const ::rtl::OUString& rName )
729 {
730     Any                     aPreVal, aPostVal;
731     {
732         ::osl::MutexGuard   aGuard( m_aMutex );
733 
734         aPreVal <<= msName;
735         aPostVal <<= rName;
736 
737         msName = rName;
738     }
739 
740     const Reference< XInterface >   xSource( *this );
741     CommitChange( AccessibleEventObject( xSource, AccessibleEventId::NAME_CHANGED, aPreVal, aPostVal ) );
742 }
743 
setDescription(const::rtl::OUString & rDescr)744 void SvxRectCtlAccessibleContext::setDescription( const ::rtl::OUString& rDescr )
745 {
746     Any                     aPreVal, aPostVal;
747     {
748         ::osl::MutexGuard   aGuard( m_aMutex );
749 
750         aPreVal <<= msDescription;
751         aPostVal <<= rDescr;
752 
753         msDescription = rDescr;
754     }
755 
756     const Reference< XInterface >   xSource( *this );
757     CommitChange( AccessibleEventObject( xSource, AccessibleEventId::DESCRIPTION_CHANGED, aPreVal, aPostVal ) );
758 }
759 
CommitChange(const AccessibleEventObject & rEvent)760 void SvxRectCtlAccessibleContext::CommitChange( const AccessibleEventObject& rEvent )
761 {
762     if (mnClientId)
763         comphelper::AccessibleEventNotifier::addEvent( mnClientId, rEvent );
764 }
765 
disposing()766 void SAL_CALL SvxRectCtlAccessibleContext::disposing()
767 {
768     if( !rBHelper.bDisposed )
769     {
770         {
771             ::osl::MutexGuard   aGuard( m_aMutex );
772             mpRepr = NULL;      // object dies with representation
773 
774             SvxRectCtlChildAccessibleContext**  p = mpChilds;
775             for( int i = MAX_NUM_OF_CHILDS ; i ; --i, ++p )
776             {
777                 SvxRectCtlChildAccessibleContext*   pChild = *p;
778                 if( pChild )
779                 {
780                     pChild->dispose();
781                     pChild->release();
782                     *p = NULL;
783                 }
784             }
785 
786             delete[] mpChilds;
787             mpChilds = NULL;
788         }
789 
790         {
791             ::osl::MutexGuard   aGuard( m_aMutex );
792 
793             // Send a disposing to all listeners.
794             if ( mnClientId )
795             {
796                 comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( mnClientId, *this );
797                 mnClientId =  0;
798             }
799 
800             mxParent = Reference< XAccessible >();
801         }
802     }
803 }
804 
GetBoundingBoxOnScreen(void)805 Rectangle SvxRectCtlAccessibleContext::GetBoundingBoxOnScreen( void )
806 {
807     ::vos::OGuard       aSolarGuard( Application::GetSolarMutex() );
808     ::osl::MutexGuard   aGuard( m_aMutex );
809 
810     ThrowExceptionIfNotAlive();
811 
812     return Rectangle( mpRepr->GetParent()->OutputToScreenPixel( mpRepr->GetPosPixel() ), mpRepr->GetSizePixel() );
813 }
814 
GetBoundingBox(void)815 Rectangle SvxRectCtlAccessibleContext::GetBoundingBox( void )
816 {
817     ::vos::OGuard       aSolarGuard( Application::GetSolarMutex() );
818     ::osl::MutexGuard   aGuard( m_aMutex );
819 
820     ThrowExceptionIfNotAlive();
821 
822     return Rectangle( mpRepr->GetPosPixel(), mpRepr->GetSizePixel() );
823 }
824 
getUniqueId(void)825 Sequence< sal_Int8 > SvxRectCtlAccessibleContext::getUniqueId( void )
826 {
827     static OImplementationId*   pId = 0;
828     if( !pId )
829     {
830         MutexGuard                      aGuard( Mutex::getGlobalMutex() );
831         if( !pId)
832         {
833             static OImplementationId    aId;
834             pId = &aId;
835         }
836     }
837     return pId->getImplementationId();
838 }
839 
ThrowExceptionIfNotAlive(void)840 void SvxRectCtlAccessibleContext::ThrowExceptionIfNotAlive( void )
841 {
842     if( IsNotAlive() )
843         throw lang::DisposedException();
844 }
845 
846 // -------------------------------------------------------------------------------------------------
847 
848 
DBG_NAME(SvxRectCtlChildAccessibleContext)849 DBG_NAME( SvxRectCtlChildAccessibleContext )
850 
851 
852 SvxRectCtlChildAccessibleContext::SvxRectCtlChildAccessibleContext(
853     const Reference<XAccessible>&   rxParent,
854     const Window&                       rParentWindow,
855     const ::rtl::OUString&              rName,
856     const ::rtl::OUString&              rDescription,
857     const Rectangle&                    rBoundingBox,
858     long                                nIndexInParent ) :
859 
860     SvxRectCtlChildAccessibleContext_Base( maMutex ),
861     msDescription( rDescription ),
862     msName( rName ),
863     mxParent(rxParent),
864     mpBoundingBox( new Rectangle( rBoundingBox ) ),
865     mrParentWindow( rParentWindow ),
866     mnClientId( 0 ),
867     mnIndexInParent( nIndexInParent ),
868     mbIsChecked( sal_False )
869 {
870     DBG_CTOR( SvxRectCtlChildAccessibleContext, NULL );
871 }
872 
873 
~SvxRectCtlChildAccessibleContext()874 SvxRectCtlChildAccessibleContext::~SvxRectCtlChildAccessibleContext()
875 {
876     DBG_DTOR( SvxRectCtlChildAccessibleContext, NULL );
877 
878     if( IsAlive() )
879     {
880         osl_incrementInterlockedCount( &m_refCount );
881         dispose();      // set mpRepr = NULL & release all childs
882     }
883 }
884 
885 //=====  XAccessible  =========================================================
886 
getAccessibleContext(void)887 Reference< XAccessibleContext> SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleContext( void )
888 {
889     return this;
890 }
891 
892 //=====  XAccessibleComponent  ================================================
893 
containsPoint(const awt::Point & rPoint)894 sal_Bool SAL_CALL SvxRectCtlChildAccessibleContext::containsPoint( const awt::Point& rPoint )
895 {
896     // no guard -> done in getBounds()
897 //  return GetBoundingBox().IsInside( VCLPoint( rPoint ) );
898     return Rectangle( Point( 0, 0 ), GetBoundingBox().GetSize() ).IsInside( VCLPoint( rPoint ) );
899 }
900 
getAccessibleAtPoint(const awt::Point &)901 Reference< XAccessible > SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleAtPoint( const awt::Point& /*rPoint*/ )
902 {
903     return Reference< XAccessible >();
904 }
905 
getBounds()906 awt::Rectangle SAL_CALL SvxRectCtlChildAccessibleContext::getBounds()
907 {
908     // no guard -> done in getBoundingBox()
909     return AWTRectangle( GetBoundingBox() );
910 }
911 
getLocation()912 awt::Point SAL_CALL SvxRectCtlChildAccessibleContext::getLocation()
913 {
914     // no guard -> done in getBoundingBox()
915     return AWTPoint( GetBoundingBox().TopLeft() );
916 }
917 
getLocationOnScreen()918 awt::Point SAL_CALL SvxRectCtlChildAccessibleContext::getLocationOnScreen()
919 {
920     // no guard -> done in getBoundingBoxOnScreen()
921     return AWTPoint( GetBoundingBoxOnScreen().TopLeft() );
922 }
923 
getSize()924 awt::Size SAL_CALL SvxRectCtlChildAccessibleContext::getSize()
925 {
926     // no guard -> done in getBoundingBox()
927     return AWTSize( GetBoundingBox().GetSize() );
928 }
929 
isShowing()930 sal_Bool SAL_CALL SvxRectCtlChildAccessibleContext::isShowing()
931 {
932     return sal_True;
933 }
934 
isVisible()935 sal_Bool SAL_CALL SvxRectCtlChildAccessibleContext::isVisible()
936 {
937     ::osl::MutexGuard                   aGuard( maMutex );
938 
939     ThrowExceptionIfNotAlive();
940 
941     return mxParent.is()? ( static_cast< SvxRectCtlAccessibleContext* >( mxParent.get() ) )->isVisible() : sal_False;
942 }
943 
isFocusTraversable()944 sal_Bool SAL_CALL SvxRectCtlChildAccessibleContext::isFocusTraversable()
945 {
946     return sal_False;
947 }
948 
addFocusListener(const Reference<awt::XFocusListener> &)949 void SAL_CALL SvxRectCtlChildAccessibleContext::addFocusListener( const Reference< awt::XFocusListener >& /*xListener*/ )
950 {
951     OSL_ENSURE( false, "SvxRectCtlChildAccessibleContext::addFocusListener: not implemented" );
952 }
953 
removeFocusListener(const Reference<awt::XFocusListener> &)954 void SAL_CALL SvxRectCtlChildAccessibleContext::removeFocusListener( const Reference< awt::XFocusListener >& /*xListener*/ )
955 {
956     OSL_ENSURE( false, "SvxRectCtlChildAccessibleContext::removeFocusListener: not implemented" );
957 }
958 
grabFocus()959 void SAL_CALL SvxRectCtlChildAccessibleContext::grabFocus()
960 {
961 }
962 
getAccessibleKeyBinding()963 Any SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleKeyBinding()
964 {
965     // here is no implementation, because here are no KeyBindings for every object
966     return Any();
967 }
getForeground()968 sal_Int32 SvxRectCtlChildAccessibleContext::getForeground(  )
969 {
970     ::vos::OGuard       aSolarGuard( Application::GetSolarMutex() );
971     ::osl::MutexGuard   aGuard( maMutex );
972     ThrowExceptionIfNotAlive();
973     return mrParentWindow.GetControlForeground().GetColor();
974 }
getBackground()975 sal_Int32 SvxRectCtlChildAccessibleContext::getBackground(  )
976 {
977     ::vos::OGuard       aSolarGuard( Application::GetSolarMutex() );
978     ::osl::MutexGuard   aGuard( maMutex );
979 
980     ThrowExceptionIfNotAlive();
981     return mrParentWindow.GetControlBackground().GetColor();
982 }
983 
984 //=====  XAccessibleContext  ==================================================
985 
getAccessibleChildCount(void)986 sal_Int32 SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleChildCount( void )
987 {
988     return 0;
989 }
990 
getAccessibleChild(sal_Int32)991 Reference< XAccessible > SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleChild( sal_Int32 /*nIndex*/ )
992 {
993     throw lang::IndexOutOfBoundsException();
994 }
995 
getAccessibleParent(void)996 Reference< XAccessible > SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleParent( void )
997 {
998     return mxParent;
999 }
1000 
getAccessibleIndexInParent(void)1001 sal_Int32 SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleIndexInParent( void )
1002 {
1003    return mnIndexInParent;
1004 }
1005 
getAccessibleRole(void)1006 sal_Int16 SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleRole( void )
1007 {
1008     return AccessibleRole::RADIO_BUTTON;
1009 }
1010 
getAccessibleDescription(void)1011 ::rtl::OUString SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleDescription( void )
1012 {
1013     ::osl::MutexGuard   aGuard( maMutex );
1014     return msDescription;
1015 }
1016 
getAccessibleName(void)1017 ::rtl::OUString SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleName( void )
1018 {
1019     ::osl::MutexGuard   aGuard( maMutex );
1020     return msName;
1021 }
1022 
1023 /** Return empty reference to indicate that the relation set is not
1024     supported.
1025 */
getAccessibleRelationSet(void)1026 Reference<XAccessibleRelationSet> SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleRelationSet( void )
1027 {
1028     //return Reference< XAccessibleRelationSet >();
1029     utl::AccessibleRelationSetHelper* pRelationSetHelper = new utl::AccessibleRelationSetHelper;
1030     uno::Reference< accessibility::XAccessibleRelationSet > xSet = pRelationSetHelper;
1031     if( mxParent.is() )
1032       {
1033         uno::Sequence< uno::Reference< uno::XInterface > > aSequence(1);
1034         aSequence[0] = mxParent;
1035         pRelationSetHelper->AddRelation( accessibility::AccessibleRelation( accessibility::AccessibleRelationType::MEMBER_OF, aSequence ) );
1036 
1037     }
1038 
1039     return xSet;
1040 }
1041 
getAccessibleStateSet(void)1042 Reference< XAccessibleStateSet > SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleStateSet( void )
1043 {
1044     ::osl::MutexGuard                       aGuard( maMutex );
1045     utl::AccessibleStateSetHelper*          pStateSetHelper = new utl::AccessibleStateSetHelper;
1046 
1047     if( IsAlive() )
1048     {
1049         if( mbIsChecked )
1050         {
1051             pStateSetHelper->AddState( AccessibleStateType::CHECKED );
1052 //          pStateSetHelper->AddState( AccessibleStateType::SELECTED );
1053         }
1054 
1055         pStateSetHelper->AddState( AccessibleStateType::ENABLED );
1056         pStateSetHelper->AddState( AccessibleStateType::SENSITIVE );
1057         pStateSetHelper->AddState( AccessibleStateType::OPAQUE );
1058         pStateSetHelper->AddState( AccessibleStateType::SELECTABLE );
1059         pStateSetHelper->AddState( AccessibleStateType::SHOWING );
1060         pStateSetHelper->AddState( AccessibleStateType::VISIBLE );
1061     }
1062     else
1063         pStateSetHelper->AddState( AccessibleStateType::DEFUNC );
1064 
1065     return pStateSetHelper;
1066 }
1067 
getLocale(void)1068 lang::Locale SAL_CALL SvxRectCtlChildAccessibleContext::getLocale( void )
1069 {
1070     ::osl::MutexGuard                       aGuard( maMutex );
1071     if( mxParent.is() )
1072     {
1073         Reference< XAccessibleContext >     xParentContext( mxParent->getAccessibleContext() );
1074         if( xParentContext.is() )
1075             return xParentContext->getLocale();
1076     }
1077 
1078     //  No locale and no parent.  Therefore throw exception to indicate this
1079     //  cluelessness.
1080     throw IllegalAccessibleComponentStateException();
1081 }
1082 
addEventListener(const Reference<XAccessibleEventListener> & xListener)1083 void SAL_CALL SvxRectCtlChildAccessibleContext::addEventListener( const Reference< XAccessibleEventListener >& xListener )
1084 {
1085     if (xListener.is())
1086     {
1087         ::osl::MutexGuard   aGuard( maMutex );
1088         if (!mnClientId)
1089             mnClientId = comphelper::AccessibleEventNotifier::registerClient( );
1090         comphelper::AccessibleEventNotifier::addEventListener( mnClientId, xListener );
1091     }
1092 }
1093 
1094 
1095 
1096 
removeEventListener(const Reference<XAccessibleEventListener> & xListener)1097 void SAL_CALL SvxRectCtlChildAccessibleContext::removeEventListener( const Reference< XAccessibleEventListener >& xListener )
1098 {
1099     if (xListener.is())
1100     {
1101         ::osl::MutexGuard   aGuard( maMutex );
1102 
1103         sal_Int32 nListenerCount = comphelper::AccessibleEventNotifier::removeEventListener( mnClientId, xListener );
1104         if ( !nListenerCount )
1105         {
1106             // no listeners anymore
1107             // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client),
1108             // and at least to us not firing any events anymore, in case somebody calls
1109             // NotifyAccessibleEvent, again
1110             comphelper::AccessibleEventNotifier::revokeClient( mnClientId );
1111             mnClientId = 0;
1112         }
1113     }
1114 }
1115 
1116 //=====  XAccessibleValue  ================================================
1117 
getCurrentValue()1118 Any SAL_CALL SvxRectCtlChildAccessibleContext::getCurrentValue()
1119 {
1120     ThrowExceptionIfNotAlive();
1121 
1122     Any aRet;
1123     aRet <<= ( mbIsChecked? 1.0 : 0.0 );
1124     return aRet;
1125 }
1126 
setCurrentValue(const Any &)1127 sal_Bool SAL_CALL SvxRectCtlChildAccessibleContext::setCurrentValue( const Any& /*aNumber*/ )
1128 {
1129     return sal_False;
1130 }
1131 
getMaximumValue()1132 Any SAL_CALL SvxRectCtlChildAccessibleContext::getMaximumValue()
1133 {
1134     Any aRet;
1135     aRet <<= 1.0;
1136     return aRet;
1137 }
1138 
getMinimumValue()1139 Any SAL_CALL SvxRectCtlChildAccessibleContext::getMinimumValue()
1140 {
1141     Any aRet;
1142     aRet <<= 0.0;
1143     return aRet;
1144 }
1145 
1146 // -----------------------------------------------------------------------------
1147 // XAccessibleAction
1148 // -----------------------------------------------------------------------------
1149 
getAccessibleActionCount()1150 sal_Int32 SvxRectCtlChildAccessibleContext::getAccessibleActionCount( )
1151 {
1152     ::osl::MutexGuard   aGuard( maMutex );
1153 
1154     return 1;
1155 }
1156 
1157 // -----------------------------------------------------------------------------
1158 
doAccessibleAction(sal_Int32 nIndex)1159 sal_Bool SvxRectCtlChildAccessibleContext::doAccessibleAction ( sal_Int32 nIndex )
1160 {
1161     ::osl::MutexGuard   aGuard( maMutex );
1162 
1163     if ( nIndex < 0 || nIndex >= getAccessibleActionCount() )
1164         throw IndexOutOfBoundsException();
1165 
1166     Reference<XAccessibleSelection> xSelection( mxParent, UNO_QUERY);
1167 
1168     xSelection->selectAccessibleChild(mnIndexInParent);
1169 
1170     return sal_True;
1171 }
1172 
1173 // -----------------------------------------------------------------------------
1174 
getAccessibleActionDescription(sal_Int32 nIndex)1175 ::rtl::OUString SvxRectCtlChildAccessibleContext::getAccessibleActionDescription ( sal_Int32 nIndex )
1176 {
1177     ::osl::MutexGuard   aGuard( maMutex );
1178 
1179     if ( nIndex < 0 || nIndex >= getAccessibleActionCount() )
1180         throw IndexOutOfBoundsException();
1181     return ::rtl::OUString::createFromAscii("select");
1182 }
1183 
1184 // -----------------------------------------------------------------------------
1185 
getAccessibleActionKeyBinding(sal_Int32 nIndex)1186 Reference< XAccessibleKeyBinding > SvxRectCtlChildAccessibleContext::getAccessibleActionKeyBinding( sal_Int32 nIndex )
1187 {
1188     ::osl::MutexGuard   aGuard( maMutex );
1189 
1190     if ( nIndex < 0 || nIndex >= getAccessibleActionCount() )
1191         throw IndexOutOfBoundsException();
1192 
1193     return Reference< XAccessibleKeyBinding >();
1194 }
1195 
1196 
1197 //=====  XServiceInfo  ========================================================
1198 
getImplementationName(void)1199 ::rtl::OUString SAL_CALL SvxRectCtlChildAccessibleContext::getImplementationName( void )
1200 {
1201     return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.ui.SvxRectCtlChildAccessibleContext" ) );
1202 }
1203 
supportsService(const::rtl::OUString & sServiceName)1204 sal_Bool SAL_CALL SvxRectCtlChildAccessibleContext::supportsService( const ::rtl::OUString& sServiceName )
1205 {
1206     //  Iterate over all supported service names and return true if on of them
1207     //  matches the given name.
1208     ::osl::MutexGuard   aGuard( maMutex );
1209     Sequence< ::rtl::OUString > aSupportedServices ( getSupportedServiceNames() );
1210     int                     nLength = aSupportedServices.getLength();
1211     for( int i = 0 ; i < nLength; ++i )
1212     {
1213         if( sServiceName == aSupportedServices[ i ] )
1214             return sal_True;
1215     }
1216 
1217     return sal_False;
1218 }
1219 
getSupportedServiceNames(void)1220 Sequence< ::rtl::OUString > SAL_CALL SvxRectCtlChildAccessibleContext::getSupportedServiceNames( void )
1221 {
1222     const ::rtl::OUString sServiceName (RTL_CONSTASCII_USTRINGPARAM ("com.sun.star.accessibility.AccessibleContext"));
1223     return Sequence< ::rtl::OUString >( &sServiceName, 1 );
1224 }
1225 
1226 //=====  XTypeProvider  =======================================================
1227 
getImplementationId(void)1228 Sequence< sal_Int8 > SAL_CALL SvxRectCtlChildAccessibleContext::getImplementationId( void )
1229 {
1230     static OImplementationId*   pId = 0;
1231     if( !pId )
1232     {
1233         MutexGuard                      aGuard( Mutex::getGlobalMutex() );
1234         if( !pId)
1235         {
1236             static OImplementationId    aId;
1237             pId = &aId;
1238         }
1239     }
1240     return pId->getImplementationId();
1241 }
1242 
1243 //=====  internal  ============================================================
1244 
CommitChange(const AccessibleEventObject & rEvent)1245 void SvxRectCtlChildAccessibleContext::CommitChange( const AccessibleEventObject& rEvent )
1246 {
1247     if (mnClientId)
1248         comphelper::AccessibleEventNotifier::addEvent( mnClientId, rEvent );
1249 }
1250 
disposing()1251 void SAL_CALL SvxRectCtlChildAccessibleContext::disposing()
1252 {
1253     if( !rBHelper.bDisposed )
1254     {
1255         ::osl::MutexGuard   aGuard( maMutex );
1256 
1257         // Send a disposing to all listeners.
1258         if ( mnClientId )
1259         {
1260             comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( mnClientId, *this );
1261             mnClientId =  0;
1262         }
1263 
1264         mxParent = Reference< XAccessible >();
1265 
1266         delete mpBoundingBox;
1267     }
1268 }
1269 
ThrowExceptionIfNotAlive(void)1270 void SvxRectCtlChildAccessibleContext::ThrowExceptionIfNotAlive( void )
1271 {
1272     if( IsNotAlive() )
1273         throw lang::DisposedException();
1274 }
1275 
GetBoundingBoxOnScreen(void)1276 Rectangle SvxRectCtlChildAccessibleContext::GetBoundingBoxOnScreen( void )
1277 {
1278     ::osl::MutexGuard   aGuard( maMutex );
1279 
1280     // no ThrowExceptionIfNotAlive() because its done in GetBoundingBox()
1281     Rectangle           aRect( GetBoundingBox() );
1282 
1283     return Rectangle( mrParentWindow.OutputToScreenPixel( aRect.TopLeft() ), aRect.GetSize() );
1284 }
1285 
GetBoundingBox(void)1286 Rectangle SvxRectCtlChildAccessibleContext::GetBoundingBox( void )
1287 {
1288     // no guard necessary, because no one changes mpBoundingBox after creating it
1289     ThrowExceptionIfNotAlive();
1290 
1291     return *mpBoundingBox;
1292 }
setStateChecked(sal_Bool bChecked,sal_Bool bFireFocus)1293 void SvxRectCtlChildAccessibleContext::setStateChecked( sal_Bool bChecked, sal_Bool bFireFocus )
1294 {
1295     if( mbIsChecked != bChecked )
1296     {
1297         mbIsChecked = bChecked;
1298 
1299         const Reference< XInterface >   xSource( *this );
1300 
1301         Any                             aOld;
1302         Any                             aNew;
1303         Any&                            rMod = bChecked? aNew : aOld;
1304         if( bFireFocus )
1305         {
1306             //Solution: Send the STATE_CHANGED(Focused) event to accessible
1307             rMod <<= AccessibleStateType::FOCUSED;
1308             CommitChange( AccessibleEventObject( xSource, AccessibleEventId::STATE_CHANGED, aNew, aOld ) );
1309         }
1310         rMod <<= AccessibleStateType::CHECKED;
1311 
1312         CommitChange( AccessibleEventObject( xSource, AccessibleEventId::STATE_CHANGED, aNew, aOld ) );
1313     }
1314 }
1315 
FireFocusEvent()1316 void SvxRectCtlChildAccessibleContext::FireFocusEvent()
1317 {
1318     const Reference< XInterface >   xSource( *this );
1319     Any                             aOld;
1320     Any                             aNew;
1321     aNew <<= AccessibleStateType::FOCUSED;
1322     CommitChange( AccessibleEventObject( xSource, AccessibleEventId::STATE_CHANGED, aNew, aOld ) );
1323 }
1324