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 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*21075d77SSteve Yin case VCLEVENT_LISTBOX_SELECT: 120*21075d77SSteve Yin case VCLEVENT_LISTBOX_FOCUSITEMCHANGED: 121*21075d77SSteve Yin 122*21075d77SSteve Yin { 123*21075d77SSteve Yin // Forward the call to the list child. 124*21075d77SSteve Yin VCLXAccessibleList* pList = static_cast<VCLXAccessibleList*>(m_xList.get()); 125*21075d77SSteve Yin if ( pList == NULL ) 126*21075d77SSteve Yin { 127*21075d77SSteve Yin getAccessibleChild ( m_bHasTextChild ? 1 : 0 ); 128*21075d77SSteve Yin pList = static_cast<VCLXAccessibleList*>(m_xList.get()); 129*21075d77SSteve Yin } 130*21075d77SSteve Yin if ( pList != NULL ) 131*21075d77SSteve Yin { 132*21075d77SSteve Yin pList->ProcessWindowEvent (rVclWindowEvent, m_bIsDropDownBox); 133*21075d77SSteve Yin if(m_bIsDropDownBox) 134*21075d77SSteve Yin { 135*21075d77SSteve Yin NotifyAccessibleEvent(AccessibleEventId::VALUE_CHANGED, Any(), Any()); 136*21075d77SSteve Yin Any aOldValue; 137*21075d77SSteve Yin Any aNewValue; 138*21075d77SSteve Yin aOldValue <<= AccessibleStateType::INDETERMINATE; 139*21075d77SSteve Yin NotifyAccessibleEvent(AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue); 140*21075d77SSteve Yin 141*21075d77SSteve Yin } 142*21075d77SSteve Yin } 143*21075d77SSteve Yin break; 144*21075d77SSteve Yin } 145cdf0e10cSrcweir case VCLEVENT_DROPDOWN_OPEN: 146*21075d77SSteve Yin { 147*21075d77SSteve Yin VCLXAccessibleList* pList = static_cast<VCLXAccessibleList*>(m_xList.get()); 148*21075d77SSteve Yin if ( pList == NULL ) 149*21075d77SSteve Yin { 150*21075d77SSteve Yin getAccessibleChild ( m_bHasTextChild ? 1 : 0 ); 151*21075d77SSteve Yin pList = static_cast<VCLXAccessibleList*>(m_xList.get()); 152*21075d77SSteve Yin } 153*21075d77SSteve Yin if ( pList != NULL ) 154*21075d77SSteve Yin { 155*21075d77SSteve Yin pList->ProcessWindowEvent (rVclWindowEvent); 156*21075d77SSteve Yin pList->HandleDropOpen(); 157*21075d77SSteve Yin } 158*21075d77SSteve Yin break; 159*21075d77SSteve Yin } 160cdf0e10cSrcweir case VCLEVENT_DROPDOWN_CLOSE: 161*21075d77SSteve Yin { 162*21075d77SSteve Yin VCLXAccessibleList* pList = static_cast<VCLXAccessibleList*>(m_xList.get()); 163*21075d77SSteve Yin if ( pList == NULL ) 164*21075d77SSteve Yin { 165*21075d77SSteve Yin getAccessibleChild ( m_bHasTextChild ? 1 : 0 ); 166*21075d77SSteve Yin pList = static_cast<VCLXAccessibleList*>(m_xList.get()); 167*21075d77SSteve Yin } 168*21075d77SSteve Yin if ( pList != NULL ) 169*21075d77SSteve Yin { 170*21075d77SSteve Yin pList->ProcessWindowEvent (rVclWindowEvent); 171*21075d77SSteve Yin } 172*21075d77SSteve Yin Window* pWindow = GetWindow(); 173*21075d77SSteve Yin if( pWindow && (pWindow->HasFocus() || pWindow->HasChildPathFocus()) ) 174*21075d77SSteve Yin { 175*21075d77SSteve Yin Any aOldValue, aNewValue; 176*21075d77SSteve Yin aNewValue <<= AccessibleStateType::FOCUSED; 177*21075d77SSteve Yin NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); 178*21075d77SSteve Yin } 179*21075d77SSteve Yin break; 180*21075d77SSteve Yin } 181*21075d77SSteve Yin case VCLEVENT_COMBOBOX_SELECT: 182*21075d77SSteve Yin { 183*21075d77SSteve Yin VCLXAccessibleList* pList = static_cast<VCLXAccessibleList*>(m_xList.get()); 184*21075d77SSteve Yin if (pList != NULL) 185*21075d77SSteve Yin { 186*21075d77SSteve Yin Reference<XAccessibleText> xText (m_xText->getAccessibleContext(), UNO_QUERY); 187*21075d77SSteve Yin if ( xText.is() ) 188*21075d77SSteve Yin { 189*21075d77SSteve Yin ::rtl::OUString sText = xText->getSelectedText(); 190*21075d77SSteve Yin if ( !sText.getLength() ) 191*21075d77SSteve Yin sText = xText->getText(); 192*21075d77SSteve Yin pList->UpdateSelection_Acc (sText, m_bIsDropDownBox); 193*21075d77SSteve Yin //if(m_bIsDropDownBox && !pList->IsInDropDown()) 194*21075d77SSteve Yin if (m_bIsDropDownBox || ( !m_bIsDropDownBox && m_aBoxType==COMBOBOX)) 195*21075d77SSteve Yin NotifyAccessibleEvent(AccessibleEventId::VALUE_CHANGED, Any(), Any()); 196*21075d77SSteve Yin 197*21075d77SSteve Yin Any aOldValue; 198*21075d77SSteve Yin Any aNewValue; 199*21075d77SSteve Yin aOldValue <<= AccessibleStateType::INDETERMINATE; 200*21075d77SSteve Yin NotifyAccessibleEvent(AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue); 201*21075d77SSteve Yin 202*21075d77SSteve Yin } 203*21075d77SSteve Yin } 204*21075d77SSteve Yin break; 205*21075d77SSteve Yin } 206*21075d77SSteve Yin //case VCLEVENT_DROPDOWN_OPEN: 207*21075d77SSteve Yin //case VCLEVENT_DROPDOWN_CLOSE: 208cdf0e10cSrcweir case VCLEVENT_LISTBOX_DOUBLECLICK: 209cdf0e10cSrcweir case VCLEVENT_LISTBOX_SCROLLED: 210*21075d77SSteve Yin //case VCLEVENT_LISTBOX_SELECT: 211cdf0e10cSrcweir case VCLEVENT_LISTBOX_ITEMADDED: 212cdf0e10cSrcweir case VCLEVENT_LISTBOX_ITEMREMOVED: 213cdf0e10cSrcweir case VCLEVENT_COMBOBOX_ITEMADDED: 214cdf0e10cSrcweir case VCLEVENT_COMBOBOX_ITEMREMOVED: 215cdf0e10cSrcweir case VCLEVENT_COMBOBOX_SCROLLED: 216cdf0e10cSrcweir { 217cdf0e10cSrcweir // Forward the call to the list child. 218cdf0e10cSrcweir VCLXAccessibleList* pList = static_cast<VCLXAccessibleList*>(m_xList.get()); 219cdf0e10cSrcweir if ( pList == NULL ) 220cdf0e10cSrcweir { 221cdf0e10cSrcweir getAccessibleChild ( m_bHasTextChild ? 1 : 0 ); 222cdf0e10cSrcweir pList = static_cast<VCLXAccessibleList*>(m_xList.get()); 223cdf0e10cSrcweir } 224cdf0e10cSrcweir if ( pList != NULL ) 225cdf0e10cSrcweir pList->ProcessWindowEvent (rVclWindowEvent); 226cdf0e10cSrcweir break; 227cdf0e10cSrcweir } 228cdf0e10cSrcweir 229*21075d77SSteve Yin //case VCLEVENT_COMBOBOX_SELECT: 230cdf0e10cSrcweir case VCLEVENT_COMBOBOX_DESELECT: 231cdf0e10cSrcweir { 232cdf0e10cSrcweir // Selection is handled by VCLXAccessibleList which operates on 233cdf0e10cSrcweir // the same VCL object as this box does. In case of the 234cdf0e10cSrcweir // combobox, however, we have to help the list with providing 235cdf0e10cSrcweir // the text of the currently selected item. 236cdf0e10cSrcweir VCLXAccessibleList* pList = static_cast<VCLXAccessibleList*>(m_xList.get()); 237cdf0e10cSrcweir if (pList != NULL && m_xText.is()) 238cdf0e10cSrcweir { 239cdf0e10cSrcweir Reference<XAccessibleText> xText (m_xText->getAccessibleContext(), UNO_QUERY); 240cdf0e10cSrcweir if ( xText.is() ) 241cdf0e10cSrcweir { 242cdf0e10cSrcweir ::rtl::OUString sText = xText->getSelectedText(); 243cdf0e10cSrcweir if ( !sText.getLength() ) 244cdf0e10cSrcweir sText = xText->getText(); 245cdf0e10cSrcweir pList->UpdateSelection (sText); 246cdf0e10cSrcweir } 247cdf0e10cSrcweir } 248cdf0e10cSrcweir break; 249cdf0e10cSrcweir } 250cdf0e10cSrcweir 251cdf0e10cSrcweir case VCLEVENT_EDIT_MODIFY: 252cdf0e10cSrcweir case VCLEVENT_EDIT_SELECTIONCHANGED: 253*21075d77SSteve Yin // case VCLEVENT_EDIT_CARETCHANGED: 254cdf0e10cSrcweir // Modify/Selection events are handled by the combo box instead of 255cdf0e10cSrcweir // directly by the edit field (Why?). Therefore, delegate this 256cdf0e10cSrcweir // call to the edit field. 257cdf0e10cSrcweir if (m_aBoxType==COMBOBOX) 258cdf0e10cSrcweir { 259cdf0e10cSrcweir if (m_xText.is()) 260cdf0e10cSrcweir { 261cdf0e10cSrcweir Reference<XAccessibleContext> xContext = m_xText->getAccessibleContext(); 262cdf0e10cSrcweir VCLXAccessibleEdit* pEdit = static_cast<VCLXAccessibleEdit*>(xContext.get()); 263cdf0e10cSrcweir if (pEdit != NULL) 264cdf0e10cSrcweir pEdit->ProcessWindowEvent (rVclWindowEvent); 265cdf0e10cSrcweir } 266cdf0e10cSrcweir } 267cdf0e10cSrcweir break; 268*21075d77SSteve Yin /* 269*21075d77SSteve Yin // MT: Not sending VCLEVENT_LISTBOX_STATEUPDATE, see comment in ListBox::SelectEntryPos 270*21075d77SSteve Yin case VCLEVENT_LISTBOX_STATEUPDATE: 271*21075d77SSteve Yin { 272*21075d77SSteve Yin // Need to update the INDETERMINATE state sometimes, Sym2_1986 273*21075d77SSteve Yin if (m_bIsDropDownBox && m_aBoxType==LISTBOX) 274*21075d77SSteve Yin { 275*21075d77SSteve Yin sal_Int32 nSelectedEntryCount = 0; 276*21075d77SSteve Yin ListBox* pListBox = static_cast< ListBox* >( GetWindow() ); 277*21075d77SSteve Yin if (pListBox != NULL && pListBox->GetEntryCount() > 0) 278*21075d77SSteve Yin { 279*21075d77SSteve Yin nSelectedEntryCount = pListBox->GetSelectEntryCount(); 280*21075d77SSteve Yin Any aOldValue; 281*21075d77SSteve Yin Any aNewValue; 282*21075d77SSteve Yin if ( nSelectedEntryCount == 0) 283*21075d77SSteve Yin aNewValue <<= AccessibleStateType::INDETERMINATE; 284*21075d77SSteve Yin else 285*21075d77SSteve Yin aOldValue <<= AccessibleStateType::INDETERMINATE; 286*21075d77SSteve Yin NotifyAccessibleEvent(AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue); 287*21075d77SSteve Yin } 288*21075d77SSteve Yin } 289*21075d77SSteve Yin break; 290*21075d77SSteve Yin } 291*21075d77SSteve Yin */ 292cdf0e10cSrcweir default: 293cdf0e10cSrcweir VCLXAccessibleComponent::ProcessWindowEvent( rVclWindowEvent ); 294cdf0e10cSrcweir } 295cdf0e10cSrcweir } 296cdf0e10cSrcweir 297cdf0e10cSrcweir IMPLEMENT_FORWARD_XINTERFACE2(VCLXAccessibleBox, VCLXAccessibleComponent, VCLXAccessibleBox_BASE) 298cdf0e10cSrcweir IMPLEMENT_FORWARD_XTYPEPROVIDER2(VCLXAccessibleBox, VCLXAccessibleComponent, VCLXAccessibleBox_BASE) 299cdf0e10cSrcweir 300cdf0e10cSrcweir //===== XAccessible ========================================================= 301cdf0e10cSrcweir 302cdf0e10cSrcweir Reference< XAccessibleContext > SAL_CALL VCLXAccessibleBox::getAccessibleContext( ) 303cdf0e10cSrcweir throw (RuntimeException) 304cdf0e10cSrcweir { 305cdf0e10cSrcweir ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 306cdf0e10cSrcweir 307cdf0e10cSrcweir return this; 308cdf0e10cSrcweir } 309cdf0e10cSrcweir 310cdf0e10cSrcweir //===== XAccessibleContext ================================================== 311cdf0e10cSrcweir 312cdf0e10cSrcweir sal_Int32 SAL_CALL VCLXAccessibleBox::getAccessibleChildCount (void) 313cdf0e10cSrcweir throw (RuntimeException) 314cdf0e10cSrcweir { 315cdf0e10cSrcweir vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 316cdf0e10cSrcweir ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 317cdf0e10cSrcweir 318cdf0e10cSrcweir // Usually a box has a text field and a list of items as its children. 319cdf0e10cSrcweir // Non drop down list boxes have no text field. Additionally check 320cdf0e10cSrcweir // whether the object is valid. 321cdf0e10cSrcweir sal_Int32 nCount = 0; 322cdf0e10cSrcweir if (IsValid()) 323cdf0e10cSrcweir nCount += (m_bHasTextChild?1:0) + (m_bHasListChild?1:0); 324cdf0e10cSrcweir else 325cdf0e10cSrcweir { 326cdf0e10cSrcweir // Object not valid anymore. Release references to children. 327cdf0e10cSrcweir m_bHasTextChild = false; 328cdf0e10cSrcweir m_xText = NULL; 329cdf0e10cSrcweir m_bHasListChild = false; 330cdf0e10cSrcweir m_xList = NULL; 331cdf0e10cSrcweir } 332cdf0e10cSrcweir 333cdf0e10cSrcweir return nCount; 334cdf0e10cSrcweir } 335cdf0e10cSrcweir 336cdf0e10cSrcweir Reference<XAccessible> SAL_CALL VCLXAccessibleBox::getAccessibleChild (sal_Int32 i) 337cdf0e10cSrcweir throw (IndexOutOfBoundsException, RuntimeException) 338cdf0e10cSrcweir { 339cdf0e10cSrcweir vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 340cdf0e10cSrcweir ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 341cdf0e10cSrcweir 342cdf0e10cSrcweir if (i<0 || i>=getAccessibleChildCount()) 343cdf0e10cSrcweir throw IndexOutOfBoundsException(); 344cdf0e10cSrcweir 345cdf0e10cSrcweir Reference< XAccessible > xChild; 346cdf0e10cSrcweir if (IsValid()) 347cdf0e10cSrcweir { 348cdf0e10cSrcweir if (i==1 || ! m_bHasTextChild) 349cdf0e10cSrcweir { 350cdf0e10cSrcweir // List. 351cdf0e10cSrcweir if ( ! m_xList.is()) 352cdf0e10cSrcweir { 353cdf0e10cSrcweir VCLXAccessibleList* pList = new VCLXAccessibleList ( GetVCLXWindow(), 354cdf0e10cSrcweir (m_aBoxType == LISTBOX ? VCLXAccessibleList::LISTBOX : VCLXAccessibleList::COMBOBOX), 355cdf0e10cSrcweir this); 356cdf0e10cSrcweir pList->SetIndexInParent (i); 357cdf0e10cSrcweir m_xList = pList; 358cdf0e10cSrcweir } 359cdf0e10cSrcweir xChild = m_xList; 360cdf0e10cSrcweir } 361cdf0e10cSrcweir else 362cdf0e10cSrcweir { 363cdf0e10cSrcweir // Text Field. 364cdf0e10cSrcweir if ( ! m_xText.is()) 365cdf0e10cSrcweir { 366cdf0e10cSrcweir if (m_aBoxType==COMBOBOX) 367cdf0e10cSrcweir { 368cdf0e10cSrcweir ComboBox* pComboBox = static_cast<ComboBox*>(GetWindow()); 369cdf0e10cSrcweir if (pComboBox!=NULL && pComboBox->GetSubEdit()!=NULL) 370*21075d77SSteve Yin //Set the edit's acc name the same as parent 371*21075d77SSteve Yin { 372*21075d77SSteve Yin pComboBox->GetSubEdit()->SetAccessibleName(getAccessibleName()); 373cdf0e10cSrcweir m_xText = pComboBox->GetSubEdit()->GetAccessible(); 374*21075d77SSteve Yin } 375cdf0e10cSrcweir } 376cdf0e10cSrcweir else if (m_bIsDropDownBox) 377cdf0e10cSrcweir m_xText = new VCLXAccessibleTextField (GetVCLXWindow(),this); 378cdf0e10cSrcweir } 379cdf0e10cSrcweir xChild = m_xText; 380cdf0e10cSrcweir } 381cdf0e10cSrcweir } 382cdf0e10cSrcweir 383cdf0e10cSrcweir return xChild; 384cdf0e10cSrcweir } 385cdf0e10cSrcweir 386cdf0e10cSrcweir sal_Int16 SAL_CALL VCLXAccessibleBox::getAccessibleRole (void) throw (RuntimeException) 387cdf0e10cSrcweir { 388cdf0e10cSrcweir ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 389cdf0e10cSrcweir 390cdf0e10cSrcweir // Return the role <const>COMBO_BOX</const> for both VCL combo boxes and 391cdf0e10cSrcweir // VCL list boxes in DropDown-Mode else <const>PANEL</const>. 392cdf0e10cSrcweir // This way the Java bridge has not to handle both independently. 393*21075d77SSteve Yin //return m_bIsDropDownBox ? AccessibleRole::COMBO_BOX : AccessibleRole::PANEL; 394*21075d77SSteve Yin if (m_bIsDropDownBox || (!m_bIsDropDownBox && m_aBoxType == COMBOBOX )) 395*21075d77SSteve Yin return AccessibleRole::COMBO_BOX; 396*21075d77SSteve Yin else 397*21075d77SSteve Yin return AccessibleRole::PANEL; 398cdf0e10cSrcweir } 399cdf0e10cSrcweir 400cdf0e10cSrcweir sal_Int32 SAL_CALL VCLXAccessibleBox::getAccessibleIndexInParent (void) 401cdf0e10cSrcweir throw (::com::sun::star::uno::RuntimeException) 402cdf0e10cSrcweir { 403cdf0e10cSrcweir if (m_nIndexInParent != DEFAULT_INDEX_IN_PARENT) 404cdf0e10cSrcweir return m_nIndexInParent; 405cdf0e10cSrcweir else 406cdf0e10cSrcweir return VCLXAccessibleComponent::getAccessibleIndexInParent(); 407cdf0e10cSrcweir } 408cdf0e10cSrcweir 409cdf0e10cSrcweir //===== XAccessibleAction =================================================== 410cdf0e10cSrcweir 411cdf0e10cSrcweir sal_Int32 SAL_CALL VCLXAccessibleBox::getAccessibleActionCount (void) 412cdf0e10cSrcweir throw (RuntimeException) 413cdf0e10cSrcweir { 414cdf0e10cSrcweir ::osl::Guard< ::osl::Mutex> aGuard (GetMutex()); 415cdf0e10cSrcweir 416cdf0e10cSrcweir // There is one action for drop down boxes (toggle popup) and none for 417cdf0e10cSrcweir // the other boxes. 418*21075d77SSteve Yin return m_bIsDropDownBox ? 0 : 1; 419cdf0e10cSrcweir } 420cdf0e10cSrcweir 421cdf0e10cSrcweir sal_Bool SAL_CALL VCLXAccessibleBox::doAccessibleAction (sal_Int32 nIndex) 422cdf0e10cSrcweir throw (IndexOutOfBoundsException, RuntimeException) 423cdf0e10cSrcweir { 424cdf0e10cSrcweir sal_Bool bNotify = sal_False; 425cdf0e10cSrcweir 426cdf0e10cSrcweir { 427cdf0e10cSrcweir vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 428cdf0e10cSrcweir ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 429cdf0e10cSrcweir 430cdf0e10cSrcweir if (nIndex<0 || nIndex>=getAccessibleActionCount()) 431cdf0e10cSrcweir throw ::com::sun::star::lang::IndexOutOfBoundsException(); 432cdf0e10cSrcweir 433cdf0e10cSrcweir if (m_aBoxType == COMBOBOX) 434cdf0e10cSrcweir { 435cdf0e10cSrcweir ComboBox* pComboBox = static_cast< ComboBox* >( GetWindow() ); 436cdf0e10cSrcweir if (pComboBox != NULL) 437cdf0e10cSrcweir { 438cdf0e10cSrcweir pComboBox->ToggleDropDown(); 439cdf0e10cSrcweir bNotify = sal_True; 440cdf0e10cSrcweir } 441cdf0e10cSrcweir } 442cdf0e10cSrcweir else if (m_aBoxType == LISTBOX) 443cdf0e10cSrcweir { 444cdf0e10cSrcweir ListBox* pListBox = static_cast< ListBox* >( GetWindow() ); 445cdf0e10cSrcweir if (pListBox != NULL) 446cdf0e10cSrcweir { 447cdf0e10cSrcweir pListBox->ToggleDropDown(); 448cdf0e10cSrcweir bNotify = sal_True; 449cdf0e10cSrcweir } 450cdf0e10cSrcweir } 451cdf0e10cSrcweir } 452cdf0e10cSrcweir 453cdf0e10cSrcweir if (bNotify) 454cdf0e10cSrcweir NotifyAccessibleEvent (AccessibleEventId::ACTION_CHANGED, Any(), Any()); 455cdf0e10cSrcweir 456cdf0e10cSrcweir return bNotify; 457cdf0e10cSrcweir } 458cdf0e10cSrcweir 459cdf0e10cSrcweir ::rtl::OUString SAL_CALL VCLXAccessibleBox::getAccessibleActionDescription (sal_Int32 nIndex) 460cdf0e10cSrcweir throw (IndexOutOfBoundsException, RuntimeException) 461cdf0e10cSrcweir { 462cdf0e10cSrcweir ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 463cdf0e10cSrcweir if (nIndex<0 || nIndex>=getAccessibleActionCount()) 464cdf0e10cSrcweir throw ::com::sun::star::lang::IndexOutOfBoundsException(); 465*21075d77SSteve Yin //Solution:When combo_box,it should not has action information. 466*21075d77SSteve Yin //return TK_RES_STRING( RID_STR_ACC_ACTION_TOGGLEPOPUP); 467*21075d77SSteve Yin if (m_aBoxType == LISTBOX) 468*21075d77SSteve Yin return ::rtl::OUString(); 469*21075d77SSteve Yin return m_bIsDropDownBox?::rtl::OUString():TK_RES_STRING( RID_STR_ACC_ACTION_TOGGLEPOPUP); 470cdf0e10cSrcweir } 471cdf0e10cSrcweir 472cdf0e10cSrcweir Reference< XAccessibleKeyBinding > VCLXAccessibleBox::getAccessibleActionKeyBinding( sal_Int32 nIndex ) 473cdf0e10cSrcweir throw (IndexOutOfBoundsException, RuntimeException) 474cdf0e10cSrcweir { 475cdf0e10cSrcweir ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 476cdf0e10cSrcweir 477cdf0e10cSrcweir Reference< XAccessibleKeyBinding > xRet; 478cdf0e10cSrcweir 479cdf0e10cSrcweir if (nIndex<0 || nIndex>=getAccessibleActionCount()) 480cdf0e10cSrcweir throw ::com::sun::star::lang::IndexOutOfBoundsException(); 481cdf0e10cSrcweir 482cdf0e10cSrcweir // ... which key? 483cdf0e10cSrcweir return xRet; 484cdf0e10cSrcweir } 485cdf0e10cSrcweir 486cdf0e10cSrcweir //===== XComponent ========================================================== 487cdf0e10cSrcweir 488cdf0e10cSrcweir void SAL_CALL VCLXAccessibleBox::disposing (void) 489cdf0e10cSrcweir { 490cdf0e10cSrcweir VCLXAccessibleComponent::disposing(); 491cdf0e10cSrcweir } 492cdf0e10cSrcweir 493*21075d77SSteve Yin // ===== XAccessibleValue =============================================== 494*21075d77SSteve Yin Any VCLXAccessibleBox::getCurrentValue( ) 495*21075d77SSteve Yin throw( RuntimeException ) 496*21075d77SSteve Yin { 497*21075d77SSteve Yin vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 498*21075d77SSteve Yin ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 499*21075d77SSteve Yin 500*21075d77SSteve Yin Any aAny; 501*21075d77SSteve Yin if( m_xList.is() && m_xText.is()) 502*21075d77SSteve Yin { 503*21075d77SSteve Yin // VCLXAccessibleList* pList = static_cast<VCLXAccessibleList*>(m_xList.get()); 504*21075d77SSteve Yin Reference<XAccessibleText> xText (m_xText->getAccessibleContext(), UNO_QUERY); 505*21075d77SSteve Yin if ( xText.is() ) 506*21075d77SSteve Yin { 507*21075d77SSteve Yin ::rtl::OUString sText = xText->getText(); 508*21075d77SSteve Yin aAny <<= sText; 509*21075d77SSteve Yin } 510*21075d77SSteve Yin } 511*21075d77SSteve Yin if (m_aBoxType == LISTBOX && m_bIsDropDownBox && m_xList.is() ) 512*21075d77SSteve Yin { 513*21075d77SSteve Yin 514*21075d77SSteve Yin VCLXAccessibleList* pList = static_cast<VCLXAccessibleList*>(m_xList.get()); 515*21075d77SSteve Yin if(pList->IsInDropDown()) 516*21075d77SSteve Yin { 517*21075d77SSteve Yin if(pList->getSelectedAccessibleChildCount()>0) 518*21075d77SSteve Yin { 519*21075d77SSteve Yin Reference<XAccessibleContext> xName (pList->getSelectedAccessibleChild((sal_Int32)(0)), UNO_QUERY); 520*21075d77SSteve Yin if(xName.is()) 521*21075d77SSteve Yin { 522*21075d77SSteve Yin aAny <<= xName->getAccessibleName(); 523*21075d77SSteve Yin } 524*21075d77SSteve Yin } 525*21075d77SSteve Yin } 526*21075d77SSteve Yin } 527*21075d77SSteve Yin 528*21075d77SSteve Yin return aAny; 529*21075d77SSteve Yin } 530*21075d77SSteve Yin 531*21075d77SSteve Yin sal_Bool VCLXAccessibleBox::setCurrentValue( const Any& aNumber ) 532*21075d77SSteve Yin throw( RuntimeException ) 533*21075d77SSteve Yin { 534*21075d77SSteve Yin vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 535*21075d77SSteve Yin ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); 536*21075d77SSteve Yin 537*21075d77SSteve Yin ::rtl::OUString fValue; 538*21075d77SSteve Yin sal_Bool bValid = (aNumber >>= fValue); 539*21075d77SSteve Yin if( bValid ) 540*21075d77SSteve Yin { 541*21075d77SSteve Yin 542*21075d77SSteve Yin } 543*21075d77SSteve Yin return bValid; 544*21075d77SSteve Yin 545*21075d77SSteve Yin } 546*21075d77SSteve Yin 547*21075d77SSteve Yin Any VCLXAccessibleBox::getMaximumValue( ) 548*21075d77SSteve Yin throw( RuntimeException ) 549*21075d77SSteve Yin { 550*21075d77SSteve Yin Any aAny; 551*21075d77SSteve Yin return aAny; 552*21075d77SSteve Yin } 553*21075d77SSteve Yin 554*21075d77SSteve Yin Any VCLXAccessibleBox::getMinimumValue( ) 555*21075d77SSteve Yin throw( RuntimeException ) 556*21075d77SSteve Yin { 557*21075d77SSteve Yin Any aAny; 558*21075d77SSteve Yin return aAny; 559*21075d77SSteve Yin } 560*21075d77SSteve Yin 561*21075d77SSteve Yin // Set the INDETERMINATE state when there is no selected item for combobox 562*21075d77SSteve Yin void VCLXAccessibleBox::FillAccessibleStateSet( utl::AccessibleStateSetHelper& rStateSet ) 563*21075d77SSteve Yin { 564*21075d77SSteve Yin VCLXAccessibleComponent::FillAccessibleStateSet(rStateSet); 565*21075d77SSteve Yin if (m_aBoxType == COMBOBOX ) 566*21075d77SSteve Yin { 567*21075d77SSteve Yin ::rtl::OUString sText; 568*21075d77SSteve Yin sal_Int32 nEntryCount = 0; 569*21075d77SSteve Yin ComboBox* pComboBox = static_cast<ComboBox*>(GetWindow()); 570*21075d77SSteve Yin if (pComboBox != NULL) 571*21075d77SSteve Yin { 572*21075d77SSteve Yin Edit* pSubEdit = pComboBox->GetSubEdit(); 573*21075d77SSteve Yin if ( pSubEdit) 574*21075d77SSteve Yin sText = pSubEdit->GetText(); 575*21075d77SSteve Yin nEntryCount = pComboBox->GetEntryCount(); 576*21075d77SSteve Yin } 577*21075d77SSteve Yin if (sText.getLength() == 0 && nEntryCount >0) 578*21075d77SSteve Yin rStateSet.AddState(AccessibleStateType::INDETERMINATE); 579*21075d77SSteve Yin } 580*21075d77SSteve Yin else if (m_aBoxType == LISTBOX && m_bIsDropDownBox == true) 581*21075d77SSteve Yin { 582*21075d77SSteve Yin sal_Int32 nSelectedEntryCount = 0; 583*21075d77SSteve Yin ListBox* pListBox = static_cast< ListBox* >( GetWindow() ); 584*21075d77SSteve Yin if (pListBox != NULL && pListBox->GetEntryCount() > 0) 585*21075d77SSteve Yin { 586*21075d77SSteve Yin nSelectedEntryCount = pListBox->GetSelectEntryCount(); 587*21075d77SSteve Yin if ( nSelectedEntryCount == 0) 588*21075d77SSteve Yin rStateSet.AddState(AccessibleStateType::INDETERMINATE); 589*21075d77SSteve Yin } 590*21075d77SSteve Yin } 591*21075d77SSteve Yin } 592