1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_sw.hxx" 30 #if (OSL_DEBUG_LEVEL > 1) && defined TEST_MIB 31 #ifndef _STRING_HXX 32 #include <tools/string.hxx> 33 #endif 34 35 #ifndef _STREAM_HXX 36 #include <tools/stream.hxx> 37 #endif 38 #endif // #if (OSL_DEBUG_LEVEL > 1) && defined TEST_MIB 39 #include <tools/debug.hxx> 40 #include <vcl/window.hxx> 41 #include <errhdl.hxx> 42 #include <swtypes.hxx> 43 44 #include <com/sun/star/accessibility/XAccessible.hpp> 45 #include <com/sun/star/accessibility/XAccessibleStateSet.hpp> 46 #include <com/sun/star/accessibility/AccessibleStateType.hpp> 47 #include <com/sun/star/accessibility/AccessibleEventId.hpp> 48 #include <vos/mutex.hxx> 49 #include <vcl/svapp.hxx> 50 #include <unotools/accessiblestatesethelper.hxx> 51 #include <unotools/accessiblerelationsethelper.hxx> 52 #include <viewsh.hxx> 53 #include <crsrsh.hxx> 54 #include <fesh.hxx> 55 #include <txtfrm.hxx> 56 #include <ndtxt.hxx> 57 #include <pagefrm.hxx> 58 #include <flyfrm.hxx> 59 #include <dflyobj.hxx> 60 #include <pam.hxx> 61 #include <viewimp.hxx> 62 #include <accmap.hxx> 63 #include <accfrmobjslist.hxx> 64 #include <acccontext.hxx> 65 #include <svx/AccessibleShape.hxx> 66 #include <comphelper/accessibleeventnotifier.hxx> 67 #include <PostItMgr.hxx> 68 69 using namespace sw::access; 70 71 #if (OSL_DEBUG_LEVEL > 1) && defined TEST_MIB 72 #define DBG_MSG( _msg ) \ 73 lcl_SwAccessibleContext_DbgMsg( this, _msg, 0, sal_False ); 74 #define DBG_MSG_CD( _msg ) \ 75 lcl_SwAccessibleContext_DbgMsg( this, _msg, 0, sal_True ); 76 #define DBG_MSG_PARAM( _msg, _param ) \ 77 lcl_SwAccessibleContext_DbgMsg( this, _msg, _param, sal_False ); 78 #define DBG_MSG_THIS_PARAM( _msg, _this, _param ) \ 79 lcl_SwAccessibleContext_DbgMsg( _this, _msg, _param, sal_False ); 80 81 void lcl_SwAccessibleContext_DbgMsg( SwAccessibleContext *pThisAcc, 82 const char *pMsg, 83 SwAccessibleContext *pChildAcc, 84 sal_Bool bConstrDestr ); 85 #else 86 #define DBG_MSG( _msg ) 87 #define DBG_MSG_PARAM( _msg, _param ) 88 #define DBG_MSG_THIS_PARAM( _msg, _this, _param ) 89 #define DBG_MSG_CD( _msg ) 90 #endif 91 92 using namespace ::com::sun::star; 93 using namespace ::com::sun::star::accessibility; 94 using ::rtl::OUString; 95 96 void SwAccessibleContext::InitStates() 97 { 98 bIsShowingState = GetMap() ? IsShowing( *(GetMap()) ) : sal_False; 99 100 ViewShell *pVSh = GetMap()->GetShell(); 101 bIsEditableState = pVSh && IsEditable( pVSh ); 102 bIsOpaqueState = pVSh && IsOpaque( pVSh ); 103 bIsDefuncState = sal_False; 104 } 105 106 void SwAccessibleContext::SetParent( SwAccessibleContext *pParent ) 107 { 108 vos::OGuard aGuard( aMutex ); 109 110 uno::Reference < XAccessible > xParent( pParent ); 111 xWeakParent = xParent; 112 } 113 114 uno::Reference< XAccessible > SwAccessibleContext::GetWeakParent() const 115 { 116 vos::OGuard aGuard( aMutex ); 117 118 uno::Reference< XAccessible > xParent( xWeakParent ); 119 return xParent; 120 } 121 122 Window *SwAccessibleContext::GetWindow() 123 { 124 Window *pWin = 0; 125 126 if( GetMap() ) 127 { 128 const ViewShell *pVSh = GetMap()->GetShell(); 129 ASSERT( pVSh, "no view shell" ); 130 if( pVSh ) 131 pWin = pVSh->GetWin(); 132 133 ASSERT( pWin, "no window" ); 134 } 135 136 return pWin; 137 } 138 139 // get ViewShell from accessibility map, and cast to cursor shell 140 SwCrsrShell* SwAccessibleContext::GetCrsrShell() 141 { 142 SwCrsrShell* pCrsrShell; 143 ViewShell* pViewShell = GetMap() ? GetMap()->GetShell() : 0; 144 ASSERT( pViewShell, "no view shell" ); 145 if( pViewShell && pViewShell->ISA( SwCrsrShell ) ) 146 pCrsrShell = static_cast<SwCrsrShell*>( pViewShell ); 147 else 148 pCrsrShell = NULL; 149 150 return pCrsrShell; 151 } 152 153 const SwCrsrShell* SwAccessibleContext::GetCrsrShell() const 154 { 155 // just like non-const GetCrsrShell 156 const SwCrsrShell* pCrsrShell; 157 const ViewShell* pViewShell = GetMap() ? GetMap()->GetShell() : 0; 158 ASSERT( pViewShell, "no view shell" ); 159 if( pViewShell && pViewShell->ISA( SwCrsrShell ) ) 160 pCrsrShell = static_cast<const SwCrsrShell*>( pViewShell ); 161 else 162 pCrsrShell = NULL; 163 164 return pCrsrShell; 165 } 166 167 168 enum Action { NONE, SCROLLED, SCROLLED_WITHIN, 169 SCROLLED_IN, SCROLLED_OUT }; 170 171 void SwAccessibleContext::ChildrenScrolled( const SwFrm *pFrm, 172 const SwRect& rOldVisArea ) 173 { 174 const SwRect& rNewVisArea = GetVisArea(); 175 const bool bVisibleChildrenOnly = SwAccessibleChild( pFrm ).IsVisibleChildrenOnly(); 176 177 const SwAccessibleChildSList aList( *pFrm, *(GetMap()) ); 178 SwAccessibleChildSList::const_iterator aIter( aList.begin() ); 179 while( aIter != aList.end() ) 180 { 181 const SwAccessibleChild& rLower = *aIter; 182 const SwRect aBox( rLower.GetBox( *(GetMap()) ) ); 183 if( rLower.IsAccessible( GetShell()->IsPreView() ) ) 184 { 185 Action eAction = NONE; 186 if( aBox.IsOver( rNewVisArea ) ) 187 { 188 if( aBox.IsOver( rOldVisArea ) ) 189 { 190 eAction = SCROLLED_WITHIN; 191 } 192 else 193 { 194 if ( bVisibleChildrenOnly && 195 !rLower.AlwaysIncludeAsChild() ) 196 { 197 eAction = SCROLLED_IN; 198 } 199 else 200 { 201 eAction = SCROLLED; 202 } 203 } 204 } 205 else if( aBox.IsOver( rOldVisArea ) ) 206 { 207 if ( bVisibleChildrenOnly && 208 !rLower.AlwaysIncludeAsChild() ) 209 { 210 eAction = SCROLLED_OUT; 211 } 212 else 213 { 214 eAction = SCROLLED; 215 } 216 } 217 else if( !bVisibleChildrenOnly || 218 rLower.AlwaysIncludeAsChild() ) 219 { 220 // This wouldn't be required if the SwAccessibleFrame, 221 // wouldn't know about the vis area. 222 eAction = SCROLLED; 223 } 224 if( NONE != eAction ) 225 { 226 if ( rLower.GetSwFrm() ) 227 { 228 ASSERT( !rLower.AlwaysIncludeAsChild(), 229 "<SwAccessibleContext::ChildrenScrolled(..)> - always included child not considered!" ); 230 const SwFrm* pLower( rLower.GetSwFrm() ); 231 ::vos::ORef< SwAccessibleContext > xAccImpl = 232 GetMap()->GetContextImpl( pLower, SCROLLED_OUT == eAction || 233 SCROLLED_IN == eAction ); 234 if( xAccImpl.isValid() ) 235 { 236 switch( eAction ) 237 { 238 case SCROLLED: 239 xAccImpl->Scrolled( rOldVisArea ); 240 break; 241 case SCROLLED_WITHIN: 242 xAccImpl->ScrolledWithin( rOldVisArea ); 243 break; 244 case SCROLLED_IN: 245 xAccImpl->ScrolledIn(); 246 break; 247 case SCROLLED_OUT: 248 xAccImpl->ScrolledOut( rOldVisArea ); 249 break; 250 case NONE: 251 break; 252 } 253 } 254 else 255 { 256 ChildrenScrolled( pLower, rOldVisArea ); 257 } 258 } 259 else if ( rLower.GetDrawObject() ) 260 { 261 ASSERT( !rLower.AlwaysIncludeAsChild(), 262 "<SwAccessibleContext::ChildrenScrolled(..)> - always included child not considered!" ); 263 ::vos::ORef< ::accessibility::AccessibleShape > xAccImpl = 264 GetMap()->GetContextImpl( rLower.GetDrawObject(), 265 this, 266 SCROLLED_OUT == eAction || 267 SCROLLED_IN == eAction ); 268 if( xAccImpl.isValid() ) 269 { 270 switch( eAction ) 271 { 272 case SCROLLED: 273 case SCROLLED_WITHIN: 274 xAccImpl->ViewForwarderChanged( 275 ::accessibility::IAccessibleViewForwarderListener::VISIBLE_AREA, 276 GetMap() ); 277 break; 278 case SCROLLED_IN: 279 ScrolledInShape( rLower.GetDrawObject(), 280 xAccImpl.getBodyPtr() ); 281 break; 282 case SCROLLED_OUT: 283 { 284 xAccImpl->ViewForwarderChanged( 285 ::accessibility::IAccessibleViewForwarderListener::VISIBLE_AREA, 286 GetMap() ); 287 DisposeShape( rLower.GetDrawObject(), 288 xAccImpl.getBodyPtr() ); 289 } 290 break; 291 case NONE: 292 break; 293 } 294 } 295 } 296 else if ( rLower.GetWindow() ) 297 { 298 // nothing to do - as such children are always included as children. 299 ASSERT( rLower.AlwaysIncludeAsChild(), 300 "<SwAccessibleContext::ChildrenScrolled(..)> - not always included child not considered!" ); 301 } 302 } 303 } 304 else if ( rLower.GetSwFrm() && 305 ( !bVisibleChildrenOnly || 306 aBox.IsOver( rOldVisArea ) || 307 aBox.IsOver( rNewVisArea ) ) ) 308 { 309 // There are no unaccessible SdrObjects that need to be notified 310 ChildrenScrolled( rLower.GetSwFrm(), rOldVisArea ); 311 } 312 ++aIter; 313 } 314 } 315 316 void SwAccessibleContext::Scrolled( const SwRect& rOldVisArea ) 317 { 318 SetVisArea( GetMap()->GetVisArea() ); 319 320 ChildrenScrolled( GetFrm(), rOldVisArea ); 321 322 sal_Bool bIsOldShowingState; 323 sal_Bool bIsNewShowingState = IsShowing( *(GetMap()) ); 324 { 325 vos::OGuard aGuard( aMutex ); 326 bIsOldShowingState = bIsShowingState; 327 bIsShowingState = bIsNewShowingState; 328 } 329 330 if( bIsOldShowingState != bIsNewShowingState ) 331 FireStateChangedEvent( AccessibleStateType::SHOWING, 332 bIsNewShowingState ); 333 } 334 335 void SwAccessibleContext::ScrolledWithin( const SwRect& rOldVisArea ) 336 { 337 SetVisArea( GetMap()->GetVisArea() ); 338 339 ChildrenScrolled( GetFrm(), rOldVisArea ); 340 341 FireVisibleDataEvent(); 342 } 343 344 void SwAccessibleContext::ScrolledIn() 345 { 346 // This accessible should be freshly created, because it 347 // was not visisble before. Therefor, its vis area must already 348 // reflect the scrolling. 349 ASSERT( GetVisArea() == GetMap()->GetVisArea(), 350 "Vis area of child is wrong. Did it exist already?" ); 351 352 // Send child event at parent. That's all we have to do here. 353 const SwFrm* pParent = GetParent(); 354 ::vos::ORef< SwAccessibleContext > xParentImpl( 355 GetMap()->GetContextImpl( pParent, sal_False ) ); 356 uno::Reference < XAccessibleContext > xThis( this ); 357 if( xParentImpl.isValid() ) 358 { 359 SetParent( xParentImpl.getBodyPtr() ); 360 361 AccessibleEventObject aEvent; 362 aEvent.EventId = AccessibleEventId::CHILD; 363 aEvent.NewValue <<= xThis; 364 365 xParentImpl->FireAccessibleEvent( aEvent ); 366 DBG_MSG_PARAM( "AccessibleChild (added)", xChildImpl.getBodyPtr() ); 367 368 if( HasCursor() ) 369 { 370 Window *pWin = GetWindow(); 371 if( pWin && pWin->HasFocus() ) 372 { 373 FireStateChangedEvent( AccessibleStateType::FOCUSED, sal_True ); 374 } 375 } 376 377 } 378 } 379 380 void SwAccessibleContext::ScrolledOut( const SwRect& rOldVisArea ) 381 { 382 SetVisArea( GetMap()->GetVisArea() ); 383 384 // First of all, update the children. That's required to dispose 385 // all children that are existing only if they are visible. They 386 // are not disposed by the recusive Dispose call that follows later on, 387 // because this call will only dispose children that are in the 388 // new vis area. The children we want to dispode however are in the 389 // old vis area all. 390 ChildrenScrolled( GetFrm(), rOldVisArea ); 391 392 // Broadcast a state changed event for the showing state. 393 // It might be that the child is freshly created just to send 394 // the child event. In this case no listener will exist. 395 FireStateChangedEvent( AccessibleStateType::SHOWING, sal_False ); 396 397 // We now dispose the frame 398 Dispose( sal_True ); 399 } 400 401 // --> OD 2005-12-12 #i27301# - use new type definition for <_nStates> 402 void SwAccessibleContext::InvalidateChildrenStates( const SwFrm* _pFrm, 403 tAccessibleStates _nStates ) 404 { 405 const SwAccessibleChildSList aVisList( GetVisArea(), *_pFrm, *(GetMap()) ); 406 407 SwAccessibleChildSList::const_iterator aIter( aVisList.begin() ); 408 while( aIter != aVisList.end() ) 409 { 410 const SwAccessibleChild& rLower = *aIter; 411 const SwFrm* pLower = rLower.GetSwFrm(); 412 if( pLower ) 413 { 414 ::vos::ORef< SwAccessibleContext > xAccImpl; 415 if( rLower.IsAccessible( GetShell()->IsPreView() ) ) 416 xAccImpl = GetMap()->GetContextImpl( pLower, sal_False ); 417 if( xAccImpl.isValid() ) 418 xAccImpl->InvalidateStates( _nStates ); 419 else 420 InvalidateChildrenStates( pLower, _nStates ); 421 } 422 else if ( rLower.GetDrawObject() ) 423 { 424 // TODO: SdrObjects 425 } 426 else if ( rLower.GetWindow() ) 427 { 428 // nothing to do ? 429 } 430 431 ++aIter; 432 } 433 } 434 // <-- 435 436 void SwAccessibleContext::DisposeChildren( const SwFrm *pFrm, 437 sal_Bool bRecursive ) 438 { 439 const SwAccessibleChildSList aVisList( GetVisArea(), *pFrm, *(GetMap()) ); 440 SwAccessibleChildSList::const_iterator aIter( aVisList.begin() ); 441 while( aIter != aVisList.end() ) 442 { 443 const SwAccessibleChild& rLower = *aIter; 444 const SwFrm* pLower = rLower.GetSwFrm(); 445 if( pLower ) 446 { 447 ::vos::ORef< SwAccessibleContext > xAccImpl; 448 if( rLower.IsAccessible( GetShell()->IsPreView() ) ) 449 xAccImpl = GetMap()->GetContextImpl( pLower, sal_False ); 450 if( xAccImpl.isValid() ) 451 xAccImpl->Dispose( bRecursive ); 452 else if( bRecursive ) 453 DisposeChildren( pLower, bRecursive ); 454 } 455 else if ( rLower.GetDrawObject() ) 456 { 457 ::vos::ORef< ::accessibility::AccessibleShape > xAccImpl( 458 GetMap()->GetContextImpl( rLower.GetDrawObject(), 459 this, sal_False ) ); 460 if( xAccImpl.isValid() ) 461 DisposeShape( rLower.GetDrawObject(), xAccImpl.getBodyPtr() ); 462 } 463 else if ( rLower.GetWindow() ) 464 { 465 DisposeChild( rLower, sal_False ); 466 } 467 ++aIter; 468 } 469 } 470 471 void SwAccessibleContext::_InvalidateContent( sal_Bool ) 472 { 473 } 474 475 void SwAccessibleContext::_InvalidateCursorPos() 476 { 477 } 478 479 void SwAccessibleContext::_InvalidateFocus() 480 { 481 } 482 483 void SwAccessibleContext::FireAccessibleEvent( AccessibleEventObject& rEvent ) 484 { 485 ASSERT( GetFrm(), "fire event for diposed frame?" ); 486 if( !GetFrm() ) 487 return; 488 489 if( !rEvent.Source.is() ) 490 { 491 uno::Reference < XAccessibleContext > xThis( this ); 492 rEvent.Source = xThis; 493 } 494 495 if (nClientId) 496 comphelper::AccessibleEventNotifier::addEvent( nClientId, rEvent ); 497 } 498 499 void SwAccessibleContext::FireVisibleDataEvent() 500 { 501 AccessibleEventObject aEvent; 502 aEvent.EventId = AccessibleEventId::VISIBLE_DATA_CHANGED; 503 504 FireAccessibleEvent( aEvent ); 505 DBG_MSG( "AccessibleVisibleData" ) 506 } 507 508 void SwAccessibleContext::FireStateChangedEvent( sal_Int16 nState, 509 sal_Bool bNewState ) 510 { 511 AccessibleEventObject aEvent; 512 513 aEvent.EventId = AccessibleEventId::STATE_CHANGED; 514 if( bNewState ) 515 aEvent.NewValue <<= nState; 516 else 517 aEvent.OldValue <<= nState; 518 519 FireAccessibleEvent( aEvent ); 520 DBG_MSG( "StateChanged" ) 521 } 522 523 void SwAccessibleContext::GetStates( 524 ::utl::AccessibleStateSetHelper& rStateSet ) 525 { 526 vos::OGuard aGuard(Application::GetSolarMutex()); 527 528 // SHOWING 529 if( bIsShowingState ) 530 rStateSet.AddState( AccessibleStateType::SHOWING ); 531 532 // EDITABLE 533 if( bIsEditableState ) 534 rStateSet.AddState( AccessibleStateType::EDITABLE ); 535 536 // ENABLED 537 rStateSet.AddState( AccessibleStateType::ENABLED ); 538 539 // OPAQUE 540 if( bIsOpaqueState ) 541 rStateSet.AddState( AccessibleStateType::OPAQUE ); 542 543 // VISIBLE 544 rStateSet.AddState( AccessibleStateType::VISIBLE ); 545 546 if( bIsDefuncState ) 547 rStateSet.AddState( AccessibleStateType::DEFUNC ); 548 } 549 550 sal_Bool SwAccessibleContext::IsEditableState() 551 { 552 sal_Bool bRet; 553 { 554 vos::OGuard aGuard( aMutex ); 555 bRet = bIsEditableState; 556 } 557 558 return bRet; 559 } 560 561 SwAccessibleContext::SwAccessibleContext( SwAccessibleMap *pM, 562 sal_Int16 nR, 563 const SwFrm *pF ) 564 : SwAccessibleFrame( pM->GetVisArea().SVRect(), pF, 565 pM->GetShell()->IsPreView() ) 566 , pMap( pM ) 567 , nClientId(0) 568 , nRole( nR ) 569 , bDisposing( sal_False ) 570 , bRegisteredAtAccessibleMap( true ) 571 { 572 InitStates(); 573 DBG_MSG_CD( "constructed" ) 574 } 575 576 SwAccessibleContext::~SwAccessibleContext() 577 { 578 vos::OGuard aGuard(Application::GetSolarMutex()); 579 580 DBG_MSG_CD( "destructed" ) 581 RemoveFrmFromAccessibleMap(); 582 } 583 584 uno::Reference< XAccessibleContext > SAL_CALL 585 SwAccessibleContext::getAccessibleContext( void ) 586 throw (uno::RuntimeException) 587 { 588 uno::Reference < XAccessibleContext > xRet( this ); 589 return xRet; 590 } 591 592 sal_Int32 SAL_CALL SwAccessibleContext::getAccessibleChildCount( void ) 593 throw (uno::RuntimeException) 594 { 595 vos::OGuard aGuard(Application::GetSolarMutex()); 596 597 CHECK_FOR_DEFUNC( XAccessibleContext ) 598 599 return bDisposing ? 0 : GetChildCount( *(GetMap()) ); 600 } 601 602 uno::Reference< XAccessible> SAL_CALL 603 SwAccessibleContext::getAccessibleChild( sal_Int32 nIndex ) 604 throw (uno::RuntimeException, lang::IndexOutOfBoundsException) 605 { 606 vos::OGuard aGuard(Application::GetSolarMutex()); 607 608 CHECK_FOR_DEFUNC( XAccessibleContext ) 609 610 const SwAccessibleChild aChild( GetChild( *(GetMap()), nIndex ) ); 611 if( !aChild.IsValid() ) 612 { 613 uno::Reference < XAccessibleContext > xThis( this ); 614 lang::IndexOutOfBoundsException aExcept( 615 OUString( RTL_CONSTASCII_USTRINGPARAM("index out of bounds") ), 616 xThis ); 617 throw aExcept; 618 } 619 620 uno::Reference< XAccessible > xChild; 621 if( aChild.GetSwFrm() ) 622 { 623 ::vos::ORef < SwAccessibleContext > xChildImpl( 624 GetMap()->GetContextImpl( aChild.GetSwFrm(), !bDisposing ) ); 625 if( xChildImpl.isValid() ) 626 { 627 xChildImpl->SetParent( this ); 628 xChild = xChildImpl.getBodyPtr(); 629 } 630 } 631 else if ( aChild.GetDrawObject() ) 632 { 633 ::vos::ORef < ::accessibility::AccessibleShape > xChildImpl( 634 GetMap()->GetContextImpl( aChild.GetDrawObject(), 635 this, !bDisposing ) ); 636 if( xChildImpl.isValid() ) 637 xChild = xChildImpl.getBodyPtr(); 638 } 639 else if ( aChild.GetWindow() ) 640 { 641 xChild = aChild.GetWindow()->GetAccessible(); 642 } 643 644 return xChild; 645 } 646 647 uno::Reference< XAccessible> SAL_CALL SwAccessibleContext::getAccessibleParent (void) 648 throw (uno::RuntimeException) 649 { 650 vos::OGuard aGuard(Application::GetSolarMutex()); 651 652 CHECK_FOR_DEFUNC( XAccessibleContext ) 653 654 const SwFrm *pUpper = GetParent(); 655 ASSERT( pUpper != 0 || bDisposing, "no upper found" ); 656 657 uno::Reference< XAccessible > xAcc; 658 if( pUpper ) 659 xAcc = GetMap()->GetContext( pUpper, !bDisposing ); 660 661 ASSERT( xAcc.is() || bDisposing, "no parent found" ); 662 663 // Remember the parent as weak ref. 664 { 665 vos::OGuard aWeakParentGuard( aMutex ); 666 xWeakParent = xAcc; 667 } 668 669 return xAcc; 670 } 671 672 sal_Int32 SAL_CALL SwAccessibleContext::getAccessibleIndexInParent (void) 673 throw (uno::RuntimeException) 674 { 675 vos::OGuard aGuard(Application::GetSolarMutex()); 676 677 CHECK_FOR_DEFUNC( XAccessibleContext ) 678 679 const SwFrm *pUpper = GetParent(); 680 ASSERT( pUpper != 0 || bDisposing, "no upper found" ); 681 682 sal_Int32 nIndex = -1; 683 if( pUpper ) 684 { 685 ::vos::ORef < SwAccessibleContext > xAccImpl( 686 GetMap()->GetContextImpl( pUpper, !bDisposing ) ); 687 ASSERT( xAccImpl.isValid() || bDisposing, "no parent found" ); 688 if( xAccImpl.isValid() ) 689 nIndex = xAccImpl->GetChildIndex( *(GetMap()), SwAccessibleChild(GetFrm()) ); 690 } 691 692 return nIndex; 693 } 694 695 sal_Int16 SAL_CALL SwAccessibleContext::getAccessibleRole (void) 696 throw (uno::RuntimeException) 697 { 698 return nRole; 699 } 700 701 OUString SAL_CALL SwAccessibleContext::getAccessibleDescription (void) 702 throw (uno::RuntimeException) 703 { 704 ASSERT( !this, "description needs to be overloaded" ); 705 THROW_RUNTIME_EXCEPTION( XAccessibleContext, "internal error (method must be overloaded)" ); 706 } 707 708 OUString SAL_CALL SwAccessibleContext::getAccessibleName (void) 709 throw (uno::RuntimeException) 710 { 711 return sName; 712 } 713 714 uno::Reference< XAccessibleRelationSet> SAL_CALL 715 SwAccessibleContext::getAccessibleRelationSet (void) 716 throw (uno::RuntimeException) 717 { 718 // by default there are no relations 719 uno::Reference< XAccessibleRelationSet> xRet( new utl::AccessibleRelationSetHelper() ); 720 return xRet; 721 } 722 723 uno::Reference<XAccessibleStateSet> SAL_CALL 724 SwAccessibleContext::getAccessibleStateSet (void) 725 throw (uno::RuntimeException) 726 { 727 vos::OGuard aGuard(Application::GetSolarMutex()); 728 729 CHECK_FOR_DEFUNC( XAccessibleContext ) 730 731 ::utl::AccessibleStateSetHelper *pStateSet = 732 new ::utl::AccessibleStateSetHelper; 733 734 uno::Reference<XAccessibleStateSet> xStateSet( pStateSet ); 735 GetStates( *pStateSet ); 736 737 return xStateSet; 738 } 739 740 lang::Locale SAL_CALL SwAccessibleContext::getLocale (void) 741 throw (IllegalAccessibleComponentStateException, uno::RuntimeException) 742 { 743 vos::OGuard aGuard(Application::GetSolarMutex()); 744 745 lang::Locale aLoc( Application::GetSettings().GetLocale() ); 746 return aLoc; 747 } 748 749 void SAL_CALL SwAccessibleContext::addEventListener( 750 const uno::Reference< XAccessibleEventListener >& xListener ) 751 throw (uno::RuntimeException) 752 { 753 DBG_MSG( "accessible event listener added" ) 754 755 if (xListener.is()) 756 { 757 vos::OGuard aGuard(Application::GetSolarMutex()); 758 if (!nClientId) 759 nClientId = comphelper::AccessibleEventNotifier::registerClient( ); 760 comphelper::AccessibleEventNotifier::addEventListener( nClientId, xListener ); 761 } 762 } 763 764 void SAL_CALL SwAccessibleContext::removeEventListener( 765 const uno::Reference< XAccessibleEventListener >& xListener ) 766 throw (uno::RuntimeException) 767 { 768 DBG_MSG( "accessible event listener removed" ) 769 770 if (xListener.is()) 771 { 772 vos::OGuard aGuard(Application::GetSolarMutex()); 773 sal_Int32 nListenerCount = comphelper::AccessibleEventNotifier::removeEventListener( nClientId, xListener ); 774 if ( !nListenerCount ) 775 { 776 // no listeners anymore 777 // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client), 778 // and at least to us not firing any events anymore, in case somebody calls 779 // NotifyAccessibleEvent, again 780 comphelper::AccessibleEventNotifier::revokeClient( nClientId ); 781 nClientId = 0; 782 } 783 } 784 } 785 786 static sal_Bool lcl_PointInRectangle(const awt::Point & aPoint, 787 const awt::Rectangle & aRect) 788 { 789 long nDiffX = aPoint.X - aRect.X; 790 long nDiffY = aPoint.Y - aRect.Y; 791 792 return 793 nDiffX >= 0 && nDiffX < aRect.Width && nDiffY >= 0 && 794 nDiffY < aRect.Height; 795 796 } 797 798 sal_Bool SAL_CALL SwAccessibleContext::containsPoint( 799 const awt::Point& aPoint ) 800 throw (uno::RuntimeException) 801 { 802 awt::Rectangle aPixBounds = getBoundsImpl(sal_True); 803 aPixBounds.X = 0; 804 aPixBounds.Y = 0; 805 806 return lcl_PointInRectangle(aPoint, aPixBounds); 807 } 808 809 uno::Reference< XAccessible > SAL_CALL SwAccessibleContext::getAccessibleAtPoint( 810 const awt::Point& aPoint ) 811 throw (uno::RuntimeException) 812 { 813 vos::OGuard aGuard(Application::GetSolarMutex()); 814 815 CHECK_FOR_DEFUNC( XAccessibleComponent ) 816 817 uno::Reference< XAccessible > xAcc; 818 819 Window *pWin = GetWindow(); 820 CHECK_FOR_WINDOW( XAccessibleComponent, pWin ) 821 822 Point aPixPoint( aPoint.X, aPoint.Y ); // px rel to parent 823 if( !GetFrm()->IsRootFrm() ) 824 { 825 SwRect aLogBounds( GetBounds( *(GetMap()), GetFrm() ) ); // twip rel to doc root 826 Point aPixPos( GetMap()->CoreToPixel( aLogBounds.SVRect() ).TopLeft() ); 827 aPixPoint.X() += aPixPos.X(); 828 aPixPoint.Y() += aPixPos.Y(); 829 } 830 831 const SwAccessibleChild aChild( GetChildAtPixel( aPixPoint, *(GetMap()) ) ); 832 if( aChild.GetSwFrm() ) 833 { 834 xAcc = GetMap()->GetContext( aChild.GetSwFrm() ); 835 } 836 else if( aChild.GetDrawObject() ) 837 { 838 xAcc = GetMap()->GetContext( aChild.GetDrawObject(), this ); 839 } 840 else if ( aChild.GetWindow() ) 841 { 842 xAcc = aChild.GetWindow()->GetAccessible(); 843 } 844 845 return xAcc; 846 } 847 848 849 /** 850 Get bounding box. 851 852 There are two modes. 853 854 - realative 855 856 Return bounding box relative to parent if parent is no root 857 frame. Otherwise return the absolute bounding box. 858 859 - absolute 860 861 Return the absolute bounding box. 862 863 @param bRelative 864 true: Use relative mode. 865 false: Use absolute mode. 866 */ 867 awt::Rectangle SAL_CALL SwAccessibleContext::getBoundsImpl(sal_Bool bRelative) 868 throw (uno::RuntimeException) 869 { 870 vos::OGuard aGuard(Application::GetSolarMutex()); 871 872 CHECK_FOR_DEFUNC( XAccessibleComponent ) 873 874 const SwFrm *pParent = GetParent(); 875 ASSERT( pParent, "no Parent found" ); 876 Window *pWin = GetWindow(); 877 878 CHECK_FOR_WINDOW( XAccessibleComponent, pWin && pParent ) 879 880 SwRect aLogBounds( GetBounds( *(GetMap()), GetFrm() ) ); // twip rel to doc root 881 Rectangle aPixBounds( 0, 0, 0, 0 ); 882 if( GetFrm()->IsPageFrm() && 883 static_cast < const SwPageFrm * >( GetFrm() )->IsEmptyPage() ) 884 { 885 ASSERT( GetShell()->IsPreView(), "empty page accessible?" ); 886 if( GetShell()->IsPreView() ) 887 { 888 // OD 15.01.2003 #103492# - adjust method call <GetMap()->GetPreViewPageSize()> 889 sal_uInt16 nPageNum = 890 static_cast < const SwPageFrm * >( GetFrm() )->GetPhyPageNum(); 891 aLogBounds.SSize( GetMap()->GetPreViewPageSize( nPageNum ) ); 892 } 893 } 894 if( !aLogBounds.IsEmpty() ) 895 { 896 aPixBounds = GetMap()->CoreToPixel( aLogBounds.SVRect() ); 897 if( !pParent->IsRootFrm() && bRelative) 898 { 899 SwRect aParentLogBounds( GetBounds( *(GetMap()), pParent ) ); // twip rel to doc root 900 Point aParentPixPos( GetMap()->CoreToPixel( aParentLogBounds.SVRect() ).TopLeft() ); 901 aPixBounds.Move( -aParentPixPos.X(), -aParentPixPos.Y() ); 902 } 903 } 904 905 awt::Rectangle aBox( aPixBounds.Left(), aPixBounds.Top(), 906 aPixBounds.GetWidth(), aPixBounds.GetHeight() ); 907 908 return aBox; 909 } 910 911 912 awt::Rectangle SAL_CALL SwAccessibleContext::getBounds() 913 throw (uno::RuntimeException) 914 { 915 return getBoundsImpl(sal_True); 916 } 917 918 awt::Point SAL_CALL SwAccessibleContext::getLocation() 919 throw (uno::RuntimeException) 920 { 921 awt::Rectangle aRect = getBoundsImpl(sal_True); 922 awt::Point aPoint(aRect.X, aRect.Y); 923 924 return aPoint; 925 } 926 927 928 929 awt::Point SAL_CALL SwAccessibleContext::getLocationOnScreen() 930 throw (uno::RuntimeException) 931 { 932 awt::Rectangle aRect = getBoundsImpl(sal_False); 933 934 Point aPixPos(aRect.X, aRect.Y); 935 936 /* getBoundsImpl already checked that GetWindow returns valid pointer. */ 937 aPixPos = GetWindow()->OutputToAbsoluteScreenPixel(aPixPos); 938 awt::Point aPoint(aPixPos.X(), aPixPos.Y()); 939 940 return aPoint; 941 } 942 943 944 awt::Size SAL_CALL SwAccessibleContext::getSize() 945 throw (uno::RuntimeException) 946 { 947 awt::Rectangle aRect = getBoundsImpl(sal_False); 948 awt::Size aSize( aRect.Width, aRect.Height ); 949 950 return aSize; 951 } 952 953 void SAL_CALL SwAccessibleContext::grabFocus() 954 throw (uno::RuntimeException) 955 { 956 vos::OGuard aGuard(Application::GetSolarMutex()); 957 958 CHECK_FOR_DEFUNC( XAccessibleContext ); 959 960 if( GetFrm()->IsFlyFrm() ) 961 { 962 const SdrObject *pObj = 963 static_cast < const SwFlyFrm * >( GetFrm() )->GetVirtDrawObj(); 964 if( pObj ) 965 Select( const_cast < SdrObject * >( pObj ), sal_False ); 966 } 967 else 968 { 969 const SwCntntFrm *pCFrm = 0; 970 if( GetFrm()->IsCntntFrm() ) 971 pCFrm = static_cast< const SwCntntFrm * >( GetFrm() ); 972 else if( GetFrm()->IsLayoutFrm() ) 973 pCFrm = static_cast< const SwLayoutFrm * >( GetFrm() )->ContainsCntnt(); 974 975 if( pCFrm && pCFrm->IsTxtFrm() ) 976 { 977 const SwTxtFrm *pTxtFrm = static_cast< const SwTxtFrm * >( pCFrm ); 978 const SwTxtNode *pTxtNd = pTxtFrm->GetTxtNode(); 979 if( pTxtNd ) 980 { 981 // create pam for selection 982 SwIndex aIndex( const_cast< SwTxtNode * >( pTxtNd ), 983 pTxtFrm->GetOfst() ); 984 SwPosition aStartPos( *pTxtNd, aIndex ); 985 SwPaM aPaM( aStartPos ); 986 987 // set PaM at cursor shell 988 Select( aPaM ); 989 } 990 } 991 } 992 } 993 994 995 uno::Any SAL_CALL SwAccessibleContext::getAccessibleKeyBinding() 996 throw (uno::RuntimeException) 997 { 998 // There are no key bindings 999 return uno::Any(); 1000 } 1001 1002 sal_Int32 SAL_CALL SwAccessibleContext::getForeground() 1003 throw (uno::RuntimeException) 1004 { 1005 return 0; 1006 } 1007 1008 sal_Int32 SAL_CALL SwAccessibleContext::getBackground() 1009 throw (uno::RuntimeException) 1010 { 1011 return 0xffffff; 1012 } 1013 1014 1015 OUString SAL_CALL SwAccessibleContext::getImplementationName() 1016 throw( uno::RuntimeException ) 1017 { 1018 ASSERT( !this, "implementation name needs to be overloaded" ); 1019 1020 THROW_RUNTIME_EXCEPTION( lang::XServiceInfo, "implementation name needs to be overloaded" ) 1021 } 1022 1023 sal_Bool SAL_CALL 1024 SwAccessibleContext::supportsService (const ::rtl::OUString& ) 1025 throw (uno::RuntimeException) 1026 { 1027 ASSERT( !this, "supports service needs to be overloaded" ); 1028 THROW_RUNTIME_EXCEPTION( lang::XServiceInfo, "supports service needs to be overloaded" ) 1029 } 1030 1031 uno::Sequence< OUString > SAL_CALL SwAccessibleContext::getSupportedServiceNames() 1032 throw( uno::RuntimeException ) 1033 { 1034 ASSERT( !this, "supported services names needs to be overloaded" ); 1035 THROW_RUNTIME_EXCEPTION( lang::XServiceInfo, "supported services needs to be overloaded" ) 1036 } 1037 1038 void SwAccessibleContext::DisposeShape( const SdrObject *pObj, 1039 ::accessibility::AccessibleShape *pAccImpl ) 1040 { 1041 ::vos::ORef< ::accessibility::AccessibleShape > xAccImpl( pAccImpl ); 1042 if( !xAccImpl.isValid() ) 1043 xAccImpl = GetMap()->GetContextImpl( pObj, this, sal_True ); 1044 1045 AccessibleEventObject aEvent; 1046 aEvent.EventId = AccessibleEventId::CHILD; 1047 uno::Reference< XAccessible > xAcc( xAccImpl.getBodyPtr() ); 1048 aEvent.OldValue <<= xAcc; 1049 FireAccessibleEvent( aEvent ); 1050 1051 GetMap()->RemoveContext( pObj ); 1052 xAccImpl->dispose(); 1053 } 1054 1055 void SwAccessibleContext::ScrolledInShape( const SdrObject* , 1056 ::accessibility::AccessibleShape *pAccImpl ) 1057 { 1058 AccessibleEventObject aEvent; 1059 aEvent.EventId = AccessibleEventId::CHILD; 1060 uno::Reference< XAccessible > xAcc( pAccImpl ); 1061 aEvent.NewValue <<= xAcc; 1062 FireAccessibleEvent( aEvent ); 1063 1064 if( pAccImpl->GetState( AccessibleStateType::FOCUSED ) ) 1065 { 1066 Window *pWin = GetWindow(); 1067 if( pWin && pWin->HasFocus() ) 1068 { 1069 AccessibleEventObject aStateChangedEvent; 1070 aStateChangedEvent.EventId = AccessibleEventId::STATE_CHANGED; 1071 aStateChangedEvent.NewValue <<= AccessibleStateType::FOCUSED; 1072 aStateChangedEvent.Source = xAcc; 1073 1074 FireAccessibleEvent( aStateChangedEvent ); 1075 } 1076 } 1077 } 1078 1079 void SwAccessibleContext::Dispose( sal_Bool bRecursive ) 1080 { 1081 vos::OGuard aGuard(Application::GetSolarMutex()); 1082 1083 ASSERT( GetFrm() && GetMap(), "already disposed" ); 1084 ASSERT( GetMap()->GetVisArea() == GetVisArea(), 1085 "invalid vis area for dispose" ); 1086 1087 bDisposing = sal_True; 1088 1089 // dispose children 1090 if( bRecursive ) 1091 DisposeChildren( GetFrm(), bRecursive ); 1092 1093 // get parent 1094 uno::Reference< XAccessible > xParent( GetWeakParent() ); 1095 uno::Reference < XAccessibleContext > xThis( this ); 1096 1097 // send child event at parent 1098 if( xParent.is() ) 1099 { 1100 SwAccessibleContext *pAcc = (SwAccessibleContext *)xParent.get(); 1101 1102 AccessibleEventObject aEvent; 1103 aEvent.EventId = AccessibleEventId::CHILD; 1104 aEvent.OldValue <<= xThis; 1105 pAcc->FireAccessibleEvent( aEvent ); 1106 DBG_MSG_THIS_PARAM( "AccessibleChild (removed)", pAcc, this ) 1107 } 1108 1109 // set defunc state (its not required to broadcast a state changed 1110 // event if the object is diposed afterwards) 1111 { 1112 vos::OGuard aDefuncStateGuard( aMutex ); 1113 bIsDefuncState = sal_True; 1114 } 1115 1116 // broadcast dispose event 1117 if ( nClientId ) 1118 { 1119 comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( nClientId, *this ); 1120 nClientId = 0; 1121 DBG_MSG_CD( "dispose" ) 1122 } 1123 1124 RemoveFrmFromAccessibleMap(); 1125 ClearFrm(); 1126 pMap = 0; 1127 1128 bDisposing = sal_False; 1129 } 1130 1131 void SwAccessibleContext::DisposeChild( const SwAccessibleChild& rChildFrmOrObj, 1132 sal_Bool bRecursive ) 1133 { 1134 vos::OGuard aGuard(Application::GetSolarMutex()); 1135 1136 if ( IsShowing( *(GetMap()), rChildFrmOrObj ) || 1137 rChildFrmOrObj.AlwaysIncludeAsChild() || 1138 !SwAccessibleChild( GetFrm() ).IsVisibleChildrenOnly() ) 1139 { 1140 // If the object could have existed before, than there is nothing to do, 1141 // because no wrapper exists now and therefor no one is interested to 1142 // get notified of the movement. 1143 if( rChildFrmOrObj.GetSwFrm() ) 1144 { 1145 ::vos::ORef< SwAccessibleContext > xAccImpl = 1146 GetMap()->GetContextImpl( rChildFrmOrObj.GetSwFrm(), 1147 sal_True ); 1148 xAccImpl->Dispose( bRecursive ); 1149 } 1150 else if ( rChildFrmOrObj.GetDrawObject() ) 1151 { 1152 ::vos::ORef< ::accessibility::AccessibleShape > xAccImpl = 1153 GetMap()->GetContextImpl( rChildFrmOrObj.GetDrawObject(), 1154 this, sal_True ); 1155 DisposeShape( rChildFrmOrObj.GetDrawObject(), 1156 xAccImpl.getBodyPtr() ); 1157 } 1158 else if ( rChildFrmOrObj.GetWindow() ) 1159 { 1160 AccessibleEventObject aEvent; 1161 aEvent.EventId = AccessibleEventId::CHILD; 1162 uno::Reference< XAccessible > xAcc = 1163 rChildFrmOrObj.GetWindow()->GetAccessible(); 1164 aEvent.OldValue <<= xAcc; 1165 FireAccessibleEvent( aEvent ); 1166 } 1167 } 1168 else if( bRecursive && rChildFrmOrObj.GetSwFrm() ) 1169 DisposeChildren( rChildFrmOrObj.GetSwFrm(), bRecursive ); 1170 } 1171 1172 void SwAccessibleContext::InvalidatePosOrSize( const SwRect& ) 1173 { 1174 vos::OGuard aGuard(Application::GetSolarMutex()); 1175 1176 ASSERT( GetFrm() && !GetFrm()->Frm().IsEmpty(), "context should have a size" ); 1177 1178 sal_Bool bIsOldShowingState; 1179 sal_Bool bIsNewShowingState = IsShowing( *(GetMap()) ); 1180 { 1181 vos::OGuard aShowingStateGuard( aMutex ); 1182 bIsOldShowingState = bIsShowingState; 1183 bIsShowingState = bIsNewShowingState; 1184 } 1185 1186 if( bIsOldShowingState != bIsNewShowingState ) 1187 { 1188 FireStateChangedEvent( AccessibleStateType::SHOWING, 1189 bIsNewShowingState ); 1190 } 1191 else if( bIsNewShowingState ) 1192 { 1193 // The frame stays visible -> broadcast event 1194 FireVisibleDataEvent(); 1195 } 1196 1197 if( !bIsNewShowingState && 1198 SwAccessibleChild( GetParent() ).IsVisibleChildrenOnly() ) 1199 { 1200 // The frame is now invisible -> dispose it 1201 Dispose( sal_True ); 1202 } 1203 else 1204 { 1205 _InvalidateContent( sal_True ); 1206 } 1207 } 1208 1209 void SwAccessibleContext::InvalidateChildPosOrSize( 1210 const SwAccessibleChild& rChildFrmOrObj, 1211 const SwRect& rOldFrm ) 1212 { 1213 vos::OGuard aGuard(Application::GetSolarMutex()); 1214 1215 ASSERT( !rChildFrmOrObj.GetSwFrm() || 1216 !rChildFrmOrObj.GetSwFrm()->Frm().IsEmpty(), 1217 "child context should have a size" ); 1218 1219 if ( rChildFrmOrObj.AlwaysIncludeAsChild() ) 1220 { 1221 // nothing to do; 1222 return; 1223 } 1224 1225 const bool bVisibleChildrenOnly = SwAccessibleChild( GetFrm() ).IsVisibleChildrenOnly(); 1226 const bool bNew = rOldFrm.IsEmpty() || 1227 ( rOldFrm.Left() == 0 && rOldFrm.Top() == 0 ); 1228 if( IsShowing( *(GetMap()), rChildFrmOrObj ) ) 1229 { 1230 // If the object could have existed before, than there is nothing to do, 1231 // because no wrapper exists now and therefor no one is interested to 1232 // get notified of the movement. 1233 if( bNew || (bVisibleChildrenOnly && !IsShowing( rOldFrm )) ) 1234 { 1235 if( rChildFrmOrObj.GetSwFrm() ) 1236 { 1237 // The frame becomes visible. A child event must be send. 1238 ::vos::ORef< SwAccessibleContext > xAccImpl = 1239 GetMap()->GetContextImpl( rChildFrmOrObj.GetSwFrm(), 1240 sal_True ); 1241 xAccImpl->ScrolledIn(); 1242 } 1243 else if ( rChildFrmOrObj.GetDrawObject() ) 1244 { 1245 ::vos::ORef< ::accessibility::AccessibleShape > xAccImpl = 1246 GetMap()->GetContextImpl( rChildFrmOrObj.GetDrawObject(), 1247 this, sal_True ); 1248 // --> OD 2004-11-29 #i37790# 1249 if ( xAccImpl.isValid() ) 1250 { 1251 ScrolledInShape( rChildFrmOrObj.GetDrawObject(), 1252 xAccImpl.getBodyPtr() ); 1253 } 1254 else 1255 { 1256 ASSERT( false , 1257 "<SwAccessibleContext::InvalidateChildPosOrSize(..)> - no accessible shape found." ); 1258 } 1259 // <-- 1260 } 1261 else if ( rChildFrmOrObj.GetWindow() ) 1262 { 1263 AccessibleEventObject aEvent; 1264 aEvent.EventId = AccessibleEventId::CHILD; 1265 aEvent.NewValue <<= (rChildFrmOrObj.GetWindow()->GetAccessible()); 1266 FireAccessibleEvent( aEvent ); 1267 } 1268 } 1269 } 1270 else 1271 { 1272 // If the frame was visible before, than a child event for the parent 1273 // needs to be send. However, there is no wrapper existing, and so 1274 // no notifications for grandchildren are required. If the are 1275 // grandgrandchildren, they would be notified by the layout. 1276 if( bVisibleChildrenOnly && 1277 !bNew && IsShowing( rOldFrm ) ) 1278 { 1279 if( rChildFrmOrObj.GetSwFrm() ) 1280 { 1281 ::vos::ORef< SwAccessibleContext > xAccImpl = 1282 GetMap()->GetContextImpl( rChildFrmOrObj.GetSwFrm(), 1283 sal_True ); 1284 xAccImpl->SetParent( this ); 1285 xAccImpl->Dispose( sal_True ); 1286 } 1287 else if ( rChildFrmOrObj.GetDrawObject() ) 1288 { 1289 ::vos::ORef< ::accessibility::AccessibleShape > xAccImpl = 1290 GetMap()->GetContextImpl( rChildFrmOrObj.GetDrawObject(), 1291 this, sal_True ); 1292 DisposeShape( rChildFrmOrObj.GetDrawObject(), 1293 xAccImpl.getBodyPtr() ); 1294 } 1295 else if ( rChildFrmOrObj.GetWindow() ) 1296 { 1297 ASSERT( false, 1298 "<SwAccessibleContext::InvalidateChildPosOrSize(..)> - not expected to handle dispose of child of type <Window>." ); 1299 } 1300 } 1301 } 1302 } 1303 1304 void SwAccessibleContext::InvalidateContent() 1305 { 1306 vos::OGuard aGuard(Application::GetSolarMutex()); 1307 1308 _InvalidateContent( sal_False ); 1309 } 1310 1311 void SwAccessibleContext::InvalidateCursorPos() 1312 { 1313 vos::OGuard aGuard(Application::GetSolarMutex()); 1314 1315 _InvalidateCursorPos(); 1316 } 1317 1318 void SwAccessibleContext::InvalidateFocus() 1319 { 1320 vos::OGuard aGuard(Application::GetSolarMutex()); 1321 1322 _InvalidateFocus(); 1323 } 1324 1325 // --> OD 2005-12-12 #i27301# - use new type definition for <_nStates> 1326 void SwAccessibleContext::InvalidateStates( tAccessibleStates _nStates ) 1327 { 1328 if( GetMap() ) 1329 { 1330 ViewShell *pVSh = GetMap()->GetShell(); 1331 if( pVSh ) 1332 { 1333 if( (_nStates & ACC_STATE_EDITABLE) != 0 ) 1334 { 1335 sal_Bool bIsOldEditableState; 1336 sal_Bool bIsNewEditableState = IsEditable( pVSh ); 1337 { 1338 vos::OGuard aGuard( aMutex ); 1339 bIsOldEditableState = bIsEditableState; 1340 bIsEditableState = bIsNewEditableState; 1341 } 1342 1343 if( bIsOldEditableState != bIsNewEditableState ) 1344 FireStateChangedEvent( AccessibleStateType::EDITABLE, 1345 bIsNewEditableState ); 1346 } 1347 if( (_nStates & ACC_STATE_OPAQUE) != 0 ) 1348 { 1349 sal_Bool bIsOldOpaqueState; 1350 sal_Bool bIsNewOpaqueState = IsOpaque( pVSh ); 1351 { 1352 vos::OGuard aGuard( aMutex ); 1353 bIsOldOpaqueState = bIsOpaqueState; 1354 bIsOpaqueState = bIsNewOpaqueState; 1355 } 1356 1357 if( bIsOldOpaqueState != bIsNewOpaqueState ) 1358 FireStateChangedEvent( AccessibleStateType::OPAQUE, 1359 bIsNewOpaqueState ); 1360 } 1361 } 1362 1363 InvalidateChildrenStates( GetFrm(), _nStates ); 1364 } 1365 } 1366 // <-- 1367 1368 void SwAccessibleContext::InvalidateRelation( sal_uInt16 nType ) 1369 { 1370 AccessibleEventObject aEvent; 1371 aEvent.EventId = nType; 1372 1373 FireAccessibleEvent( aEvent ); 1374 } 1375 1376 /** text selection has changed 1377 1378 OD 2005-12-14 #i27301# 1379 1380 @author OD 1381 */ 1382 void SwAccessibleContext::InvalidateTextSelection() 1383 { 1384 AccessibleEventObject aEvent; 1385 aEvent.EventId = AccessibleEventId::TEXT_SELECTION_CHANGED; 1386 1387 FireAccessibleEvent( aEvent ); 1388 } 1389 1390 /** attributes has changed 1391 1392 OD 2009-01-06 #i88069# 1393 1394 @author OD 1395 */ 1396 void SwAccessibleContext::InvalidateAttr() 1397 { 1398 AccessibleEventObject aEvent; 1399 aEvent.EventId = AccessibleEventId::TEXT_ATTRIBUTE_CHANGED; 1400 1401 FireAccessibleEvent( aEvent ); 1402 } 1403 1404 sal_Bool SwAccessibleContext::HasCursor() 1405 { 1406 return sal_False; 1407 } 1408 1409 sal_Bool SwAccessibleContext::Select( SwPaM *pPaM, SdrObject *pObj, 1410 sal_Bool bAdd ) 1411 { 1412 SwCrsrShell* pCrsrShell = GetCrsrShell(); 1413 if( !pCrsrShell ) 1414 return sal_False; 1415 1416 SwFEShell* pFEShell = pCrsrShell->ISA( SwFEShell ) 1417 ? static_cast<SwFEShell*>( pCrsrShell ) 1418 : 0; 1419 // Get rid of activated OLE object 1420 if( pFEShell ) 1421 pFEShell->FinishOLEObj(); 1422 1423 sal_Bool bRet = sal_False; 1424 if( pObj ) 1425 { 1426 if( pFEShell ) 1427 { 1428 Point aDummy; 1429 sal_uInt8 nFlags = bAdd ? SW_ADD_SELECT : 0; 1430 pFEShell->SelectObj( aDummy, nFlags, pObj ); 1431 bRet = sal_True; 1432 } 1433 } 1434 else if( pPaM ) 1435 { 1436 // Get rid of frame selection. If there is one, make text cursor 1437 // visible again. 1438 sal_Bool bCallShowCrsr = sal_False; 1439 if( pFEShell && (pFEShell->IsFrmSelected() || 1440 pFEShell->IsObjSelected()) ) 1441 { 1442 Point aPt( LONG_MIN, LONG_MIN ); 1443 pFEShell->SelectObj( aPt, 0 ); 1444 bCallShowCrsr = sal_True; 1445 } 1446 pCrsrShell->KillPams(); 1447 pCrsrShell->SetSelection( *pPaM ); 1448 if( bCallShowCrsr ) 1449 pCrsrShell->ShowCrsr(); 1450 bRet = sal_True; 1451 } 1452 1453 return bRet; 1454 } 1455 1456 OUString SwAccessibleContext::GetResource( sal_uInt16 nResId, 1457 const OUString *pArg1, 1458 const OUString *pArg2 ) 1459 { 1460 String sStr; 1461 { 1462 vos::OGuard aGuard(Application::GetSolarMutex()); 1463 1464 sStr = SW_RES( nResId ); 1465 } 1466 1467 if( pArg1 ) 1468 { 1469 sStr.SearchAndReplace( String::CreateFromAscii( 1470 RTL_CONSTASCII_STRINGPARAM( "$(ARG1)" )), 1471 String( *pArg1 ) ); 1472 } 1473 if( pArg2 ) 1474 { 1475 sStr.SearchAndReplace( String::CreateFromAscii( 1476 RTL_CONSTASCII_STRINGPARAM( "$(ARG2)" )), 1477 String( *pArg2 ) ); 1478 } 1479 1480 return OUString( sStr ); 1481 } 1482 1483 void SwAccessibleContext::RemoveFrmFromAccessibleMap() 1484 { 1485 if( bRegisteredAtAccessibleMap && GetFrm() && GetMap() ) 1486 GetMap()->RemoveContext( GetFrm() ); 1487 } 1488 1489 bool SwAccessibleContext::HasAdditionalAccessibleChildren() 1490 { 1491 bool bRet( false ); 1492 1493 if ( GetFrm()->IsTxtFrm() ) 1494 { 1495 SwPostItMgr* pPostItMgr = GetMap()->GetShell()->GetPostItMgr(); 1496 if ( pPostItMgr && pPostItMgr->HasNotes() && pPostItMgr->ShowNotes() ) 1497 { 1498 bRet = pPostItMgr->HasFrmConnectedSidebarWins( *(GetFrm()) ); 1499 } 1500 } 1501 1502 return bRet; 1503 } 1504 /** get additional accessible child by index 1505 1506 OD 2010-01-27 #i88070# 1507 1508 @author OD 1509 */ 1510 Window* SwAccessibleContext::GetAdditionalAccessibleChild( const sal_Int32 nIndex ) 1511 { 1512 Window* pAdditionalAccessibleChild( 0 ); 1513 1514 if ( GetFrm()->IsTxtFrm() ) 1515 { 1516 SwPostItMgr* pPostItMgr = GetMap()->GetShell()->GetPostItMgr(); 1517 if ( pPostItMgr && pPostItMgr->HasNotes() && pPostItMgr->ShowNotes() ) 1518 { 1519 pAdditionalAccessibleChild = 1520 pPostItMgr->GetSidebarWinForFrmByIndex( *(GetFrm()), nIndex ); 1521 } 1522 } 1523 1524 return pAdditionalAccessibleChild; 1525 } 1526 1527 /** get all additional accessible children 1528 1529 OD 2010-01-27 #i88070# 1530 1531 @author OD 1532 */ 1533 void SwAccessibleContext::GetAdditionalAccessibleChildren( std::vector< Window* >* pChildren ) 1534 { 1535 if ( GetFrm()->IsTxtFrm() ) 1536 { 1537 SwPostItMgr* pPostItMgr = GetMap()->GetShell()->GetPostItMgr(); 1538 if ( pPostItMgr && pPostItMgr->HasNotes() && pPostItMgr->ShowNotes() ) 1539 { 1540 pPostItMgr->GetAllSidebarWinForFrm( *(GetFrm()), pChildren ); 1541 } 1542 } 1543 } 1544 1545 #if (OSL_DEBUG_LEVEL > 1) && defined TEST_MIB 1546 void lcl_SwAccessibleContext_DbgMsg( SwAccessibleContext *pThisAcc, 1547 const char *pMsg, 1548 SwAccessibleContext *pChildAcc, 1549 sal_Bool bConstrDestr ) 1550 { 1551 static SvFileStream aStrm( String::CreateFromAscii("j:\\acc.log"), 1552 STREAM_WRITE|STREAM_TRUNC|STREAM_SHARE_DENYNONE ); 1553 ByteString aName( String(pThisAcc->GetName()), 1554 RTL_TEXTENCODING_ISO_8859_1 ); 1555 if( aName.Len() ) 1556 { 1557 aStrm << aName.GetBuffer() 1558 << ": "; 1559 } 1560 aStrm << pMsg; 1561 if( pChildAcc ) 1562 { 1563 ByteString aChild( String(pChildAcc->GetName()), 1564 RTL_TEXTENCODING_ISO_8859_1 ); 1565 aStrm << ": " 1566 << aChild.GetBuffer(); 1567 } 1568 aStrm << "\r\n ("; 1569 1570 if( !bConstrDestr ) 1571 { 1572 ByteString aDesc( String(pThisAcc->getAccessibleDescription()), 1573 RTL_TEXTENCODING_ISO_8859_1 ); 1574 aStrm << aDesc.GetBuffer() 1575 << ", "; 1576 } 1577 1578 Rectangle aVisArea( pThisAcc->GetVisArea() ); 1579 aStrm << "VA: " 1580 << ByteString::CreateFromInt32( aVisArea.Left() ).GetBuffer() 1581 << "," 1582 << ByteString::CreateFromInt32( aVisArea.Top() ).GetBuffer() 1583 << "," 1584 << ByteString::CreateFromInt32( aVisArea.GetWidth() ).GetBuffer() 1585 << "," 1586 << ByteString::CreateFromInt32( aVisArea.GetHeight() ).GetBuffer(); 1587 1588 if( pThisAcc->GetFrm() ) 1589 { 1590 Rectangle aBounds( pThisAcc->GetBounds( pThisAcc->GetFrm() ) ); 1591 aStrm << ", BB: " 1592 << ByteString::CreateFromInt32( aBounds.Left() ).GetBuffer() 1593 << "," 1594 << ByteString::CreateFromInt32( aBounds.Top() ).GetBuffer() 1595 << "," 1596 << ByteString::CreateFromInt32( aBounds.GetWidth() ).GetBuffer() 1597 << "," 1598 << ByteString::CreateFromInt32( aBounds.GetHeight() ).GetBuffer() 1599 << ")\r\n"; 1600 } 1601 1602 aStrm.Flush(); 1603 } 1604 #endif 1605