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