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/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 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 64cdf0e10cSrcweir VCLXAccessibleBox::~VCLXAccessibleBox (void) 65cdf0e10cSrcweir { 66cdf0e10cSrcweir } 67cdf0e10cSrcweir 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 115cdf0e10cSrcweir void VCLXAccessibleBox::ProcessWindowEvent (const VclWindowEvent& rVclWindowEvent) 116cdf0e10cSrcweir { 117cdf0e10cSrcweir switch ( rVclWindowEvent.GetId() ) 118cdf0e10cSrcweir { 119*6485ffd2SSteve 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()); 18521075d77SSteve Yin if (pList != NULL) 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(); 19121075d77SSteve Yin if ( !sText.getLength() ) 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(); 244cdf0e10cSrcweir if ( !sText.getLength() ) 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 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 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 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(); 375cdf0e10cSrcweir } 37621075d77SSteve Yin } 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 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 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 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. 41921075d77SSteve Yin return m_bIsDropDownBox ? 0 : 1; 420cdf0e10cSrcweir } 421cdf0e10cSrcweir 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 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(); 46621075d77SSteve Yin //Solution:When combo_box,it should not has action information. 46721075d77SSteve Yin //return TK_RES_STRING( RID_STR_ACC_ACTION_TOGGLEPOPUP); 46821075d77SSteve Yin if (m_aBoxType == LISTBOX) 46921075d77SSteve Yin return ::rtl::OUString(); 47021075d77SSteve Yin return m_bIsDropDownBox?::rtl::OUString():TK_RES_STRING( RID_STR_ACC_ACTION_TOGGLEPOPUP); 471cdf0e10cSrcweir } 472cdf0e10cSrcweir 473cdf0e10cSrcweir Reference< XAccessibleKeyBinding > VCLXAccessibleBox::getAccessibleActionKeyBinding( sal_Int32 nIndex ) 474cdf0e10cSrcweir throw (IndexOutOfBoundsException, RuntimeException) 475cdf0e10cSrcweir { 476cdf0e10cSrcweir ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 477cdf0e10cSrcweir 478cdf0e10cSrcweir Reference< XAccessibleKeyBinding > xRet; 479cdf0e10cSrcweir 480cdf0e10cSrcweir if (nIndex<0 || nIndex>=getAccessibleActionCount()) 481cdf0e10cSrcweir throw ::com::sun::star::lang::IndexOutOfBoundsException(); 482cdf0e10cSrcweir 483cdf0e10cSrcweir // ... which key? 484cdf0e10cSrcweir return xRet; 485cdf0e10cSrcweir } 486cdf0e10cSrcweir 487cdf0e10cSrcweir //===== XComponent ========================================================== 488cdf0e10cSrcweir 489cdf0e10cSrcweir void SAL_CALL VCLXAccessibleBox::disposing (void) 490cdf0e10cSrcweir { 491cdf0e10cSrcweir VCLXAccessibleComponent::disposing(); 492cdf0e10cSrcweir } 493cdf0e10cSrcweir 49421075d77SSteve Yin // ===== XAccessibleValue =============================================== 49521075d77SSteve Yin Any VCLXAccessibleBox::getCurrentValue( ) 49621075d77SSteve Yin throw( RuntimeException ) 49721075d77SSteve Yin { 49821075d77SSteve Yin vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 49921075d77SSteve Yin ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 50021075d77SSteve Yin 50121075d77SSteve Yin Any aAny; 50221075d77SSteve Yin if( m_xList.is() && m_xText.is()) 50321075d77SSteve Yin { 50421075d77SSteve Yin // VCLXAccessibleList* pList = static_cast<VCLXAccessibleList*>(m_xList.get()); 50521075d77SSteve Yin Reference<XAccessibleText> xText (m_xText->getAccessibleContext(), UNO_QUERY); 50621075d77SSteve Yin if ( xText.is() ) 50721075d77SSteve Yin { 50821075d77SSteve Yin ::rtl::OUString sText = xText->getText(); 50921075d77SSteve Yin aAny <<= sText; 51021075d77SSteve Yin } 51121075d77SSteve Yin } 51221075d77SSteve Yin if (m_aBoxType == LISTBOX && m_bIsDropDownBox && m_xList.is() ) 51321075d77SSteve Yin { 51421075d77SSteve Yin 51521075d77SSteve Yin VCLXAccessibleList* pList = static_cast<VCLXAccessibleList*>(m_xList.get()); 51621075d77SSteve Yin if(pList->IsInDropDown()) 51721075d77SSteve Yin { 51821075d77SSteve Yin if(pList->getSelectedAccessibleChildCount()>0) 51921075d77SSteve Yin { 52021075d77SSteve Yin Reference<XAccessibleContext> xName (pList->getSelectedAccessibleChild((sal_Int32)(0)), UNO_QUERY); 52121075d77SSteve Yin if(xName.is()) 52221075d77SSteve Yin { 52321075d77SSteve Yin aAny <<= xName->getAccessibleName(); 52421075d77SSteve Yin } 52521075d77SSteve Yin } 52621075d77SSteve Yin } 52721075d77SSteve Yin } 52821075d77SSteve Yin 52921075d77SSteve Yin return aAny; 53021075d77SSteve Yin } 53121075d77SSteve Yin 53221075d77SSteve Yin sal_Bool VCLXAccessibleBox::setCurrentValue( const Any& aNumber ) 53321075d77SSteve Yin throw( RuntimeException ) 53421075d77SSteve Yin { 53521075d77SSteve Yin vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 53621075d77SSteve Yin ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 53721075d77SSteve Yin 53821075d77SSteve Yin ::rtl::OUString fValue; 53921075d77SSteve Yin sal_Bool bValid = (aNumber >>= fValue); 54021075d77SSteve Yin if( bValid ) 54121075d77SSteve Yin { 54221075d77SSteve Yin 54321075d77SSteve Yin } 54421075d77SSteve Yin return bValid; 54521075d77SSteve Yin 54621075d77SSteve Yin } 54721075d77SSteve Yin 54821075d77SSteve Yin Any VCLXAccessibleBox::getMaximumValue( ) 54921075d77SSteve Yin throw( RuntimeException ) 55021075d77SSteve Yin { 55121075d77SSteve Yin Any aAny; 55221075d77SSteve Yin return aAny; 55321075d77SSteve Yin } 55421075d77SSteve Yin 55521075d77SSteve Yin Any VCLXAccessibleBox::getMinimumValue( ) 55621075d77SSteve Yin throw( RuntimeException ) 55721075d77SSteve Yin { 55821075d77SSteve Yin Any aAny; 55921075d77SSteve Yin return aAny; 56021075d77SSteve Yin } 56121075d77SSteve Yin 56221075d77SSteve Yin // Set the INDETERMINATE state when there is no selected item for combobox 56321075d77SSteve Yin void VCLXAccessibleBox::FillAccessibleStateSet( utl::AccessibleStateSetHelper& rStateSet ) 56421075d77SSteve Yin { 56521075d77SSteve Yin VCLXAccessibleComponent::FillAccessibleStateSet(rStateSet); 56621075d77SSteve Yin if (m_aBoxType == COMBOBOX ) 56721075d77SSteve Yin { 56821075d77SSteve Yin ::rtl::OUString sText; 56921075d77SSteve Yin sal_Int32 nEntryCount = 0; 57021075d77SSteve Yin ComboBox* pComboBox = static_cast<ComboBox*>(GetWindow()); 57121075d77SSteve Yin if (pComboBox != NULL) 57221075d77SSteve Yin { 57321075d77SSteve Yin Edit* pSubEdit = pComboBox->GetSubEdit(); 57421075d77SSteve Yin if ( pSubEdit) 57521075d77SSteve Yin sText = pSubEdit->GetText(); 57621075d77SSteve Yin nEntryCount = pComboBox->GetEntryCount(); 57721075d77SSteve Yin } 57821075d77SSteve Yin if (sText.getLength() == 0 && nEntryCount >0) 57921075d77SSteve Yin rStateSet.AddState(AccessibleStateType::INDETERMINATE); 58021075d77SSteve Yin } 58121075d77SSteve Yin else if (m_aBoxType == LISTBOX && m_bIsDropDownBox == true) 58221075d77SSteve Yin { 58321075d77SSteve Yin sal_Int32 nSelectedEntryCount = 0; 58421075d77SSteve Yin ListBox* pListBox = static_cast< ListBox* >( GetWindow() ); 58521075d77SSteve Yin if (pListBox != NULL && pListBox->GetEntryCount() > 0) 58621075d77SSteve Yin { 58721075d77SSteve Yin nSelectedEntryCount = pListBox->GetSelectEntryCount(); 58821075d77SSteve Yin if ( nSelectedEntryCount == 0) 58921075d77SSteve Yin rStateSet.AddState(AccessibleStateType::INDETERMINATE); 59021075d77SSteve Yin } 59121075d77SSteve Yin } 59221075d77SSteve Yin } 593