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