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 #include "AccessibleFrameSelector.hxx" 27 #include <com/sun/star/awt/KeyEvent.hpp> 28 #include <com/sun/star/awt/KeyModifier.hpp> 29 #include <com/sun/star/awt/Key.hpp> 30 #ifndef _COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLESTATETYPE_HDL_ 31 #include <com/sun/star/accessibility/AccessibleStateType.hpp> 32 #endif 33 #ifndef _COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLERELATIONTYPE_HDL_ 34 #include <com/sun/star/accessibility/AccessibleRelationType.hpp> 35 #endif 36 #ifndef _COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLEROLE_HDL_ 37 #include <com/sun/star/accessibility/AccessibleRole.hpp> 38 #endif 39 #include <com/sun/star/accessibility/AccessibleEventId.hpp> 40 #include <com/sun/star/awt/FocusChangeReason.hpp> 41 #include <unotools/accessiblestatesethelper.hxx> 42 #include <unotools/accessiblerelationsethelper.hxx> 43 #include <vos/mutex.hxx> 44 #include <vcl/svapp.hxx> 45 #include <svx/frmsel.hxx> 46 #include <svx/dialmgr.hxx> 47 #include "editeng/unolingu.hxx" 48 49 #ifndef _SVX_DIALOGS_HRC 50 #include <svx/dialogs.hrc> 51 #endif 52 #ifndef SVX_FRMSEL_HRC 53 #include "frmsel.hrc" 54 #endif 55 56 #ifndef MNEMONIC_CHAR 57 #define MNEMONIC_CHAR ((sal_Unicode)'~') 58 #endif 59 60 namespace svx { 61 namespace a11y { 62 63 using ::rtl::OUString; 64 using ::com::sun::star::uno::Any; 65 using ::com::sun::star::uno::UNO_QUERY; 66 using ::com::sun::star::uno::Reference; 67 using ::com::sun::star::uno::Sequence; 68 using ::com::sun::star::uno::RuntimeException; 69 using ::com::sun::star::uno::XInterface; 70 using ::com::sun::star::lang::Locale; 71 using ::com::sun::star::lang::EventObject; 72 using ::com::sun::star::beans::XPropertyChangeListener; 73 using ::com::sun::star::awt::XFocusListener; 74 75 using namespace ::com::sun::star::accessibility; 76 77 namespace AwtKey = ::com::sun::star::awt::Key; 78 namespace AwtKeyModifier = ::com::sun::star::awt::KeyModifier; 79 namespace AwtFocusChangeReason = ::com::sun::star::awt::FocusChangeReason; 80 81 typedef ::com::sun::star::awt::Point AwtPoint; 82 typedef ::com::sun::star::awt::Size AwtSize; 83 typedef ::com::sun::star::awt::Rectangle AwtRectangle; 84 typedef ::com::sun::star::awt::KeyEvent AwtKeyEvent; 85 typedef ::com::sun::star::awt::FocusEvent AwtFocusEvent; 86 87 // ============================================================================ 88 89 AccFrameSelector::AccFrameSelector( FrameSelector& rFrameSel, FrameBorderType eBorder ) : 90 Resource( SVX_RES( RID_SVXSTR_BORDER_CONTROL ) ), 91 mpFrameSel( &rFrameSel ), 92 meBorder( eBorder ), 93 maFocusListeners( maFocusMutex ), 94 maPropertyListeners( maPropertyMutex ), 95 maNames( SVX_RES( ARR_TEXTS ) ), 96 maDescriptions( SVX_RES(ARR_DESCRIPTIONS ) ), 97 mnClientId( 0 ) 98 { 99 FreeResource(); 100 101 if ( mpFrameSel ) 102 { 103 mpFrameSel->AddEventListener( LINK( this, AccFrameSelector, WindowEventListener ) ); 104 } 105 } 106 107 // ---------------------------------------------------------------------------- 108 109 AccFrameSelector::~AccFrameSelector() 110 { 111 if ( mpFrameSel ) 112 { 113 mpFrameSel->RemoveEventListener( LINK( this, AccFrameSelector, WindowEventListener ) ); 114 } 115 } 116 117 // ---------------------------------------------------------------------------- 118 119 Reference< XAccessibleContext > AccFrameSelector::getAccessibleContext( ) 120 throw (RuntimeException) 121 { 122 return this; 123 } 124 125 // ---------------------------------------------------------------------------- 126 127 sal_Int32 AccFrameSelector::getAccessibleChildCount( ) throw (RuntimeException) 128 { 129 vos::OGuard aGuard(Application::GetSolarMutex()); 130 IsValid(); 131 return (meBorder == FRAMEBORDER_NONE) ? mpFrameSel->GetEnabledBorderCount() : 0; 132 } 133 134 // ---------------------------------------------------------------------------- 135 136 Reference< XAccessible > AccFrameSelector::getAccessibleChild( sal_Int32 i ) 137 throw (RuntimeException) 138 { 139 vos::OGuard aGuard(Application::GetSolarMutex()); 140 IsValid(); 141 Reference< XAccessible > xRet; 142 if( meBorder == FRAMEBORDER_NONE ) 143 xRet = mpFrameSel->GetChildAccessible( i ); 144 if( !xRet.is() ) 145 throw RuntimeException(); 146 return xRet; 147 } 148 149 // ---------------------------------------------------------------------------- 150 151 Reference< XAccessible > AccFrameSelector::getAccessibleParent( ) 152 throw (RuntimeException) 153 { 154 vos::OGuard aGuard(Application::GetSolarMutex()); 155 IsValid(); 156 Reference< XAccessible > xRet; 157 if(meBorder == FRAMEBORDER_NONE) 158 xRet = mpFrameSel->GetParent()->GetAccessible( sal_True ); 159 else 160 xRet = mpFrameSel->CreateAccessible(); 161 return xRet; 162 } 163 164 // ---------------------------------------------------------------------------- 165 166 sal_Int32 AccFrameSelector::getAccessibleIndexInParent( ) 167 throw (RuntimeException) 168 { 169 vos::OGuard aGuard(Application::GetSolarMutex()); 170 IsValid(); 171 172 sal_Int32 nIdx = 0; 173 if( meBorder == FRAMEBORDER_NONE ) 174 { 175 Window* pTabPage = mpFrameSel->GetParent(); 176 sal_Int32 nChildren = pTabPage->GetChildCount(); 177 for( nIdx = 0; nIdx < nChildren; ++nIdx ) 178 if( pTabPage->GetChild( static_cast< sal_uInt16 >( nIdx ) ) == mpFrameSel ) 179 break; 180 } 181 else 182 nIdx = mpFrameSel->GetEnabledBorderIndex( meBorder ); 183 184 if( nIdx < 0 ) 185 throw RuntimeException(); 186 return nIdx; 187 } 188 189 // ---------------------------------------------------------------------------- 190 191 sal_Int16 AccFrameSelector::getAccessibleRole( ) throw (RuntimeException) 192 { 193 // return AccessibleRole::OPTION_PANE; 194 return meBorder == FRAMEBORDER_NONE ? AccessibleRole::OPTION_PANE : AccessibleRole::CHECK_BOX; 195 } 196 197 // ---------------------------------------------------------------------------- 198 199 OUString AccFrameSelector::getAccessibleDescription( ) 200 throw (RuntimeException) 201 { 202 vos::OGuard aGuard(Application::GetSolarMutex()); 203 IsValid(); 204 return maDescriptions.GetString(meBorder); 205 } 206 207 // ---------------------------------------------------------------------------- 208 209 OUString AccFrameSelector::getAccessibleName( ) 210 throw (RuntimeException) 211 { 212 vos::OGuard aGuard(Application::GetSolarMutex()); 213 IsValid(); 214 return maNames.GetString(meBorder); 215 } 216 217 // ---------------------------------------------------------------------------- 218 219 Reference< XAccessibleRelationSet > AccFrameSelector::getAccessibleRelationSet( ) 220 throw (RuntimeException) 221 { 222 vos::OGuard aGuard(Application::GetSolarMutex()); 223 IsValid(); 224 utl::AccessibleRelationSetHelper* pHelper; 225 Reference< XAccessibleRelationSet > xRet = pHelper = new utl::AccessibleRelationSetHelper; 226 //if(meBorder == FRAMEBORDER_NONE) 227 //{ 228 // //add the label relation 229 // Window* pPrev = mpFrameSel->GetWindow( WINDOW_PREV ); 230 // if(pPrev && WINDOW_FIXEDTEXT == pPrev->GetType()) 231 // { 232 // AccessibleRelation aLabelRelation; 233 // aLabelRelation.RelationType = AccessibleRelationType::LABELED_BY; 234 // aLabelRelation.TargetSet.realloc(1); 235 // aLabelRelation.TargetSet.getArray()[0] = pPrev->GetAccessible(); 236 // pHelper->AddRelation(aLabelRelation); 237 // } 238 //} 239 if(meBorder == FRAMEBORDER_NONE) 240 { 241 //add the label relation 242 Window *pLabeledBy = mpFrameSel->GetAccessibleRelationLabeledBy(); 243 if ( pLabeledBy && pLabeledBy != mpFrameSel ) 244 { 245 AccessibleRelation aLabelRelation; 246 aLabelRelation.RelationType = AccessibleRelationType::LABELED_BY; 247 aLabelRelation.TargetSet.realloc(1); 248 aLabelRelation.TargetSet.getArray()[0] = pLabeledBy->GetAccessible(); 249 pHelper->AddRelation(aLabelRelation); 250 } 251 Window* pMemberOf = mpFrameSel->GetAccessibleRelationMemberOf(); 252 if ( pMemberOf && pMemberOf != mpFrameSel ) 253 { 254 AccessibleRelation aMemberOfRelation; 255 aMemberOfRelation.RelationType = AccessibleRelationType::MEMBER_OF; 256 aMemberOfRelation.TargetSet.realloc(1); 257 aMemberOfRelation.TargetSet.getArray()[0] = pMemberOf->GetAccessible(); 258 pHelper->AddRelation(aMemberOfRelation); 259 } 260 } 261 return xRet; 262 } 263 264 // ---------------------------------------------------------------------------- 265 266 Reference< XAccessibleStateSet > AccFrameSelector::getAccessibleStateSet( ) 267 throw (RuntimeException) 268 { 269 vos::OGuard aGuard(Application::GetSolarMutex()); 270 utl::AccessibleStateSetHelper* pStateSetHelper = new utl::AccessibleStateSetHelper; 271 Reference< XAccessibleStateSet > xRet = pStateSetHelper; 272 273 if(!mpFrameSel) 274 pStateSetHelper->AddState(AccessibleStateType::DEFUNC); 275 else 276 { 277 const sal_Int16 aStandardStates[] = 278 { 279 AccessibleStateType::EDITABLE, 280 AccessibleStateType::FOCUSABLE, 281 AccessibleStateType::MULTI_SELECTABLE, 282 AccessibleStateType::SELECTABLE, 283 AccessibleStateType::SHOWING, 284 AccessibleStateType::VISIBLE, 285 AccessibleStateType::OPAQUE, 286 0}; 287 sal_Int16 nState = 0; 288 while(aStandardStates[nState]) 289 { 290 pStateSetHelper->AddState(aStandardStates[nState++]); 291 } 292 if(mpFrameSel->IsEnabled()) 293 { 294 pStateSetHelper->AddState(AccessibleStateType::ENABLED); 295 pStateSetHelper->AddState(AccessibleStateType::SENSITIVE); 296 } 297 298 sal_Bool bIsParent = meBorder == FRAMEBORDER_NONE; 299 if(mpFrameSel->HasFocus() && 300 (bIsParent || mpFrameSel->IsBorderSelected(meBorder))) 301 { 302 pStateSetHelper->AddState(AccessibleStateType::ACTIVE); 303 pStateSetHelper->AddState(AccessibleStateType::FOCUSED); 304 pStateSetHelper->AddState(AccessibleStateType::SELECTED); 305 } 306 } 307 return xRet; 308 } 309 310 // ---------------------------------------------------------------------------- 311 312 Locale AccFrameSelector::getLocale( ) 313 throw (IllegalAccessibleComponentStateException, RuntimeException) 314 { 315 Locale aRet; 316 SvxLanguageToLocale( aRet, Application::GetSettings().GetUILanguage() ); 317 return aRet; 318 } 319 320 // ---------------------------------------------------------------------------- 321 322 void AccFrameSelector::addPropertyChangeListener( 323 const Reference< XPropertyChangeListener >& xListener ) 324 throw (RuntimeException) 325 { 326 maPropertyListeners.addInterface( xListener ); 327 } 328 329 // ---------------------------------------------------------------------------- 330 331 void AccFrameSelector::removePropertyChangeListener( const Reference< XPropertyChangeListener >& xListener ) 332 throw (RuntimeException) 333 { 334 maPropertyListeners.removeInterface( xListener ); 335 } 336 337 // ---------------------------------------------------------------------------- 338 339 sal_Bool AccFrameSelector::containsPoint( const AwtPoint& aPt ) 340 throw (RuntimeException) 341 { 342 vos::OGuard aGuard(Application::GetSolarMutex()); 343 IsValid(); 344 //aPt is relative to the frame selector 345 return mpFrameSel->ContainsClickPoint( Point( aPt.X, aPt.Y ) ); 346 } 347 348 // ---------------------------------------------------------------------------- 349 350 Reference< XAccessible > AccFrameSelector::getAccessibleAtPoint( 351 const AwtPoint& aPt ) 352 throw (RuntimeException) 353 { 354 vos::OGuard aGuard(Application::GetSolarMutex()); 355 IsValid(); 356 //aPt is relative to the frame selector 357 return mpFrameSel->GetChildAccessible( Point( aPt.X, aPt.Y ) ); 358 } 359 360 AwtRectangle AccFrameSelector::getBounds( ) throw (RuntimeException) 361 { 362 vos::OGuard aGuard(Application::GetSolarMutex()); 363 IsValid(); 364 Size aSz; 365 Point aPos; 366 switch(meBorder) 367 { 368 case FRAMEBORDER_NONE: 369 aSz = mpFrameSel->GetSizePixel(); 370 aPos = mpFrameSel->GetPosPixel(); 371 break; 372 default: 373 const Rectangle aSpot = mpFrameSel->GetClickBoundRect( meBorder ); 374 aPos = aSpot.TopLeft(); 375 aSz = aSpot.GetSize(); 376 } 377 AwtRectangle aRet; 378 aRet.X = aPos.X(); 379 aRet.Y = aPos.Y(); 380 aRet.Width = aSz.Width(); 381 aRet.Height = aSz.Height(); 382 return aRet; 383 } 384 385 // ---------------------------------------------------------------------------- 386 387 AwtPoint AccFrameSelector::getLocation( ) throw (RuntimeException) 388 { 389 vos::OGuard aGuard(Application::GetSolarMutex()); 390 IsValid(); 391 Point aPos; 392 switch(meBorder) 393 { 394 case FRAMEBORDER_NONE: 395 aPos = mpFrameSel->GetPosPixel(); 396 break; 397 default: 398 const Rectangle aSpot = mpFrameSel->GetClickBoundRect( meBorder ); 399 aPos = aSpot.TopLeft(); 400 } 401 AwtPoint aRet(aPos.X(), aPos.Y()); 402 return aRet; 403 } 404 405 // ---------------------------------------------------------------------------- 406 407 AwtPoint AccFrameSelector::getLocationOnScreen( ) throw (RuntimeException) 408 { 409 vos::OGuard aGuard(Application::GetSolarMutex()); 410 IsValid(); 411 Point aPos; 412 switch(meBorder) 413 { 414 case FRAMEBORDER_NONE: 415 aPos = mpFrameSel->GetPosPixel(); 416 break; 417 default: 418 const Rectangle aSpot = mpFrameSel->GetClickBoundRect( meBorder ); 419 aPos = aSpot.TopLeft(); 420 } 421 aPos = mpFrameSel->OutputToAbsoluteScreenPixel( aPos ); 422 AwtPoint aRet(aPos.X(), aPos.Y()); 423 return aRet; 424 } 425 426 // ---------------------------------------------------------------------------- 427 428 AwtSize AccFrameSelector::getSize( ) throw (RuntimeException) 429 { 430 vos::OGuard aGuard(Application::GetSolarMutex()); 431 IsValid(); 432 Size aSz; 433 switch(meBorder) 434 { 435 case FRAMEBORDER_NONE: 436 aSz = mpFrameSel->GetSizePixel(); 437 break; 438 default: 439 const Rectangle aSpot = mpFrameSel->GetClickBoundRect( meBorder ); 440 aSz = aSpot.GetSize(); 441 } 442 AwtSize aRet(aSz.Width(), aSz.Height()); 443 return aRet; 444 } 445 446 // ---------------------------------------------------------------------------- 447 448 sal_Bool AccFrameSelector::isShowing( ) throw (RuntimeException) 449 { 450 vos::OGuard aGuard(Application::GetSolarMutex()); 451 IsValid(); 452 return sal_True; 453 } 454 455 // ---------------------------------------------------------------------------- 456 457 sal_Bool AccFrameSelector::isVisible( ) throw (RuntimeException) 458 { 459 vos::OGuard aGuard(Application::GetSolarMutex()); 460 IsValid(); 461 return sal_True; 462 } 463 464 // ---------------------------------------------------------------------------- 465 466 sal_Bool AccFrameSelector::isFocusTraversable( ) throw (RuntimeException) 467 { 468 vos::OGuard aGuard(Application::GetSolarMutex()); 469 IsValid(); 470 return sal_True; 471 } 472 473 // ---------------------------------------------------------------------------- 474 475 void AccFrameSelector::addFocusListener( const Reference< XFocusListener >& xListener ) throw (RuntimeException) 476 { 477 maFocusListeners.addInterface( xListener ); 478 } 479 480 // ---------------------------------------------------------------------------- 481 482 void AccFrameSelector::removeFocusListener( const Reference< XFocusListener >& xListener ) throw (RuntimeException) 483 { 484 maFocusListeners.removeInterface( xListener ); 485 } 486 487 // ---------------------------------------------------------------------------- 488 489 void AccFrameSelector::grabFocus( ) throw (RuntimeException) 490 { 491 vos::OGuard aGuard(Application::GetSolarMutex()); 492 IsValid(); 493 mpFrameSel->GrabFocus(); 494 } 495 496 // ---------------------------------------------------------------------------- 497 498 Any AccFrameSelector::getAccessibleKeyBinding( ) throw (RuntimeException) 499 { 500 Any aRet; 501 vos::OGuard aGuard(Application::GetSolarMutex()); 502 IsValid(); 503 utl::AccessibleRelationSetHelper* pHelper; 504 Reference< XAccessibleRelationSet > xRet = pHelper = new utl::AccessibleRelationSetHelper; 505 if(meBorder == FRAMEBORDER_NONE) 506 { 507 Window* pPrev = mpFrameSel->GetWindow( WINDOW_PREV ); 508 if(pPrev && WINDOW_FIXEDTEXT == pPrev->GetType()) 509 { 510 String sText = pPrev->GetText(); 511 xub_StrLen nFound = sText.Search( MNEMONIC_CHAR ); 512 if(STRING_NOTFOUND != nFound && ++nFound < sText.Len()) 513 { 514 sText.ToUpperAscii(); 515 sal_Unicode cChar = sText.GetChar(nFound); 516 AwtKeyEvent aEvent; 517 518 aEvent.KeyCode = 0; 519 aEvent.KeyChar = cChar; 520 aEvent.KeyFunc = 0; 521 if(cChar >= 'A' && cChar <= 'Z') 522 { 523 aEvent.KeyCode = AwtKey::A + cChar - 'A'; 524 } 525 aEvent.Modifiers = AwtKeyModifier::MOD2; 526 aRet <<= aEvent; 527 } 528 } 529 } 530 return aRet; 531 } 532 533 // ---------------------------------------------------------------------------- 534 535 sal_Int32 AccFrameSelector::getForeground( ) 536 throw (RuntimeException) 537 { 538 Any aRet; 539 vos::OGuard aGuard(Application::GetSolarMutex()); 540 IsValid(); 541 return mpFrameSel->GetControlForeground().GetColor(); 542 } 543 544 // ---------------------------------------------------------------------------- 545 546 sal_Int32 AccFrameSelector::getBackground( ) 547 throw (RuntimeException) 548 { 549 Any aRet; 550 vos::OGuard aGuard(Application::GetSolarMutex()); 551 IsValid(); 552 return mpFrameSel->GetControlBackground().GetColor(); 553 } 554 555 // ---------------------------------------------------------------------------- 556 557 void AccFrameSelector::addEventListener( const Reference< XAccessibleEventListener >& xListener ) throw (RuntimeException) 558 { 559 vos::OGuard aGuard( Application::GetSolarMutex() ); 560 561 if ( xListener.is() ) 562 { 563 if ( !mnClientId ) 564 { 565 mnClientId = ::comphelper::AccessibleEventNotifier::registerClient(); 566 } 567 ::comphelper::AccessibleEventNotifier::addEventListener( mnClientId, xListener ); 568 } 569 } 570 571 // ---------------------------------------------------------------------------- 572 573 void AccFrameSelector::removeEventListener( const Reference< XAccessibleEventListener >& xListener ) throw (RuntimeException) 574 { 575 vos::OGuard aGuard( Application::GetSolarMutex() ); 576 577 if ( xListener.is() && mnClientId != 0 && 578 ::comphelper::AccessibleEventNotifier::removeEventListener( mnClientId, xListener ) == 0 ) 579 { 580 // no listeners anymore 581 // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client), 582 // and at least to us not firing any events anymore, in case somebody calls 583 // NotifyAccessibleEvent, again 584 ::comphelper::AccessibleEventNotifier::TClientId nId( mnClientId ); 585 mnClientId = 0; 586 ::comphelper::AccessibleEventNotifier::revokeClient( nId ); 587 } 588 } 589 590 // ---------------------------------------------------------------------------- 591 592 OUString AccFrameSelector::getImplementationName( ) throw (RuntimeException) 593 { 594 return OUString::createFromAscii("AccFrameSelector"); 595 } 596 597 // ---------------------------------------------------------------------------- 598 599 const sal_Char sAccessible[] = "Accessible"; 600 const sal_Char sAccessibleContext[] = "AccessibleContext"; 601 const sal_Char sAccessibleComponent[] = "AccessibleComponent"; 602 603 sal_Bool AccFrameSelector::supportsService( const OUString& rServiceName ) 604 throw (RuntimeException) 605 { 606 return rServiceName.equalsAsciiL( sAccessible , sizeof(sAccessible )-1 ) || 607 rServiceName.equalsAsciiL( sAccessibleContext , sizeof(sAccessibleContext )-1 ) || 608 rServiceName.equalsAsciiL( sAccessibleComponent, sizeof(sAccessibleComponent)-1 ); 609 } 610 611 // ---------------------------------------------------------------------------- 612 613 Sequence< OUString > AccFrameSelector::getSupportedServiceNames( ) 614 throw (RuntimeException) 615 { 616 Sequence< OUString > aRet(3); 617 OUString* pArray = aRet.getArray(); 618 pArray[0] = OUString( RTL_CONSTASCII_USTRINGPARAM(sAccessible ) ); 619 pArray[1] = OUString( RTL_CONSTASCII_USTRINGPARAM(sAccessibleContext ) ); 620 pArray[2] = OUString( RTL_CONSTASCII_USTRINGPARAM(sAccessibleComponent) ); 621 return aRet; 622 } 623 624 // ---------------------------------------------------------------------------- 625 626 void AccFrameSelector::IsValid() throw (RuntimeException) 627 { 628 if(!mpFrameSel) 629 throw RuntimeException(); 630 } 631 632 // ---------------------------------------------------------------------------- 633 634 void AccFrameSelector::NotifyFocusListeners(sal_Bool bGetFocus) 635 { 636 vos::OGuard aGuard(Application::GetSolarMutex()); 637 AwtFocusEvent aEvent; 638 aEvent.FocusFlags = 0; 639 if(bGetFocus) 640 { 641 sal_uInt16 nFocusFlags = mpFrameSel->GetGetFocusFlags(); 642 if(nFocusFlags&GETFOCUS_TAB) 643 aEvent.FocusFlags |= AwtFocusChangeReason::TAB; 644 if(nFocusFlags&GETFOCUS_CURSOR) 645 aEvent.FocusFlags |= AwtFocusChangeReason::CURSOR; 646 if(nFocusFlags&GETFOCUS_MNEMONIC) 647 aEvent.FocusFlags |= AwtFocusChangeReason::MNEMONIC; 648 if(nFocusFlags&GETFOCUS_FORWARD) 649 aEvent.FocusFlags |= AwtFocusChangeReason::FORWARD; 650 if(nFocusFlags&GETFOCUS_BACKWARD) 651 aEvent.FocusFlags |= AwtFocusChangeReason::BACKWARD; 652 if(nFocusFlags&GETFOCUS_AROUND) 653 aEvent.FocusFlags |= AwtFocusChangeReason::AROUND; 654 if(nFocusFlags&GETFOCUS_UNIQUEMNEMONIC) 655 aEvent.FocusFlags |= AwtFocusChangeReason::UNIQUEMNEMONIC; 656 // if(nFocusFlags&GETFOCUS_INIT) 657 // aEvent.FocusFlags |= AwtFocusChangeReason:: 658 } 659 // else 660 //how can I find the current focus window? 661 // aEvent.NextFocus = ; 662 aEvent.Temporary = sal_False; 663 664 Reference < XAccessibleContext > xThis( this ); 665 aEvent.Source = xThis; 666 667 ::cppu::OInterfaceIteratorHelper aIter( maFocusListeners ); 668 while( aIter.hasMoreElements() ) 669 { 670 Reference < XFocusListener > xListener( aIter.next(), UNO_QUERY ); 671 if(bGetFocus) 672 xListener->focusGained( aEvent ); 673 else 674 xListener->focusLost( aEvent ); 675 } 676 } 677 678 // ---------------------------------------------------------------------------- 679 680 IMPL_LINK( AccFrameSelector, WindowEventListener, VclSimpleEvent*, pEvent ) 681 { 682 VclWindowEvent* pWinEvent = dynamic_cast< VclWindowEvent* >( pEvent ); 683 DBG_ASSERT( pWinEvent, "AccFrameSelector::WindowEventListener - unknown window event" ); 684 if ( pWinEvent ) 685 { 686 Window* pWindow = pWinEvent->GetWindow(); 687 DBG_ASSERT( pWindow, "AccFrameSelector::WindowEventListener: no window!" ); 688 if ( !pWindow->IsAccessibilityEventsSuppressed() || ( pWinEvent->GetId() == VCLEVENT_OBJECT_DYING ) ) 689 { 690 ProcessWindowEvent( *pWinEvent ); 691 } 692 } 693 694 return 0; 695 } 696 697 // ---------------------------------------------------------------------------- 698 699 void AccFrameSelector::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) 700 { 701 switch ( rVclWindowEvent.GetId() ) 702 { 703 case VCLEVENT_WINDOW_GETFOCUS: 704 { 705 if ( meBorder == FRAMEBORDER_NONE ) 706 { 707 Any aOldValue, aNewValue; 708 aNewValue <<= AccessibleStateType::FOCUSED; 709 NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); 710 } 711 } 712 break; 713 case VCLEVENT_WINDOW_LOSEFOCUS: 714 { 715 if ( meBorder == FRAMEBORDER_NONE ) 716 { 717 Any aOldValue, aNewValue; 718 aOldValue <<= AccessibleStateType::FOCUSED; 719 NotifyAccessibleEvent( AccessibleEventId::STATE_CHANGED, aOldValue, aNewValue ); 720 } 721 } 722 break; 723 default: 724 { 725 } 726 break; 727 } 728 } 729 730 // ---------------------------------------------------------------------------- 731 732 void AccFrameSelector::NotifyAccessibleEvent( const sal_Int16 _nEventId, 733 const Any& _rOldValue, const Any& _rNewValue ) 734 { 735 if ( mnClientId ) 736 { 737 Reference< XInterface > xSource( *this ); 738 AccessibleEventObject aEvent( xSource, _nEventId, _rNewValue, _rOldValue ); 739 ::comphelper::AccessibleEventNotifier::addEvent( mnClientId, aEvent ); 740 } 741 } 742 743 // ---------------------------------------------------------------------------- 744 745 void AccFrameSelector::Invalidate() 746 { 747 if ( mpFrameSel ) 748 { 749 mpFrameSel->RemoveEventListener( LINK( this, AccFrameSelector, WindowEventListener ) ); 750 } 751 mpFrameSel = 0; 752 EventObject aEvent; 753 Reference < XAccessibleContext > xThis( this ); 754 aEvent.Source = xThis; 755 maFocusListeners.disposeAndClear( aEvent ); 756 maPropertyListeners.disposeAndClear( aEvent ); 757 } 758 759 // ============================================================================ 760 761 } // namespace a11y 762 } // namespace svx 763 764