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 $
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>
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 ============================================================
76 struct ChildIndexToPointData
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
[] =
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
[] =
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
);
125 // angles are counted reverse counter clock wise
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;
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
;
152 SvxRectCtlAccessibleContext::SvxRectCtlAccessibleContext(
153 const Reference
< XAccessible
>& rxParent
,
155 const ::rtl::OUString
* pName
,
156 const ::rtl::OUString
* pDesc
) :
158 SvxRectCtlAccessibleContext_Base( m_aMutex
),
159 mxParent( rxParent
),
163 mnSelectedChild( NOCHILDSELECTED
),
164 mbAngleMode( rRepr
.GetNumOfChilds() == 8 )
166 DBG_CTOR( SvxRectCtlAccessibleContext
, NULL
);
172 ::vos::OGuard
aSolarGuard( Application::GetSolarMutex() );
173 msName
= SVX_RESSTR( mbAngleMode
? RID_SVXSTR_RECTCTL_ACC_ANGL_NAME
: RID_SVXSTR_RECTCTL_ACC_CORN_NAME
);
177 msDescription
= *pDesc
;
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
)
192 SvxRectCtlAccessibleContext::~SvxRectCtlAccessibleContext()
194 DBG_DTOR( SvxRectCtlAccessibleContext
, NULL
);
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
)
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
);
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
)
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
)
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
];
297 ::vos::OGuard
aSolarGuard( Application::GetSolarMutex() );
299 ::osl::MutexGuard
aGuard( m_aMutex
);
301 ThrowExceptionIfNotAlive();
303 xChild
= mpChilds
[ nIndex
];
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
;
323 if( mnSelectedChild
== nIndex
)
324 pChild
->setStateChecked( sal_True
);
331 Reference
< XAccessible
> SAL_CALL
SvxRectCtlAccessibleContext::getAccessibleParent( void ) throw( RuntimeException
)
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.
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 )
357 // Return -1 to indicate that this object's parent does not know about the
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
);
379 /** Return empty reference to indicate that the relation set is not
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
;
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
);
402 pStateSetHelper
->AddState( AccessibleStateType::SHOWING
);
405 pStateSetHelper
->AddState( AccessibleStateType::VISIBLE
);
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
);
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
)
432 ::osl::MutexGuard
aGuard( m_aMutex
);
434 mnClientId
= comphelper::AccessibleEventNotifier::registerClient( );
435 comphelper::AccessibleEventNotifier::addEventListener( mnClientId
, xListener
);
439 void SAL_CALL
SvxRectCtlAccessibleContext::removeEventListener( const Reference
< XAccessibleEventListener
>& xListener
)
440 throw( RuntimeException
)
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
);
459 void SAL_CALL
SvxRectCtlAccessibleContext::addFocusListener( const Reference
< awt::XFocusListener
>& xListener
)
460 throw( RuntimeException
)
464 ::osl::MutexGuard
aGuard( m_aMutex
);
466 ThrowExceptionIfNotAlive();
468 Reference
< awt::XWindow
> xWindow
= VCLUnoHelper::GetInterface( mpRepr
);
470 xWindow
->addFocusListener( xListener
);
474 void SAL_CALL
SvxRectCtlAccessibleContext::removeFocusListener( const Reference
< awt::XFocusListener
>& xListener
)
475 throw (RuntimeException
)
479 ::osl::MutexGuard
aGuard( m_aMutex
);
481 ThrowExceptionIfNotAlive();
483 Reference
< awt::XWindow
> xWindow
= VCLUnoHelper::GetInterface( mpRepr
);
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();
499 Any SAL_CALL
SvxRectCtlAccessibleContext::getAccessibleKeyBinding() throw( RuntimeException
)
501 // here is no implementation, because here are no KeyBindings for every object
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
)
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
);
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
)
653 SvxRectCtlChildAccessibleContext
* pChild
;
654 if( mnSelectedChild
!= NOCHILDSELECTED
)
655 { // deselect old selected child if one is selected
656 pChild
= mpChilds
[ mnSelectedChild
];
658 pChild
->setStateChecked( sal_False
);
662 mnSelectedChild
= nNew
;
664 if( nNew
!= NOCHILDSELECTED
)
666 pChild
= mpChilds
[ nNew
];
668 pChild
->setStateChecked( sal_True
);
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
);
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
;
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
)
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
;
745 ::osl::MutexGuard
aGuard( m_aMutex
);
747 // Send a disposing to all listeners.
750 comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( mnClientId
, *this );
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;
784 MutexGuard
aGuard( Mutex::getGlobalMutex() );
787 static OImplementationId aId
;
791 return pId
->getImplementationId();
794 void SvxRectCtlAccessibleContext::ThrowExceptionIfNotAlive( void ) throw( lang::DisposedException
)
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
),
818 mpBoundingBox( new Rectangle( rBoundingBox
) ),
819 mrParentWindow( rParentWindow
),
821 mnIndexInParent( nIndexInParent
),
822 mbIsChecked( sal_False
)
824 DBG_CTOR( SvxRectCtlChildAccessibleContext
, NULL
);
828 SvxRectCtlChildAccessibleContext::~SvxRectCtlChildAccessibleContext()
830 DBG_DTOR( SvxRectCtlChildAccessibleContext
, NULL
);
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
)
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
)
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
)
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
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
)
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
)
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
);
981 /** Return empty reference to indicate that the relation set is not
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
;
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
);
1010 pStateSetHelper
->AddState( AccessibleStateType::DEFUNC
);
1012 return pStateSetHelper
;
1015 lang::Locale SAL_CALL
SvxRectCtlChildAccessibleContext::getLocale( void ) throw( IllegalAccessibleComponentStateException
, RuntimeException
)
1017 ::osl::MutexGuard
aGuard( maMutex
);
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
1027 throw IllegalAccessibleComponentStateException();
1030 void SAL_CALL
SvxRectCtlChildAccessibleContext::addEventListener( const Reference
< XAccessibleEventListener
>& xListener
)
1031 throw( RuntimeException
)
1035 ::osl::MutexGuard
aGuard( maMutex
);
1037 mnClientId
= comphelper::AccessibleEventNotifier::registerClient( );
1038 comphelper::AccessibleEventNotifier::addEventListener( mnClientId
, xListener
);
1045 void SAL_CALL
SvxRectCtlChildAccessibleContext::removeEventListener( const Reference
< XAccessibleEventListener
>& xListener
)
1046 throw( RuntimeException
)
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
);
1065 //===== XAccessibleValue ================================================
1067 Any SAL_CALL
SvxRectCtlChildAccessibleContext::getCurrentValue() throw( RuntimeException
)
1069 ThrowExceptionIfNotAlive();
1072 aRet
<<= ( mbIsChecked
? 1.0 : 0.0 );
1076 sal_Bool SAL_CALL
SvxRectCtlChildAccessibleContext::setCurrentValue( const Any
& /*aNumber*/ ) throw( RuntimeException
)
1081 Any SAL_CALL
SvxRectCtlChildAccessibleContext::getMaximumValue() throw( RuntimeException
)
1088 Any SAL_CALL
SvxRectCtlChildAccessibleContext::getMinimumValue() throw( RuntimeException
)
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
] )
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;
1131 MutexGuard
aGuard( Mutex::getGlobalMutex() );
1134 static OImplementationId aId
;
1138 return pId
->getImplementationId();
1141 //===== internal ============================================================
1143 void SvxRectCtlChildAccessibleContext::CommitChange( const AccessibleEventObject
& rEvent
)
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.
1158 comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( mnClientId
, *this );
1162 mxParent
= Reference
< XAccessible
>();
1164 delete mpBoundingBox
;
1168 void SvxRectCtlChildAccessibleContext::ThrowExceptionIfNotAlive( void ) throw( lang::DisposedException
)
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 );
1202 Any
& rMod
= bChecked
? aNew
: aOld
;
1204 rMod
<<= AccessibleStateType::CHECKED
;
1206 CommitChange( AccessibleEventObject( xSource
, AccessibleEventId::STATE_CHANGED
, aNew
, aOld
) );