xref: /AOO41X/main/accessibility/source/standard/vclxaccessiblelist.cxx (revision 21075d779129cb18aa18227e3636dda359ad2404)
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
10cdf0e10cSrcweir  *
110841af79SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
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.
19cdf0e10cSrcweir  *
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/standard/vclxaccessiblelist.hxx>
27cdf0e10cSrcweir #include <accessibility/standard/vclxaccessiblelistitem.hxx>
28cdf0e10cSrcweir #include <accessibility/helper/listboxhelper.hxx>
29cdf0e10cSrcweir 
30cdf0e10cSrcweir #include <unotools/accessiblestatesethelper.hxx>
31cdf0e10cSrcweir #include <com/sun/star/accessibility/AccessibleStateType.hpp>
32cdf0e10cSrcweir #include <com/sun/star/accessibility/AccessibleEventId.hpp>
33cdf0e10cSrcweir #include <com/sun/star/accessibility/AccessibleRole.hpp>
34cdf0e10cSrcweir #include <vcl/svapp.hxx>
35cdf0e10cSrcweir #include <vcl/combobox.hxx>
36cdf0e10cSrcweir #include <vcl/lstbox.hxx>
37cdf0e10cSrcweir #include <toolkit/helper/convert.hxx>
38cdf0e10cSrcweir 
39*21075d77SSteve Yin #ifndef _UTL_ACCESSIBLERELATIONSETHELPER_HXX_
40*21075d77SSteve Yin #include <unotools/accessiblerelationsethelper.hxx>
41*21075d77SSteve Yin #endif
42*21075d77SSteve Yin #ifndef _COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLERELATIONTYPE_HPP_
43*21075d77SSteve Yin #include <com/sun/star/accessibility/AccessibleRelationType.hpp>
44*21075d77SSteve Yin #endif
45cdf0e10cSrcweir using namespace ::com::sun::star;
46cdf0e10cSrcweir using namespace ::com::sun::star::uno;
47cdf0e10cSrcweir using namespace ::com::sun::star::lang;
48cdf0e10cSrcweir using namespace ::com::sun::star::beans;
49cdf0e10cSrcweir using namespace ::com::sun::star::accessibility;
50cdf0e10cSrcweir using namespace ::accessibility;
51cdf0e10cSrcweir 
52cdf0e10cSrcweir namespace
53cdf0e10cSrcweir {
54cdf0e10cSrcweir 	void checkSelection_Impl( sal_Int32 _nIndex, const IComboListBoxHelper& _rListBox, sal_Bool bSelected )
55cdf0e10cSrcweir         throw (::com::sun::star::lang::IndexOutOfBoundsException)
56cdf0e10cSrcweir 	{
57cdf0e10cSrcweir 		sal_Int32 nCount = bSelected ? (sal_Int32)_rListBox.GetSelectEntryCount()
58cdf0e10cSrcweir 									 : (sal_Int32)_rListBox.GetEntryCount();
59cdf0e10cSrcweir 		if ( _nIndex < 0 || _nIndex >= nCount )
60cdf0e10cSrcweir 			throw ::com::sun::star::lang::IndexOutOfBoundsException();
61cdf0e10cSrcweir 	}
62cdf0e10cSrcweir }
63cdf0e10cSrcweir 
64cdf0e10cSrcweir VCLXAccessibleList::VCLXAccessibleList (VCLXWindow* pVCLWindow, BoxType aBoxType,
65cdf0e10cSrcweir 										const Reference< XAccessible >& _xParent)
66cdf0e10cSrcweir     : VCLXAccessibleComponent	(pVCLWindow),
67cdf0e10cSrcweir       m_aBoxType				(aBoxType),
68cdf0e10cSrcweir       m_nVisibleLineCount		(0),
69cdf0e10cSrcweir       m_nIndexInParent			(DEFAULT_INDEX_IN_PARENT),
70cdf0e10cSrcweir 	  m_nLastTopEntry			( 0 ),
71cdf0e10cSrcweir 	  m_nLastSelectedPos		( LISTBOX_ENTRY_NOTFOUND ),
72cdf0e10cSrcweir 	  m_bDisableProcessEvent	( false ),
73cdf0e10cSrcweir 	  m_bVisible				( true ),
74*21075d77SSteve Yin 	m_nCurSelectedPos		( LISTBOX_ENTRY_NOTFOUND ),
75cdf0e10cSrcweir       m_xParent                 ( _xParent )
76cdf0e10cSrcweir {
77cdf0e10cSrcweir     // Because combo boxes and list boxes have the no common interface for
78cdf0e10cSrcweir     // methods with identical signature we have to write down twice the
79cdf0e10cSrcweir     // same code.
80cdf0e10cSrcweir     switch (m_aBoxType)
81cdf0e10cSrcweir     {
82cdf0e10cSrcweir         case COMBOBOX:
83cdf0e10cSrcweir         {
84cdf0e10cSrcweir             ComboBox* pBox = static_cast<ComboBox*>(GetWindow());
85cdf0e10cSrcweir             if ( pBox != NULL )
86cdf0e10cSrcweir                 m_pListBoxHelper = new VCLListBoxHelper<ComboBox> (*pBox);
87cdf0e10cSrcweir             break;
88cdf0e10cSrcweir         }
89cdf0e10cSrcweir 
90cdf0e10cSrcweir         case LISTBOX:
91cdf0e10cSrcweir         {
92cdf0e10cSrcweir             ListBox* pBox = static_cast<ListBox*>(GetWindow());
93cdf0e10cSrcweir             if ( pBox != NULL )
94cdf0e10cSrcweir                 m_pListBoxHelper = new VCLListBoxHelper<ListBox> (*pBox);
95cdf0e10cSrcweir             break;
96cdf0e10cSrcweir         }
97cdf0e10cSrcweir     }
98cdf0e10cSrcweir     UpdateVisibleLineCount();
99*21075d77SSteve Yin 	m_nCurSelectedPos=m_pListBoxHelper->GetSelectEntryPos();
100cdf0e10cSrcweir 
101cdf0e10cSrcweir 	sal_uInt16 nCount = static_cast<sal_uInt16>(getAccessibleChildCount());
102cdf0e10cSrcweir 	m_aAccessibleChildren.reserve(nCount);
103cdf0e10cSrcweir }
104cdf0e10cSrcweir // -----------------------------------------------------------------------------
105cdf0e10cSrcweir 
106cdf0e10cSrcweir VCLXAccessibleList::~VCLXAccessibleList (void)
107cdf0e10cSrcweir {
108cdf0e10cSrcweir     delete m_pListBoxHelper;
109cdf0e10cSrcweir }
110cdf0e10cSrcweir // -----------------------------------------------------------------------------
111cdf0e10cSrcweir 
112cdf0e10cSrcweir void VCLXAccessibleList::SetIndexInParent (sal_Int32 nIndex)
113cdf0e10cSrcweir {
114cdf0e10cSrcweir     m_nIndexInParent = nIndex;
115cdf0e10cSrcweir }
116cdf0e10cSrcweir // -----------------------------------------------------------------------------
117cdf0e10cSrcweir 
118cdf0e10cSrcweir void SAL_CALL VCLXAccessibleList::disposing (void)
119cdf0e10cSrcweir {
120cdf0e10cSrcweir 	VCLXAccessibleComponent::disposing();
121cdf0e10cSrcweir 
122cdf0e10cSrcweir     // Dispose all items in the list.
123cdf0e10cSrcweir 	clearItems();
124cdf0e10cSrcweir 
125cdf0e10cSrcweir 	delete m_pListBoxHelper;
126cdf0e10cSrcweir 	m_pListBoxHelper = NULL;
127cdf0e10cSrcweir }
128cdf0e10cSrcweir // -----------------------------------------------------------------------------
129cdf0e10cSrcweir 
130cdf0e10cSrcweir void VCLXAccessibleList::clearItems()
131cdf0e10cSrcweir {
132cdf0e10cSrcweir //	ListItems::iterator aEnd = m_aAccessibleChildren.end();
133cdf0e10cSrcweir //	for (ListItems::iterator aIter = m_aAccessibleChildren.begin(); aIter != aEnd; ++aIter)
134cdf0e10cSrcweir //		::comphelper::disposeComponent(*aIter);
135cdf0e10cSrcweir 
136cdf0e10cSrcweir     // Clear the list itself and delete all the rest.
137cdf0e10cSrcweir 	ListItems().swap(m_aAccessibleChildren); // clear and minimize
138cdf0e10cSrcweir }
139cdf0e10cSrcweir // -----------------------------------------------------------------------------
140cdf0e10cSrcweir 
141cdf0e10cSrcweir void VCLXAccessibleList::FillAccessibleStateSet (utl::AccessibleStateSetHelper& rStateSet)
142cdf0e10cSrcweir {
143cdf0e10cSrcweir 	vos::OGuard aSolarGuard( Application::GetSolarMutex() );
144cdf0e10cSrcweir 
145cdf0e10cSrcweir 	VCLXAccessibleComponent::FillAccessibleStateSet( rStateSet );
146cdf0e10cSrcweir 	// check if our list should be visible
147cdf0e10cSrcweir 	if (	m_pListBoxHelper
148cdf0e10cSrcweir 		&& (m_pListBoxHelper->GetStyle() & WB_DROPDOWN ) == WB_DROPDOWN
149cdf0e10cSrcweir 		&& !m_pListBoxHelper->IsInDropDown() )
150cdf0e10cSrcweir 	{
151cdf0e10cSrcweir 		rStateSet.RemoveState (AccessibleStateType::VISIBLE);
152cdf0e10cSrcweir 		rStateSet.RemoveState (AccessibleStateType::SHOWING);
153cdf0e10cSrcweir 		m_bVisible = false;
154cdf0e10cSrcweir 	}
155cdf0e10cSrcweir 
156cdf0e10cSrcweir     // Both the combo box and list box are handled identical in the
157cdf0e10cSrcweir     // following but for some reason they don't have a common interface for
158cdf0e10cSrcweir     // the methods used.
159cdf0e10cSrcweir 	if ( m_pListBoxHelper )
160cdf0e10cSrcweir 	{
161cdf0e10cSrcweir         if ( m_pListBoxHelper->IsMultiSelectionEnabled() )
162cdf0e10cSrcweir             rStateSet.AddState( AccessibleStateType::MULTI_SELECTABLE);
163cdf0e10cSrcweir 		rStateSet.AddState (AccessibleStateType::FOCUSABLE);
164cdf0e10cSrcweir         // All children are transient.
165cdf0e10cSrcweir         rStateSet.AddState (AccessibleStateType::MANAGES_DESCENDANTS);
166cdf0e10cSrcweir 	}
167cdf0e10cSrcweir }
168cdf0e10cSrcweir // -----------------------------------------------------------------------------
169cdf0e10cSrcweir void VCLXAccessibleList::notifyVisibleStates(sal_Bool _bSetNew )
170cdf0e10cSrcweir {
171cdf0e10cSrcweir 	m_bVisible = _bSetNew ? true : false;
172cdf0e10cSrcweir 	Any aOldValue, aNewValue;
173cdf0e10cSrcweir 	(_bSetNew ? aNewValue : aOldValue ) <<= AccessibleStateType::VISIBLE;
174cdf0e10cSrcweir 	NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
175cdf0e10cSrcweir 	(_bSetNew ? aNewValue : aOldValue ) <<= AccessibleStateType::SHOWING;
176cdf0e10cSrcweir 	NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
177cdf0e10cSrcweir 
178cdf0e10cSrcweir 	ListItems::iterator aIter = m_aAccessibleChildren.begin();
179cdf0e10cSrcweir 	ListItems::iterator aEnd = m_aAccessibleChildren.end();
180cdf0e10cSrcweir     UpdateVisibleLineCount();
181cdf0e10cSrcweir 	// adjust the index inside the VCLXAccessibleListItem
182cdf0e10cSrcweir 	for (;aIter != aEnd ; ++aIter)
183cdf0e10cSrcweir 	{
184cdf0e10cSrcweir 		Reference< XAccessible > xHold = *aIter;
185cdf0e10cSrcweir 		VCLXAccessibleListItem* pItem = static_cast<VCLXAccessibleListItem*>(xHold.get());
186cdf0e10cSrcweir 		if ( pItem )
187cdf0e10cSrcweir 		{
188cdf0e10cSrcweir 			sal_uInt16 nTopEntry = 0;
189cdf0e10cSrcweir 			if ( m_pListBoxHelper )
190cdf0e10cSrcweir 				nTopEntry = m_pListBoxHelper->GetTopEntry();
191cdf0e10cSrcweir             sal_uInt16 nPos = (sal_uInt16)(aIter - m_aAccessibleChildren.begin());
192cdf0e10cSrcweir 			sal_Bool bVisible = ( nPos>=nTopEntry && nPos<( nTopEntry + m_nVisibleLineCount ) );
193cdf0e10cSrcweir 			pItem->SetVisible( m_bVisible && bVisible );
194cdf0e10cSrcweir 		}
195cdf0e10cSrcweir 
196cdf0e10cSrcweir 	}
197cdf0e10cSrcweir }
198cdf0e10cSrcweir // -----------------------------------------------------------------------------
199*21075d77SSteve Yin void VCLXAccessibleList::UpdateSelection_Acc (::rtl::OUString sTextOfSelectedItem, bool b_IsDropDownList)
200*21075d77SSteve Yin {
201*21075d77SSteve Yin     if ( m_aBoxType == COMBOBOX )
202*21075d77SSteve Yin     {
203*21075d77SSteve Yin         ComboBox* pBox = static_cast<ComboBox*>(GetWindow());
204*21075d77SSteve Yin         if ( pBox != NULL )
205*21075d77SSteve Yin         {
206*21075d77SSteve Yin 		// Find the index of the selected item inside the VCL control...
207*21075d77SSteve Yin 		sal_uInt16 nIndex = pBox->GetEntryPos (XubString(sTextOfSelectedItem));
208*21075d77SSteve Yin 		// ...and then find the associated accessibility object.
209*21075d77SSteve Yin 		if ( nIndex == LISTBOX_ENTRY_NOTFOUND )
210*21075d77SSteve Yin 			nIndex = 0;
211*21075d77SSteve Yin 		UpdateSelection_Impl_Acc(b_IsDropDownList);
212*21075d77SSteve Yin         }
213*21075d77SSteve Yin     }
214*21075d77SSteve Yin }
215*21075d77SSteve Yin 
216*21075d77SSteve Yin // -----------------------------------------------------------------------------
217*21075d77SSteve Yin void VCLXAccessibleList::UpdateSelection_Impl_Acc(bool b_IsDropDownList)
218*21075d77SSteve Yin {
219*21075d77SSteve Yin 	uno::Any aOldValue, aNewValue;
220*21075d77SSteve Yin 	VCLXAccessibleListItem* pCurItem =NULL;
221*21075d77SSteve Yin 
222*21075d77SSteve Yin 	{
223*21075d77SSteve Yin 		vos::OGuard aSolarGuard( Application::GetSolarMutex() );
224*21075d77SSteve Yin 		::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
225*21075d77SSteve Yin 	    	Reference< XAccessible > xNewAcc;
226*21075d77SSteve Yin 		if ( m_pListBoxHelper )
227*21075d77SSteve Yin 		{
228*21075d77SSteve Yin 			sal_uInt16 i=0;
229*21075d77SSteve Yin 			m_nCurSelectedPos = LISTBOX_ENTRY_NOTFOUND;
230*21075d77SSteve Yin 			for ( ListItems::iterator aIter = m_aAccessibleChildren.begin();
231*21075d77SSteve Yin 				  aIter != m_aAccessibleChildren.end(); ++aIter,++i)
232*21075d77SSteve Yin 			{
233*21075d77SSteve Yin 				Reference< XAccessible > xHold = *aIter;
234*21075d77SSteve Yin 				if ( xHold.is() )
235*21075d77SSteve Yin 				{
236*21075d77SSteve Yin 					VCLXAccessibleListItem* pItem = static_cast< VCLXAccessibleListItem* >( xHold.get() );
237*21075d77SSteve Yin 					// Retrieve the item's index from the list entry.
238*21075d77SSteve Yin 					sal_Bool bNowSelected = m_pListBoxHelper->IsEntryPosSelected (i);
239*21075d77SSteve Yin 					if (bNowSelected)
240*21075d77SSteve Yin 						m_nCurSelectedPos = i;
241*21075d77SSteve Yin 
242*21075d77SSteve Yin 					if ( bNowSelected && !pItem->IsSelected() )
243*21075d77SSteve Yin 					{
244*21075d77SSteve Yin 						xNewAcc = *aIter;
245*21075d77SSteve Yin 						aNewValue <<= xNewAcc;
246*21075d77SSteve Yin 
247*21075d77SSteve Yin 						pCurItem = pItem;
248*21075d77SSteve Yin 
249*21075d77SSteve Yin 					}
250*21075d77SSteve Yin 					else if ( pItem->IsSelected() )
251*21075d77SSteve Yin 						m_nLastSelectedPos = i;
252*21075d77SSteve Yin 
253*21075d77SSteve Yin 					pItem->SetSelected( bNowSelected );
254*21075d77SSteve Yin 				}
255*21075d77SSteve Yin 				else
256*21075d77SSteve Yin 				{ // it could happen that a child was not created before
257*21075d77SSteve Yin 					checkEntrySelected(i,aNewValue,xNewAcc);
258*21075d77SSteve Yin 				}
259*21075d77SSteve Yin 			}
260*21075d77SSteve Yin 			sal_uInt16 nCount = m_pListBoxHelper->GetEntryCount();
261*21075d77SSteve Yin 			if ( i < nCount ) // here we have to check the if any other listbox entry is selected
262*21075d77SSteve Yin 			{
263*21075d77SSteve Yin 				for (; i < nCount && !checkEntrySelected(i,aNewValue,xNewAcc) ;++i )
264*21075d77SSteve Yin 					;
265*21075d77SSteve Yin 			}
266*21075d77SSteve Yin 			if ( xNewAcc.is() && GetWindow()->HasFocus() )
267*21075d77SSteve Yin 			{
268*21075d77SSteve Yin 				if ( m_nLastSelectedPos != LISTBOX_ENTRY_NOTFOUND )
269*21075d77SSteve Yin 					aOldValue <<= getAccessibleChild( (sal_Int32)m_nLastSelectedPos );
270*21075d77SSteve Yin 				aNewValue <<= xNewAcc;
271*21075d77SSteve Yin 			}
272*21075d77SSteve Yin 		}
273*21075d77SSteve Yin 	}
274*21075d77SSteve Yin 	if (m_aBoxType == COMBOBOX && b_IsDropDownList)
275*21075d77SSteve Yin 	{
276*21075d77SSteve Yin 		//VCLXAccessibleDropDownComboBox
277*21075d77SSteve Yin 		//when in list is dropped down, xText = NULL
278*21075d77SSteve Yin 		if (m_pListBoxHelper->IsInDropDown())
279*21075d77SSteve Yin 		{
280*21075d77SSteve Yin 			if ( aNewValue.hasValue() || aOldValue.hasValue() )
281*21075d77SSteve Yin 			{
282*21075d77SSteve Yin 				NotifyAccessibleEvent(
283*21075d77SSteve Yin 					AccessibleEventId::ACTIVE_DESCENDANT_CHANGED,
284*21075d77SSteve Yin 					aOldValue,
285*21075d77SSteve Yin 					aNewValue );
286*21075d77SSteve Yin 
287*21075d77SSteve Yin 				NotifyListItem(aNewValue);
288*21075d77SSteve Yin 
289*21075d77SSteve Yin 			}
290*21075d77SSteve Yin 		}
291*21075d77SSteve Yin 	}
292*21075d77SSteve Yin 	else if (m_aBoxType == COMBOBOX && !b_IsDropDownList)
293*21075d77SSteve Yin 	{
294*21075d77SSteve Yin 		//VCLXAccessibleComboBox
295*21075d77SSteve Yin 		NotifyAccessibleEvent( AccessibleEventId::SELECTION_CHANGED, uno::Any(), uno::Any() );
296*21075d77SSteve Yin 	}
297*21075d77SSteve Yin 	else if (m_aBoxType == LISTBOX && b_IsDropDownList)
298*21075d77SSteve Yin 	{
299*21075d77SSteve Yin 		//VCLXAccessibleDropdownListBox
300*21075d77SSteve Yin 		//when in list is dropped down, xText = NULL
301*21075d77SSteve Yin 		if (m_pListBoxHelper->IsInDropDown())
302*21075d77SSteve Yin 		{
303*21075d77SSteve Yin 			if ( aNewValue.hasValue() || aOldValue.hasValue() )
304*21075d77SSteve Yin 			{
305*21075d77SSteve Yin 				NotifyAccessibleEvent(
306*21075d77SSteve Yin 					AccessibleEventId::ACTIVE_DESCENDANT_CHANGED,
307*21075d77SSteve Yin 					aOldValue,
308*21075d77SSteve Yin 					aNewValue );
309*21075d77SSteve Yin 
310*21075d77SSteve Yin 				NotifyListItem(aNewValue);
311*21075d77SSteve Yin 			}
312*21075d77SSteve Yin 		}
313*21075d77SSteve Yin 	}
314*21075d77SSteve Yin 	else if (m_aBoxType == LISTBOX && !b_IsDropDownList)
315*21075d77SSteve Yin 	{
316*21075d77SSteve Yin 		//VCLXAccessibleListBox, xText = NULL.
317*21075d77SSteve Yin 
318*21075d77SSteve Yin 
319*21075d77SSteve Yin 		if ( aNewValue.hasValue())
320*21075d77SSteve Yin 		{
321*21075d77SSteve Yin 			NotifyListItem(aNewValue);
322*21075d77SSteve Yin 		}
323*21075d77SSteve Yin 	}
324*21075d77SSteve Yin }
325*21075d77SSteve Yin void VCLXAccessibleList::NotifyListItem(::com::sun::star::uno::Any& val)
326*21075d77SSteve Yin {
327*21075d77SSteve Yin 	Reference< XAccessible > xCurItem;
328*21075d77SSteve Yin 	val >>= xCurItem;
329*21075d77SSteve Yin 	if (xCurItem.is())
330*21075d77SSteve Yin 	{
331*21075d77SSteve Yin 		VCLXAccessibleListItem* pCurItem = static_cast< VCLXAccessibleListItem* >(xCurItem.get());
332*21075d77SSteve Yin 		if (pCurItem)
333*21075d77SSteve Yin 		{
334*21075d77SSteve Yin 			pCurItem->NotifyAccessibleEvent(AccessibleEventId::SELECTION_CHANGED,Any(),Any());
335*21075d77SSteve Yin 		}
336*21075d77SSteve Yin 	}
337*21075d77SSteve Yin }
338*21075d77SSteve Yin 
339*21075d77SSteve Yin 
340*21075d77SSteve Yin void VCLXAccessibleList::UpdateFocus_Impl_Acc (sal_uInt16 nPos ,bool b_IsDropDownList)
341*21075d77SSteve Yin {
342*21075d77SSteve Yin 	if (!(m_aBoxType == LISTBOX && !b_IsDropDownList))
343*21075d77SSteve Yin 	{
344*21075d77SSteve Yin 		return ;
345*21075d77SSteve Yin 	}
346*21075d77SSteve Yin     Reference<XAccessible> xChild= CreateChild(nPos);
347*21075d77SSteve Yin 	if ( !xChild.is() )
348*21075d77SSteve Yin 	{
349*21075d77SSteve Yin 		return ;
350*21075d77SSteve Yin 	}
351*21075d77SSteve Yin 	m_nCurSelectedPos = nPos;
352*21075d77SSteve Yin 	uno::Any aOldValue, aNewValue;
353*21075d77SSteve Yin 	aNewValue <<= xChild;
354*21075d77SSteve Yin 
355*21075d77SSteve Yin 	NotifyAccessibleEvent(
356*21075d77SSteve Yin 			AccessibleEventId::ACTIVE_DESCENDANT_CHANGED,
357*21075d77SSteve Yin 			aOldValue,
358*21075d77SSteve Yin 			aNewValue );
359*21075d77SSteve Yin }
360*21075d77SSteve Yin 
361*21075d77SSteve Yin // -----------------------------------------------------------------------------
362*21075d77SSteve Yin void VCLXAccessibleList::ProcessWindowEvent (const VclWindowEvent& rVclWindowEvent,  bool b_IsDropDownList)
363*21075d77SSteve Yin {
364*21075d77SSteve Yin 	switch ( rVclWindowEvent.GetId() )
365*21075d77SSteve Yin       {
366*21075d77SSteve Yin 		case VCLEVENT_LISTBOX_SELECT:
367*21075d77SSteve Yin 			if ( !m_bDisableProcessEvent )
368*21075d77SSteve Yin 				UpdateSelection_Impl_Acc(b_IsDropDownList);
369*21075d77SSteve Yin 			break;
370*21075d77SSteve Yin 		case VCLEVENT_LISTBOX_FOCUSITEMCHANGED:
371*21075d77SSteve Yin 			if ( !m_bDisableProcessEvent )
372*21075d77SSteve Yin 				UpdateFocus_Impl_Acc((sal_uInt16)reinterpret_cast<sal_uInt32>(rVclWindowEvent.GetData()),b_IsDropDownList);
373*21075d77SSteve Yin 			break;
374*21075d77SSteve Yin 		case VCLEVENT_WINDOW_GETFOCUS:
375*21075d77SSteve Yin 			break;
376*21075d77SSteve Yin 		case VCLEVENT_CONTROL_GETFOCUS:
377*21075d77SSteve Yin 			{
378*21075d77SSteve Yin 				VCLXAccessibleComponent::ProcessWindowEvent (rVclWindowEvent);
379*21075d77SSteve Yin 				if (m_aBoxType == COMBOBOX && b_IsDropDownList)
380*21075d77SSteve Yin 				{
381*21075d77SSteve Yin 					//VCLXAccessibleDropDownComboBox
382*21075d77SSteve Yin 				}
383*21075d77SSteve Yin 				else if (m_aBoxType == LISTBOX && b_IsDropDownList)
384*21075d77SSteve Yin 				{
385*21075d77SSteve Yin 				}
386*21075d77SSteve Yin 				else if ( m_aBoxType == LISTBOX && !b_IsDropDownList)
387*21075d77SSteve Yin 				{
388*21075d77SSteve Yin 					if ( m_pListBoxHelper )
389*21075d77SSteve Yin 					{
390*21075d77SSteve Yin 						uno::Any	aOldValue,
391*21075d77SSteve Yin 									aNewValue;
392*21075d77SSteve Yin 						sal_uInt16 nPos = m_nCurSelectedPos; //m_pListBoxHelper->GetSelectEntryPos();
393*21075d77SSteve Yin 
394*21075d77SSteve Yin 						if ( nPos == LISTBOX_ENTRY_NOTFOUND )
395*21075d77SSteve Yin 							nPos = m_pListBoxHelper->GetTopEntry();
396*21075d77SSteve Yin 						if ( nPos != LISTBOX_ENTRY_NOTFOUND )
397*21075d77SSteve Yin 							aNewValue <<= CreateChild(nPos);
398*21075d77SSteve Yin 						NotifyAccessibleEvent(	AccessibleEventId::ACTIVE_DESCENDANT_CHANGED,
399*21075d77SSteve Yin 												aOldValue,
400*21075d77SSteve Yin 												aNewValue );
401*21075d77SSteve Yin 					}
402*21075d77SSteve Yin 				}
403*21075d77SSteve Yin 			}
404*21075d77SSteve Yin 			break;
405*21075d77SSteve Yin 		default:
406*21075d77SSteve Yin 			break;
407*21075d77SSteve Yin 	}
408*21075d77SSteve Yin 
409*21075d77SSteve Yin }
410*21075d77SSteve Yin // -----------------------------------------------------------------------------
411cdf0e10cSrcweir void VCLXAccessibleList::ProcessWindowEvent (const VclWindowEvent& rVclWindowEvent)
412cdf0e10cSrcweir {
413cdf0e10cSrcweir     // Create a reference to this object to prevent an early release of the
414cdf0e10cSrcweir     // listbox (VCLEVENT_OBJECT_DYING).
415cdf0e10cSrcweir 	Reference< XAccessible > xTemp = this;
416cdf0e10cSrcweir 
417cdf0e10cSrcweir 	switch ( rVclWindowEvent.GetId() )
418cdf0e10cSrcweir     {
419cdf0e10cSrcweir 		case VCLEVENT_DROPDOWN_OPEN:
420cdf0e10cSrcweir 			notifyVisibleStates(sal_True);
421cdf0e10cSrcweir 			break;
422cdf0e10cSrcweir 		case VCLEVENT_DROPDOWN_CLOSE:
423cdf0e10cSrcweir 			notifyVisibleStates(sal_False);
424cdf0e10cSrcweir 			break;
425cdf0e10cSrcweir 		case VCLEVENT_LISTBOX_SCROLLED:
426cdf0e10cSrcweir 		case VCLEVENT_COMBOBOX_SCROLLED:
427cdf0e10cSrcweir 			UpdateEntryRange_Impl();
428cdf0e10cSrcweir 			break;
429*21075d77SSteve Yin 		// IAccessible2 implementation, 2009
430*21075d77SSteve Yin 		/*
431cdf0e10cSrcweir 		case VCLEVENT_LISTBOX_SELECT:
432cdf0e10cSrcweir 			if ( !m_bDisableProcessEvent )
433cdf0e10cSrcweir 				UpdateSelection_Impl();
434cdf0e10cSrcweir 			break;
435*21075d77SSteve Yin 		*/
436cdf0e10cSrcweir 		// The selection events VCLEVENT_COMBOBOX_SELECT and
437cdf0e10cSrcweir 		// VCLEVENT_COMBOBOX_DESELECT are not handled here because here we
438cdf0e10cSrcweir 		// have no access to the edit field.  Its text is necessary to
439cdf0e10cSrcweir 		// identify the currently selected item.
440cdf0e10cSrcweir 
441cdf0e10cSrcweir 		case VCLEVENT_OBJECT_DYING:
442cdf0e10cSrcweir 		{
443cdf0e10cSrcweir             dispose();
444cdf0e10cSrcweir 
445cdf0e10cSrcweir             VCLXAccessibleComponent::ProcessWindowEvent (rVclWindowEvent);
446cdf0e10cSrcweir             break;
447cdf0e10cSrcweir 		}
448cdf0e10cSrcweir 
449cdf0e10cSrcweir         case VCLEVENT_LISTBOX_ITEMREMOVED:
450cdf0e10cSrcweir         case VCLEVENT_COMBOBOX_ITEMREMOVED:
451cdf0e10cSrcweir             HandleChangedItemList (false, reinterpret_cast<sal_IntPtr>(
452cdf0e10cSrcweir                 rVclWindowEvent.GetData()));
453cdf0e10cSrcweir             break;
454cdf0e10cSrcweir 
455cdf0e10cSrcweir         case VCLEVENT_LISTBOX_ITEMADDED:
456cdf0e10cSrcweir         case VCLEVENT_COMBOBOX_ITEMADDED:
457cdf0e10cSrcweir             HandleChangedItemList (true, reinterpret_cast<sal_IntPtr>(
458cdf0e10cSrcweir                 rVclWindowEvent.GetData()));
459cdf0e10cSrcweir             break;
460cdf0e10cSrcweir 		case VCLEVENT_CONTROL_GETFOCUS:
461*21075d77SSteve Yin 			{
462cdf0e10cSrcweir 	            VCLXAccessibleComponent::ProcessWindowEvent (rVclWindowEvent);
463*21075d77SSteve Yin 				// Added by IBM Symphony Acc team to handle the list item focus when List control get focus
464*21075d77SSteve Yin 				sal_Bool b_IsDropDownList = sal_True;
465*21075d77SSteve Yin 				if (m_pListBoxHelper)
466*21075d77SSteve Yin 					b_IsDropDownList = ((m_pListBoxHelper->GetStyle() & WB_DROPDOWN ) == WB_DROPDOWN);
467*21075d77SSteve Yin 				if ( m_aBoxType == LISTBOX && !b_IsDropDownList )
468*21075d77SSteve Yin 				{
469cdf0e10cSrcweir 					if ( m_pListBoxHelper )
470cdf0e10cSrcweir 					{
471cdf0e10cSrcweir 						uno::Any	aOldValue,
472cdf0e10cSrcweir 									aNewValue;
473*21075d77SSteve Yin 						sal_uInt16 nPos = m_nCurSelectedPos;
474*21075d77SSteve Yin 
475cdf0e10cSrcweir 						if ( nPos == LISTBOX_ENTRY_NOTFOUND )
476cdf0e10cSrcweir 							nPos = m_pListBoxHelper->GetTopEntry();
477cdf0e10cSrcweir 						if ( nPos != LISTBOX_ENTRY_NOTFOUND )
478cdf0e10cSrcweir 							aNewValue <<= CreateChild(nPos);
479cdf0e10cSrcweir 						NotifyAccessibleEvent(	AccessibleEventId::ACTIVE_DESCENDANT_CHANGED,
480cdf0e10cSrcweir 												aOldValue,
481cdf0e10cSrcweir 												aNewValue );
482cdf0e10cSrcweir 					}
483*21075d77SSteve Yin 				}
484*21075d77SSteve Yin 			}
485cdf0e10cSrcweir 			break;
486cdf0e10cSrcweir 
487cdf0e10cSrcweir         default:
488cdf0e10cSrcweir             VCLXAccessibleComponent::ProcessWindowEvent (rVclWindowEvent);
489cdf0e10cSrcweir     }
490cdf0e10cSrcweir }
491*21075d77SSteve Yin 
492*21075d77SSteve Yin  void VCLXAccessibleList::FillAccessibleRelationSet( utl::AccessibleRelationSetHelper& rRelationSet )
493*21075d77SSteve Yin {
494*21075d77SSteve Yin 	ListBox* pBox = static_cast<ListBox*>(GetWindow());
495*21075d77SSteve Yin 	if( m_aBoxType == LISTBOX  )
496*21075d77SSteve Yin 	{
497*21075d77SSteve Yin 		if (m_pListBoxHelper && (m_pListBoxHelper->GetStyle() & WB_DROPDOWN ) != WB_DROPDOWN)
498*21075d77SSteve Yin 		{
499*21075d77SSteve Yin 			uno::Sequence< uno::Reference< uno::XInterface > > aSequence(1);
500*21075d77SSteve Yin 			aSequence[0] = pBox->GetAccessible();
501*21075d77SSteve Yin 			rRelationSet.AddRelation( com::sun::star::accessibility::AccessibleRelation( com::sun::star::accessibility::AccessibleRelationType::MEMBER_OF, aSequence ) );
502*21075d77SSteve Yin 		}
503*21075d77SSteve Yin 	}
504*21075d77SSteve Yin 	else
505*21075d77SSteve Yin 	{
506*21075d77SSteve Yin 		VCLXAccessibleComponent::FillAccessibleRelationSet(rRelationSet);
507*21075d77SSteve Yin 	}
508*21075d77SSteve Yin }
509cdf0e10cSrcweir // -----------------------------------------------------------------------------
510cdf0e10cSrcweir 
511cdf0e10cSrcweir /** To find out which item is currently selected and to update the SELECTED
512cdf0e10cSrcweir     state of the associated accessibility objects accordingly we exploit the
513cdf0e10cSrcweir     fact that the
514cdf0e10cSrcweir */
515cdf0e10cSrcweir void VCLXAccessibleList::UpdateSelection (::rtl::OUString sTextOfSelectedItem)
516cdf0e10cSrcweir {
517cdf0e10cSrcweir     if ( m_aBoxType == COMBOBOX )
518cdf0e10cSrcweir     {
519cdf0e10cSrcweir         ComboBox* pBox = static_cast<ComboBox*>(GetWindow());
520cdf0e10cSrcweir         if ( pBox != NULL )
521cdf0e10cSrcweir         {
522cdf0e10cSrcweir             // Find the index of the selected item inside the VCL control...
523cdf0e10cSrcweir             sal_uInt16 nIndex = pBox->GetEntryPos (XubString(sTextOfSelectedItem));
524cdf0e10cSrcweir             // ...and then find the associated accessibility object.
525cdf0e10cSrcweir 			if ( nIndex == LISTBOX_ENTRY_NOTFOUND )
526cdf0e10cSrcweir 				nIndex = 0;
527cdf0e10cSrcweir 			UpdateSelection_Impl(nIndex);
528cdf0e10cSrcweir         }
529cdf0e10cSrcweir     }
530cdf0e10cSrcweir }
531cdf0e10cSrcweir // -----------------------------------------------------------------------------
532cdf0e10cSrcweir 
533cdf0e10cSrcweir void VCLXAccessibleList::adjustEntriesIndexInParent(ListItems::iterator& _aBegin,::std::mem_fun_t<bool,VCLXAccessibleListItem>& _rMemFun)
534cdf0e10cSrcweir {
535cdf0e10cSrcweir 	ListItems::iterator aIter = _aBegin;
536cdf0e10cSrcweir 	ListItems::iterator aEnd = m_aAccessibleChildren.end();
537cdf0e10cSrcweir 	// adjust the index inside the VCLXAccessibleListItem
538cdf0e10cSrcweir 	for (;aIter != aEnd ; ++aIter)
539cdf0e10cSrcweir 	{
540cdf0e10cSrcweir 		Reference< XAccessible > xHold = *aIter;
541cdf0e10cSrcweir 		VCLXAccessibleListItem* pItem = static_cast<VCLXAccessibleListItem*>(xHold.get());
542cdf0e10cSrcweir 		if ( pItem )
543cdf0e10cSrcweir 			_rMemFun(pItem);
544cdf0e10cSrcweir 	}
545cdf0e10cSrcweir }
546cdf0e10cSrcweir // -----------------------------------------------------------------------------
547cdf0e10cSrcweir 
548cdf0e10cSrcweir Reference<XAccessible> VCLXAccessibleList::CreateChild (sal_Int32 i)
549cdf0e10cSrcweir {
550cdf0e10cSrcweir     Reference<XAccessible> xChild;
551cdf0e10cSrcweir 
552cdf0e10cSrcweir 	sal_uInt16 nPos = static_cast<sal_uInt16>(i);
553cdf0e10cSrcweir 	if ( nPos >= m_aAccessibleChildren.size() )
554cdf0e10cSrcweir 	{
555cdf0e10cSrcweir 		m_aAccessibleChildren.resize(nPos + 1);
556cdf0e10cSrcweir 
557cdf0e10cSrcweir 		// insert into the container
558cdf0e10cSrcweir 		xChild = new VCLXAccessibleListItem(m_pListBoxHelper, i, this);
559cdf0e10cSrcweir 		m_aAccessibleChildren[nPos] = xChild;
560cdf0e10cSrcweir 	}
561cdf0e10cSrcweir 	else
562cdf0e10cSrcweir 	{
563cdf0e10cSrcweir 		xChild = m_aAccessibleChildren[nPos];
564cdf0e10cSrcweir 		// check if position is empty and can be used else we have to adjust all entries behind this
565cdf0e10cSrcweir 		if ( xChild.is() )
566cdf0e10cSrcweir 		{
567*21075d77SSteve Yin 			// IAccessible2 implementation, 2009
568*21075d77SSteve Yin 			/*
569cdf0e10cSrcweir 			ListItems::iterator aIter = m_aAccessibleChildren.begin() + nPos;
570cdf0e10cSrcweir             ::std::mem_fun_t<bool, VCLXAccessibleListItem> aTemp(&VCLXAccessibleListItem::IncrementIndexInParent);
571cdf0e10cSrcweir 			adjustEntriesIndexInParent(	aIter, aTemp);
572*21075d77SSteve Yin 			*/
573cdf0e10cSrcweir 		}
574cdf0e10cSrcweir 		else
575cdf0e10cSrcweir 		{
576cdf0e10cSrcweir 			xChild = new VCLXAccessibleListItem(m_pListBoxHelper, i, this);
577cdf0e10cSrcweir 			m_aAccessibleChildren[nPos] = xChild;
578cdf0e10cSrcweir 		}
579cdf0e10cSrcweir 	}
580cdf0e10cSrcweir 
581cdf0e10cSrcweir     if ( xChild.is() )
582cdf0e10cSrcweir     {
583cdf0e10cSrcweir 		// Just add the SELECTED state.
584cdf0e10cSrcweir 		sal_Bool bNowSelected = sal_False;
585cdf0e10cSrcweir 		if ( m_pListBoxHelper )
586cdf0e10cSrcweir 			bNowSelected = m_pListBoxHelper->IsEntryPosSelected ((sal_uInt16)i);
587*21075d77SSteve Yin 		// IAccessible2 implementation 2009
588*21075d77SSteve Yin 		if (bNowSelected)
589*21075d77SSteve Yin 			m_nCurSelectedPos = sal_uInt16(i);
590cdf0e10cSrcweir         VCLXAccessibleListItem* pItem = static_cast< VCLXAccessibleListItem* >(xChild.get());
591cdf0e10cSrcweir         pItem->SetSelected( bNowSelected );
592cdf0e10cSrcweir 
593cdf0e10cSrcweir 		// Set the child's VISIBLE state.
594cdf0e10cSrcweir         UpdateVisibleLineCount();
595cdf0e10cSrcweir 		sal_uInt16 nTopEntry = 0;
596cdf0e10cSrcweir 		if ( m_pListBoxHelper )
597cdf0e10cSrcweir 			nTopEntry = m_pListBoxHelper->GetTopEntry();
598cdf0e10cSrcweir 		sal_Bool bVisible = ( nPos>=nTopEntry && nPos<( nTopEntry + m_nVisibleLineCount ) );
599cdf0e10cSrcweir 		pItem->SetVisible( m_bVisible && bVisible );
600cdf0e10cSrcweir     }
601cdf0e10cSrcweir 
602cdf0e10cSrcweir     return xChild;
603cdf0e10cSrcweir }
604cdf0e10cSrcweir // -----------------------------------------------------------------------------
605cdf0e10cSrcweir 
606cdf0e10cSrcweir void VCLXAccessibleList::HandleChangedItemList (bool bItemInserted, sal_Int32 nIndex)
607cdf0e10cSrcweir {
608*21075d77SSteve Yin 	// IAccessible2 implementation 2009
609*21075d77SSteve Yin 	/*
610cdf0e10cSrcweir     if ( !bItemInserted )
611cdf0e10cSrcweir 	{
612cdf0e10cSrcweir 		if ( nIndex == -1 ) // special handling here
613cdf0e10cSrcweir 		{
614cdf0e10cSrcweir 			clearItems();
615cdf0e10cSrcweir 		}
616cdf0e10cSrcweir 		else
617cdf0e10cSrcweir 		{
618cdf0e10cSrcweir 			if ( nIndex >= 0 && static_cast<sal_uInt16>(nIndex) < m_aAccessibleChildren.size() )
619cdf0e10cSrcweir 			{
620cdf0e10cSrcweir 				ListItems::iterator aIter = m_aAccessibleChildren.erase(m_aAccessibleChildren.begin()+nIndex);
621cdf0e10cSrcweir             ::std::mem_fun_t<bool, VCLXAccessibleListItem> aTemp(&VCLXAccessibleListItem::DecrementIndexInParent);
622cdf0e10cSrcweir 				adjustEntriesIndexInParent(	aIter, aTemp );
623cdf0e10cSrcweir 			}
624cdf0e10cSrcweir 		}
625cdf0e10cSrcweir 	}
626cdf0e10cSrcweir 	else
627cdf0e10cSrcweir 		getAccessibleChild(nIndex);
628*21075d77SSteve Yin 	*/
629*21075d77SSteve Yin 	clearItems();
630cdf0e10cSrcweir     NotifyAccessibleEvent (
631cdf0e10cSrcweir         AccessibleEventId::INVALIDATE_ALL_CHILDREN,
632cdf0e10cSrcweir         Any(), Any());
633cdf0e10cSrcweir }
634cdf0e10cSrcweir // -----------------------------------------------------------------------------
635cdf0e10cSrcweir 
636cdf0e10cSrcweir IMPLEMENT_FORWARD_XINTERFACE2(VCLXAccessibleList, VCLXAccessibleComponent, VCLXAccessibleList_BASE)
637cdf0e10cSrcweir IMPLEMENT_FORWARD_XTYPEPROVIDER2(VCLXAccessibleList, VCLXAccessibleComponent, VCLXAccessibleList_BASE)
638cdf0e10cSrcweir 
639cdf0e10cSrcweir //=====  XAccessible  =========================================================
640cdf0e10cSrcweir 
641cdf0e10cSrcweir Reference<XAccessibleContext> SAL_CALL
642cdf0e10cSrcweir     VCLXAccessibleList::getAccessibleContext (void)
643cdf0e10cSrcweir     throw (RuntimeException)
644cdf0e10cSrcweir {
645cdf0e10cSrcweir 	return this;
646cdf0e10cSrcweir }
647cdf0e10cSrcweir // -----------------------------------------------------------------------------
648cdf0e10cSrcweir 
649cdf0e10cSrcweir //=====  XAccessibleContext  ==================================================
650cdf0e10cSrcweir 
651cdf0e10cSrcweir sal_Int32 SAL_CALL VCLXAccessibleList::getAccessibleChildCount (void)
652cdf0e10cSrcweir     throw (RuntimeException)
653cdf0e10cSrcweir {
654cdf0e10cSrcweir 	vos::OGuard aSolarGuard( Application::GetSolarMutex() );
655cdf0e10cSrcweir 	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
656cdf0e10cSrcweir 
657cdf0e10cSrcweir 	sal_Int32 nCount = 0;
658cdf0e10cSrcweir 	if ( m_pListBoxHelper )
659cdf0e10cSrcweir 		nCount = m_pListBoxHelper->GetEntryCount();
660cdf0e10cSrcweir 
661cdf0e10cSrcweir     return nCount;
662cdf0e10cSrcweir }
663cdf0e10cSrcweir // -----------------------------------------------------------------------------
664cdf0e10cSrcweir 
665cdf0e10cSrcweir Reference<XAccessible> SAL_CALL VCLXAccessibleList::getAccessibleChild (sal_Int32 i)
666cdf0e10cSrcweir     throw (IndexOutOfBoundsException, RuntimeException)
667cdf0e10cSrcweir {
668cdf0e10cSrcweir 	vos::OGuard aSolarGuard( Application::GetSolarMutex() );
669cdf0e10cSrcweir 	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
670cdf0e10cSrcweir 
671cdf0e10cSrcweir 	if ( i < 0 || i >= getAccessibleChildCount() )
672cdf0e10cSrcweir 		throw IndexOutOfBoundsException();
673cdf0e10cSrcweir 
674cdf0e10cSrcweir     Reference< XAccessible > xChild;
675cdf0e10cSrcweir     // search for the child
676cdf0e10cSrcweir 	if ( static_cast<sal_uInt16>(i) >= m_aAccessibleChildren.size() )
677cdf0e10cSrcweir 		xChild = CreateChild (i);
678cdf0e10cSrcweir 	else
679cdf0e10cSrcweir 	{
680cdf0e10cSrcweir 		xChild = m_aAccessibleChildren[i];
681cdf0e10cSrcweir 		if ( !xChild.is() )
682cdf0e10cSrcweir 			xChild = CreateChild (i);
683cdf0e10cSrcweir 	}
684cdf0e10cSrcweir 	OSL_ENSURE( xChild.is(), "VCLXAccessibleList::getAccessibleChild: returning empty child!" );
685cdf0e10cSrcweir     return xChild;
686cdf0e10cSrcweir }
687cdf0e10cSrcweir // -----------------------------------------------------------------------------
688cdf0e10cSrcweir 
689cdf0e10cSrcweir Reference< XAccessible > SAL_CALL VCLXAccessibleList::getAccessibleParent(  )
690cdf0e10cSrcweir 	throw (RuntimeException)
691cdf0e10cSrcweir {
692cdf0e10cSrcweir 	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
693cdf0e10cSrcweir 
694cdf0e10cSrcweir 	return m_xParent;
695cdf0e10cSrcweir }
696cdf0e10cSrcweir // -----------------------------------------------------------------------------
697cdf0e10cSrcweir 
698cdf0e10cSrcweir sal_Int32 SAL_CALL VCLXAccessibleList::getAccessibleIndexInParent (void)
699cdf0e10cSrcweir     throw (::com::sun::star::uno::RuntimeException)
700cdf0e10cSrcweir {
701cdf0e10cSrcweir     if (m_nIndexInParent != DEFAULT_INDEX_IN_PARENT)
702cdf0e10cSrcweir         return m_nIndexInParent;
703cdf0e10cSrcweir     else
704cdf0e10cSrcweir         return VCLXAccessibleComponent::getAccessibleIndexInParent();
705cdf0e10cSrcweir }
706cdf0e10cSrcweir // -----------------------------------------------------------------------------
707cdf0e10cSrcweir 
708cdf0e10cSrcweir sal_Int16 SAL_CALL VCLXAccessibleList::getAccessibleRole (void)
709cdf0e10cSrcweir     throw (RuntimeException)
710cdf0e10cSrcweir {
711cdf0e10cSrcweir     return AccessibleRole::LIST;
712cdf0e10cSrcweir }
713cdf0e10cSrcweir // -----------------------------------------------------------------------------
714cdf0e10cSrcweir 
715cdf0e10cSrcweir //=====  XAccessibleComponent  ================================================
716cdf0e10cSrcweir 
717cdf0e10cSrcweir sal_Bool SAL_CALL VCLXAccessibleList::contains( const awt::Point& rPoint ) throw (RuntimeException)
718cdf0e10cSrcweir {
719cdf0e10cSrcweir 	vos::OGuard aSolarGuard( Application::GetSolarMutex() );
720cdf0e10cSrcweir 	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
721cdf0e10cSrcweir 
722cdf0e10cSrcweir 	sal_Bool bInside = sal_False;
723cdf0e10cSrcweir 
724cdf0e10cSrcweir     Window* pListBox = GetWindow();
725cdf0e10cSrcweir     if ( pListBox )
726cdf0e10cSrcweir 	{
727cdf0e10cSrcweir 		Rectangle aRect( Point(0,0), pListBox->GetSizePixel() );
728cdf0e10cSrcweir 		bInside = aRect.IsInside( VCLPoint( rPoint ) );
729cdf0e10cSrcweir 	}
730cdf0e10cSrcweir 
731cdf0e10cSrcweir 	return bInside;
732cdf0e10cSrcweir }
733cdf0e10cSrcweir // -----------------------------------------------------------------------------
734cdf0e10cSrcweir 
735cdf0e10cSrcweir Reference< XAccessible > SAL_CALL VCLXAccessibleList::getAccessibleAt( const awt::Point& rPoint )
736cdf0e10cSrcweir     throw (RuntimeException)
737cdf0e10cSrcweir {
738cdf0e10cSrcweir 	vos::OGuard aSolarGuard( Application::GetSolarMutex() );
739cdf0e10cSrcweir 	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
740cdf0e10cSrcweir 
741cdf0e10cSrcweir 	Reference< XAccessible > xChild;
742cdf0e10cSrcweir 	if ( m_pListBoxHelper )
743cdf0e10cSrcweir 	{
744cdf0e10cSrcweir         UpdateVisibleLineCount();
745cdf0e10cSrcweir 		if ( contains( rPoint ) && m_nVisibleLineCount > 0 )
746cdf0e10cSrcweir 		{
747cdf0e10cSrcweir 			Point aPos = VCLPoint( rPoint );
748cdf0e10cSrcweir 			sal_uInt16 nEndPos = m_pListBoxHelper->GetTopEntry() + (sal_uInt16)m_nVisibleLineCount;
749cdf0e10cSrcweir 			for ( sal_uInt16 i = m_pListBoxHelper->GetTopEntry(); i < nEndPos; ++i )
750cdf0e10cSrcweir 			{
751cdf0e10cSrcweir 				if ( m_pListBoxHelper->GetBoundingRectangle(i).IsInside( aPos ) )
752cdf0e10cSrcweir 				{
753cdf0e10cSrcweir 					xChild = getAccessibleChild(i);
754cdf0e10cSrcweir 					break;
755cdf0e10cSrcweir 				}
756cdf0e10cSrcweir 			}
757cdf0e10cSrcweir 		}
758cdf0e10cSrcweir 	}
759cdf0e10cSrcweir 
760cdf0e10cSrcweir     return xChild;
761cdf0e10cSrcweir }
762cdf0e10cSrcweir // -----------------------------------------------------------------------------
763cdf0e10cSrcweir 
764cdf0e10cSrcweir //===== XServiceInfo ==========================================================
765cdf0e10cSrcweir 
766cdf0e10cSrcweir ::rtl::OUString VCLXAccessibleList::getImplementationName (void)
767cdf0e10cSrcweir     throw (RuntimeException)
768cdf0e10cSrcweir {
769cdf0e10cSrcweir 	return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.toolkit.AccessibleList"));
770cdf0e10cSrcweir }
771cdf0e10cSrcweir // -----------------------------------------------------------------------------
772cdf0e10cSrcweir 
773cdf0e10cSrcweir Sequence< ::rtl::OUString > VCLXAccessibleList::getSupportedServiceNames (void)
774cdf0e10cSrcweir     throw (RuntimeException)
775cdf0e10cSrcweir {
776cdf0e10cSrcweir 	Sequence< ::rtl::OUString > aNames = VCLXAccessibleComponent::getSupportedServiceNames();
777cdf0e10cSrcweir 	sal_Int32 nLength = aNames.getLength();
778cdf0e10cSrcweir 	aNames.realloc( nLength + 1 );
779cdf0e10cSrcweir 	aNames[nLength] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.accessibility.AccessibleList"));
780cdf0e10cSrcweir 	return aNames;
781cdf0e10cSrcweir }
782cdf0e10cSrcweir // -----------------------------------------------------------------------------
783cdf0e10cSrcweir 
784cdf0e10cSrcweir void VCLXAccessibleList::UpdateVisibleLineCount()
785cdf0e10cSrcweir {
786cdf0e10cSrcweir 	if ( m_pListBoxHelper )
787cdf0e10cSrcweir 	{
788cdf0e10cSrcweir 		if ( (m_pListBoxHelper->GetStyle() & WB_DROPDOWN ) == WB_DROPDOWN )
789cdf0e10cSrcweir 			m_nVisibleLineCount = m_pListBoxHelper->GetDisplayLineCount();
790cdf0e10cSrcweir 		else
791cdf0e10cSrcweir 		{
792cdf0e10cSrcweir 			sal_uInt16 nCols = 0,
793cdf0e10cSrcweir 				nLines = 0;
794cdf0e10cSrcweir 			m_pListBoxHelper->GetMaxVisColumnsAndLines (nCols, nLines);
795cdf0e10cSrcweir 			m_nVisibleLineCount = nLines;
796cdf0e10cSrcweir 		}
797cdf0e10cSrcweir 	}
798cdf0e10cSrcweir }
799cdf0e10cSrcweir 
800cdf0e10cSrcweir // -----------------------------------------------------------------------------
801cdf0e10cSrcweir void VCLXAccessibleList::UpdateEntryRange_Impl()
802cdf0e10cSrcweir {
803cdf0e10cSrcweir 	vos::OGuard aSolarGuard( Application::GetSolarMutex() );
804cdf0e10cSrcweir 	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
805cdf0e10cSrcweir 
806cdf0e10cSrcweir 	sal_Int32 nTop = m_nLastTopEntry;
807cdf0e10cSrcweir 
808cdf0e10cSrcweir 	if ( m_pListBoxHelper )
809cdf0e10cSrcweir 		nTop = m_pListBoxHelper->GetTopEntry();
810cdf0e10cSrcweir 	if ( nTop != m_nLastTopEntry )
811cdf0e10cSrcweir 	{
812cdf0e10cSrcweir         UpdateVisibleLineCount();
813cdf0e10cSrcweir 		sal_Int32 nBegin = Min( m_nLastTopEntry, nTop );
814cdf0e10cSrcweir 		sal_Int32 nEnd = Max( m_nLastTopEntry + m_nVisibleLineCount, nTop + m_nVisibleLineCount );
815cdf0e10cSrcweir 		for (sal_uInt16 i = static_cast<sal_uInt16>(nBegin); (i <= static_cast<sal_uInt16>(nEnd)); ++i)
816cdf0e10cSrcweir 		{
817cdf0e10cSrcweir 			sal_Bool bVisible = ( i >= nTop && i < ( nTop + m_nVisibleLineCount ) );
818cdf0e10cSrcweir 			Reference< XAccessible > xHold;
819cdf0e10cSrcweir 			if ( i < m_aAccessibleChildren.size() )
820cdf0e10cSrcweir 				xHold = m_aAccessibleChildren[i];
821cdf0e10cSrcweir 			else if ( bVisible )
822cdf0e10cSrcweir 				xHold = CreateChild(i);
823cdf0e10cSrcweir 
824cdf0e10cSrcweir 			if ( xHold.is() )
825cdf0e10cSrcweir 				static_cast< VCLXAccessibleListItem* >( xHold.get() )->SetVisible( m_bVisible && bVisible );
826cdf0e10cSrcweir 		}
827cdf0e10cSrcweir 	}
828cdf0e10cSrcweir 
829cdf0e10cSrcweir 	m_nLastTopEntry = nTop;
830cdf0e10cSrcweir }
831cdf0e10cSrcweir // -----------------------------------------------------------------------------
832cdf0e10cSrcweir sal_Bool VCLXAccessibleList::checkEntrySelected(sal_uInt16 _nPos,Any& _rNewValue,Reference< XAccessible >& _rxNewAcc)
833cdf0e10cSrcweir {
834cdf0e10cSrcweir 	OSL_ENSURE(m_pListBoxHelper,"Helper is not valid!");
835cdf0e10cSrcweir 	sal_Bool bNowSelected = sal_False;
836cdf0e10cSrcweir 	if ( m_pListBoxHelper )
837cdf0e10cSrcweir 	{
838cdf0e10cSrcweir 		bNowSelected = m_pListBoxHelper->IsEntryPosSelected (_nPos);
839cdf0e10cSrcweir 		if ( bNowSelected )
840cdf0e10cSrcweir 		{
841cdf0e10cSrcweir 			_rxNewAcc = CreateChild(_nPos);
842cdf0e10cSrcweir 			_rNewValue <<= _rxNewAcc;
843cdf0e10cSrcweir 		}
844cdf0e10cSrcweir 	}
845cdf0e10cSrcweir 	return bNowSelected;
846cdf0e10cSrcweir }
847cdf0e10cSrcweir // -----------------------------------------------------------------------------
848cdf0e10cSrcweir 
849cdf0e10cSrcweir void VCLXAccessibleList::UpdateSelection_Impl(sal_uInt16)
850cdf0e10cSrcweir {
851cdf0e10cSrcweir 	uno::Any aOldValue, aNewValue;
852cdf0e10cSrcweir 
853cdf0e10cSrcweir 	{
854cdf0e10cSrcweir 		vos::OGuard aSolarGuard( Application::GetSolarMutex() );
855cdf0e10cSrcweir 		::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
856cdf0e10cSrcweir 	    Reference< XAccessible > xNewAcc;
857cdf0e10cSrcweir 
858cdf0e10cSrcweir 		if ( m_pListBoxHelper )
859cdf0e10cSrcweir 		{
860cdf0e10cSrcweir 			sal_uInt16 i=0;
861*21075d77SSteve Yin 			m_nCurSelectedPos = LISTBOX_ENTRY_NOTFOUND;
862cdf0e10cSrcweir 			for ( ListItems::iterator aIter = m_aAccessibleChildren.begin();
863cdf0e10cSrcweir 				  aIter != m_aAccessibleChildren.end(); ++aIter,++i)
864cdf0e10cSrcweir 			{
865cdf0e10cSrcweir 				Reference< XAccessible > xHold = *aIter;
866cdf0e10cSrcweir 				if ( xHold.is() )
867cdf0e10cSrcweir 				{
868cdf0e10cSrcweir 					VCLXAccessibleListItem* pItem = static_cast< VCLXAccessibleListItem* >( xHold.get() );
869cdf0e10cSrcweir 					// Retrieve the item's index from the list entry.
870cdf0e10cSrcweir 					sal_Bool bNowSelected = m_pListBoxHelper->IsEntryPosSelected (i);
871*21075d77SSteve Yin 					if (bNowSelected)
872*21075d77SSteve Yin 						m_nCurSelectedPos = i;
873cdf0e10cSrcweir 
874cdf0e10cSrcweir 					if ( bNowSelected && !pItem->IsSelected() )
875cdf0e10cSrcweir 					{
876cdf0e10cSrcweir 						xNewAcc = *aIter;
877cdf0e10cSrcweir 						aNewValue <<= xNewAcc;
878cdf0e10cSrcweir 					}
879cdf0e10cSrcweir 					else if ( pItem->IsSelected() )
880cdf0e10cSrcweir 						m_nLastSelectedPos = i;
881cdf0e10cSrcweir 
882cdf0e10cSrcweir 					pItem->SetSelected( bNowSelected );
883cdf0e10cSrcweir 				}
884cdf0e10cSrcweir 				else
885cdf0e10cSrcweir 				{ // it could happen that a child was not created before
886cdf0e10cSrcweir 					checkEntrySelected(i,aNewValue,xNewAcc);
887cdf0e10cSrcweir 				}
888cdf0e10cSrcweir 			}
889cdf0e10cSrcweir 			sal_uInt16 nCount = m_pListBoxHelper->GetEntryCount();
890cdf0e10cSrcweir 			if ( i < nCount ) // here we have to check the if any other listbox entry is selected
891cdf0e10cSrcweir 			{
892cdf0e10cSrcweir 				for (; i < nCount && !checkEntrySelected(i,aNewValue,xNewAcc) ;++i )
893cdf0e10cSrcweir 					;
894cdf0e10cSrcweir 			}
895cdf0e10cSrcweir 			if ( xNewAcc.is() && GetWindow()->HasFocus() )
896cdf0e10cSrcweir 			{
897cdf0e10cSrcweir 				if ( m_nLastSelectedPos != LISTBOX_ENTRY_NOTFOUND )
898cdf0e10cSrcweir 					aOldValue <<= getAccessibleChild( (sal_Int32)m_nLastSelectedPos );
899cdf0e10cSrcweir 				aNewValue <<= xNewAcc;
900cdf0e10cSrcweir 			}
901cdf0e10cSrcweir 		}
902cdf0e10cSrcweir 	}
903*21075d77SSteve Yin 	if (!m_pListBoxHelper->IsInDropDown())
904*21075d77SSteve Yin 	{
905*21075d77SSteve Yin 	}
906*21075d77SSteve Yin 	else
907*21075d77SSteve Yin 	{
908cdf0e10cSrcweir 		if ( aNewValue.hasValue() || aOldValue.hasValue() )
909cdf0e10cSrcweir 			NotifyAccessibleEvent(
910cdf0e10cSrcweir 				AccessibleEventId::ACTIVE_DESCENDANT_CHANGED,
911cdf0e10cSrcweir 				aOldValue,
912cdf0e10cSrcweir 				aNewValue );
913*21075d77SSteve Yin 		//the SELECTION_CHANGED is not necessary
914*21075d77SSteve Yin 		//NotifyAccessibleEvent( AccessibleEventId::SELECTION_CHANGED, Any(), Any() );
915*21075d77SSteve Yin 	}
916cdf0e10cSrcweir }
917cdf0e10cSrcweir 
918cdf0e10cSrcweir // -----------------------------------------------------------------------------
919cdf0e10cSrcweir // XAccessibleSelection
920cdf0e10cSrcweir // -----------------------------------------------------------------------------
921cdf0e10cSrcweir void SAL_CALL VCLXAccessibleList::selectAccessibleChild( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
922cdf0e10cSrcweir {
923cdf0e10cSrcweir 	sal_Bool bNotify = sal_False;
924cdf0e10cSrcweir 
925cdf0e10cSrcweir 	{
926cdf0e10cSrcweir 		vos::OGuard aSolarGuard( Application::GetSolarMutex() );
927cdf0e10cSrcweir 		::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
928cdf0e10cSrcweir 
929cdf0e10cSrcweir 		if ( m_pListBoxHelper )
930cdf0e10cSrcweir 		{
931cdf0e10cSrcweir 			checkSelection_Impl(nChildIndex,*m_pListBoxHelper,sal_False);
932cdf0e10cSrcweir 
933cdf0e10cSrcweir 			m_pListBoxHelper->SelectEntryPos( (sal_uInt16)nChildIndex, sal_True );
934cdf0e10cSrcweir 			// call the select handler, don't handle events in this time
935cdf0e10cSrcweir 			m_bDisableProcessEvent = true;
936cdf0e10cSrcweir 			m_pListBoxHelper->Select();
937cdf0e10cSrcweir 			m_bDisableProcessEvent = false;
938cdf0e10cSrcweir 			bNotify = sal_True;
939cdf0e10cSrcweir 		}
940cdf0e10cSrcweir 	}
941cdf0e10cSrcweir 
942cdf0e10cSrcweir 	if ( bNotify )
943cdf0e10cSrcweir         UpdateSelection_Impl();
944cdf0e10cSrcweir }
945cdf0e10cSrcweir // -----------------------------------------------------------------------------
946cdf0e10cSrcweir sal_Bool SAL_CALL VCLXAccessibleList::isAccessibleChildSelected( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
947cdf0e10cSrcweir {
948cdf0e10cSrcweir 	vos::OGuard aSolarGuard( Application::GetSolarMutex() );
949cdf0e10cSrcweir 	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
950cdf0e10cSrcweir 
951cdf0e10cSrcweir     sal_Bool bRet = sal_False;
952cdf0e10cSrcweir 	if ( m_pListBoxHelper )
953cdf0e10cSrcweir 	{
954cdf0e10cSrcweir 		checkSelection_Impl(nChildIndex,*m_pListBoxHelper,sal_False);
955cdf0e10cSrcweir 
956cdf0e10cSrcweir     	bRet = m_pListBoxHelper->IsEntryPosSelected( (sal_uInt16)nChildIndex );
957cdf0e10cSrcweir 	}
958cdf0e10cSrcweir     return bRet;
959cdf0e10cSrcweir }
960cdf0e10cSrcweir // -----------------------------------------------------------------------------
961cdf0e10cSrcweir void SAL_CALL VCLXAccessibleList::clearAccessibleSelection(  ) throw (RuntimeException)
962cdf0e10cSrcweir {
963cdf0e10cSrcweir 	sal_Bool bNotify = sal_False;
964cdf0e10cSrcweir 
965cdf0e10cSrcweir 	{
966cdf0e10cSrcweir 		vos::OGuard aSolarGuard( Application::GetSolarMutex() );
967cdf0e10cSrcweir 		::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
968cdf0e10cSrcweir 
969cdf0e10cSrcweir 		if ( m_pListBoxHelper )
970cdf0e10cSrcweir 		{
971cdf0e10cSrcweir 	    	m_pListBoxHelper->SetNoSelection();
972cdf0e10cSrcweir 			bNotify = sal_True;
973cdf0e10cSrcweir 		}
974cdf0e10cSrcweir 	}
975cdf0e10cSrcweir 
976cdf0e10cSrcweir 	if ( bNotify )
977cdf0e10cSrcweir         UpdateSelection_Impl();
978cdf0e10cSrcweir }
979cdf0e10cSrcweir // -----------------------------------------------------------------------------
980cdf0e10cSrcweir void SAL_CALL VCLXAccessibleList::selectAllAccessibleChildren(  ) throw (RuntimeException)
981cdf0e10cSrcweir {
982cdf0e10cSrcweir 	sal_Bool bNotify = sal_False;
983cdf0e10cSrcweir 
984cdf0e10cSrcweir 	{
985cdf0e10cSrcweir 		vos::OGuard aSolarGuard( Application::GetSolarMutex() );
986cdf0e10cSrcweir 		::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
987cdf0e10cSrcweir 
988cdf0e10cSrcweir 		if ( m_pListBoxHelper )
989cdf0e10cSrcweir 		{
990cdf0e10cSrcweir 	    	sal_uInt16 nCount = m_pListBoxHelper->GetEntryCount();
991cdf0e10cSrcweir 	    	for ( sal_uInt16 i = 0; i < nCount; ++i )
992cdf0e10cSrcweir 	    		m_pListBoxHelper->SelectEntryPos( i, sal_True );
993cdf0e10cSrcweir 			// call the select handler, don't handle events in this time
994cdf0e10cSrcweir 			m_bDisableProcessEvent = true;
995cdf0e10cSrcweir 			m_pListBoxHelper->Select();
996cdf0e10cSrcweir 			m_bDisableProcessEvent = false;
997cdf0e10cSrcweir 			bNotify = sal_True;
998cdf0e10cSrcweir 		}
999cdf0e10cSrcweir 	}
1000cdf0e10cSrcweir 
1001cdf0e10cSrcweir 	if ( bNotify )
1002cdf0e10cSrcweir         UpdateSelection_Impl();
1003cdf0e10cSrcweir }
1004cdf0e10cSrcweir // -----------------------------------------------------------------------------
1005cdf0e10cSrcweir sal_Int32 SAL_CALL VCLXAccessibleList::getSelectedAccessibleChildCount(  ) throw (RuntimeException)
1006cdf0e10cSrcweir {
1007cdf0e10cSrcweir 	vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1008cdf0e10cSrcweir 	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
1009cdf0e10cSrcweir 
1010cdf0e10cSrcweir     sal_Int32 nCount = 0;
1011cdf0e10cSrcweir 	if ( m_pListBoxHelper )
1012cdf0e10cSrcweir    		nCount = m_pListBoxHelper->GetSelectEntryCount();
1013cdf0e10cSrcweir     return nCount;
1014cdf0e10cSrcweir }
1015cdf0e10cSrcweir // -----------------------------------------------------------------------------
1016cdf0e10cSrcweir Reference< XAccessible > SAL_CALL VCLXAccessibleList::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
1017cdf0e10cSrcweir {
1018cdf0e10cSrcweir 	vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1019cdf0e10cSrcweir 	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
1020cdf0e10cSrcweir 
1021cdf0e10cSrcweir 	if ( m_pListBoxHelper )
1022cdf0e10cSrcweir 	{
1023cdf0e10cSrcweir 		checkSelection_Impl(nSelectedChildIndex,*m_pListBoxHelper,sal_True);
1024cdf0e10cSrcweir 		return getAccessibleChild( (sal_Int32)m_pListBoxHelper->GetSelectEntryPos( (sal_uInt16)nSelectedChildIndex ) );
1025cdf0e10cSrcweir 	}
1026cdf0e10cSrcweir 
1027cdf0e10cSrcweir 	return NULL;
1028cdf0e10cSrcweir }
1029cdf0e10cSrcweir // -----------------------------------------------------------------------------
1030cdf0e10cSrcweir void SAL_CALL VCLXAccessibleList::deselectAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
1031cdf0e10cSrcweir {
1032cdf0e10cSrcweir 	sal_Bool bNotify = sal_False;
1033cdf0e10cSrcweir 
1034cdf0e10cSrcweir 	{
1035cdf0e10cSrcweir 		vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1036cdf0e10cSrcweir 		::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
1037cdf0e10cSrcweir 
1038cdf0e10cSrcweir 		if ( m_pListBoxHelper )
1039cdf0e10cSrcweir 		{
1040cdf0e10cSrcweir 			checkSelection_Impl(nSelectedChildIndex,*m_pListBoxHelper,sal_False);
1041cdf0e10cSrcweir 
1042cdf0e10cSrcweir 			m_pListBoxHelper->SelectEntryPos( (sal_uInt16)nSelectedChildIndex, sal_False );
1043cdf0e10cSrcweir 			// call the select handler, don't handle events in this time
1044cdf0e10cSrcweir 			m_bDisableProcessEvent = true;
1045cdf0e10cSrcweir 			m_pListBoxHelper->Select();
1046cdf0e10cSrcweir 			m_bDisableProcessEvent = false;
1047cdf0e10cSrcweir 			bNotify = sal_True;
1048cdf0e10cSrcweir 		}
1049cdf0e10cSrcweir 	}
1050cdf0e10cSrcweir 
1051cdf0e10cSrcweir 	if ( bNotify )
1052cdf0e10cSrcweir         UpdateSelection_Impl();
1053cdf0e10cSrcweir }
1054cdf0e10cSrcweir // -----------------------------------------------------------------------------
1055cdf0e10cSrcweir // accessibility::XAccessibleComponent
1056cdf0e10cSrcweir awt::Rectangle VCLXAccessibleList::implGetBounds() throw (uno::RuntimeException)
1057cdf0e10cSrcweir {
1058cdf0e10cSrcweir 	awt::Rectangle aBounds ( 0, 0, 0, 0 );
1059cdf0e10cSrcweir 	if ( m_pListBoxHelper
1060cdf0e10cSrcweir 		&& (m_pListBoxHelper->GetStyle() & WB_DROPDOWN ) == WB_DROPDOWN )
1061cdf0e10cSrcweir 	{
1062cdf0e10cSrcweir 		if ( m_pListBoxHelper->IsInDropDown() )
1063cdf0e10cSrcweir 			aBounds = AWTRectangle(m_pListBoxHelper->GetDropDownPosSizePixel());
1064cdf0e10cSrcweir 	}
1065cdf0e10cSrcweir 	else
1066cdf0e10cSrcweir 	{
1067cdf0e10cSrcweir 		// a list has the same bounds as his parent but starts at (0,0)
1068cdf0e10cSrcweir 		aBounds = VCLXAccessibleComponent::implGetBounds();
1069cdf0e10cSrcweir 		aBounds.X = 0;
1070cdf0e10cSrcweir 		aBounds.Y = 0;
1071cdf0e10cSrcweir 		if ( m_aBoxType == COMBOBOX )
1072cdf0e10cSrcweir 		{
1073cdf0e10cSrcweir 			ComboBox* pBox = static_cast<ComboBox*>(GetWindow());
1074cdf0e10cSrcweir 			if ( pBox )
1075cdf0e10cSrcweir 			{
1076cdf0e10cSrcweir 				Size aSize = pBox->GetSubEdit()->GetSizePixel();
1077*21075d77SSteve Yin 				// IAccessible2 implementation, 2009
1078*21075d77SSteve Yin 				//aBounds.X += aSize.Height();
1079*21075d77SSteve Yin 				//aBounds.Y += aSize.Width();
1080*21075d77SSteve Yin 				aBounds.Y += aSize.Height();
1081cdf0e10cSrcweir 				aBounds.Height -= aSize.Height();
1082*21075d77SSteve Yin 				//aBounds.Width  -= aSize.Width();
1083cdf0e10cSrcweir 			}
1084cdf0e10cSrcweir 		}
1085cdf0e10cSrcweir 	}
1086cdf0e10cSrcweir 	return aBounds;
1087cdf0e10cSrcweir }
1088cdf0e10cSrcweir // -----------------------------------------------------------------------------
1089cdf0e10cSrcweir 
1090cdf0e10cSrcweir awt::Point VCLXAccessibleList::getLocationOnScreen(  ) throw (uno::RuntimeException)
1091cdf0e10cSrcweir {
1092cdf0e10cSrcweir 	vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1093cdf0e10cSrcweir 	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
1094cdf0e10cSrcweir 
1095cdf0e10cSrcweir 	awt::Point aPos;
1096cdf0e10cSrcweir 	if ( m_pListBoxHelper
1097cdf0e10cSrcweir 		&& (m_pListBoxHelper->GetStyle() & WB_DROPDOWN ) == WB_DROPDOWN )
1098cdf0e10cSrcweir 	{
1099cdf0e10cSrcweir 		if ( m_pListBoxHelper->IsInDropDown() )
1100cdf0e10cSrcweir 			aPos = AWTPoint(m_pListBoxHelper->GetDropDownPosSizePixel().TopLeft());
1101cdf0e10cSrcweir 	}
1102cdf0e10cSrcweir 	else
1103cdf0e10cSrcweir 	{
1104cdf0e10cSrcweir 		aPos = VCLXAccessibleComponent::getLocationOnScreen();
1105cdf0e10cSrcweir 		if ( m_aBoxType == COMBOBOX )
1106cdf0e10cSrcweir 		{
1107cdf0e10cSrcweir 			ComboBox* pBox = static_cast<ComboBox*>(GetWindow());
1108cdf0e10cSrcweir 			if ( pBox )
1109cdf0e10cSrcweir 			{
1110*21075d77SSteve Yin 				//aPos.X += pBox->GetSubEdit()->GetSizePixel().Height();
1111*21075d77SSteve Yin 				//aPos.Y += pBox->GetSubEdit()->GetSizePixel().Width();
1112*21075d77SSteve Yin 				aPos.Y += pBox->GetSubEdit()->GetSizePixel().Height();
1113cdf0e10cSrcweir 			}
1114cdf0e10cSrcweir 		}
1115cdf0e10cSrcweir 	}
1116cdf0e10cSrcweir 	return aPos;
1117cdf0e10cSrcweir }
1118cdf0e10cSrcweir // -----------------------------------------------------------------------------
1119*21075d77SSteve Yin sal_Bool	VCLXAccessibleList::IsInDropDown()
1120*21075d77SSteve Yin {
1121*21075d77SSteve Yin 	return m_pListBoxHelper->IsInDropDown();
1122*21075d77SSteve Yin }
1123*21075d77SSteve Yin // -----------------------------------------------------------------------------
1124*21075d77SSteve Yin void VCLXAccessibleList::HandleDropOpen()
1125*21075d77SSteve Yin {
1126*21075d77SSteve Yin 	if ( !m_bDisableProcessEvent )
1127*21075d77SSteve Yin 		UpdateSelection_Impl();
1128*21075d77SSteve Yin 	if (m_nCurSelectedPos != LISTBOX_ENTRY_NOTFOUND &&
1129*21075d77SSteve Yin 		m_nLastSelectedPos != LISTBOX_ENTRY_NOTFOUND)
1130*21075d77SSteve Yin 	{
1131*21075d77SSteve Yin 		Reference< XAccessible > xChild = getAccessibleChild(m_nCurSelectedPos);
1132*21075d77SSteve Yin 		if(xChild.is())
1133*21075d77SSteve Yin 		{
1134*21075d77SSteve Yin 			uno::Any aNewValue;
1135*21075d77SSteve Yin 			aNewValue <<= xChild;
1136*21075d77SSteve Yin 			NotifyAccessibleEvent(AccessibleEventId::ACTIVE_DESCENDANT_CHANGED,	uno::Any(), aNewValue );
1137*21075d77SSteve Yin 		}
1138*21075d77SSteve Yin 	}
1139*21075d77SSteve Yin }
1140