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