10841af79SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
30841af79SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
40841af79SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
50841af79SAndrew Rist  * distributed with this work for additional information
60841af79SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
70841af79SAndrew Rist  * to you under the Apache License, Version 2.0 (the
80841af79SAndrew Rist  * "License"); you may not use this file except in compliance
90841af79SAndrew Rist  * with the License.  You may obtain a copy of the License at
100841af79SAndrew Rist  *
110841af79SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
120841af79SAndrew Rist  *
130841af79SAndrew Rist  * Unless required by applicable law or agreed to in writing,
140841af79SAndrew Rist  * software distributed under the License is distributed on an
150841af79SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
160841af79SAndrew Rist  * KIND, either express or implied.  See the License for the
170841af79SAndrew Rist  * specific language governing permissions and limitations
180841af79SAndrew Rist  * under the License.
190841af79SAndrew Rist  *
200841af79SAndrew Rist  *************************************************************/
210841af79SAndrew Rist 
220841af79SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_accessibility.hxx"
26cdf0e10cSrcweir #include <accessibility/standard/vclxaccessiblebox.hxx>
27cdf0e10cSrcweir #include <accessibility/standard/vclxaccessibletextfield.hxx>
28cdf0e10cSrcweir #include <accessibility/standard/vclxaccessibleedit.hxx>
29cdf0e10cSrcweir #include <accessibility/standard/vclxaccessiblelist.hxx>
30cdf0e10cSrcweir #include <accessibility/helper/listboxhelper.hxx>
31cdf0e10cSrcweir 
32cdf0e10cSrcweir #include <unotools/accessiblestatesethelper.hxx>
33cdf0e10cSrcweir #include <com/sun/star/accessibility/AccessibleStateType.hpp>
34cdf0e10cSrcweir #include <com/sun/star/accessibility/AccessibleEventId.hpp>
35cdf0e10cSrcweir #include <com/sun/star/accessibility/AccessibleRole.hpp>
36cdf0e10cSrcweir #include <vcl/svapp.hxx>
37cdf0e10cSrcweir #include <vcl/combobox.hxx>
38cdf0e10cSrcweir #include <vcl/lstbox.hxx>
39cdf0e10cSrcweir #include <accessibility/helper/accresmgr.hxx>
40cdf0e10cSrcweir #include <accessibility/helper/accessiblestrings.hrc>
41cdf0e10cSrcweir 
42cdf0e10cSrcweir using namespace ::com::sun::star;
43cdf0e10cSrcweir using namespace ::com::sun::star::uno;
44cdf0e10cSrcweir using namespace ::com::sun::star::lang;
45cdf0e10cSrcweir using namespace ::com::sun::star::beans;
46cdf0e10cSrcweir using namespace ::com::sun::star::accessibility;
47cdf0e10cSrcweir 
VCLXAccessibleBox(VCLXWindow * pVCLWindow,BoxType aType,bool bIsDropDownBox)48cdf0e10cSrcweir VCLXAccessibleBox::VCLXAccessibleBox (VCLXWindow* pVCLWindow, BoxType aType, bool bIsDropDownBox)
49cdf0e10cSrcweir     : VCLXAccessibleComponent (pVCLWindow),
50cdf0e10cSrcweir       m_aBoxType (aType),
51cdf0e10cSrcweir       m_bIsDropDownBox (bIsDropDownBox),
52cdf0e10cSrcweir       m_nIndexInParent (DEFAULT_INDEX_IN_PARENT)
53cdf0e10cSrcweir {
54cdf0e10cSrcweir     // Set up the flags that indicate which children this object has.
55cdf0e10cSrcweir     m_bHasListChild = true;
56cdf0e10cSrcweir 
57cdf0e10cSrcweir     // A text field is not present for non drop down list boxes.
58cdf0e10cSrcweir     if ((m_aBoxType==LISTBOX) && ! m_bIsDropDownBox)
59cdf0e10cSrcweir         m_bHasTextChild = false;
60cdf0e10cSrcweir     else
61cdf0e10cSrcweir         m_bHasTextChild = true;
62cdf0e10cSrcweir }
63cdf0e10cSrcweir 
~VCLXAccessibleBox(void)64cdf0e10cSrcweir VCLXAccessibleBox::~VCLXAccessibleBox (void)
65cdf0e10cSrcweir {
66cdf0e10cSrcweir }
67cdf0e10cSrcweir 
ProcessWindowChildEvent(const VclWindowEvent & rVclWindowEvent)68cdf0e10cSrcweir void VCLXAccessibleBox::ProcessWindowChildEvent( const VclWindowEvent& rVclWindowEvent )
69cdf0e10cSrcweir {
70cdf0e10cSrcweir    	uno::Any aOldValue, aNewValue;
71cdf0e10cSrcweir     uno::Reference<XAccessible> xAcc;
72cdf0e10cSrcweir 
73cdf0e10cSrcweir 	switch ( rVclWindowEvent.GetId() )
74cdf0e10cSrcweir 	{
75cdf0e10cSrcweir         case VCLEVENT_WINDOW_SHOW:
76cdf0e10cSrcweir         case VCLEVENT_WINDOW_HIDE:
77cdf0e10cSrcweir         {
78cdf0e10cSrcweir             Window* pChildWindow = (Window *) rVclWindowEvent.GetData();
79cdf0e10cSrcweir             // Just compare to the combo box text field.  All other children
80cdf0e10cSrcweir             // are identical to this object in which case this object will
81cdf0e10cSrcweir             // be removed in a short time.
82cdf0e10cSrcweir             if (m_aBoxType==COMBOBOX)
83cdf0e10cSrcweir             {
84cdf0e10cSrcweir                 ComboBox* pComboBox = static_cast<ComboBox*>(GetWindow());
85cdf0e10cSrcweir                 if ( ( pComboBox != NULL ) && ( pChildWindow != NULL ) )
86cdf0e10cSrcweir                     if (pChildWindow == pComboBox->GetSubEdit())
87cdf0e10cSrcweir                     {
88cdf0e10cSrcweir                         if (rVclWindowEvent.GetId() == VCLEVENT_WINDOW_SHOW)
89cdf0e10cSrcweir                         {
90cdf0e10cSrcweir                             // Instantiate text field.
91cdf0e10cSrcweir                             getAccessibleChild (0);
92cdf0e10cSrcweir                             aNewValue <<= m_xText;
93cdf0e10cSrcweir                         }
94cdf0e10cSrcweir                         else
95cdf0e10cSrcweir                         {
96cdf0e10cSrcweir                             // Release text field.
97cdf0e10cSrcweir                             aOldValue <<= m_xText;
98cdf0e10cSrcweir                             m_xText = NULL;
99cdf0e10cSrcweir                         }
100cdf0e10cSrcweir                         // Tell the listeners about the new/removed child.
101cdf0e10cSrcweir                         NotifyAccessibleEvent (
102cdf0e10cSrcweir                             AccessibleEventId::CHILD,
103cdf0e10cSrcweir                             aOldValue, aNewValue);
104cdf0e10cSrcweir                     }
105cdf0e10cSrcweir 
106cdf0e10cSrcweir             }
107cdf0e10cSrcweir         }
108cdf0e10cSrcweir         break;
109cdf0e10cSrcweir 
110cdf0e10cSrcweir         default:
111cdf0e10cSrcweir             VCLXAccessibleComponent::ProcessWindowChildEvent (rVclWindowEvent);
112cdf0e10cSrcweir 	}
113cdf0e10cSrcweir }
114cdf0e10cSrcweir 
ProcessWindowEvent(const VclWindowEvent & rVclWindowEvent)115cdf0e10cSrcweir void VCLXAccessibleBox::ProcessWindowEvent (const VclWindowEvent& rVclWindowEvent)
116cdf0e10cSrcweir {
117cdf0e10cSrcweir 	switch ( rVclWindowEvent.GetId() )
118cdf0e10cSrcweir 	{
1196485ffd2SSteve Yin 		case VCLEVENT_DROPDOWN_SELECT:
12021075d77SSteve Yin 		case VCLEVENT_LISTBOX_SELECT:
12121075d77SSteve Yin 		case VCLEVENT_LISTBOX_FOCUSITEMCHANGED:
12221075d77SSteve Yin 
12321075d77SSteve Yin 		{
12421075d77SSteve Yin 	            // Forward the call to the list child.
12521075d77SSteve Yin 	            VCLXAccessibleList* pList = static_cast<VCLXAccessibleList*>(m_xList.get());
12621075d77SSteve Yin 	            if ( pList == NULL )
12721075d77SSteve Yin 			{
12821075d77SSteve Yin 				getAccessibleChild ( m_bHasTextChild ? 1 : 0 );
12921075d77SSteve Yin 				pList = static_cast<VCLXAccessibleList*>(m_xList.get());
13021075d77SSteve Yin 			}
13121075d77SSteve Yin 			if ( pList != NULL )
13221075d77SSteve Yin 			{
13321075d77SSteve Yin 				pList->ProcessWindowEvent (rVclWindowEvent, m_bIsDropDownBox);
13421075d77SSteve Yin 				if(m_bIsDropDownBox)
13521075d77SSteve Yin 				{
13621075d77SSteve Yin 					NotifyAccessibleEvent(AccessibleEventId::VALUE_CHANGED, Any(), Any());
13721075d77SSteve Yin 					Any aOldValue;
13821075d77SSteve Yin 					Any aNewValue;
13921075d77SSteve Yin 					aOldValue <<= AccessibleStateType::INDETERMINATE;
14021075d77SSteve Yin 					NotifyAccessibleEvent(AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue);
14121075d77SSteve Yin 
14221075d77SSteve Yin 				}
14321075d77SSteve Yin 			}
14421075d77SSteve Yin 			break;
14521075d77SSteve Yin 		}
146cdf0e10cSrcweir 		case VCLEVENT_DROPDOWN_OPEN:
14721075d77SSteve Yin 		{
14821075d77SSteve Yin 	             VCLXAccessibleList* pList = static_cast<VCLXAccessibleList*>(m_xList.get());
14921075d77SSteve Yin 	             if ( pList == NULL )
15021075d77SSteve Yin 			{
15121075d77SSteve Yin 				getAccessibleChild ( m_bHasTextChild ? 1 : 0 );
15221075d77SSteve Yin 				pList = static_cast<VCLXAccessibleList*>(m_xList.get());
15321075d77SSteve Yin 			}
15421075d77SSteve Yin 			if ( pList != NULL )
15521075d77SSteve Yin 			{
15621075d77SSteve Yin 				pList->ProcessWindowEvent (rVclWindowEvent);
15721075d77SSteve Yin 				pList->HandleDropOpen();
15821075d77SSteve Yin 			}
15921075d77SSteve Yin 			break;
16021075d77SSteve Yin 		}
161cdf0e10cSrcweir 		case VCLEVENT_DROPDOWN_CLOSE:
16221075d77SSteve Yin 		{
16321075d77SSteve Yin 	             VCLXAccessibleList* pList = static_cast<VCLXAccessibleList*>(m_xList.get());
16421075d77SSteve Yin 	             if ( pList == NULL )
16521075d77SSteve Yin 			{
16621075d77SSteve Yin 				getAccessibleChild ( m_bHasTextChild ? 1 : 0 );
16721075d77SSteve Yin 				pList = static_cast<VCLXAccessibleList*>(m_xList.get());
16821075d77SSteve Yin 			}
16921075d77SSteve Yin 			if ( pList != NULL )
17021075d77SSteve Yin 			{
17121075d77SSteve Yin 				pList->ProcessWindowEvent (rVclWindowEvent);
17221075d77SSteve Yin 			}
17321075d77SSteve Yin 			Window* pWindow = GetWindow();
17421075d77SSteve Yin 			if( pWindow && (pWindow->HasFocus() || pWindow->HasChildPathFocus()) )
17521075d77SSteve Yin 			{
17621075d77SSteve Yin 				Any aOldValue, aNewValue;
17721075d77SSteve Yin 				aNewValue <<= AccessibleStateType::FOCUSED;
17821075d77SSteve Yin 				NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue );
17921075d77SSteve Yin 			}
18021075d77SSteve Yin 			break;
18121075d77SSteve Yin 		}
18221075d77SSteve Yin 		case VCLEVENT_COMBOBOX_SELECT:
18321075d77SSteve Yin 		{
18421075d77SSteve Yin 	             VCLXAccessibleList* pList = static_cast<VCLXAccessibleList*>(m_xList.get());
185*9c07f23fSJuergen Schmidt 	             if (pList != NULL && m_xText.is())
18621075d77SSteve Yin 	             {
18721075d77SSteve Yin 		                Reference<XAccessibleText> xText (m_xText->getAccessibleContext(), UNO_QUERY);
18821075d77SSteve Yin 		                if ( xText.is() )
18921075d77SSteve Yin 				{
19021075d77SSteve Yin 					::rtl::OUString sText = xText->getSelectedText();
191144e4e62SHerbert Dürr 					if ( sText.isEmpty() )
19221075d77SSteve Yin 						sText = xText->getText();
19321075d77SSteve Yin 		                    pList->UpdateSelection_Acc (sText, m_bIsDropDownBox);
19421075d77SSteve Yin 					//if(m_bIsDropDownBox && !pList->IsInDropDown())
19521075d77SSteve Yin 					if (m_bIsDropDownBox || ( !m_bIsDropDownBox && m_aBoxType==COMBOBOX))
19621075d77SSteve Yin 						NotifyAccessibleEvent(AccessibleEventId::VALUE_CHANGED, Any(), Any());
19721075d77SSteve Yin 
19821075d77SSteve Yin 						Any aOldValue;
19921075d77SSteve Yin 						Any aNewValue;
20021075d77SSteve Yin 						aOldValue <<= AccessibleStateType::INDETERMINATE;
20121075d77SSteve Yin 						NotifyAccessibleEvent(AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue);
20221075d77SSteve Yin 
20321075d77SSteve Yin 				}
20421075d77SSteve Yin 	            	}
20521075d77SSteve Yin 			break;
20621075d77SSteve Yin 		}
20721075d77SSteve Yin 		//case VCLEVENT_DROPDOWN_OPEN:
20821075d77SSteve Yin 		//case VCLEVENT_DROPDOWN_CLOSE:
209cdf0e10cSrcweir 		case VCLEVENT_LISTBOX_DOUBLECLICK:
210cdf0e10cSrcweir 		case VCLEVENT_LISTBOX_SCROLLED:
21121075d77SSteve Yin 		//case VCLEVENT_LISTBOX_SELECT:
212cdf0e10cSrcweir         case VCLEVENT_LISTBOX_ITEMADDED:
213cdf0e10cSrcweir         case VCLEVENT_LISTBOX_ITEMREMOVED:
214cdf0e10cSrcweir         case VCLEVENT_COMBOBOX_ITEMADDED:
215cdf0e10cSrcweir         case VCLEVENT_COMBOBOX_ITEMREMOVED:
216cdf0e10cSrcweir 		case VCLEVENT_COMBOBOX_SCROLLED:
217cdf0e10cSrcweir         {
218cdf0e10cSrcweir             // Forward the call to the list child.
219cdf0e10cSrcweir             VCLXAccessibleList* pList = static_cast<VCLXAccessibleList*>(m_xList.get());
220cdf0e10cSrcweir             if ( pList == NULL )
221cdf0e10cSrcweir 			{
222cdf0e10cSrcweir 				getAccessibleChild ( m_bHasTextChild ? 1 : 0 );
223cdf0e10cSrcweir 				pList = static_cast<VCLXAccessibleList*>(m_xList.get());
224cdf0e10cSrcweir 			}
225cdf0e10cSrcweir 			if ( pList != NULL )
226cdf0e10cSrcweir 				pList->ProcessWindowEvent (rVclWindowEvent);
227cdf0e10cSrcweir             break;
228cdf0e10cSrcweir         }
229cdf0e10cSrcweir 
23021075d77SSteve Yin 		//case VCLEVENT_COMBOBOX_SELECT:
231cdf0e10cSrcweir         case VCLEVENT_COMBOBOX_DESELECT:
232cdf0e10cSrcweir         {
233cdf0e10cSrcweir             // Selection is handled by VCLXAccessibleList which operates on
234cdf0e10cSrcweir             // the same VCL object as this box does.  In case of the
235cdf0e10cSrcweir             // combobox, however, we have to help the list with providing
236cdf0e10cSrcweir             // the text of the currently selected item.
237cdf0e10cSrcweir             VCLXAccessibleList* pList = static_cast<VCLXAccessibleList*>(m_xList.get());
238cdf0e10cSrcweir             if (pList != NULL && m_xText.is())
239cdf0e10cSrcweir             {
240cdf0e10cSrcweir                 Reference<XAccessibleText> xText (m_xText->getAccessibleContext(), UNO_QUERY);
241cdf0e10cSrcweir                 if ( xText.is() )
242cdf0e10cSrcweir 				{
243cdf0e10cSrcweir 					::rtl::OUString sText = xText->getSelectedText();
244144e4e62SHerbert Dürr 					if ( sText.isEmpty() )
245cdf0e10cSrcweir 						sText = xText->getText();
246cdf0e10cSrcweir                     pList->UpdateSelection (sText);
247cdf0e10cSrcweir 				}
248cdf0e10cSrcweir             }
249cdf0e10cSrcweir 			break;
250cdf0e10cSrcweir         }
251cdf0e10cSrcweir 
252cdf0e10cSrcweir 		case VCLEVENT_EDIT_MODIFY:
253cdf0e10cSrcweir         case VCLEVENT_EDIT_SELECTIONCHANGED:
25421075d77SSteve Yin 	 // case VCLEVENT_EDIT_CARETCHANGED:
255cdf0e10cSrcweir             // Modify/Selection events are handled by the combo box instead of
256cdf0e10cSrcweir             // directly by the edit field (Why?).  Therefore, delegate this
257cdf0e10cSrcweir             // call to the edit field.
258cdf0e10cSrcweir             if (m_aBoxType==COMBOBOX)
259cdf0e10cSrcweir             {
260cdf0e10cSrcweir                 if (m_xText.is())
261cdf0e10cSrcweir                 {
262cdf0e10cSrcweir                     Reference<XAccessibleContext> xContext = m_xText->getAccessibleContext();
263cdf0e10cSrcweir                     VCLXAccessibleEdit* pEdit = static_cast<VCLXAccessibleEdit*>(xContext.get());
264cdf0e10cSrcweir                     if (pEdit != NULL)
265cdf0e10cSrcweir                         pEdit->ProcessWindowEvent (rVclWindowEvent);
266cdf0e10cSrcweir                 }
267cdf0e10cSrcweir             }
268cdf0e10cSrcweir             break;
26921075d77SSteve Yin 		/*
27021075d77SSteve Yin 		// MT: Not sending VCLEVENT_LISTBOX_STATEUPDATE, see comment in ListBox::SelectEntryPos
27121075d77SSteve Yin 		case VCLEVENT_LISTBOX_STATEUPDATE:
27221075d77SSteve Yin 		{
2730deba7fbSSteve Yin 			// Need to update the INDETERMINATE state sometimes
27421075d77SSteve Yin 			if (m_bIsDropDownBox && m_aBoxType==LISTBOX)
27521075d77SSteve Yin 			{
27621075d77SSteve Yin 				sal_Int32 nSelectedEntryCount = 0;
27721075d77SSteve Yin 				ListBox* pListBox = static_cast< ListBox* >( GetWindow() );
27821075d77SSteve Yin 				if (pListBox != NULL && pListBox->GetEntryCount() > 0)
27921075d77SSteve Yin 				{
28021075d77SSteve Yin 	        		nSelectedEntryCount = pListBox->GetSelectEntryCount();
28121075d77SSteve Yin 					Any aOldValue;
28221075d77SSteve Yin 					Any aNewValue;
28321075d77SSteve Yin 					if ( nSelectedEntryCount == 0)
28421075d77SSteve Yin 						aNewValue <<= AccessibleStateType::INDETERMINATE;
28521075d77SSteve Yin 					else
28621075d77SSteve Yin 						aOldValue <<= AccessibleStateType::INDETERMINATE;
28721075d77SSteve Yin 					NotifyAccessibleEvent(AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue);
28821075d77SSteve Yin 				}
28921075d77SSteve Yin 			}
29021075d77SSteve Yin 			break;
29121075d77SSteve Yin 		}
29221075d77SSteve Yin 		*/
293cdf0e10cSrcweir 		default:
294cdf0e10cSrcweir 			VCLXAccessibleComponent::ProcessWindowEvent( rVclWindowEvent );
295cdf0e10cSrcweir 	}
296cdf0e10cSrcweir }
297cdf0e10cSrcweir 
IMPLEMENT_FORWARD_XINTERFACE2(VCLXAccessibleBox,VCLXAccessibleComponent,VCLXAccessibleBox_BASE)298cdf0e10cSrcweir IMPLEMENT_FORWARD_XINTERFACE2(VCLXAccessibleBox, VCLXAccessibleComponent, VCLXAccessibleBox_BASE)
299cdf0e10cSrcweir IMPLEMENT_FORWARD_XTYPEPROVIDER2(VCLXAccessibleBox, VCLXAccessibleComponent, VCLXAccessibleBox_BASE)
300cdf0e10cSrcweir 
301cdf0e10cSrcweir //=====  XAccessible  =========================================================
302cdf0e10cSrcweir 
303cdf0e10cSrcweir Reference< XAccessibleContext > SAL_CALL VCLXAccessibleBox::getAccessibleContext(  )
304cdf0e10cSrcweir 	throw (RuntimeException)
305cdf0e10cSrcweir {
306cdf0e10cSrcweir 	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
307cdf0e10cSrcweir 
308cdf0e10cSrcweir 	return this;
309cdf0e10cSrcweir }
310cdf0e10cSrcweir 
311cdf0e10cSrcweir //=====  XAccessibleContext  ==================================================
312cdf0e10cSrcweir 
getAccessibleChildCount(void)313cdf0e10cSrcweir sal_Int32 SAL_CALL VCLXAccessibleBox::getAccessibleChildCount (void)
314cdf0e10cSrcweir     throw (RuntimeException)
315cdf0e10cSrcweir {
316cdf0e10cSrcweir 	vos::OGuard aSolarGuard( Application::GetSolarMutex() );
317cdf0e10cSrcweir 	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
318cdf0e10cSrcweir 
319cdf0e10cSrcweir     // Usually a box has a text field and a list of items as its children.
320cdf0e10cSrcweir     // Non drop down list boxes have no text field.  Additionally check
321cdf0e10cSrcweir     // whether the object is valid.
322cdf0e10cSrcweir     sal_Int32 nCount = 0;
323cdf0e10cSrcweir     if (IsValid())
324cdf0e10cSrcweir         nCount += (m_bHasTextChild?1:0) + (m_bHasListChild?1:0);
325cdf0e10cSrcweir     else
326cdf0e10cSrcweir     {
327cdf0e10cSrcweir         // Object not valid anymore.  Release references to children.
328cdf0e10cSrcweir         m_bHasTextChild = false;
329cdf0e10cSrcweir         m_xText = NULL;
330cdf0e10cSrcweir         m_bHasListChild = false;
331cdf0e10cSrcweir         m_xList = NULL;
332cdf0e10cSrcweir     }
333cdf0e10cSrcweir 
334cdf0e10cSrcweir     return nCount;
335cdf0e10cSrcweir }
336cdf0e10cSrcweir 
getAccessibleChild(sal_Int32 i)337cdf0e10cSrcweir Reference<XAccessible> SAL_CALL VCLXAccessibleBox::getAccessibleChild (sal_Int32 i)
338cdf0e10cSrcweir     throw (IndexOutOfBoundsException, RuntimeException)
339cdf0e10cSrcweir {
340cdf0e10cSrcweir 	vos::OGuard aSolarGuard( Application::GetSolarMutex() );
341cdf0e10cSrcweir 	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
342cdf0e10cSrcweir 
343cdf0e10cSrcweir 	if (i<0 || i>=getAccessibleChildCount())
344cdf0e10cSrcweir 		throw IndexOutOfBoundsException();
345cdf0e10cSrcweir 
346cdf0e10cSrcweir 	Reference< XAccessible > xChild;
347cdf0e10cSrcweir     if (IsValid())
348cdf0e10cSrcweir     {
349cdf0e10cSrcweir         if (i==1 || ! m_bHasTextChild)
350cdf0e10cSrcweir         {
351cdf0e10cSrcweir             // List.
352cdf0e10cSrcweir             if ( ! m_xList.is())
353cdf0e10cSrcweir             {
354cdf0e10cSrcweir                 VCLXAccessibleList* pList = new VCLXAccessibleList ( GetVCLXWindow(),
355cdf0e10cSrcweir 					(m_aBoxType == LISTBOX ? VCLXAccessibleList::LISTBOX : VCLXAccessibleList::COMBOBOX),
356cdf0e10cSrcweir 																	this);
357cdf0e10cSrcweir                 pList->SetIndexInParent (i);
358cdf0e10cSrcweir                 m_xList = pList;
359cdf0e10cSrcweir             }
360cdf0e10cSrcweir             xChild = m_xList;
361cdf0e10cSrcweir         }
362cdf0e10cSrcweir         else
363cdf0e10cSrcweir         {
364cdf0e10cSrcweir             // Text Field.
365cdf0e10cSrcweir             if ( ! m_xText.is())
366cdf0e10cSrcweir             {
367cdf0e10cSrcweir                 if (m_aBoxType==COMBOBOX)
368cdf0e10cSrcweir                 {
369cdf0e10cSrcweir                     ComboBox* pComboBox = static_cast<ComboBox*>(GetWindow());
370cdf0e10cSrcweir                     if (pComboBox!=NULL && pComboBox->GetSubEdit()!=NULL)
37121075d77SSteve Yin 					//Set the edit's acc name the same as parent
37221075d77SSteve Yin 					{
37321075d77SSteve Yin 						pComboBox->GetSubEdit()->SetAccessibleName(getAccessibleName());
374cdf0e10cSrcweir                         m_xText = pComboBox->GetSubEdit()->GetAccessible();
37521075d77SSteve Yin 					}
376cdf0e10cSrcweir                 }
377cdf0e10cSrcweir                 else if (m_bIsDropDownBox)
378cdf0e10cSrcweir                     m_xText = new VCLXAccessibleTextField (GetVCLXWindow(),this);
379cdf0e10cSrcweir             }
380cdf0e10cSrcweir             xChild = m_xText;
381cdf0e10cSrcweir         }
382cdf0e10cSrcweir     }
383cdf0e10cSrcweir 
384cdf0e10cSrcweir     return xChild;
385cdf0e10cSrcweir }
386cdf0e10cSrcweir 
getAccessibleRole(void)387cdf0e10cSrcweir sal_Int16 SAL_CALL VCLXAccessibleBox::getAccessibleRole (void) throw (RuntimeException)
388cdf0e10cSrcweir {
389cdf0e10cSrcweir 	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
390cdf0e10cSrcweir 
391cdf0e10cSrcweir     // Return the role <const>COMBO_BOX</const> for both VCL combo boxes and
392cdf0e10cSrcweir     // VCL list boxes in DropDown-Mode else <const>PANEL</const>.
393cdf0e10cSrcweir 	// This way the Java bridge has not to handle both independently.
39421075d77SSteve Yin     //return m_bIsDropDownBox ? AccessibleRole::COMBO_BOX : AccessibleRole::PANEL;
39521075d77SSteve Yin 	if (m_bIsDropDownBox || (!m_bIsDropDownBox && m_aBoxType == COMBOBOX ))
39621075d77SSteve Yin 		return AccessibleRole::COMBO_BOX;
39721075d77SSteve Yin 	else
39821075d77SSteve Yin 		return AccessibleRole::PANEL;
399cdf0e10cSrcweir }
400cdf0e10cSrcweir 
getAccessibleIndexInParent(void)401cdf0e10cSrcweir sal_Int32 SAL_CALL VCLXAccessibleBox::getAccessibleIndexInParent (void)
402cdf0e10cSrcweir     throw (::com::sun::star::uno::RuntimeException)
403cdf0e10cSrcweir {
404cdf0e10cSrcweir     if (m_nIndexInParent != DEFAULT_INDEX_IN_PARENT)
405cdf0e10cSrcweir         return m_nIndexInParent;
406cdf0e10cSrcweir     else
407cdf0e10cSrcweir         return VCLXAccessibleComponent::getAccessibleIndexInParent();
408cdf0e10cSrcweir }
409cdf0e10cSrcweir 
410cdf0e10cSrcweir //=====  XAccessibleAction  ===================================================
411cdf0e10cSrcweir 
getAccessibleActionCount(void)412cdf0e10cSrcweir sal_Int32 SAL_CALL VCLXAccessibleBox::getAccessibleActionCount (void)
413cdf0e10cSrcweir     throw (RuntimeException)
414cdf0e10cSrcweir {
415cdf0e10cSrcweir 	::osl::Guard< ::osl::Mutex> aGuard (GetMutex());
416cdf0e10cSrcweir 
417cdf0e10cSrcweir     // There is one action for drop down boxes (toggle popup) and none for
418cdf0e10cSrcweir     // the other boxes.
419*9c07f23fSJuergen Schmidt 	return m_bIsDropDownBox ? 1 : 0;
420cdf0e10cSrcweir }
421cdf0e10cSrcweir 
doAccessibleAction(sal_Int32 nIndex)422cdf0e10cSrcweir sal_Bool SAL_CALL VCLXAccessibleBox::doAccessibleAction (sal_Int32 nIndex)
423cdf0e10cSrcweir     throw (IndexOutOfBoundsException, RuntimeException)
424cdf0e10cSrcweir {
425cdf0e10cSrcweir 	sal_Bool bNotify = sal_False;
426cdf0e10cSrcweir 
427cdf0e10cSrcweir 	{
428cdf0e10cSrcweir 		vos::OGuard aSolarGuard( Application::GetSolarMutex() );
429cdf0e10cSrcweir 		::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
430cdf0e10cSrcweir 
431cdf0e10cSrcweir         if (nIndex<0 || nIndex>=getAccessibleActionCount())
432cdf0e10cSrcweir             throw ::com::sun::star::lang::IndexOutOfBoundsException();
433cdf0e10cSrcweir 
434cdf0e10cSrcweir 		if (m_aBoxType == COMBOBOX)
435cdf0e10cSrcweir         {
436cdf0e10cSrcweir             ComboBox* pComboBox = static_cast< ComboBox* >( GetWindow() );
437cdf0e10cSrcweir             if (pComboBox != NULL)
438cdf0e10cSrcweir             {
439cdf0e10cSrcweir                 pComboBox->ToggleDropDown();
440cdf0e10cSrcweir                 bNotify = sal_True;
441cdf0e10cSrcweir             }
442cdf0e10cSrcweir         }
443cdf0e10cSrcweir         else if (m_aBoxType == LISTBOX)
444cdf0e10cSrcweir         {
445cdf0e10cSrcweir             ListBox* pListBox = static_cast< ListBox* >( GetWindow() );
446cdf0e10cSrcweir             if (pListBox != NULL)
447cdf0e10cSrcweir             {
448cdf0e10cSrcweir                 pListBox->ToggleDropDown();
449cdf0e10cSrcweir                 bNotify = sal_True;
450cdf0e10cSrcweir             }
451cdf0e10cSrcweir         }
452cdf0e10cSrcweir     }
453cdf0e10cSrcweir 
454cdf0e10cSrcweir 	if (bNotify)
455cdf0e10cSrcweir 		NotifyAccessibleEvent (AccessibleEventId::ACTION_CHANGED, Any(), Any());
456cdf0e10cSrcweir 
457cdf0e10cSrcweir 	return bNotify;
458cdf0e10cSrcweir }
459cdf0e10cSrcweir 
getAccessibleActionDescription(sal_Int32 nIndex)460cdf0e10cSrcweir ::rtl::OUString SAL_CALL VCLXAccessibleBox::getAccessibleActionDescription (sal_Int32 nIndex)
461cdf0e10cSrcweir     throw (IndexOutOfBoundsException, RuntimeException)
462cdf0e10cSrcweir {
463cdf0e10cSrcweir 	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
464cdf0e10cSrcweir     if (nIndex<0 || nIndex>=getAccessibleActionCount())
465cdf0e10cSrcweir         throw ::com::sun::star::lang::IndexOutOfBoundsException();
466*9c07f23fSJuergen Schmidt 
467*9c07f23fSJuergen Schmidt 	return m_bIsDropDownBox ? TK_RES_STRING( RID_STR_ACC_ACTION_TOGGLEPOPUP) : ::rtl::OUString();
468cdf0e10cSrcweir }
469cdf0e10cSrcweir 
getAccessibleActionKeyBinding(sal_Int32 nIndex)470cdf0e10cSrcweir Reference< XAccessibleKeyBinding > VCLXAccessibleBox::getAccessibleActionKeyBinding( sal_Int32 nIndex )
471cdf0e10cSrcweir 	throw (IndexOutOfBoundsException, RuntimeException)
472cdf0e10cSrcweir {
473cdf0e10cSrcweir 	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
474cdf0e10cSrcweir 
475cdf0e10cSrcweir 	Reference< XAccessibleKeyBinding > xRet;
476cdf0e10cSrcweir 
477cdf0e10cSrcweir     if (nIndex<0 || nIndex>=getAccessibleActionCount())
478cdf0e10cSrcweir         throw ::com::sun::star::lang::IndexOutOfBoundsException();
479cdf0e10cSrcweir 
480cdf0e10cSrcweir 	// ... which key?
481cdf0e10cSrcweir 	return xRet;
482cdf0e10cSrcweir }
483cdf0e10cSrcweir 
484cdf0e10cSrcweir //=====  XComponent  ==========================================================
485cdf0e10cSrcweir 
disposing(void)486cdf0e10cSrcweir void SAL_CALL VCLXAccessibleBox::disposing (void)
487cdf0e10cSrcweir {
488cdf0e10cSrcweir 	VCLXAccessibleComponent::disposing();
489cdf0e10cSrcweir }
490cdf0e10cSrcweir 
49121075d77SSteve Yin // =====  XAccessibleValue  ===============================================
getCurrentValue()49221075d77SSteve Yin Any VCLXAccessibleBox::getCurrentValue( )
49321075d77SSteve Yin     throw( RuntimeException )
49421075d77SSteve Yin {
49521075d77SSteve Yin 	vos::OGuard aSolarGuard( Application::GetSolarMutex() );
49621075d77SSteve Yin 	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
49721075d77SSteve Yin 
49821075d77SSteve Yin 	Any aAny;
49921075d77SSteve Yin 	if( m_xList.is() && m_xText.is())
50021075d77SSteve Yin 	{
50121075d77SSteve Yin 		// VCLXAccessibleList* pList = static_cast<VCLXAccessibleList*>(m_xList.get());
50221075d77SSteve Yin 		Reference<XAccessibleText> xText (m_xText->getAccessibleContext(), UNO_QUERY);
50321075d77SSteve Yin 		if ( xText.is() )
50421075d77SSteve Yin 		{
50521075d77SSteve Yin 			::rtl::OUString sText = xText->getText();
50621075d77SSteve Yin 			aAny <<= sText;
50721075d77SSteve Yin 		}
50821075d77SSteve Yin 	}
50921075d77SSteve Yin 	if (m_aBoxType == LISTBOX && m_bIsDropDownBox  && m_xList.is() )
51021075d77SSteve Yin 	{
51121075d77SSteve Yin 
51221075d77SSteve Yin 		VCLXAccessibleList* pList = static_cast<VCLXAccessibleList*>(m_xList.get());
51321075d77SSteve Yin 		if(pList->IsInDropDown())
51421075d77SSteve Yin 		{
51521075d77SSteve Yin 			if(pList->getSelectedAccessibleChildCount()>0)
51621075d77SSteve Yin 			{
51721075d77SSteve Yin 				Reference<XAccessibleContext> xName (pList->getSelectedAccessibleChild((sal_Int32)(0)), UNO_QUERY);
51821075d77SSteve Yin 				if(xName.is())
51921075d77SSteve Yin 				{
52021075d77SSteve Yin 					aAny <<= xName->getAccessibleName();
52121075d77SSteve Yin 				}
52221075d77SSteve Yin 			}
52321075d77SSteve Yin 		}
52421075d77SSteve Yin 	}
52521075d77SSteve Yin 
52621075d77SSteve Yin     return aAny;
52721075d77SSteve Yin }
52821075d77SSteve Yin 
setCurrentValue(const Any & aNumber)52921075d77SSteve Yin sal_Bool VCLXAccessibleBox::setCurrentValue( const Any& aNumber )
53021075d77SSteve Yin     throw( RuntimeException )
53121075d77SSteve Yin {
53221075d77SSteve Yin 	vos::OGuard aSolarGuard( Application::GetSolarMutex() );
53321075d77SSteve Yin 	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
53421075d77SSteve Yin 
53521075d77SSteve Yin     ::rtl::OUString  fValue;
53621075d77SSteve Yin     sal_Bool bValid = (aNumber >>= fValue);
53721075d77SSteve Yin     if( bValid )
53821075d77SSteve Yin     {
53921075d77SSteve Yin 
54021075d77SSteve Yin     }
54121075d77SSteve Yin     return bValid;
54221075d77SSteve Yin 
54321075d77SSteve Yin }
54421075d77SSteve Yin 
getMaximumValue()54521075d77SSteve Yin Any VCLXAccessibleBox::getMaximumValue( )
54621075d77SSteve Yin     throw( RuntimeException )
54721075d77SSteve Yin {
54821075d77SSteve Yin     Any aAny;
54921075d77SSteve Yin     return aAny;
55021075d77SSteve Yin }
55121075d77SSteve Yin 
getMinimumValue()55221075d77SSteve Yin Any VCLXAccessibleBox::getMinimumValue(  )
55321075d77SSteve Yin     throw( RuntimeException )
55421075d77SSteve Yin {
55521075d77SSteve Yin     Any aAny;
55621075d77SSteve Yin     return aAny;
55721075d77SSteve Yin }
55821075d77SSteve Yin 
55921075d77SSteve Yin // Set the INDETERMINATE state when there is no selected item for combobox
FillAccessibleStateSet(utl::AccessibleStateSetHelper & rStateSet)56021075d77SSteve Yin void VCLXAccessibleBox::FillAccessibleStateSet( utl::AccessibleStateSetHelper& rStateSet )
56121075d77SSteve Yin {
56221075d77SSteve Yin 	VCLXAccessibleComponent::FillAccessibleStateSet(rStateSet);
56321075d77SSteve Yin 	if (m_aBoxType == COMBOBOX )
56421075d77SSteve Yin 	{
56521075d77SSteve Yin 		::rtl::OUString sText;
56621075d77SSteve Yin 		sal_Int32 nEntryCount = 0;
56721075d77SSteve Yin 		ComboBox* pComboBox = static_cast<ComboBox*>(GetWindow());
56821075d77SSteve Yin 		if (pComboBox != NULL)
56921075d77SSteve Yin 		{
57021075d77SSteve Yin 			Edit* pSubEdit = pComboBox->GetSubEdit();
57121075d77SSteve Yin 			if ( pSubEdit)
57221075d77SSteve Yin 				sText = pSubEdit->GetText();
57321075d77SSteve Yin 			nEntryCount = pComboBox->GetEntryCount();
57421075d77SSteve Yin 		}
575144e4e62SHerbert Dürr 		if ( sText.isEmpty() && nEntryCount > 0 )
57621075d77SSteve Yin 			rStateSet.AddState(AccessibleStateType::INDETERMINATE);
57721075d77SSteve Yin 	}
57821075d77SSteve Yin 	else if (m_aBoxType == LISTBOX && m_bIsDropDownBox == true)
57921075d77SSteve Yin 	{
58021075d77SSteve Yin 		sal_Int32 nSelectedEntryCount = 0;
58121075d77SSteve Yin 		ListBox* pListBox = static_cast< ListBox* >( GetWindow() );
58221075d77SSteve Yin 		if (pListBox != NULL && pListBox->GetEntryCount() > 0)
58321075d77SSteve Yin 		{
58421075d77SSteve Yin 	        	nSelectedEntryCount = pListBox->GetSelectEntryCount();
58521075d77SSteve Yin 			if ( nSelectedEntryCount == 0)
58621075d77SSteve Yin 				rStateSet.AddState(AccessibleStateType::INDETERMINATE);
58721075d77SSteve Yin 		}
58821075d77SSteve Yin 	}
58921075d77SSteve Yin }
590