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