10841af79SAndrew Rist /**************************************************************
2*aa5a148eSmseidel  *
30841af79SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
40841af79SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
50841af79SAndrew Rist  * distributed with this work for additional information
60841af79SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
70841af79SAndrew Rist  * to you under the Apache License, Version 2.0 (the
80841af79SAndrew Rist  * "License"); you may not use this file except in compliance
90841af79SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*aa5a148eSmseidel  *
110841af79SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*aa5a148eSmseidel  *
130841af79SAndrew Rist  * Unless required by applicable law or agreed to in writing,
140841af79SAndrew Rist  * software distributed under the License is distributed on an
150841af79SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
160841af79SAndrew Rist  * KIND, either express or implied.  See the License for the
170841af79SAndrew Rist  * specific language governing permissions and limitations
180841af79SAndrew Rist  * under the License.
19*aa5a148eSmseidel  *
200841af79SAndrew Rist  *************************************************************/
210841af79SAndrew Rist 
220841af79SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_accessibility.hxx"
26cdf0e10cSrcweir #include <accessibility/extended/accessiblelistbox.hxx>
27cdf0e10cSrcweir #include <accessibility/extended/accessiblelistboxentry.hxx>
28cdf0e10cSrcweir #include <svtools/svtreebx.hxx>
29cdf0e10cSrcweir #include <com/sun/star/awt/Point.hpp>
30cdf0e10cSrcweir #include <com/sun/star/awt/Rectangle.hpp>
31cdf0e10cSrcweir #include <com/sun/star/awt/Size.hpp>
32cdf0e10cSrcweir #include <com/sun/star/accessibility/AccessibleEventId.hpp>
33cdf0e10cSrcweir #include <com/sun/star/accessibility/AccessibleRole.hpp>
34cdf0e10cSrcweir #include <com/sun/star/accessibility/AccessibleStateType.hpp>
35cdf0e10cSrcweir #include <tools/debug.hxx>
36cdf0e10cSrcweir #include <vcl/svapp.hxx>
37cdf0e10cSrcweir #include <toolkit/awt/vclxwindow.hxx>
38cdf0e10cSrcweir #include <toolkit/helper/convert.hxx>
39cdf0e10cSrcweir #include <unotools/accessiblestatesethelper.hxx>
40cdf0e10cSrcweir 
41cdf0e10cSrcweir //........................................................................
42cdf0e10cSrcweir namespace accessibility
43cdf0e10cSrcweir {
44cdf0e10cSrcweir //........................................................................
45cdf0e10cSrcweir 
46cdf0e10cSrcweir 	// class AccessibleListBox -----------------------------------------------------
47cdf0e10cSrcweir 
48cdf0e10cSrcweir 	using namespace ::com::sun::star::accessibility;
49cdf0e10cSrcweir 	using namespace ::com::sun::star::uno;
50cdf0e10cSrcweir 	using namespace ::com::sun::star::lang;
51cdf0e10cSrcweir 	using namespace ::com::sun::star;
52cdf0e10cSrcweir 
DBG_NAME(AccessibleListBox)53cdf0e10cSrcweir 	DBG_NAME(AccessibleListBox)
54cdf0e10cSrcweir 
55cdf0e10cSrcweir 	// -----------------------------------------------------------------------------
56cdf0e10cSrcweir 	// Ctor() and Dtor()
57cdf0e10cSrcweir 	// -----------------------------------------------------------------------------
58cdf0e10cSrcweir 	AccessibleListBox::AccessibleListBox( SvTreeListBox& _rListBox, const Reference< XAccessible >& _xParent ) :
59cdf0e10cSrcweir 
60cdf0e10cSrcweir 		VCLXAccessibleComponent( _rListBox.GetWindowPeer() ),
61cdf0e10cSrcweir 		m_xParent( _xParent )
62cdf0e10cSrcweir 	{
63cdf0e10cSrcweir 		DBG_CTOR( AccessibleListBox, NULL );
64cdf0e10cSrcweir 	}
65cdf0e10cSrcweir 	// -----------------------------------------------------------------------------
~AccessibleListBox()66cdf0e10cSrcweir 	AccessibleListBox::~AccessibleListBox()
67cdf0e10cSrcweir 	{
68cdf0e10cSrcweir 		DBG_DTOR( AccessibleListBox, NULL );
69cdf0e10cSrcweir 		if ( isAlive() )
70cdf0e10cSrcweir 		{
71cdf0e10cSrcweir 			// increment ref count to prevent double call of Dtor
72*aa5a148eSmseidel 			osl_incrementInterlockedCount( &m_refCount );
73*aa5a148eSmseidel 			dispose();
74cdf0e10cSrcweir 		}
75cdf0e10cSrcweir 	}
IMPLEMENT_FORWARD_XINTERFACE2(AccessibleListBox,VCLXAccessibleComponent,AccessibleListBox_BASE)76cdf0e10cSrcweir 	IMPLEMENT_FORWARD_XINTERFACE2(AccessibleListBox, VCLXAccessibleComponent, AccessibleListBox_BASE)
77cdf0e10cSrcweir 	IMPLEMENT_FORWARD_XTYPEPROVIDER2(AccessibleListBox, VCLXAccessibleComponent, AccessibleListBox_BASE)
78cdf0e10cSrcweir 	// -----------------------------------------------------------------------------
79cdf0e10cSrcweir 	SvTreeListBox* AccessibleListBox::getListBox() const
80cdf0e10cSrcweir 	{
81cdf0e10cSrcweir 		return	static_cast< SvTreeListBox* >( const_cast<AccessibleListBox*>(this)->GetWindow() );
82cdf0e10cSrcweir 	}
83cdf0e10cSrcweir 	// -----------------------------------------------------------------------------
ProcessWindowEvent(const VclWindowEvent & rVclWindowEvent)84cdf0e10cSrcweir 	void AccessibleListBox::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
85cdf0e10cSrcweir 	{
86*aa5a148eSmseidel 		if ( isAlive() )
87cdf0e10cSrcweir 		{
88cdf0e10cSrcweir 			switch ( rVclWindowEvent.GetId() )
89cdf0e10cSrcweir 			{
90*aa5a148eSmseidel 				case VCLEVENT_CHECKBOX_TOGGLE :
91cdf0e10cSrcweir 				{
9221075d77SSteve Yin 					if ( !getListBox() || !getListBox()->HasFocus() )
93cdf0e10cSrcweir 					{
9421075d77SSteve Yin 						return;
9521075d77SSteve Yin 					}
9621075d77SSteve Yin 					AccessibleListBoxEntry* pCurOpEntry = GetCurEventEntry(rVclWindowEvent);
9721075d77SSteve Yin 					if(!pCurOpEntry)
9821075d77SSteve Yin 					{
9921075d77SSteve Yin 						return ;
10021075d77SSteve Yin 					}
10121075d77SSteve Yin 					uno::Any aValue;
10221075d77SSteve Yin 					aValue <<= AccessibleStateType::CHECKED;
103*aa5a148eSmseidel 
10421075d77SSteve Yin 					if ( getListBox()->GetCheckButtonState( pCurOpEntry->GetSvLBoxEntry() ) == SV_BUTTON_CHECKED )
10521075d77SSteve Yin 					{
10621075d77SSteve Yin 						pCurOpEntry->NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, uno::Any(), aValue );
10721075d77SSteve Yin 					}
10821075d77SSteve Yin 					else
10921075d77SSteve Yin 					{
11021075d77SSteve Yin 						pCurOpEntry->NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aValue,uno::Any() );
111cdf0e10cSrcweir 					}
112cdf0e10cSrcweir 					break;
113cdf0e10cSrcweir 				}
114cdf0e10cSrcweir 
115cdf0e10cSrcweir 				case VCLEVENT_LISTBOX_SELECT :
116cdf0e10cSrcweir 				{
117*aa5a148eSmseidel 					// First send an event that tells the listeners of a
118*aa5a148eSmseidel 					// modified selection. The active descendant event is
119*aa5a148eSmseidel 					// send after that so that the receiving AT has time to
120*aa5a148eSmseidel 					// read the text or name of the active child.
121*aa5a148eSmseidel //					NotifyAccessibleEvent( AccessibleEventId::SELECTION_CHANGED, Any(), Any() );
12221075d77SSteve Yin 					OSL_ASSERT(0 && "Debug: Treelist shouldn't use VCLEVENT_LISTBOX_SELECT");
12321075d77SSteve Yin 				}
12421075d77SSteve Yin 				case VCLEVENT_LISTBOX_TREESELECT:
12521075d77SSteve Yin 					{
12621075d77SSteve Yin 						if ( getListBox() && getListBox()->HasFocus() )
12721075d77SSteve Yin 						{
12821075d77SSteve Yin 							AccessibleListBoxEntry* pEntry =static_cast< AccessibleListBoxEntry* >(m_xFocusedChild.get());
12921075d77SSteve Yin 							if (pEntry)
13021075d77SSteve Yin 							{
13121075d77SSteve Yin 								pEntry->NotifyAccessibleEvent( AccessibleEventId::SELECTION_CHANGED, Any(), Any() );
13221075d77SSteve Yin 							}
13321075d77SSteve Yin 						}
13421075d77SSteve Yin 					}
13521075d77SSteve Yin 					break;
13621075d77SSteve Yin 				case VCLEVENT_LISTBOX_TREEFOCUS:
13721075d77SSteve Yin 					{
13821075d77SSteve Yin 						SvTreeListBox* pBox = getListBox();
13921075d77SSteve Yin 						sal_Bool bNeedFocus = sal_False;
14021075d77SSteve Yin 						if (pBox)
14121075d77SSteve Yin 						{
14221075d77SSteve Yin 							Window* pParent = ((Window*)pBox)->GetParent();
14321075d77SSteve Yin 							if (pParent && pParent->GetType() == WINDOW_FLOATINGWINDOW)
14421075d77SSteve Yin 							{
14521075d77SSteve Yin 								// MT: ImplGetAppSVData shouldn't be exported from VCL.
14621075d77SSteve Yin 								// In which scenario is this needed?
14721075d77SSteve Yin 								// If needed, we need to find an other solution
14821075d77SSteve Yin 								/*
14921075d77SSteve Yin 								ImplSVData* pSVData = ImplGetAppSVData();
15021075d77SSteve Yin 								if (pSVData && pSVData->maWinData.mpFirstFloat == (FloatingWindow*)pParent)
15121075d77SSteve Yin 									bNeedFocus = sal_True;
15221075d77SSteve Yin 								*/
153*aa5a148eSmseidel 							}
15421075d77SSteve Yin 						}
15521075d77SSteve Yin 						if( pBox && (pBox->HasFocus() || bNeedFocus) )
15621075d77SSteve Yin 						{
15721075d77SSteve Yin 							uno::Any aOldValue, aNewValue;
15821075d77SSteve Yin 							SvLBoxEntry* pEntry = static_cast< SvLBoxEntry* >( rVclWindowEvent.GetData() );
15921075d77SSteve Yin 							if ( pEntry )
16021075d77SSteve Yin 							{
16121075d77SSteve Yin 								AccessibleListBoxEntry* pEntryFocus =static_cast< AccessibleListBoxEntry* >(m_xFocusedChild.get());
16221075d77SSteve Yin 								if (pEntryFocus && pEntryFocus->GetSvLBoxEntry() == pEntry)
16321075d77SSteve Yin 								{
16421075d77SSteve Yin 									aOldValue <<= uno::Any();
16521075d77SSteve Yin 									aNewValue <<= m_xFocusedChild;
16621075d77SSteve Yin 									NotifyAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, aOldValue, aNewValue );
16721075d77SSteve Yin 									return ;
16821075d77SSteve Yin 								}
16921075d77SSteve Yin 
17021075d77SSteve Yin 								aOldValue <<= m_xFocusedChild;
17121075d77SSteve Yin 
17221075d77SSteve Yin 								MAP_ENTRY::iterator mi = m_mapEntry.find(pEntry);
17321075d77SSteve Yin 								if(mi != m_mapEntry.end())
17421075d77SSteve Yin 								{
17521075d77SSteve Yin 									OSL_ASSERT(mi->second.get() != NULL);
17621075d77SSteve Yin 									m_xFocusedChild = mi->second;
17721075d77SSteve Yin 								}
17821075d77SSteve Yin 								else
17921075d77SSteve Yin 								{
18021075d77SSteve Yin 									AccessibleListBoxEntry *pEntNew = new AccessibleListBoxEntry( *getListBox(), pEntry, NULL );
18121075d77SSteve Yin 									m_xFocusedChild = pEntNew;
18221075d77SSteve Yin 									m_mapEntry.insert(MAP_ENTRY::value_type(pEntry,pEntNew));
18321075d77SSteve Yin 								}
184*aa5a148eSmseidel 
18521075d77SSteve Yin 								aNewValue <<= m_xFocusedChild;
18621075d77SSteve Yin 								NotifyAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, aOldValue, aNewValue );
18721075d77SSteve Yin 							}
18821075d77SSteve Yin 							else
18921075d77SSteve Yin 							{
19021075d77SSteve Yin 								aOldValue <<= uno::Any();
19121075d77SSteve Yin 								aNewValue <<= AccessibleStateType::FOCUSED;
19221075d77SSteve Yin 								NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
19321075d77SSteve Yin 							}
194*aa5a148eSmseidel 						}
19521075d77SSteve Yin 					}
19621075d77SSteve Yin 					break;
19721075d77SSteve Yin 				case VCLEVENT_LISTBOX_ITEMREMOVED:
198cdf0e10cSrcweir 					{
199cdf0e10cSrcweir 						SvLBoxEntry* pEntry = static_cast< SvLBoxEntry* >( rVclWindowEvent.GetData() );
200cdf0e10cSrcweir 						if ( pEntry )
201cdf0e10cSrcweir 						{
20221075d77SSteve Yin 							RemoveChildEntries(pEntry);
20321075d77SSteve Yin 						}
20421075d77SSteve Yin 						else
20521075d77SSteve Yin 						{
20621075d77SSteve Yin 							// NULL means Clear()
20721075d77SSteve Yin 							MAP_ENTRY::iterator mi = m_mapEntry.begin();
20821075d77SSteve Yin 							for ( ; mi != m_mapEntry.end() ; ++mi)
20921075d77SSteve Yin 							{
21021075d77SSteve Yin 								uno::Any aNewValue;
21121075d77SSteve Yin 								uno::Any aOldValue;
212*aa5a148eSmseidel 								aOldValue <<= mi->second;
21321075d77SSteve Yin 								NotifyAccessibleEvent( AccessibleEventId::CHILD, aOldValue, aNewValue );
21421075d77SSteve Yin 							}
21521075d77SSteve Yin 							m_mapEntry.clear();
216cdf0e10cSrcweir 						}
217*aa5a148eSmseidel 
218*aa5a148eSmseidel 
219cdf0e10cSrcweir 					}
220cdf0e10cSrcweir 					break;
221cdf0e10cSrcweir 
222*aa5a148eSmseidel 				// --> OD 2009-04-01 #i92103#
223*aa5a148eSmseidel 				case VCLEVENT_ITEM_EXPANDED :
224*aa5a148eSmseidel 				case VCLEVENT_ITEM_COLLAPSED :
225*aa5a148eSmseidel 				{
226*aa5a148eSmseidel 					SvLBoxEntry* pEntry = static_cast< SvLBoxEntry* >( rVclWindowEvent.GetData() );
227*aa5a148eSmseidel 					if ( pEntry )
228*aa5a148eSmseidel 					{
229*aa5a148eSmseidel 						AccessibleListBoxEntry* pAccListBoxEntry =
230*aa5a148eSmseidel 							new AccessibleListBoxEntry( *getListBox(), pEntry, this );
231*aa5a148eSmseidel 						Reference< XAccessible > xChild = pAccListBoxEntry;
232*aa5a148eSmseidel 						const short nAccEvent =
233*aa5a148eSmseidel 							( rVclWindowEvent.GetId() == VCLEVENT_ITEM_EXPANDED )
234*aa5a148eSmseidel 							? AccessibleEventId::LISTBOX_ENTRY_EXPANDED
235*aa5a148eSmseidel 							: AccessibleEventId::LISTBOX_ENTRY_COLLAPSED;
236*aa5a148eSmseidel 						uno::Any aListBoxEntry;
237*aa5a148eSmseidel 						aListBoxEntry <<= xChild;
238*aa5a148eSmseidel 						NotifyAccessibleEvent( nAccEvent, Any(), aListBoxEntry );
239*aa5a148eSmseidel 						if ( getListBox() && getListBox()->HasFocus() )
240*aa5a148eSmseidel 						{
241*aa5a148eSmseidel 							NotifyAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, Any(), aListBoxEntry );
242*aa5a148eSmseidel 						}
243*aa5a148eSmseidel 					}
244*aa5a148eSmseidel 				}
245*aa5a148eSmseidel 				break;
246*aa5a148eSmseidel 				// <--
247cdf0e10cSrcweir 				default:
248cdf0e10cSrcweir 					VCLXAccessibleComponent::ProcessWindowEvent (rVclWindowEvent);
249cdf0e10cSrcweir 			}
250cdf0e10cSrcweir 		}
251cdf0e10cSrcweir 	}
25221075d77SSteve Yin 
GetCurEventEntry(const VclWindowEvent & rVclWindowEvent)25321075d77SSteve Yin 	AccessibleListBoxEntry* AccessibleListBox::GetCurEventEntry( const VclWindowEvent& rVclWindowEvent )
25421075d77SSteve Yin 	{
25521075d77SSteve Yin 		SvLBoxEntry* pEntry = static_cast< SvLBoxEntry* >( rVclWindowEvent.GetData() );
25621075d77SSteve Yin 		if ( !pEntry )
25721075d77SSteve Yin 			pEntry = getListBox()->GetCurEntry();
258*aa5a148eSmseidel 
25921075d77SSteve Yin 		AccessibleListBoxEntry* pEntryFocus =static_cast< AccessibleListBoxEntry* >(m_xFocusedChild.get());
26021075d77SSteve Yin 		if (pEntryFocus && pEntry && pEntry != pEntryFocus->GetSvLBoxEntry())
26121075d77SSteve Yin 		{
26221075d77SSteve Yin 			AccessibleListBoxEntry *pAccCurOptionEntry =NULL;
26321075d77SSteve Yin 			MAP_ENTRY::iterator mi = m_mapEntry.find(pEntry);
26421075d77SSteve Yin 			if (mi != m_mapEntry.end())
26521075d77SSteve Yin 			{
26621075d77SSteve Yin 				pAccCurOptionEntry= static_cast< AccessibleListBoxEntry* >(mi->second.get());
26721075d77SSteve Yin 			}
26821075d77SSteve Yin 			else
26921075d77SSteve Yin 			{
270*aa5a148eSmseidel 				pAccCurOptionEntry =new AccessibleListBoxEntry( *getListBox(), pEntry, NULL );
271*aa5a148eSmseidel 				std::pair<MAP_ENTRY::iterator, bool> pairMi = m_mapEntry.insert(MAP_ENTRY::value_type(pAccCurOptionEntry->GetSvLBoxEntry(),pAccCurOptionEntry));
27221075d77SSteve Yin 				mi = pairMi.first;
273*aa5a148eSmseidel 			}
27421075d77SSteve Yin 
275*aa5a148eSmseidel 			uno::Any aNewValue;
27621075d77SSteve Yin 			aNewValue <<= mi->second;//xAcc
277*aa5a148eSmseidel 			NotifyAccessibleEvent( AccessibleEventId::CHILD, uno::Any(), aNewValue );//Add
278*aa5a148eSmseidel 
27921075d77SSteve Yin 			return pAccCurOptionEntry;
28021075d77SSteve Yin 		}
28121075d77SSteve Yin 		else
28221075d77SSteve Yin 		{
28321075d77SSteve Yin 			return pEntryFocus;
28421075d77SSteve Yin 		}
28521075d77SSteve Yin 		return NULL;
28621075d77SSteve Yin 	}
28721075d77SSteve Yin 
RemoveChildEntries(SvLBoxEntry * pEntry)28821075d77SSteve Yin 	void AccessibleListBox::RemoveChildEntries(SvLBoxEntry* pEntry)
28921075d77SSteve Yin 	{
29021075d77SSteve Yin 		MAP_ENTRY::iterator mi = m_mapEntry.find(pEntry);
29121075d77SSteve Yin 		if ( mi != m_mapEntry.end() )
29221075d77SSteve Yin 		{
29321075d77SSteve Yin 			uno::Any aNewValue;
29421075d77SSteve Yin 			uno::Any aOldValue;
295*aa5a148eSmseidel 			aOldValue <<= mi->second;
29621075d77SSteve Yin 			NotifyAccessibleEvent( AccessibleEventId::CHILD, aOldValue, aNewValue );
29721075d77SSteve Yin 
29821075d77SSteve Yin 			m_mapEntry.erase(mi);
29921075d77SSteve Yin 		}
30021075d77SSteve Yin 
30121075d77SSteve Yin 		SvTreeListBox* pBox = getListBox();
30221075d77SSteve Yin 		SvLBoxEntry* pEntryChild = pBox->FirstChild(pEntry);
30321075d77SSteve Yin 		while (pEntryChild)
30421075d77SSteve Yin 		{
30521075d77SSteve Yin 			RemoveChildEntries(pEntryChild);
30621075d77SSteve Yin 			pEntryChild = pBox->NextSibling(pEntryChild);
307*aa5a148eSmseidel 		}
30821075d77SSteve Yin 	}
30921075d77SSteve Yin 
310cdf0e10cSrcweir 	// -----------------------------------------------------------------------------
ProcessWindowChildEvent(const VclWindowEvent & rVclWindowEvent)311*aa5a148eSmseidel 	void AccessibleListBox::ProcessWindowChildEvent( const VclWindowEvent& rVclWindowEvent )
312*aa5a148eSmseidel 	{
313*aa5a148eSmseidel 		switch ( rVclWindowEvent.GetId() )
314*aa5a148eSmseidel 		{
315*aa5a148eSmseidel 			case VCLEVENT_WINDOW_SHOW:
316*aa5a148eSmseidel 			case VCLEVENT_WINDOW_HIDE:
317*aa5a148eSmseidel 			{
318*aa5a148eSmseidel 			}
319*aa5a148eSmseidel 			break;
320*aa5a148eSmseidel 			default:
321*aa5a148eSmseidel 			{
322*aa5a148eSmseidel 				VCLXAccessibleComponent::ProcessWindowChildEvent( rVclWindowEvent );
323*aa5a148eSmseidel 			}
324*aa5a148eSmseidel 			break;
325*aa5a148eSmseidel 		}
326*aa5a148eSmseidel 	}
327cdf0e10cSrcweir 
328cdf0e10cSrcweir 	// -----------------------------------------------------------------------------
329cdf0e10cSrcweir 	// XComponent
330cdf0e10cSrcweir 	// -----------------------------------------------------------------------------
disposing()331cdf0e10cSrcweir 	void SAL_CALL AccessibleListBox::disposing()
332cdf0e10cSrcweir 	{
333cdf0e10cSrcweir 		::osl::MutexGuard aGuard( m_aMutex );
334cdf0e10cSrcweir 
33521075d77SSteve Yin 		m_mapEntry.clear();
336cdf0e10cSrcweir 		VCLXAccessibleComponent::disposing();
337*aa5a148eSmseidel 		m_xParent = NULL;
338cdf0e10cSrcweir 	}
339cdf0e10cSrcweir 	// -----------------------------------------------------------------------------
340cdf0e10cSrcweir 	// XServiceInfo
341cdf0e10cSrcweir 	// -----------------------------------------------------------------------------
getImplementationName()342cdf0e10cSrcweir 	::rtl::OUString SAL_CALL AccessibleListBox::getImplementationName() throw(RuntimeException)
343cdf0e10cSrcweir 	{
344cdf0e10cSrcweir 		return getImplementationName_Static();
345cdf0e10cSrcweir 	}
346cdf0e10cSrcweir 	// -----------------------------------------------------------------------------
getSupportedServiceNames()347cdf0e10cSrcweir 	Sequence< ::rtl::OUString > SAL_CALL AccessibleListBox::getSupportedServiceNames() throw(RuntimeException)
348cdf0e10cSrcweir 	{
349cdf0e10cSrcweir 		return getSupportedServiceNames_Static();
350cdf0e10cSrcweir 	}
351cdf0e10cSrcweir 	// -----------------------------------------------------------------------------
supportsService(const::rtl::OUString & _rServiceName)352cdf0e10cSrcweir 	sal_Bool SAL_CALL AccessibleListBox::supportsService( const ::rtl::OUString& _rServiceName ) throw (RuntimeException)
353cdf0e10cSrcweir 	{
354cdf0e10cSrcweir 		Sequence< ::rtl::OUString > aSupported( getSupportedServiceNames() );
355cdf0e10cSrcweir 		const ::rtl::OUString* pSupported = aSupported.getConstArray();
356cdf0e10cSrcweir 		const ::rtl::OUString* pEnd = pSupported + aSupported.getLength();
357cdf0e10cSrcweir 		for ( ; pSupported != pEnd && !pSupported->equals(_rServiceName); ++pSupported )
358cdf0e10cSrcweir 			;
359cdf0e10cSrcweir 
360cdf0e10cSrcweir 		return pSupported != pEnd;
361cdf0e10cSrcweir 	}
362cdf0e10cSrcweir 	// -----------------------------------------------------------------------------
363cdf0e10cSrcweir 	// XServiceInfo - static methods
364cdf0e10cSrcweir 	// -----------------------------------------------------------------------------
getSupportedServiceNames_Static(void)365cdf0e10cSrcweir 	Sequence< ::rtl::OUString > AccessibleListBox::getSupportedServiceNames_Static(void) throw( RuntimeException )
366cdf0e10cSrcweir 	{
367cdf0e10cSrcweir 		Sequence< ::rtl::OUString > aSupported(3);
368cdf0e10cSrcweir 		aSupported[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.accessibility.AccessibleContext") );
369cdf0e10cSrcweir 		aSupported[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.accessibility.AccessibleComponent") );
370cdf0e10cSrcweir 		aSupported[2] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.AccessibleTreeListBox") );
371cdf0e10cSrcweir 		return aSupported;
372cdf0e10cSrcweir 	}
373cdf0e10cSrcweir 	// -----------------------------------------------------------------------------
getImplementationName_Static(void)374cdf0e10cSrcweir 	::rtl::OUString AccessibleListBox::getImplementationName_Static(void) throw( RuntimeException )
375cdf0e10cSrcweir 	{
376cdf0e10cSrcweir 		return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.svtools.AccessibleTreeListBox") );
377cdf0e10cSrcweir 	}
378cdf0e10cSrcweir 	// -----------------------------------------------------------------------------
379cdf0e10cSrcweir 	// XAccessible
380cdf0e10cSrcweir 	// -----------------------------------------------------------------------------
getAccessibleContext()381cdf0e10cSrcweir 	Reference< XAccessibleContext > SAL_CALL AccessibleListBox::getAccessibleContext(  ) throw (RuntimeException)
382cdf0e10cSrcweir 	{
383cdf0e10cSrcweir 		ensureAlive();
384cdf0e10cSrcweir 		return this;
385cdf0e10cSrcweir 	}
386cdf0e10cSrcweir 	// -----------------------------------------------------------------------------
387cdf0e10cSrcweir 	// XAccessibleContext
388cdf0e10cSrcweir 	// -----------------------------------------------------------------------------
getAccessibleChildCount()389cdf0e10cSrcweir 	sal_Int32 SAL_CALL AccessibleListBox::getAccessibleChildCount(  ) throw (RuntimeException)
390cdf0e10cSrcweir 	{
391cdf0e10cSrcweir 		::comphelper::OExternalLockGuard aGuard( this );
392cdf0e10cSrcweir 
393cdf0e10cSrcweir 		ensureAlive();
394cdf0e10cSrcweir 
395*aa5a148eSmseidel 		sal_Int32 nCount = 0;
396*aa5a148eSmseidel 		SvTreeListBox* pSvTreeListBox = getListBox();
397*aa5a148eSmseidel 		if ( pSvTreeListBox )
398*aa5a148eSmseidel 			nCount = pSvTreeListBox->GetLevelChildCount( NULL );
399cdf0e10cSrcweir 
400*aa5a148eSmseidel 		return nCount;
401cdf0e10cSrcweir 	}
402cdf0e10cSrcweir 	// -----------------------------------------------------------------------------
getAccessibleChild(sal_Int32 i)403cdf0e10cSrcweir 	Reference< XAccessible > SAL_CALL AccessibleListBox::getAccessibleChild( sal_Int32 i ) throw (IndexOutOfBoundsException,RuntimeException)
404cdf0e10cSrcweir 	{
405cdf0e10cSrcweir 		::comphelper::OExternalLockGuard aGuard( this );
406cdf0e10cSrcweir 
407cdf0e10cSrcweir 		ensureAlive();
408cdf0e10cSrcweir 		SvLBoxEntry* pEntry = getListBox()->GetEntry(i);
409cdf0e10cSrcweir 		if ( !pEntry )
410cdf0e10cSrcweir 			throw IndexOutOfBoundsException();
411cdf0e10cSrcweir 
41221075d77SSteve Yin 		// Solution: Set the parameter of the parent to null to let entry determine the parent by itself
41321075d77SSteve Yin 		//return new AccessibleListBoxEntry( *getListBox(), pEntry, this );
41421075d77SSteve Yin 		return new AccessibleListBoxEntry( *getListBox(), pEntry, NULL );
415cdf0e10cSrcweir 	}
416cdf0e10cSrcweir 	// -----------------------------------------------------------------------------
getAccessibleParent()417cdf0e10cSrcweir 	Reference< XAccessible > SAL_CALL AccessibleListBox::getAccessibleParent(  ) throw (RuntimeException)
418cdf0e10cSrcweir 	{
419cdf0e10cSrcweir 		::osl::MutexGuard aGuard( m_aMutex );
420cdf0e10cSrcweir 
421cdf0e10cSrcweir 		ensureAlive();
422cdf0e10cSrcweir 		return m_xParent;
423cdf0e10cSrcweir 	}
424cdf0e10cSrcweir 	// -----------------------------------------------------------------------------
getRoleType()42521075d77SSteve Yin 	sal_Int32 SAL_CALL AccessibleListBox::getRoleType()
42621075d77SSteve Yin 	{
42721075d77SSteve Yin 		sal_Int32 nCase = 0;
42821075d77SSteve Yin 		SvLBoxEntry* pEntry = getListBox()->GetEntry(0);
42921075d77SSteve Yin 		if ( pEntry )
43021075d77SSteve Yin 		{
43121075d77SSteve Yin 			if( pEntry->HasChildsOnDemand() || getListBox()->GetChildCount(pEntry) > 0  )
43221075d77SSteve Yin 			{
43321075d77SSteve Yin 				nCase = 1;
43421075d77SSteve Yin 				return nCase;
43521075d77SSteve Yin 			}
43621075d77SSteve Yin 		}
43721075d77SSteve Yin 
438*aa5a148eSmseidel 		sal_Bool bHasButtons = (getListBox()->GetStyle() & WB_HASBUTTONS)!=0;
43921075d77SSteve Yin 		if( !(getListBox()->GetTreeFlags() & TREEFLAG_CHKBTN) )
44021075d77SSteve Yin 		{
44121075d77SSteve Yin 			if( bHasButtons )
44221075d77SSteve Yin 				nCase = 1;
44321075d77SSteve Yin 		}
44421075d77SSteve Yin 		else
44521075d77SSteve Yin 		{
44621075d77SSteve Yin 			if( bHasButtons )
44721075d77SSteve Yin 				nCase = 2;
44821075d77SSteve Yin 			 else
44921075d77SSteve Yin 				nCase = 3;
45021075d77SSteve Yin 		}
45121075d77SSteve Yin 		return nCase;
45221075d77SSteve Yin 	}
getAccessibleRole()453cdf0e10cSrcweir 	sal_Int16 SAL_CALL AccessibleListBox::getAccessibleRole(  ) throw (RuntimeException)
454cdf0e10cSrcweir 	{
45521075d77SSteve Yin 		if(getListBox())
45621075d77SSteve Yin 		{
457*aa5a148eSmseidel 			short nType = getListBox()->GetAllEntriesAccessibleRoleType();
45821075d77SSteve Yin 			if( nType == TREEBOX_ALLITEM_ACCROLE_TYPE_TREE)
45921075d77SSteve Yin 					return AccessibleRole::TREE;
46021075d77SSteve Yin 			else if( nType == TREEBOX_ALLITEM_ACCROLE_TYPE_LIST)
46121075d77SSteve Yin 					return AccessibleRole::LIST;
46221075d77SSteve Yin 		}
46321075d77SSteve Yin 
46421075d77SSteve Yin 		//o is: return AccessibleRole::TREE;
465*aa5a148eSmseidel 		sal_Bool bHasButtons = (getListBox()->GetStyle() & WB_HASBUTTONS)!=0;
46621075d77SSteve Yin 		if(!bHasButtons && (getListBox()->GetTreeFlags() & TREEFLAG_CHKBTN))
46721075d77SSteve Yin 			return AccessibleRole::LIST;
46821075d77SSteve Yin 		else
46921075d77SSteve Yin 			if(getRoleType() == 0)
47021075d77SSteve Yin 				return AccessibleRole::LIST;
47121075d77SSteve Yin 			else
47221075d77SSteve Yin 			return AccessibleRole::TREE;
473cdf0e10cSrcweir 	}
474cdf0e10cSrcweir 	// -----------------------------------------------------------------------------
getAccessibleDescription()475cdf0e10cSrcweir 	::rtl::OUString SAL_CALL AccessibleListBox::getAccessibleDescription(  ) throw (RuntimeException)
476cdf0e10cSrcweir 	{
477cdf0e10cSrcweir 		::comphelper::OExternalLockGuard aGuard( this );
478cdf0e10cSrcweir 
479cdf0e10cSrcweir 		ensureAlive();
480cdf0e10cSrcweir 		return getListBox()->GetAccessibleDescription();
481cdf0e10cSrcweir 	}
482cdf0e10cSrcweir 	// -----------------------------------------------------------------------------
getAccessibleName()483cdf0e10cSrcweir 	::rtl::OUString SAL_CALL AccessibleListBox::getAccessibleName(  ) throw (RuntimeException)
484cdf0e10cSrcweir 	{
485cdf0e10cSrcweir 		::comphelper::OExternalLockGuard aGuard( this );
486cdf0e10cSrcweir 
487cdf0e10cSrcweir 		ensureAlive();
488cdf0e10cSrcweir 		return getListBox()->GetAccessibleName();
489cdf0e10cSrcweir 	}
490cdf0e10cSrcweir 	// -----------------------------------------------------------------------------
491cdf0e10cSrcweir 	// XAccessibleSelection
492cdf0e10cSrcweir 	// -----------------------------------------------------------------------------
selectAccessibleChild(sal_Int32 nChildIndex)493cdf0e10cSrcweir 	void SAL_CALL AccessibleListBox::selectAccessibleChild( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
494cdf0e10cSrcweir 	{
495*aa5a148eSmseidel 		::comphelper::OExternalLockGuard aGuard( this );
496cdf0e10cSrcweir 
497cdf0e10cSrcweir 		ensureAlive();
498cdf0e10cSrcweir 
499cdf0e10cSrcweir 		SvLBoxEntry* pEntry = getListBox()->GetEntry( nChildIndex );
500cdf0e10cSrcweir 		if ( !pEntry )
501cdf0e10cSrcweir 			throw IndexOutOfBoundsException();
502cdf0e10cSrcweir 
503cdf0e10cSrcweir 		getListBox()->Select( pEntry, sal_True );
504cdf0e10cSrcweir 	}
505cdf0e10cSrcweir 	// -----------------------------------------------------------------------------
isAccessibleChildSelected(sal_Int32 nChildIndex)506cdf0e10cSrcweir 	sal_Bool SAL_CALL AccessibleListBox::isAccessibleChildSelected( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
507cdf0e10cSrcweir 	{
508*aa5a148eSmseidel 		::comphelper::OExternalLockGuard aGuard( this );
509cdf0e10cSrcweir 
510cdf0e10cSrcweir 		ensureAlive();
511cdf0e10cSrcweir 
512cdf0e10cSrcweir 		SvLBoxEntry* pEntry = getListBox()->GetEntry( nChildIndex );
513cdf0e10cSrcweir 		if ( !pEntry )
514cdf0e10cSrcweir 			throw IndexOutOfBoundsException();
515cdf0e10cSrcweir 
516cdf0e10cSrcweir 		return getListBox()->IsSelected( pEntry );
517cdf0e10cSrcweir 	}
518cdf0e10cSrcweir 	// -----------------------------------------------------------------------------
clearAccessibleSelection()519cdf0e10cSrcweir 	void SAL_CALL AccessibleListBox::clearAccessibleSelection(  ) throw (RuntimeException)
520cdf0e10cSrcweir 	{
521*aa5a148eSmseidel 		::comphelper::OExternalLockGuard aGuard( this );
522cdf0e10cSrcweir 
523cdf0e10cSrcweir 		ensureAlive();
524cdf0e10cSrcweir 
525*aa5a148eSmseidel 		sal_Int32 i, nCount = 0;
526cdf0e10cSrcweir 		nCount = getListBox()->GetLevelChildCount( NULL );
527cdf0e10cSrcweir 		for ( i = 0; i < nCount; ++i )
528cdf0e10cSrcweir 		{
529cdf0e10cSrcweir 			SvLBoxEntry* pEntry = getListBox()->GetEntry( i );
530cdf0e10cSrcweir 			if ( getListBox()->IsSelected( pEntry ) )
531cdf0e10cSrcweir 				getListBox()->Select( pEntry, sal_False );
532cdf0e10cSrcweir 		}
533cdf0e10cSrcweir 	}
534cdf0e10cSrcweir 	// -----------------------------------------------------------------------------
selectAllAccessibleChildren()535cdf0e10cSrcweir 	void SAL_CALL AccessibleListBox::selectAllAccessibleChildren(  ) throw (RuntimeException)
536cdf0e10cSrcweir 	{
537*aa5a148eSmseidel 		::comphelper::OExternalLockGuard aGuard( this );
538cdf0e10cSrcweir 
539cdf0e10cSrcweir 		ensureAlive();
540cdf0e10cSrcweir 
541*aa5a148eSmseidel 		sal_Int32 i, nCount = 0;
542cdf0e10cSrcweir 		nCount = getListBox()->GetLevelChildCount( NULL );
543cdf0e10cSrcweir 		for ( i = 0; i < nCount; ++i )
544cdf0e10cSrcweir 		{
545cdf0e10cSrcweir 			SvLBoxEntry* pEntry = getListBox()->GetEntry( i );
546cdf0e10cSrcweir 			if ( !getListBox()->IsSelected( pEntry ) )
547cdf0e10cSrcweir 				getListBox()->Select( pEntry, sal_True );
548cdf0e10cSrcweir 		}
549cdf0e10cSrcweir 	}
550cdf0e10cSrcweir 	// -----------------------------------------------------------------------------
getSelectedAccessibleChildCount()551cdf0e10cSrcweir 	sal_Int32 SAL_CALL AccessibleListBox::getSelectedAccessibleChildCount(  ) throw (RuntimeException)
552cdf0e10cSrcweir 	{
553*aa5a148eSmseidel 		::comphelper::OExternalLockGuard aGuard( this );
554cdf0e10cSrcweir 
555cdf0e10cSrcweir 		ensureAlive();
55621075d77SSteve Yin 
557*aa5a148eSmseidel 
558*aa5a148eSmseidel //		sal_Int32 i, nSelCount = 0, nCount = 0;
55921075d77SSteve Yin // 		nCount = getListBox()->GetLevelChildCount( NULL );
56021075d77SSteve Yin // 		for ( i = 0; i < nCount; ++i )
56121075d77SSteve Yin // 		{
56221075d77SSteve Yin // 			SvLBoxEntry* pEntry = getListBox()->GetEntry( i );
56321075d77SSteve Yin // 			if ( getListBox()->IsSelected( pEntry ) )
56421075d77SSteve Yin // 				++nSelCount;
56521075d77SSteve Yin // 		}
566*aa5a148eSmseidel //		return nSelCount;
56721075d77SSteve Yin 
568*aa5a148eSmseidel 		int nTestCount = getListBox()->GetSelectionCount();
56921075d77SSteve Yin 		return nTestCount;
570cdf0e10cSrcweir 	}
571cdf0e10cSrcweir 	// -----------------------------------------------------------------------------
getSelectedAccessibleChild(sal_Int32 nSelectedChildIndex)572cdf0e10cSrcweir 	Reference< XAccessible > SAL_CALL AccessibleListBox::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
573cdf0e10cSrcweir 	{
574*aa5a148eSmseidel 		::comphelper::OExternalLockGuard aGuard( this );
575cdf0e10cSrcweir 
576cdf0e10cSrcweir 		ensureAlive();
577cdf0e10cSrcweir 
578cdf0e10cSrcweir 		if ( nSelectedChildIndex < 0 || nSelectedChildIndex >= getSelectedAccessibleChildCount() )
579cdf0e10cSrcweir 			throw IndexOutOfBoundsException();
580cdf0e10cSrcweir 
581cdf0e10cSrcweir 		Reference< XAccessible > xChild;
582*aa5a148eSmseidel 		sal_Int32 i, nSelCount = 0, nCount = 0;
583cdf0e10cSrcweir 		nCount = getListBox()->GetLevelChildCount( NULL );
584cdf0e10cSrcweir 		for ( i = 0; i < nCount; ++i )
585cdf0e10cSrcweir 		{
586cdf0e10cSrcweir 			SvLBoxEntry* pEntry = getListBox()->GetEntry( i );
587cdf0e10cSrcweir 			if ( getListBox()->IsSelected( pEntry ) )
588cdf0e10cSrcweir 				++nSelCount;
589cdf0e10cSrcweir 
590cdf0e10cSrcweir 			if ( nSelCount == ( nSelectedChildIndex + 1 ) )
591cdf0e10cSrcweir 			{
59221075d77SSteve Yin 				// Solution: Set the parameter of the parent to null to let entry determine the parent by itself
59321075d77SSteve Yin 				//xChild = new AccessibleListBoxEntry( *getListBox(), pEntry, this );
59421075d77SSteve Yin 				xChild = new AccessibleListBoxEntry( *getListBox(), pEntry, NULL );
595cdf0e10cSrcweir 				break;
596cdf0e10cSrcweir 			}
597cdf0e10cSrcweir 		}
598cdf0e10cSrcweir 
599cdf0e10cSrcweir 		return xChild;
600cdf0e10cSrcweir 	}
601cdf0e10cSrcweir 	// -----------------------------------------------------------------------------
deselectAccessibleChild(sal_Int32 nSelectedChildIndex)602cdf0e10cSrcweir 	void SAL_CALL AccessibleListBox::deselectAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
603cdf0e10cSrcweir 	{
604*aa5a148eSmseidel 		::comphelper::OExternalLockGuard aGuard( this );
605cdf0e10cSrcweir 
606cdf0e10cSrcweir 		ensureAlive();
607cdf0e10cSrcweir 
608cdf0e10cSrcweir 		SvLBoxEntry* pEntry = getListBox()->GetEntry( nSelectedChildIndex );
609cdf0e10cSrcweir 		if ( !pEntry )
610cdf0e10cSrcweir 			throw IndexOutOfBoundsException();
611cdf0e10cSrcweir 
612cdf0e10cSrcweir 		getListBox()->Select( pEntry, sal_False );
613cdf0e10cSrcweir 	}
614cdf0e10cSrcweir 	// -----------------------------------------------------------------------------
FillAccessibleStateSet(utl::AccessibleStateSetHelper & rStateSet)615cdf0e10cSrcweir 	void AccessibleListBox::FillAccessibleStateSet( utl::AccessibleStateSetHelper& rStateSet )
616cdf0e10cSrcweir 	{
617cdf0e10cSrcweir 		VCLXAccessibleComponent::FillAccessibleStateSet( rStateSet );
618cdf0e10cSrcweir 		if ( getListBox() && isAlive() )
619cdf0e10cSrcweir 		{
620cdf0e10cSrcweir 			rStateSet.AddState( AccessibleStateType::FOCUSABLE );
621cdf0e10cSrcweir 			rStateSet.AddState( AccessibleStateType::MANAGES_DESCENDANTS );
622cdf0e10cSrcweir 			if ( getListBox()->GetSelectionMode() == MULTIPLE_SELECTION )
623cdf0e10cSrcweir 				rStateSet.AddState( AccessibleStateType::MULTI_SELECTABLE );
624cdf0e10cSrcweir 		}
625cdf0e10cSrcweir 	}
626cdf0e10cSrcweir 
627cdf0e10cSrcweir 
628cdf0e10cSrcweir //........................................................................
629cdf0e10cSrcweir }// namespace accessibility
630cdf0e10cSrcweir //........................................................................
631