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; 371 return msDescription +::rtl::OUString::createFromAscii(" Please use arrow key to selection."); 372 } 373 374 ::rtl::OUString SAL_CALL SvxRectCtlAccessibleContext::getAccessibleName( void ) throw( RuntimeException ) 375 { 376 ::osl::MutexGuard aGuard( m_aMutex ); 377 return msName; 378 } 379 380 /** Return empty reference to indicate that the relation set is not 381 supported. 382 */ 383 Reference< XAccessibleRelationSet > SAL_CALL SvxRectCtlAccessibleContext::getAccessibleRelationSet( void ) throw( RuntimeException ) 384 { 385 //return Reference< XAccessibleRelationSet >(); 386 utl::AccessibleRelationSetHelper* pRelationSetHelper = new utl::AccessibleRelationSetHelper; 387 uno::Reference< accessibility::XAccessibleRelationSet > xSet = pRelationSetHelper; 388 Window* pWindow = mpRepr; 389 if ( pWindow ) 390 { 391 // Window *pLabeledBy = pWindow->GetAccRelationLabeledBy(); 392 Window *pLabeledBy = pWindow->GetAccessibleRelationLabeledBy(); 393 if ( pLabeledBy && pLabeledBy != pWindow ) 394 { 395 uno::Sequence< uno::Reference< uno::XInterface > > aSequence(1); 396 aSequence[0] = pLabeledBy->GetAccessible(); 397 pRelationSetHelper->AddRelation( accessibility::AccessibleRelation( accessibility::AccessibleRelationType::LABELED_BY, aSequence ) ); 398 } 399 Window* pMemberOf = pWindow->GetAccessibleRelationMemberOf(); 400 if ( pMemberOf && pMemberOf != pWindow ) 401 { 402 uno::Sequence< uno::Reference< uno::XInterface > > aSequence(1); 403 aSequence[0] = pMemberOf->GetAccessible(); 404 pRelationSetHelper->AddRelation( accessibility::AccessibleRelation( accessibility::AccessibleRelationType::MEMBER_OF, aSequence ) ); 405 } 406 } 407 return xSet; 408 } 409 //Solution:Add the event handling method 410 void SvxRectCtlAccessibleContext::FireAccessibleEvent (short nEventId, const ::com::sun::star::uno::Any& rOld, const ::com::sun::star::uno::Any& rNew) 411 { 412 const Reference< XInterface > xSource( *this ); 413 CommitChange( AccessibleEventObject( xSource, nEventId, rNew,rOld ) ); 414 } 415 Reference< XAccessibleStateSet > SAL_CALL SvxRectCtlAccessibleContext::getAccessibleStateSet( void ) throw( RuntimeException ) 416 { 417 ::osl::MutexGuard aGuard( m_aMutex ); 418 utl::AccessibleStateSetHelper* pStateSetHelper = new utl::AccessibleStateSetHelper; 419 420 if( IsAlive() ) 421 { 422 pStateSetHelper->AddState( AccessibleStateType::ENABLED ); 423 // pStateSetHelper->AddState( AccessibleStateType::SENSITIVE ); 424 pStateSetHelper->AddState( AccessibleStateType::FOCUSABLE ); 425 if( mpRepr->HasFocus() ) 426 pStateSetHelper->AddState( AccessibleStateType::FOCUSED ); 427 pStateSetHelper->AddState( AccessibleStateType::OPAQUE ); 428 429 if( isShowing() ) 430 pStateSetHelper->AddState( AccessibleStateType::SHOWING ); 431 432 if( isVisible() ) 433 pStateSetHelper->AddState( AccessibleStateType::VISIBLE ); 434 } 435 else 436 pStateSetHelper->AddState( AccessibleStateType::DEFUNC ); 437 438 return pStateSetHelper; 439 } 440 441 lang::Locale SAL_CALL SvxRectCtlAccessibleContext::getLocale( void ) throw( IllegalAccessibleComponentStateException, RuntimeException ) 442 { 443 ::osl::MutexGuard aGuard( m_aMutex ); 444 if( mxParent.is() ) 445 { 446 Reference< XAccessibleContext > xParentContext( mxParent->getAccessibleContext() ); 447 if( xParentContext.is() ) 448 return xParentContext->getLocale(); 449 } 450 451 // No parent. Therefore throw exception to indicate this cluelessness. 452 throw IllegalAccessibleComponentStateException(); 453 } 454 455 void SAL_CALL SvxRectCtlAccessibleContext::addEventListener( const Reference< XAccessibleEventListener >& xListener ) 456 throw( RuntimeException ) 457 { 458 if (xListener.is()) 459 { 460 ::osl::MutexGuard aGuard( m_aMutex ); 461 if (!mnClientId) 462 mnClientId = comphelper::AccessibleEventNotifier::registerClient( ); 463 comphelper::AccessibleEventNotifier::addEventListener( mnClientId, xListener ); 464 } 465 } 466 467 void SAL_CALL SvxRectCtlAccessibleContext::removeEventListener( const Reference< XAccessibleEventListener >& xListener ) 468 throw( RuntimeException ) 469 { 470 if (xListener.is()) 471 { 472 ::osl::MutexGuard aGuard( m_aMutex ); 473 474 sal_Int32 nListenerCount = comphelper::AccessibleEventNotifier::removeEventListener( mnClientId, xListener ); 475 if ( !nListenerCount ) 476 { 477 // no listeners anymore 478 // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client), 479 // and at least to us not firing any events anymore, in case somebody calls 480 // NotifyAccessibleEvent, again 481 comphelper::AccessibleEventNotifier::revokeClient( mnClientId ); 482 mnClientId = 0; 483 } 484 } 485 } 486 487 void SAL_CALL SvxRectCtlAccessibleContext::addFocusListener( const Reference< awt::XFocusListener >& xListener ) 488 throw( RuntimeException ) 489 { 490 if( xListener.is() ) 491 { 492 ::osl::MutexGuard aGuard( m_aMutex ); 493 494 ThrowExceptionIfNotAlive(); 495 496 Reference< awt::XWindow > xWindow = VCLUnoHelper::GetInterface( mpRepr ); 497 if( xWindow.is() ) 498 xWindow->addFocusListener( xListener ); 499 } 500 } 501 502 void SAL_CALL SvxRectCtlAccessibleContext::removeFocusListener( const Reference< awt::XFocusListener >& xListener ) 503 throw (RuntimeException) 504 { 505 if( xListener.is() ) 506 { 507 ::osl::MutexGuard aGuard( m_aMutex ); 508 509 ThrowExceptionIfNotAlive(); 510 511 Reference< awt::XWindow > xWindow = VCLUnoHelper::GetInterface( mpRepr ); 512 if( xWindow.is() ) 513 xWindow->removeFocusListener( xListener ); 514 } 515 } 516 517 void SAL_CALL SvxRectCtlAccessibleContext::grabFocus() throw( RuntimeException ) 518 { 519 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 520 ::osl::MutexGuard aGuard( m_aMutex ); 521 522 ThrowExceptionIfNotAlive(); 523 524 mpRepr->GrabFocus(); 525 } 526 527 Any SAL_CALL SvxRectCtlAccessibleContext::getAccessibleKeyBinding() throw( RuntimeException ) 528 { 529 // here is no implementation, because here are no KeyBindings for every object 530 return Any(); 531 } 532 533 sal_Int32 SvxRectCtlAccessibleContext::getForeground( ) 534 throw (::com::sun::star::uno::RuntimeException) 535 { 536 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 537 ::osl::MutexGuard aGuard( m_aMutex ); 538 ThrowExceptionIfNotAlive(); 539 540 return mpRepr->GetControlForeground().GetColor(); 541 } 542 sal_Int32 SvxRectCtlAccessibleContext::getBackground( ) 543 throw (::com::sun::star::uno::RuntimeException) 544 { 545 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 546 ::osl::MutexGuard aGuard( m_aMutex ); 547 ThrowExceptionIfNotAlive(); 548 549 return mpRepr->GetControlBackground().GetColor(); 550 } 551 552 //===== XServiceInfo ======================================================== 553 554 ::rtl::OUString SAL_CALL SvxRectCtlAccessibleContext::getImplementationName( void ) throw( RuntimeException ) 555 { 556 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.ui.SvxRectCtlAccessibleContext" ) ); 557 } 558 559 sal_Bool SAL_CALL SvxRectCtlAccessibleContext::supportsService( const ::rtl::OUString& sServiceName ) throw( RuntimeException ) 560 { 561 ::osl::MutexGuard aGuard( m_aMutex ); 562 // Iterate over all supported service names and return true if on of them 563 // matches the given name. 564 Sequence< ::rtl::OUString > aSupportedServices( getSupportedServiceNames() ); 565 int nLength = aSupportedServices.getLength(); 566 const ::rtl::OUString* pStr = aSupportedServices.getConstArray(); 567 568 for( int i = nLength ; i ; --i, ++pStr ) 569 { 570 if( sServiceName == *pStr ) 571 return sal_True; 572 } 573 574 return sal_False; 575 } 576 577 Sequence< ::rtl::OUString > SAL_CALL SvxRectCtlAccessibleContext::getSupportedServiceNames( void ) throw( RuntimeException ) 578 { 579 const ::rtl::OUString sServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.accessibility.AccessibleContext" ) ); 580 return Sequence< ::rtl::OUString >( &sServiceName, 1 ); 581 } 582 583 //===== XTypeProvider ======================================================= 584 585 Sequence< sal_Int8 > SAL_CALL SvxRectCtlAccessibleContext::getImplementationId( void ) throw( RuntimeException ) 586 { 587 return getUniqueId(); 588 } 589 590 //===== XAccessibleSelection ============================================= 591 592 void SAL_CALL SvxRectCtlAccessibleContext::selectAccessibleChild( sal_Int32 nIndex ) throw( lang::IndexOutOfBoundsException, RuntimeException ) 593 { 594 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 595 596 ::osl::MutexGuard aGuard( m_aMutex ); 597 598 checkChildIndex( nIndex ); 599 600 ThrowExceptionIfNotAlive(); 601 602 const ChildIndexToPointData* pData = IndexToPoint( nIndex, mbAngleMode ); 603 604 DBG_ASSERT( pData, 605 "SvxRectCtlAccessibleContext::selectAccessibleChild(): this is an impossible state! Or at least should be..." ); 606 607 // this does all wich is needed, including the change of the child's state! 608 mpRepr->SetActualRP( pData->ePoint ); 609 } 610 611 sal_Bool SAL_CALL SvxRectCtlAccessibleContext::isAccessibleChildSelected( sal_Int32 nIndex ) throw( lang::IndexOutOfBoundsException, RuntimeException ) 612 { 613 ::osl::MutexGuard aGuard( m_aMutex ); 614 615 checkChildIndex( nIndex ); 616 617 return nIndex == mnSelectedChild; 618 } 619 620 void SAL_CALL SvxRectCtlAccessibleContext::clearAccessibleSelection() throw( RuntimeException ) 621 { 622 DBG_ASSERT( sal_False, "SvxRectCtlAccessibleContext::clearAccessibleSelection() is not possible!" ); 623 } 624 625 void SAL_CALL SvxRectCtlAccessibleContext::selectAllAccessibleChildren() throw( RuntimeException ) 626 { 627 // guard in selectAccessibleChild()! 628 629 selectAccessibleChild( 0 ); // default per definition 630 } 631 632 sal_Int32 SAL_CALL SvxRectCtlAccessibleContext::getSelectedAccessibleChildCount() throw( RuntimeException ) 633 { 634 ::osl::MutexGuard aGuard( m_aMutex ); 635 636 return mnSelectedChild == NOCHILDSELECTED? 0 : 1; 637 } 638 639 Reference< XAccessible > SAL_CALL SvxRectCtlAccessibleContext::getSelectedAccessibleChild( sal_Int32 nIndex ) 640 throw( lang::IndexOutOfBoundsException, RuntimeException ) 641 { 642 ::osl::MutexGuard aGuard( m_aMutex ); 643 644 checkChildIndexOnSelection( nIndex ); 645 646 return getAccessibleChild( mnSelectedChild ); 647 } 648 649 void SAL_CALL SvxRectCtlAccessibleContext::deselectAccessibleChild( sal_Int32 /*nIndex*/ ) throw( lang::IndexOutOfBoundsException, RuntimeException ) 650 { 651 ::rtl::OUString aMessage( RTL_CONSTASCII_USTRINGPARAM( "deselectAccessibleChild is not possible in this context" ) ); 652 653 DBG_ASSERT( sal_False, "SvxRectCtlAccessibleContext::deselectAccessibleChild() is not possible!" ); 654 655 throw lang::IndexOutOfBoundsException( aMessage, *this ); // never possible 656 } 657 658 //===== internals ======================================================== 659 660 void SvxRectCtlAccessibleContext::checkChildIndex( long nIndex ) throw( lang::IndexOutOfBoundsException ) 661 { 662 if( nIndex < 0 || nIndex >= getAccessibleChildCount() ) 663 throw lang::IndexOutOfBoundsException(); 664 } 665 666 void SvxRectCtlAccessibleContext::checkChildIndexOnSelection( long nIndex ) throw( lang::IndexOutOfBoundsException ) 667 { 668 if( nIndex || mnSelectedChild == NOCHILDSELECTED ) 669 // in our case only for the first (0) _selected_ child this is a valid request 670 throw lang::IndexOutOfBoundsException(); 671 } 672 void SvxRectCtlAccessibleContext::FireChildFocus( RECT_POINT eButton ) 673 { 674 ::osl::MutexGuard aGuard( m_aMutex ); 675 long nNew = PointToIndex( eButton, mbAngleMode ); 676 long nNumOfChilds = getAccessibleChildCount(); 677 if( nNew < nNumOfChilds ) 678 { 679 // select new child 680 SvxRectCtlChildAccessibleContext* pChild; 681 mnSelectedChild = nNew; 682 if( nNew != NOCHILDSELECTED ) 683 { 684 pChild = mpChilds[ nNew ]; 685 if( pChild ) 686 { 687 pChild->FireFocusEvent(); 688 } 689 } 690 else 691 { 692 const Reference< XInterface > xSource( *this ); 693 Any aOld; 694 Any aNew; 695 aNew <<= AccessibleStateType::FOCUSED; 696 CommitChange( AccessibleEventObject( xSource, AccessibleEventId::STATE_CHANGED, aNew, aOld ) ); 697 } 698 } 699 else 700 mnSelectedChild = NOCHILDSELECTED; 701 } 702 void SvxRectCtlAccessibleContext::selectChild( long nNew, sal_Bool bFireFocus ) 703 { 704 ::osl::MutexGuard aGuard( m_aMutex ); 705 if( nNew != mnSelectedChild ) 706 { 707 long nNumOfChilds = getAccessibleChildCount(); 708 if( nNew < nNumOfChilds ) 709 { // valid index 710 SvxRectCtlChildAccessibleContext* pChild; 711 if( mnSelectedChild != NOCHILDSELECTED ) 712 { // deselect old selected child if one is selected 713 pChild = mpChilds[ mnSelectedChild ]; 714 if( pChild ) 715 pChild->setStateChecked( sal_False, bFireFocus ); 716 } 717 718 // select new child 719 mnSelectedChild = nNew; 720 721 if( nNew != NOCHILDSELECTED ) 722 { 723 pChild = mpChilds[ nNew ]; 724 if( pChild ) 725 pChild->setStateChecked( sal_True, bFireFocus ); 726 } 727 } 728 else 729 mnSelectedChild = NOCHILDSELECTED; 730 } 731 } 732 733 void SvxRectCtlAccessibleContext::selectChild( RECT_POINT eButton , sal_Bool bFireFocus) 734 { 735 // no guard -> is done in next selectChild 736 selectChild( PointToIndex( eButton, mbAngleMode ) , bFireFocus); 737 } 738 void SvxRectCtlAccessibleContext::setName( const ::rtl::OUString& rName ) 739 { 740 Any aPreVal, aPostVal; 741 { 742 ::osl::MutexGuard aGuard( m_aMutex ); 743 744 aPreVal <<= msName; 745 aPostVal <<= rName; 746 747 msName = rName; 748 } 749 750 const Reference< XInterface > xSource( *this ); 751 CommitChange( AccessibleEventObject( xSource, AccessibleEventId::NAME_CHANGED, aPreVal, aPostVal ) ); 752 } 753 754 void SvxRectCtlAccessibleContext::setDescription( const ::rtl::OUString& rDescr ) 755 { 756 Any aPreVal, aPostVal; 757 { 758 ::osl::MutexGuard aGuard( m_aMutex ); 759 760 aPreVal <<= msDescription; 761 aPostVal <<= rDescr; 762 763 msDescription = rDescr; 764 } 765 766 const Reference< XInterface > xSource( *this ); 767 CommitChange( AccessibleEventObject( xSource, AccessibleEventId::DESCRIPTION_CHANGED, aPreVal, aPostVal ) ); 768 } 769 770 void SvxRectCtlAccessibleContext::CommitChange( const AccessibleEventObject& rEvent ) 771 { 772 if (mnClientId) 773 comphelper::AccessibleEventNotifier::addEvent( mnClientId, rEvent ); 774 } 775 776 void SAL_CALL SvxRectCtlAccessibleContext::disposing() 777 { 778 if( !rBHelper.bDisposed ) 779 { 780 { 781 ::osl::MutexGuard aGuard( m_aMutex ); 782 mpRepr = NULL; // object dies with representation 783 784 SvxRectCtlChildAccessibleContext** p = mpChilds; 785 for( int i = MAX_NUM_OF_CHILDS ; i ; --i, ++p ) 786 { 787 SvxRectCtlChildAccessibleContext* pChild = *p; 788 if( pChild ) 789 { 790 pChild->dispose(); 791 pChild->release(); 792 *p = NULL; 793 } 794 } 795 796 delete[] mpChilds; 797 mpChilds = NULL; 798 } 799 800 { 801 ::osl::MutexGuard aGuard( m_aMutex ); 802 803 // Send a disposing to all listeners. 804 if ( mnClientId ) 805 { 806 comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( mnClientId, *this ); 807 mnClientId = 0; 808 } 809 810 mxParent = Reference< XAccessible >(); 811 } 812 } 813 } 814 815 Rectangle SvxRectCtlAccessibleContext::GetBoundingBoxOnScreen( void ) throw( RuntimeException ) 816 { 817 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 818 ::osl::MutexGuard aGuard( m_aMutex ); 819 820 ThrowExceptionIfNotAlive(); 821 822 return Rectangle( mpRepr->GetParent()->OutputToScreenPixel( mpRepr->GetPosPixel() ), mpRepr->GetSizePixel() ); 823 } 824 825 Rectangle SvxRectCtlAccessibleContext::GetBoundingBox( void ) throw( RuntimeException ) 826 { 827 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 828 ::osl::MutexGuard aGuard( m_aMutex ); 829 830 ThrowExceptionIfNotAlive(); 831 832 return Rectangle( mpRepr->GetPosPixel(), mpRepr->GetSizePixel() ); 833 } 834 835 Sequence< sal_Int8 > SvxRectCtlAccessibleContext::getUniqueId( void ) 836 { 837 static OImplementationId* pId = 0; 838 if( !pId ) 839 { 840 MutexGuard aGuard( Mutex::getGlobalMutex() ); 841 if( !pId) 842 { 843 static OImplementationId aId; 844 pId = &aId; 845 } 846 } 847 return pId->getImplementationId(); 848 } 849 850 void SvxRectCtlAccessibleContext::ThrowExceptionIfNotAlive( void ) throw( lang::DisposedException ) 851 { 852 if( IsNotAlive() ) 853 throw lang::DisposedException(); 854 } 855 856 // ------------------------------------------------------------------------------------------------- 857 858 859 DBG_NAME( SvxRectCtlChildAccessibleContext ) 860 861 862 SvxRectCtlChildAccessibleContext::SvxRectCtlChildAccessibleContext( 863 const Reference<XAccessible>& rxParent, 864 const Window& rParentWindow, 865 const ::rtl::OUString& rName, 866 const ::rtl::OUString& rDescription, 867 const Rectangle& rBoundingBox, 868 long nIndexInParent ) : 869 870 SvxRectCtlChildAccessibleContext_Base( maMutex ), 871 msDescription( rDescription ), 872 msName( rName ), 873 mxParent(rxParent), 874 mpBoundingBox( new Rectangle( rBoundingBox ) ), 875 mrParentWindow( rParentWindow ), 876 mnClientId( 0 ), 877 mnIndexInParent( nIndexInParent ), 878 mbIsChecked( sal_False ) 879 { 880 DBG_CTOR( SvxRectCtlChildAccessibleContext, NULL ); 881 } 882 883 884 SvxRectCtlChildAccessibleContext::~SvxRectCtlChildAccessibleContext() 885 { 886 DBG_DTOR( SvxRectCtlChildAccessibleContext, NULL ); 887 888 if( IsAlive() ) 889 { 890 osl_incrementInterlockedCount( &m_refCount ); 891 dispose(); // set mpRepr = NULL & release all childs 892 } 893 } 894 895 //===== XAccessible ========================================================= 896 897 Reference< XAccessibleContext> SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleContext( void ) throw( RuntimeException ) 898 { 899 return this; 900 } 901 902 //===== XAccessibleComponent ================================================ 903 904 sal_Bool SAL_CALL SvxRectCtlChildAccessibleContext::containsPoint( const awt::Point& rPoint ) throw( RuntimeException ) 905 { 906 // no guard -> done in getBounds() 907 // return GetBoundingBox().IsInside( VCLPoint( rPoint ) ); 908 return Rectangle( Point( 0, 0 ), GetBoundingBox().GetSize() ).IsInside( VCLPoint( rPoint ) ); 909 } 910 911 Reference< XAccessible > SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleAtPoint( const awt::Point& /*rPoint*/ ) throw( RuntimeException ) 912 { 913 return Reference< XAccessible >(); 914 } 915 916 awt::Rectangle SAL_CALL SvxRectCtlChildAccessibleContext::getBounds() throw( RuntimeException ) 917 { 918 // no guard -> done in getBoundingBox() 919 return AWTRectangle( GetBoundingBox() ); 920 } 921 922 awt::Point SAL_CALL SvxRectCtlChildAccessibleContext::getLocation() throw( RuntimeException ) 923 { 924 // no guard -> done in getBoundingBox() 925 return AWTPoint( GetBoundingBox().TopLeft() ); 926 } 927 928 awt::Point SAL_CALL SvxRectCtlChildAccessibleContext::getLocationOnScreen() throw( RuntimeException ) 929 { 930 // no guard -> done in getBoundingBoxOnScreen() 931 return AWTPoint( GetBoundingBoxOnScreen().TopLeft() ); 932 } 933 934 awt::Size SAL_CALL SvxRectCtlChildAccessibleContext::getSize() throw( RuntimeException ) 935 { 936 // no guard -> done in getBoundingBox() 937 return AWTSize( GetBoundingBox().GetSize() ); 938 } 939 940 sal_Bool SAL_CALL SvxRectCtlChildAccessibleContext::isShowing() throw( RuntimeException ) 941 { 942 return sal_True; 943 } 944 945 sal_Bool SAL_CALL SvxRectCtlChildAccessibleContext::isVisible() throw( RuntimeException ) 946 { 947 ::osl::MutexGuard aGuard( maMutex ); 948 949 ThrowExceptionIfNotAlive(); 950 951 return mxParent.is()? ( static_cast< SvxRectCtlAccessibleContext* >( mxParent.get() ) )->isVisible() : sal_False; 952 } 953 954 sal_Bool SAL_CALL SvxRectCtlChildAccessibleContext::isFocusTraversable() throw( RuntimeException ) 955 { 956 return sal_False; 957 } 958 959 void SAL_CALL SvxRectCtlChildAccessibleContext::addFocusListener( const Reference< awt::XFocusListener >& /*xListener*/ ) 960 throw( RuntimeException ) 961 { 962 OSL_ENSURE( false, "SvxRectCtlChildAccessibleContext::addFocusListener: not implemented" ); 963 } 964 965 void SAL_CALL SvxRectCtlChildAccessibleContext::removeFocusListener( const Reference< awt::XFocusListener >& /*xListener*/ ) 966 throw (RuntimeException) 967 { 968 OSL_ENSURE( false, "SvxRectCtlChildAccessibleContext::removeFocusListener: not implemented" ); 969 } 970 971 void SAL_CALL SvxRectCtlChildAccessibleContext::grabFocus() throw( RuntimeException ) 972 { 973 } 974 975 Any SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleKeyBinding() throw( RuntimeException ) 976 { 977 // here is no implementation, because here are no KeyBindings for every object 978 return Any(); 979 } 980 sal_Int32 SvxRectCtlChildAccessibleContext::getForeground( ) 981 throw (::com::sun::star::uno::RuntimeException) 982 { 983 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 984 ::osl::MutexGuard aGuard( maMutex ); 985 ThrowExceptionIfNotAlive(); 986 return mrParentWindow.GetControlForeground().GetColor(); 987 } 988 sal_Int32 SvxRectCtlChildAccessibleContext::getBackground( ) 989 throw (::com::sun::star::uno::RuntimeException) 990 { 991 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 992 ::osl::MutexGuard aGuard( maMutex ); 993 994 ThrowExceptionIfNotAlive(); 995 return mrParentWindow.GetControlBackground().GetColor(); 996 } 997 998 //===== XAccessibleContext ================================================== 999 1000 sal_Int32 SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleChildCount( void ) throw( RuntimeException ) 1001 { 1002 return 0; 1003 } 1004 1005 Reference< XAccessible > SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleChild( sal_Int32 /*nIndex*/ ) throw ( RuntimeException, lang::IndexOutOfBoundsException ) 1006 { 1007 throw lang::IndexOutOfBoundsException(); 1008 } 1009 1010 Reference< XAccessible > SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleParent( void ) throw( RuntimeException ) 1011 { 1012 return mxParent; 1013 } 1014 1015 sal_Int32 SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleIndexInParent( void ) throw( RuntimeException ) 1016 { 1017 return mnIndexInParent; 1018 } 1019 1020 sal_Int16 SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleRole( void ) throw( RuntimeException ) 1021 { 1022 return AccessibleRole::RADIO_BUTTON; 1023 } 1024 1025 ::rtl::OUString SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleDescription( void ) throw( RuntimeException ) 1026 { 1027 ::osl::MutexGuard aGuard( maMutex ); 1028 return msDescription; 1029 } 1030 1031 ::rtl::OUString SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleName( void ) throw( RuntimeException ) 1032 { 1033 ::osl::MutexGuard aGuard( maMutex ); 1034 return msName; 1035 } 1036 1037 /** Return empty reference to indicate that the relation set is not 1038 supported. 1039 */ 1040 Reference<XAccessibleRelationSet> SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleRelationSet( void ) throw( RuntimeException ) 1041 { 1042 //return Reference< XAccessibleRelationSet >(); 1043 utl::AccessibleRelationSetHelper* pRelationSetHelper = new utl::AccessibleRelationSetHelper; 1044 uno::Reference< accessibility::XAccessibleRelationSet > xSet = pRelationSetHelper; 1045 if( mxParent.is() ) 1046 { 1047 uno::Sequence< uno::Reference< uno::XInterface > > aSequence(1); 1048 aSequence[0] = mxParent; 1049 pRelationSetHelper->AddRelation( accessibility::AccessibleRelation( accessibility::AccessibleRelationType::MEMBER_OF, aSequence ) ); 1050 1051 } 1052 1053 return xSet; 1054 } 1055 1056 Reference< XAccessibleStateSet > SAL_CALL SvxRectCtlChildAccessibleContext::getAccessibleStateSet( void ) throw( RuntimeException ) 1057 { 1058 ::osl::MutexGuard aGuard( maMutex ); 1059 utl::AccessibleStateSetHelper* pStateSetHelper = new utl::AccessibleStateSetHelper; 1060 1061 if( IsAlive() ) 1062 { 1063 if( mbIsChecked ) 1064 { 1065 pStateSetHelper->AddState( AccessibleStateType::CHECKED ); 1066 // pStateSetHelper->AddState( AccessibleStateType::SELECTED ); 1067 } 1068 1069 pStateSetHelper->AddState( AccessibleStateType::ENABLED ); 1070 pStateSetHelper->AddState( AccessibleStateType::SENSITIVE ); 1071 pStateSetHelper->AddState( AccessibleStateType::OPAQUE ); 1072 pStateSetHelper->AddState( AccessibleStateType::SELECTABLE ); 1073 pStateSetHelper->AddState( AccessibleStateType::SHOWING ); 1074 pStateSetHelper->AddState( AccessibleStateType::VISIBLE ); 1075 } 1076 else 1077 pStateSetHelper->AddState( AccessibleStateType::DEFUNC ); 1078 1079 return pStateSetHelper; 1080 } 1081 1082 lang::Locale SAL_CALL SvxRectCtlChildAccessibleContext::getLocale( void ) throw( IllegalAccessibleComponentStateException, RuntimeException ) 1083 { 1084 ::osl::MutexGuard aGuard( maMutex ); 1085 if( mxParent.is() ) 1086 { 1087 Reference< XAccessibleContext > xParentContext( mxParent->getAccessibleContext() ); 1088 if( xParentContext.is() ) 1089 return xParentContext->getLocale(); 1090 } 1091 1092 // No locale and no parent. Therefore throw exception to indicate this 1093 // cluelessness. 1094 throw IllegalAccessibleComponentStateException(); 1095 } 1096 1097 void SAL_CALL SvxRectCtlChildAccessibleContext::addEventListener( const Reference< XAccessibleEventListener >& xListener ) 1098 throw( RuntimeException ) 1099 { 1100 if (xListener.is()) 1101 { 1102 ::osl::MutexGuard aGuard( maMutex ); 1103 if (!mnClientId) 1104 mnClientId = comphelper::AccessibleEventNotifier::registerClient( ); 1105 comphelper::AccessibleEventNotifier::addEventListener( mnClientId, xListener ); 1106 } 1107 } 1108 1109 1110 1111 1112 void SAL_CALL SvxRectCtlChildAccessibleContext::removeEventListener( const Reference< XAccessibleEventListener >& xListener ) 1113 throw( RuntimeException ) 1114 { 1115 if (xListener.is()) 1116 { 1117 ::osl::MutexGuard aGuard( maMutex ); 1118 1119 sal_Int32 nListenerCount = comphelper::AccessibleEventNotifier::removeEventListener( mnClientId, xListener ); 1120 if ( !nListenerCount ) 1121 { 1122 // no listeners anymore 1123 // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client), 1124 // and at least to us not firing any events anymore, in case somebody calls 1125 // NotifyAccessibleEvent, again 1126 comphelper::AccessibleEventNotifier::revokeClient( mnClientId ); 1127 mnClientId = 0; 1128 } 1129 } 1130 } 1131 1132 //===== XAccessibleValue ================================================ 1133 1134 Any SAL_CALL SvxRectCtlChildAccessibleContext::getCurrentValue() throw( RuntimeException ) 1135 { 1136 ThrowExceptionIfNotAlive(); 1137 1138 Any aRet; 1139 aRet <<= ( mbIsChecked? 1.0 : 0.0 ); 1140 return aRet; 1141 } 1142 1143 sal_Bool SAL_CALL SvxRectCtlChildAccessibleContext::setCurrentValue( const Any& /*aNumber*/ ) throw( RuntimeException ) 1144 { 1145 return sal_False; 1146 } 1147 1148 Any SAL_CALL SvxRectCtlChildAccessibleContext::getMaximumValue() throw( RuntimeException ) 1149 { 1150 Any aRet; 1151 aRet <<= 1.0; 1152 return aRet; 1153 } 1154 1155 Any SAL_CALL SvxRectCtlChildAccessibleContext::getMinimumValue() throw( RuntimeException ) 1156 { 1157 Any aRet; 1158 aRet <<= 0.0; 1159 return aRet; 1160 } 1161 1162 // ----------------------------------------------------------------------------- 1163 // XAccessibleAction 1164 // ----------------------------------------------------------------------------- 1165 1166 sal_Int32 SvxRectCtlChildAccessibleContext::getAccessibleActionCount( ) throw (RuntimeException) 1167 { 1168 ::osl::MutexGuard aGuard( maMutex ); 1169 1170 return 1; 1171 } 1172 1173 // ----------------------------------------------------------------------------- 1174 1175 sal_Bool SvxRectCtlChildAccessibleContext::doAccessibleAction ( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException) 1176 { 1177 ::osl::MutexGuard aGuard( maMutex ); 1178 1179 if ( nIndex < 0 || nIndex >= getAccessibleActionCount() ) 1180 throw IndexOutOfBoundsException(); 1181 1182 Reference<XAccessibleSelection> xSelection( mxParent, UNO_QUERY); 1183 1184 xSelection->selectAccessibleChild(mnIndexInParent); 1185 1186 return sal_True; 1187 } 1188 1189 // ----------------------------------------------------------------------------- 1190 1191 ::rtl::OUString SvxRectCtlChildAccessibleContext::getAccessibleActionDescription ( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException) 1192 { 1193 ::osl::MutexGuard aGuard( maMutex ); 1194 1195 if ( nIndex < 0 || nIndex >= getAccessibleActionCount() ) 1196 throw IndexOutOfBoundsException(); 1197 return ::rtl::OUString::createFromAscii("select"); 1198 } 1199 1200 // ----------------------------------------------------------------------------- 1201 1202 Reference< XAccessibleKeyBinding > SvxRectCtlChildAccessibleContext::getAccessibleActionKeyBinding( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException) 1203 { 1204 ::osl::MutexGuard aGuard( maMutex ); 1205 1206 if ( nIndex < 0 || nIndex >= getAccessibleActionCount() ) 1207 throw IndexOutOfBoundsException(); 1208 1209 return Reference< XAccessibleKeyBinding >(); 1210 } 1211 1212 1213 //===== XServiceInfo ======================================================== 1214 1215 ::rtl::OUString SAL_CALL SvxRectCtlChildAccessibleContext::getImplementationName( void ) throw( RuntimeException ) 1216 { 1217 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.ui.SvxRectCtlChildAccessibleContext" ) ); 1218 } 1219 1220 sal_Bool SAL_CALL SvxRectCtlChildAccessibleContext::supportsService( const ::rtl::OUString& sServiceName ) throw( RuntimeException ) 1221 { 1222 // Iterate over all supported service names and return true if on of them 1223 // matches the given name. 1224 ::osl::MutexGuard aGuard( maMutex ); 1225 Sequence< ::rtl::OUString > aSupportedServices ( getSupportedServiceNames() ); 1226 int nLength = aSupportedServices.getLength(); 1227 for( int i = 0 ; i < nLength; ++i ) 1228 { 1229 if( sServiceName == aSupportedServices[ i ] ) 1230 return sal_True; 1231 } 1232 1233 return sal_False; 1234 } 1235 1236 Sequence< ::rtl::OUString > SAL_CALL SvxRectCtlChildAccessibleContext::getSupportedServiceNames( void ) throw( RuntimeException ) 1237 { 1238 const ::rtl::OUString sServiceName (RTL_CONSTASCII_USTRINGPARAM ("com.sun.star.accessibility.AccessibleContext")); 1239 return Sequence< ::rtl::OUString >( &sServiceName, 1 ); 1240 } 1241 1242 //===== XTypeProvider ======================================================= 1243 1244 Sequence< sal_Int8 > SAL_CALL SvxRectCtlChildAccessibleContext::getImplementationId( void ) throw( RuntimeException ) 1245 { 1246 static OImplementationId* pId = 0; 1247 if( !pId ) 1248 { 1249 MutexGuard aGuard( Mutex::getGlobalMutex() ); 1250 if( !pId) 1251 { 1252 static OImplementationId aId; 1253 pId = &aId; 1254 } 1255 } 1256 return pId->getImplementationId(); 1257 } 1258 1259 //===== internal ============================================================ 1260 1261 void SvxRectCtlChildAccessibleContext::CommitChange( const AccessibleEventObject& rEvent ) 1262 { 1263 if (mnClientId) 1264 comphelper::AccessibleEventNotifier::addEvent( mnClientId, rEvent ); 1265 } 1266 1267 void SAL_CALL SvxRectCtlChildAccessibleContext::disposing() 1268 { 1269 if( !rBHelper.bDisposed ) 1270 { 1271 ::osl::MutexGuard aGuard( maMutex ); 1272 1273 // Send a disposing to all listeners. 1274 if ( mnClientId ) 1275 { 1276 comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( mnClientId, *this ); 1277 mnClientId = 0; 1278 } 1279 1280 mxParent = Reference< XAccessible >(); 1281 1282 delete mpBoundingBox; 1283 } 1284 } 1285 1286 void SvxRectCtlChildAccessibleContext::ThrowExceptionIfNotAlive( void ) throw( lang::DisposedException ) 1287 { 1288 if( IsNotAlive() ) 1289 throw lang::DisposedException(); 1290 } 1291 1292 Rectangle SvxRectCtlChildAccessibleContext::GetBoundingBoxOnScreen( void ) throw( RuntimeException ) 1293 { 1294 ::osl::MutexGuard aGuard( maMutex ); 1295 1296 // no ThrowExceptionIfNotAlive() because its done in GetBoundingBox() 1297 Rectangle aRect( GetBoundingBox() ); 1298 1299 return Rectangle( mrParentWindow.OutputToScreenPixel( aRect.TopLeft() ), aRect.GetSize() ); 1300 } 1301 1302 Rectangle SvxRectCtlChildAccessibleContext::GetBoundingBox( void ) throw( RuntimeException ) 1303 { 1304 // no guard neccessary, because no one changes mpBoundingBox after creating it 1305 ThrowExceptionIfNotAlive(); 1306 1307 return *mpBoundingBox; 1308 } 1309 void SvxRectCtlChildAccessibleContext::setStateChecked( sal_Bool bChecked, sal_Bool bFireFocus ) 1310 { 1311 if( mbIsChecked != bChecked ) 1312 { 1313 mbIsChecked = bChecked; 1314 1315 const Reference< XInterface > xSource( *this ); 1316 1317 Any aOld; 1318 Any aNew; 1319 Any& rMod = bChecked? aNew : aOld; 1320 if( bFireFocus ) 1321 { 1322 //Solution: Send the STATE_CHANGED(Focused) event to accessible 1323 rMod <<= AccessibleStateType::FOCUSED; 1324 CommitChange( AccessibleEventObject( xSource, AccessibleEventId::STATE_CHANGED, aNew, aOld ) ); 1325 } 1326 rMod <<= AccessibleStateType::CHECKED; 1327 1328 CommitChange( AccessibleEventObject( xSource, AccessibleEventId::STATE_CHANGED, aNew, aOld ) ); 1329 } 1330 } 1331 1332 void SvxRectCtlChildAccessibleContext::FireFocusEvent() 1333 { 1334 const Reference< XInterface > xSource( *this ); 1335 Any aOld; 1336 Any aNew; 1337 aNew <<= AccessibleStateType::FOCUSED; 1338 CommitChange( AccessibleEventObject( xSource, AccessibleEventId::STATE_CHANGED, aNew, aOld ) ); 1339 } 1340