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