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/accessiblelistboxentry.hxx" 27 #include <svtools/svtreebx.hxx> 28 #include <svtools/stringtransfer.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/AccessibleRelationType.hpp> 34 #include <com/sun/star/accessibility/AccessibleRole.hpp> 35 #include <com/sun/star/accessibility/AccessibleStateType.hpp> 36 #include <tools/debug.hxx> 37 #include <vcl/svapp.hxx> 38 #include <vcl/controllayout.hxx> 39 #include <toolkit/awt/vclxwindow.hxx> 40 #include <toolkit/helper/convert.hxx> 41 #include <unotools/accessiblestatesethelper.hxx> 42 #include <unotools/accessiblerelationsethelper.hxx> 43 #include <cppuhelper/typeprovider.hxx> 44 #include <comphelper/sequence.hxx> 45 #include <comphelper/accessibleeventnotifier.hxx> 46 #include <toolkit/helper/vclunohelper.hxx> 47 48 #define ACCESSIBLE_ACTION_COUNT 1 49 50 namespace 51 { 52 void checkActionIndex_Impl( sal_Int32 _nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException) 53 { 54 if ( _nIndex < 0 || _nIndex >= ACCESSIBLE_ACTION_COUNT ) 55 // only three actions 56 throw ::com::sun::star::lang::IndexOutOfBoundsException(); 57 } 58 } 59 60 //........................................................................ 61 namespace accessibility 62 { 63 //........................................................................ 64 // class ALBSolarGuard --------------------------------------------------------- 65 66 /** Aquire the solar mutex. */ 67 class ALBSolarGuard : public ::vos::OGuard 68 { 69 public: 70 inline ALBSolarGuard() : ::vos::OGuard( Application::GetSolarMutex() ) {} 71 }; 72 73 // class AccessibleListBoxEntry ----------------------------------------------------- 74 75 using namespace ::com::sun::star::accessibility; 76 using namespace ::com::sun::star::uno; 77 using namespace ::com::sun::star::lang; 78 using namespace ::com::sun::star; 79 80 DBG_NAME(AccessibleListBoxEntry) 81 82 // ----------------------------------------------------------------------------- 83 // Ctor() and Dtor() 84 // ----------------------------------------------------------------------------- 85 AccessibleListBoxEntry::AccessibleListBoxEntry( SvTreeListBox& _rListBox, 86 SvLBoxEntry* _pEntry, 87 const Reference< XAccessible >& _xParent ) : 88 89 AccessibleListBoxEntry_BASE ( m_aMutex ), 90 ListBoxAccessibleBase( _rListBox ), 91 92 m_nClientId ( 0 ), 93 m_aParent ( _xParent ) 94 95 { 96 DBG_CTOR( AccessibleListBoxEntry, NULL ); 97 98 _rListBox.FillEntryPath( _pEntry, m_aEntryPath ); 99 } 100 // ----------------------------------------------------------------------------- 101 AccessibleListBoxEntry::~AccessibleListBoxEntry() 102 { 103 DBG_DTOR( AccessibleListBoxEntry, NULL ); 104 105 if ( IsAlive_Impl() ) 106 { 107 // increment ref count to prevent double call of Dtor 108 osl_incrementInterlockedCount( &m_refCount ); 109 dispose(); 110 } 111 } 112 113 // ----------------------------------------------------------------------------- 114 Rectangle AccessibleListBoxEntry::GetBoundingBox_Impl() const 115 { 116 Rectangle aRect; 117 SvLBoxEntry* pEntry = getListBox()->GetEntryFromPath( m_aEntryPath ); 118 if ( pEntry ) 119 { 120 aRect = getListBox()->GetBoundingRect( pEntry ); 121 SvLBoxEntry* pParent = getListBox()->GetParent( pEntry ); 122 if ( pParent ) 123 { 124 // position relative to parent entry 125 Point aTopLeft = aRect.TopLeft(); 126 aTopLeft -= getListBox()->GetBoundingRect( pParent ).TopLeft(); 127 aRect = Rectangle( aTopLeft, aRect.GetSize() ); 128 } 129 } 130 131 return aRect; 132 } 133 // ----------------------------------------------------------------------------- 134 Rectangle AccessibleListBoxEntry::GetBoundingBoxOnScreen_Impl() const 135 { 136 Rectangle aRect; 137 SvLBoxEntry* pEntry = getListBox()->GetEntryFromPath( m_aEntryPath ); 138 if ( pEntry ) 139 { 140 aRect = getListBox()->GetBoundingRect( pEntry ); 141 Point aTopLeft = aRect.TopLeft(); 142 aTopLeft += getListBox()->GetWindowExtentsRelative( NULL ).TopLeft(); 143 aRect = Rectangle( aTopLeft, aRect.GetSize() ); 144 } 145 146 return aRect; 147 } 148 // ----------------------------------------------------------------------------- 149 sal_Bool AccessibleListBoxEntry::IsAlive_Impl() const 150 { 151 return ( !rBHelper.bDisposed && !rBHelper.bInDispose && isAlive() ); 152 } 153 // ----------------------------------------------------------------------------- 154 sal_Bool AccessibleListBoxEntry::IsShowing_Impl() const 155 { 156 Reference< XAccessible > xParent = implGetParentAccessible( ); 157 158 sal_Bool bShowing = sal_False; 159 Reference< XAccessibleContext > m_xParentContext = 160 xParent.is() ? xParent->getAccessibleContext() : Reference< XAccessibleContext >(); 161 if( m_xParentContext.is() ) 162 { 163 Reference< XAccessibleComponent > xParentComp( m_xParentContext, uno::UNO_QUERY ); 164 if( xParentComp.is() ) 165 bShowing = GetBoundingBox_Impl().IsOver( VCLRectangle( xParentComp->getBounds() ) ); 166 } 167 168 return bShowing; 169 } 170 // ----------------------------------------------------------------------------- 171 Rectangle AccessibleListBoxEntry::GetBoundingBox() throw ( lang::DisposedException ) 172 { 173 ALBSolarGuard aSolarGuard; 174 ::osl::MutexGuard aGuard( m_aMutex ); 175 176 EnsureIsAlive(); 177 return GetBoundingBox_Impl(); 178 } 179 // ----------------------------------------------------------------------------- 180 Rectangle AccessibleListBoxEntry::GetBoundingBoxOnScreen() throw ( lang::DisposedException ) 181 { 182 ALBSolarGuard aSolarGuard; 183 ::osl::MutexGuard aGuard( m_aMutex ); 184 185 EnsureIsAlive(); 186 return GetBoundingBoxOnScreen_Impl(); 187 } 188 // ----------------------------------------------------------------------------- 189 void AccessibleListBoxEntry::EnsureIsAlive() const throw ( lang::DisposedException ) 190 { 191 if ( !IsAlive_Impl() ) 192 throw lang::DisposedException(); 193 } 194 // ----------------------------------------------------------------------------- 195 ::rtl::OUString AccessibleListBoxEntry::implGetText() 196 { 197 ::rtl::OUString sRet; 198 SvLBoxEntry* pEntry = getListBox()->GetEntryFromPath( m_aEntryPath ); 199 if ( pEntry ) 200 sRet = getListBox()->SearchEntryText( pEntry ); 201 return sRet; 202 } 203 // ----------------------------------------------------------------------------- 204 Locale AccessibleListBoxEntry::implGetLocale() 205 { 206 Locale aLocale; 207 aLocale = Application::GetSettings().GetUILocale(); 208 209 return aLocale; 210 } 211 void AccessibleListBoxEntry::implGetSelection( sal_Int32& nStartIndex, sal_Int32& nEndIndex ) 212 { 213 nStartIndex = 0; 214 nEndIndex = 0; 215 } 216 // ----------------------------------------------------------------------------- 217 // XTypeProvider 218 // ----------------------------------------------------------------------------- 219 // ----------------------------------------------------------------------------- 220 Sequence< sal_Int8 > AccessibleListBoxEntry::getImplementationId() throw (RuntimeException) 221 { 222 static ::cppu::OImplementationId* pId = NULL; 223 224 if ( !pId ) 225 { 226 ::osl::Guard< ::osl::Mutex > aGuard( m_aMutex ); 227 228 if ( !pId ) 229 { 230 static ::cppu::OImplementationId aId; 231 pId = &aId; 232 } 233 } 234 return pId->getImplementationId(); 235 } 236 237 // ----------------------------------------------------------------------------- 238 // XComponent/ListBoxAccessibleBase 239 // ----------------------------------------------------------------------------- 240 void SAL_CALL AccessibleListBoxEntry::dispose() throw ( uno::RuntimeException ) 241 { 242 AccessibleListBoxEntry_BASE::dispose(); 243 } 244 245 // ----------------------------------------------------------------------------- 246 // XComponent 247 // ----------------------------------------------------------------------------- 248 void SAL_CALL AccessibleListBoxEntry::disposing() 249 { 250 ALBSolarGuard(); 251 ::osl::MutexGuard aGuard( m_aMutex ); 252 253 Reference< XAccessible > xKeepAlive( this ); 254 255 // Send a disposing to all listeners. 256 if ( m_nClientId ) 257 { 258 ::comphelper::AccessibleEventNotifier::TClientId nId = m_nClientId; 259 m_nClientId = 0; 260 ::comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( nId, *this ); 261 } 262 263 // clean up 264 { 265 266 ListBoxAccessibleBase::disposing(); 267 } 268 m_aParent = WeakReference< XAccessible >(); 269 } 270 // ----------------------------------------------------------------------------- 271 // XServiceInfo 272 // ----------------------------------------------------------------------------- 273 ::rtl::OUString SAL_CALL AccessibleListBoxEntry::getImplementationName() throw(RuntimeException) 274 { 275 return getImplementationName_Static(); 276 } 277 // ----------------------------------------------------------------------------- 278 Sequence< ::rtl::OUString > SAL_CALL AccessibleListBoxEntry::getSupportedServiceNames() throw(RuntimeException) 279 { 280 return getSupportedServiceNames_Static(); 281 } 282 // ----------------------------------------------------------------------------- 283 sal_Bool SAL_CALL AccessibleListBoxEntry::supportsService( const ::rtl::OUString& _rServiceName ) throw (RuntimeException) 284 { 285 Sequence< ::rtl::OUString > aSupported( getSupportedServiceNames() ); 286 const ::rtl::OUString* pSupported = aSupported.getConstArray(); 287 const ::rtl::OUString* pEnd = pSupported + aSupported.getLength(); 288 for ( ; pSupported != pEnd && !pSupported->equals(_rServiceName); ++pSupported ) 289 ; 290 291 return pSupported != pEnd; 292 } 293 // ----------------------------------------------------------------------------- 294 // XServiceInfo - static methods 295 // ----------------------------------------------------------------------------- 296 Sequence< ::rtl::OUString > AccessibleListBoxEntry::getSupportedServiceNames_Static(void) throw( RuntimeException ) 297 { 298 Sequence< ::rtl::OUString > aSupported(3); 299 aSupported[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.accessibility.AccessibleContext") ); 300 aSupported[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.accessibility.AccessibleComponent") ); 301 aSupported[2] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.AccessibleTreeListBoxEntry") ); 302 return aSupported; 303 } 304 // ----------------------------------------------------------------------------- 305 ::rtl::OUString AccessibleListBoxEntry::getImplementationName_Static(void) throw( RuntimeException ) 306 { 307 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.svtools.AccessibleTreeListBoxEntry") ); 308 } 309 // ----------------------------------------------------------------------------- 310 // XAccessible 311 // ----------------------------------------------------------------------------- 312 Reference< XAccessibleContext > SAL_CALL AccessibleListBoxEntry::getAccessibleContext( ) throw (RuntimeException) 313 { 314 EnsureIsAlive(); 315 return this; 316 } 317 // ----------------------------------------------------------------------------- 318 // XAccessibleContext 319 // ----------------------------------------------------------------------------- 320 sal_Int32 SAL_CALL AccessibleListBoxEntry::getAccessibleChildCount( ) throw (RuntimeException) 321 { 322 ALBSolarGuard aSolarGuard; 323 ::osl::MutexGuard aGuard( m_aMutex ); 324 325 EnsureIsAlive(); 326 SvLBoxEntry* pEntry = getListBox()->GetEntryFromPath( m_aEntryPath ); 327 sal_Int32 nCount = 0; 328 if ( pEntry ) 329 nCount = getListBox()->GetLevelChildCount( pEntry ); 330 331 return nCount; 332 } 333 // ----------------------------------------------------------------------------- 334 Reference< XAccessible > SAL_CALL AccessibleListBoxEntry::getAccessibleChild( sal_Int32 i ) throw (IndexOutOfBoundsException,RuntimeException) 335 { 336 ALBSolarGuard aSolarGuard; 337 ::osl::MutexGuard aGuard( m_aMutex ); 338 EnsureIsAlive(); 339 340 SvLBoxEntry* pParent = getListBox()->GetEntryFromPath( m_aEntryPath ); 341 SvLBoxEntry* pEntry = pParent ? getListBox()->GetEntry( pParent, i ) : NULL; 342 if ( !pEntry ) 343 throw IndexOutOfBoundsException(); 344 345 return new AccessibleListBoxEntry( *getListBox(), pEntry, this ); 346 } 347 348 // ----------------------------------------------------------------------------- 349 Reference< XAccessible > AccessibleListBoxEntry::implGetParentAccessible( ) const 350 { 351 Reference< XAccessible > xParent = (Reference< XAccessible >)m_aParent; 352 if ( !xParent.is() ) 353 { 354 DBG_ASSERT( m_aEntryPath.size(), "AccessibleListBoxEntry::getAccessibleParent: invalid path!" ); 355 if ( 1 == m_aEntryPath.size() ) 356 { // we're a top level entry 357 // -> our parent is the tree listbox itself 358 if ( getListBox() ) 359 xParent = getListBox()->GetAccessible( ); 360 } 361 else 362 { // we have a entry as parent -> get it's accessible 363 364 // shorten our access path by one 365 ::std::deque< sal_Int32 > aParentPath( m_aEntryPath ); 366 aParentPath.pop_back(); 367 368 // get the entry for this shortened access path 369 SvLBoxEntry* pParentEntry = getListBox()->GetEntryFromPath( m_aEntryPath ); 370 DBG_ASSERT( pParentEntry, "AccessibleListBoxEntry::implGetParentAccessible: could not obtain a parent entry!" ); 371 372 if ( pParentEntry ) 373 xParent = new AccessibleListBoxEntry( *getListBox(), pParentEntry, NULL ); 374 // note that we pass NULL here as parent-accessible: 375 // this is allowed, as the AccessibleListBoxEntry class will create it's parent 376 // when needed 377 } 378 } 379 380 return xParent; 381 } 382 383 // ----------------------------------------------------------------------------- 384 Reference< XAccessible > SAL_CALL AccessibleListBoxEntry::getAccessibleParent( ) throw (RuntimeException) 385 { 386 ALBSolarGuard aSolarGuard; 387 ::osl::MutexGuard aGuard( m_aMutex ); 388 EnsureIsAlive(); 389 390 return implGetParentAccessible( ); 391 } 392 // ----------------------------------------------------------------------------- 393 sal_Int32 SAL_CALL AccessibleListBoxEntry::getAccessibleIndexInParent( ) throw (RuntimeException) 394 { 395 ::osl::MutexGuard aGuard( m_aMutex ); 396 397 DBG_ASSERT( !m_aEntryPath.empty(), "empty path" ); 398 return m_aEntryPath.empty() ? -1 : m_aEntryPath.back(); 399 } 400 // ----------------------------------------------------------------------------- 401 sal_Int16 SAL_CALL AccessibleListBoxEntry::getAccessibleRole( ) throw (RuntimeException) 402 { 403 return AccessibleRole::LABEL; 404 } 405 // ----------------------------------------------------------------------------- 406 ::rtl::OUString SAL_CALL AccessibleListBoxEntry::getAccessibleDescription( ) throw (RuntimeException) 407 { 408 // no description for every item 409 return ::rtl::OUString(); 410 } 411 // ----------------------------------------------------------------------------- 412 ::rtl::OUString SAL_CALL AccessibleListBoxEntry::getAccessibleName( ) throw (RuntimeException) 413 { 414 ::osl::MutexGuard aGuard( m_aMutex ); 415 416 EnsureIsAlive(); 417 return implGetText(); 418 } 419 // ----------------------------------------------------------------------------- 420 Reference< XAccessibleRelationSet > SAL_CALL AccessibleListBoxEntry::getAccessibleRelationSet( ) throw (RuntimeException) 421 { 422 Reference< XAccessibleRelationSet > xRelSet; 423 Reference< XAccessible > xParent; 424 if ( m_aEntryPath.size() > 1 ) // not a root entry 425 xParent = implGetParentAccessible(); 426 if ( xParent.is() ) 427 { 428 utl::AccessibleRelationSetHelper* pRelationSetHelper = new utl::AccessibleRelationSetHelper; 429 Sequence< Reference< XInterface > > aSequence(1); 430 aSequence[0] = xParent; 431 pRelationSetHelper->AddRelation( 432 AccessibleRelation( AccessibleRelationType::NODE_CHILD_OF, aSequence ) ); 433 xRelSet = pRelationSetHelper; 434 } 435 return xRelSet; 436 } 437 // ----------------------------------------------------------------------------- 438 Reference< XAccessibleStateSet > SAL_CALL AccessibleListBoxEntry::getAccessibleStateSet( ) throw (RuntimeException) 439 { 440 ::osl::MutexGuard aGuard( m_aMutex ); 441 442 utl::AccessibleStateSetHelper* pStateSetHelper = new utl::AccessibleStateSetHelper; 443 Reference< XAccessibleStateSet > xStateSet = pStateSetHelper; 444 445 if ( IsAlive_Impl() ) 446 { 447 pStateSetHelper->AddState( AccessibleStateType::TRANSIENT ); 448 pStateSetHelper->AddState( AccessibleStateType::SELECTABLE ); 449 pStateSetHelper->AddState( AccessibleStateType::ENABLED ); 450 pStateSetHelper->AddState( AccessibleStateType::SENSITIVE ); 451 if ( getListBox()->IsInplaceEditingEnabled() ) 452 pStateSetHelper->AddState( AccessibleStateType::EDITABLE ); 453 if ( IsShowing_Impl() ) 454 pStateSetHelper->AddState( AccessibleStateType::SHOWING ); 455 getListBox()->FillAccessibleEntryStateSet( 456 getListBox()->GetEntryFromPath( m_aEntryPath ), *pStateSetHelper ); 457 } 458 else 459 pStateSetHelper->AddState( AccessibleStateType::DEFUNC ); 460 461 return xStateSet; 462 } 463 // ----------------------------------------------------------------------------- 464 Locale SAL_CALL AccessibleListBoxEntry::getLocale( ) throw (IllegalAccessibleComponentStateException, RuntimeException) 465 { 466 ALBSolarGuard aSolarGuard; 467 ::osl::MutexGuard aGuard( m_aMutex ); 468 469 return implGetLocale(); 470 } 471 // ----------------------------------------------------------------------------- 472 // XAccessibleComponent 473 // ----------------------------------------------------------------------------- 474 sal_Bool SAL_CALL AccessibleListBoxEntry::containsPoint( const awt::Point& rPoint ) throw (RuntimeException) 475 { 476 return Rectangle( Point(), GetBoundingBox().GetSize() ).IsInside( VCLPoint( rPoint ) ); 477 } 478 // ----------------------------------------------------------------------------- 479 Reference< XAccessible > SAL_CALL AccessibleListBoxEntry::getAccessibleAtPoint( const awt::Point& _aPoint ) throw (RuntimeException) 480 { 481 ALBSolarGuard aSolarGuard; 482 ::osl::MutexGuard aGuard( m_aMutex ); 483 484 EnsureIsAlive(); 485 SvLBoxEntry* pEntry = getListBox()->GetEntry( VCLPoint( _aPoint ) ); 486 if ( !pEntry ) 487 throw RuntimeException(); 488 489 Reference< XAccessible > xAcc; 490 AccessibleListBoxEntry* pAccEntry = new AccessibleListBoxEntry( *getListBox(), pEntry, this ); 491 Rectangle aRect = pAccEntry->GetBoundingBox_Impl(); 492 if ( aRect.IsInside( VCLPoint( _aPoint ) ) ) 493 xAcc = pAccEntry; 494 return xAcc; 495 } 496 // ----------------------------------------------------------------------------- 497 awt::Rectangle SAL_CALL AccessibleListBoxEntry::getBounds( ) throw (RuntimeException) 498 { 499 return AWTRectangle( GetBoundingBox() ); 500 } 501 // ----------------------------------------------------------------------------- 502 awt::Point SAL_CALL AccessibleListBoxEntry::getLocation( ) throw (RuntimeException) 503 { 504 return AWTPoint( GetBoundingBox().TopLeft() ); 505 } 506 // ----------------------------------------------------------------------------- 507 awt::Point SAL_CALL AccessibleListBoxEntry::getLocationOnScreen( ) throw (RuntimeException) 508 { 509 return AWTPoint( GetBoundingBoxOnScreen().TopLeft() ); 510 } 511 // ----------------------------------------------------------------------------- 512 awt::Size SAL_CALL AccessibleListBoxEntry::getSize( ) throw (RuntimeException) 513 { 514 return AWTSize( GetBoundingBox().GetSize() ); 515 } 516 // ----------------------------------------------------------------------------- 517 void SAL_CALL AccessibleListBoxEntry::grabFocus( ) throw (RuntimeException) 518 { 519 // do nothing, because no focus for each item 520 } 521 // ----------------------------------------------------------------------------- 522 sal_Int32 AccessibleListBoxEntry::getForeground( ) throw (RuntimeException) 523 { 524 ALBSolarGuard aSolarGuard; 525 ::osl::MutexGuard aGuard( m_aMutex ); 526 527 sal_Int32 nColor = 0; 528 Reference< XAccessible > xParent = getAccessibleParent(); 529 if ( xParent.is() ) 530 { 531 Reference< XAccessibleComponent > xParentComp( xParent->getAccessibleContext(), UNO_QUERY ); 532 if ( xParentComp.is() ) 533 nColor = xParentComp->getForeground(); 534 } 535 536 return nColor; 537 } 538 // ----------------------------------------------------------------------------- 539 sal_Int32 AccessibleListBoxEntry::getBackground( ) throw (RuntimeException) 540 { 541 ALBSolarGuard aSolarGuard; 542 ::osl::MutexGuard aGuard( m_aMutex ); 543 544 sal_Int32 nColor = 0; 545 Reference< XAccessible > xParent = getAccessibleParent(); 546 if ( xParent.is() ) 547 { 548 Reference< XAccessibleComponent > xParentComp( xParent->getAccessibleContext(), UNO_QUERY ); 549 if ( xParentComp.is() ) 550 nColor = xParentComp->getBackground(); 551 } 552 553 return nColor; 554 } 555 // ----------------------------------------------------------------------------- 556 // XAccessibleText 557 // ----------------------------------------------------------------------------- 558 // ----------------------------------------------------------------------------- 559 awt::Rectangle SAL_CALL AccessibleListBoxEntry::getCharacterBounds( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException) 560 { 561 ALBSolarGuard aSolarGuard; 562 ::osl::MutexGuard aGuard( m_aMutex ); 563 564 EnsureIsAlive(); 565 566 if ( !implIsValidIndex( nIndex, implGetText().getLength() ) ) 567 throw IndexOutOfBoundsException(); 568 569 awt::Rectangle aBounds( 0, 0, 0, 0 ); 570 SvLBoxEntry* pEntry = getListBox()->GetEntryFromPath( m_aEntryPath ); 571 if ( pEntry ) 572 { 573 ::vcl::ControlLayoutData aLayoutData; 574 Rectangle aItemRect = GetBoundingBox(); 575 getListBox()->RecordLayoutData( &aLayoutData, aItemRect ); 576 Rectangle aCharRect = aLayoutData.GetCharacterBounds( nIndex ); 577 aCharRect.Move( -aItemRect.Left(), -aItemRect.Top() ); 578 aBounds = AWTRectangle( aCharRect ); 579 } 580 581 return aBounds; 582 } 583 // ----------------------------------------------------------------------------- 584 sal_Int32 SAL_CALL AccessibleListBoxEntry::getIndexAtPoint( const awt::Point& aPoint ) throw (RuntimeException) 585 { 586 ALBSolarGuard aSolarGuard; 587 ::osl::MutexGuard aGuard( m_aMutex ); 588 EnsureIsAlive(); 589 590 sal_Int32 nIndex = -1; 591 SvLBoxEntry* pEntry = getListBox()->GetEntryFromPath( m_aEntryPath ); 592 if ( pEntry ) 593 { 594 ::vcl::ControlLayoutData aLayoutData; 595 Rectangle aItemRect = GetBoundingBox(); 596 getListBox()->RecordLayoutData( &aLayoutData, aItemRect ); 597 Point aPnt( VCLPoint( aPoint ) ); 598 aPnt += aItemRect.TopLeft(); 599 nIndex = aLayoutData.GetIndexForPoint( aPnt ); 600 } 601 602 return nIndex; 603 } 604 // ----------------------------------------------------------------------------- 605 sal_Bool SAL_CALL AccessibleListBoxEntry::copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (IndexOutOfBoundsException, RuntimeException) 606 { 607 ALBSolarGuard aSolarGuard; 608 ::osl::MutexGuard aGuard( m_aMutex ); 609 EnsureIsAlive(); 610 611 String sText = getText(); 612 if ( ( 0 > nStartIndex ) || ( sText.Len() <= nStartIndex ) 613 || ( 0 > nEndIndex ) || ( sText.Len() <= nEndIndex ) ) 614 throw IndexOutOfBoundsException(); 615 616 sal_Int32 nLen = nEndIndex - nStartIndex + 1; 617 ::svt::OStringTransfer::CopyString( sText.Copy( (sal_uInt16)nStartIndex, (sal_uInt16)nLen ), getListBox() ); 618 619 return sal_True; 620 } 621 // ----------------------------------------------------------------------------- 622 // XAccessibleEventBroadcaster 623 // ----------------------------------------------------------------------------- 624 void SAL_CALL AccessibleListBoxEntry::addEventListener( const Reference< XAccessibleEventListener >& xListener ) throw (RuntimeException) 625 { 626 if (xListener.is()) 627 { 628 ::osl::MutexGuard aGuard( m_aMutex ); 629 if (!m_nClientId) 630 m_nClientId = comphelper::AccessibleEventNotifier::registerClient( ); 631 comphelper::AccessibleEventNotifier::addEventListener( m_nClientId, xListener ); 632 } 633 } 634 // ----------------------------------------------------------------------------- 635 void SAL_CALL AccessibleListBoxEntry::removeEventListener( const Reference< XAccessibleEventListener >& xListener ) throw (RuntimeException) 636 { 637 if (xListener.is()) 638 { 639 ::osl::MutexGuard aGuard( m_aMutex ); 640 641 sal_Int32 nListenerCount = comphelper::AccessibleEventNotifier::removeEventListener( m_nClientId, xListener ); 642 if ( !nListenerCount ) 643 { 644 // no listeners anymore 645 // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client), 646 // and at least to us not firing any events anymore, in case somebody calls 647 // NotifyAccessibleEvent, again 648 sal_Int32 nId = m_nClientId; 649 m_nClientId = 0; 650 comphelper::AccessibleEventNotifier::revokeClient( nId ); 651 652 } 653 } 654 } 655 // ----------------------------------------------------------------------------- 656 // XAccessibleAction 657 // ----------------------------------------------------------------------------- 658 sal_Int32 SAL_CALL AccessibleListBoxEntry::getAccessibleActionCount( ) throw (RuntimeException) 659 { 660 ::osl::MutexGuard aGuard( m_aMutex ); 661 662 // three actions supported 663 return ACCESSIBLE_ACTION_COUNT; 664 } 665 // ----------------------------------------------------------------------------- 666 sal_Bool SAL_CALL AccessibleListBoxEntry::doAccessibleAction( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException) 667 { 668 ALBSolarGuard aSolarGuard; 669 ::osl::MutexGuard aGuard( m_aMutex ); 670 671 sal_Bool bRet = sal_False; 672 checkActionIndex_Impl( nIndex ); 673 EnsureIsAlive(); 674 675 SvLBoxEntry* pEntry = getListBox()->GetEntryFromPath( m_aEntryPath ); 676 if ( pEntry ) 677 { 678 if ( getListBox()->IsExpanded( pEntry ) ) 679 getListBox()->Collapse( pEntry ); 680 else 681 getListBox()->Expand( pEntry ); 682 bRet = sal_True; 683 } 684 685 return bRet; 686 } 687 // ----------------------------------------------------------------------------- 688 ::rtl::OUString SAL_CALL AccessibleListBoxEntry::getAccessibleActionDescription( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException) 689 { 690 ALBSolarGuard aSolarGuard; 691 ::osl::MutexGuard aGuard( m_aMutex ); 692 693 checkActionIndex_Impl( nIndex ); 694 EnsureIsAlive(); 695 696 static const ::rtl::OUString sActionDesc( RTL_CONSTASCII_USTRINGPARAM( "toggleExpand" ) ); 697 return sActionDesc; 698 } 699 // ----------------------------------------------------------------------------- 700 Reference< XAccessibleKeyBinding > AccessibleListBoxEntry::getAccessibleActionKeyBinding( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException) 701 { 702 ::osl::MutexGuard aGuard( m_aMutex ); 703 704 Reference< XAccessibleKeyBinding > xRet; 705 checkActionIndex_Impl( nIndex ); 706 // ... which key? 707 return xRet; 708 } 709 // ----------------------------------------------------------------------------- 710 // XAccessibleSelection 711 // ----------------------------------------------------------------------------- 712 void SAL_CALL AccessibleListBoxEntry::selectAccessibleChild( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) 713 { 714 ALBSolarGuard aSolarGuard; 715 ::osl::MutexGuard aGuard( m_aMutex ); 716 717 EnsureIsAlive(); 718 719 SvLBoxEntry* pParent = getListBox()->GetEntryFromPath( m_aEntryPath ); 720 SvLBoxEntry* pEntry = getListBox()->GetEntry( pParent, nChildIndex ); 721 if ( !pEntry ) 722 throw IndexOutOfBoundsException(); 723 724 getListBox()->Select( pEntry, sal_True ); 725 } 726 // ----------------------------------------------------------------------------- 727 sal_Bool SAL_CALL AccessibleListBoxEntry::isAccessibleChildSelected( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) 728 { 729 ALBSolarGuard aSolarGuard; 730 ::osl::MutexGuard aGuard( m_aMutex ); 731 732 EnsureIsAlive(); 733 734 SvLBoxEntry* pParent = getListBox()->GetEntryFromPath( m_aEntryPath ); 735 SvLBoxEntry* pEntry = getListBox()->GetEntry( pParent, nChildIndex ); 736 if ( !pEntry ) 737 throw IndexOutOfBoundsException(); 738 739 return getListBox()->IsSelected( pEntry ); 740 } 741 // ----------------------------------------------------------------------------- 742 void SAL_CALL AccessibleListBoxEntry::clearAccessibleSelection( ) throw (RuntimeException) 743 { 744 ALBSolarGuard aSolarGuard; 745 ::osl::MutexGuard aGuard( m_aMutex ); 746 747 EnsureIsAlive(); 748 749 SvLBoxEntry* pParent = getListBox()->GetEntryFromPath( m_aEntryPath ); 750 if ( !pParent ) 751 throw RuntimeException(); 752 sal_Int32 i, nCount = 0; 753 nCount = getListBox()->GetLevelChildCount( pParent ); 754 for ( i = 0; i < nCount; ++i ) 755 { 756 SvLBoxEntry* pEntry = getListBox()->GetEntry( pParent, i ); 757 if ( getListBox()->IsSelected( pEntry ) ) 758 getListBox()->Select( pEntry, sal_False ); 759 } 760 } 761 // ----------------------------------------------------------------------------- 762 void SAL_CALL AccessibleListBoxEntry::selectAllAccessibleChildren( ) throw (RuntimeException) 763 { 764 ALBSolarGuard aSolarGuard; 765 ::osl::MutexGuard aGuard( m_aMutex ); 766 767 EnsureIsAlive(); 768 769 SvLBoxEntry* pParent = getListBox()->GetEntryFromPath( m_aEntryPath ); 770 if ( !pParent ) 771 throw RuntimeException(); 772 sal_Int32 i, nCount = 0; 773 nCount = getListBox()->GetLevelChildCount( pParent ); 774 for ( i = 0; i < nCount; ++i ) 775 { 776 SvLBoxEntry* pEntry = getListBox()->GetEntry( pParent, i ); 777 if ( !getListBox()->IsSelected( pEntry ) ) 778 getListBox()->Select( pEntry, sal_True ); 779 } 780 } 781 // ----------------------------------------------------------------------------- 782 sal_Int32 SAL_CALL AccessibleListBoxEntry::getSelectedAccessibleChildCount( ) throw (RuntimeException) 783 { 784 ALBSolarGuard aSolarGuard; 785 ::osl::MutexGuard aGuard( m_aMutex ); 786 787 EnsureIsAlive(); 788 789 sal_Int32 i, nSelCount = 0, nCount = 0; 790 791 SvLBoxEntry* pParent = getListBox()->GetEntryFromPath( m_aEntryPath ); 792 if ( !pParent ) 793 throw RuntimeException(); 794 nCount = getListBox()->GetLevelChildCount( pParent ); 795 for ( i = 0; i < nCount; ++i ) 796 { 797 SvLBoxEntry* pEntry = getListBox()->GetEntry( pParent, i ); 798 if ( getListBox()->IsSelected( pEntry ) ) 799 ++nSelCount; 800 } 801 802 return nSelCount; 803 } 804 // ----------------------------------------------------------------------------- 805 Reference< XAccessible > SAL_CALL AccessibleListBoxEntry::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) 806 { 807 ALBSolarGuard aSolarGuard; 808 ::osl::MutexGuard aGuard( m_aMutex ); 809 810 EnsureIsAlive(); 811 812 if ( nSelectedChildIndex < 0 || nSelectedChildIndex >= getSelectedAccessibleChildCount() ) 813 throw IndexOutOfBoundsException(); 814 815 Reference< XAccessible > xChild; 816 sal_Int32 i, nSelCount = 0, nCount = 0; 817 818 SvLBoxEntry* pParent = getListBox()->GetEntryFromPath( m_aEntryPath ); 819 if ( !pParent ) 820 throw RuntimeException(); 821 nCount = getListBox()->GetLevelChildCount( pParent ); 822 for ( i = 0; i < nCount; ++i ) 823 { 824 SvLBoxEntry* pEntry = getListBox()->GetEntry( pParent, i ); 825 if ( getListBox()->IsSelected( pEntry ) ) 826 ++nSelCount; 827 828 if ( nSelCount == ( nSelectedChildIndex + 1 ) ) 829 { 830 xChild = new AccessibleListBoxEntry( *getListBox(), pEntry, this ); 831 break; 832 } 833 } 834 835 return xChild; 836 } 837 // ----------------------------------------------------------------------------- 838 void SAL_CALL AccessibleListBoxEntry::deselectAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) 839 { 840 ALBSolarGuard aSolarGuard; 841 ::osl::MutexGuard aGuard( m_aMutex ); 842 843 EnsureIsAlive(); 844 845 SvLBoxEntry* pParent = getListBox()->GetEntryFromPath( m_aEntryPath ); 846 SvLBoxEntry* pEntry = getListBox()->GetEntry( pParent, nSelectedChildIndex ); 847 if ( !pEntry ) 848 throw IndexOutOfBoundsException(); 849 850 getListBox()->Select( pEntry, sal_False ); 851 } 852 sal_Int32 SAL_CALL AccessibleListBoxEntry::getCaretPosition( ) throw (::com::sun::star::uno::RuntimeException) 853 { 854 return -1; 855 } 856 sal_Bool SAL_CALL AccessibleListBoxEntry::setCaretPosition ( sal_Int32 nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) 857 { 858 ALBSolarGuard aSolarGuard; 859 ::osl::MutexGuard aGuard( m_aMutex ); 860 EnsureIsAlive(); 861 862 if ( !implIsValidRange( nIndex, nIndex, implGetText().getLength() ) ) 863 throw IndexOutOfBoundsException(); 864 865 return sal_False; 866 } 867 sal_Unicode SAL_CALL AccessibleListBoxEntry::getCharacter( sal_Int32 nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) 868 { 869 ALBSolarGuard aSolarGuard; 870 ::osl::MutexGuard aGuard( m_aMutex ); 871 EnsureIsAlive(); 872 return OCommonAccessibleText::getCharacter( nIndex ); 873 } 874 ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > SAL_CALL AccessibleListBoxEntry::getCharacterAttributes( sal_Int32 nIndex, const ::com::sun::star::uno::Sequence< ::rtl::OUString >& ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) 875 { 876 ALBSolarGuard aSolarGuard; 877 ::osl::MutexGuard aGuard( m_aMutex ); 878 EnsureIsAlive(); 879 880 ::rtl::OUString sText( implGetText() ); 881 882 if ( !implIsValidIndex( nIndex, sText.getLength() ) ) 883 throw IndexOutOfBoundsException(); 884 885 return ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >(); 886 } 887 sal_Int32 SAL_CALL AccessibleListBoxEntry::getCharacterCount( ) throw (::com::sun::star::uno::RuntimeException) 888 { 889 ALBSolarGuard aSolarGuard; 890 ::osl::MutexGuard aGuard( m_aMutex ); 891 EnsureIsAlive(); 892 return OCommonAccessibleText::getCharacterCount( ); 893 } 894 895 ::rtl::OUString SAL_CALL AccessibleListBoxEntry::getSelectedText( ) throw (::com::sun::star::uno::RuntimeException) 896 { 897 ALBSolarGuard aSolarGuard; 898 ::osl::MutexGuard aGuard( m_aMutex ); 899 EnsureIsAlive(); 900 return OCommonAccessibleText::getSelectedText( ); 901 } 902 sal_Int32 SAL_CALL AccessibleListBoxEntry::getSelectionStart( ) throw (::com::sun::star::uno::RuntimeException) 903 { 904 ALBSolarGuard aSolarGuard; 905 ::osl::MutexGuard aGuard( m_aMutex ); 906 EnsureIsAlive(); 907 return OCommonAccessibleText::getSelectionStart( ); 908 } 909 sal_Int32 SAL_CALL AccessibleListBoxEntry::getSelectionEnd( ) throw (::com::sun::star::uno::RuntimeException) 910 { 911 ALBSolarGuard aSolarGuard; 912 ::osl::MutexGuard aGuard( m_aMutex ); 913 EnsureIsAlive(); 914 return OCommonAccessibleText::getSelectionEnd( ); 915 } 916 sal_Bool SAL_CALL AccessibleListBoxEntry::setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) 917 { 918 ALBSolarGuard aSolarGuard; 919 ::osl::MutexGuard aGuard( m_aMutex ); 920 EnsureIsAlive(); 921 922 if ( !implIsValidRange( nStartIndex, nEndIndex, implGetText().getLength() ) ) 923 throw IndexOutOfBoundsException(); 924 925 return sal_False; 926 } 927 ::rtl::OUString SAL_CALL AccessibleListBoxEntry::getText( ) throw (::com::sun::star::uno::RuntimeException) 928 { 929 ALBSolarGuard aSolarGuard; 930 ::osl::MutexGuard aGuard( m_aMutex ); 931 EnsureIsAlive(); 932 return OCommonAccessibleText::getText( ); 933 } 934 ::rtl::OUString SAL_CALL AccessibleListBoxEntry::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) 935 { 936 ALBSolarGuard aSolarGuard; 937 ::osl::MutexGuard aGuard( m_aMutex ); 938 EnsureIsAlive(); 939 return OCommonAccessibleText::getTextRange( nStartIndex, nEndIndex ); 940 } 941 ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleListBoxEntry::getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) 942 { 943 ALBSolarGuard aSolarGuard; 944 ::osl::MutexGuard aGuard( m_aMutex ); 945 EnsureIsAlive(); 946 return OCommonAccessibleText::getTextAtIndex( nIndex ,aTextType); 947 } 948 ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleListBoxEntry::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) 949 { 950 ALBSolarGuard aSolarGuard; 951 ::osl::MutexGuard aGuard( m_aMutex ); 952 EnsureIsAlive(); 953 return OCommonAccessibleText::getTextBeforeIndex( nIndex ,aTextType); 954 } 955 ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleListBoxEntry::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) 956 { 957 ALBSolarGuard aSolarGuard; 958 ::osl::MutexGuard aGuard( m_aMutex ); 959 EnsureIsAlive(); 960 961 return OCommonAccessibleText::getTextBehindIndex( nIndex ,aTextType); 962 } 963 //........................................................................ 964 }// namespace accessibility 965 //........................................................................ 966 967