fdo#74697 Add Bluez 5 support for impress remote.
[LibreOffice.git] / svx / source / accessibility / svxrectctaccessiblecontext.cxx
blobbbb2797788d18a3e5a4abc87ac965d12a14e6c60
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "svxrectctaccessiblecontext.hxx"
21 #include <com/sun/star/accessibility/AccessibleRole.hpp>
22 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
23 #include <unotools/accessiblestatesethelper.hxx>
24 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
25 #include <com/sun/star/beans/PropertyChangeEvent.hpp>
26 #include <com/sun/star/awt/XWindow.hpp>
27 #include <cppuhelper/typeprovider.hxx>
28 #include <toolkit/helper/vclunohelper.hxx>
29 #include <toolkit/helper/convert.hxx>
30 #include <vcl/svapp.hxx>
31 #include <osl/mutex.hxx>
32 #include <tools/debug.hxx>
33 #include <tools/gen.hxx>
35 #include <svx/dialogs.hrc>
36 #include "accessibility.hrc"
37 #include <svx/dlgctrl.hxx>
38 #include <svx/dialmgr.hxx>
39 #include <comphelper/accessibleeventnotifier.hxx>
42 using namespace ::cppu;
43 using namespace ::osl;
44 using namespace ::com::sun::star;
45 using namespace ::com::sun::star::uno;
46 using namespace ::com::sun::star::accessibility;
49 #define MAX_NUM_OF_CHILDREN 9
50 #define NOCHILDSELECTED -1
53 DBG_NAME( SvxRectCtlAccessibleContext )
56 //===== internal ============================================================
58 namespace
60 struct ChildIndexToPointData
62 short nResIdName;
63 short nResIdDescr;
64 RECT_POINT ePoint;
69 static const ChildIndexToPointData* IndexToPoint( long nIndex, bool bAngleControl )
71 DBG_ASSERT( nIndex < ( bAngleControl? 8 : 9 ) && nIndex >= 0, "-IndexToPoint(): invalid child index! You have been warned..." );
73 // angles are counted reverse counter clock wise
74 static const ChildIndexToPointData pAngleData[] =
75 { // index
76 { RID_SVXSTR_RECTCTL_ACC_CHLD_A000, RID_SVXSTR_RECTCTL_ACC_CHLD_A000, RP_RM }, // 0
77 { RID_SVXSTR_RECTCTL_ACC_CHLD_A045, RID_SVXSTR_RECTCTL_ACC_CHLD_A045, RP_RT }, // 1
78 { RID_SVXSTR_RECTCTL_ACC_CHLD_A090, RID_SVXSTR_RECTCTL_ACC_CHLD_A090, RP_MT }, // 2
79 { RID_SVXSTR_RECTCTL_ACC_CHLD_A135, RID_SVXSTR_RECTCTL_ACC_CHLD_A135, RP_LT }, // 3
80 { RID_SVXSTR_RECTCTL_ACC_CHLD_A180, RID_SVXSTR_RECTCTL_ACC_CHLD_A180, RP_LM }, // 4
81 { RID_SVXSTR_RECTCTL_ACC_CHLD_A225, RID_SVXSTR_RECTCTL_ACC_CHLD_A225, RP_LB }, // 5
82 { RID_SVXSTR_RECTCTL_ACC_CHLD_A270, RID_SVXSTR_RECTCTL_ACC_CHLD_A270, RP_MB }, // 6
83 { RID_SVXSTR_RECTCTL_ACC_CHLD_A315, RID_SVXSTR_RECTCTL_ACC_CHLD_A315, RP_RB } // 7
86 // corners are counted from left to right and top to bottom
87 static const ChildIndexToPointData pCornerData[] =
88 { // index
89 { RID_SVXSTR_RECTCTL_ACC_CHLD_LT, RID_SVXSTR_RECTCTL_ACC_CHLD_LT, RP_LT }, // 0
90 { RID_SVXSTR_RECTCTL_ACC_CHLD_MT, RID_SVXSTR_RECTCTL_ACC_CHLD_MT, RP_MT }, // 1
91 { RID_SVXSTR_RECTCTL_ACC_CHLD_RT, RID_SVXSTR_RECTCTL_ACC_CHLD_RT, RP_RT }, // 2
92 { RID_SVXSTR_RECTCTL_ACC_CHLD_LM, RID_SVXSTR_RECTCTL_ACC_CHLD_LM, RP_LM }, // 3
93 { RID_SVXSTR_RECTCTL_ACC_CHLD_MM, RID_SVXSTR_RECTCTL_ACC_CHLD_MM, RP_MM }, // 4
94 { RID_SVXSTR_RECTCTL_ACC_CHLD_RM, RID_SVXSTR_RECTCTL_ACC_CHLD_RM, RP_RM }, // 5
95 { RID_SVXSTR_RECTCTL_ACC_CHLD_LB, RID_SVXSTR_RECTCTL_ACC_CHLD_LB, RP_LB }, // 6
96 { RID_SVXSTR_RECTCTL_ACC_CHLD_MB, RID_SVXSTR_RECTCTL_ACC_CHLD_MB, RP_MB }, // 7
97 { RID_SVXSTR_RECTCTL_ACC_CHLD_RB, RID_SVXSTR_RECTCTL_ACC_CHLD_RB, RP_RB } // 8
100 return ( bAngleControl? pAngleData : pCornerData ) + nIndex;
104 static long PointToIndex( RECT_POINT ePoint, bool bAngleControl )
106 long nRet( (long) ePoint );
107 if( bAngleControl )
108 { // angle control
109 // angles are counted reverse counter clock wise
110 switch( ePoint )
112 case RP_LT: nRet = 3; break;
113 case RP_MT: nRet = 2; break;
114 case RP_RT: nRet = 1; break;
115 case RP_LM: nRet = 4; break;
116 case RP_MM: nRet = NOCHILDSELECTED; break;
117 case RP_RM: nRet = 0; break;
118 case RP_LB: nRet = 5; break;
119 case RP_MB: nRet = 6; break;
120 case RP_RB: nRet = 7; break;
123 else
124 { // corner control
125 // corners are counted from left to right and top to bottom
126 DBG_ASSERT( RP_LT == 0 && RP_MT == 1 && RP_RT == 2 && RP_LM == 3 && RP_MM == 4 && RP_RM == 5 &&
127 RP_LB == 6 && RP_MB == 7 && RP_RB == 8, "*PointToIndex(): unexpected enum value!" );
129 nRet = ( long ) ePoint;
132 return nRet;
136 SvxRectCtlAccessibleContext::SvxRectCtlAccessibleContext(
137 const Reference< XAccessible >& rxParent,
138 SvxRectCtl& rRepr,
139 const OUString* pName,
140 const OUString* pDesc ) :
142 SvxRectCtlAccessibleContext_Base( m_aMutex ),
143 mxParent( rxParent ),
144 mpRepr( &rRepr ),
145 mpChildren( NULL ),
146 mnClientId( 0 ),
147 mnSelectedChild( NOCHILDSELECTED ),
148 mbAngleMode( rRepr.GetNumOfChildren() == 8 )
150 DBG_CTOR( SvxRectCtlAccessibleContext, NULL );
152 if( pName )
153 msName = *pName;
154 else
156 ::SolarMutexGuard aSolarGuard;
157 msName = SVX_RESSTR( mbAngleMode? RID_SVXSTR_RECTCTL_ACC_ANGL_NAME : RID_SVXSTR_RECTCTL_ACC_CORN_NAME );
160 if( pDesc )
161 msDescription = *pDesc;
162 else
164 ::SolarMutexGuard aSolarGuard;
165 msDescription = SVX_RESSTR( mbAngleMode? RID_SVXSTR_RECTCTL_ACC_ANGL_DESCR : RID_SVXSTR_RECTCTL_ACC_CORN_DESCR );
168 mpChildren = new SvxRectCtlChildAccessibleContext*[ MAX_NUM_OF_CHILDREN ];
170 SvxRectCtlChildAccessibleContext** p = mpChildren;
171 for( int i = MAX_NUM_OF_CHILDREN ; i ; --i, ++p )
172 *p = NULL;
176 SvxRectCtlAccessibleContext::~SvxRectCtlAccessibleContext()
178 DBG_DTOR( SvxRectCtlAccessibleContext, NULL );
180 if( IsAlive() )
182 osl_atomic_increment( &m_refCount );
183 dispose(); // set mpRepr = NULL & release all children
187 //===== XAccessible =========================================================
189 Reference< XAccessibleContext > SAL_CALL SvxRectCtlAccessibleContext::getAccessibleContext( void ) throw( RuntimeException )
191 return this;
194 //===== XAccessibleComponent ================================================
196 sal_Bool SAL_CALL SvxRectCtlAccessibleContext::containsPoint( const awt::Point& rPoint ) throw( RuntimeException )
198 // no guard -> done in getBounds()
199 // return GetBoundingBox().IsInside( VCLPoint( rPoint ) );
200 return Rectangle( Point( 0, 0 ), GetBoundingBox().GetSize() ).IsInside( VCLPoint( rPoint ) );
203 Reference< XAccessible > SAL_CALL SvxRectCtlAccessibleContext::getAccessibleAtPoint( const awt::Point& rPoint ) throw( RuntimeException )
205 ::osl::MutexGuard aGuard( m_aMutex );
207 ThrowExceptionIfNotAlive();
209 Reference< XAccessible > xRet;
211 long nChild = PointToIndex( mpRepr->GetApproxRPFromPixPt( rPoint ), mbAngleMode );
213 if( nChild != NOCHILDSELECTED )
214 xRet = getAccessibleChild( nChild );
216 return xRet;
219 awt::Rectangle SAL_CALL SvxRectCtlAccessibleContext::getBounds() throw( RuntimeException )
221 // no guard -> done in GetBoundingBox()
222 return AWTRectangle( GetBoundingBox() );
225 awt::Point SAL_CALL SvxRectCtlAccessibleContext::getLocation() throw( RuntimeException )
227 // no guard -> done in GetBoundingBox()
228 return AWTPoint( GetBoundingBox().TopLeft() );
231 awt::Point SAL_CALL SvxRectCtlAccessibleContext::getLocationOnScreen() throw( RuntimeException )
233 // no guard -> done in GetBoundingBoxOnScreen()
234 return AWTPoint( GetBoundingBoxOnScreen().TopLeft() );
237 awt::Size SAL_CALL SvxRectCtlAccessibleContext::getSize() throw( RuntimeException )
239 // no guard -> done in GetBoundingBox()
240 return AWTSize( GetBoundingBox().GetSize() );
243 sal_Bool SAL_CALL SvxRectCtlAccessibleContext::isShowing() throw( RuntimeException )
245 return sal_True;
248 sal_Bool SAL_CALL SvxRectCtlAccessibleContext::isVisible() throw( RuntimeException )
250 ::osl::MutexGuard aGuard( m_aMutex );
252 ThrowExceptionIfNotAlive();
254 return mpRepr->IsVisible();
257 sal_Bool SAL_CALL SvxRectCtlAccessibleContext::isFocusTraversable() throw( RuntimeException )
259 return sal_True;
262 //===== XAccessibleContext ==================================================
264 sal_Int32 SAL_CALL SvxRectCtlAccessibleContext::getAccessibleChildCount( void ) throw( RuntimeException )
266 ::osl::MutexGuard aGuard( m_aMutex );
268 ThrowExceptionIfNotAlive();
270 return mpRepr->GetNumOfChildren();
273 Reference< XAccessible > SAL_CALL SvxRectCtlAccessibleContext::getAccessibleChild( sal_Int32 nIndex )
274 throw( RuntimeException, lang::IndexOutOfBoundsException )
276 checkChildIndex( nIndex );
278 Reference< XAccessible > xChild = mpChildren[ nIndex ];
279 if( !xChild.is() )
281 ::SolarMutexGuard aSolarGuard;
283 ::osl::MutexGuard aGuard( m_aMutex );
285 ThrowExceptionIfNotAlive();
287 xChild = mpChildren[ nIndex ];
289 if( !xChild.is() )
291 const ChildIndexToPointData* p = IndexToPoint( nIndex, mbAngleMode );
292 OUString aName(SVX_RESSTR(p->nResIdName));
293 OUString aDescr(SVX_RESSTR(p->nResIdDescr));
295 Rectangle aFocusRect( mpRepr->CalculateFocusRectangle( p->ePoint ) );
297 SvxRectCtlChildAccessibleContext* pChild = new SvxRectCtlChildAccessibleContext(
298 this, *mpRepr, aName, aDescr, aFocusRect, nIndex );
299 xChild = mpChildren[ nIndex ] = pChild;
300 pChild->acquire();
302 // set actual state
303 if( mnSelectedChild == nIndex )
304 pChild->setStateChecked( true );
308 return xChild;
311 Reference< XAccessible > SAL_CALL SvxRectCtlAccessibleContext::getAccessibleParent( void ) throw( RuntimeException )
313 return mxParent;
316 sal_Int32 SAL_CALL SvxRectCtlAccessibleContext::getAccessibleIndexInParent( void ) throw( RuntimeException )
318 ::osl::MutexGuard aGuard( m_aMutex );
319 // Use a simple but slow solution for now. Optimize later.
321 // Iterate over all the parent's children and search for this object.
322 if( mxParent.is() )
324 Reference< XAccessibleContext > xParentContext( mxParent->getAccessibleContext() );
325 if( xParentContext.is() )
327 sal_Int32 nChildCount = xParentContext->getAccessibleChildCount();
328 for( sal_Int32 i = 0 ; i < nChildCount ; ++i )
330 Reference< XAccessible > xChild( xParentContext->getAccessibleChild( i ) );
331 if( xChild.get() == ( XAccessible* ) this )
332 return i;
337 // Return -1 to indicate that this object's parent does not know about the
338 // object.
339 return -1;
342 sal_Int16 SAL_CALL SvxRectCtlAccessibleContext::getAccessibleRole( void ) throw( RuntimeException )
344 return AccessibleRole::PANEL;
347 OUString SAL_CALL SvxRectCtlAccessibleContext::getAccessibleDescription( void ) throw( RuntimeException )
349 ::osl::MutexGuard aGuard( m_aMutex );
350 return msDescription;
353 OUString SAL_CALL SvxRectCtlAccessibleContext::getAccessibleName( void ) throw( RuntimeException )
355 ::osl::MutexGuard aGuard( m_aMutex );
356 return msName;
359 /** Return empty reference to indicate that the relation set is not
360 supported.
362 Reference< XAccessibleRelationSet > SAL_CALL SvxRectCtlAccessibleContext::getAccessibleRelationSet( void ) throw( RuntimeException )
364 return Reference< XAccessibleRelationSet >();
367 Reference< XAccessibleStateSet > SAL_CALL SvxRectCtlAccessibleContext::getAccessibleStateSet( void ) throw( RuntimeException )
369 ::osl::MutexGuard aGuard( m_aMutex );
370 utl::AccessibleStateSetHelper* pStateSetHelper = new utl::AccessibleStateSetHelper;
372 if( IsAlive() )
374 pStateSetHelper->AddState( AccessibleStateType::FOCUSABLE );
375 if( mpRepr->HasFocus() )
376 pStateSetHelper->AddState( AccessibleStateType::FOCUSED );
377 pStateSetHelper->AddState( AccessibleStateType::OPAQUE );
379 if( isShowing() )
380 pStateSetHelper->AddState( AccessibleStateType::SHOWING );
382 if( isVisible() )
383 pStateSetHelper->AddState( AccessibleStateType::VISIBLE );
385 else
386 pStateSetHelper->AddState( AccessibleStateType::DEFUNC );
388 return pStateSetHelper;
391 lang::Locale SAL_CALL SvxRectCtlAccessibleContext::getLocale( void ) throw( IllegalAccessibleComponentStateException, RuntimeException )
393 ::osl::MutexGuard aGuard( m_aMutex );
394 if( mxParent.is() )
396 Reference< XAccessibleContext > xParentContext( mxParent->getAccessibleContext() );
397 if( xParentContext.is() )
398 return xParentContext->getLocale();
401 // No parent. Therefore throw exception to indicate this cluelessness.
402 throw IllegalAccessibleComponentStateException();
405 void SAL_CALL SvxRectCtlAccessibleContext::addAccessibleEventListener( const Reference< XAccessibleEventListener >& xListener )
406 throw( RuntimeException )
408 if (xListener.is())
410 ::osl::MutexGuard aGuard( m_aMutex );
411 if (!mnClientId)
412 mnClientId = comphelper::AccessibleEventNotifier::registerClient( );
413 comphelper::AccessibleEventNotifier::addEventListener( mnClientId, xListener );
417 void SAL_CALL SvxRectCtlAccessibleContext::removeAccessibleEventListener( const Reference< XAccessibleEventListener >& xListener )
418 throw( RuntimeException )
420 if (xListener.is())
422 ::osl::MutexGuard aGuard( m_aMutex );
424 sal_Int32 nListenerCount = comphelper::AccessibleEventNotifier::removeEventListener( mnClientId, xListener );
425 if ( !nListenerCount )
427 // no listeners anymore
428 // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client),
429 // and at least to us not firing any events anymore, in case somebody calls
430 // NotifyAccessibleEvent, again
431 comphelper::AccessibleEventNotifier::revokeClient( mnClientId );
432 mnClientId = 0;
437 void SAL_CALL SvxRectCtlAccessibleContext::addFocusListener( const Reference< awt::XFocusListener >& xListener )
438 throw( RuntimeException )
440 if( xListener.is() )
442 ::osl::MutexGuard aGuard( m_aMutex );
444 ThrowExceptionIfNotAlive();
446 Reference< awt::XWindow > xWindow = VCLUnoHelper::GetInterface( mpRepr );
447 if( xWindow.is() )
448 xWindow->addFocusListener( xListener );
452 void SAL_CALL SvxRectCtlAccessibleContext::removeFocusListener( const Reference< awt::XFocusListener >& xListener )
453 throw (RuntimeException)
455 if( xListener.is() )
457 ::osl::MutexGuard aGuard( m_aMutex );
459 ThrowExceptionIfNotAlive();
461 Reference< awt::XWindow > xWindow = VCLUnoHelper::GetInterface( mpRepr );
462 if( xWindow.is() )
463 xWindow->removeFocusListener( xListener );
467 void SAL_CALL SvxRectCtlAccessibleContext::grabFocus() throw( RuntimeException )
469 ::SolarMutexGuard aSolarGuard;
470 ::osl::MutexGuard aGuard( m_aMutex );
472 ThrowExceptionIfNotAlive();
474 mpRepr->GrabFocus();
477 Any SAL_CALL SvxRectCtlAccessibleContext::getAccessibleKeyBinding() throw( RuntimeException )
479 // here is no implementation, because here are no KeyBindings for every object
480 return Any();
483 sal_Int32 SvxRectCtlAccessibleContext::getForeground( )
484 throw (::com::sun::star::uno::RuntimeException)
486 ::SolarMutexGuard aSolarGuard;
487 ::osl::MutexGuard aGuard( m_aMutex );
488 ThrowExceptionIfNotAlive();
490 return mpRepr->GetControlForeground().GetColor();
492 sal_Int32 SvxRectCtlAccessibleContext::getBackground( )
493 throw (::com::sun::star::uno::RuntimeException)
495 ::SolarMutexGuard aSolarGuard;
496 ::osl::MutexGuard aGuard( m_aMutex );
497 ThrowExceptionIfNotAlive();
499 return mpRepr->GetControlBackground().GetColor();
502 //===== XServiceInfo ========================================================
504 OUString SAL_CALL SvxRectCtlAccessibleContext::getImplementationName( void ) throw( RuntimeException )
506 return OUString( "com.sun.star.comp.ui.SvxRectCtlAccessibleContext" );
509 sal_Bool SAL_CALL SvxRectCtlAccessibleContext::supportsService( const OUString& sServiceName ) throw( RuntimeException )
511 ::osl::MutexGuard aGuard( m_aMutex );
512 // Iterate over all supported service names and return true if on of them
513 // matches the given name.
514 Sequence< OUString > aSupportedServices( getSupportedServiceNames() );
515 int nLength = aSupportedServices.getLength();
516 const OUString* pStr = aSupportedServices.getConstArray();
518 for( int i = nLength ; i ; --i, ++pStr )
520 if( sServiceName == *pStr )
521 return sal_True;
524 return sal_False;
527 Sequence< OUString > SAL_CALL SvxRectCtlAccessibleContext::getSupportedServiceNames( void ) throw( RuntimeException )
529 const OUString sServiceName( "com.sun.star.accessibility.AccessibleContext" );
530 return Sequence< OUString >( &sServiceName, 1 );
533 //===== XTypeProvider =======================================================
535 Sequence< sal_Int8 > SAL_CALL SvxRectCtlAccessibleContext::getImplementationId( void ) throw( RuntimeException )
537 return getUniqueId();
540 //===== XAccessibleSelection =============================================
542 void SAL_CALL SvxRectCtlAccessibleContext::selectAccessibleChild( sal_Int32 nIndex ) throw( lang::IndexOutOfBoundsException, RuntimeException )
544 ::SolarMutexGuard aSolarGuard;
546 ::osl::MutexGuard aGuard( m_aMutex );
548 checkChildIndex( nIndex );
550 ThrowExceptionIfNotAlive();
552 const ChildIndexToPointData* pData = IndexToPoint( nIndex, mbAngleMode );
554 DBG_ASSERT( pData,
555 "SvxRectCtlAccessibleContext::selectAccessibleChild(): this is an impossible state! Or at least should be..." );
557 // this does all what is needed, including the change of the child's state!
558 mpRepr->SetActualRP( pData->ePoint );
561 sal_Bool SAL_CALL SvxRectCtlAccessibleContext::isAccessibleChildSelected( sal_Int32 nIndex ) throw( lang::IndexOutOfBoundsException, RuntimeException )
563 ::osl::MutexGuard aGuard( m_aMutex );
565 checkChildIndex( nIndex );
567 return nIndex == mnSelectedChild;
570 void SAL_CALL SvxRectCtlAccessibleContext::clearAccessibleSelection() throw( RuntimeException )
572 DBG_ASSERT( sal_False, "SvxRectCtlAccessibleContext::clearAccessibleSelection() is not possible!" );
575 void SAL_CALL SvxRectCtlAccessibleContext::selectAllAccessibleChildren() throw( RuntimeException )
577 // guard in selectAccessibleChild()!
579 selectAccessibleChild( 0 ); // default per definition
582 sal_Int32 SAL_CALL SvxRectCtlAccessibleContext::getSelectedAccessibleChildCount() throw( RuntimeException )
584 ::osl::MutexGuard aGuard( m_aMutex );
586 return mnSelectedChild == NOCHILDSELECTED? 0 : 1;
589 Reference< XAccessible > SAL_CALL SvxRectCtlAccessibleContext::getSelectedAccessibleChild( sal_Int32 nIndex )
590 throw( lang::IndexOutOfBoundsException, RuntimeException )
592 ::osl::MutexGuard aGuard( m_aMutex );
594 checkChildIndexOnSelection( nIndex );
596 return getAccessibleChild( mnSelectedChild );
599 void SAL_CALL SvxRectCtlAccessibleContext::deselectAccessibleChild( sal_Int32 /*nIndex*/ ) throw( lang::IndexOutOfBoundsException, RuntimeException )
601 OUString aMessage( "deselectAccessibleChild is not possible in this context" );
603 DBG_ASSERT( sal_False, "SvxRectCtlAccessibleContext::deselectAccessibleChild() is not possible!" );
605 throw lang::IndexOutOfBoundsException( aMessage, *this ); // never possible
608 //===== internals ========================================================
610 void SvxRectCtlAccessibleContext::checkChildIndex( long nIndex ) throw( lang::IndexOutOfBoundsException )
612 if( nIndex < 0 || nIndex >= getAccessibleChildCount() )
613 throw lang::IndexOutOfBoundsException();
616 void SvxRectCtlAccessibleContext::checkChildIndexOnSelection( long nIndex ) throw( lang::IndexOutOfBoundsException )
618 if( nIndex || mnSelectedChild == NOCHILDSELECTED )
619 // in our case only for the first (0) _selected_ child this is a valid request
620 throw lang::IndexOutOfBoundsException();
623 void SvxRectCtlAccessibleContext::selectChild( long nNew )
625 ::osl::MutexGuard aGuard( m_aMutex );
626 if( nNew != mnSelectedChild )
628 long nNumOfChildren = getAccessibleChildCount();
629 if( nNew < nNumOfChildren )
630 { // valid index
631 SvxRectCtlChildAccessibleContext* pChild;
632 if( mnSelectedChild != NOCHILDSELECTED )
633 { // deselect old selected child if one is selected
634 pChild = mpChildren[ mnSelectedChild ];
635 if( pChild )
636 pChild->setStateChecked( false );
639 // select new child
640 mnSelectedChild = nNew;
642 if( nNew != NOCHILDSELECTED )
644 pChild = mpChildren[ nNew ];
645 if( pChild )
646 pChild->setStateChecked( true );
649 else
650 mnSelectedChild = NOCHILDSELECTED;
654 void SvxRectCtlAccessibleContext::selectChild( RECT_POINT eButton )
656 // no guard -> is done in next selectChild
657 selectChild( PointToIndex( eButton, mbAngleMode ) );
660 void SAL_CALL SvxRectCtlAccessibleContext::disposing()
662 if( !rBHelper.bDisposed )
665 ::osl::MutexGuard aGuard( m_aMutex );
666 mpRepr = NULL; // object dies with representation
668 SvxRectCtlChildAccessibleContext** p = mpChildren;
669 for( int i = MAX_NUM_OF_CHILDREN ; i ; --i, ++p )
671 SvxRectCtlChildAccessibleContext* pChild = *p;
672 if( pChild )
674 pChild->dispose();
675 pChild->release();
676 *p = NULL;
680 delete[] mpChildren;
681 mpChildren = NULL;
685 ::osl::MutexGuard aGuard( m_aMutex );
687 // Send a disposing to all listeners.
688 if ( mnClientId )
690 comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( mnClientId, *this );
691 mnClientId = 0;
694 mxParent = Reference< XAccessible >();
699 Rectangle SvxRectCtlAccessibleContext::GetBoundingBoxOnScreen( void ) throw( RuntimeException )
701 ::SolarMutexGuard aSolarGuard;
702 ::osl::MutexGuard aGuard( m_aMutex );
704 ThrowExceptionIfNotAlive();
706 return Rectangle( mpRepr->GetParent()->OutputToScreenPixel( mpRepr->GetPosPixel() ), mpRepr->GetSizePixel() );
709 Rectangle SvxRectCtlAccessibleContext::GetBoundingBox( void ) throw( RuntimeException )
711 ::SolarMutexGuard aSolarGuard;
712 ::osl::MutexGuard aGuard( m_aMutex );
714 ThrowExceptionIfNotAlive();
716 return Rectangle( mpRepr->GetPosPixel(), mpRepr->GetSizePixel() );
719 Sequence< sal_Int8 > SvxRectCtlAccessibleContext::getUniqueId( void )
721 static OImplementationId* pId = 0;
722 if( !pId )
724 MutexGuard aGuard( Mutex::getGlobalMutex() );
725 if( !pId)
727 static OImplementationId aId;
728 pId = &aId;
731 return pId->getImplementationId();
734 void SvxRectCtlAccessibleContext::ThrowExceptionIfNotAlive( void ) throw( lang::DisposedException )
736 if( IsNotAlive() )
737 throw lang::DisposedException();
740 // -------------------------------------------------------------------------------------------------
743 DBG_NAME( SvxRectCtlChildAccessibleContext )
746 SvxRectCtlChildAccessibleContext::SvxRectCtlChildAccessibleContext(
747 const Reference<XAccessible>& rxParent,
748 const Window& rParentWindow,
749 const OUString& rName,
750 const OUString& rDescription,
751 const Rectangle& rBoundingBox,
752 long nIndexInParent ) :
754 SvxRectCtlChildAccessibleContext_Base( maMutex ),
755 msDescription( rDescription ),
756 msName( rName ),
757 mxParent(rxParent),
758 mpBoundingBox( new Rectangle( rBoundingBox ) ),
759 mrParentWindow( rParentWindow ),
760 mnClientId( 0 ),
761 mnIndexInParent( nIndexInParent ),
762 mbIsChecked( false )
764 DBG_CTOR( SvxRectCtlChildAccessibleContext, NULL );
768 SvxRectCtlChildAccessibleContext::~SvxRectCtlChildAccessibleContext()
770 DBG_DTOR( SvxRectCtlChildAccessibleContext, NULL );
772 if( IsAlive() )
774 osl_atomic_increment( &m_refCount );
775 dispose(); // set mpRepr = NULL & release all children
779 //===== XAccessible =========================================================
781 Reference< XAccessibleContext> SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleContext( void ) throw( RuntimeException )
783 return this;
786 //===== XAccessibleComponent ================================================
788 sal_Bool SAL_CALL SvxRectCtlChildAccessibleContext::containsPoint( const awt::Point& rPoint ) throw( RuntimeException )
790 // no guard -> done in getBounds()
791 return Rectangle( Point( 0, 0 ), GetBoundingBox().GetSize() ).IsInside( VCLPoint( rPoint ) );
794 Reference< XAccessible > SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleAtPoint( const awt::Point& /*rPoint*/ ) throw( RuntimeException )
796 return Reference< XAccessible >();
799 awt::Rectangle SAL_CALL SvxRectCtlChildAccessibleContext::getBounds() throw( RuntimeException )
801 // no guard -> done in getBoundingBox()
802 return AWTRectangle( GetBoundingBox() );
805 awt::Point SAL_CALL SvxRectCtlChildAccessibleContext::getLocation() throw( RuntimeException )
807 // no guard -> done in getBoundingBox()
808 return AWTPoint( GetBoundingBox().TopLeft() );
811 awt::Point SAL_CALL SvxRectCtlChildAccessibleContext::getLocationOnScreen() throw( RuntimeException )
813 // no guard -> done in getBoundingBoxOnScreen()
814 return AWTPoint( GetBoundingBoxOnScreen().TopLeft() );
817 awt::Size SAL_CALL SvxRectCtlChildAccessibleContext::getSize() throw( RuntimeException )
819 // no guard -> done in getBoundingBox()
820 return AWTSize( GetBoundingBox().GetSize() );
823 sal_Bool SAL_CALL SvxRectCtlChildAccessibleContext::isShowing() throw( RuntimeException )
825 return sal_True;
828 sal_Bool SAL_CALL SvxRectCtlChildAccessibleContext::isVisible() throw( RuntimeException )
830 ::osl::MutexGuard aGuard( maMutex );
832 ThrowExceptionIfNotAlive();
834 return mxParent.is()? ( static_cast< SvxRectCtlAccessibleContext* >( mxParent.get() ) )->isVisible() : sal_False;
837 sal_Bool SAL_CALL SvxRectCtlChildAccessibleContext::isFocusTraversable() throw( RuntimeException )
839 return sal_False;
842 void SAL_CALL SvxRectCtlChildAccessibleContext::addFocusListener( const Reference< awt::XFocusListener >& /*xListener*/ )
843 throw( RuntimeException )
845 OSL_FAIL( "SvxRectCtlChildAccessibleContext::addFocusListener: not implemented" );
848 void SAL_CALL SvxRectCtlChildAccessibleContext::removeFocusListener( const Reference< awt::XFocusListener >& /*xListener*/ )
849 throw (RuntimeException)
851 OSL_FAIL( "SvxRectCtlChildAccessibleContext::removeFocusListener: not implemented" );
854 void SAL_CALL SvxRectCtlChildAccessibleContext::grabFocus() throw( RuntimeException )
858 Any SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleKeyBinding() throw( RuntimeException )
860 // here is no implementation, because here are no KeyBindings for every object
861 return Any();
863 sal_Int32 SvxRectCtlChildAccessibleContext::getForeground( )
864 throw (::com::sun::star::uno::RuntimeException)
866 ::SolarMutexGuard aSolarGuard;
867 ::osl::MutexGuard aGuard( maMutex );
868 ThrowExceptionIfNotAlive();
869 return mrParentWindow.GetControlForeground().GetColor();
871 sal_Int32 SvxRectCtlChildAccessibleContext::getBackground( )
872 throw (::com::sun::star::uno::RuntimeException)
874 ::SolarMutexGuard aSolarGuard;
875 ::osl::MutexGuard aGuard( maMutex );
877 ThrowExceptionIfNotAlive();
878 return mrParentWindow.GetControlBackground().GetColor();
881 //===== XAccessibleContext ==================================================
883 sal_Int32 SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleChildCount( void ) throw( RuntimeException )
885 return 0;
888 Reference< XAccessible > SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleChild( sal_Int32 /*nIndex*/ ) throw ( RuntimeException, lang::IndexOutOfBoundsException )
890 throw lang::IndexOutOfBoundsException();
893 Reference< XAccessible > SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleParent( void ) throw( RuntimeException )
895 return mxParent;
898 sal_Int32 SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleIndexInParent( void ) throw( RuntimeException )
900 return mnIndexInParent;
903 sal_Int16 SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleRole( void ) throw( RuntimeException )
905 return AccessibleRole::RADIO_BUTTON;
908 OUString SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleDescription( void ) throw( RuntimeException )
910 ::osl::MutexGuard aGuard( maMutex );
911 return msDescription;
914 OUString SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleName( void ) throw( RuntimeException )
916 ::osl::MutexGuard aGuard( maMutex );
917 return msName;
920 /** Return empty reference to indicate that the relation set is not
921 supported.
923 Reference<XAccessibleRelationSet> SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleRelationSet( void ) throw( RuntimeException )
925 return Reference< XAccessibleRelationSet >();
928 Reference< XAccessibleStateSet > SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleStateSet( void ) throw( RuntimeException )
930 ::osl::MutexGuard aGuard( maMutex );
931 utl::AccessibleStateSetHelper* pStateSetHelper = new utl::AccessibleStateSetHelper;
933 if( IsAlive() )
935 if( mbIsChecked )
937 pStateSetHelper->AddState( AccessibleStateType::CHECKED );
938 // pStateSetHelper->AddState( AccessibleStateType::SELECTED );
941 pStateSetHelper->AddState( AccessibleStateType::ENABLED );
942 pStateSetHelper->AddState( AccessibleStateType::SENSITIVE );
943 pStateSetHelper->AddState( AccessibleStateType::OPAQUE );
944 pStateSetHelper->AddState( AccessibleStateType::SELECTABLE );
945 pStateSetHelper->AddState( AccessibleStateType::SHOWING );
946 pStateSetHelper->AddState( AccessibleStateType::VISIBLE );
948 else
949 pStateSetHelper->AddState( AccessibleStateType::DEFUNC );
951 return pStateSetHelper;
954 lang::Locale SAL_CALL SvxRectCtlChildAccessibleContext::getLocale( void ) throw( IllegalAccessibleComponentStateException, RuntimeException )
956 ::osl::MutexGuard aGuard( maMutex );
957 if( mxParent.is() )
959 Reference< XAccessibleContext > xParentContext( mxParent->getAccessibleContext() );
960 if( xParentContext.is() )
961 return xParentContext->getLocale();
964 // No locale and no parent. Therefore throw exception to indicate this
965 // cluelessness.
966 throw IllegalAccessibleComponentStateException();
969 void SAL_CALL SvxRectCtlChildAccessibleContext::addAccessibleEventListener( const Reference< XAccessibleEventListener >& xListener )
970 throw( RuntimeException )
972 if (xListener.is())
974 ::osl::MutexGuard aGuard( maMutex );
975 if (!mnClientId)
976 mnClientId = comphelper::AccessibleEventNotifier::registerClient( );
977 comphelper::AccessibleEventNotifier::addEventListener( mnClientId, xListener );
984 void SAL_CALL SvxRectCtlChildAccessibleContext::removeAccessibleEventListener( const Reference< XAccessibleEventListener >& xListener )
985 throw( RuntimeException )
987 if (xListener.is())
989 ::osl::MutexGuard aGuard( maMutex );
991 sal_Int32 nListenerCount = comphelper::AccessibleEventNotifier::removeEventListener( mnClientId, xListener );
992 if ( !nListenerCount )
994 // no listeners anymore
995 // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client),
996 // and at least to us not firing any events anymore, in case somebody calls
997 // NotifyAccessibleEvent, again
998 comphelper::AccessibleEventNotifier::revokeClient( mnClientId );
999 mnClientId = 0;
1004 //===== XAccessibleValue ================================================
1006 Any SAL_CALL SvxRectCtlChildAccessibleContext::getCurrentValue() throw( RuntimeException )
1008 ThrowExceptionIfNotAlive();
1010 Any aRet;
1011 aRet <<= ( mbIsChecked? 1.0 : 0.0 );
1012 return aRet;
1015 sal_Bool SAL_CALL SvxRectCtlChildAccessibleContext::setCurrentValue( const Any& /*aNumber*/ ) throw( RuntimeException )
1017 return sal_False;
1020 Any SAL_CALL SvxRectCtlChildAccessibleContext::getMaximumValue() throw( RuntimeException )
1022 Any aRet;
1023 aRet <<= 1.0;
1024 return aRet;
1027 Any SAL_CALL SvxRectCtlChildAccessibleContext::getMinimumValue() throw( RuntimeException )
1029 Any aRet;
1030 aRet <<= 0.0;
1031 return aRet;
1034 //===== XServiceInfo ========================================================
1036 OUString SAL_CALL SvxRectCtlChildAccessibleContext::getImplementationName( void ) throw( RuntimeException )
1038 return OUString( "com.sun.star.comp.ui.SvxRectCtlChildAccessibleContext" );
1041 sal_Bool SAL_CALL SvxRectCtlChildAccessibleContext::supportsService( const OUString& sServiceName ) throw( RuntimeException )
1043 // Iterate over all supported service names and return true if on of them
1044 // matches the given name.
1045 ::osl::MutexGuard aGuard( maMutex );
1046 Sequence< OUString > aSupportedServices ( getSupportedServiceNames() );
1047 int nLength = aSupportedServices.getLength();
1048 for( int i = 0 ; i < nLength; ++i )
1050 if( sServiceName == aSupportedServices[ i ] )
1051 return sal_True;
1054 return sal_False;
1057 Sequence< OUString > SAL_CALL SvxRectCtlChildAccessibleContext::getSupportedServiceNames( void ) throw( RuntimeException )
1059 const OUString sServiceName ("com.sun.star.accessibility.AccessibleContext");
1060 return Sequence< OUString >( &sServiceName, 1 );
1063 //===== XTypeProvider =======================================================
1065 Sequence< sal_Int8 > SAL_CALL SvxRectCtlChildAccessibleContext::getImplementationId( void ) throw( RuntimeException )
1067 static OImplementationId* pId = 0;
1068 if( !pId )
1070 MutexGuard aGuard( Mutex::getGlobalMutex() );
1071 if( !pId)
1073 static OImplementationId aId;
1074 pId = &aId;
1077 return pId->getImplementationId();
1080 //===== internal ============================================================
1082 void SvxRectCtlChildAccessibleContext::CommitChange( const AccessibleEventObject& rEvent )
1084 if (mnClientId)
1085 comphelper::AccessibleEventNotifier::addEvent( mnClientId, rEvent );
1088 void SAL_CALL SvxRectCtlChildAccessibleContext::disposing()
1090 if( !rBHelper.bDisposed )
1092 ::osl::MutexGuard aGuard( maMutex );
1094 // Send a disposing to all listeners.
1095 if ( mnClientId )
1097 comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( mnClientId, *this );
1098 mnClientId = 0;
1101 mxParent = Reference< XAccessible >();
1103 delete mpBoundingBox;
1107 void SvxRectCtlChildAccessibleContext::ThrowExceptionIfNotAlive( void ) throw( lang::DisposedException )
1109 if( IsNotAlive() )
1110 throw lang::DisposedException();
1113 Rectangle SvxRectCtlChildAccessibleContext::GetBoundingBoxOnScreen( void ) throw( RuntimeException )
1115 ::osl::MutexGuard aGuard( maMutex );
1117 // no ThrowExceptionIfNotAlive() because its done in GetBoundingBox()
1118 Rectangle aRect( GetBoundingBox() );
1120 return Rectangle( mrParentWindow.OutputToScreenPixel( aRect.TopLeft() ), aRect.GetSize() );
1123 Rectangle SvxRectCtlChildAccessibleContext::GetBoundingBox( void ) throw( RuntimeException )
1125 // no guard necessary, because no one changes mpBoundingBox after creating it
1126 ThrowExceptionIfNotAlive();
1128 return *mpBoundingBox;
1131 void SvxRectCtlChildAccessibleContext::setStateChecked( bool bChecked )
1133 if( mbIsChecked != bChecked )
1135 mbIsChecked = bChecked;
1137 const Reference< XInterface > xSource( *this );
1139 Any aOld;
1140 Any aNew;
1141 Any& rMod = bChecked? aNew : aOld;
1143 rMod <<= AccessibleStateType::CHECKED;
1145 CommitChange( AccessibleEventObject( xSource, AccessibleEventId::STATE_CHANGED, aNew, aOld ) );
1149 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */