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 DBG_NAME(AccessibleListBox)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 // ----------------------------------------------------------------------------- ~AccessibleListBox()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 } IMPLEMENT_FORWARD_XINTERFACE2(AccessibleListBox,VCLXAccessibleComponent,AccessibleListBox_BASE)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 // ----------------------------------------------------------------------------- ProcessWindowEvent(const VclWindowEvent & rVclWindowEvent)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 GetCurEventEntry(const VclWindowEvent & rVclWindowEvent)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 RemoveChildEntries(SvLBoxEntry * pEntry)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 // ----------------------------------------------------------------------------- ProcessWindowChildEvent(const VclWindowEvent & rVclWindowEvent)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 // ----------------------------------------------------------------------------- disposing()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 // ----------------------------------------------------------------------------- getImplementationName()342 ::rtl::OUString SAL_CALL AccessibleListBox::getImplementationName() throw(RuntimeException) 343 { 344 return getImplementationName_Static(); 345 } 346 // ----------------------------------------------------------------------------- getSupportedServiceNames()347 Sequence< ::rtl::OUString > SAL_CALL AccessibleListBox::getSupportedServiceNames() throw(RuntimeException) 348 { 349 return getSupportedServiceNames_Static(); 350 } 351 // ----------------------------------------------------------------------------- supportsService(const::rtl::OUString & _rServiceName)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 // ----------------------------------------------------------------------------- getSupportedServiceNames_Static(void)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 // ----------------------------------------------------------------------------- getImplementationName_Static(void)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 // ----------------------------------------------------------------------------- getAccessibleContext()381 Reference< XAccessibleContext > SAL_CALL AccessibleListBox::getAccessibleContext( ) throw (RuntimeException) 382 { 383 ensureAlive(); 384 return this; 385 } 386 // ----------------------------------------------------------------------------- 387 // XAccessibleContext 388 // ----------------------------------------------------------------------------- getAccessibleChildCount()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 // ----------------------------------------------------------------------------- getAccessibleChild(sal_Int32 i)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 // ----------------------------------------------------------------------------- getAccessibleParent()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 // ----------------------------------------------------------------------------- getRoleType()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 { 433 nCase = 1; 434 return nCase; 435 } 436 } 437 438 sal_Bool bHasButtons = (getListBox()->GetStyle() & WB_HASBUTTONS)!=0; 439 if( !(getListBox()->GetTreeFlags() & TREEFLAG_CHKBTN) ) 440 { 441 if( bHasButtons ) 442 nCase = 1; 443 } 444 else 445 { 446 if( bHasButtons ) 447 nCase = 2; 448 else 449 nCase = 3; 450 } 451 return nCase; 452 } getAccessibleRole()453 sal_Int16 SAL_CALL AccessibleListBox::getAccessibleRole( ) throw (RuntimeException) 454 { 455 if(getListBox()) 456 { 457 short nType = getListBox()->GetAllEntriesAccessibleRoleType(); 458 if( nType == TREEBOX_ALLITEM_ACCROLE_TYPE_TREE) 459 return AccessibleRole::TREE; 460 else if( nType == TREEBOX_ALLITEM_ACCROLE_TYPE_LIST) 461 return AccessibleRole::LIST; 462 } 463 464 //o is: return AccessibleRole::TREE; 465 sal_Bool bHasButtons = (getListBox()->GetStyle() & WB_HASBUTTONS)!=0; 466 if(!bHasButtons && (getListBox()->GetTreeFlags() & TREEFLAG_CHKBTN)) 467 return AccessibleRole::LIST; 468 else 469 if(getRoleType() == 0) 470 return AccessibleRole::LIST; 471 else 472 return AccessibleRole::TREE; 473 } 474 // ----------------------------------------------------------------------------- getAccessibleDescription()475 ::rtl::OUString SAL_CALL AccessibleListBox::getAccessibleDescription( ) throw (RuntimeException) 476 { 477 ::comphelper::OExternalLockGuard aGuard( this ); 478 479 ensureAlive(); 480 return getListBox()->GetAccessibleDescription(); 481 } 482 // ----------------------------------------------------------------------------- getAccessibleName()483 ::rtl::OUString SAL_CALL AccessibleListBox::getAccessibleName( ) throw (RuntimeException) 484 { 485 ::comphelper::OExternalLockGuard aGuard( this ); 486 487 ensureAlive(); 488 return getListBox()->GetAccessibleName(); 489 } 490 // ----------------------------------------------------------------------------- 491 // XAccessibleSelection 492 // ----------------------------------------------------------------------------- selectAccessibleChild(sal_Int32 nChildIndex)493 void SAL_CALL AccessibleListBox::selectAccessibleChild( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) 494 { 495 ::comphelper::OExternalLockGuard aGuard( this ); 496 497 ensureAlive(); 498 499 SvLBoxEntry* pEntry = getListBox()->GetEntry( nChildIndex ); 500 if ( !pEntry ) 501 throw IndexOutOfBoundsException(); 502 503 getListBox()->Select( pEntry, sal_True ); 504 } 505 // ----------------------------------------------------------------------------- isAccessibleChildSelected(sal_Int32 nChildIndex)506 sal_Bool SAL_CALL AccessibleListBox::isAccessibleChildSelected( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) 507 { 508 ::comphelper::OExternalLockGuard aGuard( this ); 509 510 ensureAlive(); 511 512 SvLBoxEntry* pEntry = getListBox()->GetEntry( nChildIndex ); 513 if ( !pEntry ) 514 throw IndexOutOfBoundsException(); 515 516 return getListBox()->IsSelected( pEntry ); 517 } 518 // ----------------------------------------------------------------------------- clearAccessibleSelection()519 void SAL_CALL AccessibleListBox::clearAccessibleSelection( ) throw (RuntimeException) 520 { 521 ::comphelper::OExternalLockGuard aGuard( this ); 522 523 ensureAlive(); 524 525 sal_Int32 i, nCount = 0; 526 nCount = getListBox()->GetLevelChildCount( NULL ); 527 for ( i = 0; i < nCount; ++i ) 528 { 529 SvLBoxEntry* pEntry = getListBox()->GetEntry( i ); 530 if ( getListBox()->IsSelected( pEntry ) ) 531 getListBox()->Select( pEntry, sal_False ); 532 } 533 } 534 // ----------------------------------------------------------------------------- selectAllAccessibleChildren()535 void SAL_CALL AccessibleListBox::selectAllAccessibleChildren( ) throw (RuntimeException) 536 { 537 ::comphelper::OExternalLockGuard aGuard( this ); 538 539 ensureAlive(); 540 541 sal_Int32 i, nCount = 0; 542 nCount = getListBox()->GetLevelChildCount( NULL ); 543 for ( i = 0; i < nCount; ++i ) 544 { 545 SvLBoxEntry* pEntry = getListBox()->GetEntry( i ); 546 if ( !getListBox()->IsSelected( pEntry ) ) 547 getListBox()->Select( pEntry, sal_True ); 548 } 549 } 550 // ----------------------------------------------------------------------------- getSelectedAccessibleChildCount()551 sal_Int32 SAL_CALL AccessibleListBox::getSelectedAccessibleChildCount( ) throw (RuntimeException) 552 { 553 ::comphelper::OExternalLockGuard aGuard( this ); 554 555 ensureAlive(); 556 557 558 // sal_Int32 i, nSelCount = 0, nCount = 0; 559 // nCount = getListBox()->GetLevelChildCount( NULL ); 560 // for ( i = 0; i < nCount; ++i ) 561 // { 562 // SvLBoxEntry* pEntry = getListBox()->GetEntry( i ); 563 // if ( getListBox()->IsSelected( pEntry ) ) 564 // ++nSelCount; 565 // } 566 // return nSelCount; 567 568 int nTestCount = getListBox()->GetSelectionCount(); 569 return nTestCount; 570 } 571 // ----------------------------------------------------------------------------- getSelectedAccessibleChild(sal_Int32 nSelectedChildIndex)572 Reference< XAccessible > SAL_CALL AccessibleListBox::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) 573 { 574 ::comphelper::OExternalLockGuard aGuard( this ); 575 576 ensureAlive(); 577 578 if ( nSelectedChildIndex < 0 || nSelectedChildIndex >= getSelectedAccessibleChildCount() ) 579 throw IndexOutOfBoundsException(); 580 581 Reference< XAccessible > xChild; 582 sal_Int32 i, nSelCount = 0, nCount = 0; 583 nCount = getListBox()->GetLevelChildCount( NULL ); 584 for ( i = 0; i < nCount; ++i ) 585 { 586 SvLBoxEntry* pEntry = getListBox()->GetEntry( i ); 587 if ( getListBox()->IsSelected( pEntry ) ) 588 ++nSelCount; 589 590 if ( nSelCount == ( nSelectedChildIndex + 1 ) ) 591 { 592 // Solution: Set the parameter of the parent to null to let entry determine the parent by itself 593 //xChild = new AccessibleListBoxEntry( *getListBox(), pEntry, this ); 594 xChild = new AccessibleListBoxEntry( *getListBox(), pEntry, NULL ); 595 break; 596 } 597 } 598 599 return xChild; 600 } 601 // ----------------------------------------------------------------------------- deselectAccessibleChild(sal_Int32 nSelectedChildIndex)602 void SAL_CALL AccessibleListBox::deselectAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) 603 { 604 ::comphelper::OExternalLockGuard aGuard( this ); 605 606 ensureAlive(); 607 608 SvLBoxEntry* pEntry = getListBox()->GetEntry( nSelectedChildIndex ); 609 if ( !pEntry ) 610 throw IndexOutOfBoundsException(); 611 612 getListBox()->Select( pEntry, sal_False ); 613 } 614 // ----------------------------------------------------------------------------- FillAccessibleStateSet(utl::AccessibleStateSetHelper & rStateSet)615 void AccessibleListBox::FillAccessibleStateSet( utl::AccessibleStateSetHelper& rStateSet ) 616 { 617 VCLXAccessibleComponent::FillAccessibleStateSet( rStateSet ); 618 if ( getListBox() && isAlive() ) 619 { 620 rStateSet.AddState( AccessibleStateType::FOCUSABLE ); 621 rStateSet.AddState( AccessibleStateType::MANAGES_DESCENDANTS ); 622 if ( getListBox()->GetSelectionMode() == MULTIPLE_SELECTION ) 623 rStateSet.AddState( AccessibleStateType::MULTI_SELECTABLE ); 624 } 625 } 626 627 628 //........................................................................ 629 }// namespace accessibility 630 //........................................................................ 631