10841af79SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
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
100841af79SAndrew Rist  *
110841af79SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
120841af79SAndrew Rist  *
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.
190841af79SAndrew Rist  *
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
72cdf0e10cSrcweir         	osl_incrementInterlockedCount( &m_refCount );
73cdf0e10cSrcweir         	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 	{
86cdf0e10cSrcweir     	if ( isAlive() )
87cdf0e10cSrcweir 		{
88cdf0e10cSrcweir 			switch ( rVclWindowEvent.GetId() )
89cdf0e10cSrcweir 			{
90cdf0e10cSrcweir 				case  VCLEVENT_CHECKBOX_TOGGLE :
91cdf0e10cSrcweir 				{
92*21075d77SSteve Yin 					if ( !getListBox() || !getListBox()->HasFocus() )
93cdf0e10cSrcweir 					{
94*21075d77SSteve Yin 						return;
95*21075d77SSteve Yin 					}
96*21075d77SSteve Yin 					AccessibleListBoxEntry* pCurOpEntry = GetCurEventEntry(rVclWindowEvent);
97*21075d77SSteve Yin 					if(!pCurOpEntry)
98*21075d77SSteve Yin 					{
99*21075d77SSteve Yin 						return ;
100*21075d77SSteve Yin 					}
101*21075d77SSteve Yin 					uno::Any aValue;
102*21075d77SSteve Yin 					aValue <<= AccessibleStateType::CHECKED;
103*21075d77SSteve Yin 
104*21075d77SSteve Yin 					if ( getListBox()->GetCheckButtonState( pCurOpEntry->GetSvLBoxEntry() ) == SV_BUTTON_CHECKED )
105*21075d77SSteve Yin 					{
106*21075d77SSteve Yin 						pCurOpEntry->NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, uno::Any(), aValue );
107*21075d77SSteve Yin 					}
108*21075d77SSteve Yin 					else
109*21075d77SSteve Yin 					{
110*21075d77SSteve Yin 						pCurOpEntry->NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aValue,uno::Any() );
111cdf0e10cSrcweir 					}
112cdf0e10cSrcweir 					break;
113cdf0e10cSrcweir 				}
114cdf0e10cSrcweir 
115cdf0e10cSrcweir 				case VCLEVENT_LISTBOX_SELECT :
116cdf0e10cSrcweir 				{
117cdf0e10cSrcweir                     // First send an event that tells the listeners of a
118cdf0e10cSrcweir                     // modified selection.  The active descendant event is
119cdf0e10cSrcweir                     // send after that so that the receiving AT has time to
120cdf0e10cSrcweir                     // read the text or name of the active child.
121*21075d77SSteve Yin //                    NotifyAccessibleEvent( AccessibleEventId::SELECTION_CHANGED, Any(), Any() );
122*21075d77SSteve Yin 					OSL_ASSERT(0 && "Debug: Treelist shouldn't use VCLEVENT_LISTBOX_SELECT");
123*21075d77SSteve Yin 				}
124*21075d77SSteve Yin 				case VCLEVENT_LISTBOX_TREESELECT:
125*21075d77SSteve Yin 					{
126*21075d77SSteve Yin 						if ( getListBox() && getListBox()->HasFocus() )
127*21075d77SSteve Yin 						{
128*21075d77SSteve Yin 							AccessibleListBoxEntry* pEntry =static_cast< AccessibleListBoxEntry* >(m_xFocusedChild.get());
129*21075d77SSteve Yin 							if (pEntry)
130*21075d77SSteve Yin 							{
131*21075d77SSteve Yin 								pEntry->NotifyAccessibleEvent( AccessibleEventId::SELECTION_CHANGED, Any(), Any() );
132*21075d77SSteve Yin 							}
133*21075d77SSteve Yin 						}
134*21075d77SSteve Yin 					}
135*21075d77SSteve Yin 					break;
136*21075d77SSteve Yin 				case VCLEVENT_LISTBOX_TREEFOCUS:
137*21075d77SSteve Yin 					{
138*21075d77SSteve Yin 						SvTreeListBox* pBox = getListBox();
139*21075d77SSteve Yin 						sal_Bool bNeedFocus = sal_False;
140*21075d77SSteve Yin 						if (pBox)
141*21075d77SSteve Yin 						{
142*21075d77SSteve Yin 							Window* pParent = ((Window*)pBox)->GetParent();
143*21075d77SSteve Yin 							if (pParent && pParent->GetType() == WINDOW_FLOATINGWINDOW)
144*21075d77SSteve Yin 							{
145*21075d77SSteve Yin 								// MT: ImplGetAppSVData shouldn't be exported from VCL.
146*21075d77SSteve Yin 								// In which scenario is this needed?
147*21075d77SSteve Yin 								// If needed, we need to find an other solution
148*21075d77SSteve Yin 								/*
149*21075d77SSteve Yin 								ImplSVData* pSVData = ImplGetAppSVData();
150*21075d77SSteve Yin 								if (pSVData && pSVData->maWinData.mpFirstFloat == (FloatingWindow*)pParent)
151*21075d77SSteve Yin 									bNeedFocus = sal_True;
152*21075d77SSteve Yin 								*/
153*21075d77SSteve Yin 							}
154*21075d77SSteve Yin 						}
155*21075d77SSteve Yin 						if( pBox && (pBox->HasFocus() || bNeedFocus) )
156*21075d77SSteve Yin 						{
157*21075d77SSteve Yin 							uno::Any aOldValue, aNewValue;
158*21075d77SSteve Yin 							SvLBoxEntry* pEntry = static_cast< SvLBoxEntry* >( rVclWindowEvent.GetData() );
159*21075d77SSteve Yin 							if ( pEntry )
160*21075d77SSteve Yin 							{
161*21075d77SSteve Yin 								AccessibleListBoxEntry* pEntryFocus =static_cast< AccessibleListBoxEntry* >(m_xFocusedChild.get());
162*21075d77SSteve Yin 								if (pEntryFocus && pEntryFocus->GetSvLBoxEntry() == pEntry)
163*21075d77SSteve Yin 								{
164*21075d77SSteve Yin 									aOldValue <<= uno::Any();
165*21075d77SSteve Yin 									aNewValue <<= m_xFocusedChild;
166*21075d77SSteve Yin 									NotifyAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, aOldValue, aNewValue );
167*21075d77SSteve Yin 									return ;
168*21075d77SSteve Yin 								}
169*21075d77SSteve Yin 
170*21075d77SSteve Yin 								aOldValue <<= m_xFocusedChild;
171*21075d77SSteve Yin 
172*21075d77SSteve Yin 								MAP_ENTRY::iterator mi = m_mapEntry.find(pEntry);
173*21075d77SSteve Yin 								if(mi != m_mapEntry.end())
174*21075d77SSteve Yin 								{
175*21075d77SSteve Yin 									OSL_ASSERT(mi->second.get() != NULL);
176*21075d77SSteve Yin 									m_xFocusedChild = mi->second;
177*21075d77SSteve Yin 								}
178*21075d77SSteve Yin 								else
179*21075d77SSteve Yin 								{
180*21075d77SSteve Yin 									AccessibleListBoxEntry *pEntNew = new AccessibleListBoxEntry( *getListBox(), pEntry, NULL );
181*21075d77SSteve Yin 									m_xFocusedChild = pEntNew;
182*21075d77SSteve Yin 									m_mapEntry.insert(MAP_ENTRY::value_type(pEntry,pEntNew));
183*21075d77SSteve Yin 								}
184*21075d77SSteve Yin 
185*21075d77SSteve Yin 								aNewValue <<= m_xFocusedChild;
186*21075d77SSteve Yin 								NotifyAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, aOldValue, aNewValue );
187*21075d77SSteve Yin 							}
188*21075d77SSteve Yin 							else
189*21075d77SSteve Yin 							{
190*21075d77SSteve Yin 								aOldValue <<= uno::Any();
191*21075d77SSteve Yin 								aNewValue <<= AccessibleStateType::FOCUSED;
192*21075d77SSteve Yin 								NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
193*21075d77SSteve Yin 							}
194*21075d77SSteve Yin 						}
195*21075d77SSteve Yin 					}
196*21075d77SSteve Yin 					break;
197*21075d77SSteve Yin 				case VCLEVENT_LISTBOX_ITEMREMOVED:
198cdf0e10cSrcweir 					{
199cdf0e10cSrcweir 						SvLBoxEntry* pEntry = static_cast< SvLBoxEntry* >( rVclWindowEvent.GetData() );
200cdf0e10cSrcweir 						if ( pEntry )
201cdf0e10cSrcweir 						{
202*21075d77SSteve Yin 							RemoveChildEntries(pEntry);
203*21075d77SSteve Yin 						}
204*21075d77SSteve Yin 						else
205*21075d77SSteve Yin 						{
206*21075d77SSteve Yin 							// NULL means Clear()
207*21075d77SSteve Yin 							MAP_ENTRY::iterator mi = m_mapEntry.begin();
208*21075d77SSteve Yin 							for ( ; mi != m_mapEntry.end() ; ++mi)
209*21075d77SSteve Yin 							{
210*21075d77SSteve Yin 								uno::Any aNewValue;
211*21075d77SSteve Yin 								uno::Any aOldValue;
212*21075d77SSteve Yin 								aOldValue <<= mi->second;
213*21075d77SSteve Yin 								NotifyAccessibleEvent( AccessibleEventId::CHILD, aOldValue, aNewValue );
214*21075d77SSteve Yin 							}
215*21075d77SSteve Yin 							m_mapEntry.clear();
216cdf0e10cSrcweir 						}
217*21075d77SSteve Yin 
218*21075d77SSteve Yin 
219cdf0e10cSrcweir 					}
220cdf0e10cSrcweir 					break;
221cdf0e10cSrcweir 
222cdf0e10cSrcweir                 // --> OD 2009-04-01 #i92103#
223cdf0e10cSrcweir                 case VCLEVENT_ITEM_EXPANDED :
224cdf0e10cSrcweir                 case VCLEVENT_ITEM_COLLAPSED :
225cdf0e10cSrcweir                 {
226cdf0e10cSrcweir                     SvLBoxEntry* pEntry = static_cast< SvLBoxEntry* >( rVclWindowEvent.GetData() );
227cdf0e10cSrcweir                     if ( pEntry )
228cdf0e10cSrcweir                     {
229cdf0e10cSrcweir                         AccessibleListBoxEntry* pAccListBoxEntry =
230cdf0e10cSrcweir                             new AccessibleListBoxEntry( *getListBox(), pEntry, this );
231cdf0e10cSrcweir                         Reference< XAccessible > xChild = pAccListBoxEntry;
232cdf0e10cSrcweir                         const short nAccEvent =
233cdf0e10cSrcweir                                 ( rVclWindowEvent.GetId() == VCLEVENT_ITEM_EXPANDED )
234cdf0e10cSrcweir                                 ? AccessibleEventId::LISTBOX_ENTRY_EXPANDED
235cdf0e10cSrcweir                                 : AccessibleEventId::LISTBOX_ENTRY_COLLAPSED;
236cdf0e10cSrcweir                         uno::Any aListBoxEntry;
237cdf0e10cSrcweir                         aListBoxEntry <<= xChild;
238cdf0e10cSrcweir                         NotifyAccessibleEvent( nAccEvent, Any(), aListBoxEntry );
239cdf0e10cSrcweir                         if ( getListBox() && getListBox()->HasFocus() )
240cdf0e10cSrcweir                         {
241cdf0e10cSrcweir                             NotifyAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, Any(), aListBoxEntry );
242cdf0e10cSrcweir                         }
243cdf0e10cSrcweir                     }
244cdf0e10cSrcweir                 }
245*21075d77SSteve Yin                 break;
246cdf0e10cSrcweir                 // <--
247cdf0e10cSrcweir 				default:
248cdf0e10cSrcweir 					VCLXAccessibleComponent::ProcessWindowEvent (rVclWindowEvent);
249cdf0e10cSrcweir 			}
250cdf0e10cSrcweir 		}
251cdf0e10cSrcweir 	}
252*21075d77SSteve Yin 
GetCurEventEntry(const VclWindowEvent & rVclWindowEvent)253*21075d77SSteve Yin 	AccessibleListBoxEntry* AccessibleListBox::GetCurEventEntry( const VclWindowEvent& rVclWindowEvent )
254*21075d77SSteve Yin 	{
255*21075d77SSteve Yin 		SvLBoxEntry* pEntry = static_cast< SvLBoxEntry* >( rVclWindowEvent.GetData() );
256*21075d77SSteve Yin 		if ( !pEntry )
257*21075d77SSteve Yin 			pEntry = getListBox()->GetCurEntry();
258*21075d77SSteve Yin 
259*21075d77SSteve Yin 		AccessibleListBoxEntry* pEntryFocus =static_cast< AccessibleListBoxEntry* >(m_xFocusedChild.get());
260*21075d77SSteve Yin 		if (pEntryFocus && pEntry && pEntry != pEntryFocus->GetSvLBoxEntry())
261*21075d77SSteve Yin 		{
262*21075d77SSteve Yin 			AccessibleListBoxEntry *pAccCurOptionEntry =NULL;
263*21075d77SSteve Yin 			MAP_ENTRY::iterator mi = m_mapEntry.find(pEntry);
264*21075d77SSteve Yin 			if (mi != m_mapEntry.end())
265*21075d77SSteve Yin 			{
266*21075d77SSteve Yin 				pAccCurOptionEntry= static_cast< AccessibleListBoxEntry* >(mi->second.get());
267*21075d77SSteve Yin 			}
268*21075d77SSteve Yin 			else
269*21075d77SSteve Yin 			{
270*21075d77SSteve Yin 				pAccCurOptionEntry =new AccessibleListBoxEntry( *getListBox(), pEntry, NULL );
271*21075d77SSteve Yin 				std::pair<MAP_ENTRY::iterator, bool> pairMi =  m_mapEntry.insert(MAP_ENTRY::value_type(pAccCurOptionEntry->GetSvLBoxEntry(),pAccCurOptionEntry));
272*21075d77SSteve Yin 				mi = pairMi.first;
273*21075d77SSteve Yin 			}
274*21075d77SSteve Yin 
275*21075d77SSteve Yin 			uno::Any aNewValue;
276*21075d77SSteve Yin 			aNewValue <<= mi->second;//xAcc
277*21075d77SSteve Yin 			NotifyAccessibleEvent( AccessibleEventId::CHILD, uno::Any(), aNewValue );//Add
278*21075d77SSteve Yin 
279*21075d77SSteve Yin 			return pAccCurOptionEntry;
280*21075d77SSteve Yin 		}
281*21075d77SSteve Yin 		else
282*21075d77SSteve Yin 		{
283*21075d77SSteve Yin 			return pEntryFocus;
284*21075d77SSteve Yin 		}
285*21075d77SSteve Yin 		return NULL;
286*21075d77SSteve Yin 	}
287*21075d77SSteve Yin 
RemoveChildEntries(SvLBoxEntry * pEntry)288*21075d77SSteve Yin 	void AccessibleListBox::RemoveChildEntries(SvLBoxEntry* pEntry)
289*21075d77SSteve Yin 	{
290*21075d77SSteve Yin 		MAP_ENTRY::iterator mi = m_mapEntry.find(pEntry);
291*21075d77SSteve Yin 		if ( mi != m_mapEntry.end() )
292*21075d77SSteve Yin 		{
293*21075d77SSteve Yin 			uno::Any aNewValue;
294*21075d77SSteve Yin 			uno::Any aOldValue;
295*21075d77SSteve Yin 			aOldValue <<= mi->second;
296*21075d77SSteve Yin 			NotifyAccessibleEvent( AccessibleEventId::CHILD, aOldValue, aNewValue );
297*21075d77SSteve Yin 
298*21075d77SSteve Yin 			m_mapEntry.erase(mi);
299*21075d77SSteve Yin 		}
300*21075d77SSteve Yin 
301*21075d77SSteve Yin 		SvTreeListBox* pBox = getListBox();
302*21075d77SSteve Yin 		SvLBoxEntry* pEntryChild = pBox->FirstChild(pEntry);
303*21075d77SSteve Yin 		while (pEntryChild)
304*21075d77SSteve Yin 		{
305*21075d77SSteve Yin 			RemoveChildEntries(pEntryChild);
306*21075d77SSteve Yin 			pEntryChild = pBox->NextSibling(pEntryChild);
307*21075d77SSteve Yin 		}
308*21075d77SSteve Yin 	}
309*21075d77SSteve Yin 
310cdf0e10cSrcweir 	// -----------------------------------------------------------------------------
ProcessWindowChildEvent(const VclWindowEvent & rVclWindowEvent)311cdf0e10cSrcweir     void AccessibleListBox::ProcessWindowChildEvent( const VclWindowEvent& rVclWindowEvent )
312cdf0e10cSrcweir     {
313cdf0e10cSrcweir         switch ( rVclWindowEvent.GetId() )
314cdf0e10cSrcweir         {
315cdf0e10cSrcweir             case VCLEVENT_WINDOW_SHOW:
316cdf0e10cSrcweir             case VCLEVENT_WINDOW_HIDE:
317cdf0e10cSrcweir             {
318cdf0e10cSrcweir             }
319cdf0e10cSrcweir             break;
320cdf0e10cSrcweir             default:
321cdf0e10cSrcweir             {
322cdf0e10cSrcweir                 VCLXAccessibleComponent::ProcessWindowChildEvent( rVclWindowEvent );
323cdf0e10cSrcweir             }
324cdf0e10cSrcweir             break;
325cdf0e10cSrcweir         }
326cdf0e10cSrcweir     }
327cdf0e10cSrcweir 
328cdf0e10cSrcweir 	// -----------------------------------------------------------------------------
329cdf0e10cSrcweir 	// XComponent
330cdf0e10cSrcweir 	// -----------------------------------------------------------------------------
disposing()331cdf0e10cSrcweir 	void SAL_CALL AccessibleListBox::disposing()
332cdf0e10cSrcweir 	{
333cdf0e10cSrcweir 		::osl::MutexGuard aGuard( m_aMutex );
334cdf0e10cSrcweir 
335*21075d77SSteve Yin 		m_mapEntry.clear();
336cdf0e10cSrcweir 		VCLXAccessibleComponent::disposing();
337cdf0e10cSrcweir 	    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 
395cdf0e10cSrcweir         sal_Int32 nCount = 0;
396cdf0e10cSrcweir         SvTreeListBox* pSvTreeListBox = getListBox();
397cdf0e10cSrcweir         if ( pSvTreeListBox )
398cdf0e10cSrcweir             nCount = pSvTreeListBox->GetLevelChildCount( NULL );
399cdf0e10cSrcweir 
400cdf0e10cSrcweir         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 
412*21075d77SSteve Yin 		// Solution: Set the parameter of the parent to null to let entry determine the parent by itself
413*21075d77SSteve Yin 		//return new AccessibleListBoxEntry( *getListBox(), pEntry, this );
414*21075d77SSteve 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()425*21075d77SSteve Yin 	sal_Int32 SAL_CALL AccessibleListBox::getRoleType()
426*21075d77SSteve Yin 	{
427*21075d77SSteve Yin 		sal_Int32 nCase = 0;
428*21075d77SSteve Yin 		SvLBoxEntry* pEntry = getListBox()->GetEntry(0);
429*21075d77SSteve Yin 		if ( pEntry )
430*21075d77SSteve Yin 		{
431*21075d77SSteve Yin 			if( pEntry->HasChildsOnDemand() || getListBox()->GetChildCount(pEntry) > 0  )
432*21075d77SSteve Yin 			{
433*21075d77SSteve Yin 				nCase = 1;
434*21075d77SSteve Yin 				return nCase;
435*21075d77SSteve Yin 			}
436*21075d77SSteve Yin 		}
437*21075d77SSteve Yin 
438*21075d77SSteve Yin 		sal_Bool bHasButtons = (getListBox()->GetStyle() & WB_HASBUTTONS)!=0;
439*21075d77SSteve Yin 		if( !(getListBox()->GetTreeFlags() & TREEFLAG_CHKBTN) )
440*21075d77SSteve Yin 		{
441*21075d77SSteve Yin 			if( bHasButtons )
442*21075d77SSteve Yin 				nCase = 1;
443*21075d77SSteve Yin 		}
444*21075d77SSteve Yin 		else
445*21075d77SSteve Yin 		{
446*21075d77SSteve Yin 			if( bHasButtons )
447*21075d77SSteve Yin 				nCase = 2;
448*21075d77SSteve Yin 			 else
449*21075d77SSteve Yin 				nCase = 3;
450*21075d77SSteve Yin 		}
451*21075d77SSteve Yin 		return nCase;
452*21075d77SSteve Yin 	}
getAccessibleRole()453cdf0e10cSrcweir 	sal_Int16 SAL_CALL AccessibleListBox::getAccessibleRole(  ) throw (RuntimeException)
454cdf0e10cSrcweir 	{
455*21075d77SSteve Yin 		if(getListBox())
456*21075d77SSteve Yin 		{
457*21075d77SSteve Yin 			short nType = getListBox()->GetAllEntriesAccessibleRoleType();
458*21075d77SSteve Yin 			if( nType == TREEBOX_ALLITEM_ACCROLE_TYPE_TREE)
459*21075d77SSteve Yin 					return AccessibleRole::TREE;
460*21075d77SSteve Yin 			else if( nType == TREEBOX_ALLITEM_ACCROLE_TYPE_LIST)
461*21075d77SSteve Yin 					return AccessibleRole::LIST;
462*21075d77SSteve Yin 		}
463*21075d77SSteve Yin 
464*21075d77SSteve Yin 		//o is: return AccessibleRole::TREE;
465*21075d77SSteve Yin 		sal_Bool bHasButtons = (getListBox()->GetStyle() & WB_HASBUTTONS)!=0;
466*21075d77SSteve Yin 		if(!bHasButtons && (getListBox()->GetTreeFlags() & TREEFLAG_CHKBTN))
467*21075d77SSteve Yin 			return AccessibleRole::LIST;
468*21075d77SSteve Yin 		else
469*21075d77SSteve Yin 			if(getRoleType() == 0)
470*21075d77SSteve Yin 				return AccessibleRole::LIST;
471*21075d77SSteve Yin 			else
472*21075d77SSteve 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 	{
495cdf0e10cSrcweir     	::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 	{
508cdf0e10cSrcweir     	::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 	{
521cdf0e10cSrcweir     	::comphelper::OExternalLockGuard aGuard( this );
522cdf0e10cSrcweir 
523cdf0e10cSrcweir 		ensureAlive();
524cdf0e10cSrcweir 
525cdf0e10cSrcweir     	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 	{
537cdf0e10cSrcweir     	::comphelper::OExternalLockGuard aGuard( this );
538cdf0e10cSrcweir 
539cdf0e10cSrcweir 		ensureAlive();
540cdf0e10cSrcweir 
541cdf0e10cSrcweir     	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 	{
553cdf0e10cSrcweir     	::comphelper::OExternalLockGuard aGuard( this );
554cdf0e10cSrcweir 
555cdf0e10cSrcweir 		ensureAlive();
556*21075d77SSteve Yin 
557*21075d77SSteve Yin 
558*21075d77SSteve Yin //     	sal_Int32 i, nSelCount = 0, nCount = 0;
559*21075d77SSteve Yin // 		nCount = getListBox()->GetLevelChildCount( NULL );
560*21075d77SSteve Yin // 		for ( i = 0; i < nCount; ++i )
561*21075d77SSteve Yin // 		{
562*21075d77SSteve Yin // 			SvLBoxEntry* pEntry = getListBox()->GetEntry( i );
563*21075d77SSteve Yin // 			if ( getListBox()->IsSelected( pEntry ) )
564*21075d77SSteve Yin // 				++nSelCount;
565*21075d77SSteve Yin // 		}
566*21075d77SSteve Yin //    	return nSelCount;
567*21075d77SSteve Yin 
568*21075d77SSteve Yin 		int nTestCount =  getListBox()->GetSelectionCount();
569*21075d77SSteve Yin 		return nTestCount;
570cdf0e10cSrcweir 	}
571cdf0e10cSrcweir 	// -----------------------------------------------------------------------------
getSelectedAccessibleChild(sal_Int32 nSelectedChildIndex)572cdf0e10cSrcweir 	Reference< XAccessible > SAL_CALL AccessibleListBox::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
573cdf0e10cSrcweir 	{
574cdf0e10cSrcweir     	::comphelper::OExternalLockGuard aGuard( this );
575cdf0e10cSrcweir 
576cdf0e10cSrcweir 		ensureAlive();
577cdf0e10cSrcweir 
578cdf0e10cSrcweir 		if ( nSelectedChildIndex < 0 || nSelectedChildIndex >= getSelectedAccessibleChildCount() )
579cdf0e10cSrcweir 			throw IndexOutOfBoundsException();
580cdf0e10cSrcweir 
581cdf0e10cSrcweir 		Reference< XAccessible > xChild;
582cdf0e10cSrcweir     	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 			{
592*21075d77SSteve Yin 				// Solution: Set the parameter of the parent to null to let entry determine the parent by itself
593*21075d77SSteve Yin 				//xChild = new AccessibleListBoxEntry( *getListBox(), pEntry, this );
594*21075d77SSteve 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 	{
604cdf0e10cSrcweir     	::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 //........................................................................
631cdf0e10cSrcweir 
632