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