update dev300-m58
[ooovba.git] / svx / source / accessibility / svxrectctaccessiblecontext.cxx
blob75e4ef1d598d55859ccbdd09eb270c2a8dd94b66
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: svxrectctaccessiblecontext.cxx,v $
10 * $Revision: 1.24 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svx.hxx"
35 #include "svxrectctaccessiblecontext.hxx"
36 #include <com/sun/star/accessibility/AccessibleRole.hpp>
37 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
38 #include <unotools/accessiblestatesethelper.hxx>
39 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
40 #include <com/sun/star/beans/PropertyChangeEvent.hpp>
41 #include <com/sun/star/awt/XWindow.hpp>
42 #include <cppuhelper/typeprovider.hxx>
43 #include <toolkit/helper/vclunohelper.hxx>
44 #include <toolkit/helper/convert.hxx>
45 #include <vcl/svapp.hxx>
46 #include <osl/mutex.hxx>
47 #include <rtl/uuid.h>
48 #include <tools/debug.hxx>
49 #include <tools/gen.hxx>
51 #include <svx/dialogs.hrc>
52 #include "accessibility.hrc"
53 #include <svx/dlgctrl.hxx>
54 #include <svx/dialmgr.hxx>
55 #include <comphelper/accessibleeventnotifier.hxx>
58 using namespace ::cppu;
59 using namespace ::osl;
60 using namespace ::com::sun::star;
61 using namespace ::com::sun::star::uno;
62 using namespace ::com::sun::star::accessibility;
65 #define MAX_NUM_OF_CHILDS 9
66 #define NOCHILDSELECTED -1
69 DBG_NAME( SvxRectCtlAccessibleContext )
72 //===== internal ============================================================
74 namespace
76 struct ChildIndexToPointData
78 short nResIdName;
79 short nResIdDescr;
80 RECT_POINT ePoint;
85 static const ChildIndexToPointData* IndexToPoint( long nIndex, sal_Bool bAngleControl )
87 DBG_ASSERT( nIndex < ( bAngleControl? 8 : 9 ) && nIndex >= 0, "-IndexToPoint(): invalid child index! You have been warned..." );
89 // angles are counted reverse counter clock wise
90 static const ChildIndexToPointData pAngleData[] =
91 { // index
92 { RID_SVXSTR_RECTCTL_ACC_CHLD_A000, RID_SVXSTR_RECTCTL_ACC_CHLD_A000, RP_RM }, // 0
93 { RID_SVXSTR_RECTCTL_ACC_CHLD_A045, RID_SVXSTR_RECTCTL_ACC_CHLD_A045, RP_RT }, // 1
94 { RID_SVXSTR_RECTCTL_ACC_CHLD_A090, RID_SVXSTR_RECTCTL_ACC_CHLD_A090, RP_MT }, // 2
95 { RID_SVXSTR_RECTCTL_ACC_CHLD_A135, RID_SVXSTR_RECTCTL_ACC_CHLD_A135, RP_LT }, // 3
96 { RID_SVXSTR_RECTCTL_ACC_CHLD_A180, RID_SVXSTR_RECTCTL_ACC_CHLD_A180, RP_LM }, // 4
97 { RID_SVXSTR_RECTCTL_ACC_CHLD_A225, RID_SVXSTR_RECTCTL_ACC_CHLD_A225, RP_LB }, // 5
98 { RID_SVXSTR_RECTCTL_ACC_CHLD_A270, RID_SVXSTR_RECTCTL_ACC_CHLD_A270, RP_MB }, // 6
99 { RID_SVXSTR_RECTCTL_ACC_CHLD_A315, RID_SVXSTR_RECTCTL_ACC_CHLD_A315, RP_RB } // 7
102 // corners are counted from left to right and top to bottom
103 static const ChildIndexToPointData pCornerData[] =
104 { // index
105 { RID_SVXSTR_RECTCTL_ACC_CHLD_LT, RID_SVXSTR_RECTCTL_ACC_CHLD_LT, RP_LT }, // 0
106 { RID_SVXSTR_RECTCTL_ACC_CHLD_MT, RID_SVXSTR_RECTCTL_ACC_CHLD_MT, RP_MT }, // 1
107 { RID_SVXSTR_RECTCTL_ACC_CHLD_RT, RID_SVXSTR_RECTCTL_ACC_CHLD_RT, RP_RT }, // 2
108 { RID_SVXSTR_RECTCTL_ACC_CHLD_LM, RID_SVXSTR_RECTCTL_ACC_CHLD_LM, RP_LM }, // 3
109 { RID_SVXSTR_RECTCTL_ACC_CHLD_MM, RID_SVXSTR_RECTCTL_ACC_CHLD_MM, RP_MM }, // 4
110 { RID_SVXSTR_RECTCTL_ACC_CHLD_RM, RID_SVXSTR_RECTCTL_ACC_CHLD_RM, RP_RM }, // 5
111 { RID_SVXSTR_RECTCTL_ACC_CHLD_LB, RID_SVXSTR_RECTCTL_ACC_CHLD_LB, RP_LB }, // 6
112 { RID_SVXSTR_RECTCTL_ACC_CHLD_MB, RID_SVXSTR_RECTCTL_ACC_CHLD_MB, RP_MB }, // 7
113 { RID_SVXSTR_RECTCTL_ACC_CHLD_RB, RID_SVXSTR_RECTCTL_ACC_CHLD_RB, RP_RB } // 8
116 return ( bAngleControl? pAngleData : pCornerData ) + nIndex;
120 static long PointToIndex( RECT_POINT ePoint, sal_Bool bAngleControl )
122 long nRet( (long) ePoint );
123 if( bAngleControl )
124 { // angle control
125 // angles are counted reverse counter clock wise
126 switch( ePoint )
128 case RP_LT: nRet = 3; break;
129 case RP_MT: nRet = 2; break;
130 case RP_RT: nRet = 1; break;
131 case RP_LM: nRet = 4; break;
132 case RP_MM: nRet = NOCHILDSELECTED; break;
133 case RP_RM: nRet = 0; break;
134 case RP_LB: nRet = 5; break;
135 case RP_MB: nRet = 6; break;
136 case RP_RB: nRet = 7; break;
139 else
140 { // corner control
141 // corners are counted from left to right and top to bottom
142 DBG_ASSERT( RP_LT == 0 && RP_MT == 1 && RP_RT == 2 && RP_LM == 3 && RP_MM == 4 && RP_RM == 5 &&
143 RP_LB == 6 && RP_MB == 7 && RP_RB == 8, "*PointToIndex(): unexpected enum value!" );
145 nRet = ( long ) ePoint;
148 return nRet;
152 SvxRectCtlAccessibleContext::SvxRectCtlAccessibleContext(
153 const Reference< XAccessible >& rxParent,
154 SvxRectCtl& rRepr,
155 const ::rtl::OUString* pName,
156 const ::rtl::OUString* pDesc ) :
158 SvxRectCtlAccessibleContext_Base( m_aMutex ),
159 mxParent( rxParent ),
160 mpRepr( &rRepr ),
161 mpChilds( NULL ),
162 mnClientId( 0 ),
163 mnSelectedChild( NOCHILDSELECTED ),
164 mbAngleMode( rRepr.GetNumOfChilds() == 8 )
166 DBG_CTOR( SvxRectCtlAccessibleContext, NULL );
168 if( pName )
169 msName = *pName;
170 else
172 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
173 msName = SVX_RESSTR( mbAngleMode? RID_SVXSTR_RECTCTL_ACC_ANGL_NAME : RID_SVXSTR_RECTCTL_ACC_CORN_NAME );
176 if( pDesc )
177 msDescription = *pDesc;
178 else
180 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
181 msDescription = SVX_RESSTR( mbAngleMode? RID_SVXSTR_RECTCTL_ACC_ANGL_DESCR : RID_SVXSTR_RECTCTL_ACC_CORN_DESCR );
184 mpChilds = new SvxRectCtlChildAccessibleContext*[ MAX_NUM_OF_CHILDS ];
186 SvxRectCtlChildAccessibleContext** p = mpChilds;
187 for( int i = MAX_NUM_OF_CHILDS ; i ; --i, ++p )
188 *p = NULL;
192 SvxRectCtlAccessibleContext::~SvxRectCtlAccessibleContext()
194 DBG_DTOR( SvxRectCtlAccessibleContext, NULL );
196 if( IsAlive() )
198 osl_incrementInterlockedCount( &m_refCount );
199 dispose(); // set mpRepr = NULL & release all childs
203 //===== XAccessible =========================================================
205 Reference< XAccessibleContext > SAL_CALL SvxRectCtlAccessibleContext::getAccessibleContext( void ) throw( RuntimeException )
207 return this;
210 //===== XAccessibleComponent ================================================
212 sal_Bool SAL_CALL SvxRectCtlAccessibleContext::containsPoint( const awt::Point& rPoint ) throw( RuntimeException )
214 // no guard -> done in getBounds()
215 // return GetBoundingBox().IsInside( VCLPoint( rPoint ) );
216 return Rectangle( Point( 0, 0 ), GetBoundingBox().GetSize() ).IsInside( VCLPoint( rPoint ) );
219 Reference< XAccessible > SAL_CALL SvxRectCtlAccessibleContext::getAccessibleAtPoint( const awt::Point& rPoint ) throw( RuntimeException )
221 ::osl::MutexGuard aGuard( m_aMutex );
223 ThrowExceptionIfNotAlive();
225 Reference< XAccessible > xRet;
227 long nChild = PointToIndex( mpRepr->GetApproxRPFromPixPt( rPoint ), mbAngleMode );
229 if( nChild != NOCHILDSELECTED )
230 xRet = getAccessibleChild( nChild );
232 return xRet;
235 awt::Rectangle SAL_CALL SvxRectCtlAccessibleContext::getBounds() throw( RuntimeException )
237 // no guard -> done in GetBoundingBox()
238 return AWTRectangle( GetBoundingBox() );
241 awt::Point SAL_CALL SvxRectCtlAccessibleContext::getLocation() throw( RuntimeException )
243 // no guard -> done in GetBoundingBox()
244 return AWTPoint( GetBoundingBox().TopLeft() );
247 awt::Point SAL_CALL SvxRectCtlAccessibleContext::getLocationOnScreen() throw( RuntimeException )
249 // no guard -> done in GetBoundingBoxOnScreen()
250 return AWTPoint( GetBoundingBoxOnScreen().TopLeft() );
253 awt::Size SAL_CALL SvxRectCtlAccessibleContext::getSize() throw( RuntimeException )
255 // no guard -> done in GetBoundingBox()
256 return AWTSize( GetBoundingBox().GetSize() );
259 sal_Bool SAL_CALL SvxRectCtlAccessibleContext::isShowing() throw( RuntimeException )
261 return sal_True;
264 sal_Bool SAL_CALL SvxRectCtlAccessibleContext::isVisible() throw( RuntimeException )
266 ::osl::MutexGuard aGuard( m_aMutex );
268 ThrowExceptionIfNotAlive();
270 return mpRepr->IsVisible();
273 sal_Bool SAL_CALL SvxRectCtlAccessibleContext::isFocusTraversable() throw( RuntimeException )
275 return sal_True;
278 //===== XAccessibleContext ==================================================
280 sal_Int32 SAL_CALL SvxRectCtlAccessibleContext::getAccessibleChildCount( void ) throw( RuntimeException )
282 ::osl::MutexGuard aGuard( m_aMutex );
284 ThrowExceptionIfNotAlive();
286 return mpRepr->GetNumOfChilds();
289 Reference< XAccessible > SAL_CALL SvxRectCtlAccessibleContext::getAccessibleChild( sal_Int32 nIndex )
290 throw( RuntimeException, lang::IndexOutOfBoundsException )
292 checkChildIndex( nIndex );
294 Reference< XAccessible > xChild = mpChilds[ nIndex ];
295 if( !xChild.is() )
297 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
299 ::osl::MutexGuard aGuard( m_aMutex );
301 ThrowExceptionIfNotAlive();
303 xChild = mpChilds[ nIndex ];
305 if( !xChild.is() )
307 const ChildIndexToPointData* p = IndexToPoint( nIndex, mbAngleMode );
308 UniString tmp = SVX_RESSTR( p->nResIdName );
309 ::rtl::OUString aName( tmp );
310 tmp = SVX_RESSTR( p->nResIdDescr );
311 ::rtl::OUString aDescr( tmp );
313 Rectangle aFocusRect( mpRepr->CalculateFocusRectangle( p->ePoint ) );
315 Rectangle aBoundingBoxOnScreen( mpRepr->OutputToScreenPixel( aFocusRect.TopLeft() ), aFocusRect.GetSize() );
317 SvxRectCtlChildAccessibleContext* pChild = new SvxRectCtlChildAccessibleContext(
318 this, *mpRepr, aName, aDescr, aFocusRect, nIndex );
319 xChild = mpChilds[ nIndex ] = pChild;
320 pChild->acquire();
322 // set actual state
323 if( mnSelectedChild == nIndex )
324 pChild->setStateChecked( sal_True );
328 return xChild;
331 Reference< XAccessible > SAL_CALL SvxRectCtlAccessibleContext::getAccessibleParent( void ) throw( RuntimeException )
333 return mxParent;
336 sal_Int32 SAL_CALL SvxRectCtlAccessibleContext::getAccessibleIndexInParent( void ) throw( RuntimeException )
338 ::osl::MutexGuard aGuard( m_aMutex );
339 // Use a simple but slow solution for now. Optimize later.
341 // Iterate over all the parent's children and search for this object.
342 if( mxParent.is() )
344 Reference< XAccessibleContext > xParentContext( mxParent->getAccessibleContext() );
345 if( xParentContext.is() )
347 sal_Int32 nChildCount = xParentContext->getAccessibleChildCount();
348 for( sal_Int32 i = 0 ; i < nChildCount ; ++i )
350 Reference< XAccessible > xChild( xParentContext->getAccessibleChild( i ) );
351 if( xChild.get() == ( XAccessible* ) this )
352 return i;
357 // Return -1 to indicate that this object's parent does not know about the
358 // object.
359 return -1;
362 sal_Int16 SAL_CALL SvxRectCtlAccessibleContext::getAccessibleRole( void ) throw( RuntimeException )
364 return AccessibleRole::PANEL;
367 ::rtl::OUString SAL_CALL SvxRectCtlAccessibleContext::getAccessibleDescription( void ) throw( RuntimeException )
369 ::osl::MutexGuard aGuard( m_aMutex );
370 return msDescription;
373 ::rtl::OUString SAL_CALL SvxRectCtlAccessibleContext::getAccessibleName( void ) throw( RuntimeException )
375 ::osl::MutexGuard aGuard( m_aMutex );
376 return msName;
379 /** Return empty reference to indicate that the relation set is not
380 supported.
382 Reference< XAccessibleRelationSet > SAL_CALL SvxRectCtlAccessibleContext::getAccessibleRelationSet( void ) throw( RuntimeException )
384 return Reference< XAccessibleRelationSet >();
387 Reference< XAccessibleStateSet > SAL_CALL SvxRectCtlAccessibleContext::getAccessibleStateSet( void ) throw( RuntimeException )
389 ::osl::MutexGuard aGuard( m_aMutex );
390 utl::AccessibleStateSetHelper* pStateSetHelper = new utl::AccessibleStateSetHelper;
392 if( IsAlive() )
394 // pStateSetHelper->AddState( AccessibleStateType::ENABLED );
395 // pStateSetHelper->AddState( AccessibleStateType::SENSITIVE );
396 pStateSetHelper->AddState( AccessibleStateType::FOCUSABLE );
397 if( mpRepr->HasFocus() )
398 pStateSetHelper->AddState( AccessibleStateType::FOCUSED );
399 pStateSetHelper->AddState( AccessibleStateType::OPAQUE );
401 if( isShowing() )
402 pStateSetHelper->AddState( AccessibleStateType::SHOWING );
404 if( isVisible() )
405 pStateSetHelper->AddState( AccessibleStateType::VISIBLE );
407 else
408 pStateSetHelper->AddState( AccessibleStateType::DEFUNC );
410 return pStateSetHelper;
413 lang::Locale SAL_CALL SvxRectCtlAccessibleContext::getLocale( void ) throw( IllegalAccessibleComponentStateException, RuntimeException )
415 ::osl::MutexGuard aGuard( m_aMutex );
416 if( mxParent.is() )
418 Reference< XAccessibleContext > xParentContext( mxParent->getAccessibleContext() );
419 if( xParentContext.is() )
420 return xParentContext->getLocale();
423 // No parent. Therefore throw exception to indicate this cluelessness.
424 throw IllegalAccessibleComponentStateException();
427 void SAL_CALL SvxRectCtlAccessibleContext::addEventListener( const Reference< XAccessibleEventListener >& xListener )
428 throw( RuntimeException )
430 if (xListener.is())
432 ::osl::MutexGuard aGuard( m_aMutex );
433 if (!mnClientId)
434 mnClientId = comphelper::AccessibleEventNotifier::registerClient( );
435 comphelper::AccessibleEventNotifier::addEventListener( mnClientId, xListener );
439 void SAL_CALL SvxRectCtlAccessibleContext::removeEventListener( const Reference< XAccessibleEventListener >& xListener )
440 throw( RuntimeException )
442 if (xListener.is())
444 ::osl::MutexGuard aGuard( m_aMutex );
446 sal_Int32 nListenerCount = comphelper::AccessibleEventNotifier::removeEventListener( mnClientId, xListener );
447 if ( !nListenerCount )
449 // no listeners anymore
450 // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client),
451 // and at least to us not firing any events anymore, in case somebody calls
452 // NotifyAccessibleEvent, again
453 comphelper::AccessibleEventNotifier::revokeClient( mnClientId );
454 mnClientId = 0;
459 void SAL_CALL SvxRectCtlAccessibleContext::addFocusListener( const Reference< awt::XFocusListener >& xListener )
460 throw( RuntimeException )
462 if( xListener.is() )
464 ::osl::MutexGuard aGuard( m_aMutex );
466 ThrowExceptionIfNotAlive();
468 Reference< awt::XWindow > xWindow = VCLUnoHelper::GetInterface( mpRepr );
469 if( xWindow.is() )
470 xWindow->addFocusListener( xListener );
474 void SAL_CALL SvxRectCtlAccessibleContext::removeFocusListener( const Reference< awt::XFocusListener >& xListener )
475 throw (RuntimeException)
477 if( xListener.is() )
479 ::osl::MutexGuard aGuard( m_aMutex );
481 ThrowExceptionIfNotAlive();
483 Reference< awt::XWindow > xWindow = VCLUnoHelper::GetInterface( mpRepr );
484 if( xWindow.is() )
485 xWindow->removeFocusListener( xListener );
489 void SAL_CALL SvxRectCtlAccessibleContext::grabFocus() throw( RuntimeException )
491 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
492 ::osl::MutexGuard aGuard( m_aMutex );
494 ThrowExceptionIfNotAlive();
496 mpRepr->GrabFocus();
499 Any SAL_CALL SvxRectCtlAccessibleContext::getAccessibleKeyBinding() throw( RuntimeException )
501 // here is no implementation, because here are no KeyBindings for every object
502 return Any();
505 sal_Int32 SvxRectCtlAccessibleContext::getForeground( )
506 throw (::com::sun::star::uno::RuntimeException)
508 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
509 ::osl::MutexGuard aGuard( m_aMutex );
510 ThrowExceptionIfNotAlive();
512 return mpRepr->GetControlForeground().GetColor();
514 sal_Int32 SvxRectCtlAccessibleContext::getBackground( )
515 throw (::com::sun::star::uno::RuntimeException)
517 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
518 ::osl::MutexGuard aGuard( m_aMutex );
519 ThrowExceptionIfNotAlive();
521 return mpRepr->GetControlBackground().GetColor();
524 //===== XServiceInfo ========================================================
526 ::rtl::OUString SAL_CALL SvxRectCtlAccessibleContext::getImplementationName( void ) throw( RuntimeException )
528 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.ui.SvxRectCtlAccessibleContext" ) );
531 sal_Bool SAL_CALL SvxRectCtlAccessibleContext::supportsService( const ::rtl::OUString& sServiceName ) throw( RuntimeException )
533 ::osl::MutexGuard aGuard( m_aMutex );
534 // Iterate over all supported service names and return true if on of them
535 // matches the given name.
536 Sequence< ::rtl::OUString > aSupportedServices( getSupportedServiceNames() );
537 int nLength = aSupportedServices.getLength();
538 const ::rtl::OUString* pStr = aSupportedServices.getConstArray();
540 for( int i = nLength ; i ; --i, ++pStr )
542 if( sServiceName == *pStr )
543 return sal_True;
546 return sal_False;
549 Sequence< ::rtl::OUString > SAL_CALL SvxRectCtlAccessibleContext::getSupportedServiceNames( void ) throw( RuntimeException )
551 const ::rtl::OUString sServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.accessibility.AccessibleContext" ) );
552 return Sequence< ::rtl::OUString >( &sServiceName, 1 );
555 //===== XTypeProvider =======================================================
557 Sequence< sal_Int8 > SAL_CALL SvxRectCtlAccessibleContext::getImplementationId( void ) throw( RuntimeException )
559 return getUniqueId();
562 //===== XAccessibleSelection =============================================
564 void SAL_CALL SvxRectCtlAccessibleContext::selectAccessibleChild( sal_Int32 nIndex ) throw( lang::IndexOutOfBoundsException, RuntimeException )
566 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
568 ::osl::MutexGuard aGuard( m_aMutex );
570 checkChildIndex( nIndex );
572 ThrowExceptionIfNotAlive();
574 const ChildIndexToPointData* pData = IndexToPoint( nIndex, mbAngleMode );
576 DBG_ASSERT( pData,
577 "SvxRectCtlAccessibleContext::selectAccessibleChild(): this is an impossible state! Or at least should be..." );
579 // this does all wich is needed, including the change of the child's state!
580 mpRepr->SetActualRP( pData->ePoint );
583 sal_Bool SAL_CALL SvxRectCtlAccessibleContext::isAccessibleChildSelected( sal_Int32 nIndex ) throw( lang::IndexOutOfBoundsException, RuntimeException )
585 ::osl::MutexGuard aGuard( m_aMutex );
587 checkChildIndex( nIndex );
589 return nIndex == mnSelectedChild;
592 void SAL_CALL SvxRectCtlAccessibleContext::clearAccessibleSelection() throw( RuntimeException )
594 DBG_ASSERT( sal_False, "SvxRectCtlAccessibleContext::clearAccessibleSelection() is not possible!" );
597 void SAL_CALL SvxRectCtlAccessibleContext::selectAllAccessibleChildren() throw( RuntimeException )
599 // guard in selectAccessibleChild()!
601 selectAccessibleChild( 0 ); // default per definition
604 sal_Int32 SAL_CALL SvxRectCtlAccessibleContext::getSelectedAccessibleChildCount() throw( RuntimeException )
606 ::osl::MutexGuard aGuard( m_aMutex );
608 return mnSelectedChild == NOCHILDSELECTED? 0 : 1;
611 Reference< XAccessible > SAL_CALL SvxRectCtlAccessibleContext::getSelectedAccessibleChild( sal_Int32 nIndex )
612 throw( lang::IndexOutOfBoundsException, RuntimeException )
614 ::osl::MutexGuard aGuard( m_aMutex );
616 checkChildIndexOnSelection( nIndex );
618 return getAccessibleChild( mnSelectedChild );
621 void SAL_CALL SvxRectCtlAccessibleContext::deselectAccessibleChild( sal_Int32 /*nIndex*/ ) throw( lang::IndexOutOfBoundsException, RuntimeException )
623 ::rtl::OUString aMessage( RTL_CONSTASCII_USTRINGPARAM( "deselectAccessibleChild is not possible in this context" ) );
625 DBG_ASSERT( sal_False, "SvxRectCtlAccessibleContext::deselectAccessibleChild() is not possible!" );
627 throw lang::IndexOutOfBoundsException( aMessage, *this ); // never possible
630 //===== internals ========================================================
632 void SvxRectCtlAccessibleContext::checkChildIndex( long nIndex ) throw( lang::IndexOutOfBoundsException )
634 if( nIndex < 0 || nIndex >= getAccessibleChildCount() )
635 throw lang::IndexOutOfBoundsException();
638 void SvxRectCtlAccessibleContext::checkChildIndexOnSelection( long nIndex ) throw( lang::IndexOutOfBoundsException )
640 if( nIndex || mnSelectedChild == NOCHILDSELECTED )
641 // in our case only for the first (0) _selected_ child this is a valid request
642 throw lang::IndexOutOfBoundsException();
645 void SvxRectCtlAccessibleContext::selectChild( long nNew )
647 ::osl::MutexGuard aGuard( m_aMutex );
648 if( nNew != mnSelectedChild )
650 long nNumOfChilds = getAccessibleChildCount();
651 if( nNew < nNumOfChilds )
652 { // valid index
653 SvxRectCtlChildAccessibleContext* pChild;
654 if( mnSelectedChild != NOCHILDSELECTED )
655 { // deselect old selected child if one is selected
656 pChild = mpChilds[ mnSelectedChild ];
657 if( pChild )
658 pChild->setStateChecked( sal_False );
661 // select new child
662 mnSelectedChild = nNew;
664 if( nNew != NOCHILDSELECTED )
666 pChild = mpChilds[ nNew ];
667 if( pChild )
668 pChild->setStateChecked( sal_True );
671 else
672 mnSelectedChild = NOCHILDSELECTED;
676 void SvxRectCtlAccessibleContext::selectChild( RECT_POINT eButton )
678 // no guard -> is done in next selectChild
679 selectChild( PointToIndex( eButton, mbAngleMode ) );
682 void SvxRectCtlAccessibleContext::setName( const ::rtl::OUString& rName )
684 Any aPreVal, aPostVal;
686 ::osl::MutexGuard aGuard( m_aMutex );
688 aPreVal <<= msName;
689 aPostVal <<= rName;
691 msName = rName;
694 const Reference< XInterface > xSource( *this );
695 CommitChange( AccessibleEventObject( xSource, AccessibleEventId::NAME_CHANGED, aPreVal, aPostVal ) );
698 void SvxRectCtlAccessibleContext::setDescription( const ::rtl::OUString& rDescr )
700 Any aPreVal, aPostVal;
702 ::osl::MutexGuard aGuard( m_aMutex );
704 aPreVal <<= msDescription;
705 aPostVal <<= rDescr;
707 msDescription = rDescr;
710 const Reference< XInterface > xSource( *this );
711 CommitChange( AccessibleEventObject( xSource, AccessibleEventId::DESCRIPTION_CHANGED, aPreVal, aPostVal ) );
714 void SvxRectCtlAccessibleContext::CommitChange( const AccessibleEventObject& rEvent )
716 if (mnClientId)
717 comphelper::AccessibleEventNotifier::addEvent( mnClientId, rEvent );
720 void SAL_CALL SvxRectCtlAccessibleContext::disposing()
722 if( !rBHelper.bDisposed )
725 ::osl::MutexGuard aGuard( m_aMutex );
726 mpRepr = NULL; // object dies with representation
728 SvxRectCtlChildAccessibleContext** p = mpChilds;
729 for( int i = MAX_NUM_OF_CHILDS ; i ; --i, ++p )
731 SvxRectCtlChildAccessibleContext* pChild = *p;
732 if( pChild )
734 pChild->dispose();
735 pChild->release();
736 *p = NULL;
740 delete[] mpChilds;
741 mpChilds = NULL;
745 ::osl::MutexGuard aGuard( m_aMutex );
747 // Send a disposing to all listeners.
748 if ( mnClientId )
750 comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( mnClientId, *this );
751 mnClientId = 0;
754 mxParent = Reference< XAccessible >();
759 Rectangle SvxRectCtlAccessibleContext::GetBoundingBoxOnScreen( void ) throw( RuntimeException )
761 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
762 ::osl::MutexGuard aGuard( m_aMutex );
764 ThrowExceptionIfNotAlive();
766 return Rectangle( mpRepr->GetParent()->OutputToScreenPixel( mpRepr->GetPosPixel() ), mpRepr->GetSizePixel() );
769 Rectangle SvxRectCtlAccessibleContext::GetBoundingBox( void ) throw( RuntimeException )
771 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
772 ::osl::MutexGuard aGuard( m_aMutex );
774 ThrowExceptionIfNotAlive();
776 return Rectangle( mpRepr->GetPosPixel(), mpRepr->GetSizePixel() );
779 Sequence< sal_Int8 > SvxRectCtlAccessibleContext::getUniqueId( void )
781 static OImplementationId* pId = 0;
782 if( !pId )
784 MutexGuard aGuard( Mutex::getGlobalMutex() );
785 if( !pId)
787 static OImplementationId aId;
788 pId = &aId;
791 return pId->getImplementationId();
794 void SvxRectCtlAccessibleContext::ThrowExceptionIfNotAlive( void ) throw( lang::DisposedException )
796 if( IsNotAlive() )
797 throw lang::DisposedException();
800 // -------------------------------------------------------------------------------------------------
803 DBG_NAME( SvxRectCtlChildAccessibleContext )
806 SvxRectCtlChildAccessibleContext::SvxRectCtlChildAccessibleContext(
807 const Reference<XAccessible>& rxParent,
808 const Window& rParentWindow,
809 const ::rtl::OUString& rName,
810 const ::rtl::OUString& rDescription,
811 const Rectangle& rBoundingBox,
812 long nIndexInParent ) :
814 SvxRectCtlChildAccessibleContext_Base( maMutex ),
815 msDescription( rDescription ),
816 msName( rName ),
817 mxParent(rxParent),
818 mpBoundingBox( new Rectangle( rBoundingBox ) ),
819 mrParentWindow( rParentWindow ),
820 mnClientId( 0 ),
821 mnIndexInParent( nIndexInParent ),
822 mbIsChecked( sal_False )
824 DBG_CTOR( SvxRectCtlChildAccessibleContext, NULL );
828 SvxRectCtlChildAccessibleContext::~SvxRectCtlChildAccessibleContext()
830 DBG_DTOR( SvxRectCtlChildAccessibleContext, NULL );
832 if( IsAlive() )
834 osl_incrementInterlockedCount( &m_refCount );
835 dispose(); // set mpRepr = NULL & release all childs
839 //===== XAccessible =========================================================
841 Reference< XAccessibleContext> SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleContext( void ) throw( RuntimeException )
843 return this;
846 //===== XAccessibleComponent ================================================
848 sal_Bool SAL_CALL SvxRectCtlChildAccessibleContext::containsPoint( const awt::Point& rPoint ) throw( RuntimeException )
850 // no guard -> done in getBounds()
851 // return GetBoundingBox().IsInside( VCLPoint( rPoint ) );
852 return Rectangle( Point( 0, 0 ), GetBoundingBox().GetSize() ).IsInside( VCLPoint( rPoint ) );
855 Reference< XAccessible > SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleAtPoint( const awt::Point& /*rPoint*/ ) throw( RuntimeException )
857 return Reference< XAccessible >();
860 awt::Rectangle SAL_CALL SvxRectCtlChildAccessibleContext::getBounds() throw( RuntimeException )
862 // no guard -> done in getBoundingBox()
863 return AWTRectangle( GetBoundingBox() );
866 awt::Point SAL_CALL SvxRectCtlChildAccessibleContext::getLocation() throw( RuntimeException )
868 // no guard -> done in getBoundingBox()
869 return AWTPoint( GetBoundingBox().TopLeft() );
872 awt::Point SAL_CALL SvxRectCtlChildAccessibleContext::getLocationOnScreen() throw( RuntimeException )
874 // no guard -> done in getBoundingBoxOnScreen()
875 return AWTPoint( GetBoundingBoxOnScreen().TopLeft() );
878 awt::Size SAL_CALL SvxRectCtlChildAccessibleContext::getSize() throw( RuntimeException )
880 // no guard -> done in getBoundingBox()
881 return AWTSize( GetBoundingBox().GetSize() );
884 sal_Bool SAL_CALL SvxRectCtlChildAccessibleContext::isShowing() throw( RuntimeException )
886 return sal_True;
889 sal_Bool SAL_CALL SvxRectCtlChildAccessibleContext::isVisible() throw( RuntimeException )
891 ::osl::MutexGuard aGuard( maMutex );
893 ThrowExceptionIfNotAlive();
895 return mxParent.is()? ( static_cast< SvxRectCtlAccessibleContext* >( mxParent.get() ) )->isVisible() : sal_False;
898 sal_Bool SAL_CALL SvxRectCtlChildAccessibleContext::isFocusTraversable() throw( RuntimeException )
900 return sal_False;
903 void SAL_CALL SvxRectCtlChildAccessibleContext::addFocusListener( const Reference< awt::XFocusListener >& /*xListener*/ )
904 throw( RuntimeException )
906 OSL_ENSURE( false, "SvxRectCtlChildAccessibleContext::addFocusListener: not implemented" );
909 void SAL_CALL SvxRectCtlChildAccessibleContext::removeFocusListener( const Reference< awt::XFocusListener >& /*xListener*/ )
910 throw (RuntimeException)
912 OSL_ENSURE( false, "SvxRectCtlChildAccessibleContext::removeFocusListener: not implemented" );
915 void SAL_CALL SvxRectCtlChildAccessibleContext::grabFocus() throw( RuntimeException )
919 Any SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleKeyBinding() throw( RuntimeException )
921 // here is no implementation, because here are no KeyBindings for every object
922 return Any();
924 sal_Int32 SvxRectCtlChildAccessibleContext::getForeground( )
925 throw (::com::sun::star::uno::RuntimeException)
927 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
928 ::osl::MutexGuard aGuard( maMutex );
929 ThrowExceptionIfNotAlive();
930 return mrParentWindow.GetControlForeground().GetColor();
932 sal_Int32 SvxRectCtlChildAccessibleContext::getBackground( )
933 throw (::com::sun::star::uno::RuntimeException)
935 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
936 ::osl::MutexGuard aGuard( maMutex );
938 ThrowExceptionIfNotAlive();
939 return mrParentWindow.GetControlBackground().GetColor();
942 //===== XAccessibleContext ==================================================
944 sal_Int32 SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleChildCount( void ) throw( RuntimeException )
946 return 0;
949 Reference< XAccessible > SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleChild( sal_Int32 /*nIndex*/ ) throw ( RuntimeException, lang::IndexOutOfBoundsException )
951 throw lang::IndexOutOfBoundsException();
954 Reference< XAccessible > SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleParent( void ) throw( RuntimeException )
956 return mxParent;
959 sal_Int32 SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleIndexInParent( void ) throw( RuntimeException )
961 return mnIndexInParent;
964 sal_Int16 SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleRole( void ) throw( RuntimeException )
966 return AccessibleRole::RADIO_BUTTON;
969 ::rtl::OUString SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleDescription( void ) throw( RuntimeException )
971 ::osl::MutexGuard aGuard( maMutex );
972 return msDescription;
975 ::rtl::OUString SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleName( void ) throw( RuntimeException )
977 ::osl::MutexGuard aGuard( maMutex );
978 return msName;
981 /** Return empty reference to indicate that the relation set is not
982 supported.
984 Reference<XAccessibleRelationSet> SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleRelationSet( void ) throw( RuntimeException )
986 return Reference< XAccessibleRelationSet >();
989 Reference< XAccessibleStateSet > SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleStateSet( void ) throw( RuntimeException )
991 ::osl::MutexGuard aGuard( maMutex );
992 utl::AccessibleStateSetHelper* pStateSetHelper = new utl::AccessibleStateSetHelper;
994 if( IsAlive() )
996 if( mbIsChecked )
998 pStateSetHelper->AddState( AccessibleStateType::CHECKED );
999 // pStateSetHelper->AddState( AccessibleStateType::SELECTED );
1002 pStateSetHelper->AddState( AccessibleStateType::ENABLED );
1003 pStateSetHelper->AddState( AccessibleStateType::SENSITIVE );
1004 pStateSetHelper->AddState( AccessibleStateType::OPAQUE );
1005 pStateSetHelper->AddState( AccessibleStateType::SELECTABLE );
1006 pStateSetHelper->AddState( AccessibleStateType::SHOWING );
1007 pStateSetHelper->AddState( AccessibleStateType::VISIBLE );
1009 else
1010 pStateSetHelper->AddState( AccessibleStateType::DEFUNC );
1012 return pStateSetHelper;
1015 lang::Locale SAL_CALL SvxRectCtlChildAccessibleContext::getLocale( void ) throw( IllegalAccessibleComponentStateException, RuntimeException )
1017 ::osl::MutexGuard aGuard( maMutex );
1018 if( mxParent.is() )
1020 Reference< XAccessibleContext > xParentContext( mxParent->getAccessibleContext() );
1021 if( xParentContext.is() )
1022 return xParentContext->getLocale();
1025 // No locale and no parent. Therefore throw exception to indicate this
1026 // cluelessness.
1027 throw IllegalAccessibleComponentStateException();
1030 void SAL_CALL SvxRectCtlChildAccessibleContext::addEventListener( const Reference< XAccessibleEventListener >& xListener )
1031 throw( RuntimeException )
1033 if (xListener.is())
1035 ::osl::MutexGuard aGuard( maMutex );
1036 if (!mnClientId)
1037 mnClientId = comphelper::AccessibleEventNotifier::registerClient( );
1038 comphelper::AccessibleEventNotifier::addEventListener( mnClientId, xListener );
1045 void SAL_CALL SvxRectCtlChildAccessibleContext::removeEventListener( const Reference< XAccessibleEventListener >& xListener )
1046 throw( RuntimeException )
1048 if (xListener.is())
1050 ::osl::MutexGuard aGuard( maMutex );
1052 sal_Int32 nListenerCount = comphelper::AccessibleEventNotifier::removeEventListener( mnClientId, xListener );
1053 if ( !nListenerCount )
1055 // no listeners anymore
1056 // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client),
1057 // and at least to us not firing any events anymore, in case somebody calls
1058 // NotifyAccessibleEvent, again
1059 comphelper::AccessibleEventNotifier::revokeClient( mnClientId );
1060 mnClientId = 0;
1065 //===== XAccessibleValue ================================================
1067 Any SAL_CALL SvxRectCtlChildAccessibleContext::getCurrentValue() throw( RuntimeException )
1069 ThrowExceptionIfNotAlive();
1071 Any aRet;
1072 aRet <<= ( mbIsChecked? 1.0 : 0.0 );
1073 return aRet;
1076 sal_Bool SAL_CALL SvxRectCtlChildAccessibleContext::setCurrentValue( const Any& /*aNumber*/ ) throw( RuntimeException )
1078 return sal_False;
1081 Any SAL_CALL SvxRectCtlChildAccessibleContext::getMaximumValue() throw( RuntimeException )
1083 Any aRet;
1084 aRet <<= 1.0;
1085 return aRet;
1088 Any SAL_CALL SvxRectCtlChildAccessibleContext::getMinimumValue() throw( RuntimeException )
1090 Any aRet;
1091 aRet <<= 0.0;
1092 return aRet;
1095 //===== XServiceInfo ========================================================
1097 ::rtl::OUString SAL_CALL SvxRectCtlChildAccessibleContext::getImplementationName( void ) throw( RuntimeException )
1099 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.ui.SvxRectCtlChildAccessibleContext" ) );
1102 sal_Bool SAL_CALL SvxRectCtlChildAccessibleContext::supportsService( const ::rtl::OUString& sServiceName ) throw( RuntimeException )
1104 // Iterate over all supported service names and return true if on of them
1105 // matches the given name.
1106 ::osl::MutexGuard aGuard( maMutex );
1107 Sequence< ::rtl::OUString > aSupportedServices ( getSupportedServiceNames() );
1108 int nLength = aSupportedServices.getLength();
1109 for( int i = 0 ; i < nLength; ++i )
1111 if( sServiceName == aSupportedServices[ i ] )
1112 return sal_True;
1115 return sal_False;
1118 Sequence< ::rtl::OUString > SAL_CALL SvxRectCtlChildAccessibleContext::getSupportedServiceNames( void ) throw( RuntimeException )
1120 const ::rtl::OUString sServiceName (RTL_CONSTASCII_USTRINGPARAM ("com.sun.star.accessibility.AccessibleContext"));
1121 return Sequence< ::rtl::OUString >( &sServiceName, 1 );
1124 //===== XTypeProvider =======================================================
1126 Sequence< sal_Int8 > SAL_CALL SvxRectCtlChildAccessibleContext::getImplementationId( void ) throw( RuntimeException )
1128 static OImplementationId* pId = 0;
1129 if( !pId )
1131 MutexGuard aGuard( Mutex::getGlobalMutex() );
1132 if( !pId)
1134 static OImplementationId aId;
1135 pId = &aId;
1138 return pId->getImplementationId();
1141 //===== internal ============================================================
1143 void SvxRectCtlChildAccessibleContext::CommitChange( const AccessibleEventObject& rEvent )
1145 if (mnClientId)
1146 comphelper::AccessibleEventNotifier::addEvent( mnClientId, rEvent );
1149 void SAL_CALL SvxRectCtlChildAccessibleContext::disposing()
1151 if( !rBHelper.bDisposed )
1153 ::osl::MutexGuard aGuard( maMutex );
1155 // Send a disposing to all listeners.
1156 if ( mnClientId )
1158 comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( mnClientId, *this );
1159 mnClientId = 0;
1162 mxParent = Reference< XAccessible >();
1164 delete mpBoundingBox;
1168 void SvxRectCtlChildAccessibleContext::ThrowExceptionIfNotAlive( void ) throw( lang::DisposedException )
1170 if( IsNotAlive() )
1171 throw lang::DisposedException();
1174 Rectangle SvxRectCtlChildAccessibleContext::GetBoundingBoxOnScreen( void ) throw( RuntimeException )
1176 ::osl::MutexGuard aGuard( maMutex );
1178 // no ThrowExceptionIfNotAlive() because its done in GetBoundingBox()
1179 Rectangle aRect( GetBoundingBox() );
1181 return Rectangle( mrParentWindow.OutputToScreenPixel( aRect.TopLeft() ), aRect.GetSize() );
1184 Rectangle SvxRectCtlChildAccessibleContext::GetBoundingBox( void ) throw( RuntimeException )
1186 // no guard neccessary, because no one changes mpBoundingBox after creating it
1187 ThrowExceptionIfNotAlive();
1189 return *mpBoundingBox;
1192 void SvxRectCtlChildAccessibleContext::setStateChecked( sal_Bool bChecked )
1194 if( mbIsChecked != bChecked )
1196 mbIsChecked = bChecked;
1198 const Reference< XInterface > xSource( *this );
1200 Any aOld;
1201 Any aNew;
1202 Any& rMod = bChecked? aNew : aOld;
1204 rMod <<= AccessibleStateType::CHECKED;
1206 CommitChange( AccessibleEventObject( xSource, AccessibleEventId::STATE_CHANGED, aNew, aOld ) );