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/accessiblelistboxentry.hxx"
27 #include <svtools/svtreebx.hxx>
28 #include <accessibility/helper/accresmgr.hxx>
29 #include <svtools/stringtransfer.hxx>
30 #include <com/sun/star/awt/Point.hpp>
31 #include <com/sun/star/awt/Rectangle.hpp>
32 #include <com/sun/star/awt/Size.hpp>
33 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
34 #include <com/sun/star/accessibility/AccessibleRelationType.hpp>
35 #include <com/sun/star/accessibility/AccessibleRole.hpp>
36 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
37 #include <tools/debug.hxx>
38 #include <vcl/svapp.hxx>
39 #include <vcl/controllayout.hxx>
40 #include <toolkit/awt/vclxwindow.hxx>
41 #include <toolkit/helper/convert.hxx>
42 #include <unotools/accessiblestatesethelper.hxx>
43 #include <unotools/accessiblerelationsethelper.hxx>
44 #include <cppuhelper/typeprovider.hxx>
45 #include <comphelper/sequence.hxx>
46 #include <comphelper/accessibleeventnotifier.hxx>
47 #include <toolkit/helper/vclunohelper.hxx>
48 #include <accessibility/helper/accessiblestrings.hrc>
49 #ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLEVALUE_HPP_
50 #include <com/sun/star/accessibility/XAccessibleValue.hpp>
51 #endif
52 #define ACCESSIBLE_ACTION_COUNT	1
53 
54 namespace
55 {
checkActionIndex_Impl(sal_Int32 _nIndex)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 	/** Acquire the solar mutex. */
71 	class ALBSolarGuard : public ::vos::OGuard
72 	{
73 	public:
ALBSolarGuard()74     	inline ALBSolarGuard() : ::vos::OGuard( Application::GetSolarMutex() ) {}
75 	};
76 
77 	// class AccessibleListBoxEntry -----------------------------------------------------
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 	using namespace ::comphelper;
DBG_NAME(AccessibleListBoxEntry)84 	DBG_NAME(AccessibleListBoxEntry)
85 
86 	// -----------------------------------------------------------------------------
87 	// Ctor() and Dtor()
88 	// -----------------------------------------------------------------------------
89 	AccessibleListBoxEntry::AccessibleListBoxEntry( SvTreeListBox& _rListBox,
90 													SvLBoxEntry* _pEntry,
91 													const Reference< XAccessible >& _xParent ) :
92 
93 		AccessibleListBoxEntry_BASE	( m_aMutex ),
94 		ListBoxAccessibleBase( _rListBox ),
95 
96 		m_pSvLBoxEntry  ( _pEntry ),
97         m_nClientId     ( 0 ),
98 		m_aParent		( _xParent )
99 
100 	{
101 		DBG_CTOR( AccessibleListBoxEntry, NULL );
102 
103 		_rListBox.FillEntryPath( _pEntry, m_aEntryPath );
104 	}
105 	// -----------------------------------------------------------------------------
~AccessibleListBoxEntry()106 	AccessibleListBoxEntry::~AccessibleListBoxEntry()
107 	{
108 		DBG_DTOR( AccessibleListBoxEntry, NULL );
109 
110 		if ( IsAlive_Impl() )
111 		{
112         	// increment ref count to prevent double call of Dtor
113         	osl_incrementInterlockedCount( &m_refCount );
114         	dispose();
115 		}
116 	}
117 
NotifyAccessibleEvent(sal_Int16 _nEventId,const::com::sun::star::uno::Any & _aOldValue,const::com::sun::star::uno::Any & _aNewValue)118 	void AccessibleListBoxEntry::NotifyAccessibleEvent( sal_Int16 _nEventId,
119 											   	const ::com::sun::star::uno::Any& _aOldValue,
120 											   	const ::com::sun::star::uno::Any& _aNewValue )
121 	{
122         Reference< uno::XInterface > xSource( *this );
123         AccessibleEventObject aEventObj( xSource, _nEventId, _aNewValue, _aOldValue );
124 
125 	    if (m_nClientId)
126 		    comphelper::AccessibleEventNotifier::addEvent( m_nClientId, aEventObj );
127 	}
128 
129 
130 	// -----------------------------------------------------------------------------
GetBoundingBox_Impl() const131 	Rectangle AccessibleListBoxEntry::GetBoundingBox_Impl() const
132 	{
133 		Rectangle aRect;
134 		SvLBoxEntry* pEntry = getListBox()->GetEntryFromPath( m_aEntryPath );
135 		if ( pEntry )
136 		{
137 			aRect = getListBox()->GetBoundingRect( pEntry );
138 			SvLBoxEntry* pParent = getListBox()->GetParent( pEntry );
139 			if ( pParent )
140 			{
141 				// position relative to parent entry
142 				Point aTopLeft = aRect.TopLeft();
143     			aTopLeft -= getListBox()->GetBoundingRect( pParent ).TopLeft();
144 				aRect = Rectangle( aTopLeft, aRect.GetSize() );
145 			}
146 		}
147 
148 		return aRect;
149 	}
150 	// -----------------------------------------------------------------------------
GetBoundingBoxOnScreen_Impl() const151 	Rectangle AccessibleListBoxEntry::GetBoundingBoxOnScreen_Impl() const
152 	{
153 		Rectangle aRect;
154 		SvLBoxEntry* pEntry = getListBox()->GetEntryFromPath( m_aEntryPath );
155 		if ( pEntry )
156 		{
157 			aRect = getListBox()->GetBoundingRect( pEntry );
158 			Point aTopLeft = aRect.TopLeft();
159     		aTopLeft += getListBox()->GetWindowExtentsRelative( NULL ).TopLeft();
160 			aRect = Rectangle( aTopLeft, aRect.GetSize() );
161 		}
162 
163 		return aRect;
164 	}
165 	// -----------------------------------------------------------------------------
IsAlive_Impl() const166 	sal_Bool AccessibleListBoxEntry::IsAlive_Impl() const
167 	{
168     	return ( !rBHelper.bDisposed && !rBHelper.bInDispose && isAlive() );
169 	}
170 	// -----------------------------------------------------------------------------
IsShowing_Impl() const171 	sal_Bool AccessibleListBoxEntry::IsShowing_Impl() const
172 	{
173 		Reference< XAccessible > xParent = implGetParentAccessible( );
174 
175 		sal_Bool bShowing = sal_False;
176 		Reference< XAccessibleContext > m_xParentContext =
177 			xParent.is() ? xParent->getAccessibleContext() : Reference< XAccessibleContext >();
178     	if( m_xParentContext.is() )
179     	{
180         	Reference< XAccessibleComponent > xParentComp( m_xParentContext, uno::UNO_QUERY );
181         	if( xParentComp.is() )
182             	bShowing = GetBoundingBox_Impl().IsOver( VCLRectangle( xParentComp->getBounds() ) );
183     	}
184 
185 		return bShowing;
186 	}
187 	// -----------------------------------------------------------------------------
GetBoundingBox()188 	Rectangle AccessibleListBoxEntry::GetBoundingBox() throw ( lang::DisposedException )
189 	{
190     	ALBSolarGuard aSolarGuard;
191 		::osl::MutexGuard aGuard( m_aMutex );
192 
193 		EnsureIsAlive();
194     	return GetBoundingBox_Impl();
195 	}
196 	// -----------------------------------------------------------------------------
GetBoundingBoxOnScreen()197 	Rectangle AccessibleListBoxEntry::GetBoundingBoxOnScreen() throw ( lang::DisposedException )
198 	{
199     	ALBSolarGuard aSolarGuard;
200 		::osl::MutexGuard aGuard( m_aMutex );
201 
202 		EnsureIsAlive();
203     	return GetBoundingBoxOnScreen_Impl();
204 	}
205 	// -----------------------------------------------------------------------------
EnsureIsAlive() const206 	void AccessibleListBoxEntry::EnsureIsAlive() const throw ( lang::DisposedException )
207 	{
208     	if ( !IsAlive_Impl() )
209         	throw lang::DisposedException();
210 	}
211 	// -----------------------------------------------------------------------------
implGetText()212 	::rtl::OUString AccessibleListBoxEntry::implGetText()
213 	{
214 		::rtl::OUString sRet;
215 		SvLBoxEntry* pEntry = getListBox()->GetEntryFromPath( m_aEntryPath );
216 		if ( pEntry )
217 			sRet = getListBox()->SearchEntryTextWithHeadTitle( pEntry );
218 		return sRet;
219 	}
220 	// -----------------------------------------------------------------------------
implGetLocale()221 	Locale AccessibleListBoxEntry::implGetLocale()
222 	{
223     	Locale aLocale;
224 		aLocale = Application::GetSettings().GetUILocale();
225 
226     	return aLocale;
227 	}
implGetSelection(sal_Int32 & nStartIndex,sal_Int32 & nEndIndex)228 	void AccessibleListBoxEntry::implGetSelection( sal_Int32& nStartIndex, sal_Int32& nEndIndex )
229 	{
230 		nStartIndex = 0;
231 		nEndIndex = 0;
232 	}
233 	// -----------------------------------------------------------------------------
234 	// XTypeProvider
235 	// -----------------------------------------------------------------------------
236 	// -----------------------------------------------------------------------------
getImplementationId()237 	Sequence< sal_Int8 > AccessibleListBoxEntry::getImplementationId() throw (RuntimeException)
238 	{
239 		static ::cppu::OImplementationId* pId = NULL;
240 
241 		if ( !pId )
242 		{
243 			::osl::Guard< ::osl::Mutex > aGuard( m_aMutex );
244 
245 			if ( !pId )
246 			{
247 				static ::cppu::OImplementationId aId;
248 				pId = &aId;
249 			}
250 		}
251 		return pId->getImplementationId();
252 	}
253 
254 	// -----------------------------------------------------------------------------
255 	// XComponent/ListBoxAccessibleBase
256 	// -----------------------------------------------------------------------------
dispose()257 	void SAL_CALL AccessibleListBoxEntry::dispose() throw ( uno::RuntimeException )
258 	{
259 		AccessibleListBoxEntry_BASE::dispose();
260 	}
261 
262 	// -----------------------------------------------------------------------------
263 	// XComponent
264 	// -----------------------------------------------------------------------------
disposing()265 	void SAL_CALL AccessibleListBoxEntry::disposing()
266 	{
267 		ALBSolarGuard();
268 		::osl::MutexGuard aGuard( m_aMutex );
269 
270 		Reference< XAccessible > xKeepAlive( this );
271 
272         // Send a disposing to all listeners.
273 	    if ( m_nClientId )
274 	    {
275 			::comphelper::AccessibleEventNotifier::TClientId nId = m_nClientId;
276 		    m_nClientId =  0;
277             ::comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( nId, *this );
278 	    }
279 
280 		// clean up
281 		{
282 
283 			ListBoxAccessibleBase::disposing();
284 		}
285 	    m_aParent = WeakReference< XAccessible >();
286 	}
287 	// -----------------------------------------------------------------------------
288 	// XServiceInfo
289 	// -----------------------------------------------------------------------------
getImplementationName()290 	::rtl::OUString SAL_CALL AccessibleListBoxEntry::getImplementationName() throw(RuntimeException)
291 	{
292 		return getImplementationName_Static();
293 	}
294 	// -----------------------------------------------------------------------------
getSupportedServiceNames()295 	Sequence< ::rtl::OUString > SAL_CALL AccessibleListBoxEntry::getSupportedServiceNames() throw(RuntimeException)
296 	{
297 		return getSupportedServiceNames_Static();
298 	}
299 	// -----------------------------------------------------------------------------
supportsService(const::rtl::OUString & _rServiceName)300 	sal_Bool SAL_CALL AccessibleListBoxEntry::supportsService( const ::rtl::OUString& _rServiceName ) throw (RuntimeException)
301 	{
302 		Sequence< ::rtl::OUString > aSupported( getSupportedServiceNames() );
303 		const ::rtl::OUString* pSupported = aSupported.getConstArray();
304 		const ::rtl::OUString* pEnd = pSupported + aSupported.getLength();
305 		for ( ; pSupported != pEnd && !pSupported->equals(_rServiceName); ++pSupported )
306 			;
307 
308 		return pSupported != pEnd;
309 	}
310 	// -----------------------------------------------------------------------------
311 	// XServiceInfo - static methods
312 	// -----------------------------------------------------------------------------
getSupportedServiceNames_Static(void)313 	Sequence< ::rtl::OUString > AccessibleListBoxEntry::getSupportedServiceNames_Static(void) throw( RuntimeException )
314 	{
315 		Sequence< ::rtl::OUString > aSupported(3);
316 		aSupported[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.accessibility.AccessibleContext") );
317 		aSupported[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.accessibility.AccessibleComponent") );
318 		aSupported[2] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.AccessibleTreeListBoxEntry") );
319 		return aSupported;
320 	}
321 	// -----------------------------------------------------------------------------
getImplementationName_Static(void)322 	::rtl::OUString AccessibleListBoxEntry::getImplementationName_Static(void) throw( RuntimeException )
323 	{
324 		return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.svtools.AccessibleTreeListBoxEntry") );
325 	}
326 	// -----------------------------------------------------------------------------
327 	// XAccessible
328 	// -----------------------------------------------------------------------------
getAccessibleContext()329 	Reference< XAccessibleContext > SAL_CALL AccessibleListBoxEntry::getAccessibleContext(  ) throw (RuntimeException)
330 	{
331 		EnsureIsAlive();
332 		return this;
333 	}
334 	// -----------------------------------------------------------------------------
335 	// XAccessibleContext
336 	// -----------------------------------------------------------------------------
getAccessibleChildCount()337 	sal_Int32 SAL_CALL AccessibleListBoxEntry::getAccessibleChildCount(  ) throw (RuntimeException)
338 	{
339 		ALBSolarGuard aSolarGuard;
340 		::osl::MutexGuard aGuard( m_aMutex );
341 
342 		EnsureIsAlive();
343 		SvLBoxEntry* pEntry = getListBox()->GetEntryFromPath( m_aEntryPath );
344 		sal_Int32 nCount = 0;
345 		if ( pEntry )
346 			nCount = getListBox()->GetLevelChildCount( pEntry );
347 
348 		return nCount;
349 	}
350 	// -----------------------------------------------------------------------------
getAccessibleChild(sal_Int32 i)351 	Reference< XAccessible > SAL_CALL AccessibleListBoxEntry::getAccessibleChild( sal_Int32 i ) throw (IndexOutOfBoundsException,RuntimeException)
352 	{
353 		ALBSolarGuard aSolarGuard;
354 		::osl::MutexGuard aGuard( m_aMutex );
355 		EnsureIsAlive();
356 
357 //		SvLBoxEntry* pParent = getListBox()->GetEntryFromPath( m_aEntryPath );
358 //		SvLBoxEntry* pEntry = pParent ? getListBox()->GetEntry( pParent, i ) : NULL;
359 		SvLBoxEntry* pEntry =GetRealChild(i);
360 		if ( !pEntry )
361 			throw IndexOutOfBoundsException();
362 
363 		return new AccessibleListBoxEntry( *getListBox(), pEntry, this );
364 	}
365 
366 	// -----------------------------------------------------------------------------
implGetParentAccessible() const367 	Reference< XAccessible > AccessibleListBoxEntry::implGetParentAccessible( ) const
368 	{
369 		Reference< XAccessible > xParent = (Reference< XAccessible >)m_aParent;
370 		if ( !xParent.is() )
371 		{
372 			DBG_ASSERT( m_aEntryPath.size(), "AccessibleListBoxEntry::getAccessibleParent: invalid path!" );
373 			if ( 1 == m_aEntryPath.size() )
374 			{	// we're a top level entry
375 				// -> our parent is the tree listbox itself
376 				if ( getListBox() )
377 					xParent = getListBox()->GetAccessible( );
378 			}
379 			else
380 			{	// we have a entry as parent -> get it's accessible
381 
382 				// shorten our access path by one
383 				::std::deque< sal_Int32 > aParentPath( m_aEntryPath );
384 				aParentPath.pop_back();
385 
386 				// get the entry for this shortened access path
387 				SvLBoxEntry* pParentEntry = getListBox()->GetEntryFromPath( m_aEntryPath );
388 				DBG_ASSERT( pParentEntry, "AccessibleListBoxEntry::implGetParentAccessible: could not obtain a parent entry!" );
389 
390 				if ( pParentEntry )
391 					pParentEntry = getListBox()->GetParent(pParentEntry);
392 				if ( pParentEntry )
393 					xParent = new AccessibleListBoxEntry( *getListBox(), pParentEntry, NULL );
394 					// note that we pass NULL here as parent-accessible:
395 					// this is allowed, as the AccessibleListBoxEntry class will create it's parent
396 					// when needed
397 			}
398 		}
399 
400 		return xParent;
401 	}
402 
403 	// -----------------------------------------------------------------------------
getAccessibleParent()404 	Reference< XAccessible > SAL_CALL AccessibleListBoxEntry::getAccessibleParent(  ) throw (RuntimeException)
405 	{
406     	ALBSolarGuard aSolarGuard;
407 		::osl::MutexGuard aGuard( m_aMutex );
408 		EnsureIsAlive();
409 
410 		return implGetParentAccessible( );
411 	}
412 	// -----------------------------------------------------------------------------
getAccessibleIndexInParent()413 	sal_Int32 SAL_CALL AccessibleListBoxEntry::getAccessibleIndexInParent(  ) throw (RuntimeException)
414 	{
415 		::osl::MutexGuard aGuard( m_aMutex );
416 
417 		DBG_ASSERT( !m_aEntryPath.empty(), "empty path" );
418     	return m_aEntryPath.empty() ? -1 : m_aEntryPath.back();
419 	}
420 	// -----------------------------------------------------------------------------
getRoleType()421 	sal_Int32 SAL_CALL AccessibleListBoxEntry::getRoleType()
422 	{
423 		sal_Int32 nCase = 0;
424 		SvLBoxEntry* pEntry = getListBox()->GetEntry(0);
425 		if ( pEntry )
426 		{
427 			if( pEntry->HasChildsOnDemand() || getListBox()->GetChildCount(pEntry) > 0  )
428 			{
429 				nCase = 1;
430 				return nCase;
431 			}
432 		}
433 
434 		sal_Bool bHasButtons = (getListBox()->GetStyle() & WB_HASBUTTONS)!=0;
435 		if( !(getListBox()->GetTreeFlags() & TREEFLAG_CHKBTN) )
436 		{
437 			if( bHasButtons )
438 				nCase = 1;
439 		}
440 		else
441 		{
442 			if( bHasButtons )
443 				nCase = 2;
444 			 else
445 				nCase = 3;
446 		}
447 		return nCase;
448 	}
getAccessibleRole()449 	sal_Int16 SAL_CALL AccessibleListBoxEntry::getAccessibleRole(  ) throw (RuntimeException)
450 	{
451 		SvTreeListBox* pBox = getListBox();
452 		if(pBox)
453 		{
454 			short nType = pBox->GetAllEntriesAccessibleRoleType();
455 			if( nType == TREEBOX_ALLITEM_ACCROLE_TYPE_TREE)
456 					return AccessibleRole::TREE_ITEM;
457 			else if( nType == TREEBOX_ALLITEM_ACCROLE_TYPE_LIST)
458 					return AccessibleRole::LIST_ITEM;
459 		}
460 
461 		sal_uInt16 treeFlag = pBox->GetTreeFlags();
462 		if(treeFlag & TREEFLAG_CHKBTN )
463 		{
464 			SvLBoxEntry* pEntry = pBox->GetEntryFromPath( m_aEntryPath );
465 			SvButtonState eState = pBox->GetCheckButtonState( pEntry );
466 			switch( eState )
467 			{
468 				case SV_BUTTON_CHECKED:
469 				case SV_BUTTON_UNCHECKED:
470 					return AccessibleRole::CHECK_BOX;
471 				case SV_BUTTON_TRISTATE:
472 				default:
473 					return AccessibleRole::LABEL;
474 			}
475 		}
476 		else
477 		{
478 
479 		if(getRoleType() == 0)
480 			return AccessibleRole::LIST_ITEM;
481 		else
482 			//o is: return AccessibleRole::LABEL;
483 			return AccessibleRole::TREE_ITEM;
484 		}
485 	}
486 	// -----------------------------------------------------------------------------
getAccessibleDescription()487 	::rtl::OUString SAL_CALL AccessibleListBoxEntry::getAccessibleDescription(  ) throw (RuntimeException)
488 	{
489 		// no description for every item
490 		SvLBoxEntry* pEntry = getListBox()->GetEntryFromPath( m_aEntryPath );
491 		if( getAccessibleRole() == AccessibleRole::TREE_ITEM )
492 		{
493 			return getListBox()->GetEntryLongDescription( pEntry );
494 		}
495 		//want to cout the real column number in the list box.
496 		sal_uInt16 iRealItemCount = 0;
497 		sal_uInt16 iCount = 0;
498 		sal_uInt16 iTotleItemCount = pEntry->ItemCount();
499 		SvLBoxItem* pItem;
500 		while( iCount < iTotleItemCount )
501 		{
502 			pItem = pEntry->GetItem( iCount );
503 			if ( pItem->IsA() == SV_ITEM_ID_LBOXSTRING &&
504 				 static_cast<SvLBoxString*>( pItem )->GetText().Len() > 0 )
505 			{
506 				iRealItemCount++;
507 			}
508 			iCount++;
509 		}
510 		if(iRealItemCount<=1  )
511 		{
512 			return ::rtl::OUString();
513 		}
514 		else
515 		{
516 			return getListBox()->SearchEntryTextWithHeadTitle( pEntry );
517 		}
518 
519 	}
520 	// -----------------------------------------------------------------------------
getAccessibleName()521 	::rtl::OUString SAL_CALL AccessibleListBoxEntry::getAccessibleName(  ) throw (RuntimeException)
522 	{
523 		::osl::MutexGuard aGuard( m_aMutex );
524 
525 		EnsureIsAlive();
526 
527 		::rtl::OUString sRet;
528 		sRet = implGetText();
529 
530 		SvLBoxEntry* pEntry = getListBox()->GetEntryFromPath( m_aEntryPath );
531 
532 		String altText = getListBox()->GetEntryAltText( pEntry );
533 		if( altText.Len() > 0 )
534 		{
535 			sRet += ::rtl::OUString(' ');
536 			sRet += altText;
537 		}
538 
539 		// IA2 CWS. Removed for now - only used in Sw/Sd/ScContentLBoxString, they should decide if they need this
540 		// if ( pEntry && pEntry->IsMarked())
541 		//	sRet = sRet + ::rtl::OUString(TK_RES_STRING(STR_SVT_ACC_LISTENTRY_SELCTED_STATE));
542 
543 		return sRet;
544 	}
545 	// -----------------------------------------------------------------------------
getAccessibleRelationSet()546 	Reference< XAccessibleRelationSet > SAL_CALL AccessibleListBoxEntry::getAccessibleRelationSet(  ) throw (RuntimeException)
547 	{
548         Reference< XAccessibleRelationSet > xRelSet;
549         Reference< XAccessible > xParent;
550         if ( m_aEntryPath.size() > 1 ) // not a root entry
551             xParent = implGetParentAccessible();
552         if ( xParent.is() )
553         {
554             utl::AccessibleRelationSetHelper* pRelationSetHelper = new utl::AccessibleRelationSetHelper;
555             Sequence< Reference< XInterface > > aSequence(1);
556             aSequence[0] = xParent;
557             pRelationSetHelper->AddRelation(
558                 AccessibleRelation( AccessibleRelationType::NODE_CHILD_OF, aSequence ) );
559             xRelSet = pRelationSetHelper;
560         }
561         return xRelSet;
562 	}
563 	// -----------------------------------------------------------------------------
getAccessibleStateSet()564 	Reference< XAccessibleStateSet > SAL_CALL AccessibleListBoxEntry::getAccessibleStateSet(  ) throw (RuntimeException)
565 	{
566 		::osl::MutexGuard aGuard( m_aMutex );
567 
568     	utl::AccessibleStateSetHelper* pStateSetHelper = new utl::AccessibleStateSetHelper;
569 		Reference< XAccessibleStateSet > xStateSet = pStateSetHelper;
570 
571 		if ( IsAlive_Impl() )
572 		{
573 			switch(getAccessibleRole())
574 			{
575 				case AccessibleRole::LABEL:
576 			       	pStateSetHelper->AddState( AccessibleStateType::TRANSIENT );
577 			       	pStateSetHelper->AddState( AccessibleStateType::SELECTABLE );
578 			       	pStateSetHelper->AddState( AccessibleStateType::ENABLED );
579 					if ( getListBox()->IsInplaceEditingEnabled() )
580 				       	pStateSetHelper->AddState( AccessibleStateType::EDITABLE );
581 					if ( IsShowing_Impl() )
582 				        	pStateSetHelper->AddState( AccessibleStateType::SHOWING );
583 					break;
584 				case AccessibleRole::CHECK_BOX:
585 			       	pStateSetHelper->AddState( AccessibleStateType::TRANSIENT );
586 			       	pStateSetHelper->AddState( AccessibleStateType::SELECTABLE );
587 			       	pStateSetHelper->AddState( AccessibleStateType::ENABLED );
588 					if ( IsShowing_Impl() )
589 				        	pStateSetHelper->AddState( AccessibleStateType::SHOWING );
590 					break;
591 			}
592 			getListBox()->FillAccessibleEntryStateSet(
593 				getListBox()->GetEntryFromPath( m_aEntryPath ), *pStateSetHelper );
594 		}
595 		else
596         	pStateSetHelper->AddState( AccessibleStateType::DEFUNC );
597 
598     	return xStateSet;
599 	}
600 	// -----------------------------------------------------------------------------
getLocale()601 	Locale SAL_CALL AccessibleListBoxEntry::getLocale(  ) throw (IllegalAccessibleComponentStateException, RuntimeException)
602 	{
603 		ALBSolarGuard aSolarGuard;
604 		::osl::MutexGuard aGuard( m_aMutex );
605 
606 		return implGetLocale();
607 	}
608 	// -----------------------------------------------------------------------------
609 	// XAccessibleComponent
610 	// -----------------------------------------------------------------------------
containsPoint(const awt::Point & rPoint)611 	sal_Bool SAL_CALL AccessibleListBoxEntry::containsPoint( const awt::Point& rPoint ) throw (RuntimeException)
612 	{
613     	return Rectangle( Point(), GetBoundingBox().GetSize() ).IsInside( VCLPoint( rPoint ) );
614 	}
615 	// -----------------------------------------------------------------------------
getAccessibleAtPoint(const awt::Point & _aPoint)616 	Reference< XAccessible > SAL_CALL AccessibleListBoxEntry::getAccessibleAtPoint( const awt::Point& _aPoint ) throw (RuntimeException)
617 	{
618 		ALBSolarGuard aSolarGuard;
619 		::osl::MutexGuard aGuard( m_aMutex );
620 
621 		EnsureIsAlive();
622 		SvLBoxEntry* pEntry = getListBox()->GetEntry( VCLPoint( _aPoint ) );
623 		if ( !pEntry )
624 			throw RuntimeException();
625 
626 		Reference< XAccessible > xAcc;
627 		AccessibleListBoxEntry* pAccEntry = new AccessibleListBoxEntry( *getListBox(), pEntry, this );
628 		Rectangle aRect = pAccEntry->GetBoundingBox_Impl();
629 		if ( aRect.IsInside( VCLPoint( _aPoint ) ) )
630 			xAcc = pAccEntry;
631 		return xAcc;
632 	}
633 	// -----------------------------------------------------------------------------
getBounds()634 	awt::Rectangle SAL_CALL AccessibleListBoxEntry::getBounds(  ) throw (RuntimeException)
635 	{
636     	return AWTRectangle( GetBoundingBox() );
637 	}
638 	// -----------------------------------------------------------------------------
getLocation()639 	awt::Point SAL_CALL AccessibleListBoxEntry::getLocation(  ) throw (RuntimeException)
640 	{
641     	return AWTPoint( GetBoundingBox().TopLeft() );
642 	}
643 	// -----------------------------------------------------------------------------
getLocationOnScreen()644 	awt::Point SAL_CALL AccessibleListBoxEntry::getLocationOnScreen(  ) throw (RuntimeException)
645 	{
646     	return AWTPoint( GetBoundingBoxOnScreen().TopLeft() );
647 	}
648 	// -----------------------------------------------------------------------------
getSize()649 	awt::Size SAL_CALL AccessibleListBoxEntry::getSize(  ) throw (RuntimeException)
650 	{
651     	return AWTSize( GetBoundingBox().GetSize() );
652 	}
653 	// -----------------------------------------------------------------------------
grabFocus()654 	void SAL_CALL AccessibleListBoxEntry::grabFocus(  ) throw (RuntimeException)
655 	{
656 		// do nothing, because no focus for each item
657 	}
658 	// -----------------------------------------------------------------------------
getForeground()659 	sal_Int32 AccessibleListBoxEntry::getForeground(	) throw (RuntimeException)
660 	{
661     	ALBSolarGuard aSolarGuard;
662 		::osl::MutexGuard aGuard( m_aMutex );
663 
664 		sal_Int32 nColor = 0;
665 		Reference< XAccessible > xParent = getAccessibleParent();
666 		if ( xParent.is() )
667 		{
668 			Reference< XAccessibleComponent > xParentComp( xParent->getAccessibleContext(), UNO_QUERY );
669 			if ( xParentComp.is() )
670 				nColor = xParentComp->getForeground();
671 		}
672 
673 		return nColor;
674 	}
675 	// -----------------------------------------------------------------------------
getBackground()676 	sal_Int32 AccessibleListBoxEntry::getBackground(  ) throw (RuntimeException)
677 	{
678     	ALBSolarGuard aSolarGuard;
679 		::osl::MutexGuard aGuard( m_aMutex );
680 
681 		sal_Int32 nColor = 0;
682 		Reference< XAccessible > xParent = getAccessibleParent();
683 		if ( xParent.is() )
684 		{
685 			Reference< XAccessibleComponent > xParentComp( xParent->getAccessibleContext(), UNO_QUERY );
686 			if ( xParentComp.is() )
687 				nColor = xParentComp->getBackground();
688 		}
689 
690 		return nColor;
691 	}
692 	// -----------------------------------------------------------------------------
693 	// XAccessibleText
694 	// -----------------------------------------------------------------------------
695 	// -----------------------------------------------------------------------------
getCharacterBounds(sal_Int32 nIndex)696 	awt::Rectangle SAL_CALL AccessibleListBoxEntry::getCharacterBounds( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException)
697 	{
698     	ALBSolarGuard aSolarGuard;
699 		::osl::MutexGuard aGuard( m_aMutex );
700 
701 		EnsureIsAlive();
702 
703         if ( !implIsValidIndex( nIndex, implGetText().getLength() ) )
704             throw IndexOutOfBoundsException();
705 
706 		awt::Rectangle aBounds( 0, 0, 0, 0 );
707 		SvLBoxEntry* pEntry = getListBox()->GetEntryFromPath( m_aEntryPath );
708 		if ( pEntry )
709 		{
710 			::vcl::ControlLayoutData aLayoutData;
711 			Rectangle aItemRect = GetBoundingBox();
712 			getListBox()->RecordLayoutData( &aLayoutData, aItemRect );
713 			Rectangle aCharRect = aLayoutData.GetCharacterBounds( nIndex );
714 			aCharRect.Move( -aItemRect.Left(), -aItemRect.Top() );
715 			aBounds = AWTRectangle( aCharRect );
716 		}
717 
718 		return aBounds;
719 	}
720 	// -----------------------------------------------------------------------------
getIndexAtPoint(const awt::Point & aPoint)721 	sal_Int32 SAL_CALL AccessibleListBoxEntry::getIndexAtPoint( const awt::Point& aPoint ) throw (RuntimeException)
722 	{
723     	ALBSolarGuard aSolarGuard;
724 		::osl::MutexGuard aGuard( m_aMutex );
725 		EnsureIsAlive();
726 		if(aPoint.X==0 && aPoint.Y==0) return 0;
727 
728 		sal_Int32 nIndex = -1;
729 		SvLBoxEntry* pEntry = getListBox()->GetEntryFromPath( m_aEntryPath );
730 		if ( pEntry )
731 		{
732 			::vcl::ControlLayoutData aLayoutData;
733 			Rectangle aItemRect = GetBoundingBox();
734 			getListBox()->RecordLayoutData( &aLayoutData, aItemRect );
735 			Point aPnt( VCLPoint( aPoint ) );
736 			aPnt += aItemRect.TopLeft();
737 			nIndex = aLayoutData.GetIndexForPoint( aPnt );
738 		}
739 
740 	    return nIndex;
741 	}
742 	// -----------------------------------------------------------------------------
copyText(sal_Int32 nStartIndex,sal_Int32 nEndIndex)743 	sal_Bool SAL_CALL AccessibleListBoxEntry::copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (IndexOutOfBoundsException, RuntimeException)
744 	{
745     	ALBSolarGuard aSolarGuard;
746 		::osl::MutexGuard aGuard( m_aMutex );
747 		EnsureIsAlive();
748 
749 		String sText = getText();
750 		if	( ( 0 > nStartIndex ) || ( sText.Len() <= nStartIndex )
751 			|| ( 0 > nEndIndex ) || ( sText.Len() <= nEndIndex ) )
752 			throw IndexOutOfBoundsException();
753 
754 		sal_Int32 nLen = nEndIndex - nStartIndex + 1;
755         ::svt::OStringTransfer::CopyString( sText.Copy( (sal_uInt16)nStartIndex, (sal_uInt16)nLen ), getListBox() );
756 
757 		return sal_True;
758 	}
759 	// -----------------------------------------------------------------------------
760 	// XAccessibleEventBroadcaster
761 	// -----------------------------------------------------------------------------
addEventListener(const Reference<XAccessibleEventListener> & xListener)762 	void SAL_CALL AccessibleListBoxEntry::addEventListener( const Reference< XAccessibleEventListener >& xListener ) throw (RuntimeException)
763 	{
764 	    if (xListener.is())
765         {
766 			::osl::MutexGuard aGuard( m_aMutex );
767 		    if (!m_nClientId)
768                 m_nClientId = comphelper::AccessibleEventNotifier::registerClient( );
769 		    comphelper::AccessibleEventNotifier::addEventListener( m_nClientId, xListener );
770         }
771 	}
772 	// -----------------------------------------------------------------------------
removeEventListener(const Reference<XAccessibleEventListener> & xListener)773 	void SAL_CALL AccessibleListBoxEntry::removeEventListener( const Reference< XAccessibleEventListener >& xListener ) throw (RuntimeException)
774 	{
775 	    if (xListener.is())
776 	    {
777 			::osl::MutexGuard aGuard( m_aMutex );
778 
779             sal_Int32 nListenerCount = comphelper::AccessibleEventNotifier::removeEventListener( m_nClientId, xListener );
780 		    if ( !nListenerCount )
781 		    {
782 			    // no listeners anymore
783 			    // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client),
784 			    // and at least to us not firing any events anymore, in case somebody calls
785 			    // NotifyAccessibleEvent, again
786 				sal_Int32 nId = m_nClientId;
787 				m_nClientId = 0;
788 			    comphelper::AccessibleEventNotifier::revokeClient( nId );
789 
790 		    }
791 	    }
792 	}
793 	// -----------------------------------------------------------------------------
794 	// XAccessibleAction
795 	// -----------------------------------------------------------------------------
getAccessibleActionCount()796     sal_Int32 SAL_CALL AccessibleListBoxEntry::getAccessibleActionCount(  ) throw (RuntimeException)
797 	{
798 		::osl::MutexGuard aGuard( m_aMutex );
799 
800 		// three actions supported
801 		SvTreeListBox* pBox = getListBox();
802 		sal_uInt16 treeFlag = pBox->GetTreeFlags();
803 		sal_Bool bHasButtons = (getListBox()->GetStyle() & WB_HASBUTTONS)!=0;
804 		if( (treeFlag & TREEFLAG_CHKBTN) && !bHasButtons)
805 		{
806 			sal_Int16 role = getAccessibleRole();
807 			if ( role == AccessibleRole::CHECK_BOX )
808 				return 2;
809 			else if ( role == AccessibleRole::LABEL )
810 				return 0;
811 		}
812 		else
813 			return ACCESSIBLE_ACTION_COUNT;
814 		return 0;
815 	}
816 	// -----------------------------------------------------------------------------
doAccessibleAction(sal_Int32 nIndex)817     sal_Bool SAL_CALL AccessibleListBoxEntry::doAccessibleAction( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException)
818 	{
819     	ALBSolarGuard aSolarGuard;
820 		::osl::MutexGuard aGuard( m_aMutex );
821 
822 		sal_Bool bRet = sal_False;
823 		checkActionIndex_Impl( nIndex );
824 		EnsureIsAlive();
825 		sal_uInt16 treeFlag = getListBox()->GetTreeFlags();
826 		if( nIndex == 0 && (treeFlag & TREEFLAG_CHKBTN) )
827 		{
828 			if(getAccessibleRole() == AccessibleRole::CHECK_BOX)
829 			{
830 				SvLBoxEntry* pEntry = getListBox()->GetEntryFromPath( m_aEntryPath );
831 				SvButtonState state = getListBox()->GetCheckButtonState( pEntry );
832 				if ( state == SV_BUTTON_CHECKED )
833 					getListBox()->SetCheckButtonState(pEntry, (SvButtonState)SV_BMP_UNCHECKED);
834 				else if (state == SV_BMP_UNCHECKED)
835 					getListBox()->SetCheckButtonState(pEntry, (SvButtonState)SV_BUTTON_CHECKED);
836 			}
837 		}else if( (nIndex == 1 && (treeFlag & TREEFLAG_CHKBTN) ) || (nIndex == 0) )
838 		{
839 			SvLBoxEntry* pEntry = getListBox()->GetEntryFromPath( m_aEntryPath );
840 			if ( pEntry )
841 			{
842 				if ( getListBox()->IsExpanded( pEntry ) )
843 					getListBox()->Collapse( pEntry );
844 				else
845 					getListBox()->Expand( pEntry );
846 				bRet = sal_True;
847 			}
848 		}
849 		return bRet;
850 	}
851 	// -----------------------------------------------------------------------------
getAccessibleActionDescription(sal_Int32 nIndex)852     ::rtl::OUString SAL_CALL AccessibleListBoxEntry::getAccessibleActionDescription( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException)
853 	{
854     	ALBSolarGuard aSolarGuard;
855 		::osl::MutexGuard aGuard( m_aMutex );
856 
857 		checkActionIndex_Impl( nIndex );
858 		EnsureIsAlive();
859 
860 		static const ::rtl::OUString sActionDesc( RTL_CONSTASCII_USTRINGPARAM( "toggleExpand" ) );
861 		static const ::rtl::OUString sActionDesc1( RTL_CONSTASCII_USTRINGPARAM( "Check" ) );
862 		static const ::rtl::OUString sActionDesc2( RTL_CONSTASCII_USTRINGPARAM( "UnCheck" ) );
863 		// sal_Bool bHasButtons = (getListBox()->GetStyle() & WB_HASBUTTONS)!=0;
864 		SvLBoxEntry* pEntry = getListBox()->GetEntryFromPath( m_aEntryPath );
865 		SvButtonState state = getListBox()->GetCheckButtonState( pEntry );
866 		sal_uInt16 treeFlag = getListBox()->GetTreeFlags();
867 		if(nIndex == 0 && (treeFlag & TREEFLAG_CHKBTN))
868 		{
869 			if(getAccessibleRole() == AccessibleRole::CHECK_BOX)
870 			{
871 				if ( state == SV_BUTTON_CHECKED )
872 					return sActionDesc2;
873 				else if (state == SV_BMP_UNCHECKED)
874 					return sActionDesc1;
875 			}
876 			else
877 			{
878 				//Sometimes, a List or Tree may have both checkbox and label at the same time
879 				return ::rtl::OUString();
880 			}
881 		}else if( (nIndex == 1 && (treeFlag & TREEFLAG_CHKBTN)) || nIndex == 0 )
882 		{
883 			if( pEntry->HasChilds() || pEntry->HasChildsOnDemand() )
884 				return getListBox()->IsExpanded( pEntry ) ? \
885 				::rtl::OUString(TK_RES_STRING(STR_SVT_ACC_ACTION_COLLAPSE)) :
886 				::rtl::OUString(TK_RES_STRING(STR_SVT_ACC_ACTION_EXPAND));
887 			return ::rtl::OUString();
888 
889 		}
890 		throw IndexOutOfBoundsException();
891 	}
892 	// -----------------------------------------------------------------------------
getAccessibleActionKeyBinding(sal_Int32 nIndex)893 	Reference< XAccessibleKeyBinding > AccessibleListBoxEntry::getAccessibleActionKeyBinding( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException)
894 	{
895 		::osl::MutexGuard aGuard( m_aMutex );
896 
897 		Reference< XAccessibleKeyBinding > xRet;
898 		checkActionIndex_Impl( nIndex );
899 		// ... which key?
900 		return xRet;
901 	}
902 	// -----------------------------------------------------------------------------
903 	// XAccessibleSelection
904 	// -----------------------------------------------------------------------------
selectAccessibleChild(sal_Int32 nChildIndex)905 	void SAL_CALL AccessibleListBoxEntry::selectAccessibleChild( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
906 	{
907     	ALBSolarGuard aSolarGuard;
908 		::osl::MutexGuard aGuard( m_aMutex );
909 
910 		EnsureIsAlive();
911 		SvLBoxEntry* pEntry = GetRealChild(nChildIndex);
912 		if ( !pEntry )
913 			throw IndexOutOfBoundsException();
914 
915 		getListBox()->Select( pEntry, sal_True );
916 	}
917 	// -----------------------------------------------------------------------------
isAccessibleChildSelected(sal_Int32 nChildIndex)918 	sal_Bool SAL_CALL AccessibleListBoxEntry::isAccessibleChildSelected( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
919 	{
920     	ALBSolarGuard aSolarGuard;
921 		::osl::MutexGuard aGuard( m_aMutex );
922 
923 		EnsureIsAlive();
924 
925 		SvLBoxEntry* pParent = getListBox()->GetEntryFromPath( m_aEntryPath );
926 		SvLBoxEntry* pEntry = getListBox()->GetEntry( pParent, nChildIndex );
927 		if ( !pEntry )
928 			throw IndexOutOfBoundsException();
929 
930 		return getListBox()->IsSelected( pEntry );
931 	}
932 	// -----------------------------------------------------------------------------
clearAccessibleSelection()933 	void SAL_CALL AccessibleListBoxEntry::clearAccessibleSelection(  ) throw (RuntimeException)
934 	{
935     	ALBSolarGuard aSolarGuard;
936 		::osl::MutexGuard aGuard( m_aMutex );
937 
938 		EnsureIsAlive();
939 
940 		SvLBoxEntry* pParent = getListBox()->GetEntryFromPath( m_aEntryPath );
941 		if ( !pParent )
942 			throw RuntimeException();
943     	sal_Int32 i, nCount = 0;
944 		nCount = getListBox()->GetLevelChildCount( pParent );
945 		for ( i = 0; i < nCount; ++i )
946 		{
947 			SvLBoxEntry* pEntry = getListBox()->GetEntry( pParent, i );
948 			if ( getListBox()->IsSelected( pEntry ) )
949 				getListBox()->Select( pEntry, sal_False );
950 		}
951 	}
952 	// -----------------------------------------------------------------------------
selectAllAccessibleChildren()953 	void SAL_CALL AccessibleListBoxEntry::selectAllAccessibleChildren(  ) throw (RuntimeException)
954 	{
955     	ALBSolarGuard aSolarGuard;
956 		::osl::MutexGuard aGuard( m_aMutex );
957 
958 		EnsureIsAlive();
959 
960 		SvLBoxEntry* pParent = getListBox()->GetEntryFromPath( m_aEntryPath );
961 		if ( !pParent )
962 			throw RuntimeException();
963     	sal_Int32 i, nCount = 0;
964 		nCount = getListBox()->GetLevelChildCount( pParent );
965 		for ( i = 0; i < nCount; ++i )
966 		{
967 			SvLBoxEntry* pEntry = getListBox()->GetEntry( pParent, i );
968 			if ( !getListBox()->IsSelected( pEntry ) )
969 				getListBox()->Select( pEntry, sal_True );
970 		}
971 	}
972 	// -----------------------------------------------------------------------------
getSelectedAccessibleChildCount()973 	sal_Int32 SAL_CALL AccessibleListBoxEntry::getSelectedAccessibleChildCount(  ) throw (RuntimeException)
974 	{
975     	ALBSolarGuard aSolarGuard;
976 		::osl::MutexGuard aGuard( m_aMutex );
977 
978 		EnsureIsAlive();
979 
980     	sal_Int32 i, nSelCount = 0, nCount = 0;
981 
982 		SvLBoxEntry* pParent = getListBox()->GetEntryFromPath( m_aEntryPath );
983 		if ( !pParent )
984 			throw RuntimeException();
985 		nCount = getListBox()->GetLevelChildCount( pParent );
986 		for ( i = 0; i < nCount; ++i )
987 		{
988 			SvLBoxEntry* pEntry = getListBox()->GetEntry( pParent, i );
989 			if ( getListBox()->IsSelected( pEntry ) )
990 				++nSelCount;
991 		}
992 
993     	return nSelCount;
994 	}
995 	// -----------------------------------------------------------------------------
getSelectedAccessibleChild(sal_Int32 nSelectedChildIndex)996 	Reference< XAccessible > SAL_CALL AccessibleListBoxEntry::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
997 	{
998     	ALBSolarGuard aSolarGuard;
999 		::osl::MutexGuard aGuard( m_aMutex );
1000 
1001 		EnsureIsAlive();
1002 
1003 		if ( nSelectedChildIndex < 0 || nSelectedChildIndex >= getSelectedAccessibleChildCount() )
1004 			throw IndexOutOfBoundsException();
1005 
1006 		Reference< XAccessible > xChild;
1007     	sal_Int32 i, nSelCount = 0, nCount = 0;
1008 
1009 		SvLBoxEntry* pParent = getListBox()->GetEntryFromPath( m_aEntryPath );
1010 		if ( !pParent )
1011 			throw RuntimeException();
1012 		nCount = getListBox()->GetLevelChildCount( pParent );
1013 		for ( i = 0; i < nCount; ++i )
1014 		{
1015 			SvLBoxEntry* pEntry = getListBox()->GetEntry( pParent, i );
1016 			if ( getListBox()->IsSelected( pEntry ) )
1017 				++nSelCount;
1018 
1019 			if ( nSelCount == ( nSelectedChildIndex + 1 ) )
1020 			{
1021 				xChild = new AccessibleListBoxEntry( *getListBox(), pEntry, this );
1022 				break;
1023 			}
1024 		}
1025 
1026 		return xChild;
1027 	}
1028 	// -----------------------------------------------------------------------------
deselectAccessibleChild(sal_Int32 nSelectedChildIndex)1029 	void SAL_CALL AccessibleListBoxEntry::deselectAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
1030 	{
1031     	ALBSolarGuard aSolarGuard;
1032 		::osl::MutexGuard aGuard( m_aMutex );
1033 
1034 		EnsureIsAlive();
1035 
1036 		SvLBoxEntry* pParent = getListBox()->GetEntryFromPath( m_aEntryPath );
1037 		SvLBoxEntry* pEntry = getListBox()->GetEntry( pParent, nSelectedChildIndex );
1038 		if ( !pEntry )
1039 			throw IndexOutOfBoundsException();
1040 
1041 		getListBox()->Select( pEntry, sal_False );
1042 	}
getCaretPosition()1043 	sal_Int32 SAL_CALL AccessibleListBoxEntry::getCaretPosition(  ) throw (::com::sun::star::uno::RuntimeException)
1044 	{
1045 		return -1;
1046 	}
setCaretPosition(sal_Int32 nIndex)1047 	sal_Bool SAL_CALL AccessibleListBoxEntry::setCaretPosition ( sal_Int32 nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
1048 	{
1049 		ALBSolarGuard aSolarGuard;
1050 		::osl::MutexGuard aGuard( m_aMutex );
1051 		EnsureIsAlive();
1052 
1053 		if ( !implIsValidRange( nIndex, nIndex, implGetText().getLength() ) )
1054 			throw IndexOutOfBoundsException();
1055 
1056 		return sal_False;
1057 	}
getCharacter(sal_Int32 nIndex)1058 	sal_Unicode SAL_CALL AccessibleListBoxEntry::getCharacter( sal_Int32 nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
1059 	{
1060 		ALBSolarGuard aSolarGuard;
1061 		::osl::MutexGuard aGuard( m_aMutex );
1062 		EnsureIsAlive();
1063 		return OCommonAccessibleText::getCharacter( nIndex );
1064 	}
getCharacterAttributes(sal_Int32 nIndex,const::com::sun::star::uno::Sequence<::rtl::OUString> &)1065 	::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > SAL_CALL AccessibleListBoxEntry::getCharacterAttributes( sal_Int32 nIndex, const ::com::sun::star::uno::Sequence< ::rtl::OUString >& ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
1066 	{
1067 		ALBSolarGuard aSolarGuard;
1068 		::osl::MutexGuard aGuard( m_aMutex );
1069 		EnsureIsAlive();
1070 
1071 		::rtl::OUString sText( implGetText() );
1072 
1073 		if ( !implIsValidIndex( nIndex, sText.getLength() ) )
1074 			throw IndexOutOfBoundsException();
1075 
1076 		return ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >();
1077 	}
getCharacterCount()1078 	sal_Int32 SAL_CALL AccessibleListBoxEntry::getCharacterCount(  ) throw (::com::sun::star::uno::RuntimeException)
1079 	{
1080 		ALBSolarGuard aSolarGuard;
1081 		::osl::MutexGuard aGuard( m_aMutex );
1082 		EnsureIsAlive();
1083 		return OCommonAccessibleText::getCharacterCount(  );
1084 	}
1085 
getSelectedText()1086 	::rtl::OUString SAL_CALL AccessibleListBoxEntry::getSelectedText(  ) throw (::com::sun::star::uno::RuntimeException)
1087 	{
1088 		ALBSolarGuard aSolarGuard;
1089 		::osl::MutexGuard aGuard( m_aMutex );
1090 		EnsureIsAlive();
1091 		return OCommonAccessibleText::getSelectedText(  );
1092 	}
getSelectionStart()1093 	sal_Int32 SAL_CALL AccessibleListBoxEntry::getSelectionStart(  ) throw (::com::sun::star::uno::RuntimeException)
1094 	{
1095 		ALBSolarGuard aSolarGuard;
1096 		::osl::MutexGuard aGuard( m_aMutex );
1097 		EnsureIsAlive();
1098 		return OCommonAccessibleText::getSelectionStart(  );
1099 	}
getSelectionEnd()1100 	sal_Int32 SAL_CALL AccessibleListBoxEntry::getSelectionEnd(  ) throw (::com::sun::star::uno::RuntimeException)
1101 	{
1102 		ALBSolarGuard aSolarGuard;
1103 		::osl::MutexGuard aGuard( m_aMutex );
1104 		EnsureIsAlive();
1105 		return OCommonAccessibleText::getSelectionEnd(  );
1106 	}
setSelection(sal_Int32 nStartIndex,sal_Int32 nEndIndex)1107 	sal_Bool SAL_CALL AccessibleListBoxEntry::setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
1108 	{
1109 		ALBSolarGuard aSolarGuard;
1110 		::osl::MutexGuard aGuard( m_aMutex );
1111 		EnsureIsAlive();
1112 
1113 		if ( !implIsValidRange( nStartIndex, nEndIndex, implGetText().getLength() ) )
1114 			throw IndexOutOfBoundsException();
1115 
1116 		return sal_False;
1117 	}
getText()1118 	::rtl::OUString SAL_CALL AccessibleListBoxEntry::getText(  ) throw (::com::sun::star::uno::RuntimeException)
1119 	{
1120 		ALBSolarGuard aSolarGuard;
1121 		::osl::MutexGuard aGuard( m_aMutex );
1122 		EnsureIsAlive();
1123 		return OCommonAccessibleText::getText(  );
1124 	}
getTextRange(sal_Int32 nStartIndex,sal_Int32 nEndIndex)1125 	::rtl::OUString SAL_CALL AccessibleListBoxEntry::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
1126 	{
1127 		ALBSolarGuard aSolarGuard;
1128 		::osl::MutexGuard aGuard( m_aMutex );
1129 		EnsureIsAlive();
1130 		return OCommonAccessibleText::getTextRange( nStartIndex, nEndIndex );
1131 	}
getTextAtIndex(sal_Int32 nIndex,sal_Int16 aTextType)1132     ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleListBoxEntry::getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
1133 	{
1134 		ALBSolarGuard aSolarGuard;
1135 		::osl::MutexGuard aGuard( m_aMutex );
1136 		EnsureIsAlive();
1137 		return OCommonAccessibleText::getTextAtIndex( nIndex ,aTextType);
1138 	}
getTextBeforeIndex(sal_Int32 nIndex,sal_Int16 aTextType)1139     ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleListBoxEntry::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
1140 	{
1141 		ALBSolarGuard aSolarGuard;
1142 		::osl::MutexGuard aGuard( m_aMutex );
1143 		EnsureIsAlive();
1144 		return OCommonAccessibleText::getTextBeforeIndex( nIndex ,aTextType);
1145 	}
getTextBehindIndex(sal_Int32 nIndex,sal_Int16 aTextType)1146     ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleListBoxEntry::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
1147 	{
1148 		ALBSolarGuard aSolarGuard;
1149 		::osl::MutexGuard aGuard( m_aMutex );
1150 		EnsureIsAlive();
1151 
1152 		return OCommonAccessibleText::getTextBehindIndex( nIndex ,aTextType);
1153 	}
1154 	// -----------------------------------------------------------------------------
1155 	// XAccessibleValue
1156 	// -----------------------------------------------------------------------------
1157 
getCurrentValue()1158 	Any AccessibleListBoxEntry::getCurrentValue(  ) throw (RuntimeException)
1159 	{
1160 		::osl::MutexGuard aGuard( m_aMutex );
1161 		Any aValue;
1162 		sal_Int32 level = ((sal_Int32) m_aEntryPath.size() - 1);
1163 		level = level < 0 ?  0: level;
1164 		aValue <<= level;
1165 		return aValue;
1166 	}
1167 
1168 	// -----------------------------------------------------------------------------
1169 
setCurrentValue(const Any & aNumber)1170 	sal_Bool AccessibleListBoxEntry::setCurrentValue( const Any& aNumber ) throw (RuntimeException)
1171 	{
1172 		::osl::MutexGuard aGuard( m_aMutex );
1173 
1174 
1175 		sal_Bool bReturn = sal_False;
1176 		SvTreeListBox* pBox = getListBox();
1177 		if(getAccessibleRole() == AccessibleRole::CHECK_BOX)
1178 		{
1179 			SvLBoxEntry* pEntry = pBox->GetEntryFromPath( m_aEntryPath );
1180 			if ( pEntry )
1181 			{
1182 				sal_Int32 nValue(0), nValueMin(0), nValueMax(0);
1183 				aNumber >>= nValue;
1184 				getMinimumValue() >>= nValueMin;
1185 				getMaximumValue() >>= nValueMax;
1186 
1187 				if ( nValue < nValueMin )
1188 					nValue = nValueMin;
1189 				else if ( nValue > nValueMax )
1190 					nValue = nValueMax;
1191 
1192 				pBox->SetCheckButtonState(pEntry,  (SvButtonState) nValue );
1193 				bReturn = sal_True;
1194 			}
1195 		}
1196 
1197 		return bReturn;
1198 	}
1199 
1200 	// -----------------------------------------------------------------------------
1201 
getMaximumValue()1202 	Any AccessibleListBoxEntry::getMaximumValue(  ) throw (RuntimeException)
1203 	{
1204 		::osl::MutexGuard aGuard( m_aMutex );
1205 
1206 		Any aValue;
1207 		// SvTreeListBox* pBox = getListBox();
1208 		switch(getAccessibleRole())
1209 		{
1210 			case AccessibleRole::CHECK_BOX:
1211 				aValue <<= (sal_Int32)1;
1212 				break;
1213 			case AccessibleRole::LABEL:
1214 			default:
1215 				break;
1216 		}
1217 
1218 		return aValue;
1219 	}
1220 
1221 	// -----------------------------------------------------------------------------
1222 
getMinimumValue()1223 	Any AccessibleListBoxEntry::getMinimumValue(  ) throw (RuntimeException)
1224 	{
1225 		::osl::MutexGuard aGuard( m_aMutex );
1226 
1227 		Any aValue;
1228 		// SvTreeListBox* pBox = getListBox();
1229 		switch(getAccessibleRole())
1230 		{
1231 			case AccessibleRole::CHECK_BOX:
1232 				aValue <<= (sal_Int32)0;
1233 				break;
1234 			case AccessibleRole::LABEL:
1235 			default:
1236 				break;
1237 		}
1238 
1239 		return aValue;
1240 	}
1241 
1242 	// -----------------------------------------------------------------------------
1243 
GetRealChild(sal_Int32 nIndex)1244 	SvLBoxEntry * AccessibleListBoxEntry::GetRealChild(sal_Int32 nIndex)
1245 	{
1246 		SvLBoxEntry* pEntry =NULL;
1247 		SvLBoxEntry* pParent = getListBox()->GetEntryFromPath( m_aEntryPath );
1248 		if (pParent)
1249 		{
1250 			pEntry = getListBox()->GetEntry( pParent, nIndex );
1251 			if ( !pEntry && getAccessibleChildCount() > 0 )
1252 			{
1253 				getListBox()->RequestingChilds(pParent);
1254 				pEntry = getListBox()->GetEntry( pParent, nIndex );
1255 			}
1256 		}
1257 		return pEntry;
1258 	}
1259 //........................................................................
1260 }// namespace accessibility
1261 //........................................................................
1262 
1263