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