1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_accessibility.hxx" 26 #include <accessibility/extended/accessiblelistbox.hxx> 27 #include <accessibility/extended/accessiblelistboxentry.hxx> 28 #include <svtools/svtreebx.hxx> 29 #include <com/sun/star/awt/Point.hpp> 30 #include <com/sun/star/awt/Rectangle.hpp> 31 #include <com/sun/star/awt/Size.hpp> 32 #include <com/sun/star/accessibility/AccessibleEventId.hpp> 33 #include <com/sun/star/accessibility/AccessibleRole.hpp> 34 #include <com/sun/star/accessibility/AccessibleStateType.hpp> 35 #include <tools/debug.hxx> 36 #include <vcl/svapp.hxx> 37 #include <toolkit/awt/vclxwindow.hxx> 38 #include <toolkit/helper/convert.hxx> 39 #include <unotools/accessiblestatesethelper.hxx> 40 41 //........................................................................ 42 namespace accessibility 43 { 44 //........................................................................ 45 46 // class AccessibleListBox ----------------------------------------------------- 47 48 using namespace ::com::sun::star::accessibility; 49 using namespace ::com::sun::star::uno; 50 using namespace ::com::sun::star::lang; 51 using namespace ::com::sun::star; 52 53 DBG_NAME(AccessibleListBox) 54 55 // ----------------------------------------------------------------------------- 56 // Ctor() and Dtor() 57 // ----------------------------------------------------------------------------- 58 AccessibleListBox::AccessibleListBox( SvTreeListBox& _rListBox, const Reference< XAccessible >& _xParent ) : 59 60 VCLXAccessibleComponent( _rListBox.GetWindowPeer() ), 61 m_xParent( _xParent ) 62 { 63 DBG_CTOR( AccessibleListBox, NULL ); 64 } 65 // ----------------------------------------------------------------------------- 66 AccessibleListBox::~AccessibleListBox() 67 { 68 DBG_DTOR( AccessibleListBox, NULL ); 69 if ( isAlive() ) 70 { 71 // increment ref count to prevent double call of Dtor 72 osl_incrementInterlockedCount( &m_refCount ); 73 dispose(); 74 } 75 } 76 IMPLEMENT_FORWARD_XINTERFACE2(AccessibleListBox, VCLXAccessibleComponent, AccessibleListBox_BASE) 77 IMPLEMENT_FORWARD_XTYPEPROVIDER2(AccessibleListBox, VCLXAccessibleComponent, AccessibleListBox_BASE) 78 // ----------------------------------------------------------------------------- 79 SvTreeListBox* AccessibleListBox::getListBox() const 80 { 81 return static_cast< SvTreeListBox* >( const_cast<AccessibleListBox*>(this)->GetWindow() ); 82 } 83 // ----------------------------------------------------------------------------- 84 void AccessibleListBox::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) 85 { 86 if ( isAlive() ) 87 { 88 switch ( rVclWindowEvent.GetId() ) 89 { 90 case VCLEVENT_CHECKBOX_TOGGLE : 91 { 92 if ( !getListBox() || !getListBox()->HasFocus() ) 93 { 94 return; 95 } 96 AccessibleListBoxEntry* pCurOpEntry = GetCurEventEntry(rVclWindowEvent); 97 if(!pCurOpEntry) 98 { 99 return ; 100 } 101 uno::Any aValue; 102 aValue <<= AccessibleStateType::CHECKED; 103 104 if ( getListBox()->GetCheckButtonState( pCurOpEntry->GetSvLBoxEntry() ) == SV_BUTTON_CHECKED ) 105 { 106 pCurOpEntry->NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, uno::Any(), aValue ); 107 } 108 else 109 { 110 pCurOpEntry->NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aValue,uno::Any() ); 111 } 112 break; 113 } 114 115 case VCLEVENT_LISTBOX_SELECT : 116 { 117 // First send an event that tells the listeners of a 118 // modified selection. The active descendant event is 119 // send after that so that the receiving AT has time to 120 // read the text or name of the active child. 121 // NotifyAccessibleEvent( AccessibleEventId::SELECTION_CHANGED, Any(), Any() ); 122 OSL_ASSERT(0 && "Debug: Treelist shouldn't use VCLEVENT_LISTBOX_SELECT"); 123 } 124 case VCLEVENT_LISTBOX_TREESELECT: 125 { 126 if ( getListBox() && getListBox()->HasFocus() ) 127 { 128 AccessibleListBoxEntry* pEntry =static_cast< AccessibleListBoxEntry* >(m_xFocusedChild.get()); 129 if (pEntry) 130 { 131 pEntry->NotifyAccessibleEvent( AccessibleEventId::SELECTION_CHANGED, Any(), Any() ); 132 } 133 } 134 } 135 break; 136 case VCLEVENT_LISTBOX_TREEFOCUS: 137 { 138 SvTreeListBox* pBox = getListBox(); 139 sal_Bool bNeedFocus = sal_False; 140 if (pBox) 141 { 142 Window* pParent = ((Window*)pBox)->GetParent(); 143 if (pParent && pParent->GetType() == WINDOW_FLOATINGWINDOW) 144 { 145 // MT: ImplGetAppSVData shouldn't be exported from VCL. 146 // In which scenario is this needed? 147 // If needed, we need to find an other solution 148 /* 149 ImplSVData* pSVData = ImplGetAppSVData(); 150 if (pSVData && pSVData->maWinData.mpFirstFloat == (FloatingWindow*)pParent) 151 bNeedFocus = sal_True; 152 */ 153 } 154 } 155 if( pBox && (pBox->HasFocus() || bNeedFocus) ) 156 { 157 uno::Any aOldValue, aNewValue; 158 SvLBoxEntry* pEntry = static_cast< SvLBoxEntry* >( rVclWindowEvent.GetData() ); 159 if ( pEntry ) 160 { 161 AccessibleListBoxEntry* pEntryFocus =static_cast< AccessibleListBoxEntry* >(m_xFocusedChild.get()); 162 if (pEntryFocus && pEntryFocus->GetSvLBoxEntry() == pEntry) 163 { 164 aOldValue <<= uno::Any(); 165 aNewValue <<= m_xFocusedChild; 166 NotifyAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, aOldValue, aNewValue ); 167 return ; 168 } 169 170 aOldValue <<= m_xFocusedChild; 171 172 MAP_ENTRY::iterator mi = m_mapEntry.find(pEntry); 173 if(mi != m_mapEntry.end()) 174 { 175 OSL_ASSERT(mi->second.get() != NULL); 176 m_xFocusedChild = mi->second; 177 } 178 else 179 { 180 AccessibleListBoxEntry *pEntNew = new AccessibleListBoxEntry( *getListBox(), pEntry, NULL ); 181 m_xFocusedChild = pEntNew; 182 m_mapEntry.insert(MAP_ENTRY::value_type(pEntry,pEntNew)); 183 } 184 185 aNewValue <<= m_xFocusedChild; 186 NotifyAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, aOldValue, aNewValue ); 187 } 188 else 189 { 190 aOldValue <<= uno::Any(); 191 aNewValue <<= AccessibleStateType::FOCUSED; 192 NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); 193 } 194 } 195 } 196 break; 197 case VCLEVENT_LISTBOX_ITEMREMOVED: 198 { 199 SvLBoxEntry* pEntry = static_cast< SvLBoxEntry* >( rVclWindowEvent.GetData() ); 200 if ( pEntry ) 201 { 202 RemoveChildEntries(pEntry); 203 } 204 else 205 { 206 // NULL means Clear() 207 MAP_ENTRY::iterator mi = m_mapEntry.begin(); 208 for ( ; mi != m_mapEntry.end() ; ++mi) 209 { 210 uno::Any aNewValue; 211 uno::Any aOldValue; 212 aOldValue <<= mi->second; 213 NotifyAccessibleEvent( AccessibleEventId::CHILD, aOldValue, aNewValue ); 214 } 215 m_mapEntry.clear(); 216 } 217 218 219 } 220 break; 221 222 // --> OD 2009-04-01 #i92103# 223 case VCLEVENT_ITEM_EXPANDED : 224 case VCLEVENT_ITEM_COLLAPSED : 225 { 226 SvLBoxEntry* pEntry = static_cast< SvLBoxEntry* >( rVclWindowEvent.GetData() ); 227 if ( pEntry ) 228 { 229 AccessibleListBoxEntry* pAccListBoxEntry = 230 new AccessibleListBoxEntry( *getListBox(), pEntry, this ); 231 Reference< XAccessible > xChild = pAccListBoxEntry; 232 const short nAccEvent = 233 ( rVclWindowEvent.GetId() == VCLEVENT_ITEM_EXPANDED ) 234 ? AccessibleEventId::LISTBOX_ENTRY_EXPANDED 235 : AccessibleEventId::LISTBOX_ENTRY_COLLAPSED; 236 uno::Any aListBoxEntry; 237 aListBoxEntry <<= xChild; 238 NotifyAccessibleEvent( nAccEvent, Any(), aListBoxEntry ); 239 if ( getListBox() && getListBox()->HasFocus() ) 240 { 241 NotifyAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, Any(), aListBoxEntry ); 242 } 243 } 244 } 245 break; 246 // <-- 247 default: 248 VCLXAccessibleComponent::ProcessWindowEvent (rVclWindowEvent); 249 } 250 } 251 } 252 253 AccessibleListBoxEntry* AccessibleListBox::GetCurEventEntry( const VclWindowEvent& rVclWindowEvent ) 254 { 255 SvLBoxEntry* pEntry = static_cast< SvLBoxEntry* >( rVclWindowEvent.GetData() ); 256 if ( !pEntry ) 257 pEntry = getListBox()->GetCurEntry(); 258 259 AccessibleListBoxEntry* pEntryFocus =static_cast< AccessibleListBoxEntry* >(m_xFocusedChild.get()); 260 if (pEntryFocus && pEntry && pEntry != pEntryFocus->GetSvLBoxEntry()) 261 { 262 AccessibleListBoxEntry *pAccCurOptionEntry =NULL; 263 MAP_ENTRY::iterator mi = m_mapEntry.find(pEntry); 264 if (mi != m_mapEntry.end()) 265 { 266 pAccCurOptionEntry= static_cast< AccessibleListBoxEntry* >(mi->second.get()); 267 } 268 else 269 { 270 pAccCurOptionEntry =new AccessibleListBoxEntry( *getListBox(), pEntry, NULL ); 271 std::pair<MAP_ENTRY::iterator, bool> pairMi = m_mapEntry.insert(MAP_ENTRY::value_type(pAccCurOptionEntry->GetSvLBoxEntry(),pAccCurOptionEntry)); 272 mi = pairMi.first; 273 } 274 275 uno::Any aNewValue; 276 aNewValue <<= mi->second;//xAcc 277 NotifyAccessibleEvent( AccessibleEventId::CHILD, uno::Any(), aNewValue );//Add 278 279 return pAccCurOptionEntry; 280 } 281 else 282 { 283 return pEntryFocus; 284 } 285 return NULL; 286 } 287 288 void AccessibleListBox::RemoveChildEntries(SvLBoxEntry* pEntry) 289 { 290 MAP_ENTRY::iterator mi = m_mapEntry.find(pEntry); 291 if ( mi != m_mapEntry.end() ) 292 { 293 uno::Any aNewValue; 294 uno::Any aOldValue; 295 aOldValue <<= mi->second; 296 NotifyAccessibleEvent( AccessibleEventId::CHILD, aOldValue, aNewValue ); 297 298 m_mapEntry.erase(mi); 299 } 300 301 SvTreeListBox* pBox = getListBox(); 302 SvLBoxEntry* pEntryChild = pBox->FirstChild(pEntry); 303 while (pEntryChild) 304 { 305 RemoveChildEntries(pEntryChild); 306 pEntryChild = pBox->NextSibling(pEntryChild); 307 } 308 } 309 310 // ----------------------------------------------------------------------------- 311 void AccessibleListBox::ProcessWindowChildEvent( const VclWindowEvent& rVclWindowEvent ) 312 { 313 switch ( rVclWindowEvent.GetId() ) 314 { 315 case VCLEVENT_WINDOW_SHOW: 316 case VCLEVENT_WINDOW_HIDE: 317 { 318 } 319 break; 320 default: 321 { 322 VCLXAccessibleComponent::ProcessWindowChildEvent( rVclWindowEvent ); 323 } 324 break; 325 } 326 } 327 328 // ----------------------------------------------------------------------------- 329 // XComponent 330 // ----------------------------------------------------------------------------- 331 void SAL_CALL AccessibleListBox::disposing() 332 { 333 ::osl::MutexGuard aGuard( m_aMutex ); 334 335 m_mapEntry.clear(); 336 VCLXAccessibleComponent::disposing(); 337 m_xParent = NULL; 338 } 339 // ----------------------------------------------------------------------------- 340 // XServiceInfo 341 // ----------------------------------------------------------------------------- 342 ::rtl::OUString SAL_CALL AccessibleListBox::getImplementationName() throw(RuntimeException) 343 { 344 return getImplementationName_Static(); 345 } 346 // ----------------------------------------------------------------------------- 347 Sequence< ::rtl::OUString > SAL_CALL AccessibleListBox::getSupportedServiceNames() throw(RuntimeException) 348 { 349 return getSupportedServiceNames_Static(); 350 } 351 // ----------------------------------------------------------------------------- 352 sal_Bool SAL_CALL AccessibleListBox::supportsService( const ::rtl::OUString& _rServiceName ) throw (RuntimeException) 353 { 354 Sequence< ::rtl::OUString > aSupported( getSupportedServiceNames() ); 355 const ::rtl::OUString* pSupported = aSupported.getConstArray(); 356 const ::rtl::OUString* pEnd = pSupported + aSupported.getLength(); 357 for ( ; pSupported != pEnd && !pSupported->equals(_rServiceName); ++pSupported ) 358 ; 359 360 return pSupported != pEnd; 361 } 362 // ----------------------------------------------------------------------------- 363 // XServiceInfo - static methods 364 // ----------------------------------------------------------------------------- 365 Sequence< ::rtl::OUString > AccessibleListBox::getSupportedServiceNames_Static(void) throw( RuntimeException ) 366 { 367 Sequence< ::rtl::OUString > aSupported(3); 368 aSupported[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.accessibility.AccessibleContext") ); 369 aSupported[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.accessibility.AccessibleComponent") ); 370 aSupported[2] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.AccessibleTreeListBox") ); 371 return aSupported; 372 } 373 // ----------------------------------------------------------------------------- 374 ::rtl::OUString AccessibleListBox::getImplementationName_Static(void) throw( RuntimeException ) 375 { 376 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.svtools.AccessibleTreeListBox") ); 377 } 378 // ----------------------------------------------------------------------------- 379 // XAccessible 380 // ----------------------------------------------------------------------------- 381 Reference< XAccessibleContext > SAL_CALL AccessibleListBox::getAccessibleContext( ) throw (RuntimeException) 382 { 383 ensureAlive(); 384 return this; 385 } 386 // ----------------------------------------------------------------------------- 387 // XAccessibleContext 388 // ----------------------------------------------------------------------------- 389 sal_Int32 SAL_CALL AccessibleListBox::getAccessibleChildCount( ) throw (RuntimeException) 390 { 391 ::comphelper::OExternalLockGuard aGuard( this ); 392 393 ensureAlive(); 394 395 sal_Int32 nCount = 0; 396 SvTreeListBox* pSvTreeListBox = getListBox(); 397 if ( pSvTreeListBox ) 398 nCount = pSvTreeListBox->GetLevelChildCount( NULL ); 399 400 return nCount; 401 } 402 // ----------------------------------------------------------------------------- 403 Reference< XAccessible > SAL_CALL AccessibleListBox::getAccessibleChild( sal_Int32 i ) throw (IndexOutOfBoundsException,RuntimeException) 404 { 405 ::comphelper::OExternalLockGuard aGuard( this ); 406 407 ensureAlive(); 408 SvLBoxEntry* pEntry = getListBox()->GetEntry(i); 409 if ( !pEntry ) 410 throw IndexOutOfBoundsException(); 411 412 // Solution: Set the parameter of the parent to null to let entry determine the parent by itself 413 //return new AccessibleListBoxEntry( *getListBox(), pEntry, this ); 414 return new AccessibleListBoxEntry( *getListBox(), pEntry, NULL ); 415 } 416 // ----------------------------------------------------------------------------- 417 Reference< XAccessible > SAL_CALL AccessibleListBox::getAccessibleParent( ) throw (RuntimeException) 418 { 419 ::osl::MutexGuard aGuard( m_aMutex ); 420 421 ensureAlive(); 422 return m_xParent; 423 } 424 // ----------------------------------------------------------------------------- 425 sal_Int32 SAL_CALL AccessibleListBox::getRoleType() 426 { 427 sal_Int32 nCase = 0; 428 SvLBoxEntry* pEntry = getListBox()->GetEntry(0); 429 if ( pEntry ) 430 { 431 if( pEntry->HasChildsOnDemand() || getListBox()->GetChildCount(pEntry) > 0 ) 432 //end add by duan mei hua, 2007/01/27, for sodc_6862 433 { 434 nCase = 1; 435 return nCase; 436 } 437 } 438 439 sal_Bool bHasButtons = (getListBox()->GetStyle() & WB_HASBUTTONS)!=0; 440 if( !(getListBox()->GetTreeFlags() & TREEFLAG_CHKBTN) ) 441 { 442 if( bHasButtons ) 443 nCase = 1; 444 } 445 else 446 { 447 if( bHasButtons ) 448 nCase = 2; 449 else 450 nCase = 3; 451 } 452 return nCase; 453 } 454 sal_Int16 SAL_CALL AccessibleListBox::getAccessibleRole( ) throw (RuntimeException) 455 { 456 if(getListBox()) 457 { 458 short nType = getListBox()->GetAllEntriesAccessibleRoleType(); 459 if( nType == TREEBOX_ALLITEM_ACCROLE_TYPE_TREE) 460 return AccessibleRole::TREE; 461 else if( nType == TREEBOX_ALLITEM_ACCROLE_TYPE_LIST) 462 return AccessibleRole::LIST; 463 } 464 465 //o is: return AccessibleRole::TREE; 466 sal_Bool bHasButtons = (getListBox()->GetStyle() & WB_HASBUTTONS)!=0; 467 if(!bHasButtons && (getListBox()->GetTreeFlags() & TREEFLAG_CHKBTN)) 468 return AccessibleRole::LIST; 469 else 470 if(getRoleType() == 0) 471 return AccessibleRole::LIST; 472 else 473 return AccessibleRole::TREE; 474 } 475 // ----------------------------------------------------------------------------- 476 ::rtl::OUString SAL_CALL AccessibleListBox::getAccessibleDescription( ) throw (RuntimeException) 477 { 478 ::comphelper::OExternalLockGuard aGuard( this ); 479 480 ensureAlive(); 481 return getListBox()->GetAccessibleDescription(); 482 } 483 // ----------------------------------------------------------------------------- 484 ::rtl::OUString SAL_CALL AccessibleListBox::getAccessibleName( ) throw (RuntimeException) 485 { 486 ::comphelper::OExternalLockGuard aGuard( this ); 487 488 ensureAlive(); 489 return getListBox()->GetAccessibleName(); 490 } 491 // ----------------------------------------------------------------------------- 492 // XAccessibleSelection 493 // ----------------------------------------------------------------------------- 494 void SAL_CALL AccessibleListBox::selectAccessibleChild( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) 495 { 496 ::comphelper::OExternalLockGuard aGuard( this ); 497 498 ensureAlive(); 499 500 SvLBoxEntry* pEntry = getListBox()->GetEntry( nChildIndex ); 501 if ( !pEntry ) 502 throw IndexOutOfBoundsException(); 503 504 getListBox()->Select( pEntry, sal_True ); 505 } 506 // ----------------------------------------------------------------------------- 507 sal_Bool SAL_CALL AccessibleListBox::isAccessibleChildSelected( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) 508 { 509 ::comphelper::OExternalLockGuard aGuard( this ); 510 511 ensureAlive(); 512 513 SvLBoxEntry* pEntry = getListBox()->GetEntry( nChildIndex ); 514 if ( !pEntry ) 515 throw IndexOutOfBoundsException(); 516 517 return getListBox()->IsSelected( pEntry ); 518 } 519 // ----------------------------------------------------------------------------- 520 void SAL_CALL AccessibleListBox::clearAccessibleSelection( ) throw (RuntimeException) 521 { 522 ::comphelper::OExternalLockGuard aGuard( this ); 523 524 ensureAlive(); 525 526 sal_Int32 i, nCount = 0; 527 nCount = getListBox()->GetLevelChildCount( NULL ); 528 for ( i = 0; i < nCount; ++i ) 529 { 530 SvLBoxEntry* pEntry = getListBox()->GetEntry( i ); 531 if ( getListBox()->IsSelected( pEntry ) ) 532 getListBox()->Select( pEntry, sal_False ); 533 } 534 } 535 // ----------------------------------------------------------------------------- 536 void SAL_CALL AccessibleListBox::selectAllAccessibleChildren( ) throw (RuntimeException) 537 { 538 ::comphelper::OExternalLockGuard aGuard( this ); 539 540 ensureAlive(); 541 542 sal_Int32 i, nCount = 0; 543 nCount = getListBox()->GetLevelChildCount( NULL ); 544 for ( i = 0; i < nCount; ++i ) 545 { 546 SvLBoxEntry* pEntry = getListBox()->GetEntry( i ); 547 if ( !getListBox()->IsSelected( pEntry ) ) 548 getListBox()->Select( pEntry, sal_True ); 549 } 550 } 551 // ----------------------------------------------------------------------------- 552 sal_Int32 SAL_CALL AccessibleListBox::getSelectedAccessibleChildCount( ) throw (RuntimeException) 553 { 554 ::comphelper::OExternalLockGuard aGuard( this ); 555 556 ensureAlive(); 557 558 559 // sal_Int32 i, nSelCount = 0, nCount = 0; 560 // nCount = getListBox()->GetLevelChildCount( NULL ); 561 // for ( i = 0; i < nCount; ++i ) 562 // { 563 // SvLBoxEntry* pEntry = getListBox()->GetEntry( i ); 564 // if ( getListBox()->IsSelected( pEntry ) ) 565 // ++nSelCount; 566 // } 567 // return nSelCount; 568 569 int nTestCount = getListBox()->GetSelectionCount(); 570 return nTestCount; 571 } 572 // ----------------------------------------------------------------------------- 573 Reference< XAccessible > SAL_CALL AccessibleListBox::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) 574 { 575 ::comphelper::OExternalLockGuard aGuard( this ); 576 577 ensureAlive(); 578 579 if ( nSelectedChildIndex < 0 || nSelectedChildIndex >= getSelectedAccessibleChildCount() ) 580 throw IndexOutOfBoundsException(); 581 582 Reference< XAccessible > xChild; 583 sal_Int32 i, nSelCount = 0, nCount = 0; 584 nCount = getListBox()->GetLevelChildCount( NULL ); 585 for ( i = 0; i < nCount; ++i ) 586 { 587 SvLBoxEntry* pEntry = getListBox()->GetEntry( i ); 588 if ( getListBox()->IsSelected( pEntry ) ) 589 ++nSelCount; 590 591 if ( nSelCount == ( nSelectedChildIndex + 1 ) ) 592 { 593 // Solution: Set the parameter of the parent to null to let entry determine the parent by itself 594 //xChild = new AccessibleListBoxEntry( *getListBox(), pEntry, this ); 595 xChild = new AccessibleListBoxEntry( *getListBox(), pEntry, NULL ); 596 break; 597 } 598 } 599 600 return xChild; 601 } 602 // ----------------------------------------------------------------------------- 603 void SAL_CALL AccessibleListBox::deselectAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) 604 { 605 ::comphelper::OExternalLockGuard aGuard( this ); 606 607 ensureAlive(); 608 609 SvLBoxEntry* pEntry = getListBox()->GetEntry( nSelectedChildIndex ); 610 if ( !pEntry ) 611 throw IndexOutOfBoundsException(); 612 613 getListBox()->Select( pEntry, sal_False ); 614 } 615 // ----------------------------------------------------------------------------- 616 void AccessibleListBox::FillAccessibleStateSet( utl::AccessibleStateSetHelper& rStateSet ) 617 { 618 VCLXAccessibleComponent::FillAccessibleStateSet( rStateSet ); 619 if ( getListBox() && isAlive() ) 620 { 621 rStateSet.AddState( AccessibleStateType::FOCUSABLE ); 622 rStateSet.AddState( AccessibleStateType::MANAGES_DESCENDANTS ); 623 if ( getListBox()->GetSelectionMode() == MULTIPLE_SELECTION ) 624 rStateSet.AddState( AccessibleStateType::MULTI_SELECTABLE ); 625 } 626 } 627 628 629 //........................................................................ 630 }// namespace accessibility 631 //........................................................................ 632 633