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 {
checkActionIndex_Impl(sal_Int32 _nIndex)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 	/** Acquire the solar mutex. */
67 	class ALBSolarGuard : public ::vos::OGuard
68 	{
69 	public:
ALBSolarGuard()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 
DBG_NAME(AccessibleIconChoiceCtrlEntry)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 	// -----------------------------------------------------------------------------
disposing(const EventObject & _rSource)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 	// -----------------------------------------------------------------------------
~AccessibleIconChoiceCtrlEntry()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 	// -----------------------------------------------------------------------------
NotifyAccessibleEvent(sal_Int16 _nEventId,const::com::sun::star::uno::Any & _aOldValue,const::com::sun::star::uno::Any & _aNewValue)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 	// -----------------------------------------------------------------------------
GetBoundingBox_Impl() const145 	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 	// -----------------------------------------------------------------------------
GetBoundingBoxOnScreen_Impl() const155 	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 	// -----------------------------------------------------------------------------
IsAlive_Impl() const170 	sal_Bool AccessibleIconChoiceCtrlEntry::IsAlive_Impl() const
171 	{
172     	return ( !rBHelper.bDisposed && !rBHelper.bInDispose && m_pIconCtrl );
173 	}
174 	// -----------------------------------------------------------------------------
IsShowing_Impl() const175 	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 	// -----------------------------------------------------------------------------
GetBoundingBox()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 	// -----------------------------------------------------------------------------
GetBoundingBoxOnScreen()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 	// -----------------------------------------------------------------------------
EnsureIsAlive() const208 	void AccessibleIconChoiceCtrlEntry::EnsureIsAlive() const throw ( lang::DisposedException )
209 	{
210     	if ( !IsAlive_Impl() )
211         	throw lang::DisposedException();
212 	}
213 	// -----------------------------------------------------------------------------
implGetText()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 	// -----------------------------------------------------------------------------
implGetLocale()223 	Locale AccessibleIconChoiceCtrlEntry::implGetLocale()
224 	{
225     	Locale aLocale;
226 		aLocale = Application::GetSettings().GetUILocale();
227 
228     	return aLocale;
229 	}
implGetSelection(sal_Int32 & nStartIndex,sal_Int32 & nEndIndex)230 	void AccessibleIconChoiceCtrlEntry::implGetSelection( sal_Int32& nStartIndex, sal_Int32& nEndIndex )
231 	{
232 		nStartIndex = 0;
233 		nEndIndex = 0;
234 	}
235 	// -----------------------------------------------------------------------------
236 	// XTypeProvider
237 	// -----------------------------------------------------------------------------
238 	// -----------------------------------------------------------------------------
getImplementationId()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 	// -----------------------------------------------------------------------------
disposing()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 	// -----------------------------------------------------------------------------
getImplementationName()280 	::rtl::OUString SAL_CALL AccessibleIconChoiceCtrlEntry::getImplementationName() throw(RuntimeException)
281 	{
282 		return getImplementationName_Static();
283 	}
284 	// -----------------------------------------------------------------------------
getSupportedServiceNames()285 	Sequence< ::rtl::OUString > SAL_CALL AccessibleIconChoiceCtrlEntry::getSupportedServiceNames() throw(RuntimeException)
286 	{
287 		return getSupportedServiceNames_Static();
288 	}
289 	// -----------------------------------------------------------------------------
supportsService(const::rtl::OUString & _rServiceName)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 	// -----------------------------------------------------------------------------
getSupportedServiceNames_Static(void)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 	// -----------------------------------------------------------------------------
getImplementationName_Static(void)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 	// -----------------------------------------------------------------------------
getAccessibleContext()319 	Reference< XAccessibleContext > SAL_CALL AccessibleIconChoiceCtrlEntry::getAccessibleContext(  ) throw (RuntimeException)
320 	{
321 		EnsureIsAlive();
322 		return this;
323 	}
324 	// -----------------------------------------------------------------------------
325 	// XAccessibleContext
326 	// -----------------------------------------------------------------------------
getAccessibleChildCount()327 	sal_Int32 SAL_CALL AccessibleIconChoiceCtrlEntry::getAccessibleChildCount(  ) throw (RuntimeException)
328 	{
329 		return 0; // no children
330 	}
331 	// -----------------------------------------------------------------------------
getAccessibleChild(sal_Int32)332 	Reference< XAccessible > SAL_CALL AccessibleIconChoiceCtrlEntry::getAccessibleChild( sal_Int32 ) throw (IndexOutOfBoundsException,RuntimeException)
333 	{
334 		throw IndexOutOfBoundsException();
335 	}
336 	// -----------------------------------------------------------------------------
getAccessibleParent()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 	// -----------------------------------------------------------------------------
getAccessibleIndexInParent()345 	sal_Int32 SAL_CALL AccessibleIconChoiceCtrlEntry::getAccessibleIndexInParent(  ) throw (RuntimeException)
346 	{
347 		::osl::MutexGuard aGuard( m_aMutex );
348 
349     	return m_nIndex;
350 	}
351 	// -----------------------------------------------------------------------------
getAccessibleRole()352 	sal_Int16 SAL_CALL AccessibleIconChoiceCtrlEntry::getAccessibleRole(  ) throw (RuntimeException)
353 	{
354 		//return AccessibleRole::LABEL;
355 		return AccessibleRole::LIST_ITEM;
356 	}
357 	// -----------------------------------------------------------------------------
getAccessibleDescription()358 	::rtl::OUString SAL_CALL AccessibleIconChoiceCtrlEntry::getAccessibleDescription(  ) throw (RuntimeException)
359 	{
360 		// no description for every item
361 		return ::rtl::OUString();
362 	}
363 	// -----------------------------------------------------------------------------
getAccessibleName()364 	::rtl::OUString SAL_CALL AccessibleIconChoiceCtrlEntry::getAccessibleName(  ) throw (RuntimeException)
365 	{
366 		::osl::MutexGuard aGuard( m_aMutex );
367 
368 		EnsureIsAlive();
369 		return implGetText();
370 	}
371 	// -----------------------------------------------------------------------------
getAccessibleRelationSet()372 	Reference< XAccessibleRelationSet > SAL_CALL AccessibleIconChoiceCtrlEntry::getAccessibleRelationSet(  ) throw (RuntimeException)
373 	{
374     	return new utl::AccessibleRelationSetHelper;
375 	}
376 	// -----------------------------------------------------------------------------
getAccessibleStateSet()377 	Reference< XAccessibleStateSet > SAL_CALL AccessibleIconChoiceCtrlEntry::getAccessibleStateSet(  ) throw (RuntimeException)
378 	{
379     	ALBSolarGuard aSolarGuard;
380 		::osl::MutexGuard aGuard( m_aMutex );
381 
382     	utl::AccessibleStateSetHelper* pStateSetHelper = new utl::AccessibleStateSetHelper;
383 		Reference< XAccessibleStateSet > xStateSet = pStateSetHelper;
384 
385 		if ( IsAlive_Impl() )
386 		{
387 	       	pStateSetHelper->AddState( AccessibleStateType::TRANSIENT );
388 	       	pStateSetHelper->AddState( AccessibleStateType::SELECTABLE );
389 	       	pStateSetHelper->AddState( AccessibleStateType::ENABLED );
390             pStateSetHelper->AddState( AccessibleStateType::SENSITIVE );
391 			if ( IsShowing_Impl() )
392 			{
393 	        	pStateSetHelper->AddState( AccessibleStateType::SHOWING );
394 				pStateSetHelper->AddState( AccessibleStateType::VISIBLE );
395 			}
396 
397 			if ( m_pIconCtrl && m_pIconCtrl->GetCursor() == m_pIconCtrl->GetEntry( m_nIndex ) )
398 				pStateSetHelper->AddState( AccessibleStateType::SELECTED );
399 		}
400 		else
401         	pStateSetHelper->AddState( AccessibleStateType::DEFUNC );
402 
403     	return xStateSet;
404 	}
405 	// -----------------------------------------------------------------------------
getLocale()406 	Locale SAL_CALL AccessibleIconChoiceCtrlEntry::getLocale(  ) throw (IllegalAccessibleComponentStateException, RuntimeException)
407 	{
408 		ALBSolarGuard aSolarGuard;
409 		::osl::MutexGuard aGuard( m_aMutex );
410 
411 		return implGetLocale();
412 	}
413 	// -----------------------------------------------------------------------------
414 	// XAccessibleComponent
415 	// -----------------------------------------------------------------------------
containsPoint(const awt::Point & rPoint)416 	sal_Bool SAL_CALL AccessibleIconChoiceCtrlEntry::containsPoint( const awt::Point& rPoint ) throw (RuntimeException)
417 	{
418     	return Rectangle( Point(), GetBoundingBox().GetSize() ).IsInside( VCLPoint( rPoint ) );
419 	}
420 	// -----------------------------------------------------------------------------
getAccessibleAtPoint(const awt::Point &)421 	Reference< XAccessible > SAL_CALL AccessibleIconChoiceCtrlEntry::getAccessibleAtPoint( const awt::Point& ) throw (RuntimeException)
422 	{
423 		return Reference< XAccessible >();
424 	}
425 	// -----------------------------------------------------------------------------
getBounds()426 	awt::Rectangle SAL_CALL AccessibleIconChoiceCtrlEntry::getBounds(  ) throw (RuntimeException)
427 	{
428     	return AWTRectangle( GetBoundingBox() );
429 	}
430 	// -----------------------------------------------------------------------------
getLocation()431 	awt::Point SAL_CALL AccessibleIconChoiceCtrlEntry::getLocation(  ) throw (RuntimeException)
432 	{
433     	return AWTPoint( GetBoundingBox().TopLeft() );
434 	}
435 	// -----------------------------------------------------------------------------
getLocationOnScreen()436 	awt::Point SAL_CALL AccessibleIconChoiceCtrlEntry::getLocationOnScreen(  ) throw (RuntimeException)
437 	{
438     	return AWTPoint( GetBoundingBoxOnScreen().TopLeft() );
439 	}
440 	// -----------------------------------------------------------------------------
getSize()441 	awt::Size SAL_CALL AccessibleIconChoiceCtrlEntry::getSize(  ) throw (RuntimeException)
442 	{
443     	return AWTSize( GetBoundingBox().GetSize() );
444 	}
445 	// -----------------------------------------------------------------------------
grabFocus()446 	void SAL_CALL AccessibleIconChoiceCtrlEntry::grabFocus(  ) throw (RuntimeException)
447 	{
448 		// do nothing, because no focus for each item
449 	}
450 	// -----------------------------------------------------------------------------
getForeground()451 	sal_Int32 AccessibleIconChoiceCtrlEntry::getForeground(	) throw (RuntimeException)
452 	{
453     	ALBSolarGuard aSolarGuard;
454 		::osl::MutexGuard aGuard( m_aMutex );
455 
456 		sal_Int32 nColor = 0;
457 		Reference< XAccessible > xParent = getAccessibleParent();
458 		if ( xParent.is() )
459 		{
460 			Reference< XAccessibleComponent > xParentComp( xParent->getAccessibleContext(), UNO_QUERY );
461 			if ( xParentComp.is() )
462 				nColor = xParentComp->getForeground();
463 		}
464 
465 		return nColor;
466 	}
467 	// -----------------------------------------------------------------------------
getBackground()468 	sal_Int32 AccessibleIconChoiceCtrlEntry::getBackground(  ) throw (RuntimeException)
469 	{
470     	ALBSolarGuard aSolarGuard;
471 		::osl::MutexGuard aGuard( m_aMutex );
472 
473 		sal_Int32 nColor = 0;
474 		Reference< XAccessible > xParent = getAccessibleParent();
475 		if ( xParent.is() )
476 		{
477 			Reference< XAccessibleComponent > xParentComp( xParent->getAccessibleContext(), UNO_QUERY );
478 			if ( xParentComp.is() )
479 				nColor = xParentComp->getBackground();
480 		}
481 
482 		return nColor;
483 	}
484 	// -----------------------------------------------------------------------------
485 	// XAccessibleText
486 	// -----------------------------------------------------------------------------
487 	// -----------------------------------------------------------------------------
getCharacterBounds(sal_Int32 _nIndex)488 	awt::Rectangle SAL_CALL AccessibleIconChoiceCtrlEntry::getCharacterBounds( sal_Int32 _nIndex ) throw (IndexOutOfBoundsException, RuntimeException)
489 	{
490 		ALBSolarGuard aSolarGuard;
491 		::osl::MutexGuard aGuard( m_aMutex );
492 
493 		if ( ( 0 > _nIndex ) || ( getCharacterCount() <= _nIndex ) )
494 			throw IndexOutOfBoundsException();
495 
496 		awt::Rectangle aBounds( 0, 0, 0, 0 );
497 		if ( m_pIconCtrl )
498 		{
499 			Rectangle aItemRect = GetBoundingBox_Impl();
500 			Rectangle aCharRect = m_pIconCtrl->GetEntryCharacterBounds( m_nIndex, _nIndex );
501 			aCharRect.Move( -aItemRect.Left(), -aItemRect.Top() );
502 			aBounds = AWTRectangle( aCharRect );
503 		}
504 
505 		return aBounds;
506 	}
507 	// -----------------------------------------------------------------------------
getIndexAtPoint(const awt::Point & aPoint)508 	sal_Int32 SAL_CALL AccessibleIconChoiceCtrlEntry::getIndexAtPoint( const awt::Point& aPoint ) throw (RuntimeException)
509 	{
510 		ALBSolarGuard aSolarGuard;
511 		::osl::MutexGuard aGuard( m_aMutex );
512 
513 		sal_Int32 nIndex = -1;
514 		if ( m_pIconCtrl )
515 		{
516 			::vcl::ControlLayoutData aLayoutData;
517 			Rectangle aItemRect = GetBoundingBox_Impl();
518 			m_pIconCtrl->RecordLayoutData( &aLayoutData, aItemRect );
519 			Point aPnt( VCLPoint( aPoint ) );
520 			aPnt += aItemRect.TopLeft();
521 			nIndex = aLayoutData.GetIndexForPoint( aPnt );
522 
523 			long nLen = aLayoutData.m_aUnicodeBoundRects.size();
524 			for ( long i = 0; i < nLen; ++i )
525 			{
526 			    Rectangle aRect = aLayoutData.GetCharacterBounds(i);
527 				sal_Bool bInside = aRect.IsInside( aPnt );
528 
529 				if ( bInside )
530 					break;
531 			}
532 		}
533 
534 	    return nIndex;
535 	}
536 	// -----------------------------------------------------------------------------
copyText(sal_Int32 nStartIndex,sal_Int32 nEndIndex)537 	sal_Bool SAL_CALL AccessibleIconChoiceCtrlEntry::copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (IndexOutOfBoundsException, RuntimeException)
538 	{
539 		ALBSolarGuard aSolarGuard;
540 		::osl::MutexGuard aGuard( m_aMutex );
541 
542 		String sText = getText();
543 		if	( ( 0 > nStartIndex ) || ( sText.Len() <= nStartIndex )
544 			|| ( 0 > nEndIndex ) || ( sText.Len() <= nEndIndex ) )
545 			throw IndexOutOfBoundsException();
546 
547 		sal_Int32 nLen = nEndIndex - nStartIndex + 1;
548         ::svt::OStringTransfer::CopyString( sText.Copy( (sal_uInt16)nStartIndex, (sal_uInt16)nLen ), m_pIconCtrl );
549 
550 		return sal_True;
551 	}
552 	// -----------------------------------------------------------------------------
553 	// XAccessibleEventBroadcaster
554 	// -----------------------------------------------------------------------------
addEventListener(const Reference<XAccessibleEventListener> & xListener)555 	void SAL_CALL AccessibleIconChoiceCtrlEntry::addEventListener( const Reference< XAccessibleEventListener >& xListener ) throw (RuntimeException)
556 	{
557 	    if (xListener.is())
558         {
559 			::osl::MutexGuard aGuard( m_aMutex );
560 		    if (!m_nClientId)
561                 m_nClientId = comphelper::AccessibleEventNotifier::registerClient( );
562 		    comphelper::AccessibleEventNotifier::addEventListener( m_nClientId, xListener );
563         }
564 	}
565 	// -----------------------------------------------------------------------------
removeEventListener(const Reference<XAccessibleEventListener> & xListener)566 	void SAL_CALL AccessibleIconChoiceCtrlEntry::removeEventListener( const Reference< XAccessibleEventListener >& xListener ) throw (RuntimeException)
567 	{
568 	    if (xListener.is())
569 	    {
570 			::osl::MutexGuard aGuard( m_aMutex );
571 
572             sal_Int32 nListenerCount = comphelper::AccessibleEventNotifier::removeEventListener( m_nClientId, xListener );
573 		    if ( !nListenerCount )
574 		    {
575 			    // no listeners anymore
576 			    // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client),
577 			    // and at least to us not firing any events anymore, in case somebody calls
578 			    // NotifyAccessibleEvent, again
579 				sal_Int32 nId = m_nClientId;
580 				m_nClientId = 0;
581 			    comphelper::AccessibleEventNotifier::revokeClient( nId );
582 		    }
583 	    }
584 	}
585 
getCaretPosition()586 	sal_Int32 SAL_CALL AccessibleIconChoiceCtrlEntry::getCaretPosition(  ) throw (::com::sun::star::uno::RuntimeException)
587 	{
588 		return -1;
589 	}
setCaretPosition(sal_Int32 nIndex)590 	sal_Bool SAL_CALL AccessibleIconChoiceCtrlEntry::setCaretPosition ( sal_Int32 nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
591 	{
592 		ALBSolarGuard aSolarGuard;
593 		::osl::MutexGuard aGuard( m_aMutex );
594 		EnsureIsAlive();
595 
596 		if ( !implIsValidRange( nIndex, nIndex, implGetText().getLength() ) )
597 			throw IndexOutOfBoundsException();
598 
599 		return sal_False;
600 	}
getCharacter(sal_Int32 nIndex)601 	sal_Unicode SAL_CALL AccessibleIconChoiceCtrlEntry::getCharacter( sal_Int32 nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
602 	{
603 		ALBSolarGuard aSolarGuard;
604 		::osl::MutexGuard aGuard( m_aMutex );
605 		EnsureIsAlive();
606 		return OCommonAccessibleText::getCharacter( nIndex );
607 	}
getCharacterAttributes(sal_Int32 nIndex,const::com::sun::star::uno::Sequence<::rtl::OUString> &)608 	::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)
609 	{
610 		ALBSolarGuard aSolarGuard;
611 		::osl::MutexGuard aGuard( m_aMutex );
612 		EnsureIsAlive();
613 
614 		::rtl::OUString sText( implGetText() );
615 
616 		if ( !implIsValidIndex( nIndex, sText.getLength() ) )
617 			throw IndexOutOfBoundsException();
618 
619 		return ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >();
620 	}
getCharacterCount()621 	sal_Int32 SAL_CALL AccessibleIconChoiceCtrlEntry::getCharacterCount(  ) throw (::com::sun::star::uno::RuntimeException)
622 	{
623 		ALBSolarGuard aSolarGuard;
624 		::osl::MutexGuard aGuard( m_aMutex );
625 		EnsureIsAlive();
626 		return OCommonAccessibleText::getCharacterCount(  );
627 	}
628 
getSelectedText()629 	::rtl::OUString SAL_CALL AccessibleIconChoiceCtrlEntry::getSelectedText(  ) throw (::com::sun::star::uno::RuntimeException)
630 	{
631 		ALBSolarGuard aSolarGuard;
632 		::osl::MutexGuard aGuard( m_aMutex );
633 		EnsureIsAlive();
634 		return OCommonAccessibleText::getSelectedText(  );
635 	}
getSelectionStart()636 	sal_Int32 SAL_CALL AccessibleIconChoiceCtrlEntry::getSelectionStart(  ) throw (::com::sun::star::uno::RuntimeException)
637 	{
638 		ALBSolarGuard aSolarGuard;
639 		::osl::MutexGuard aGuard( m_aMutex );
640 		EnsureIsAlive();
641 		return OCommonAccessibleText::getSelectionStart(  );
642 	}
getSelectionEnd()643 	sal_Int32 SAL_CALL AccessibleIconChoiceCtrlEntry::getSelectionEnd(  ) throw (::com::sun::star::uno::RuntimeException)
644 	{
645 		ALBSolarGuard aSolarGuard;
646 		::osl::MutexGuard aGuard( m_aMutex );
647 		EnsureIsAlive();
648 		return OCommonAccessibleText::getSelectionEnd(  );
649 	}
setSelection(sal_Int32 nStartIndex,sal_Int32 nEndIndex)650 	sal_Bool SAL_CALL AccessibleIconChoiceCtrlEntry::setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
651 	{
652 		ALBSolarGuard aSolarGuard;
653 		::osl::MutexGuard aGuard( m_aMutex );
654 		EnsureIsAlive();
655 
656 		if ( !implIsValidRange( nStartIndex, nEndIndex, implGetText().getLength() ) )
657 			throw IndexOutOfBoundsException();
658 
659 		return sal_False;
660 	}
getText()661 	::rtl::OUString SAL_CALL AccessibleIconChoiceCtrlEntry::getText(  ) throw (::com::sun::star::uno::RuntimeException)
662 	{
663 		ALBSolarGuard aSolarGuard;
664 		::osl::MutexGuard aGuard( m_aMutex );
665 		EnsureIsAlive();
666 		return OCommonAccessibleText::getText(  );
667 	}
getTextRange(sal_Int32 nStartIndex,sal_Int32 nEndIndex)668 	::rtl::OUString SAL_CALL AccessibleIconChoiceCtrlEntry::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
669 	{
670 		ALBSolarGuard aSolarGuard;
671 		::osl::MutexGuard aGuard( m_aMutex );
672 		EnsureIsAlive();
673 		return OCommonAccessibleText::getTextRange( nStartIndex, nEndIndex );
674 	}
getTextAtIndex(sal_Int32 nIndex,sal_Int16 aTextType)675     ::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)
676 	{
677 		ALBSolarGuard aSolarGuard;
678 		::osl::MutexGuard aGuard( m_aMutex );
679 		EnsureIsAlive();
680 		return OCommonAccessibleText::getTextAtIndex( nIndex ,aTextType);
681 	}
getTextBeforeIndex(sal_Int32 nIndex,sal_Int16 aTextType)682     ::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)
683 	{
684 		ALBSolarGuard aSolarGuard;
685 		::osl::MutexGuard aGuard( m_aMutex );
686 		EnsureIsAlive();
687 		return OCommonAccessibleText::getTextBeforeIndex( nIndex ,aTextType);
688 	}
getTextBehindIndex(sal_Int32 nIndex,sal_Int16 aTextType)689     ::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)
690 	{
691 		ALBSolarGuard aSolarGuard;
692 		::osl::MutexGuard aGuard( m_aMutex );
693 		EnsureIsAlive();
694 
695 		return OCommonAccessibleText::getTextBehindIndex( nIndex ,aTextType);
696 	}
697 
698     // -----------------------------------------------------------------------------
699     // XAccessibleAction
700     // -----------------------------------------------------------------------------
getAccessibleActionCount()701     sal_Int32 SAL_CALL AccessibleIconChoiceCtrlEntry::getAccessibleActionCount(  ) throw (RuntimeException)
702     {
703         ::osl::MutexGuard aGuard( m_aMutex );
704 
705         // three actions supported
706         return ACCESSIBLE_ACTION_COUNT;
707     }
708     // -----------------------------------------------------------------------------
doAccessibleAction(sal_Int32 nIndex)709     sal_Bool SAL_CALL AccessibleIconChoiceCtrlEntry::doAccessibleAction( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException)
710     {
711         ALBSolarGuard aSolarGuard;
712         ::osl::MutexGuard aGuard( m_aMutex );
713 
714         sal_Bool bRet = sal_False;
715         checkActionIndex_Impl( nIndex );
716         EnsureIsAlive();
717 
718         SvxIconChoiceCtrlEntry* pEntry = m_pIconCtrl->GetEntry( m_nIndex );
719         if ( pEntry && !pEntry->IsSelected() )
720         {
721             m_pIconCtrl->SetNoSelection();
722             m_pIconCtrl->SetCursor( pEntry );
723             bRet = sal_True;
724         }
725 
726         return bRet;
727     }
728     // -----------------------------------------------------------------------------
getAccessibleActionDescription(sal_Int32 nIndex)729     ::rtl::OUString SAL_CALL AccessibleIconChoiceCtrlEntry::getAccessibleActionDescription( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException)
730     {
731         ALBSolarGuard aSolarGuard;
732         ::osl::MutexGuard aGuard( m_aMutex );
733 
734         checkActionIndex_Impl( nIndex );
735         EnsureIsAlive();
736 
737         static const ::rtl::OUString sActionDesc( RTL_CONSTASCII_USTRINGPARAM( "Select" ) );
738         return sActionDesc;
739     }
740     // -----------------------------------------------------------------------------
getAccessibleActionKeyBinding(sal_Int32 nIndex)741     Reference< XAccessibleKeyBinding > AccessibleIconChoiceCtrlEntry::getAccessibleActionKeyBinding( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException)
742     {
743         ::osl::MutexGuard aGuard( m_aMutex );
744 
745         Reference< XAccessibleKeyBinding > xRet;
746         checkActionIndex_Impl( nIndex );
747         // ... which key?
748         return xRet;
749     }
750 //........................................................................
751 }// namespace accessibility
752 //........................................................................
753 
754