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_svx.hxx" 26 27 28 #include "svxrectctaccessiblecontext.hxx" 29 #include <com/sun/star/accessibility/AccessibleRole.hpp> 30 #include <com/sun/star/accessibility/AccessibleEventId.hpp> 31 #include <unotools/accessiblestatesethelper.hxx> 32 #include <com/sun/star/accessibility/AccessibleStateType.hpp> 33 #include <com/sun/star/beans/PropertyChangeEvent.hpp> 34 #include <com/sun/star/awt/XWindow.hpp> 35 #include <cppuhelper/typeprovider.hxx> 36 #include <toolkit/helper/vclunohelper.hxx> 37 #include <toolkit/helper/convert.hxx> 38 #include <vcl/svapp.hxx> 39 #include <osl/mutex.hxx> 40 #include <rtl/uuid.h> 41 #include <tools/debug.hxx> 42 #include <tools/gen.hxx> 43 44 #include <svx/dialogs.hrc> 45 #include "accessibility.hrc" 46 #include <svx/dlgctrl.hxx> 47 #include <svx/dialmgr.hxx> 48 #include <comphelper/accessibleeventnotifier.hxx> 49 //IAccessibility2 Implementation 2009----- 50 #ifndef _COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLERELATIONTYPE_HPP_ 51 #include <com/sun/star/accessibility/AccessibleRelationType.hpp> 52 #endif 53 #ifndef _UTL_ACCESSIBLERELATIONSETHELPER_HXX_ 54 #include <unotools/accessiblerelationsethelper.hxx> 55 #endif 56 //-----IAccessibility2 Implementation 2009 57 58 using namespace ::cppu; 59 using namespace ::osl; 60 using namespace ::com::sun::star; 61 using namespace ::com::sun::star::uno; 62 using namespace ::com::sun::star::accessibility; 63 64 //IAccessibility2 Implementation 2009----- 65 using namespace ::com::sun::star::lang; 66 //-----IAccessibility2 Implementation 2009 67 68 #define MAX_NUM_OF_CHILDS 9 69 #define NOCHILDSELECTED -1 70 71 72 DBG_NAME( SvxRectCtlAccessibleContext ) 73 74 75 //===== internal ============================================================ 76 77 namespace 78 { 79 struct ChildIndexToPointData 80 { 81 short nResIdName; 82 short nResIdDescr; 83 RECT_POINT ePoint; 84 }; 85 } 86 87 88 static const ChildIndexToPointData* IndexToPoint( long nIndex, sal_Bool bAngleControl ) 89 { 90 DBG_ASSERT( nIndex < ( bAngleControl? 8 : 9 ) && nIndex >= 0, "-IndexToPoint(): invalid child index! You have been warned..." ); 91 92 // angles are counted reverse counter clock wise 93 static const ChildIndexToPointData pAngleData[] = 94 { // index 95 { RID_SVXSTR_RECTCTL_ACC_CHLD_A000, RID_SVXSTR_RECTCTL_ACC_CHLD_A000, RP_RM }, // 0 96 { RID_SVXSTR_RECTCTL_ACC_CHLD_A045, RID_SVXSTR_RECTCTL_ACC_CHLD_A045, RP_RT }, // 1 97 { RID_SVXSTR_RECTCTL_ACC_CHLD_A090, RID_SVXSTR_RECTCTL_ACC_CHLD_A090, RP_MT }, // 2 98 { RID_SVXSTR_RECTCTL_ACC_CHLD_A135, RID_SVXSTR_RECTCTL_ACC_CHLD_A135, RP_LT }, // 3 99 { RID_SVXSTR_RECTCTL_ACC_CHLD_A180, RID_SVXSTR_RECTCTL_ACC_CHLD_A180, RP_LM }, // 4 100 { RID_SVXSTR_RECTCTL_ACC_CHLD_A225, RID_SVXSTR_RECTCTL_ACC_CHLD_A225, RP_LB }, // 5 101 { RID_SVXSTR_RECTCTL_ACC_CHLD_A270, RID_SVXSTR_RECTCTL_ACC_CHLD_A270, RP_MB }, // 6 102 { RID_SVXSTR_RECTCTL_ACC_CHLD_A315, RID_SVXSTR_RECTCTL_ACC_CHLD_A315, RP_RB } // 7 103 }; 104 105 // corners are counted from left to right and top to bottom 106 static const ChildIndexToPointData pCornerData[] = 107 { // index 108 { RID_SVXSTR_RECTCTL_ACC_CHLD_LT, RID_SVXSTR_RECTCTL_ACC_CHLD_LT, RP_LT }, // 0 109 { RID_SVXSTR_RECTCTL_ACC_CHLD_MT, RID_SVXSTR_RECTCTL_ACC_CHLD_MT, RP_MT }, // 1 110 { RID_SVXSTR_RECTCTL_ACC_CHLD_RT, RID_SVXSTR_RECTCTL_ACC_CHLD_RT, RP_RT }, // 2 111 { RID_SVXSTR_RECTCTL_ACC_CHLD_LM, RID_SVXSTR_RECTCTL_ACC_CHLD_LM, RP_LM }, // 3 112 { RID_SVXSTR_RECTCTL_ACC_CHLD_MM, RID_SVXSTR_RECTCTL_ACC_CHLD_MM, RP_MM }, // 4 113 { RID_SVXSTR_RECTCTL_ACC_CHLD_RM, RID_SVXSTR_RECTCTL_ACC_CHLD_RM, RP_RM }, // 5 114 { RID_SVXSTR_RECTCTL_ACC_CHLD_LB, RID_SVXSTR_RECTCTL_ACC_CHLD_LB, RP_LB }, // 6 115 { RID_SVXSTR_RECTCTL_ACC_CHLD_MB, RID_SVXSTR_RECTCTL_ACC_CHLD_MB, RP_MB }, // 7 116 { RID_SVXSTR_RECTCTL_ACC_CHLD_RB, RID_SVXSTR_RECTCTL_ACC_CHLD_RB, RP_RB } // 8 117 }; 118 119 return ( bAngleControl? pAngleData : pCornerData ) + nIndex; 120 } 121 122 123 static long PointToIndex( RECT_POINT ePoint, sal_Bool bAngleControl ) 124 { 125 long nRet( (long) ePoint ); 126 if( bAngleControl ) 127 { // angle control 128 // angles are counted reverse counter clock wise 129 switch( ePoint ) 130 { 131 case RP_LT: nRet = 3; break; 132 case RP_MT: nRet = 2; break; 133 case RP_RT: nRet = 1; break; 134 case RP_LM: nRet = 4; break; 135 case RP_MM: nRet = NOCHILDSELECTED; break; 136 case RP_RM: nRet = 0; break; 137 case RP_LB: nRet = 5; break; 138 case RP_MB: nRet = 6; break; 139 case RP_RB: nRet = 7; break; 140 } 141 } 142 else 143 { // corner control 144 // corners are counted from left to right and top to bottom 145 DBG_ASSERT( RP_LT == 0 && RP_MT == 1 && RP_RT == 2 && RP_LM == 3 && RP_MM == 4 && RP_RM == 5 && 146 RP_LB == 6 && RP_MB == 7 && RP_RB == 8, "*PointToIndex(): unexpected enum value!" ); 147 148 nRet = ( long ) ePoint; 149 } 150 151 return nRet; 152 } 153 154 155 SvxRectCtlAccessibleContext::SvxRectCtlAccessibleContext( 156 const Reference< XAccessible >& rxParent, 157 SvxRectCtl& rRepr, 158 const ::rtl::OUString* pName, 159 const ::rtl::OUString* pDesc ) : 160 161 SvxRectCtlAccessibleContext_Base( m_aMutex ), 162 mxParent( rxParent ), 163 mpRepr( &rRepr ), 164 mpChilds( NULL ), 165 mnClientId( 0 ), 166 mnSelectedChild( NOCHILDSELECTED ), 167 mbAngleMode( rRepr.GetNumOfChilds() == 8 ) 168 { 169 DBG_CTOR( SvxRectCtlAccessibleContext, NULL ); 170 171 if( pName ) 172 msName = *pName; 173 else 174 { 175 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 176 msName = SVX_RESSTR( mbAngleMode? RID_SVXSTR_RECTCTL_ACC_ANGL_NAME : RID_SVXSTR_RECTCTL_ACC_CORN_NAME ); 177 } 178 179 if( pDesc ) 180 msDescription = *pDesc; 181 else 182 { 183 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 184 msDescription = SVX_RESSTR( mbAngleMode? RID_SVXSTR_RECTCTL_ACC_ANGL_DESCR : RID_SVXSTR_RECTCTL_ACC_CORN_DESCR ); 185 } 186 187 mpChilds = new SvxRectCtlChildAccessibleContext*[ MAX_NUM_OF_CHILDS ]; 188 189 SvxRectCtlChildAccessibleContext** p = mpChilds; 190 for( int i = MAX_NUM_OF_CHILDS ; i ; --i, ++p ) 191 *p = NULL; 192 } 193 194 195 SvxRectCtlAccessibleContext::~SvxRectCtlAccessibleContext() 196 { 197 DBG_DTOR( SvxRectCtlAccessibleContext, NULL ); 198 199 if( IsAlive() ) 200 { 201 osl_incrementInterlockedCount( &m_refCount ); 202 dispose(); // set mpRepr = NULL & release all childs 203 } 204 } 205 206 //===== XAccessible ========================================================= 207 208 Reference< XAccessibleContext > SAL_CALL SvxRectCtlAccessibleContext::getAccessibleContext( void ) throw( RuntimeException ) 209 { 210 return this; 211 } 212 213 //===== XAccessibleComponent ================================================ 214 215 sal_Bool SAL_CALL SvxRectCtlAccessibleContext::containsPoint( const awt::Point& rPoint ) throw( RuntimeException ) 216 { 217 // no guard -> done in getBounds() 218 // return GetBoundingBox().IsInside( VCLPoint( rPoint ) ); 219 return Rectangle( Point( 0, 0 ), GetBoundingBox().GetSize() ).IsInside( VCLPoint( rPoint ) ); 220 } 221 222 Reference< XAccessible > SAL_CALL SvxRectCtlAccessibleContext::getAccessibleAtPoint( const awt::Point& rPoint ) throw( RuntimeException ) 223 { 224 ::osl::MutexGuard aGuard( m_aMutex ); 225 226 ThrowExceptionIfNotAlive(); 227 228 Reference< XAccessible > xRet; 229 230 long nChild = PointToIndex( mpRepr->GetApproxRPFromPixPt( rPoint ), mbAngleMode ); 231 232 if( nChild != NOCHILDSELECTED ) 233 xRet = getAccessibleChild( nChild ); 234 235 return xRet; 236 } 237 238 awt::Rectangle SAL_CALL SvxRectCtlAccessibleContext::getBounds() throw( RuntimeException ) 239 { 240 // no guard -> done in GetBoundingBox() 241 return AWTRectangle( GetBoundingBox() ); 242 } 243 244 awt::Point SAL_CALL SvxRectCtlAccessibleContext::getLocation() throw( RuntimeException ) 245 { 246 // no guard -> done in GetBoundingBox() 247 return AWTPoint( GetBoundingBox().TopLeft() ); 248 } 249 250 awt::Point SAL_CALL SvxRectCtlAccessibleContext::getLocationOnScreen() throw( RuntimeException ) 251 { 252 // no guard -> done in GetBoundingBoxOnScreen() 253 return AWTPoint( GetBoundingBoxOnScreen().TopLeft() ); 254 } 255 256 awt::Size SAL_CALL SvxRectCtlAccessibleContext::getSize() throw( RuntimeException ) 257 { 258 // no guard -> done in GetBoundingBox() 259 return AWTSize( GetBoundingBox().GetSize() ); 260 } 261 262 sal_Bool SAL_CALL SvxRectCtlAccessibleContext::isShowing() throw( RuntimeException ) 263 { 264 return sal_True; 265 } 266 267 sal_Bool SAL_CALL SvxRectCtlAccessibleContext::isVisible() throw( RuntimeException ) 268 { 269 ::osl::MutexGuard aGuard( m_aMutex ); 270 271 ThrowExceptionIfNotAlive(); 272 273 return mpRepr->IsVisible(); 274 } 275 276 sal_Bool SAL_CALL SvxRectCtlAccessibleContext::isFocusTraversable() throw( RuntimeException ) 277 { 278 return sal_True; 279 } 280 281 //===== XAccessibleContext ================================================== 282 283 sal_Int32 SAL_CALL SvxRectCtlAccessibleContext::getAccessibleChildCount( void ) throw( RuntimeException ) 284 { 285 ::osl::MutexGuard aGuard( m_aMutex ); 286 287 ThrowExceptionIfNotAlive(); 288 289 return mpRepr->GetNumOfChilds(); 290 } 291 292 Reference< XAccessible > SAL_CALL SvxRectCtlAccessibleContext::getAccessibleChild( sal_Int32 nIndex ) 293 throw( RuntimeException, lang::IndexOutOfBoundsException ) 294 { 295 checkChildIndex( nIndex ); 296 297 Reference< XAccessible > xChild = mpChilds[ nIndex ]; 298 if( !xChild.is() ) 299 { 300 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 301 302 ::osl::MutexGuard aGuard( m_aMutex ); 303 304 ThrowExceptionIfNotAlive(); 305 306 xChild = mpChilds[ nIndex ]; 307 308 if( !xChild.is() ) 309 { 310 const ChildIndexToPointData* p = IndexToPoint( nIndex, mbAngleMode ); 311 UniString tmp = SVX_RESSTR( p->nResIdName ); 312 ::rtl::OUString aName( tmp ); 313 tmp = SVX_RESSTR( p->nResIdDescr ); 314 ::rtl::OUString aDescr( tmp ); 315 316 Rectangle aFocusRect( mpRepr->CalculateFocusRectangle( p->ePoint ) ); 317 318 Rectangle aBoundingBoxOnScreen( mpRepr->OutputToScreenPixel( aFocusRect.TopLeft() ), aFocusRect.GetSize() ); 319 320 SvxRectCtlChildAccessibleContext* pChild = new SvxRectCtlChildAccessibleContext( 321 this, *mpRepr, aName, aDescr, aFocusRect, nIndex ); 322 xChild = mpChilds[ nIndex ] = pChild; 323 pChild->acquire(); 324 325 // set actual state 326 if( mnSelectedChild == nIndex ) 327 pChild->setStateChecked( sal_True ); 328 } 329 } 330 331 return xChild; 332 } 333 334 Reference< XAccessible > SAL_CALL SvxRectCtlAccessibleContext::getAccessibleParent( void ) throw( RuntimeException ) 335 { 336 return mxParent; 337 } 338 339 sal_Int32 SAL_CALL SvxRectCtlAccessibleContext::getAccessibleIndexInParent( void ) throw( RuntimeException ) 340 { 341 ::osl::MutexGuard aGuard( m_aMutex ); 342 // Use a simple but slow solution for now. Optimize later. 343 344 // Iterate over all the parent's children and search for this object. 345 if( mxParent.is() ) 346 { 347 Reference< XAccessibleContext > xParentContext( mxParent->getAccessibleContext() ); 348 if( xParentContext.is() ) 349 { 350 sal_Int32 nChildCount = xParentContext->getAccessibleChildCount(); 351 for( sal_Int32 i = 0 ; i < nChildCount ; ++i ) 352 { 353 Reference< XAccessible > xChild( xParentContext->getAccessibleChild( i ) ); 354 if( xChild.get() == ( XAccessible* ) this ) 355 return i; 356 } 357 } 358 } 359 360 // Return -1 to indicate that this object's parent does not know about the 361 // object. 362 return -1; 363 } 364 365 sal_Int16 SAL_CALL SvxRectCtlAccessibleContext::getAccessibleRole( void ) throw( RuntimeException ) 366 { 367 //IAccessibility2 Implementation 2009----- 368 //return AccessibleRole::GROUP_BOX; 369 return AccessibleRole::PANEL; 370 //-----IAccessibility2 Implementation 2009 371 } 372 373 ::rtl::OUString SAL_CALL SvxRectCtlAccessibleContext::getAccessibleDescription( void ) throw( RuntimeException ) 374 { 375 ::osl::MutexGuard aGuard( m_aMutex ); 376 //IAccessibility2 Implementation 2009----- 377 //return msDescription; 378 return msDescription +::rtl::OUString::createFromAscii(" Please use arrow key to selection."); 379 //-----IAccessibility2 Implementation 2009 380 } 381 382 ::rtl::OUString SAL_CALL SvxRectCtlAccessibleContext::getAccessibleName( void ) throw( RuntimeException ) 383 { 384 ::osl::MutexGuard aGuard( m_aMutex ); 385 return msName; 386 } 387 388 /** Return empty reference to indicate that the relation set is not 389 supported. 390 */ 391 Reference< XAccessibleRelationSet > SAL_CALL SvxRectCtlAccessibleContext::getAccessibleRelationSet( void ) throw( RuntimeException ) 392 { 393 //IAccessibility2 Implementation 2009----- 394 //return Reference< XAccessibleRelationSet >(); 395 utl::AccessibleRelationSetHelper* pRelationSetHelper = new utl::AccessibleRelationSetHelper; 396 uno::Reference< accessibility::XAccessibleRelationSet > xSet = pRelationSetHelper; 397 Window* pWindow = mpRepr; 398 if ( pWindow ) 399 { 400 // Window *pLabeledBy = pWindow->GetAccRelationLabeledBy(); 401 Window *pLabeledBy = pWindow->GetAccessibleRelationLabeledBy(); 402 if ( pLabeledBy && pLabeledBy != pWindow ) 403 { 404 uno::Sequence< uno::Reference< uno::XInterface > > aSequence(1); 405 aSequence[0] = pLabeledBy->GetAccessible(); 406 pRelationSetHelper->AddRelation( accessibility::AccessibleRelation( accessibility::AccessibleRelationType::LABELED_BY, aSequence ) ); 407 } 408 Window* pMemberOf = pWindow->GetAccessibleRelationMemberOf(); 409 if ( pMemberOf && pMemberOf != pWindow ) 410 { 411 uno::Sequence< uno::Reference< uno::XInterface > > aSequence(1); 412 aSequence[0] = pMemberOf->GetAccessible(); 413 pRelationSetHelper->AddRelation( accessibility::AccessibleRelation( accessibility::AccessibleRelationType::MEMBER_OF, aSequence ) ); 414 } 415 } 416 return xSet; 417 //-----IAccessibility2 Implementation 2009 418 } 419 //IAccessibility2 Implementation 2009----- 420 //Solution:Add the event handling method 421 void SvxRectCtlAccessibleContext::FireAccessibleEvent (short nEventId, const ::com::sun::star::uno::Any& rOld, const ::com::sun::star::uno::Any& rNew) 422 { 423 const Reference< XInterface > xSource( *this ); 424 CommitChange( AccessibleEventObject( xSource, nEventId, rNew,rOld ) ); 425 } 426 //-----IAccessibility2 Implementation 2009 427 Reference< XAccessibleStateSet > SAL_CALL SvxRectCtlAccessibleContext::getAccessibleStateSet( void ) throw( RuntimeException ) 428 { 429 ::osl::MutexGuard aGuard( m_aMutex ); 430 utl::AccessibleStateSetHelper* pStateSetHelper = new utl::AccessibleStateSetHelper; 431 432 if( IsAlive() ) 433 { 434 //IAccessibility2 Implementation 2009----- 435 pStateSetHelper->AddState( AccessibleStateType::ENABLED ); 436 // pStateSetHelper->AddState( AccessibleStateType::SENSITIVE ); 437 //-----IAccessibility2 Implementation 2009 438 pStateSetHelper->AddState( AccessibleStateType::FOCUSABLE ); 439 if( mpRepr->HasFocus() ) 440 pStateSetHelper->AddState( AccessibleStateType::FOCUSED ); 441 pStateSetHelper->AddState( AccessibleStateType::OPAQUE ); 442 443 if( isShowing() ) 444 pStateSetHelper->AddState( AccessibleStateType::SHOWING ); 445 446 if( isVisible() ) 447 pStateSetHelper->AddState( AccessibleStateType::VISIBLE ); 448 } 449 else 450 pStateSetHelper->AddState( AccessibleStateType::DEFUNC ); 451 452 return pStateSetHelper; 453 } 454 455 lang::Locale SAL_CALL SvxRectCtlAccessibleContext::getLocale( void ) throw( IllegalAccessibleComponentStateException, RuntimeException ) 456 { 457 ::osl::MutexGuard aGuard( m_aMutex ); 458 if( mxParent.is() ) 459 { 460 Reference< XAccessibleContext > xParentContext( mxParent->getAccessibleContext() ); 461 if( xParentContext.is() ) 462 return xParentContext->getLocale(); 463 } 464 465 // No parent. Therefore throw exception to indicate this cluelessness. 466 throw IllegalAccessibleComponentStateException(); 467 } 468 469 void SAL_CALL SvxRectCtlAccessibleContext::addEventListener( const Reference< XAccessibleEventListener >& xListener ) 470 throw( RuntimeException ) 471 { 472 if (xListener.is()) 473 { 474 ::osl::MutexGuard aGuard( m_aMutex ); 475 if (!mnClientId) 476 mnClientId = comphelper::AccessibleEventNotifier::registerClient( ); 477 comphelper::AccessibleEventNotifier::addEventListener( mnClientId, xListener ); 478 } 479 } 480 481 void SAL_CALL SvxRectCtlAccessibleContext::removeEventListener( const Reference< XAccessibleEventListener >& xListener ) 482 throw( RuntimeException ) 483 { 484 if (xListener.is()) 485 { 486 ::osl::MutexGuard aGuard( m_aMutex ); 487 488 sal_Int32 nListenerCount = comphelper::AccessibleEventNotifier::removeEventListener( mnClientId, xListener ); 489 if ( !nListenerCount ) 490 { 491 // no listeners anymore 492 // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client), 493 // and at least to us not firing any events anymore, in case somebody calls 494 // NotifyAccessibleEvent, again 495 comphelper::AccessibleEventNotifier::revokeClient( mnClientId ); 496 mnClientId = 0; 497 } 498 } 499 } 500 501 void SAL_CALL SvxRectCtlAccessibleContext::addFocusListener( const Reference< awt::XFocusListener >& xListener ) 502 throw( RuntimeException ) 503 { 504 if( xListener.is() ) 505 { 506 ::osl::MutexGuard aGuard( m_aMutex ); 507 508 ThrowExceptionIfNotAlive(); 509 510 Reference< awt::XWindow > xWindow = VCLUnoHelper::GetInterface( mpRepr ); 511 if( xWindow.is() ) 512 xWindow->addFocusListener( xListener ); 513 } 514 } 515 516 void SAL_CALL SvxRectCtlAccessibleContext::removeFocusListener( const Reference< awt::XFocusListener >& xListener ) 517 throw (RuntimeException) 518 { 519 if( xListener.is() ) 520 { 521 ::osl::MutexGuard aGuard( m_aMutex ); 522 523 ThrowExceptionIfNotAlive(); 524 525 Reference< awt::XWindow > xWindow = VCLUnoHelper::GetInterface( mpRepr ); 526 if( xWindow.is() ) 527 xWindow->removeFocusListener( xListener ); 528 } 529 } 530 531 void SAL_CALL SvxRectCtlAccessibleContext::grabFocus() throw( RuntimeException ) 532 { 533 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 534 ::osl::MutexGuard aGuard( m_aMutex ); 535 536 ThrowExceptionIfNotAlive(); 537 538 mpRepr->GrabFocus(); 539 } 540 541 Any SAL_CALL SvxRectCtlAccessibleContext::getAccessibleKeyBinding() throw( RuntimeException ) 542 { 543 // here is no implementation, because here are no KeyBindings for every object 544 return Any(); 545 } 546 547 sal_Int32 SvxRectCtlAccessibleContext::getForeground( ) 548 throw (::com::sun::star::uno::RuntimeException) 549 { 550 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 551 ::osl::MutexGuard aGuard( m_aMutex ); 552 ThrowExceptionIfNotAlive(); 553 554 return mpRepr->GetControlForeground().GetColor(); 555 } 556 sal_Int32 SvxRectCtlAccessibleContext::getBackground( ) 557 throw (::com::sun::star::uno::RuntimeException) 558 { 559 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 560 ::osl::MutexGuard aGuard( m_aMutex ); 561 ThrowExceptionIfNotAlive(); 562 563 return mpRepr->GetControlBackground().GetColor(); 564 } 565 566 //===== XServiceInfo ======================================================== 567 568 ::rtl::OUString SAL_CALL SvxRectCtlAccessibleContext::getImplementationName( void ) throw( RuntimeException ) 569 { 570 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.ui.SvxRectCtlAccessibleContext" ) ); 571 } 572 573 sal_Bool SAL_CALL SvxRectCtlAccessibleContext::supportsService( const ::rtl::OUString& sServiceName ) throw( RuntimeException ) 574 { 575 ::osl::MutexGuard aGuard( m_aMutex ); 576 // Iterate over all supported service names and return true if on of them 577 // matches the given name. 578 Sequence< ::rtl::OUString > aSupportedServices( getSupportedServiceNames() ); 579 int nLength = aSupportedServices.getLength(); 580 const ::rtl::OUString* pStr = aSupportedServices.getConstArray(); 581 582 for( int i = nLength ; i ; --i, ++pStr ) 583 { 584 if( sServiceName == *pStr ) 585 return sal_True; 586 } 587 588 return sal_False; 589 } 590 591 Sequence< ::rtl::OUString > SAL_CALL SvxRectCtlAccessibleContext::getSupportedServiceNames( void ) throw( RuntimeException ) 592 { 593 const ::rtl::OUString sServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.accessibility.AccessibleContext" ) ); 594 return Sequence< ::rtl::OUString >( &sServiceName, 1 ); 595 } 596 597 //===== XTypeProvider ======================================================= 598 599 Sequence< sal_Int8 > SAL_CALL SvxRectCtlAccessibleContext::getImplementationId( void ) throw( RuntimeException ) 600 { 601 return getUniqueId(); 602 } 603 604 //===== XAccessibleSelection ============================================= 605 606 void SAL_CALL SvxRectCtlAccessibleContext::selectAccessibleChild( sal_Int32 nIndex ) throw( lang::IndexOutOfBoundsException, RuntimeException ) 607 { 608 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 609 610 ::osl::MutexGuard aGuard( m_aMutex ); 611 612 checkChildIndex( nIndex ); 613 614 ThrowExceptionIfNotAlive(); 615 616 const ChildIndexToPointData* pData = IndexToPoint( nIndex, mbAngleMode ); 617 618 DBG_ASSERT( pData, 619 "SvxRectCtlAccessibleContext::selectAccessibleChild(): this is an impossible state! Or at least should be..." ); 620 621 // this does all wich is needed, including the change of the child's state! 622 mpRepr->SetActualRP( pData->ePoint ); 623 } 624 625 sal_Bool SAL_CALL SvxRectCtlAccessibleContext::isAccessibleChildSelected( sal_Int32 nIndex ) throw( lang::IndexOutOfBoundsException, RuntimeException ) 626 { 627 ::osl::MutexGuard aGuard( m_aMutex ); 628 629 checkChildIndex( nIndex ); 630 631 return nIndex == mnSelectedChild; 632 } 633 634 void SAL_CALL SvxRectCtlAccessibleContext::clearAccessibleSelection() throw( RuntimeException ) 635 { 636 DBG_ASSERT( sal_False, "SvxRectCtlAccessibleContext::clearAccessibleSelection() is not possible!" ); 637 } 638 639 void SAL_CALL SvxRectCtlAccessibleContext::selectAllAccessibleChildren() throw( RuntimeException ) 640 { 641 // guard in selectAccessibleChild()! 642 643 selectAccessibleChild( 0 ); // default per definition 644 } 645 646 sal_Int32 SAL_CALL SvxRectCtlAccessibleContext::getSelectedAccessibleChildCount() throw( RuntimeException ) 647 { 648 ::osl::MutexGuard aGuard( m_aMutex ); 649 650 return mnSelectedChild == NOCHILDSELECTED? 0 : 1; 651 } 652 653 Reference< XAccessible > SAL_CALL SvxRectCtlAccessibleContext::getSelectedAccessibleChild( sal_Int32 nIndex ) 654 throw( lang::IndexOutOfBoundsException, RuntimeException ) 655 { 656 ::osl::MutexGuard aGuard( m_aMutex ); 657 658 checkChildIndexOnSelection( nIndex ); 659 660 return getAccessibleChild( mnSelectedChild ); 661 } 662 663 void SAL_CALL SvxRectCtlAccessibleContext::deselectAccessibleChild( sal_Int32 /*nIndex*/ ) throw( lang::IndexOutOfBoundsException, RuntimeException ) 664 { 665 ::rtl::OUString aMessage( RTL_CONSTASCII_USTRINGPARAM( "deselectAccessibleChild is not possible in this context" ) ); 666 667 DBG_ASSERT( sal_False, "SvxRectCtlAccessibleContext::deselectAccessibleChild() is not possible!" ); 668 669 throw lang::IndexOutOfBoundsException( aMessage, *this ); // never possible 670 } 671 672 //===== internals ======================================================== 673 674 void SvxRectCtlAccessibleContext::checkChildIndex( long nIndex ) throw( lang::IndexOutOfBoundsException ) 675 { 676 if( nIndex < 0 || nIndex >= getAccessibleChildCount() ) 677 throw lang::IndexOutOfBoundsException(); 678 } 679 680 void SvxRectCtlAccessibleContext::checkChildIndexOnSelection( long nIndex ) throw( lang::IndexOutOfBoundsException ) 681 { 682 if( nIndex || mnSelectedChild == NOCHILDSELECTED ) 683 // in our case only for the first (0) _selected_ child this is a valid request 684 throw lang::IndexOutOfBoundsException(); 685 } 686 // IAccessibility2 implementation 2009. ------ 687 void SvxRectCtlAccessibleContext::FireChildFocus( RECT_POINT eButton ) 688 { 689 ::osl::MutexGuard aGuard( m_aMutex ); 690 long nNew = PointToIndex( eButton, mbAngleMode ); 691 long nNumOfChilds = getAccessibleChildCount(); 692 if( nNew < nNumOfChilds ) 693 { 694 // select new child 695 SvxRectCtlChildAccessibleContext* pChild; 696 mnSelectedChild = nNew; 697 if( nNew != NOCHILDSELECTED ) 698 { 699 pChild = mpChilds[ nNew ]; 700 if( pChild ) 701 { 702 pChild->FireFocusEvent(); 703 } 704 } 705 else 706 { 707 const Reference< XInterface > xSource( *this ); 708 Any aOld; 709 Any aNew; 710 aNew <<= AccessibleStateType::FOCUSED; 711 CommitChange( AccessibleEventObject( xSource, AccessibleEventId::STATE_CHANGED, aNew, aOld ) ); 712 } 713 } 714 else 715 mnSelectedChild = NOCHILDSELECTED; 716 } 717 void SvxRectCtlAccessibleContext::selectChild( long nNew, sal_Bool bFireFocus ) 718 { 719 ::osl::MutexGuard aGuard( m_aMutex ); 720 if( nNew != mnSelectedChild ) 721 { 722 long nNumOfChilds = getAccessibleChildCount(); 723 if( nNew < nNumOfChilds ) 724 { // valid index 725 SvxRectCtlChildAccessibleContext* pChild; 726 if( mnSelectedChild != NOCHILDSELECTED ) 727 { // deselect old selected child if one is selected 728 pChild = mpChilds[ mnSelectedChild ]; 729 if( pChild ) 730 pChild->setStateChecked( sal_False, bFireFocus ); 731 } 732 733 // select new child 734 mnSelectedChild = nNew; 735 736 if( nNew != NOCHILDSELECTED ) 737 { 738 pChild = mpChilds[ nNew ]; 739 if( pChild ) 740 pChild->setStateChecked( sal_True, bFireFocus ); 741 } 742 } 743 else 744 mnSelectedChild = NOCHILDSELECTED; 745 } 746 } 747 748 void SvxRectCtlAccessibleContext::selectChild( RECT_POINT eButton , sal_Bool bFireFocus) 749 { 750 // no guard -> is done in next selectChild 751 selectChild( PointToIndex( eButton, mbAngleMode ) , bFireFocus); 752 } 753 // ------ IAccessibility2 implementation 2009. 754 void SvxRectCtlAccessibleContext::setName( const ::rtl::OUString& rName ) 755 { 756 Any aPreVal, aPostVal; 757 { 758 ::osl::MutexGuard aGuard( m_aMutex ); 759 760 aPreVal <<= msName; 761 aPostVal <<= rName; 762 763 msName = rName; 764 } 765 766 const Reference< XInterface > xSource( *this ); 767 CommitChange( AccessibleEventObject( xSource, AccessibleEventId::NAME_CHANGED, aPreVal, aPostVal ) ); 768 } 769 770 void SvxRectCtlAccessibleContext::setDescription( const ::rtl::OUString& rDescr ) 771 { 772 Any aPreVal, aPostVal; 773 { 774 ::osl::MutexGuard aGuard( m_aMutex ); 775 776 aPreVal <<= msDescription; 777 aPostVal <<= rDescr; 778 779 msDescription = rDescr; 780 } 781 782 const Reference< XInterface > xSource( *this ); 783 CommitChange( AccessibleEventObject( xSource, AccessibleEventId::DESCRIPTION_CHANGED, aPreVal, aPostVal ) ); 784 } 785 786 void SvxRectCtlAccessibleContext::CommitChange( const AccessibleEventObject& rEvent ) 787 { 788 if (mnClientId) 789 comphelper::AccessibleEventNotifier::addEvent( mnClientId, rEvent ); 790 } 791 792 void SAL_CALL SvxRectCtlAccessibleContext::disposing() 793 { 794 if( !rBHelper.bDisposed ) 795 { 796 { 797 ::osl::MutexGuard aGuard( m_aMutex ); 798 mpRepr = NULL; // object dies with representation 799 800 SvxRectCtlChildAccessibleContext** p = mpChilds; 801 for( int i = MAX_NUM_OF_CHILDS ; i ; --i, ++p ) 802 { 803 SvxRectCtlChildAccessibleContext* pChild = *p; 804 if( pChild ) 805 { 806 pChild->dispose(); 807 pChild->release(); 808 *p = NULL; 809 } 810 } 811 812 delete[] mpChilds; 813 mpChilds = NULL; 814 } 815 816 { 817 ::osl::MutexGuard aGuard( m_aMutex ); 818 819 // Send a disposing to all listeners. 820 if ( mnClientId ) 821 { 822 comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( mnClientId, *this ); 823 mnClientId = 0; 824 } 825 826 mxParent = Reference< XAccessible >(); 827 } 828 } 829 } 830 831 Rectangle SvxRectCtlAccessibleContext::GetBoundingBoxOnScreen( void ) throw( RuntimeException ) 832 { 833 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 834 ::osl::MutexGuard aGuard( m_aMutex ); 835 836 ThrowExceptionIfNotAlive(); 837 838 return Rectangle( mpRepr->GetParent()->OutputToScreenPixel( mpRepr->GetPosPixel() ), mpRepr->GetSizePixel() ); 839 } 840 841 Rectangle SvxRectCtlAccessibleContext::GetBoundingBox( void ) throw( RuntimeException ) 842 { 843 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 844 ::osl::MutexGuard aGuard( m_aMutex ); 845 846 ThrowExceptionIfNotAlive(); 847 848 return Rectangle( mpRepr->GetPosPixel(), mpRepr->GetSizePixel() ); 849 } 850 851 Sequence< sal_Int8 > SvxRectCtlAccessibleContext::getUniqueId( void ) 852 { 853 static OImplementationId* pId = 0; 854 if( !pId ) 855 { 856 MutexGuard aGuard( Mutex::getGlobalMutex() ); 857 if( !pId) 858 { 859 static OImplementationId aId; 860 pId = &aId; 861 } 862 } 863 return pId->getImplementationId(); 864 } 865 866 void SvxRectCtlAccessibleContext::ThrowExceptionIfNotAlive( void ) throw( lang::DisposedException ) 867 { 868 if( IsNotAlive() ) 869 throw lang::DisposedException(); 870 } 871 872 // ------------------------------------------------------------------------------------------------- 873 874 875 DBG_NAME( SvxRectCtlChildAccessibleContext ) 876 877 878 SvxRectCtlChildAccessibleContext::SvxRectCtlChildAccessibleContext( 879 const Reference<XAccessible>& rxParent, 880 const Window& rParentWindow, 881 const ::rtl::OUString& rName, 882 const ::rtl::OUString& rDescription, 883 const Rectangle& rBoundingBox, 884 long nIndexInParent ) : 885 886 SvxRectCtlChildAccessibleContext_Base( maMutex ), 887 msDescription( rDescription ), 888 msName( rName ), 889 mxParent(rxParent), 890 mpBoundingBox( new Rectangle( rBoundingBox ) ), 891 mrParentWindow( rParentWindow ), 892 mnClientId( 0 ), 893 mnIndexInParent( nIndexInParent ), 894 mbIsChecked( sal_False ) 895 { 896 DBG_CTOR( SvxRectCtlChildAccessibleContext, NULL ); 897 } 898 899 900 SvxRectCtlChildAccessibleContext::~SvxRectCtlChildAccessibleContext() 901 { 902 DBG_DTOR( SvxRectCtlChildAccessibleContext, NULL ); 903 904 if( IsAlive() ) 905 { 906 osl_incrementInterlockedCount( &m_refCount ); 907 dispose(); // set mpRepr = NULL & release all childs 908 } 909 } 910 911 //===== XAccessible ========================================================= 912 913 Reference< XAccessibleContext> SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleContext( void ) throw( RuntimeException ) 914 { 915 return this; 916 } 917 918 //===== XAccessibleComponent ================================================ 919 920 sal_Bool SAL_CALL SvxRectCtlChildAccessibleContext::containsPoint( const awt::Point& rPoint ) throw( RuntimeException ) 921 { 922 // no guard -> done in getBounds() 923 // return GetBoundingBox().IsInside( VCLPoint( rPoint ) ); 924 return Rectangle( Point( 0, 0 ), GetBoundingBox().GetSize() ).IsInside( VCLPoint( rPoint ) ); 925 } 926 927 Reference< XAccessible > SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleAtPoint( const awt::Point& /*rPoint*/ ) throw( RuntimeException ) 928 { 929 return Reference< XAccessible >(); 930 } 931 932 awt::Rectangle SAL_CALL SvxRectCtlChildAccessibleContext::getBounds() throw( RuntimeException ) 933 { 934 // no guard -> done in getBoundingBox() 935 return AWTRectangle( GetBoundingBox() ); 936 } 937 938 awt::Point SAL_CALL SvxRectCtlChildAccessibleContext::getLocation() throw( RuntimeException ) 939 { 940 // no guard -> done in getBoundingBox() 941 return AWTPoint( GetBoundingBox().TopLeft() ); 942 } 943 944 awt::Point SAL_CALL SvxRectCtlChildAccessibleContext::getLocationOnScreen() throw( RuntimeException ) 945 { 946 // no guard -> done in getBoundingBoxOnScreen() 947 return AWTPoint( GetBoundingBoxOnScreen().TopLeft() ); 948 } 949 950 awt::Size SAL_CALL SvxRectCtlChildAccessibleContext::getSize() throw( RuntimeException ) 951 { 952 // no guard -> done in getBoundingBox() 953 return AWTSize( GetBoundingBox().GetSize() ); 954 } 955 956 sal_Bool SAL_CALL SvxRectCtlChildAccessibleContext::isShowing() throw( RuntimeException ) 957 { 958 return sal_True; 959 } 960 961 sal_Bool SAL_CALL SvxRectCtlChildAccessibleContext::isVisible() throw( RuntimeException ) 962 { 963 ::osl::MutexGuard aGuard( maMutex ); 964 965 ThrowExceptionIfNotAlive(); 966 967 return mxParent.is()? ( static_cast< SvxRectCtlAccessibleContext* >( mxParent.get() ) )->isVisible() : sal_False; 968 } 969 970 sal_Bool SAL_CALL SvxRectCtlChildAccessibleContext::isFocusTraversable() throw( RuntimeException ) 971 { 972 return sal_False; 973 } 974 975 void SAL_CALL SvxRectCtlChildAccessibleContext::addFocusListener( const Reference< awt::XFocusListener >& /*xListener*/ ) 976 throw( RuntimeException ) 977 { 978 OSL_ENSURE( false, "SvxRectCtlChildAccessibleContext::addFocusListener: not implemented" ); 979 } 980 981 void SAL_CALL SvxRectCtlChildAccessibleContext::removeFocusListener( const Reference< awt::XFocusListener >& /*xListener*/ ) 982 throw (RuntimeException) 983 { 984 OSL_ENSURE( false, "SvxRectCtlChildAccessibleContext::removeFocusListener: not implemented" ); 985 } 986 987 void SAL_CALL SvxRectCtlChildAccessibleContext::grabFocus() throw( RuntimeException ) 988 { 989 } 990 991 Any SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleKeyBinding() throw( RuntimeException ) 992 { 993 // here is no implementation, because here are no KeyBindings for every object 994 return Any(); 995 } 996 sal_Int32 SvxRectCtlChildAccessibleContext::getForeground( ) 997 throw (::com::sun::star::uno::RuntimeException) 998 { 999 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 1000 ::osl::MutexGuard aGuard( maMutex ); 1001 ThrowExceptionIfNotAlive(); 1002 return mrParentWindow.GetControlForeground().GetColor(); 1003 } 1004 sal_Int32 SvxRectCtlChildAccessibleContext::getBackground( ) 1005 throw (::com::sun::star::uno::RuntimeException) 1006 { 1007 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 1008 ::osl::MutexGuard aGuard( maMutex ); 1009 1010 ThrowExceptionIfNotAlive(); 1011 return mrParentWindow.GetControlBackground().GetColor(); 1012 } 1013 1014 //===== XAccessibleContext ================================================== 1015 1016 sal_Int32 SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleChildCount( void ) throw( RuntimeException ) 1017 { 1018 return 0; 1019 } 1020 1021 Reference< XAccessible > SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleChild( sal_Int32 /*nIndex*/ ) throw ( RuntimeException, lang::IndexOutOfBoundsException ) 1022 { 1023 throw lang::IndexOutOfBoundsException(); 1024 } 1025 1026 Reference< XAccessible > SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleParent( void ) throw( RuntimeException ) 1027 { 1028 return mxParent; 1029 } 1030 1031 sal_Int32 SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleIndexInParent( void ) throw( RuntimeException ) 1032 { 1033 return mnIndexInParent; 1034 } 1035 1036 sal_Int16 SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleRole( void ) throw( RuntimeException ) 1037 { 1038 return AccessibleRole::RADIO_BUTTON; 1039 } 1040 1041 ::rtl::OUString SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleDescription( void ) throw( RuntimeException ) 1042 { 1043 ::osl::MutexGuard aGuard( maMutex ); 1044 return msDescription; 1045 } 1046 1047 ::rtl::OUString SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleName( void ) throw( RuntimeException ) 1048 { 1049 ::osl::MutexGuard aGuard( maMutex ); 1050 return msName; 1051 } 1052 1053 /** Return empty reference to indicate that the relation set is not 1054 supported. 1055 */ 1056 Reference<XAccessibleRelationSet> SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleRelationSet( void ) throw( RuntimeException ) 1057 { 1058 //return Reference< XAccessibleRelationSet >(); 1059 //IAccessibility2 Implementation 2009----- 1060 utl::AccessibleRelationSetHelper* pRelationSetHelper = new utl::AccessibleRelationSetHelper; 1061 uno::Reference< accessibility::XAccessibleRelationSet > xSet = pRelationSetHelper; 1062 if( mxParent.is() ) 1063 { 1064 uno::Sequence< uno::Reference< uno::XInterface > > aSequence(1); 1065 aSequence[0] = mxParent; 1066 pRelationSetHelper->AddRelation( accessibility::AccessibleRelation( accessibility::AccessibleRelationType::MEMBER_OF, aSequence ) ); 1067 1068 } 1069 1070 return xSet; 1071 //-----IAccessibility2 Implementation 2009 1072 } 1073 1074 Reference< XAccessibleStateSet > SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleStateSet( void ) throw( RuntimeException ) 1075 { 1076 ::osl::MutexGuard aGuard( maMutex ); 1077 utl::AccessibleStateSetHelper* pStateSetHelper = new utl::AccessibleStateSetHelper; 1078 1079 if( IsAlive() ) 1080 { 1081 if( mbIsChecked ) 1082 { 1083 pStateSetHelper->AddState( AccessibleStateType::CHECKED ); 1084 // pStateSetHelper->AddState( AccessibleStateType::SELECTED ); 1085 } 1086 1087 pStateSetHelper->AddState( AccessibleStateType::ENABLED ); 1088 pStateSetHelper->AddState( AccessibleStateType::SENSITIVE ); 1089 pStateSetHelper->AddState( AccessibleStateType::OPAQUE ); 1090 pStateSetHelper->AddState( AccessibleStateType::SELECTABLE ); 1091 pStateSetHelper->AddState( AccessibleStateType::SHOWING ); 1092 pStateSetHelper->AddState( AccessibleStateType::VISIBLE ); 1093 } 1094 else 1095 pStateSetHelper->AddState( AccessibleStateType::DEFUNC ); 1096 1097 return pStateSetHelper; 1098 } 1099 1100 lang::Locale SAL_CALL SvxRectCtlChildAccessibleContext::getLocale( void ) throw( IllegalAccessibleComponentStateException, RuntimeException ) 1101 { 1102 ::osl::MutexGuard aGuard( maMutex ); 1103 if( mxParent.is() ) 1104 { 1105 Reference< XAccessibleContext > xParentContext( mxParent->getAccessibleContext() ); 1106 if( xParentContext.is() ) 1107 return xParentContext->getLocale(); 1108 } 1109 1110 // No locale and no parent. Therefore throw exception to indicate this 1111 // cluelessness. 1112 throw IllegalAccessibleComponentStateException(); 1113 } 1114 1115 void SAL_CALL SvxRectCtlChildAccessibleContext::addEventListener( const Reference< XAccessibleEventListener >& xListener ) 1116 throw( RuntimeException ) 1117 { 1118 if (xListener.is()) 1119 { 1120 ::osl::MutexGuard aGuard( maMutex ); 1121 if (!mnClientId) 1122 mnClientId = comphelper::AccessibleEventNotifier::registerClient( ); 1123 comphelper::AccessibleEventNotifier::addEventListener( mnClientId, xListener ); 1124 } 1125 } 1126 1127 1128 1129 1130 void SAL_CALL SvxRectCtlChildAccessibleContext::removeEventListener( const Reference< XAccessibleEventListener >& xListener ) 1131 throw( RuntimeException ) 1132 { 1133 if (xListener.is()) 1134 { 1135 ::osl::MutexGuard aGuard( maMutex ); 1136 1137 sal_Int32 nListenerCount = comphelper::AccessibleEventNotifier::removeEventListener( mnClientId, xListener ); 1138 if ( !nListenerCount ) 1139 { 1140 // no listeners anymore 1141 // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client), 1142 // and at least to us not firing any events anymore, in case somebody calls 1143 // NotifyAccessibleEvent, again 1144 comphelper::AccessibleEventNotifier::revokeClient( mnClientId ); 1145 mnClientId = 0; 1146 } 1147 } 1148 } 1149 1150 //===== XAccessibleValue ================================================ 1151 1152 Any SAL_CALL SvxRectCtlChildAccessibleContext::getCurrentValue() throw( RuntimeException ) 1153 { 1154 ThrowExceptionIfNotAlive(); 1155 1156 Any aRet; 1157 aRet <<= ( mbIsChecked? 1.0 : 0.0 ); 1158 return aRet; 1159 } 1160 1161 sal_Bool SAL_CALL SvxRectCtlChildAccessibleContext::setCurrentValue( const Any& /*aNumber*/ ) throw( RuntimeException ) 1162 { 1163 return sal_False; 1164 } 1165 1166 Any SAL_CALL SvxRectCtlChildAccessibleContext::getMaximumValue() throw( RuntimeException ) 1167 { 1168 Any aRet; 1169 aRet <<= 1.0; 1170 return aRet; 1171 } 1172 1173 Any SAL_CALL SvxRectCtlChildAccessibleContext::getMinimumValue() throw( RuntimeException ) 1174 { 1175 Any aRet; 1176 aRet <<= 0.0; 1177 return aRet; 1178 } 1179 1180 //IAccessibility2 Implementation 2009----- 1181 // ----------------------------------------------------------------------------- 1182 // XAccessibleAction 1183 // ----------------------------------------------------------------------------- 1184 1185 sal_Int32 SvxRectCtlChildAccessibleContext::getAccessibleActionCount( ) throw (RuntimeException) 1186 { 1187 ::osl::MutexGuard aGuard( maMutex ); 1188 1189 return 1; 1190 } 1191 1192 // ----------------------------------------------------------------------------- 1193 1194 sal_Bool SvxRectCtlChildAccessibleContext::doAccessibleAction ( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException) 1195 { 1196 ::osl::MutexGuard aGuard( maMutex ); 1197 1198 if ( nIndex < 0 || nIndex >= getAccessibleActionCount() ) 1199 throw IndexOutOfBoundsException(); 1200 1201 Reference<XAccessibleSelection> xSelection( mxParent, UNO_QUERY); 1202 1203 xSelection->selectAccessibleChild(mnIndexInParent); 1204 1205 return sal_True; 1206 } 1207 1208 // ----------------------------------------------------------------------------- 1209 1210 ::rtl::OUString SvxRectCtlChildAccessibleContext::getAccessibleActionDescription ( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException) 1211 { 1212 ::osl::MutexGuard aGuard( maMutex ); 1213 1214 if ( nIndex < 0 || nIndex >= getAccessibleActionCount() ) 1215 throw IndexOutOfBoundsException(); 1216 return ::rtl::OUString::createFromAscii("select"); 1217 } 1218 1219 // ----------------------------------------------------------------------------- 1220 1221 Reference< XAccessibleKeyBinding > SvxRectCtlChildAccessibleContext::getAccessibleActionKeyBinding( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException) 1222 { 1223 ::osl::MutexGuard aGuard( maMutex ); 1224 1225 if ( nIndex < 0 || nIndex >= getAccessibleActionCount() ) 1226 throw IndexOutOfBoundsException(); 1227 1228 return Reference< XAccessibleKeyBinding >(); 1229 } 1230 1231 //-----IAccessibility2 Implementation 2009 1232 1233 //===== XServiceInfo ======================================================== 1234 1235 ::rtl::OUString SAL_CALL SvxRectCtlChildAccessibleContext::getImplementationName( void ) throw( RuntimeException ) 1236 { 1237 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.ui.SvxRectCtlChildAccessibleContext" ) ); 1238 } 1239 1240 sal_Bool SAL_CALL SvxRectCtlChildAccessibleContext::supportsService( const ::rtl::OUString& sServiceName ) throw( RuntimeException ) 1241 { 1242 // Iterate over all supported service names and return true if on of them 1243 // matches the given name. 1244 ::osl::MutexGuard aGuard( maMutex ); 1245 Sequence< ::rtl::OUString > aSupportedServices ( getSupportedServiceNames() ); 1246 int nLength = aSupportedServices.getLength(); 1247 for( int i = 0 ; i < nLength; ++i ) 1248 { 1249 if( sServiceName == aSupportedServices[ i ] ) 1250 return sal_True; 1251 } 1252 1253 return sal_False; 1254 } 1255 1256 Sequence< ::rtl::OUString > SAL_CALL SvxRectCtlChildAccessibleContext::getSupportedServiceNames( void ) throw( RuntimeException ) 1257 { 1258 const ::rtl::OUString sServiceName (RTL_CONSTASCII_USTRINGPARAM ("com.sun.star.accessibility.AccessibleContext")); 1259 return Sequence< ::rtl::OUString >( &sServiceName, 1 ); 1260 } 1261 1262 //===== XTypeProvider ======================================================= 1263 1264 Sequence< sal_Int8 > SAL_CALL SvxRectCtlChildAccessibleContext::getImplementationId( void ) throw( RuntimeException ) 1265 { 1266 static OImplementationId* pId = 0; 1267 if( !pId ) 1268 { 1269 MutexGuard aGuard( Mutex::getGlobalMutex() ); 1270 if( !pId) 1271 { 1272 static OImplementationId aId; 1273 pId = &aId; 1274 } 1275 } 1276 return pId->getImplementationId(); 1277 } 1278 1279 //===== internal ============================================================ 1280 1281 void SvxRectCtlChildAccessibleContext::CommitChange( const AccessibleEventObject& rEvent ) 1282 { 1283 if (mnClientId) 1284 comphelper::AccessibleEventNotifier::addEvent( mnClientId, rEvent ); 1285 } 1286 1287 void SAL_CALL SvxRectCtlChildAccessibleContext::disposing() 1288 { 1289 if( !rBHelper.bDisposed ) 1290 { 1291 ::osl::MutexGuard aGuard( maMutex ); 1292 1293 // Send a disposing to all listeners. 1294 if ( mnClientId ) 1295 { 1296 comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( mnClientId, *this ); 1297 mnClientId = 0; 1298 } 1299 1300 mxParent = Reference< XAccessible >(); 1301 1302 delete mpBoundingBox; 1303 } 1304 } 1305 1306 void SvxRectCtlChildAccessibleContext::ThrowExceptionIfNotAlive( void ) throw( lang::DisposedException ) 1307 { 1308 if( IsNotAlive() ) 1309 throw lang::DisposedException(); 1310 } 1311 1312 Rectangle SvxRectCtlChildAccessibleContext::GetBoundingBoxOnScreen( void ) throw( RuntimeException ) 1313 { 1314 ::osl::MutexGuard aGuard( maMutex ); 1315 1316 // no ThrowExceptionIfNotAlive() because its done in GetBoundingBox() 1317 Rectangle aRect( GetBoundingBox() ); 1318 1319 return Rectangle( mrParentWindow.OutputToScreenPixel( aRect.TopLeft() ), aRect.GetSize() ); 1320 } 1321 1322 Rectangle SvxRectCtlChildAccessibleContext::GetBoundingBox( void ) throw( RuntimeException ) 1323 { 1324 // no guard neccessary, because no one changes mpBoundingBox after creating it 1325 ThrowExceptionIfNotAlive(); 1326 1327 return *mpBoundingBox; 1328 } 1329 // IAccessibility2 implementation 2009. ------ 1330 void SvxRectCtlChildAccessibleContext::setStateChecked( sal_Bool bChecked, sal_Bool bFireFocus ) 1331 { 1332 if( mbIsChecked != bChecked ) 1333 { 1334 mbIsChecked = bChecked; 1335 1336 const Reference< XInterface > xSource( *this ); 1337 1338 Any aOld; 1339 Any aNew; 1340 Any& rMod = bChecked? aNew : aOld; 1341 if( bFireFocus ) 1342 { 1343 //Solution: Send the STATE_CHANGED(Focused) event to accessible 1344 rMod <<= AccessibleStateType::FOCUSED; 1345 CommitChange( AccessibleEventObject( xSource, AccessibleEventId::STATE_CHANGED, aNew, aOld ) ); 1346 } 1347 rMod <<= AccessibleStateType::CHECKED; 1348 1349 CommitChange( AccessibleEventObject( xSource, AccessibleEventId::STATE_CHANGED, aNew, aOld ) ); 1350 } 1351 } 1352 1353 void SvxRectCtlChildAccessibleContext::FireFocusEvent() 1354 { 1355 const Reference< XInterface > xSource( *this ); 1356 Any aOld; 1357 Any aNew; 1358 aNew <<= AccessibleStateType::FOCUSED; 1359 CommitChange( AccessibleEventObject( xSource, AccessibleEventId::STATE_CHANGED, aNew, aOld ) ); 1360 } 1361 // ------ IAccessibility2 implementation 2009. 1362