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