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