xref: /AOO41X/main/accessibility/source/standard/vclxaccessiblelist.cxx (revision 6485ffd2b11bb996603642c324760870d77ebb51)
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 
3921075d77SSteve Yin #ifndef _UTL_ACCESSIBLERELATIONSETHELPER_HXX_
4021075d77SSteve Yin #include <unotools/accessiblerelationsethelper.hxx>
4121075d77SSteve Yin #endif
4221075d77SSteve Yin #ifndef _COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLERELATIONTYPE_HPP_
4321075d77SSteve Yin #include <com/sun/star/accessibility/AccessibleRelationType.hpp>
4421075d77SSteve 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 {
checkSelection_Impl(sal_Int32 _nIndex,const IComboListBoxHelper & _rListBox,sal_Bool bSelected)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 
VCLXAccessibleList(VCLXWindow * pVCLWindow,BoxType aBoxType,const Reference<XAccessible> & _xParent)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 ),
7421075d77SSteve 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();
9921075d77SSteve Yin 	m_nCurSelectedPos=m_pListBoxHelper->GetSelectEntryPos();
100cdf0e10cSrcweir 
101cdf0e10cSrcweir 	sal_uInt16 nCount = static_cast<sal_uInt16>(getAccessibleChildCount());
102cdf0e10cSrcweir 	m_aAccessibleChildren.reserve(nCount);
103cdf0e10cSrcweir }
104cdf0e10cSrcweir // -----------------------------------------------------------------------------
105cdf0e10cSrcweir 
~VCLXAccessibleList(void)106cdf0e10cSrcweir VCLXAccessibleList::~VCLXAccessibleList (void)
107cdf0e10cSrcweir {
108cdf0e10cSrcweir     delete m_pListBoxHelper;
109cdf0e10cSrcweir }
110cdf0e10cSrcweir // -----------------------------------------------------------------------------
111cdf0e10cSrcweir 
SetIndexInParent(sal_Int32 nIndex)112cdf0e10cSrcweir void VCLXAccessibleList::SetIndexInParent (sal_Int32 nIndex)
113cdf0e10cSrcweir {
114cdf0e10cSrcweir     m_nIndexInParent = nIndex;
115cdf0e10cSrcweir }
116cdf0e10cSrcweir // -----------------------------------------------------------------------------
117cdf0e10cSrcweir 
disposing(void)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 
clearItems()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 
FillAccessibleStateSet(utl::AccessibleStateSetHelper & rStateSet)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 // -----------------------------------------------------------------------------
notifyVisibleStates(sal_Bool _bSetNew)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 // -----------------------------------------------------------------------------
UpdateSelection_Acc(::rtl::OUString sTextOfSelectedItem,bool b_IsDropDownList)19921075d77SSteve Yin void VCLXAccessibleList::UpdateSelection_Acc (::rtl::OUString sTextOfSelectedItem, bool b_IsDropDownList)
20021075d77SSteve Yin {
20121075d77SSteve Yin     if ( m_aBoxType == COMBOBOX )
20221075d77SSteve Yin     {
20321075d77SSteve Yin         ComboBox* pBox = static_cast<ComboBox*>(GetWindow());
20421075d77SSteve Yin         if ( pBox != NULL )
20521075d77SSteve Yin         {
20621075d77SSteve Yin 		// Find the index of the selected item inside the VCL control...
20721075d77SSteve Yin 		sal_uInt16 nIndex = pBox->GetEntryPos (XubString(sTextOfSelectedItem));
20821075d77SSteve Yin 		// ...and then find the associated accessibility object.
20921075d77SSteve Yin 		if ( nIndex == LISTBOX_ENTRY_NOTFOUND )
21021075d77SSteve Yin 			nIndex = 0;
21121075d77SSteve Yin 		UpdateSelection_Impl_Acc(b_IsDropDownList);
21221075d77SSteve Yin         }
21321075d77SSteve Yin     }
21421075d77SSteve Yin }
21521075d77SSteve Yin 
21621075d77SSteve Yin // -----------------------------------------------------------------------------
UpdateSelection_Impl_Acc(bool b_IsDropDownList)21721075d77SSteve Yin void VCLXAccessibleList::UpdateSelection_Impl_Acc(bool b_IsDropDownList)
21821075d77SSteve Yin {
21921075d77SSteve Yin 	uno::Any aOldValue, aNewValue;
22021075d77SSteve Yin 	VCLXAccessibleListItem* pCurItem =NULL;
22121075d77SSteve Yin 
22221075d77SSteve Yin 	{
22321075d77SSteve Yin 		vos::OGuard aSolarGuard( Application::GetSolarMutex() );
22421075d77SSteve Yin 		::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
22521075d77SSteve Yin 	    	Reference< XAccessible > xNewAcc;
22621075d77SSteve Yin 		if ( m_pListBoxHelper )
22721075d77SSteve Yin 		{
22821075d77SSteve Yin 			sal_uInt16 i=0;
22921075d77SSteve Yin 			m_nCurSelectedPos = LISTBOX_ENTRY_NOTFOUND;
23021075d77SSteve Yin 			for ( ListItems::iterator aIter = m_aAccessibleChildren.begin();
23121075d77SSteve Yin 				  aIter != m_aAccessibleChildren.end(); ++aIter,++i)
23221075d77SSteve Yin 			{
23321075d77SSteve Yin 				Reference< XAccessible > xHold = *aIter;
23421075d77SSteve Yin 				if ( xHold.is() )
23521075d77SSteve Yin 				{
23621075d77SSteve Yin 					VCLXAccessibleListItem* pItem = static_cast< VCLXAccessibleListItem* >( xHold.get() );
23721075d77SSteve Yin 					// Retrieve the item's index from the list entry.
23821075d77SSteve Yin 					sal_Bool bNowSelected = m_pListBoxHelper->IsEntryPosSelected (i);
23921075d77SSteve Yin 					if (bNowSelected)
24021075d77SSteve Yin 						m_nCurSelectedPos = i;
24121075d77SSteve Yin 
24221075d77SSteve Yin 					if ( bNowSelected && !pItem->IsSelected() )
24321075d77SSteve Yin 					{
24421075d77SSteve Yin 						xNewAcc = *aIter;
24521075d77SSteve Yin 						aNewValue <<= xNewAcc;
24621075d77SSteve Yin 
24721075d77SSteve Yin 						pCurItem = pItem;
24821075d77SSteve Yin 
24921075d77SSteve Yin 					}
25021075d77SSteve Yin 					else if ( pItem->IsSelected() )
25121075d77SSteve Yin 						m_nLastSelectedPos = i;
25221075d77SSteve Yin 
25321075d77SSteve Yin 					pItem->SetSelected( bNowSelected );
25421075d77SSteve Yin 				}
25521075d77SSteve Yin 				else
25621075d77SSteve Yin 				{ // it could happen that a child was not created before
25721075d77SSteve Yin 					checkEntrySelected(i,aNewValue,xNewAcc);
25821075d77SSteve Yin 				}
25921075d77SSteve Yin 			}
26021075d77SSteve Yin 			sal_uInt16 nCount = m_pListBoxHelper->GetEntryCount();
26121075d77SSteve Yin 			if ( i < nCount ) // here we have to check the if any other listbox entry is selected
26221075d77SSteve Yin 			{
26321075d77SSteve Yin 				for (; i < nCount && !checkEntrySelected(i,aNewValue,xNewAcc) ;++i )
26421075d77SSteve Yin 					;
26521075d77SSteve Yin 			}
26621075d77SSteve Yin 			if ( xNewAcc.is() && GetWindow()->HasFocus() )
26721075d77SSteve Yin 			{
26821075d77SSteve Yin 				if ( m_nLastSelectedPos != LISTBOX_ENTRY_NOTFOUND )
26921075d77SSteve Yin 					aOldValue <<= getAccessibleChild( (sal_Int32)m_nLastSelectedPos );
27021075d77SSteve Yin 				aNewValue <<= xNewAcc;
27121075d77SSteve Yin 			}
27221075d77SSteve Yin 		}
27321075d77SSteve Yin 	}
27421075d77SSteve Yin 	if (m_aBoxType == COMBOBOX && b_IsDropDownList)
27521075d77SSteve Yin 	{
27621075d77SSteve Yin 		//VCLXAccessibleDropDownComboBox
27721075d77SSteve Yin 		//when in list is dropped down, xText = NULL
27821075d77SSteve Yin 		if (m_pListBoxHelper->IsInDropDown())
27921075d77SSteve Yin 		{
28021075d77SSteve Yin 			if ( aNewValue.hasValue() || aOldValue.hasValue() )
28121075d77SSteve Yin 			{
28221075d77SSteve Yin 				NotifyAccessibleEvent(
28321075d77SSteve Yin 					AccessibleEventId::ACTIVE_DESCENDANT_CHANGED,
28421075d77SSteve Yin 					aOldValue,
28521075d77SSteve Yin 					aNewValue );
28621075d77SSteve Yin 
28721075d77SSteve Yin 				NotifyListItem(aNewValue);
28821075d77SSteve Yin 
28921075d77SSteve Yin 			}
29021075d77SSteve Yin 		}
29121075d77SSteve Yin 	}
29221075d77SSteve Yin 	else if (m_aBoxType == COMBOBOX && !b_IsDropDownList)
29321075d77SSteve Yin 	{
29421075d77SSteve Yin 		//VCLXAccessibleComboBox
29521075d77SSteve Yin 		NotifyAccessibleEvent( AccessibleEventId::SELECTION_CHANGED, uno::Any(), uno::Any() );
29621075d77SSteve Yin 	}
29721075d77SSteve Yin 	else if (m_aBoxType == LISTBOX && b_IsDropDownList)
29821075d77SSteve Yin 	{
29921075d77SSteve Yin 		//VCLXAccessibleDropdownListBox
30021075d77SSteve Yin 		//when in list is dropped down, xText = NULL
30121075d77SSteve Yin 		if (m_pListBoxHelper->IsInDropDown())
30221075d77SSteve Yin 		{
30321075d77SSteve Yin 			if ( aNewValue.hasValue() || aOldValue.hasValue() )
30421075d77SSteve Yin 			{
30521075d77SSteve Yin 				NotifyAccessibleEvent(
30621075d77SSteve Yin 					AccessibleEventId::ACTIVE_DESCENDANT_CHANGED,
30721075d77SSteve Yin 					aOldValue,
30821075d77SSteve Yin 					aNewValue );
30921075d77SSteve Yin 
31021075d77SSteve Yin 				NotifyListItem(aNewValue);
31121075d77SSteve Yin 			}
31221075d77SSteve Yin 		}
31321075d77SSteve Yin 	}
31421075d77SSteve Yin 	else if (m_aBoxType == LISTBOX && !b_IsDropDownList)
31521075d77SSteve Yin 	{
31621075d77SSteve Yin 		//VCLXAccessibleListBox, xText = NULL.
31721075d77SSteve Yin 
31821075d77SSteve Yin 
31921075d77SSteve Yin 		if ( aNewValue.hasValue())
32021075d77SSteve Yin 		{
32121075d77SSteve Yin 			NotifyListItem(aNewValue);
32221075d77SSteve Yin 		}
32321075d77SSteve Yin 	}
32421075d77SSteve Yin }
NotifyListItem(::com::sun::star::uno::Any & val)32521075d77SSteve Yin void VCLXAccessibleList::NotifyListItem(::com::sun::star::uno::Any& val)
32621075d77SSteve Yin {
32721075d77SSteve Yin 	Reference< XAccessible > xCurItem;
32821075d77SSteve Yin 	val >>= xCurItem;
32921075d77SSteve Yin 	if (xCurItem.is())
33021075d77SSteve Yin 	{
33121075d77SSteve Yin 		VCLXAccessibleListItem* pCurItem = static_cast< VCLXAccessibleListItem* >(xCurItem.get());
33221075d77SSteve Yin 		if (pCurItem)
33321075d77SSteve Yin 		{
33421075d77SSteve Yin 			pCurItem->NotifyAccessibleEvent(AccessibleEventId::SELECTION_CHANGED,Any(),Any());
33521075d77SSteve Yin 		}
33621075d77SSteve Yin 	}
33721075d77SSteve Yin }
33821075d77SSteve Yin 
33921075d77SSteve Yin 
UpdateFocus_Impl_Acc(sal_uInt16 nPos,bool b_IsDropDownList)34021075d77SSteve Yin void VCLXAccessibleList::UpdateFocus_Impl_Acc (sal_uInt16 nPos ,bool b_IsDropDownList)
34121075d77SSteve Yin {
34221075d77SSteve Yin 	if (!(m_aBoxType == LISTBOX && !b_IsDropDownList))
34321075d77SSteve Yin 	{
34421075d77SSteve Yin 		return ;
34521075d77SSteve Yin 	}
34621075d77SSteve Yin     Reference<XAccessible> xChild= CreateChild(nPos);
34721075d77SSteve Yin 	if ( !xChild.is() )
34821075d77SSteve Yin 	{
34921075d77SSteve Yin 		return ;
35021075d77SSteve Yin 	}
35121075d77SSteve Yin 	m_nCurSelectedPos = nPos;
35221075d77SSteve Yin 	uno::Any aOldValue, aNewValue;
35321075d77SSteve Yin 	aNewValue <<= xChild;
35421075d77SSteve Yin 
35521075d77SSteve Yin 	NotifyAccessibleEvent(
35621075d77SSteve Yin 			AccessibleEventId::ACTIVE_DESCENDANT_CHANGED,
35721075d77SSteve Yin 			aOldValue,
35821075d77SSteve Yin 			aNewValue );
35921075d77SSteve Yin }
36021075d77SSteve Yin 
36121075d77SSteve Yin // -----------------------------------------------------------------------------
ProcessWindowEvent(const VclWindowEvent & rVclWindowEvent,bool b_IsDropDownList)36221075d77SSteve Yin void VCLXAccessibleList::ProcessWindowEvent (const VclWindowEvent& rVclWindowEvent,  bool b_IsDropDownList)
36321075d77SSteve Yin {
36421075d77SSteve Yin 	switch ( rVclWindowEvent.GetId() )
36521075d77SSteve Yin       {
366*6485ffd2SSteve Yin 		case VCLEVENT_DROPDOWN_SELECT:
36721075d77SSteve Yin 		case VCLEVENT_LISTBOX_SELECT:
36821075d77SSteve Yin 			if ( !m_bDisableProcessEvent )
36921075d77SSteve Yin 				UpdateSelection_Impl_Acc(b_IsDropDownList);
37021075d77SSteve Yin 			break;
37121075d77SSteve Yin 		case VCLEVENT_LISTBOX_FOCUSITEMCHANGED:
37221075d77SSteve Yin 			if ( !m_bDisableProcessEvent )
37389874c60SHerbert Dürr 				UpdateFocus_Impl_Acc((sal_uInt16)reinterpret_cast<sal_uIntPtr>(rVclWindowEvent.GetData()),b_IsDropDownList);
37421075d77SSteve Yin 			break;
37521075d77SSteve Yin 		case VCLEVENT_WINDOW_GETFOCUS:
37621075d77SSteve Yin 			break;
37721075d77SSteve Yin 		case VCLEVENT_CONTROL_GETFOCUS:
37821075d77SSteve Yin 			{
37921075d77SSteve Yin 				VCLXAccessibleComponent::ProcessWindowEvent (rVclWindowEvent);
38021075d77SSteve Yin 				if (m_aBoxType == COMBOBOX && b_IsDropDownList)
38121075d77SSteve Yin 				{
38221075d77SSteve Yin 					//VCLXAccessibleDropDownComboBox
38321075d77SSteve Yin 				}
38421075d77SSteve Yin 				else if (m_aBoxType == LISTBOX && b_IsDropDownList)
38521075d77SSteve Yin 				{
38621075d77SSteve Yin 				}
38721075d77SSteve Yin 				else if ( m_aBoxType == LISTBOX && !b_IsDropDownList)
38821075d77SSteve Yin 				{
38921075d77SSteve Yin 					if ( m_pListBoxHelper )
39021075d77SSteve Yin 					{
39121075d77SSteve Yin 						uno::Any	aOldValue,
39221075d77SSteve Yin 									aNewValue;
39321075d77SSteve Yin 						sal_uInt16 nPos = m_nCurSelectedPos; //m_pListBoxHelper->GetSelectEntryPos();
39421075d77SSteve Yin 
39521075d77SSteve Yin 						if ( nPos == LISTBOX_ENTRY_NOTFOUND )
39621075d77SSteve Yin 							nPos = m_pListBoxHelper->GetTopEntry();
39721075d77SSteve Yin 						if ( nPos != LISTBOX_ENTRY_NOTFOUND )
39821075d77SSteve Yin 							aNewValue <<= CreateChild(nPos);
39921075d77SSteve Yin 						NotifyAccessibleEvent(	AccessibleEventId::ACTIVE_DESCENDANT_CHANGED,
40021075d77SSteve Yin 												aOldValue,
40121075d77SSteve Yin 												aNewValue );
40221075d77SSteve Yin 					}
40321075d77SSteve Yin 				}
40421075d77SSteve Yin 			}
40521075d77SSteve Yin 			break;
40621075d77SSteve Yin 		default:
40721075d77SSteve Yin 			break;
40821075d77SSteve Yin 	}
40921075d77SSteve Yin 
41021075d77SSteve Yin }
41121075d77SSteve Yin // -----------------------------------------------------------------------------
ProcessWindowEvent(const VclWindowEvent & rVclWindowEvent)412cdf0e10cSrcweir void VCLXAccessibleList::ProcessWindowEvent (const VclWindowEvent& rVclWindowEvent)
413cdf0e10cSrcweir {
414cdf0e10cSrcweir     // Create a reference to this object to prevent an early release of the
415cdf0e10cSrcweir     // listbox (VCLEVENT_OBJECT_DYING).
416cdf0e10cSrcweir 	Reference< XAccessible > xTemp = this;
417cdf0e10cSrcweir 
418cdf0e10cSrcweir 	switch ( rVclWindowEvent.GetId() )
419cdf0e10cSrcweir     {
420cdf0e10cSrcweir 		case VCLEVENT_DROPDOWN_OPEN:
421cdf0e10cSrcweir 			notifyVisibleStates(sal_True);
422cdf0e10cSrcweir 			break;
423cdf0e10cSrcweir 		case VCLEVENT_DROPDOWN_CLOSE:
424cdf0e10cSrcweir 			notifyVisibleStates(sal_False);
425cdf0e10cSrcweir 			break;
426cdf0e10cSrcweir 		case VCLEVENT_LISTBOX_SCROLLED:
427cdf0e10cSrcweir 		case VCLEVENT_COMBOBOX_SCROLLED:
428cdf0e10cSrcweir 			UpdateEntryRange_Impl();
429cdf0e10cSrcweir 			break;
4303ea0c3d5SHerbert Dürr 
431cdf0e10cSrcweir 		// The selection events VCLEVENT_COMBOBOX_SELECT and
432cdf0e10cSrcweir 		// VCLEVENT_COMBOBOX_DESELECT are not handled here because here we
433cdf0e10cSrcweir 		// have no access to the edit field.  Its text is necessary to
434cdf0e10cSrcweir 		// identify the currently selected item.
435cdf0e10cSrcweir 
436cdf0e10cSrcweir 		case VCLEVENT_OBJECT_DYING:
437cdf0e10cSrcweir 		{
438cdf0e10cSrcweir             dispose();
439cdf0e10cSrcweir 
440cdf0e10cSrcweir             VCLXAccessibleComponent::ProcessWindowEvent (rVclWindowEvent);
441cdf0e10cSrcweir             break;
442cdf0e10cSrcweir 		}
443cdf0e10cSrcweir 
444cdf0e10cSrcweir         case VCLEVENT_LISTBOX_ITEMREMOVED:
445cdf0e10cSrcweir         case VCLEVENT_COMBOBOX_ITEMREMOVED:
446cdf0e10cSrcweir             HandleChangedItemList (false, reinterpret_cast<sal_IntPtr>(
447cdf0e10cSrcweir                 rVclWindowEvent.GetData()));
448cdf0e10cSrcweir             break;
449cdf0e10cSrcweir 
450cdf0e10cSrcweir         case VCLEVENT_LISTBOX_ITEMADDED:
451cdf0e10cSrcweir         case VCLEVENT_COMBOBOX_ITEMADDED:
452cdf0e10cSrcweir             HandleChangedItemList (true, reinterpret_cast<sal_IntPtr>(
453cdf0e10cSrcweir                 rVclWindowEvent.GetData()));
454cdf0e10cSrcweir             break;
455cdf0e10cSrcweir 		case VCLEVENT_CONTROL_GETFOCUS:
45621075d77SSteve Yin 			{
457cdf0e10cSrcweir 	            VCLXAccessibleComponent::ProcessWindowEvent (rVclWindowEvent);
45821075d77SSteve Yin 				// Added by IBM Symphony Acc team to handle the list item focus when List control get focus
45921075d77SSteve Yin 				sal_Bool b_IsDropDownList = sal_True;
46021075d77SSteve Yin 				if (m_pListBoxHelper)
46121075d77SSteve Yin 					b_IsDropDownList = ((m_pListBoxHelper->GetStyle() & WB_DROPDOWN ) == WB_DROPDOWN);
46221075d77SSteve Yin 				if ( m_aBoxType == LISTBOX && !b_IsDropDownList )
46321075d77SSteve Yin 				{
464cdf0e10cSrcweir 					if ( m_pListBoxHelper )
465cdf0e10cSrcweir 					{
466cdf0e10cSrcweir 						uno::Any	aOldValue,
467cdf0e10cSrcweir 									aNewValue;
46821075d77SSteve Yin 						sal_uInt16 nPos = m_nCurSelectedPos;
46921075d77SSteve Yin 
470cdf0e10cSrcweir 						if ( nPos == LISTBOX_ENTRY_NOTFOUND )
471cdf0e10cSrcweir 							nPos = m_pListBoxHelper->GetTopEntry();
472cdf0e10cSrcweir 						if ( nPos != LISTBOX_ENTRY_NOTFOUND )
473cdf0e10cSrcweir 							aNewValue <<= CreateChild(nPos);
474cdf0e10cSrcweir 						NotifyAccessibleEvent(	AccessibleEventId::ACTIVE_DESCENDANT_CHANGED,
475cdf0e10cSrcweir 												aOldValue,
476cdf0e10cSrcweir 												aNewValue );
477cdf0e10cSrcweir 					}
47821075d77SSteve Yin 				}
47921075d77SSteve Yin 			}
480cdf0e10cSrcweir 			break;
481cdf0e10cSrcweir 
482cdf0e10cSrcweir         default:
483cdf0e10cSrcweir             VCLXAccessibleComponent::ProcessWindowEvent (rVclWindowEvent);
484cdf0e10cSrcweir     }
485cdf0e10cSrcweir }
48621075d77SSteve Yin 
FillAccessibleRelationSet(utl::AccessibleRelationSetHelper & rRelationSet)48721075d77SSteve Yin  void VCLXAccessibleList::FillAccessibleRelationSet( utl::AccessibleRelationSetHelper& rRelationSet )
48821075d77SSteve Yin {
48921075d77SSteve Yin 	ListBox* pBox = static_cast<ListBox*>(GetWindow());
49021075d77SSteve Yin 	if( m_aBoxType == LISTBOX  )
49121075d77SSteve Yin 	{
49221075d77SSteve Yin 		if (m_pListBoxHelper && (m_pListBoxHelper->GetStyle() & WB_DROPDOWN ) != WB_DROPDOWN)
49321075d77SSteve Yin 		{
49421075d77SSteve Yin 			uno::Sequence< uno::Reference< uno::XInterface > > aSequence(1);
49521075d77SSteve Yin 			aSequence[0] = pBox->GetAccessible();
49621075d77SSteve Yin 			rRelationSet.AddRelation( com::sun::star::accessibility::AccessibleRelation( com::sun::star::accessibility::AccessibleRelationType::MEMBER_OF, aSequence ) );
49721075d77SSteve Yin 		}
49821075d77SSteve Yin 	}
49921075d77SSteve Yin 	else
50021075d77SSteve Yin 	{
50121075d77SSteve Yin 		VCLXAccessibleComponent::FillAccessibleRelationSet(rRelationSet);
50221075d77SSteve Yin 	}
50321075d77SSteve Yin }
504cdf0e10cSrcweir // -----------------------------------------------------------------------------
505cdf0e10cSrcweir 
506cdf0e10cSrcweir /** To find out which item is currently selected and to update the SELECTED
507cdf0e10cSrcweir     state of the associated accessibility objects accordingly we exploit the
508cdf0e10cSrcweir     fact that the
509cdf0e10cSrcweir */
UpdateSelection(::rtl::OUString sTextOfSelectedItem)510cdf0e10cSrcweir void VCLXAccessibleList::UpdateSelection (::rtl::OUString sTextOfSelectedItem)
511cdf0e10cSrcweir {
512cdf0e10cSrcweir     if ( m_aBoxType == COMBOBOX )
513cdf0e10cSrcweir     {
514cdf0e10cSrcweir         ComboBox* pBox = static_cast<ComboBox*>(GetWindow());
515cdf0e10cSrcweir         if ( pBox != NULL )
516cdf0e10cSrcweir         {
517cdf0e10cSrcweir             // Find the index of the selected item inside the VCL control...
518cdf0e10cSrcweir             sal_uInt16 nIndex = pBox->GetEntryPos (XubString(sTextOfSelectedItem));
519cdf0e10cSrcweir             // ...and then find the associated accessibility object.
520cdf0e10cSrcweir 			if ( nIndex == LISTBOX_ENTRY_NOTFOUND )
521cdf0e10cSrcweir 				nIndex = 0;
522cdf0e10cSrcweir 			UpdateSelection_Impl(nIndex);
523cdf0e10cSrcweir         }
524cdf0e10cSrcweir     }
525cdf0e10cSrcweir }
526cdf0e10cSrcweir // -----------------------------------------------------------------------------
527cdf0e10cSrcweir 
adjustEntriesIndexInParent(ListItems::iterator & _aBegin,::std::mem_fun_t<bool,VCLXAccessibleListItem> & _rMemFun)528cdf0e10cSrcweir void VCLXAccessibleList::adjustEntriesIndexInParent(ListItems::iterator& _aBegin,::std::mem_fun_t<bool,VCLXAccessibleListItem>& _rMemFun)
529cdf0e10cSrcweir {
530cdf0e10cSrcweir 	ListItems::iterator aIter = _aBegin;
531cdf0e10cSrcweir 	ListItems::iterator aEnd = m_aAccessibleChildren.end();
532cdf0e10cSrcweir 	// adjust the index inside the VCLXAccessibleListItem
533cdf0e10cSrcweir 	for (;aIter != aEnd ; ++aIter)
534cdf0e10cSrcweir 	{
535cdf0e10cSrcweir 		Reference< XAccessible > xHold = *aIter;
536cdf0e10cSrcweir 		VCLXAccessibleListItem* pItem = static_cast<VCLXAccessibleListItem*>(xHold.get());
537cdf0e10cSrcweir 		if ( pItem )
538cdf0e10cSrcweir 			_rMemFun(pItem);
539cdf0e10cSrcweir 	}
540cdf0e10cSrcweir }
541cdf0e10cSrcweir // -----------------------------------------------------------------------------
542cdf0e10cSrcweir 
CreateChild(sal_Int32 i)543cdf0e10cSrcweir Reference<XAccessible> VCLXAccessibleList::CreateChild (sal_Int32 i)
544cdf0e10cSrcweir {
545cdf0e10cSrcweir     Reference<XAccessible> xChild;
546cdf0e10cSrcweir 
547cdf0e10cSrcweir 	sal_uInt16 nPos = static_cast<sal_uInt16>(i);
548cdf0e10cSrcweir 	if ( nPos >= m_aAccessibleChildren.size() )
549cdf0e10cSrcweir 	{
550cdf0e10cSrcweir 		m_aAccessibleChildren.resize(nPos + 1);
551cdf0e10cSrcweir 
552cdf0e10cSrcweir 		// insert into the container
553cdf0e10cSrcweir 		xChild = new VCLXAccessibleListItem(m_pListBoxHelper, i, this);
554cdf0e10cSrcweir 		m_aAccessibleChildren[nPos] = xChild;
555cdf0e10cSrcweir 	}
556cdf0e10cSrcweir 	else
557cdf0e10cSrcweir 	{
558cdf0e10cSrcweir 		xChild = m_aAccessibleChildren[nPos];
559cdf0e10cSrcweir 		// check if position is empty and can be used else we have to adjust all entries behind this
5603ea0c3d5SHerbert Dürr 		if ( !xChild.is() )
561cdf0e10cSrcweir 		{
562cdf0e10cSrcweir 			xChild = new VCLXAccessibleListItem(m_pListBoxHelper, i, this);
563cdf0e10cSrcweir 			m_aAccessibleChildren[nPos] = xChild;
564cdf0e10cSrcweir 		}
565cdf0e10cSrcweir 	}
566cdf0e10cSrcweir 
567cdf0e10cSrcweir     if ( xChild.is() )
568cdf0e10cSrcweir     {
569cdf0e10cSrcweir 		// Just add the SELECTED state.
570cdf0e10cSrcweir 		sal_Bool bNowSelected = sal_False;
571cdf0e10cSrcweir 		if ( m_pListBoxHelper )
572cdf0e10cSrcweir 			bNowSelected = m_pListBoxHelper->IsEntryPosSelected ((sal_uInt16)i);
57321075d77SSteve Yin 		if (bNowSelected)
57421075d77SSteve Yin 			m_nCurSelectedPos = sal_uInt16(i);
575cdf0e10cSrcweir         VCLXAccessibleListItem* pItem = static_cast< VCLXAccessibleListItem* >(xChild.get());
576cdf0e10cSrcweir         pItem->SetSelected( bNowSelected );
577cdf0e10cSrcweir 
578cdf0e10cSrcweir 		// Set the child's VISIBLE state.
579cdf0e10cSrcweir         UpdateVisibleLineCount();
580cdf0e10cSrcweir 		sal_uInt16 nTopEntry = 0;
581cdf0e10cSrcweir 		if ( m_pListBoxHelper )
582cdf0e10cSrcweir 			nTopEntry = m_pListBoxHelper->GetTopEntry();
583cdf0e10cSrcweir 		sal_Bool bVisible = ( nPos>=nTopEntry && nPos<( nTopEntry + m_nVisibleLineCount ) );
584cdf0e10cSrcweir 		pItem->SetVisible( m_bVisible && bVisible );
585cdf0e10cSrcweir     }
586cdf0e10cSrcweir 
587cdf0e10cSrcweir     return xChild;
588cdf0e10cSrcweir }
589cdf0e10cSrcweir // -----------------------------------------------------------------------------
590cdf0e10cSrcweir 
HandleChangedItemList(bool bItemInserted,sal_Int32 nIndex)591cdf0e10cSrcweir void VCLXAccessibleList::HandleChangedItemList (bool bItemInserted, sal_Int32 nIndex)
592cdf0e10cSrcweir {
59321075d77SSteve Yin 	clearItems();
594cdf0e10cSrcweir     NotifyAccessibleEvent (
595cdf0e10cSrcweir         AccessibleEventId::INVALIDATE_ALL_CHILDREN,
596cdf0e10cSrcweir         Any(), Any());
597cdf0e10cSrcweir }
598cdf0e10cSrcweir // -----------------------------------------------------------------------------
599cdf0e10cSrcweir 
IMPLEMENT_FORWARD_XINTERFACE2(VCLXAccessibleList,VCLXAccessibleComponent,VCLXAccessibleList_BASE)600cdf0e10cSrcweir IMPLEMENT_FORWARD_XINTERFACE2(VCLXAccessibleList, VCLXAccessibleComponent, VCLXAccessibleList_BASE)
601cdf0e10cSrcweir IMPLEMENT_FORWARD_XTYPEPROVIDER2(VCLXAccessibleList, VCLXAccessibleComponent, VCLXAccessibleList_BASE)
602cdf0e10cSrcweir 
603cdf0e10cSrcweir //=====  XAccessible  =========================================================
604cdf0e10cSrcweir 
605cdf0e10cSrcweir Reference<XAccessibleContext> SAL_CALL
606cdf0e10cSrcweir     VCLXAccessibleList::getAccessibleContext (void)
607cdf0e10cSrcweir     throw (RuntimeException)
608cdf0e10cSrcweir {
609cdf0e10cSrcweir 	return this;
610cdf0e10cSrcweir }
611cdf0e10cSrcweir // -----------------------------------------------------------------------------
612cdf0e10cSrcweir 
613cdf0e10cSrcweir //=====  XAccessibleContext  ==================================================
614cdf0e10cSrcweir 
getAccessibleChildCount(void)615cdf0e10cSrcweir sal_Int32 SAL_CALL VCLXAccessibleList::getAccessibleChildCount (void)
616cdf0e10cSrcweir     throw (RuntimeException)
617cdf0e10cSrcweir {
618cdf0e10cSrcweir 	vos::OGuard aSolarGuard( Application::GetSolarMutex() );
619cdf0e10cSrcweir 	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
620cdf0e10cSrcweir 
621cdf0e10cSrcweir 	sal_Int32 nCount = 0;
622cdf0e10cSrcweir 	if ( m_pListBoxHelper )
623cdf0e10cSrcweir 		nCount = m_pListBoxHelper->GetEntryCount();
624cdf0e10cSrcweir 
625cdf0e10cSrcweir     return nCount;
626cdf0e10cSrcweir }
627cdf0e10cSrcweir // -----------------------------------------------------------------------------
628cdf0e10cSrcweir 
getAccessibleChild(sal_Int32 i)629cdf0e10cSrcweir Reference<XAccessible> SAL_CALL VCLXAccessibleList::getAccessibleChild (sal_Int32 i)
630cdf0e10cSrcweir     throw (IndexOutOfBoundsException, RuntimeException)
631cdf0e10cSrcweir {
632cdf0e10cSrcweir 	vos::OGuard aSolarGuard( Application::GetSolarMutex() );
633cdf0e10cSrcweir 	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
634cdf0e10cSrcweir 
635cdf0e10cSrcweir 	if ( i < 0 || i >= getAccessibleChildCount() )
636cdf0e10cSrcweir 		throw IndexOutOfBoundsException();
637cdf0e10cSrcweir 
638cdf0e10cSrcweir     Reference< XAccessible > xChild;
639cdf0e10cSrcweir     // search for the child
640b98ff797SHerbert Dürr 	if ( i >= static_cast<sal_Int32>(m_aAccessibleChildren.size()) )
641cdf0e10cSrcweir 		xChild = CreateChild (i);
642cdf0e10cSrcweir 	else
643cdf0e10cSrcweir 	{
644cdf0e10cSrcweir 		xChild = m_aAccessibleChildren[i];
645cdf0e10cSrcweir 		if ( !xChild.is() )
646cdf0e10cSrcweir 			xChild = CreateChild (i);
647cdf0e10cSrcweir 	}
648cdf0e10cSrcweir 	OSL_ENSURE( xChild.is(), "VCLXAccessibleList::getAccessibleChild: returning empty child!" );
649cdf0e10cSrcweir     return xChild;
650cdf0e10cSrcweir }
651cdf0e10cSrcweir // -----------------------------------------------------------------------------
652cdf0e10cSrcweir 
getAccessibleParent()653cdf0e10cSrcweir Reference< XAccessible > SAL_CALL VCLXAccessibleList::getAccessibleParent(  )
654cdf0e10cSrcweir 	throw (RuntimeException)
655cdf0e10cSrcweir {
656cdf0e10cSrcweir 	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
657cdf0e10cSrcweir 
658cdf0e10cSrcweir 	return m_xParent;
659cdf0e10cSrcweir }
660cdf0e10cSrcweir // -----------------------------------------------------------------------------
661cdf0e10cSrcweir 
getAccessibleIndexInParent(void)662cdf0e10cSrcweir sal_Int32 SAL_CALL VCLXAccessibleList::getAccessibleIndexInParent (void)
663cdf0e10cSrcweir     throw (::com::sun::star::uno::RuntimeException)
664cdf0e10cSrcweir {
665cdf0e10cSrcweir     if (m_nIndexInParent != DEFAULT_INDEX_IN_PARENT)
666cdf0e10cSrcweir         return m_nIndexInParent;
667cdf0e10cSrcweir     else
668cdf0e10cSrcweir         return VCLXAccessibleComponent::getAccessibleIndexInParent();
669cdf0e10cSrcweir }
670cdf0e10cSrcweir // -----------------------------------------------------------------------------
671cdf0e10cSrcweir 
getAccessibleRole(void)672cdf0e10cSrcweir sal_Int16 SAL_CALL VCLXAccessibleList::getAccessibleRole (void)
673cdf0e10cSrcweir     throw (RuntimeException)
674cdf0e10cSrcweir {
675cdf0e10cSrcweir     return AccessibleRole::LIST;
676cdf0e10cSrcweir }
677cdf0e10cSrcweir // -----------------------------------------------------------------------------
678cdf0e10cSrcweir 
679cdf0e10cSrcweir //=====  XAccessibleComponent  ================================================
680cdf0e10cSrcweir 
contains(const awt::Point & rPoint)681cdf0e10cSrcweir sal_Bool SAL_CALL VCLXAccessibleList::contains( const awt::Point& rPoint ) throw (RuntimeException)
682cdf0e10cSrcweir {
683cdf0e10cSrcweir 	vos::OGuard aSolarGuard( Application::GetSolarMutex() );
684cdf0e10cSrcweir 	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
685cdf0e10cSrcweir 
686cdf0e10cSrcweir 	sal_Bool bInside = sal_False;
687cdf0e10cSrcweir 
688cdf0e10cSrcweir     Window* pListBox = GetWindow();
689cdf0e10cSrcweir     if ( pListBox )
690cdf0e10cSrcweir 	{
691cdf0e10cSrcweir 		Rectangle aRect( Point(0,0), pListBox->GetSizePixel() );
692cdf0e10cSrcweir 		bInside = aRect.IsInside( VCLPoint( rPoint ) );
693cdf0e10cSrcweir 	}
694cdf0e10cSrcweir 
695cdf0e10cSrcweir 	return bInside;
696cdf0e10cSrcweir }
697cdf0e10cSrcweir // -----------------------------------------------------------------------------
698cdf0e10cSrcweir 
getAccessibleAt(const awt::Point & rPoint)699cdf0e10cSrcweir Reference< XAccessible > SAL_CALL VCLXAccessibleList::getAccessibleAt( const awt::Point& rPoint )
700cdf0e10cSrcweir     throw (RuntimeException)
701cdf0e10cSrcweir {
702cdf0e10cSrcweir 	vos::OGuard aSolarGuard( Application::GetSolarMutex() );
703cdf0e10cSrcweir 	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
704cdf0e10cSrcweir 
705cdf0e10cSrcweir 	Reference< XAccessible > xChild;
706cdf0e10cSrcweir 	if ( m_pListBoxHelper )
707cdf0e10cSrcweir 	{
708cdf0e10cSrcweir         UpdateVisibleLineCount();
709cdf0e10cSrcweir 		if ( contains( rPoint ) && m_nVisibleLineCount > 0 )
710cdf0e10cSrcweir 		{
711cdf0e10cSrcweir 			Point aPos = VCLPoint( rPoint );
712cdf0e10cSrcweir 			sal_uInt16 nEndPos = m_pListBoxHelper->GetTopEntry() + (sal_uInt16)m_nVisibleLineCount;
713cdf0e10cSrcweir 			for ( sal_uInt16 i = m_pListBoxHelper->GetTopEntry(); i < nEndPos; ++i )
714cdf0e10cSrcweir 			{
715cdf0e10cSrcweir 				if ( m_pListBoxHelper->GetBoundingRectangle(i).IsInside( aPos ) )
716cdf0e10cSrcweir 				{
717cdf0e10cSrcweir 					xChild = getAccessibleChild(i);
718cdf0e10cSrcweir 					break;
719cdf0e10cSrcweir 				}
720cdf0e10cSrcweir 			}
721cdf0e10cSrcweir 		}
722cdf0e10cSrcweir 	}
723cdf0e10cSrcweir 
724cdf0e10cSrcweir     return xChild;
725cdf0e10cSrcweir }
726cdf0e10cSrcweir // -----------------------------------------------------------------------------
727cdf0e10cSrcweir 
728cdf0e10cSrcweir //===== XServiceInfo ==========================================================
729cdf0e10cSrcweir 
getImplementationName(void)730cdf0e10cSrcweir ::rtl::OUString VCLXAccessibleList::getImplementationName (void)
731cdf0e10cSrcweir     throw (RuntimeException)
732cdf0e10cSrcweir {
733cdf0e10cSrcweir 	return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.toolkit.AccessibleList"));
734cdf0e10cSrcweir }
735cdf0e10cSrcweir // -----------------------------------------------------------------------------
736cdf0e10cSrcweir 
getSupportedServiceNames(void)737cdf0e10cSrcweir Sequence< ::rtl::OUString > VCLXAccessibleList::getSupportedServiceNames (void)
738cdf0e10cSrcweir     throw (RuntimeException)
739cdf0e10cSrcweir {
740cdf0e10cSrcweir 	Sequence< ::rtl::OUString > aNames = VCLXAccessibleComponent::getSupportedServiceNames();
741cdf0e10cSrcweir 	sal_Int32 nLength = aNames.getLength();
742cdf0e10cSrcweir 	aNames.realloc( nLength + 1 );
743cdf0e10cSrcweir 	aNames[nLength] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.accessibility.AccessibleList"));
744cdf0e10cSrcweir 	return aNames;
745cdf0e10cSrcweir }
746cdf0e10cSrcweir // -----------------------------------------------------------------------------
747cdf0e10cSrcweir 
UpdateVisibleLineCount()748cdf0e10cSrcweir void VCLXAccessibleList::UpdateVisibleLineCount()
749cdf0e10cSrcweir {
750cdf0e10cSrcweir 	if ( m_pListBoxHelper )
751cdf0e10cSrcweir 	{
752cdf0e10cSrcweir 		if ( (m_pListBoxHelper->GetStyle() & WB_DROPDOWN ) == WB_DROPDOWN )
753cdf0e10cSrcweir 			m_nVisibleLineCount = m_pListBoxHelper->GetDisplayLineCount();
754cdf0e10cSrcweir 		else
755cdf0e10cSrcweir 		{
756cdf0e10cSrcweir 			sal_uInt16 nCols = 0,
757cdf0e10cSrcweir 				nLines = 0;
758cdf0e10cSrcweir 			m_pListBoxHelper->GetMaxVisColumnsAndLines (nCols, nLines);
759cdf0e10cSrcweir 			m_nVisibleLineCount = nLines;
760cdf0e10cSrcweir 		}
761cdf0e10cSrcweir 	}
762cdf0e10cSrcweir }
763cdf0e10cSrcweir 
764cdf0e10cSrcweir // -----------------------------------------------------------------------------
UpdateEntryRange_Impl()765cdf0e10cSrcweir void VCLXAccessibleList::UpdateEntryRange_Impl()
766cdf0e10cSrcweir {
767cdf0e10cSrcweir 	vos::OGuard aSolarGuard( Application::GetSolarMutex() );
768cdf0e10cSrcweir 	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
769cdf0e10cSrcweir 
770cdf0e10cSrcweir 	sal_Int32 nTop = m_nLastTopEntry;
771cdf0e10cSrcweir 
772cdf0e10cSrcweir 	if ( m_pListBoxHelper )
773cdf0e10cSrcweir 		nTop = m_pListBoxHelper->GetTopEntry();
774cdf0e10cSrcweir 	if ( nTop != m_nLastTopEntry )
775cdf0e10cSrcweir 	{
776cdf0e10cSrcweir         UpdateVisibleLineCount();
777cdf0e10cSrcweir 		sal_Int32 nBegin = Min( m_nLastTopEntry, nTop );
778cdf0e10cSrcweir 		sal_Int32 nEnd = Max( m_nLastTopEntry + m_nVisibleLineCount, nTop + m_nVisibleLineCount );
779cdf0e10cSrcweir 		for (sal_uInt16 i = static_cast<sal_uInt16>(nBegin); (i <= static_cast<sal_uInt16>(nEnd)); ++i)
780cdf0e10cSrcweir 		{
781cdf0e10cSrcweir 			sal_Bool bVisible = ( i >= nTop && i < ( nTop + m_nVisibleLineCount ) );
782cdf0e10cSrcweir 			Reference< XAccessible > xHold;
783cdf0e10cSrcweir 			if ( i < m_aAccessibleChildren.size() )
784cdf0e10cSrcweir 				xHold = m_aAccessibleChildren[i];
785cdf0e10cSrcweir 			else if ( bVisible )
786cdf0e10cSrcweir 				xHold = CreateChild(i);
787cdf0e10cSrcweir 
788cdf0e10cSrcweir 			if ( xHold.is() )
789cdf0e10cSrcweir 				static_cast< VCLXAccessibleListItem* >( xHold.get() )->SetVisible( m_bVisible && bVisible );
790cdf0e10cSrcweir 		}
791cdf0e10cSrcweir 	}
792cdf0e10cSrcweir 
793cdf0e10cSrcweir 	m_nLastTopEntry = nTop;
794cdf0e10cSrcweir }
795cdf0e10cSrcweir // -----------------------------------------------------------------------------
checkEntrySelected(sal_uInt16 _nPos,Any & _rNewValue,Reference<XAccessible> & _rxNewAcc)796cdf0e10cSrcweir sal_Bool VCLXAccessibleList::checkEntrySelected(sal_uInt16 _nPos,Any& _rNewValue,Reference< XAccessible >& _rxNewAcc)
797cdf0e10cSrcweir {
798cdf0e10cSrcweir 	OSL_ENSURE(m_pListBoxHelper,"Helper is not valid!");
799cdf0e10cSrcweir 	sal_Bool bNowSelected = sal_False;
800cdf0e10cSrcweir 	if ( m_pListBoxHelper )
801cdf0e10cSrcweir 	{
802cdf0e10cSrcweir 		bNowSelected = m_pListBoxHelper->IsEntryPosSelected (_nPos);
803cdf0e10cSrcweir 		if ( bNowSelected )
804cdf0e10cSrcweir 		{
805cdf0e10cSrcweir 			_rxNewAcc = CreateChild(_nPos);
806cdf0e10cSrcweir 			_rNewValue <<= _rxNewAcc;
807cdf0e10cSrcweir 		}
808cdf0e10cSrcweir 	}
809cdf0e10cSrcweir 	return bNowSelected;
810cdf0e10cSrcweir }
811cdf0e10cSrcweir // -----------------------------------------------------------------------------
812cdf0e10cSrcweir 
UpdateSelection_Impl(sal_uInt16)813cdf0e10cSrcweir void VCLXAccessibleList::UpdateSelection_Impl(sal_uInt16)
814cdf0e10cSrcweir {
815cdf0e10cSrcweir 	uno::Any aOldValue, aNewValue;
816cdf0e10cSrcweir 
817cdf0e10cSrcweir 	{
818cdf0e10cSrcweir 		vos::OGuard aSolarGuard( Application::GetSolarMutex() );
819cdf0e10cSrcweir 		::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
820cdf0e10cSrcweir 	    Reference< XAccessible > xNewAcc;
821cdf0e10cSrcweir 
822cdf0e10cSrcweir 		if ( m_pListBoxHelper )
823cdf0e10cSrcweir 		{
824cdf0e10cSrcweir 			sal_uInt16 i=0;
82521075d77SSteve Yin 			m_nCurSelectedPos = LISTBOX_ENTRY_NOTFOUND;
826cdf0e10cSrcweir 			for ( ListItems::iterator aIter = m_aAccessibleChildren.begin();
827cdf0e10cSrcweir 				  aIter != m_aAccessibleChildren.end(); ++aIter,++i)
828cdf0e10cSrcweir 			{
829cdf0e10cSrcweir 				Reference< XAccessible > xHold = *aIter;
830cdf0e10cSrcweir 				if ( xHold.is() )
831cdf0e10cSrcweir 				{
832cdf0e10cSrcweir 					VCLXAccessibleListItem* pItem = static_cast< VCLXAccessibleListItem* >( xHold.get() );
833cdf0e10cSrcweir 					// Retrieve the item's index from the list entry.
834cdf0e10cSrcweir 					sal_Bool bNowSelected = m_pListBoxHelper->IsEntryPosSelected (i);
83521075d77SSteve Yin 					if (bNowSelected)
83621075d77SSteve Yin 						m_nCurSelectedPos = i;
837cdf0e10cSrcweir 
838cdf0e10cSrcweir 					if ( bNowSelected && !pItem->IsSelected() )
839cdf0e10cSrcweir 					{
840cdf0e10cSrcweir 						xNewAcc = *aIter;
841cdf0e10cSrcweir 						aNewValue <<= xNewAcc;
842cdf0e10cSrcweir 					}
843cdf0e10cSrcweir 					else if ( pItem->IsSelected() )
844cdf0e10cSrcweir 						m_nLastSelectedPos = i;
845cdf0e10cSrcweir 
846cdf0e10cSrcweir 					pItem->SetSelected( bNowSelected );
847cdf0e10cSrcweir 				}
848cdf0e10cSrcweir 				else
849cdf0e10cSrcweir 				{ // it could happen that a child was not created before
850cdf0e10cSrcweir 					checkEntrySelected(i,aNewValue,xNewAcc);
851cdf0e10cSrcweir 				}
852cdf0e10cSrcweir 			}
853cdf0e10cSrcweir 			sal_uInt16 nCount = m_pListBoxHelper->GetEntryCount();
854cdf0e10cSrcweir 			if ( i < nCount ) // here we have to check the if any other listbox entry is selected
855cdf0e10cSrcweir 			{
856cdf0e10cSrcweir 				for (; i < nCount && !checkEntrySelected(i,aNewValue,xNewAcc) ;++i )
857cdf0e10cSrcweir 					;
858cdf0e10cSrcweir 			}
859cdf0e10cSrcweir 			if ( xNewAcc.is() && GetWindow()->HasFocus() )
860cdf0e10cSrcweir 			{
861cdf0e10cSrcweir 				if ( m_nLastSelectedPos != LISTBOX_ENTRY_NOTFOUND )
862cdf0e10cSrcweir 					aOldValue <<= getAccessibleChild( (sal_Int32)m_nLastSelectedPos );
863cdf0e10cSrcweir 				aNewValue <<= xNewAcc;
864cdf0e10cSrcweir 			}
865cdf0e10cSrcweir 		}
866cdf0e10cSrcweir 	}
86721075d77SSteve Yin 	if (!m_pListBoxHelper->IsInDropDown())
86821075d77SSteve Yin 	{
86921075d77SSteve Yin 	}
87021075d77SSteve Yin 	else
87121075d77SSteve Yin 	{
872cdf0e10cSrcweir 		if ( aNewValue.hasValue() || aOldValue.hasValue() )
873cdf0e10cSrcweir 			NotifyAccessibleEvent(
874cdf0e10cSrcweir 				AccessibleEventId::ACTIVE_DESCENDANT_CHANGED,
875cdf0e10cSrcweir 				aOldValue,
876cdf0e10cSrcweir 				aNewValue );
87721075d77SSteve Yin 		//the SELECTION_CHANGED is not necessary
87821075d77SSteve Yin 		//NotifyAccessibleEvent( AccessibleEventId::SELECTION_CHANGED, Any(), Any() );
87921075d77SSteve Yin 	}
880cdf0e10cSrcweir }
881cdf0e10cSrcweir 
882cdf0e10cSrcweir // -----------------------------------------------------------------------------
883cdf0e10cSrcweir // XAccessibleSelection
884cdf0e10cSrcweir // -----------------------------------------------------------------------------
selectAccessibleChild(sal_Int32 nChildIndex)885cdf0e10cSrcweir void SAL_CALL VCLXAccessibleList::selectAccessibleChild( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
886cdf0e10cSrcweir {
887cdf0e10cSrcweir 	sal_Bool bNotify = sal_False;
888cdf0e10cSrcweir 
889cdf0e10cSrcweir 	{
890cdf0e10cSrcweir 		vos::OGuard aSolarGuard( Application::GetSolarMutex() );
891cdf0e10cSrcweir 		::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
892cdf0e10cSrcweir 
893cdf0e10cSrcweir 		if ( m_pListBoxHelper )
894cdf0e10cSrcweir 		{
895cdf0e10cSrcweir 			checkSelection_Impl(nChildIndex,*m_pListBoxHelper,sal_False);
896cdf0e10cSrcweir 
897cdf0e10cSrcweir 			m_pListBoxHelper->SelectEntryPos( (sal_uInt16)nChildIndex, sal_True );
898cdf0e10cSrcweir 			// call the select handler, don't handle events in this time
899cdf0e10cSrcweir 			m_bDisableProcessEvent = true;
900cdf0e10cSrcweir 			m_pListBoxHelper->Select();
901cdf0e10cSrcweir 			m_bDisableProcessEvent = false;
902cdf0e10cSrcweir 			bNotify = sal_True;
903cdf0e10cSrcweir 		}
904cdf0e10cSrcweir 	}
905cdf0e10cSrcweir 
906cdf0e10cSrcweir 	if ( bNotify )
907cdf0e10cSrcweir         UpdateSelection_Impl();
908cdf0e10cSrcweir }
909cdf0e10cSrcweir // -----------------------------------------------------------------------------
isAccessibleChildSelected(sal_Int32 nChildIndex)910cdf0e10cSrcweir sal_Bool SAL_CALL VCLXAccessibleList::isAccessibleChildSelected( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
911cdf0e10cSrcweir {
912cdf0e10cSrcweir 	vos::OGuard aSolarGuard( Application::GetSolarMutex() );
913cdf0e10cSrcweir 	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
914cdf0e10cSrcweir 
915cdf0e10cSrcweir     sal_Bool bRet = sal_False;
916cdf0e10cSrcweir 	if ( m_pListBoxHelper )
917cdf0e10cSrcweir 	{
918cdf0e10cSrcweir 		checkSelection_Impl(nChildIndex,*m_pListBoxHelper,sal_False);
919cdf0e10cSrcweir 
920cdf0e10cSrcweir     	bRet = m_pListBoxHelper->IsEntryPosSelected( (sal_uInt16)nChildIndex );
921cdf0e10cSrcweir 	}
922cdf0e10cSrcweir     return bRet;
923cdf0e10cSrcweir }
924cdf0e10cSrcweir // -----------------------------------------------------------------------------
clearAccessibleSelection()925cdf0e10cSrcweir void SAL_CALL VCLXAccessibleList::clearAccessibleSelection(  ) throw (RuntimeException)
926cdf0e10cSrcweir {
927cdf0e10cSrcweir 	sal_Bool bNotify = sal_False;
928cdf0e10cSrcweir 
929cdf0e10cSrcweir 	{
930cdf0e10cSrcweir 		vos::OGuard aSolarGuard( Application::GetSolarMutex() );
931cdf0e10cSrcweir 		::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
932cdf0e10cSrcweir 
933cdf0e10cSrcweir 		if ( m_pListBoxHelper )
934cdf0e10cSrcweir 		{
935cdf0e10cSrcweir 	    	m_pListBoxHelper->SetNoSelection();
936cdf0e10cSrcweir 			bNotify = sal_True;
937cdf0e10cSrcweir 		}
938cdf0e10cSrcweir 	}
939cdf0e10cSrcweir 
940cdf0e10cSrcweir 	if ( bNotify )
941cdf0e10cSrcweir         UpdateSelection_Impl();
942cdf0e10cSrcweir }
943cdf0e10cSrcweir // -----------------------------------------------------------------------------
selectAllAccessibleChildren()944cdf0e10cSrcweir void SAL_CALL VCLXAccessibleList::selectAllAccessibleChildren(  ) throw (RuntimeException)
945cdf0e10cSrcweir {
946cdf0e10cSrcweir 	sal_Bool bNotify = sal_False;
947cdf0e10cSrcweir 
948cdf0e10cSrcweir 	{
949cdf0e10cSrcweir 		vos::OGuard aSolarGuard( Application::GetSolarMutex() );
950cdf0e10cSrcweir 		::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
951cdf0e10cSrcweir 
952cdf0e10cSrcweir 		if ( m_pListBoxHelper )
953cdf0e10cSrcweir 		{
954cdf0e10cSrcweir 	    	sal_uInt16 nCount = m_pListBoxHelper->GetEntryCount();
955cdf0e10cSrcweir 	    	for ( sal_uInt16 i = 0; i < nCount; ++i )
956cdf0e10cSrcweir 	    		m_pListBoxHelper->SelectEntryPos( i, sal_True );
957cdf0e10cSrcweir 			// call the select handler, don't handle events in this time
958cdf0e10cSrcweir 			m_bDisableProcessEvent = true;
959cdf0e10cSrcweir 			m_pListBoxHelper->Select();
960cdf0e10cSrcweir 			m_bDisableProcessEvent = false;
961cdf0e10cSrcweir 			bNotify = sal_True;
962cdf0e10cSrcweir 		}
963cdf0e10cSrcweir 	}
964cdf0e10cSrcweir 
965cdf0e10cSrcweir 	if ( bNotify )
966cdf0e10cSrcweir         UpdateSelection_Impl();
967cdf0e10cSrcweir }
968cdf0e10cSrcweir // -----------------------------------------------------------------------------
getSelectedAccessibleChildCount()969cdf0e10cSrcweir sal_Int32 SAL_CALL VCLXAccessibleList::getSelectedAccessibleChildCount(  ) throw (RuntimeException)
970cdf0e10cSrcweir {
971cdf0e10cSrcweir 	vos::OGuard aSolarGuard( Application::GetSolarMutex() );
972cdf0e10cSrcweir 	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
973cdf0e10cSrcweir 
974cdf0e10cSrcweir     sal_Int32 nCount = 0;
975cdf0e10cSrcweir 	if ( m_pListBoxHelper )
976cdf0e10cSrcweir    		nCount = m_pListBoxHelper->GetSelectEntryCount();
977cdf0e10cSrcweir     return nCount;
978cdf0e10cSrcweir }
979cdf0e10cSrcweir // -----------------------------------------------------------------------------
getSelectedAccessibleChild(sal_Int32 nSelectedChildIndex)980cdf0e10cSrcweir Reference< XAccessible > SAL_CALL VCLXAccessibleList::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
981cdf0e10cSrcweir {
982cdf0e10cSrcweir 	vos::OGuard aSolarGuard( Application::GetSolarMutex() );
983cdf0e10cSrcweir 	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
984cdf0e10cSrcweir 
985cdf0e10cSrcweir 	if ( m_pListBoxHelper )
986cdf0e10cSrcweir 	{
987cdf0e10cSrcweir 		checkSelection_Impl(nSelectedChildIndex,*m_pListBoxHelper,sal_True);
988cdf0e10cSrcweir 		return getAccessibleChild( (sal_Int32)m_pListBoxHelper->GetSelectEntryPos( (sal_uInt16)nSelectedChildIndex ) );
989cdf0e10cSrcweir 	}
990cdf0e10cSrcweir 
991cdf0e10cSrcweir 	return NULL;
992cdf0e10cSrcweir }
993cdf0e10cSrcweir // -----------------------------------------------------------------------------
deselectAccessibleChild(sal_Int32 nSelectedChildIndex)994cdf0e10cSrcweir void SAL_CALL VCLXAccessibleList::deselectAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
995cdf0e10cSrcweir {
996cdf0e10cSrcweir 	sal_Bool bNotify = sal_False;
997cdf0e10cSrcweir 
998cdf0e10cSrcweir 	{
999cdf0e10cSrcweir 		vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1000cdf0e10cSrcweir 		::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
1001cdf0e10cSrcweir 
1002cdf0e10cSrcweir 		if ( m_pListBoxHelper )
1003cdf0e10cSrcweir 		{
1004cdf0e10cSrcweir 			checkSelection_Impl(nSelectedChildIndex,*m_pListBoxHelper,sal_False);
1005cdf0e10cSrcweir 
1006cdf0e10cSrcweir 			m_pListBoxHelper->SelectEntryPos( (sal_uInt16)nSelectedChildIndex, sal_False );
1007cdf0e10cSrcweir 			// call the select handler, don't handle events in this time
1008cdf0e10cSrcweir 			m_bDisableProcessEvent = true;
1009cdf0e10cSrcweir 			m_pListBoxHelper->Select();
1010cdf0e10cSrcweir 			m_bDisableProcessEvent = false;
1011cdf0e10cSrcweir 			bNotify = sal_True;
1012cdf0e10cSrcweir 		}
1013cdf0e10cSrcweir 	}
1014cdf0e10cSrcweir 
1015cdf0e10cSrcweir 	if ( bNotify )
1016cdf0e10cSrcweir         UpdateSelection_Impl();
1017cdf0e10cSrcweir }
1018cdf0e10cSrcweir // -----------------------------------------------------------------------------
1019cdf0e10cSrcweir // accessibility::XAccessibleComponent
implGetBounds()1020cdf0e10cSrcweir awt::Rectangle VCLXAccessibleList::implGetBounds() throw (uno::RuntimeException)
1021cdf0e10cSrcweir {
1022cdf0e10cSrcweir 	awt::Rectangle aBounds ( 0, 0, 0, 0 );
1023cdf0e10cSrcweir 	if ( m_pListBoxHelper
1024cdf0e10cSrcweir 		&& (m_pListBoxHelper->GetStyle() & WB_DROPDOWN ) == WB_DROPDOWN )
1025cdf0e10cSrcweir 	{
1026cdf0e10cSrcweir 		if ( m_pListBoxHelper->IsInDropDown() )
1027cdf0e10cSrcweir 			aBounds = AWTRectangle(m_pListBoxHelper->GetDropDownPosSizePixel());
1028cdf0e10cSrcweir 	}
1029cdf0e10cSrcweir 	else
1030cdf0e10cSrcweir 	{
1031cdf0e10cSrcweir 		// a list has the same bounds as his parent but starts at (0,0)
1032cdf0e10cSrcweir 		aBounds = VCLXAccessibleComponent::implGetBounds();
1033cdf0e10cSrcweir 		aBounds.X = 0;
1034cdf0e10cSrcweir 		aBounds.Y = 0;
1035cdf0e10cSrcweir 		if ( m_aBoxType == COMBOBOX )
1036cdf0e10cSrcweir 		{
1037cdf0e10cSrcweir 			ComboBox* pBox = static_cast<ComboBox*>(GetWindow());
1038cdf0e10cSrcweir 			if ( pBox )
1039cdf0e10cSrcweir 			{
1040cdf0e10cSrcweir 				Size aSize = pBox->GetSubEdit()->GetSizePixel();
104121075d77SSteve Yin 				aBounds.Y += aSize.Height();
1042cdf0e10cSrcweir 				aBounds.Height -= aSize.Height();
1043cdf0e10cSrcweir 			}
1044cdf0e10cSrcweir 		}
1045cdf0e10cSrcweir 	}
1046cdf0e10cSrcweir 	return aBounds;
1047cdf0e10cSrcweir }
1048cdf0e10cSrcweir // -----------------------------------------------------------------------------
1049cdf0e10cSrcweir 
getLocationOnScreen()1050cdf0e10cSrcweir awt::Point VCLXAccessibleList::getLocationOnScreen(  ) throw (uno::RuntimeException)
1051cdf0e10cSrcweir {
1052cdf0e10cSrcweir 	vos::OGuard aSolarGuard( Application::GetSolarMutex() );
1053cdf0e10cSrcweir 	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
1054cdf0e10cSrcweir 
1055cdf0e10cSrcweir 	awt::Point aPos;
1056cdf0e10cSrcweir 	if ( m_pListBoxHelper
1057cdf0e10cSrcweir 		&& (m_pListBoxHelper->GetStyle() & WB_DROPDOWN ) == WB_DROPDOWN )
1058cdf0e10cSrcweir 	{
1059cdf0e10cSrcweir 		if ( m_pListBoxHelper->IsInDropDown() )
1060cdf0e10cSrcweir 			aPos = AWTPoint(m_pListBoxHelper->GetDropDownPosSizePixel().TopLeft());
1061cdf0e10cSrcweir 	}
1062cdf0e10cSrcweir 	else
1063cdf0e10cSrcweir 	{
1064cdf0e10cSrcweir 		aPos = VCLXAccessibleComponent::getLocationOnScreen();
1065cdf0e10cSrcweir 		if ( m_aBoxType == COMBOBOX )
1066cdf0e10cSrcweir 		{
1067cdf0e10cSrcweir 			ComboBox* pBox = static_cast<ComboBox*>(GetWindow());
1068cdf0e10cSrcweir 			if ( pBox )
1069cdf0e10cSrcweir 			{
107021075d77SSteve Yin 				aPos.Y += pBox->GetSubEdit()->GetSizePixel().Height();
1071cdf0e10cSrcweir 			}
1072cdf0e10cSrcweir 		}
1073cdf0e10cSrcweir 	}
1074cdf0e10cSrcweir 	return aPos;
1075cdf0e10cSrcweir }
1076cdf0e10cSrcweir // -----------------------------------------------------------------------------
IsInDropDown()107721075d77SSteve Yin sal_Bool	VCLXAccessibleList::IsInDropDown()
107821075d77SSteve Yin {
107921075d77SSteve Yin 	return m_pListBoxHelper->IsInDropDown();
108021075d77SSteve Yin }
108121075d77SSteve Yin // -----------------------------------------------------------------------------
HandleDropOpen()108221075d77SSteve Yin void VCLXAccessibleList::HandleDropOpen()
108321075d77SSteve Yin {
108421075d77SSteve Yin 	if ( !m_bDisableProcessEvent )
108521075d77SSteve Yin 		UpdateSelection_Impl();
108621075d77SSteve Yin 	if (m_nCurSelectedPos != LISTBOX_ENTRY_NOTFOUND &&
108721075d77SSteve Yin 		m_nLastSelectedPos != LISTBOX_ENTRY_NOTFOUND)
108821075d77SSteve Yin 	{
108921075d77SSteve Yin 		Reference< XAccessible > xChild = getAccessibleChild(m_nCurSelectedPos);
109021075d77SSteve Yin 		if(xChild.is())
109121075d77SSteve Yin 		{
109221075d77SSteve Yin 			uno::Any aNewValue;
109321075d77SSteve Yin 			aNewValue <<= xChild;
109421075d77SSteve Yin 			NotifyAccessibleEvent(AccessibleEventId::ACTIVE_DESCENDANT_CHANGED,	uno::Any(), aNewValue );
109521075d77SSteve Yin 		}
109621075d77SSteve Yin 	}
109721075d77SSteve Yin }
1098