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