xref: /trunk/main/accessibility/source/extended/accessibleiconchoicectrlentry.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_accessibility.hxx"
30 #include <accessibility/extended/accessibleiconchoicectrlentry.hxx>
31 #include <svtools/ivctrl.hxx>
32 #include <com/sun/star/awt/Point.hpp>
33 #include <com/sun/star/awt/Rectangle.hpp>
34 #include <com/sun/star/awt/Size.hpp>
35 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
36 #include <com/sun/star/accessibility/AccessibleRole.hpp>
37 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
38 #include <tools/debug.hxx>
39 #include <vcl/svapp.hxx>
40 #include <vcl/controllayout.hxx>
41 #include <toolkit/awt/vclxwindow.hxx>
42 #include <toolkit/helper/convert.hxx>
43 #include <unotools/accessiblestatesethelper.hxx>
44 #include <unotools/accessiblerelationsethelper.hxx>
45 #include <cppuhelper/typeprovider.hxx>
46 #include <comphelper/sequence.hxx>
47 #include <svtools/stringtransfer.hxx>
48 #include <comphelper/accessibleeventnotifier.hxx>
49 
50 #define ACCESSIBLE_ACTION_COUNT     1
51 #define AID_EXPAND                  0
52 #define AID_COLLAPSE                1
53 
54 namespace
55 {
56     void checkActionIndex_Impl( sal_Int32 _nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException)
57     {
58         if ( _nIndex < 0 || _nIndex >= ACCESSIBLE_ACTION_COUNT )
59             // only three actions
60             throw ::com::sun::star::lang::IndexOutOfBoundsException();
61     }
62 }
63 
64 //........................................................................
65 namespace accessibility
66 {
67     //........................................................................
68     // class ALBSolarGuard ---------------------------------------------------------
69 
70     /** Aquire the solar mutex. */
71     class ALBSolarGuard : public ::vos::OGuard
72     {
73     public:
74         inline ALBSolarGuard() : ::vos::OGuard( Application::GetSolarMutex() ) {}
75     };
76 
77     // class AccessibleIconChoiceCtrlEntry -----------------------------------------------------
78 
79     using namespace ::com::sun::star::accessibility;
80     using namespace ::com::sun::star::uno;
81     using namespace ::com::sun::star::lang;
82     using namespace ::com::sun::star;
83 
84     DBG_NAME(AccessibleIconChoiceCtrlEntry)
85 
86     // -----------------------------------------------------------------------------
87     // Ctor() and Dtor()
88     // -----------------------------------------------------------------------------
89     AccessibleIconChoiceCtrlEntry::AccessibleIconChoiceCtrlEntry( SvtIconChoiceCtrl& _rIconCtrl,
90                                                                   sal_uLong _nPos,
91                                                                   const Reference< XAccessible >& _xParent ) :
92 
93         AccessibleIconChoiceCtrlEntry_BASE  ( m_aMutex ),
94 
95         m_pIconCtrl     ( &_rIconCtrl ),
96         m_nIndex        ( _nPos ),
97         m_nClientId     ( 0 ),
98         m_xParent       ( _xParent )
99 
100     {
101         osl_incrementInterlockedCount( &m_refCount );
102         {
103             Reference< XComponent > xComp( m_xParent, UNO_QUERY );
104             if ( xComp.is() )
105                 xComp->addEventListener( this );
106         }
107         osl_decrementInterlockedCount( &m_refCount );
108 
109         DBG_CTOR( AccessibleIconChoiceCtrlEntry, NULL );
110     }
111     // -----------------------------------------------------------------------------
112     void AccessibleIconChoiceCtrlEntry::disposing( const EventObject& _rSource )
113 throw(RuntimeException)
114     {
115         if ( _rSource.Source == m_xParent )
116         {
117             dispose();
118             DBG_ASSERT( !m_xParent.is() && ( NULL == m_pIconCtrl ), "" );
119         }
120     }
121     // -----------------------------------------------------------------------------
122     AccessibleIconChoiceCtrlEntry::~AccessibleIconChoiceCtrlEntry()
123     {
124         DBG_DTOR( AccessibleIconChoiceCtrlEntry, NULL );
125 
126         if ( IsAlive_Impl() )
127         {
128             // increment ref count to prevent double call of Dtor
129             osl_incrementInterlockedCount( &m_refCount );
130             dispose();
131         }
132     }
133     #ifdef ACCESSIBLE_EVENT_NOTIFICATION_ENABLED
134     // (the following method is unused currently. If you need it, simply remove the #ifdef thing here and
135     // in the hxx)
136     // -----------------------------------------------------------------------------
137     void AccessibleIconChoiceCtrlEntry::NotifyAccessibleEvent( sal_Int16 _nEventId,
138                                                 const ::com::sun::star::uno::Any& _aOldValue,
139                                                 const ::com::sun::star::uno::Any& _aNewValue )
140     {
141         Reference< uno::XInterface > xSource( *this );
142         AccessibleEventObject aEventObj( xSource, _nEventId, _aNewValue, _aOldValue );
143 
144         if (m_nClientId)
145             comphelper::AccessibleEventNotifier::addEvent( m_nClientId, aEventObj );
146     }
147     #endif
148     // -----------------------------------------------------------------------------
149     Rectangle AccessibleIconChoiceCtrlEntry::GetBoundingBox_Impl() const
150     {
151         Rectangle aRect;
152         SvxIconChoiceCtrlEntry* pEntry = m_pIconCtrl->GetEntry( m_nIndex );
153         if ( pEntry )
154             aRect = m_pIconCtrl->GetBoundingBox( pEntry );
155 
156         return aRect;
157     }
158     // -----------------------------------------------------------------------------
159     Rectangle AccessibleIconChoiceCtrlEntry::GetBoundingBoxOnScreen_Impl() const
160     {
161         Rectangle aRect;
162         SvxIconChoiceCtrlEntry* pEntry = m_pIconCtrl->GetEntry( m_nIndex );
163         if ( pEntry )
164         {
165             aRect = m_pIconCtrl->GetBoundingBox( pEntry );
166             Point aTopLeft = aRect.TopLeft();
167             aTopLeft += m_pIconCtrl->GetWindowExtentsRelative( NULL ).TopLeft();
168             aRect = Rectangle( aTopLeft, aRect.GetSize() );
169         }
170 
171         return aRect;
172     }
173     // -----------------------------------------------------------------------------
174     sal_Bool AccessibleIconChoiceCtrlEntry::IsAlive_Impl() const
175     {
176         return ( !rBHelper.bDisposed && !rBHelper.bInDispose && m_pIconCtrl );
177     }
178     // -----------------------------------------------------------------------------
179     sal_Bool AccessibleIconChoiceCtrlEntry::IsShowing_Impl() const
180     {
181         sal_Bool bShowing = sal_False;
182         Reference< XAccessibleContext > m_xParentContext =
183             m_xParent.is() ? m_xParent->getAccessibleContext() : Reference< XAccessibleContext >();
184         if( m_xParentContext.is() )
185         {
186             Reference< XAccessibleComponent > xParentComp( m_xParentContext, uno::UNO_QUERY );
187             if( xParentComp.is() )
188                 bShowing = GetBoundingBox_Impl().IsOver( VCLRectangle( xParentComp->getBounds() ) );
189         }
190 
191         return bShowing;
192     }
193     // -----------------------------------------------------------------------------
194     Rectangle AccessibleIconChoiceCtrlEntry::GetBoundingBox() throw ( lang::DisposedException )
195     {
196         ALBSolarGuard aSolarGuard;
197         ::osl::MutexGuard aGuard( m_aMutex );
198 
199         EnsureIsAlive();
200         return GetBoundingBox_Impl();
201     }
202     // -----------------------------------------------------------------------------
203     Rectangle AccessibleIconChoiceCtrlEntry::GetBoundingBoxOnScreen() throw ( lang::DisposedException )
204     {
205         ALBSolarGuard aSolarGuard;
206         ::osl::MutexGuard aGuard( m_aMutex );
207 
208         EnsureIsAlive();
209         return GetBoundingBoxOnScreen_Impl();
210     }
211     // -----------------------------------------------------------------------------
212     void AccessibleIconChoiceCtrlEntry::EnsureIsAlive() const throw ( lang::DisposedException )
213     {
214         if ( !IsAlive_Impl() )
215             throw lang::DisposedException();
216     }
217     // -----------------------------------------------------------------------------
218     ::rtl::OUString AccessibleIconChoiceCtrlEntry::implGetText()
219     {
220         ::rtl::OUString sRet;
221         SvxIconChoiceCtrlEntry* pEntry = m_pIconCtrl->GetEntry( m_nIndex );
222         if ( pEntry )
223             sRet = pEntry->GetDisplayText();
224         return sRet;
225     }
226     // -----------------------------------------------------------------------------
227     Locale AccessibleIconChoiceCtrlEntry::implGetLocale()
228     {
229         Locale aLocale;
230         aLocale = Application::GetSettings().GetUILocale();
231 
232         return aLocale;
233     }
234     void AccessibleIconChoiceCtrlEntry::implGetSelection( sal_Int32& nStartIndex, sal_Int32& nEndIndex )
235     {
236         nStartIndex = 0;
237         nEndIndex = 0;
238     }
239     // -----------------------------------------------------------------------------
240     // XTypeProvider
241     // -----------------------------------------------------------------------------
242     // -----------------------------------------------------------------------------
243     Sequence< sal_Int8 > AccessibleIconChoiceCtrlEntry::getImplementationId() throw (RuntimeException)
244     {
245         static ::cppu::OImplementationId* pId = NULL;
246 
247         if ( !pId )
248         {
249             ::osl::Guard< ::osl::Mutex > aGuard( m_aMutex );
250 
251             if ( !pId )
252             {
253                 static ::cppu::OImplementationId aId;
254                 pId = &aId;
255             }
256         }
257         return pId->getImplementationId();
258     }
259     // -----------------------------------------------------------------------------
260     // XComponent
261     // -----------------------------------------------------------------------------
262     void SAL_CALL AccessibleIconChoiceCtrlEntry::disposing()
263     {
264         ::osl::MutexGuard aGuard( m_aMutex );
265 
266         // Send a disposing to all listeners.
267         if ( m_nClientId )
268         {
269             sal_uInt32 nId = m_nClientId;
270             m_nClientId =  0;
271             comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( nId, *this );
272         }
273 
274         Reference< XComponent > xComp( m_xParent, UNO_QUERY );
275         if ( xComp.is() )
276             xComp->removeEventListener( this );
277 
278         m_pIconCtrl = NULL;
279         m_xParent = NULL;
280     }
281     // -----------------------------------------------------------------------------
282     // XServiceInfo
283     // -----------------------------------------------------------------------------
284     ::rtl::OUString SAL_CALL AccessibleIconChoiceCtrlEntry::getImplementationName() throw(RuntimeException)
285     {
286         return getImplementationName_Static();
287     }
288     // -----------------------------------------------------------------------------
289     Sequence< ::rtl::OUString > SAL_CALL AccessibleIconChoiceCtrlEntry::getSupportedServiceNames() throw(RuntimeException)
290     {
291         return getSupportedServiceNames_Static();
292     }
293     // -----------------------------------------------------------------------------
294     sal_Bool SAL_CALL AccessibleIconChoiceCtrlEntry::supportsService( const ::rtl::OUString& _rServiceName ) throw (RuntimeException)
295     {
296         Sequence< ::rtl::OUString > aSupported( getSupportedServiceNames() );
297         const ::rtl::OUString* pSupported = aSupported.getConstArray();
298         const ::rtl::OUString* pEnd = pSupported + aSupported.getLength();
299         for ( ; pSupported != pEnd && !pSupported->equals(_rServiceName); ++pSupported )
300             ;
301 
302         return pSupported != pEnd;
303     }
304     // -----------------------------------------------------------------------------
305     // XServiceInfo - static methods
306     // -----------------------------------------------------------------------------
307     Sequence< ::rtl::OUString > AccessibleIconChoiceCtrlEntry::getSupportedServiceNames_Static(void) throw( RuntimeException )
308     {
309         Sequence< ::rtl::OUString > aSupported(3);
310         aSupported[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.accessibility.AccessibleContext") );
311         aSupported[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.accessibility.AccessibleComponent") );
312         aSupported[2] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.AccessibleIconChoiceControlEntry") );
313         return aSupported;
314     }
315     // -----------------------------------------------------------------------------
316     ::rtl::OUString AccessibleIconChoiceCtrlEntry::getImplementationName_Static(void) throw( RuntimeException )
317     {
318         return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.svtools.AccessibleIconChoiceControlEntry") );
319     }
320     // -----------------------------------------------------------------------------
321     // XAccessible
322     // -----------------------------------------------------------------------------
323     Reference< XAccessibleContext > SAL_CALL AccessibleIconChoiceCtrlEntry::getAccessibleContext(  ) throw (RuntimeException)
324     {
325         EnsureIsAlive();
326         return this;
327     }
328     // -----------------------------------------------------------------------------
329     // XAccessibleContext
330     // -----------------------------------------------------------------------------
331     sal_Int32 SAL_CALL AccessibleIconChoiceCtrlEntry::getAccessibleChildCount(  ) throw (RuntimeException)
332     {
333         return 0; // no children
334     }
335     // -----------------------------------------------------------------------------
336     Reference< XAccessible > SAL_CALL AccessibleIconChoiceCtrlEntry::getAccessibleChild( sal_Int32 ) throw (IndexOutOfBoundsException,RuntimeException)
337     {
338         throw IndexOutOfBoundsException();
339     }
340     // -----------------------------------------------------------------------------
341     Reference< XAccessible > SAL_CALL AccessibleIconChoiceCtrlEntry::getAccessibleParent(  ) throw (RuntimeException)
342     {
343         ::osl::MutexGuard aGuard( m_aMutex );
344 
345         EnsureIsAlive();
346         return m_xParent;
347     }
348     // -----------------------------------------------------------------------------
349     sal_Int32 SAL_CALL AccessibleIconChoiceCtrlEntry::getAccessibleIndexInParent(  ) throw (RuntimeException)
350     {
351         ::osl::MutexGuard aGuard( m_aMutex );
352 
353         return m_nIndex;
354     }
355     // -----------------------------------------------------------------------------
356     sal_Int16 SAL_CALL AccessibleIconChoiceCtrlEntry::getAccessibleRole(  ) throw (RuntimeException)
357     {
358         return AccessibleRole::LABEL;
359     }
360     // -----------------------------------------------------------------------------
361     ::rtl::OUString SAL_CALL AccessibleIconChoiceCtrlEntry::getAccessibleDescription(  ) throw (RuntimeException)
362     {
363         // no description for every item
364         return ::rtl::OUString();
365     }
366     // -----------------------------------------------------------------------------
367     ::rtl::OUString SAL_CALL AccessibleIconChoiceCtrlEntry::getAccessibleName(  ) throw (RuntimeException)
368     {
369         ::osl::MutexGuard aGuard( m_aMutex );
370 
371         EnsureIsAlive();
372         return implGetText();
373     }
374     // -----------------------------------------------------------------------------
375     Reference< XAccessibleRelationSet > SAL_CALL AccessibleIconChoiceCtrlEntry::getAccessibleRelationSet(  ) throw (RuntimeException)
376     {
377         return new utl::AccessibleRelationSetHelper;
378     }
379     // -----------------------------------------------------------------------------
380     Reference< XAccessibleStateSet > SAL_CALL AccessibleIconChoiceCtrlEntry::getAccessibleStateSet(  ) throw (RuntimeException)
381     {
382         ALBSolarGuard aSolarGuard;
383         ::osl::MutexGuard aGuard( m_aMutex );
384 
385         utl::AccessibleStateSetHelper* pStateSetHelper = new utl::AccessibleStateSetHelper;
386         Reference< XAccessibleStateSet > xStateSet = pStateSetHelper;
387 
388         if ( IsAlive_Impl() )
389         {
390             pStateSetHelper->AddState( AccessibleStateType::TRANSIENT );
391             pStateSetHelper->AddState( AccessibleStateType::SELECTABLE );
392             pStateSetHelper->AddState( AccessibleStateType::ENABLED );
393             pStateSetHelper->AddState( AccessibleStateType::SENSITIVE );
394             if ( IsShowing_Impl() )
395             {
396                 pStateSetHelper->AddState( AccessibleStateType::SHOWING );
397                 pStateSetHelper->AddState( AccessibleStateType::VISIBLE );
398             }
399 
400             if ( m_pIconCtrl && m_pIconCtrl->GetCursor() == m_pIconCtrl->GetEntry( m_nIndex ) )
401                 pStateSetHelper->AddState( AccessibleStateType::SELECTED );
402         }
403         else
404             pStateSetHelper->AddState( AccessibleStateType::DEFUNC );
405 
406         return xStateSet;
407     }
408     // -----------------------------------------------------------------------------
409     Locale SAL_CALL AccessibleIconChoiceCtrlEntry::getLocale(  ) throw (IllegalAccessibleComponentStateException, RuntimeException)
410     {
411         ALBSolarGuard aSolarGuard;
412         ::osl::MutexGuard aGuard( m_aMutex );
413 
414         return implGetLocale();
415     }
416     // -----------------------------------------------------------------------------
417     // XAccessibleComponent
418     // -----------------------------------------------------------------------------
419     sal_Bool SAL_CALL AccessibleIconChoiceCtrlEntry::containsPoint( const awt::Point& rPoint ) throw (RuntimeException)
420     {
421         return Rectangle( Point(), GetBoundingBox().GetSize() ).IsInside( VCLPoint( rPoint ) );
422     }
423     // -----------------------------------------------------------------------------
424     Reference< XAccessible > SAL_CALL AccessibleIconChoiceCtrlEntry::getAccessibleAtPoint( const awt::Point& ) throw (RuntimeException)
425     {
426         return Reference< XAccessible >();
427     }
428     // -----------------------------------------------------------------------------
429     awt::Rectangle SAL_CALL AccessibleIconChoiceCtrlEntry::getBounds(  ) throw (RuntimeException)
430     {
431         return AWTRectangle( GetBoundingBox() );
432     }
433     // -----------------------------------------------------------------------------
434     awt::Point SAL_CALL AccessibleIconChoiceCtrlEntry::getLocation(  ) throw (RuntimeException)
435     {
436         return AWTPoint( GetBoundingBox().TopLeft() );
437     }
438     // -----------------------------------------------------------------------------
439     awt::Point SAL_CALL AccessibleIconChoiceCtrlEntry::getLocationOnScreen(  ) throw (RuntimeException)
440     {
441         return AWTPoint( GetBoundingBoxOnScreen().TopLeft() );
442     }
443     // -----------------------------------------------------------------------------
444     awt::Size SAL_CALL AccessibleIconChoiceCtrlEntry::getSize(  ) throw (RuntimeException)
445     {
446         return AWTSize( GetBoundingBox().GetSize() );
447     }
448     // -----------------------------------------------------------------------------
449     void SAL_CALL AccessibleIconChoiceCtrlEntry::grabFocus(  ) throw (RuntimeException)
450     {
451         // do nothing, because no focus for each item
452     }
453     // -----------------------------------------------------------------------------
454     sal_Int32 AccessibleIconChoiceCtrlEntry::getForeground( ) throw (RuntimeException)
455     {
456         ALBSolarGuard aSolarGuard;
457         ::osl::MutexGuard aGuard( m_aMutex );
458 
459         sal_Int32 nColor = 0;
460         Reference< XAccessible > xParent = getAccessibleParent();
461         if ( xParent.is() )
462         {
463             Reference< XAccessibleComponent > xParentComp( xParent->getAccessibleContext(), UNO_QUERY );
464             if ( xParentComp.is() )
465                 nColor = xParentComp->getForeground();
466         }
467 
468         return nColor;
469     }
470     // -----------------------------------------------------------------------------
471     sal_Int32 AccessibleIconChoiceCtrlEntry::getBackground(  ) throw (RuntimeException)
472     {
473         ALBSolarGuard aSolarGuard;
474         ::osl::MutexGuard aGuard( m_aMutex );
475 
476         sal_Int32 nColor = 0;
477         Reference< XAccessible > xParent = getAccessibleParent();
478         if ( xParent.is() )
479         {
480             Reference< XAccessibleComponent > xParentComp( xParent->getAccessibleContext(), UNO_QUERY );
481             if ( xParentComp.is() )
482                 nColor = xParentComp->getBackground();
483         }
484 
485         return nColor;
486     }
487     // -----------------------------------------------------------------------------
488     // XAccessibleText
489     // -----------------------------------------------------------------------------
490     // -----------------------------------------------------------------------------
491     awt::Rectangle SAL_CALL AccessibleIconChoiceCtrlEntry::getCharacterBounds( sal_Int32 _nIndex ) throw (IndexOutOfBoundsException, RuntimeException)
492     {
493         ALBSolarGuard aSolarGuard;
494         ::osl::MutexGuard aGuard( m_aMutex );
495 
496         if ( ( 0 > _nIndex ) || ( getCharacterCount() <= _nIndex ) )
497             throw IndexOutOfBoundsException();
498 
499         awt::Rectangle aBounds( 0, 0, 0, 0 );
500         if ( m_pIconCtrl )
501         {
502             Rectangle aItemRect = GetBoundingBox_Impl();
503             Rectangle aCharRect = m_pIconCtrl->GetEntryCharacterBounds( m_nIndex, _nIndex );
504             aCharRect.Move( -aItemRect.Left(), -aItemRect.Top() );
505             aBounds = AWTRectangle( aCharRect );
506         }
507 
508         return aBounds;
509     }
510     // -----------------------------------------------------------------------------
511     sal_Int32 SAL_CALL AccessibleIconChoiceCtrlEntry::getIndexAtPoint( const awt::Point& aPoint ) throw (RuntimeException)
512     {
513         ALBSolarGuard aSolarGuard;
514         ::osl::MutexGuard aGuard( m_aMutex );
515 
516         sal_Int32 nIndex = -1;
517         if ( m_pIconCtrl )
518         {
519             ::vcl::ControlLayoutData aLayoutData;
520             Rectangle aItemRect = GetBoundingBox_Impl();
521             m_pIconCtrl->RecordLayoutData( &aLayoutData, aItemRect );
522             Point aPnt( VCLPoint( aPoint ) );
523             aPnt += aItemRect.TopLeft();
524             nIndex = aLayoutData.GetIndexForPoint( aPnt );
525 
526             long nLen = aLayoutData.m_aUnicodeBoundRects.size();
527             for ( long i = 0; i < nLen; ++i )
528             {
529                 Rectangle aRect = aLayoutData.GetCharacterBounds(i);
530                 sal_Bool bInside = aRect.IsInside( aPnt );
531 
532                 if ( bInside )
533                     break;
534             }
535         }
536 
537         return nIndex;
538     }
539     // -----------------------------------------------------------------------------
540     sal_Bool SAL_CALL AccessibleIconChoiceCtrlEntry::copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (IndexOutOfBoundsException, RuntimeException)
541     {
542         ALBSolarGuard aSolarGuard;
543         ::osl::MutexGuard aGuard( m_aMutex );
544 
545         String sText = getText();
546         if  ( ( 0 > nStartIndex ) || ( sText.Len() <= nStartIndex )
547             || ( 0 > nEndIndex ) || ( sText.Len() <= nEndIndex ) )
548             throw IndexOutOfBoundsException();
549 
550         sal_Int32 nLen = nEndIndex - nStartIndex + 1;
551         ::svt::OStringTransfer::CopyString( sText.Copy( (sal_uInt16)nStartIndex, (sal_uInt16)nLen ), m_pIconCtrl );
552 
553         return sal_True;
554     }
555     // -----------------------------------------------------------------------------
556     // XAccessibleEventBroadcaster
557     // -----------------------------------------------------------------------------
558     void SAL_CALL AccessibleIconChoiceCtrlEntry::addEventListener( const Reference< XAccessibleEventListener >& xListener ) throw (RuntimeException)
559     {
560         if (xListener.is())
561         {
562             ::osl::MutexGuard aGuard( m_aMutex );
563             if (!m_nClientId)
564                 m_nClientId = comphelper::AccessibleEventNotifier::registerClient( );
565             comphelper::AccessibleEventNotifier::addEventListener( m_nClientId, xListener );
566         }
567     }
568     // -----------------------------------------------------------------------------
569     void SAL_CALL AccessibleIconChoiceCtrlEntry::removeEventListener( const Reference< XAccessibleEventListener >& xListener ) throw (RuntimeException)
570     {
571         if (xListener.is())
572         {
573             ::osl::MutexGuard aGuard( m_aMutex );
574 
575             sal_Int32 nListenerCount = comphelper::AccessibleEventNotifier::removeEventListener( m_nClientId, xListener );
576             if ( !nListenerCount )
577             {
578                 // no listeners anymore
579                 // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client),
580                 // and at least to us not firing any events anymore, in case somebody calls
581                 // NotifyAccessibleEvent, again
582                 sal_Int32 nId = m_nClientId;
583                 m_nClientId = 0;
584                 comphelper::AccessibleEventNotifier::revokeClient( nId );
585             }
586         }
587     }
588 
589     sal_Int32 SAL_CALL AccessibleIconChoiceCtrlEntry::getCaretPosition(  ) throw (::com::sun::star::uno::RuntimeException)
590     {
591         return -1;
592     }
593     sal_Bool SAL_CALL AccessibleIconChoiceCtrlEntry::setCaretPosition ( sal_Int32 nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
594     {
595         ALBSolarGuard aSolarGuard;
596         ::osl::MutexGuard aGuard( m_aMutex );
597         EnsureIsAlive();
598 
599         if ( !implIsValidRange( nIndex, nIndex, implGetText().getLength() ) )
600             throw IndexOutOfBoundsException();
601 
602         return sal_False;
603     }
604     sal_Unicode SAL_CALL AccessibleIconChoiceCtrlEntry::getCharacter( sal_Int32 nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
605     {
606         ALBSolarGuard aSolarGuard;
607         ::osl::MutexGuard aGuard( m_aMutex );
608         EnsureIsAlive();
609         return OCommonAccessibleText::getCharacter( nIndex );
610     }
611     ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > SAL_CALL AccessibleIconChoiceCtrlEntry::getCharacterAttributes( sal_Int32 nIndex, const ::com::sun::star::uno::Sequence< ::rtl::OUString >& ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
612     {
613         ALBSolarGuard aSolarGuard;
614         ::osl::MutexGuard aGuard( m_aMutex );
615         EnsureIsAlive();
616 
617         ::rtl::OUString sText( implGetText() );
618 
619         if ( !implIsValidIndex( nIndex, sText.getLength() ) )
620             throw IndexOutOfBoundsException();
621 
622         return ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >();
623     }
624     sal_Int32 SAL_CALL AccessibleIconChoiceCtrlEntry::getCharacterCount(  ) throw (::com::sun::star::uno::RuntimeException)
625     {
626         ALBSolarGuard aSolarGuard;
627         ::osl::MutexGuard aGuard( m_aMutex );
628         EnsureIsAlive();
629         return OCommonAccessibleText::getCharacterCount(  );
630     }
631 
632     ::rtl::OUString SAL_CALL AccessibleIconChoiceCtrlEntry::getSelectedText(  ) throw (::com::sun::star::uno::RuntimeException)
633     {
634         ALBSolarGuard aSolarGuard;
635         ::osl::MutexGuard aGuard( m_aMutex );
636         EnsureIsAlive();
637         return OCommonAccessibleText::getSelectedText(  );
638     }
639     sal_Int32 SAL_CALL AccessibleIconChoiceCtrlEntry::getSelectionStart(  ) throw (::com::sun::star::uno::RuntimeException)
640     {
641         ALBSolarGuard aSolarGuard;
642         ::osl::MutexGuard aGuard( m_aMutex );
643         EnsureIsAlive();
644         return OCommonAccessibleText::getSelectionStart(  );
645     }
646     sal_Int32 SAL_CALL AccessibleIconChoiceCtrlEntry::getSelectionEnd(  ) throw (::com::sun::star::uno::RuntimeException)
647     {
648         ALBSolarGuard aSolarGuard;
649         ::osl::MutexGuard aGuard( m_aMutex );
650         EnsureIsAlive();
651         return OCommonAccessibleText::getSelectionEnd(  );
652     }
653     sal_Bool SAL_CALL AccessibleIconChoiceCtrlEntry::setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
654     {
655         ALBSolarGuard aSolarGuard;
656         ::osl::MutexGuard aGuard( m_aMutex );
657         EnsureIsAlive();
658 
659         if ( !implIsValidRange( nStartIndex, nEndIndex, implGetText().getLength() ) )
660             throw IndexOutOfBoundsException();
661 
662         return sal_False;
663     }
664     ::rtl::OUString SAL_CALL AccessibleIconChoiceCtrlEntry::getText(  ) throw (::com::sun::star::uno::RuntimeException)
665     {
666         ALBSolarGuard aSolarGuard;
667         ::osl::MutexGuard aGuard( m_aMutex );
668         EnsureIsAlive();
669         return OCommonAccessibleText::getText(  );
670     }
671     ::rtl::OUString SAL_CALL AccessibleIconChoiceCtrlEntry::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
672     {
673         ALBSolarGuard aSolarGuard;
674         ::osl::MutexGuard aGuard( m_aMutex );
675         EnsureIsAlive();
676         return OCommonAccessibleText::getTextRange( nStartIndex, nEndIndex );
677     }
678     ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleIconChoiceCtrlEntry::getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
679     {
680         ALBSolarGuard aSolarGuard;
681         ::osl::MutexGuard aGuard( m_aMutex );
682         EnsureIsAlive();
683         return OCommonAccessibleText::getTextAtIndex( nIndex ,aTextType);
684     }
685     ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleIconChoiceCtrlEntry::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
686     {
687         ALBSolarGuard aSolarGuard;
688         ::osl::MutexGuard aGuard( m_aMutex );
689         EnsureIsAlive();
690         return OCommonAccessibleText::getTextBeforeIndex( nIndex ,aTextType);
691     }
692     ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleIconChoiceCtrlEntry::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
693     {
694         ALBSolarGuard aSolarGuard;
695         ::osl::MutexGuard aGuard( m_aMutex );
696         EnsureIsAlive();
697 
698         return OCommonAccessibleText::getTextBehindIndex( nIndex ,aTextType);
699     }
700 
701     // -----------------------------------------------------------------------------
702     // XAccessibleAction
703     // -----------------------------------------------------------------------------
704     sal_Int32 SAL_CALL AccessibleIconChoiceCtrlEntry::getAccessibleActionCount(  ) throw (RuntimeException)
705     {
706         ::osl::MutexGuard aGuard( m_aMutex );
707 
708         // three actions supported
709         return ACCESSIBLE_ACTION_COUNT;
710     }
711     // -----------------------------------------------------------------------------
712     sal_Bool SAL_CALL AccessibleIconChoiceCtrlEntry::doAccessibleAction( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException)
713     {
714         ALBSolarGuard aSolarGuard;
715         ::osl::MutexGuard aGuard( m_aMutex );
716 
717         sal_Bool bRet = sal_False;
718         checkActionIndex_Impl( nIndex );
719         EnsureIsAlive();
720 
721         SvxIconChoiceCtrlEntry* pEntry = m_pIconCtrl->GetEntry( m_nIndex );
722         if ( pEntry && !pEntry->IsSelected() )
723         {
724             m_pIconCtrl->SetNoSelection();
725             m_pIconCtrl->SetCursor( pEntry );
726             bRet = sal_True;
727         }
728 
729         return bRet;
730     }
731     // -----------------------------------------------------------------------------
732     ::rtl::OUString SAL_CALL AccessibleIconChoiceCtrlEntry::getAccessibleActionDescription( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException)
733     {
734         ALBSolarGuard aSolarGuard;
735         ::osl::MutexGuard aGuard( m_aMutex );
736 
737         checkActionIndex_Impl( nIndex );
738         EnsureIsAlive();
739 
740         static const ::rtl::OUString sActionDesc( RTL_CONSTASCII_USTRINGPARAM( "Select" ) );
741         return sActionDesc;
742     }
743     // -----------------------------------------------------------------------------
744     Reference< XAccessibleKeyBinding > AccessibleIconChoiceCtrlEntry::getAccessibleActionKeyBinding( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException)
745     {
746         ::osl::MutexGuard aGuard( m_aMutex );
747 
748         Reference< XAccessibleKeyBinding > xRet;
749         checkActionIndex_Impl( nIndex );
750         // ... which key?
751         return xRet;
752     }
753 //........................................................................
754 }// namespace accessibility
755 //........................................................................
756 
757