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