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 27 28 #include <vos/ref.hxx> 29 #include <cppuhelper/weakref.hxx> 30 #include <vcl/window.hxx> 31 #include <svx/svdmodel.hxx> 32 #include <svx/unomod.hxx> 33 #include <tools/debug.hxx> 34 35 #include <map> 36 #include <list> 37 #include <vector> 38 #include <accmap.hxx> 39 #include <acccontext.hxx> 40 #include <accdoc.hxx> 41 #include <accpreview.hxx> 42 #include <accpage.hxx> 43 #include <accpara.hxx> 44 #include <accheaderfooter.hxx> 45 #include <accfootnote.hxx> 46 #include <acctextframe.hxx> 47 #include <accgraphic.hxx> 48 #include <accembedded.hxx> 49 #include <acccell.hxx> 50 #include <acctable.hxx> 51 #include <fesh.hxx> 52 #include <rootfrm.hxx> 53 #include <txtfrm.hxx> 54 #include <hffrm.hxx> 55 #include <ftnfrm.hxx> 56 #include <cellfrm.hxx> 57 #include <tabfrm.hxx> 58 #include <pagefrm.hxx> 59 #include <flyfrm.hxx> 60 #include <ndtyp.hxx> 61 #include <IDocumentDrawModelAccess.hxx> 62 #include <svx/ShapeTypeHandler.hxx> 63 #include <vcl/svapp.hxx> 64 //IAccessibility2 Implementation 2009----- 65 #ifndef _SVX_ACCESSIBILITY_SHAPE_TYPE_HANDLER_HXX 66 #include <svx/ShapeTypeHandler.hxx> 67 #endif 68 #ifndef _SVX_ACCESSIBILITY_SVX_SHAPE_TYPES_HXX 69 #include <svx/SvxShapeTypes.hxx> 70 #endif 71 #ifndef _SVDPAGE_HXX 72 #include <svx/svdpage.hxx> 73 #endif 74 #include <com/sun/star/accessibility/AccessibleRelationType.hpp> 75 #include <com/sun/star/accessibility/AccessibleEventId.hpp> 76 #include <com/sun/star/accessibility/AccessibleStateType.hpp> 77 #include <com/sun/star/accessibility/AccessibleRole.hpp> 78 #include <cppuhelper/implbase1.hxx> 79 #include <pagepreviewlayout.hxx> 80 #include <dcontact.hxx> 81 #include <svx/unoapi.hxx> 82 #include <svx/svdmark.hxx> 83 #include <doc.hxx> 84 #include <pam.hxx> 85 #include <ndtxt.hxx> 86 #include <dflyobj.hxx> 87 #include <prevwpage.hxx> 88 #include <switerator.hxx> 89 90 using namespace ::com::sun::star; 91 using namespace ::com::sun::star::accessibility; 92 using ::rtl::OUString; 93 using namespace ::sw::access; 94 95 struct SwFrmFunc 96 { 97 sal_Bool operator()( const SwFrm * p1, 98 const SwFrm * p2) const 99 { 100 return p1 < p2; 101 } 102 }; 103 104 typedef ::std::map < const SwFrm *, uno::WeakReference < XAccessible >, SwFrmFunc > _SwAccessibleContextMap_Impl; 105 106 class SwAccessibleContextMap_Impl: public _SwAccessibleContextMap_Impl 107 { 108 public: 109 110 #ifdef DBG_UTIL 111 sal_Bool mbLocked; 112 #endif 113 114 SwAccessibleContextMap_Impl() 115 #ifdef DBG_UTIL 116 : mbLocked( sal_False ) 117 #endif 118 {} 119 120 }; 121 122 //------------------------------------------------------------------------------ 123 class SwDrawModellListener_Impl : public SfxListener, 124 public ::cppu::WeakImplHelper1< document::XEventBroadcaster > 125 { 126 mutable ::osl::Mutex maListenerMutex; 127 ::cppu::OInterfaceContainerHelper maEventListeners; 128 SdrModel *mpDrawModel; 129 protected: 130 virtual ~SwDrawModellListener_Impl(); 131 public: 132 133 SwDrawModellListener_Impl( SdrModel *pDrawModel ); 134 135 136 virtual void SAL_CALL addEventListener( const uno::Reference< document::XEventListener >& xListener ) throw (uno::RuntimeException); 137 virtual void SAL_CALL removeEventListener( const uno::Reference< document::XEventListener >& xListener ) throw (uno::RuntimeException); 138 139 virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ); 140 void Dispose(); 141 }; 142 143 SwDrawModellListener_Impl::SwDrawModellListener_Impl( SdrModel *pDrawModel ) : 144 maEventListeners( maListenerMutex ), 145 mpDrawModel( pDrawModel ) 146 { 147 StartListening( *mpDrawModel ); 148 } 149 150 SwDrawModellListener_Impl::~SwDrawModellListener_Impl() 151 { 152 EndListening( *mpDrawModel ); 153 } 154 155 void SAL_CALL SwDrawModellListener_Impl::addEventListener( const uno::Reference< document::XEventListener >& xListener ) throw (uno::RuntimeException) 156 { 157 maEventListeners.addInterface( xListener ); 158 } 159 160 void SAL_CALL SwDrawModellListener_Impl::removeEventListener( const uno::Reference< document::XEventListener >& xListener ) throw (uno::RuntimeException) 161 { 162 maEventListeners.removeInterface( xListener ); 163 } 164 165 void SwDrawModellListener_Impl::Notify( SfxBroadcaster& /*rBC*/, 166 const SfxHint& rHint ) 167 { 168 // do not broadcast notifications for writer fly frames, because there 169 // are no shapes that need to know about them. 170 // OD 01.07.2003 #110554# - correct condition in order not to broadcast 171 // notifications for writer fly frames. 172 // OD 01.07.2003 #110554# - do not broadcast notifications for plane 173 // <SdrObject>objects 174 const SdrHint *pSdrHint = PTR_CAST( SdrHint, &rHint ); 175 if ( !pSdrHint || 176 ( pSdrHint->GetObject() && 177 ( pSdrHint->GetObject()->ISA(SwFlyDrawObj) || 178 pSdrHint->GetObject()->ISA(SwVirtFlyDrawObj) || 179 IS_TYPE(SdrObject,pSdrHint->GetObject()) ) ) ) 180 { 181 return; 182 } 183 184 ASSERT( mpDrawModel, "draw model listener is disposed" ); 185 if( !mpDrawModel ) 186 return; 187 188 document::EventObject aEvent; 189 if( !SvxUnoDrawMSFactory::createEvent( mpDrawModel, pSdrHint, aEvent ) ) 190 return; 191 192 ::cppu::OInterfaceIteratorHelper aIter( maEventListeners ); 193 while( aIter.hasMoreElements() ) 194 { 195 uno::Reference < document::XEventListener > xListener( aIter.next(), 196 uno::UNO_QUERY ); 197 try 198 { 199 xListener->notifyEvent( aEvent ); 200 } 201 catch( uno::RuntimeException const & r ) 202 { 203 (void)r; 204 #if OSL_DEBUG_LEVEL > 1 205 ByteString aError( "Runtime exception caught while notifying shape.:\n" ); 206 aError += ByteString( String( r.Message), RTL_TEXTENCODING_ASCII_US ); 207 DBG_ERROR( aError.GetBuffer() ); 208 #endif 209 } 210 } 211 } 212 213 void SwDrawModellListener_Impl::Dispose() 214 { 215 mpDrawModel = 0; 216 } 217 218 //------------------------------------------------------------------------------ 219 struct SwShapeFunc 220 { 221 sal_Bool operator()( const SdrObject * p1, 222 const SdrObject * p2) const 223 { 224 return p1 < p2; 225 } 226 }; 227 typedef ::std::map < const SdrObject *, uno::WeakReference < XAccessible >, SwShapeFunc > _SwAccessibleShapeMap_Impl; 228 typedef ::std::pair < const SdrObject *, ::vos::ORef < ::accessibility::AccessibleShape > > SwAccessibleObjShape_Impl; 229 230 class SwAccessibleShapeMap_Impl: public _SwAccessibleShapeMap_Impl 231 232 { 233 ::accessibility::AccessibleShapeTreeInfo maInfo; 234 235 public: 236 237 #ifdef DBG_UTIL 238 sal_Bool mbLocked; 239 #endif 240 SwAccessibleShapeMap_Impl( SwAccessibleMap *pMap ) 241 #ifdef DBG_UTIL 242 : mbLocked( sal_False ) 243 #endif 244 { 245 maInfo.SetSdrView( pMap->GetShell()->GetDrawView() ); 246 maInfo.SetWindow( pMap->GetShell()->GetWin() ); 247 maInfo.SetViewForwarder( pMap ); 248 // --> OD 2005-08-08 #i52858# - method name changed 249 uno::Reference < document::XEventBroadcaster > xModelBroadcaster = 250 new SwDrawModellListener_Impl( 251 pMap->GetShell()->getIDocumentDrawModelAccess()->GetOrCreateDrawModel() ); 252 // <-- 253 maInfo.SetControllerBroadcaster( xModelBroadcaster ); 254 } 255 256 ~SwAccessibleShapeMap_Impl(); 257 258 const ::accessibility::AccessibleShapeTreeInfo& GetInfo() const { return maInfo; } 259 260 SwAccessibleObjShape_Impl *Copy( size_t& rSize, 261 const SwFEShell *pFESh = 0, 262 SwAccessibleObjShape_Impl **pSelShape = 0 ) const; 263 }; 264 265 SwAccessibleShapeMap_Impl::~SwAccessibleShapeMap_Impl() 266 { 267 uno::Reference < document::XEventBroadcaster > xBrd( maInfo.GetControllerBroadcaster() ); 268 if( xBrd.is() ) 269 static_cast < SwDrawModellListener_Impl * >( xBrd.get() )->Dispose(); 270 } 271 272 SwAccessibleObjShape_Impl 273 *SwAccessibleShapeMap_Impl::Copy( 274 size_t& rSize, const SwFEShell *pFESh, 275 SwAccessibleObjShape_Impl **pSelStart ) const 276 { 277 SwAccessibleObjShape_Impl *pShapes = 0; 278 SwAccessibleObjShape_Impl *pSelShape = 0; 279 280 sal_uInt16 nSelShapes = pFESh ? pFESh->IsObjSelected() : 0; 281 rSize = size(); 282 283 if( rSize > 0 ) 284 { 285 pShapes = 286 new SwAccessibleObjShape_Impl[rSize]; 287 288 const_iterator aIter = begin(); 289 const_iterator aEndIter = end(); 290 291 SwAccessibleObjShape_Impl *pShape = pShapes; 292 pSelShape = &(pShapes[rSize]); 293 while( aIter != aEndIter ) 294 { 295 const SdrObject *pObj = (*aIter).first; 296 uno::Reference < XAccessible > xAcc( (*aIter).second ); 297 //IAccessibility2 Implementation 2009----- 298 if( nSelShapes && pFESh &&pFESh->IsObjSelected( *pObj ) ) 299 //-----IAccessibility2 Implementation 2009 300 { 301 // selected objects are inserted from the back 302 --pSelShape; 303 pSelShape->first = pObj; 304 pSelShape->second = 305 static_cast < ::accessibility::AccessibleShape* >( 306 xAcc.get() ); 307 --nSelShapes; 308 } 309 else 310 { 311 pShape->first = pObj; 312 pShape->second = 313 static_cast < ::accessibility::AccessibleShape* >( 314 xAcc.get() ); 315 ++pShape; 316 } 317 ++aIter; 318 } 319 ASSERT( pSelShape == pShape, "copying shapes went wrong!" ); 320 } 321 322 if( pSelStart ) 323 *pSelStart = pSelShape; 324 325 return pShapes; 326 } 327 328 //------------------------------------------------------------------------------ 329 struct SwAccessibleEvent_Impl 330 { 331 public: 332 enum EventType { CARET_OR_STATES, 333 INVALID_CONTENT, 334 POS_CHANGED, 335 CHILD_POS_CHANGED, 336 SHAPE_SELECTION, 337 DISPOSE, 338 INVALID_ATTR }; 339 340 private: 341 SwRect maOldBox; // the old bounds for CHILD_POS_CHANGED 342 // and POS_CHANGED 343 uno::WeakReference < XAccessible > mxAcc; // The object that fires the event 344 SwAccessibleChild maFrmOrObj; // the child for CHILD_POS_CHANGED and 345 // the same as xAcc for any other 346 // event type 347 EventType meType; // The event type 348 // --> OD 2005-12-12 #i27301# - use new type definition for <mnStates> 349 tAccessibleStates mnStates; // check states or update caret pos 350 // <-- 351 352 SwAccessibleEvent_Impl& operator==( const SwAccessibleEvent_Impl& ); 353 354 public: 355 //IAccessibility2 Implementation 2009----- 356 const SwFrm* mpParentFrm; // The object that fires the event 357 sal_Bool IsNoXaccParentFrm() const 358 { 359 return CHILD_POS_CHANGED == meType && mpParentFrm != 0; 360 } 361 uno::WeakReference < XAccessible > GetxAcc() const { return mxAcc;} 362 //-----IAccessibility2 Implementation 2009 363 public: 364 SwAccessibleEvent_Impl( EventType eT, 365 SwAccessibleContext *pA, 366 const SwAccessibleChild& rFrmOrObj ) 367 : mxAcc( pA ), 368 maFrmOrObj( rFrmOrObj ), 369 meType( eT ), 370 mnStates( 0 ), 371 mpParentFrm( 0 ) 372 {} 373 374 SwAccessibleEvent_Impl( EventType eT, 375 const SwAccessibleChild& rFrmOrObj ) 376 : maFrmOrObj( rFrmOrObj ), 377 meType( eT ), 378 mnStates( 0 ), 379 mpParentFrm( 0 ) 380 { 381 ASSERT( SwAccessibleEvent_Impl::DISPOSE == meType, 382 "wrong event constructor, DISPOSE only" ); 383 } 384 385 SwAccessibleEvent_Impl( EventType eT ) 386 : meType( eT ), 387 mnStates( 0 ), 388 mpParentFrm( 0 ) 389 { 390 ASSERT( SwAccessibleEvent_Impl::SHAPE_SELECTION == meType, 391 "wrong event constructor, SHAPE_SELECTION only" ); 392 } 393 394 SwAccessibleEvent_Impl( EventType eT, 395 SwAccessibleContext *pA, 396 const SwAccessibleChild& rFrmOrObj, 397 const SwRect& rR ) 398 : maOldBox( rR ), 399 mxAcc( pA ), 400 maFrmOrObj( rFrmOrObj ), 401 meType( eT ), 402 mnStates( 0 ), 403 mpParentFrm( 0 ) 404 { 405 ASSERT( SwAccessibleEvent_Impl::CHILD_POS_CHANGED == meType || 406 SwAccessibleEvent_Impl::POS_CHANGED == meType, 407 "wrong event constructor, (CHILD_)POS_CHANGED only" ); 408 } 409 410 // --> OD 2005-12-12 #i27301# - use new type definition for parameter <_nStates> 411 SwAccessibleEvent_Impl( EventType eT, 412 SwAccessibleContext *pA, 413 const SwAccessibleChild& rFrmOrObj, 414 const tAccessibleStates _nStates ) 415 : mxAcc( pA ), 416 maFrmOrObj( rFrmOrObj ), 417 meType( eT ), 418 mnStates( _nStates ), 419 mpParentFrm( 0 ) 420 { 421 ASSERT( SwAccessibleEvent_Impl::CARET_OR_STATES == meType, 422 "wrong event constructor, CARET_OR_STATES only" ); 423 } 424 425 //IAccessibility2 Implementation 2009----- 426 SwAccessibleEvent_Impl( EventType eT, 427 const SwFrm *pParentFrm, 428 const SwAccessibleChild& rFrmOrObj, 429 const SwRect& rR ) : 430 maOldBox( rR ), 431 maFrmOrObj( rFrmOrObj ), 432 meType( eT ), 433 mnStates( 0 ), 434 mpParentFrm( pParentFrm ) 435 { 436 OSL_ENSURE( SwAccessibleEvent_Impl::CHILD_POS_CHANGED == meType, 437 "wrong event constructor, CHILD_POS_CHANGED only" ); 438 } 439 //-----IAccessibility2 Implementation 2009 440 // <SetType(..)> only used in method <SwAccessibleMap::AppendEvent(..)> 441 inline void SetType( EventType eT ) 442 { 443 meType = eT; 444 } 445 inline EventType GetType() const 446 { 447 return meType; 448 } 449 450 inline ::vos::ORef < SwAccessibleContext > GetContext() const 451 { 452 uno::Reference < XAccessible > xTmp( mxAcc ); 453 ::vos::ORef < SwAccessibleContext > xAccImpl( 454 static_cast<SwAccessibleContext*>( xTmp.get() ) ); 455 456 return xAccImpl; 457 } 458 459 inline const SwRect& GetOldBox() const 460 { 461 return maOldBox; 462 } 463 // <SetOldBox(..)> only used in method <SwAccessibleMap::AppendEvent(..)> 464 inline void SetOldBox( const SwRect& rOldBox ) 465 { 466 maOldBox = rOldBox; 467 } 468 469 inline const SwAccessibleChild& GetFrmOrObj() const 470 { 471 return maFrmOrObj; 472 } 473 474 // <SetStates(..)> only used in method <SwAccessibleMap::AppendEvent(..)> 475 // --> OD 2005-12-12 #i27301# - use new type definition for parameter <_nStates> 476 inline void SetStates( tAccessibleStates _nStates ) 477 { 478 mnStates |= _nStates; 479 } 480 // <-- 481 482 inline sal_Bool IsUpdateCursorPos() const 483 { 484 return (mnStates & ACC_STATE_CARET) != 0; 485 } 486 inline sal_Bool IsInvalidateStates() const 487 { 488 return (mnStates & ACC_STATE_MASK) != 0; 489 } 490 inline sal_Bool IsInvalidateRelation() const 491 { 492 return (mnStates & ACC_STATE_RELATION_MASK) != 0; 493 } 494 // --> OD 2005-12-12 #i27301# - new event TEXT_SELECTION_CHANGED 495 inline sal_Bool IsInvalidateTextSelection() const 496 { 497 return ( mnStates & ACC_STATE_TEXT_SELECTION_CHANGED ) != 0; 498 } 499 // <-- 500 // --> OD 2009-01-07 #i88069# - new event TEXT_ATTRIBUTE_CHANGED 501 inline sal_Bool IsInvalidateTextAttrs() const 502 { 503 return ( mnStates & ACC_STATE_TEXT_ATTRIBUTE_CHANGED ) != 0; 504 } 505 // <-- 506 // --> OD 2005-12-12 #i27301# - use new type definition <tAccessibleStates> 507 // for return value 508 inline tAccessibleStates GetStates() const 509 { 510 return mnStates & ACC_STATE_MASK; 511 } 512 // <-- 513 // --> OD 2005-12-12 #i27301# - use new type definition <tAccessibleStates> 514 // for return value 515 inline tAccessibleStates GetAllStates() const 516 { 517 return mnStates; 518 } 519 // <-- 520 }; 521 522 //------------------------------------------------------------------------------ 523 typedef ::std::list < SwAccessibleEvent_Impl > _SwAccessibleEventList_Impl; 524 525 class SwAccessibleEventList_Impl: public _SwAccessibleEventList_Impl 526 { 527 sal_Bool mbFiring; 528 529 public: 530 531 SwAccessibleEventList_Impl() 532 : mbFiring( sal_False ) 533 {} 534 535 inline void SetFiring() 536 { 537 mbFiring = sal_True; 538 } 539 inline sal_Bool IsFiring() const 540 { 541 return mbFiring; 542 } 543 //IAccessibility2 Implementation 2009----- 544 struct XAccisNULL 545 { 546 bool operator()(const SwAccessibleEvent_Impl& e) 547 { 548 return e.IsNoXaccParentFrm(); 549 } 550 }; 551 void MoveInvalidXAccToEnd(); 552 //-----IAccessibility2 Implementation 2009 553 }; 554 555 //IAccessibility2 Implementation 2009----- 556 void SwAccessibleEventList_Impl::MoveInvalidXAccToEnd() 557 { 558 int nSize = size(); 559 if (nSize < 2 ) 560 { 561 return; 562 } 563 SwAccessibleEventList_Impl lstEvent; 564 iterator li = begin(); 565 for ( ;li != end();) 566 { 567 SwAccessibleEvent_Impl e = *li; 568 if (e.IsNoXaccParentFrm()) 569 { 570 iterator liNext = li; 571 ++liNext; 572 erase(li); 573 li = liNext; 574 lstEvent.insert(lstEvent.end(),e); 575 } 576 else 577 ++li; 578 } 579 OSL_ENSURE(size() + lstEvent.size() == nSize ,""); 580 insert(end(),lstEvent.begin(),lstEvent.end()); 581 OSL_ENSURE(size() == nSize ,""); 582 } 583 //-----IAccessibility2 Implementation 2009 584 //------------------------------------------------------------------------------ 585 // The shape list is filled if an accessible shape is destroyed. It 586 // simply keeps a reference to the accessible shape's XShape. These 587 // references are destroyed within the EndAction when firing events, 588 // There are twp reason for this. First of all, a new accessible shape 589 // for the XShape might be created soon. It's then cheaper if the XShape 590 // still exists. The other reason are situations where an accessible shape 591 // is destroyed within an SwFrmFmt::Modify. In this case, destryoing 592 // the XShape at the same time (indirectly by destroying the accessible 593 // shape) leads to an assert, because a client of the Modify is destroyed 594 // within a Modify call. 595 596 typedef ::std::list < uno::Reference < drawing::XShape > > _SwShapeList_Impl; 597 598 class SwShapeList_Impl: public _SwShapeList_Impl 599 { 600 public: 601 602 SwShapeList_Impl() {} 603 }; 604 605 606 //------------------------------------------------------------------------------ 607 struct SwAccessibleChildFunc 608 { 609 sal_Bool operator()( const SwAccessibleChild& r1, 610 const SwAccessibleChild& r2 ) const 611 { 612 const void *p1 = r1.GetSwFrm() 613 ? static_cast < const void * >( r1.GetSwFrm()) 614 : ( r1.GetDrawObject() 615 ? static_cast < const void * >( r1.GetDrawObject() ) 616 : static_cast < const void * >( r1.GetWindow() ) ); 617 const void *p2 = r2.GetSwFrm() 618 ? static_cast < const void * >( r2.GetSwFrm()) 619 : ( r2.GetDrawObject() 620 ? static_cast < const void * >( r2.GetDrawObject() ) 621 : static_cast < const void * >( r2.GetWindow() ) ); 622 return p1 < p2; 623 } 624 }; 625 typedef ::std::map < SwAccessibleChild, SwAccessibleEventList_Impl::iterator, 626 SwAccessibleChildFunc > _SwAccessibleEventMap_Impl; 627 628 class SwAccessibleEventMap_Impl: public _SwAccessibleEventMap_Impl 629 { 630 }; 631 632 //------------------------------------------------------------------------------ 633 // --> OD 2005-12-13 #i27301# - map containing the accessible paragraph, which 634 // have a selection. Needed to keep this information to submit corresponding 635 // TEXT_SELECTION_CHANGED events. 636 struct SwAccessibleParaSelection 637 { 638 xub_StrLen nStartOfSelection; 639 xub_StrLen nEndOfSelection; 640 641 SwAccessibleParaSelection( const xub_StrLen _nStartOfSelection, 642 const xub_StrLen _nEndOfSelection ) 643 : nStartOfSelection( _nStartOfSelection ), 644 nEndOfSelection( _nEndOfSelection ) 645 {} 646 }; 647 648 struct SwXAccWeakRefComp 649 { 650 sal_Bool operator()( const uno::WeakReference<XAccessible>& _rXAccWeakRef1, 651 const uno::WeakReference<XAccessible>& _rXAccWeakRef2 ) const 652 { 653 return _rXAccWeakRef1.get() < _rXAccWeakRef2.get(); 654 } 655 }; 656 657 typedef ::std::map< uno::WeakReference < XAccessible >, 658 SwAccessibleParaSelection, 659 SwXAccWeakRefComp > _SwAccessibleSelectedParas_Impl; 660 661 class SwAccessibleSelectedParas_Impl: public _SwAccessibleSelectedParas_Impl 662 {}; 663 // <-- 664 665 // helper class that stores preview data 666 class SwAccPreviewData 667 { 668 typedef std::vector<Rectangle> Rectangles; 669 Rectangles maPreviewRects; 670 Rectangles maLogicRects; 671 672 SwRect maVisArea; 673 Fraction maScale; 674 675 const SwPageFrm *mpSelPage; 676 677 /** adjust logic page retangle to its visible part 678 679 OD 17.01.2003 #103492# 680 681 @author OD 682 683 @param _iorLogicPgSwRect 684 input/output parameter - reference to the logic page rectangle, which 685 has to be adjusted. 686 687 @param _rPrevwPgSwRect 688 input parameter - constant reference to the corresponding preview page 689 rectangle; needed to determine the visible part of the logic page rectangle. 690 691 @param _rPrevwWinSize 692 input paramter - constant reference to the preview window size in TWIP; 693 needed to determine the visible part of the logic page rectangle 694 */ 695 void AdjustLogicPgRectToVisibleArea( SwRect& _iorLogicPgSwRect, 696 const SwRect& _rPrevwPgSwRect, 697 const Size& _rPrevwWinSize ); 698 699 public: 700 SwAccPreviewData(); 701 ~SwAccPreviewData(); 702 703 // OD 14.01.2003 #103492# - complete re-factoring of method due to new 704 // page/print preview functionality. 705 void Update( const SwAccessibleMap& rAccMap, 706 const std::vector<PrevwPage*>& _rPrevwPages, 707 const Fraction& _rScale, 708 const SwPageFrm* _pSelectedPageFrm, 709 const Size& _rPrevwWinSize ); 710 711 // OD 14.01.2003 #103492# - complete re-factoring of method due to new 712 // page/print preview functionality. 713 void InvalidateSelection( const SwPageFrm* _pSelectedPageFrm ); 714 715 const SwRect& GetVisArea() const; 716 717 MapMode GetMapModeForPreview( ) const; 718 719 /** Adjust the MapMode so that the preview page appears at the 720 * proper position. rPoint identifies the page for which the 721 * MapMode should be adjusted. If bFromPreview is true, rPoint is 722 * a preview coordinate; else it's a document coordinate. */ 723 // OD 17.01.2003 #103492# - delete unused 3rd parameter. 724 void AdjustMapMode( MapMode& rMapMode, 725 const Point& rPoint ) const; 726 727 inline const SwPageFrm *GetSelPage() const { return mpSelPage; } 728 729 void DisposePage(const SwPageFrm *pPageFrm ); 730 }; 731 732 SwAccPreviewData::SwAccPreviewData() : 733 mpSelPage( 0 ) 734 { 735 } 736 737 SwAccPreviewData::~SwAccPreviewData() 738 { 739 } 740 741 // OD 13.01.2003 #103492# - complete re-factoring of method due to new page/print 742 // preview functionality. 743 void SwAccPreviewData::Update( const SwAccessibleMap& rAccMap, 744 const std::vector<PrevwPage*>& _rPrevwPages, 745 const Fraction& _rScale, 746 const SwPageFrm* _pSelectedPageFrm, 747 const Size& _rPrevwWinSize ) 748 { 749 // store preview scaling, maximal preview page size and selected page 750 maScale = _rScale; 751 mpSelPage = _pSelectedPageFrm; 752 753 // prepare loop on preview pages 754 maPreviewRects.clear(); 755 maLogicRects.clear(); 756 SwAccessibleChild aPage; 757 maVisArea.Clear(); 758 759 // loop on preview pages to calculate <maPreviewRects>, <maLogicRects> and 760 // <maVisArea> 761 for ( std::vector<PrevwPage*>::const_iterator aPageIter = _rPrevwPages.begin(); 762 aPageIter != _rPrevwPages.end(); 763 ++aPageIter ) 764 { 765 aPage = (*aPageIter)->pPage; 766 767 // add preview page rectangle to <maPreviewRects> 768 Rectangle aPrevwPgRect( (*aPageIter)->aPrevwWinPos, (*aPageIter)->aPageSize ); 769 maPreviewRects.push_back( aPrevwPgRect ); 770 771 // add logic page rectangle to <maLogicRects> 772 SwRect aLogicPgSwRect( aPage.GetBox( rAccMap ) ); 773 Rectangle aLogicPgRect( aLogicPgSwRect.SVRect() ); 774 maLogicRects.push_back( aLogicPgRect ); 775 // union visible area with visible part of logic page rectangle 776 if ( (*aPageIter)->bVisible ) 777 { 778 if ( !(*aPageIter)->pPage->IsEmptyPage() ) 779 { 780 AdjustLogicPgRectToVisibleArea( aLogicPgSwRect, 781 SwRect( aPrevwPgRect ), 782 _rPrevwWinSize ); 783 } 784 if ( maVisArea.IsEmpty() ) 785 maVisArea = aLogicPgSwRect; 786 else 787 maVisArea.Union( aLogicPgSwRect ); 788 } 789 } 790 } 791 792 // OD 16.01.2003 #103492# - complete re-factoring of method due to new page/print 793 // preview functionality. 794 void SwAccPreviewData::InvalidateSelection( const SwPageFrm* _pSelectedPageFrm ) 795 { 796 mpSelPage = _pSelectedPageFrm; 797 ASSERT( mpSelPage, "selected page not found" ); 798 } 799 800 struct ContainsPredicate 801 { 802 const Point& mrPoint; 803 ContainsPredicate( const Point& rPoint ) : mrPoint(rPoint) {} 804 bool operator() ( const Rectangle& rRect ) const 805 { 806 return rRect.IsInside( mrPoint ) ? true : false; 807 } 808 }; 809 810 const SwRect& SwAccPreviewData::GetVisArea() const 811 { 812 return maVisArea; 813 } 814 815 void SwAccPreviewData::AdjustMapMode( MapMode& rMapMode, 816 const Point& rPoint ) const 817 { 818 // adjust scale 819 rMapMode.SetScaleX( maScale ); 820 rMapMode.SetScaleY( maScale ); 821 822 // find proper rectangle 823 Rectangles::const_iterator aBegin = maLogicRects.begin(); 824 Rectangles::const_iterator aEnd = maLogicRects.end(); 825 Rectangles::const_iterator aFound = ::std::find_if( aBegin, aEnd, 826 ContainsPredicate( rPoint ) ); 827 828 if( aFound != aEnd ) 829 { 830 // found! set new origin 831 Point aPoint = (maPreviewRects.begin() + (aFound - aBegin))->TopLeft(); 832 aPoint -= (maLogicRects.begin() + (aFound-aBegin))->TopLeft(); 833 rMapMode.SetOrigin( aPoint ); 834 } 835 // else: don't adjust MapMode 836 } 837 838 void SwAccPreviewData::DisposePage(const SwPageFrm *pPageFrm ) 839 { 840 if( mpSelPage == pPageFrm ) 841 mpSelPage = 0; 842 } 843 844 /** adjust logic page retangle to its visible part 845 846 OD 17.01.2003 #103492# 847 848 @author OD 849 */ 850 void SwAccPreviewData::AdjustLogicPgRectToVisibleArea( 851 SwRect& _iorLogicPgSwRect, 852 const SwRect& _rPrevwPgSwRect, 853 const Size& _rPrevwWinSize ) 854 { 855 // determine preview window rectangle 856 const SwRect aPrevwWinSwRect( Point( 0, 0 ), _rPrevwWinSize ); 857 // calculate visible preview page rectangle 858 SwRect aVisPrevwPgSwRect( _rPrevwPgSwRect ); 859 aVisPrevwPgSwRect.Intersection( aPrevwWinSwRect ); 860 // adjust logic page rectangle 861 SwTwips nTmpDiff; 862 // left 863 nTmpDiff = aVisPrevwPgSwRect.Left() - _rPrevwPgSwRect.Left(); 864 if ( nTmpDiff > 0 ) 865 _iorLogicPgSwRect.Left( _iorLogicPgSwRect.Left() + nTmpDiff ); 866 // top 867 nTmpDiff = aVisPrevwPgSwRect.Top() - _rPrevwPgSwRect.Top(); 868 if ( nTmpDiff > 0 ) 869 _iorLogicPgSwRect.Top( _iorLogicPgSwRect.Top() + nTmpDiff ); 870 // right 871 nTmpDiff = _rPrevwPgSwRect.Right() - aVisPrevwPgSwRect.Right(); 872 if ( nTmpDiff > 0 ) 873 _iorLogicPgSwRect.Right( _iorLogicPgSwRect.Right() - nTmpDiff ); 874 // bottom 875 nTmpDiff = _rPrevwPgSwRect.Bottom() - aVisPrevwPgSwRect.Bottom(); 876 if ( nTmpDiff > 0 ) 877 _iorLogicPgSwRect.Bottom( _iorLogicPgSwRect.Bottom() - nTmpDiff ); 878 } 879 880 //------------------------------------------------------------------------------ 881 static sal_Bool AreInSameTable( const uno::Reference< XAccessible >& rAcc, 882 const SwFrm *pFrm ) 883 { 884 sal_Bool bRet = sal_False; 885 886 if( pFrm && pFrm->IsCellFrm() && rAcc.is() ) 887 { 888 // Is it in the same table? We check that 889 // by comparing the last table frame in the 890 // follow chain, because that's cheaper than 891 // searching the first one. 892 SwAccessibleContext *pAccImpl = 893 static_cast< SwAccessibleContext *>( rAcc.get() ); 894 if( pAccImpl->GetFrm()->IsCellFrm() ) 895 { 896 const SwTabFrm *pTabFrm1 = pAccImpl->GetFrm()->FindTabFrm(); 897 while( pTabFrm1->GetFollow() ) 898 pTabFrm1 = pTabFrm1->GetFollow(); 899 900 const SwTabFrm *pTabFrm2 = pFrm->FindTabFrm(); 901 while( pTabFrm2->GetFollow() ) 902 pTabFrm2 = pTabFrm2->GetFollow(); 903 904 bRet = (pTabFrm1 == pTabFrm2); 905 } 906 } 907 908 return bRet; 909 } 910 911 void SwAccessibleMap::FireEvent( const SwAccessibleEvent_Impl& rEvent ) 912 { 913 ::vos::ORef < SwAccessibleContext > xAccImpl( rEvent.GetContext() ); 914 //IAccessibility2 Implementation 2009----- 915 if (!xAccImpl.isValid() && rEvent.mpParentFrm != 0 ) 916 { 917 SwAccessibleContextMap_Impl::iterator aIter = 918 mpFrmMap->find( rEvent.mpParentFrm ); 919 if( aIter != mpFrmMap->end() ) 920 { 921 uno::Reference < XAccessible > xAcc( (*aIter).second ); 922 if (xAcc.is()) 923 { 924 uno::Reference < XAccessibleContext > xContext(xAcc,uno::UNO_QUERY); 925 if (xContext.is() && xContext->getAccessibleRole() == AccessibleRole::PARAGRAPH) 926 { 927 xAccImpl = static_cast< SwAccessibleContext *>( xAcc.get() ); 928 } 929 } 930 } 931 } 932 //-----IAccessibility2 Implementation 2009 933 if( SwAccessibleEvent_Impl::SHAPE_SELECTION == rEvent.GetType() ) 934 { 935 DoInvalidateShapeSelection(); 936 } 937 else if( xAccImpl.isValid() && xAccImpl->GetFrm() ) 938 { 939 // --> OD 2009-01-07 #i88069# 940 if ( rEvent.GetType() != SwAccessibleEvent_Impl::DISPOSE && 941 rEvent.IsInvalidateTextAttrs() ) 942 { 943 xAccImpl->InvalidateAttr(); 944 } 945 // <-- 946 switch( rEvent.GetType() ) 947 { 948 case SwAccessibleEvent_Impl::INVALID_CONTENT: 949 xAccImpl->InvalidateContent(); 950 break; 951 case SwAccessibleEvent_Impl::POS_CHANGED: 952 xAccImpl->InvalidatePosOrSize( rEvent.GetOldBox() ); 953 break; 954 case SwAccessibleEvent_Impl::CHILD_POS_CHANGED: 955 xAccImpl->InvalidateChildPosOrSize( rEvent.GetFrmOrObj(), 956 rEvent.GetOldBox() ); 957 break; 958 case SwAccessibleEvent_Impl::DISPOSE: 959 ASSERT( xAccImpl.isValid(), 960 "dispose event has been stored" ); 961 break; 962 // --> OD 2009-01-06 #i88069# 963 case SwAccessibleEvent_Impl::INVALID_ATTR: 964 // nothing to do here - handled above 965 break; 966 // <-- 967 default: 968 break; 969 } 970 if( SwAccessibleEvent_Impl::DISPOSE != rEvent.GetType() ) 971 { 972 if( rEvent.IsUpdateCursorPos() ) 973 xAccImpl->InvalidateCursorPos(); 974 if( rEvent.IsInvalidateStates() ) 975 xAccImpl->InvalidateStates( rEvent.GetStates() ); 976 if( rEvent.IsInvalidateRelation() ) 977 { 978 // --> OD 2005-12-01 #i27138# 979 // both events CONTENT_FLOWS_FROM_RELATION_CHANGED and 980 // CONTENT_FLOWS_TO_RELATION_CHANGED are possible 981 if ( rEvent.GetAllStates() & ACC_STATE_RELATION_FROM ) 982 { 983 xAccImpl->InvalidateRelation( 984 AccessibleEventId::CONTENT_FLOWS_FROM_RELATION_CHANGED ); 985 } 986 if ( rEvent.GetAllStates() & ACC_STATE_RELATION_TO ) 987 { 988 xAccImpl->InvalidateRelation( 989 AccessibleEventId::CONTENT_FLOWS_TO_RELATION_CHANGED ); 990 } 991 // <-- 992 } 993 // --> OD 2005-12-12 #i27301# - submit event TEXT_SELECTION_CHANGED 994 if ( rEvent.IsInvalidateTextSelection() ) 995 { 996 xAccImpl->InvalidateTextSelection(); 997 } 998 // <-- 999 } 1000 } 1001 } 1002 1003 void SwAccessibleMap::AppendEvent( const SwAccessibleEvent_Impl& rEvent ) 1004 { 1005 vos::OGuard aGuard( maEventMutex ); 1006 1007 if( !mpEvents ) 1008 mpEvents = new SwAccessibleEventList_Impl; 1009 if( !mpEventMap ) 1010 mpEventMap = new SwAccessibleEventMap_Impl; 1011 1012 if( mpEvents->IsFiring() ) 1013 { 1014 // While events are fired new ones are generated. They have to be fired 1015 // now. This does not work for DISPOSE events! 1016 ASSERT( rEvent.GetType() != SwAccessibleEvent_Impl::DISPOSE, 1017 "dispose event while firing events" ); 1018 FireEvent( rEvent ); 1019 } 1020 else 1021 { 1022 1023 SwAccessibleEventMap_Impl::iterator aIter = 1024 mpEventMap->find( rEvent.GetFrmOrObj() ); 1025 if( aIter != mpEventMap->end() ) 1026 { 1027 SwAccessibleEvent_Impl aEvent( *(*aIter).second ); 1028 ASSERT( aEvent.GetType() != SwAccessibleEvent_Impl::DISPOSE, 1029 "dispose events should not be stored" ); 1030 sal_Bool bAppendEvent = sal_True; 1031 switch( rEvent.GetType() ) 1032 { 1033 case SwAccessibleEvent_Impl::CARET_OR_STATES: 1034 // A CARET_OR_STATES event is added to any other 1035 // event only. It is broadcasted after any other event, so the 1036 // event should be put to the back. 1037 ASSERT( aEvent.GetType() != SwAccessibleEvent_Impl::CHILD_POS_CHANGED, 1038 "invalid event combination" ); 1039 aEvent.SetStates( rEvent.GetAllStates() ); 1040 break; 1041 case SwAccessibleEvent_Impl::INVALID_CONTENT: 1042 // An INVALID_CONTENT event overwrites a CARET_OR_STATES 1043 // event (but keeps its flags) and it is contained in a 1044 // POS_CHANGED event. 1045 // Therefor, the event's type has to be adapted and the event 1046 // has to be put at the end. 1047 ASSERT( aEvent.GetType() != SwAccessibleEvent_Impl::CHILD_POS_CHANGED, 1048 "invalid event combination" ); 1049 if( aEvent.GetType() == SwAccessibleEvent_Impl::CARET_OR_STATES ) 1050 aEvent.SetType( SwAccessibleEvent_Impl::INVALID_CONTENT ); 1051 break; 1052 case SwAccessibleEvent_Impl::POS_CHANGED: 1053 // A pos changed event overwrites CARET_STATES (keeping its 1054 // flags) as well as INVALID_CONTENT. The old box position 1055 // has to be stored however if the old event is not a 1056 // POS_CHANGED itself. 1057 ASSERT( aEvent.GetType() != SwAccessibleEvent_Impl::CHILD_POS_CHANGED, 1058 "invalid event combination" ); 1059 if( aEvent.GetType() != SwAccessibleEvent_Impl::POS_CHANGED ) 1060 aEvent.SetOldBox( rEvent.GetOldBox() ); 1061 aEvent.SetType( SwAccessibleEvent_Impl::POS_CHANGED ); 1062 break; 1063 case SwAccessibleEvent_Impl::CHILD_POS_CHANGED: 1064 // CHILD_POS_CHANGED events can only follow CHILD_POS_CHANGED 1065 // events. The only action that needs to be done again is 1066 // to put the old event to the back. The new one cannot be used, 1067 // because we are interested in the old frame bounds. 1068 ASSERT( aEvent.GetType() == SwAccessibleEvent_Impl::CHILD_POS_CHANGED, 1069 "invalid event combination" ); 1070 break; 1071 case SwAccessibleEvent_Impl::SHAPE_SELECTION: 1072 ASSERT( aEvent.GetType() == SwAccessibleEvent_Impl::SHAPE_SELECTION, 1073 "invalid event combination" ); 1074 break; 1075 case SwAccessibleEvent_Impl::DISPOSE: 1076 // DISPOSE events overwrite all others. They are not stored 1077 // but executed immediatly to avoid broadcasting of 1078 // defunctional objects. So what needs to be done here is to 1079 // remove all events for the frame in question. 1080 bAppendEvent = sal_False; 1081 break; 1082 // --> OD 2009-01-06 #i88069# 1083 case SwAccessibleEvent_Impl::INVALID_ATTR: 1084 ASSERT( aEvent.GetType() == SwAccessibleEvent_Impl::INVALID_ATTR, 1085 "invalid event combination" ); 1086 break; 1087 // <-- 1088 } 1089 if( bAppendEvent ) 1090 { 1091 mpEvents->erase( (*aIter).second ); 1092 (*aIter).second = mpEvents->insert( mpEvents->end(), aEvent ); 1093 } 1094 else 1095 { 1096 mpEvents->erase( (*aIter).second ); 1097 mpEventMap->erase( aIter ); 1098 } 1099 } 1100 else if( SwAccessibleEvent_Impl::DISPOSE != rEvent.GetType() ) 1101 { 1102 SwAccessibleEventMap_Impl::value_type aEntry( rEvent.GetFrmOrObj(), 1103 mpEvents->insert( mpEvents->end(), rEvent ) ); 1104 mpEventMap->insert( aEntry ); 1105 } 1106 } 1107 } 1108 1109 void SwAccessibleMap::InvalidateCursorPosition( 1110 const uno::Reference< XAccessible >& rAcc ) 1111 { 1112 SwAccessibleContext *pAccImpl = 1113 static_cast< SwAccessibleContext *>( rAcc.get() ); 1114 ASSERT( pAccImpl, "no caret context" ); 1115 ASSERT( pAccImpl->GetFrm(), "caret context is disposed" ); 1116 if( GetShell()->ActionPend() ) 1117 { 1118 SwAccessibleEvent_Impl aEvent( SwAccessibleEvent_Impl::CARET_OR_STATES, 1119 pAccImpl, 1120 SwAccessibleChild(pAccImpl->GetFrm()), 1121 ACC_STATE_CARET ); 1122 AppendEvent( aEvent ); 1123 } 1124 else 1125 { 1126 FireEvents(); 1127 // While firing events the current frame might have 1128 // been disposed because it moved out of the vis area. 1129 // Setting the cursor for such frames is useless and even 1130 // causes asserts. 1131 if( pAccImpl->GetFrm() ) 1132 pAccImpl->InvalidateCursorPos(); 1133 } 1134 } 1135 1136 void SwAccessibleMap::InvalidateShapeSelection() 1137 { 1138 if( GetShell()->ActionPend() ) 1139 { 1140 SwAccessibleEvent_Impl aEvent( 1141 SwAccessibleEvent_Impl::SHAPE_SELECTION ); 1142 AppendEvent( aEvent ); 1143 } 1144 else 1145 { 1146 FireEvents(); 1147 DoInvalidateShapeSelection(); 1148 } 1149 } 1150 //IAccessibility2 Implementation 2009----- 1151 //This method should implement the following functions: 1152 //1.find the shape objects and set the selected state. 1153 //2.find the Swframe objects and set the selected state. 1154 //3.find the paragraph objects and set the selected state. 1155 void SwAccessibleMap::InvalidateShapeInParaSelection() 1156 { 1157 SwAccessibleObjShape_Impl *pShapes = 0; 1158 SwAccessibleObjShape_Impl *pSelShape = 0; 1159 size_t nShapes = 0; 1160 1161 const ViewShell *pVSh = GetShell(); 1162 const SwFEShell *pFESh = pVSh->ISA( SwFEShell ) ? 1163 static_cast< const SwFEShell * >( pVSh ) : 0; 1164 SwPaM* pCrsr = pFESh ? pFESh->GetCrsr( sal_False /* ??? */ ) : NULL;//IAccessibility2 Implementation 2009 1165 1166 //sal_uInt16 nSelShapes = pFESh ? pFESh->IsObjSelected() : 0; 1167 1168 { 1169 vos::OGuard aGuard( maMutex ); 1170 if( mpShapeMap ) 1171 pShapes = mpShapeMap->Copy( nShapes, pFESh, &pSelShape ); 1172 } 1173 1174 sal_Bool bIsSelAll =IsDocumentSelAll(); 1175 1176 if( mpShapeMap ) 1177 { 1178 //Checked for shapes. 1179 _SwAccessibleShapeMap_Impl::const_iterator aIter = mpShapeMap->begin(); 1180 _SwAccessibleShapeMap_Impl::const_iterator aEndIter = mpShapeMap->end(); 1181 ::vos::ORef< SwAccessibleContext > xParentAccImpl; 1182 1183 if( bIsSelAll) 1184 { 1185 while( aIter != aEndIter ) 1186 { 1187 uno::Reference < XAccessible > xAcc( (*aIter).second ); 1188 if( xAcc.is() ) 1189 (static_cast < ::accessibility::AccessibleShape* >(xAcc.get()))->SetState( AccessibleStateType::SELECTED ); 1190 1191 ++aIter; 1192 } 1193 } 1194 else 1195 { 1196 while( aIter != aEndIter ) 1197 { 1198 sal_Bool bChanged = sal_False; 1199 sal_Bool bMarked = sal_False; 1200 SwAccessibleChild pFrm( (*aIter).first ); 1201 1202 const SwFrmFmt *pFrmFmt = (*aIter).first ? ::FindFrmFmt( (*aIter).first ) : 0; 1203 if( !pFrmFmt ) { ++aIter; continue; } 1204 const SwFmtAnchor& pAnchor = pFrmFmt->GetAnchor(); 1205 const SwPosition *pPos = pAnchor.GetCntntAnchor(); 1206 1207 if(pAnchor.GetAnchorId() == FLY_AT_PAGE) 1208 { 1209 uno::Reference < XAccessible > xAcc( (*aIter).second ); 1210 if(xAcc.is()) 1211 (static_cast < ::accessibility::AccessibleShape* >(xAcc.get()))->ResetState( AccessibleStateType::SELECTED ); 1212 1213 ++aIter; continue; 1214 } 1215 1216 if( !pPos ) { ++aIter; continue; } 1217 if( pPos->nNode.GetNode().GetTxtNode() ) 1218 { 1219 int pIndex = pPos->nContent.GetIndex(); 1220 SwPaM* pTmpCrsr = pCrsr; 1221 if( pTmpCrsr != NULL ) 1222 { 1223 const SwTxtNode* pNode = pPos->nNode.GetNode().GetTxtNode(); 1224 sal_uLong nHere = pNode->GetIndex(); 1225 1226 do 1227 { 1228 // ignore, if no mark 1229 if( pTmpCrsr->HasMark() ) 1230 { 1231 bMarked = sal_True; 1232 // check whether nHere is 'inside' pCrsr 1233 SwPosition* pStart = pTmpCrsr->Start(); 1234 sal_uLong nStartIndex = pStart->nNode.GetIndex(); 1235 SwPosition* pEnd = pTmpCrsr->End(); 1236 sal_uLong nEndIndex = pEnd->nNode.GetIndex(); 1237 if( ( nHere >= nStartIndex ) && (nHere <= nEndIndex) ) 1238 { 1239 if( pAnchor.GetAnchorId() == FLY_AS_CHAR ) 1240 { 1241 if( ( (nHere == nStartIndex) && (pIndex >= pStart->nContent.GetIndex()) || (nHere > nStartIndex) ) 1242 &&( (nHere == nEndIndex) && (pIndex < pEnd->nContent.GetIndex()) || (nHere < nEndIndex) ) ) 1243 { 1244 uno::Reference < XAccessible > xAcc( (*aIter).second ); 1245 if( xAcc.is() ) 1246 bChanged = (static_cast < ::accessibility::AccessibleShape* >(xAcc.get()))->SetState( AccessibleStateType::SELECTED ); 1247 } 1248 else 1249 { 1250 uno::Reference < XAccessible > xAcc( (*aIter).second ); 1251 if( xAcc.is() ) 1252 bChanged = (static_cast < ::accessibility::AccessibleShape* >(xAcc.get()))->ResetState( AccessibleStateType::SELECTED ); 1253 } 1254 } 1255 else if( pAnchor.GetAnchorId() == FLY_AT_PARA ) 1256 { 1257 if( ((nHere > nStartIndex) || pStart->nContent.GetIndex() ==0 ) 1258 && (nHere < nEndIndex ) ) 1259 { 1260 uno::Reference < XAccessible > xAcc( (*aIter).second ); 1261 if( xAcc.is() ) 1262 bChanged = (static_cast < ::accessibility::AccessibleShape* >(xAcc.get()))->SetState( AccessibleStateType::SELECTED ); 1263 } 1264 else 1265 { 1266 uno::Reference < XAccessible > xAcc( (*aIter).second ); 1267 if(xAcc.is()) 1268 bChanged = (static_cast < ::accessibility::AccessibleShape* >(xAcc.get()))->ResetState( AccessibleStateType::SELECTED ); 1269 } 1270 } 1271 } 1272 } 1273 // next PaM in ring 1274 pTmpCrsr = static_cast<SwPaM*>( pTmpCrsr->GetNext() ); 1275 } 1276 while( pTmpCrsr != pCrsr ); 1277 } 1278 if( !bMarked ) 1279 { 1280 SwAccessibleObjShape_Impl *pShape = pShapes; 1281 size_t nNumShapes = nShapes; 1282 while( nNumShapes ) 1283 { 1284 if( pShape < pSelShape && (pShape->first==(*aIter).first) ) 1285 { 1286 uno::Reference < XAccessible > xAcc( (*aIter).second ); 1287 if(xAcc.is()) 1288 bChanged = (static_cast < ::accessibility::AccessibleShape* >(xAcc.get()))->ResetState( AccessibleStateType::SELECTED ); 1289 } 1290 --nNumShapes; 1291 ++pShape; 1292 } 1293 } 1294 } 1295 ++aIter; 1296 }//while( aIter != aEndIter ) 1297 }//else 1298 } 1299 1300 //Checked for FlyFrm 1301 SwAccessibleContextMap_Impl::iterator aIter = mpFrmMap->begin(); 1302 while( aIter != mpFrmMap->end() ) 1303 { 1304 const SwFrm *pFrm = (*aIter).first; 1305 if(pFrm->IsFlyFrm()) 1306 { 1307 sal_Bool bFrmChanged = sal_False; 1308 uno::Reference < XAccessible > xAcc = (*aIter).second; 1309 1310 if(xAcc.is()) 1311 { 1312 SwAccessibleFrameBase *pAccFrame = (static_cast< SwAccessibleFrameBase * >(xAcc.get())); 1313 bFrmChanged = pAccFrame->SetSelectedState( sal_True ); 1314 if (bFrmChanged) 1315 { 1316 const SwFlyFrm *pFlyFrm = static_cast< const SwFlyFrm * >( pFrm ); 1317 const SwFrmFmt *pFrmFmt = pFlyFrm->GetFmt(); 1318 if (pFrmFmt) 1319 { 1320 const SwFmtAnchor& pAnchor = pFrmFmt->GetAnchor(); 1321 if( pAnchor.GetAnchorId() == FLY_AS_CHAR ) 1322 { 1323 uno::Reference< XAccessible > xAccParent = pAccFrame->getAccessibleParent(); 1324 if (xAccParent.is()) 1325 { 1326 uno::Reference< XAccessibleContext > xAccContext = xAccParent->getAccessibleContext(); 1327 if(xAccContext.is() && xAccContext->getAccessibleRole() == AccessibleRole::PARAGRAPH) 1328 { 1329 SwAccessibleParagraph* pAccPara = static_cast< SwAccessibleParagraph *>(xAccContext.get()); 1330 if(pAccFrame->IsSeletedInDoc()) 1331 { 1332 m_setParaAdd.insert(pAccPara); 1333 } 1334 else if(m_setParaAdd.count(pAccPara) == 0) 1335 { 1336 m_setParaRemove.insert(pAccPara); 1337 } 1338 } 1339 } 1340 } 1341 } 1342 } 1343 } 1344 } 1345 ++aIter; 1346 } 1347 typedef std::vector< SwAccessibleContext* > VEC_PARA; 1348 VEC_PARA vecAdd; 1349 VEC_PARA vecRemove; 1350 //Checked for Paras. 1351 SwPaM* pTmpCrsr = pCrsr; 1352 sal_Bool bMarkChanged = sal_False; 1353 SwAccessibleContextMap_Impl mapTemp; 1354 if( pTmpCrsr != NULL ) 1355 { 1356 do 1357 { 1358 if( pTmpCrsr->HasMark() ) 1359 { 1360 SwNodeIndex nStartIndex( pTmpCrsr->Start()->nNode ); 1361 SwNodeIndex nEndIndex( pTmpCrsr->End()->nNode ); 1362 while(nStartIndex <= nEndIndex) 1363 { 1364 SwFrm *pFrm = NULL; 1365 if(nStartIndex.GetNode().IsCntntNode()) 1366 { 1367 SwCntntNode* pCNd = (SwCntntNode*)&(nStartIndex.GetNode()); 1368 SwClientIter aClientIter( *pCNd ); 1369 pFrm = (SwFrm*)aClientIter.First( TYPE(SwFrm)); 1370 } 1371 else if( nStartIndex.GetNode().IsTableNode() ) 1372 { 1373 SwTableNode * pTable= (SwTableNode *)&(nStartIndex.GetNode()); 1374 SwFrmFmt* pFmt = const_cast<SwFrmFmt*>(pTable->GetTable().GetFrmFmt()); 1375 SwClientIter aClientIter( *pFmt ); 1376 pFrm = (SwFrm*)aClientIter.First( TYPE(SwFrm)); 1377 } 1378 1379 if( pFrm && mpFrmMap) 1380 { 1381 aIter = mpFrmMap->find( pFrm ); 1382 if( aIter != mpFrmMap->end() ) 1383 { 1384 uno::Reference < XAccessible > xAcc = (*aIter).second; 1385 sal_Bool isChanged = sal_False; 1386 if( xAcc.is() ) 1387 { 1388 isChanged = (static_cast< SwAccessibleContext * >(xAcc.get()))->SetSelectedState( sal_True ); 1389 } 1390 if(!isChanged) 1391 { 1392 SwAccessibleContextMap_Impl::iterator aEraseIter = mpSeletedFrmMap->find( pFrm ); 1393 if(aEraseIter != mpSeletedFrmMap->end()) 1394 mpSeletedFrmMap->erase(aEraseIter); 1395 } 1396 else 1397 { 1398 bMarkChanged = sal_True; 1399 vecAdd.push_back(static_cast< SwAccessibleContext * >(xAcc.get())); 1400 } 1401 1402 mapTemp.insert( SwAccessibleContextMap_Impl::value_type( pFrm, xAcc ) ); 1403 } 1404 } 1405 nStartIndex++; 1406 } 1407 } 1408 pTmpCrsr = static_cast<SwPaM*>( pTmpCrsr->GetNext() ); 1409 } 1410 while( pTmpCrsr != pCrsr ); 1411 } 1412 if( !mpSeletedFrmMap ) 1413 mpSeletedFrmMap = new SwAccessibleContextMap_Impl; 1414 if( !mpSeletedFrmMap->empty() ) 1415 { 1416 aIter = mpSeletedFrmMap->begin(); 1417 while( aIter != mpSeletedFrmMap->end() ) 1418 { 1419 uno::Reference < XAccessible > xAcc = (*aIter).second; 1420 if(xAcc.is()) 1421 (static_cast< SwAccessibleContext * >(xAcc.get()))->SetSelectedState( sal_False ); 1422 ++aIter; 1423 vecRemove.push_back(static_cast< SwAccessibleContext * >(xAcc.get())); 1424 } 1425 bMarkChanged = sal_True; 1426 mpSeletedFrmMap->clear(); 1427 } 1428 1429 if( !mapTemp.empty() ) 1430 { 1431 aIter = mapTemp.begin(); 1432 while( aIter != mapTemp.end() ) 1433 { 1434 mpSeletedFrmMap->insert( SwAccessibleContextMap_Impl::value_type( (*aIter).first, (*aIter).second ) ); 1435 ++aIter; 1436 } 1437 mapTemp.clear(); 1438 } 1439 if( bMarkChanged && mpFrmMap) 1440 { 1441 VEC_PARA::iterator vi = vecAdd.begin(); 1442 for (; vi != vecAdd.end() ; ++vi) 1443 { 1444 AccessibleEventObject aEvent; 1445 aEvent.EventId = AccessibleEventId::SELECTION_CHANGED; 1446 SwAccessibleContext* pAccPara = *vi; 1447 if (pAccPara) 1448 { 1449 pAccPara->FireAccessibleEvent( aEvent ); 1450 } 1451 } 1452 vi = vecRemove.begin(); 1453 for (; vi != vecRemove.end() ; ++vi) 1454 { 1455 AccessibleEventObject aEvent; 1456 aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_REMOVE; 1457 SwAccessibleContext* pAccPara = *vi; 1458 if (pAccPara) 1459 { 1460 pAccPara->FireAccessibleEvent( aEvent ); 1461 } 1462 } 1463 } 1464 } 1465 1466 //Marge with DoInvalidateShapeFocus 1467 void SwAccessibleMap::DoInvalidateShapeSelection(sal_Bool bInvalidateFocusMode /*=sal_False*/) 1468 { 1469 SwAccessibleObjShape_Impl *pShapes = 0; 1470 SwAccessibleObjShape_Impl *pSelShape = 0; 1471 size_t nShapes = 0; 1472 1473 const ViewShell *pVSh = GetShell(); 1474 const SwFEShell *pFESh = pVSh->ISA( SwFEShell ) ? 1475 static_cast< const SwFEShell * >( pVSh ) : 0; 1476 sal_uInt16 nSelShapes = pFESh ? pFESh->IsObjSelected() : 0; 1477 1478 1479 //when InvalidateFocus Call this function ,and the current selected shape count is not 1 , 1480 //return 1481 if (bInvalidateFocusMode && nSelShapes != 1) 1482 { 1483 return; 1484 } 1485 { 1486 vos::OGuard aGuard( maMutex ); 1487 if( mpShapeMap ) 1488 pShapes = mpShapeMap->Copy( nShapes, pFESh, &pSelShape ); 1489 } 1490 1491 if( pShapes ) 1492 { 1493 typedef std::vector< ::vos::ORef < ::accessibility::AccessibleShape > > VEC_SHAPE; 1494 VEC_SHAPE vecxShapeAdd; 1495 VEC_SHAPE vecxShapeRemove; 1496 int nCountSelectedShape=0; 1497 1498 Window *pWin = GetShell()->GetWin(); 1499 sal_Bool bFocused = pWin && pWin->HasFocus(); 1500 SwAccessibleObjShape_Impl *pShape = pShapes; 1501 int nShapeCount = nShapes; 1502 while( nShapeCount ) 1503 { 1504 //if( pShape->second.isValid() ) 1505 if (pShape->second.isValid() && IsInSameLevel(pShape->first, pFESh)) 1506 { 1507 if( pShape < pSelShape ) 1508 { 1509 if(pShape->second->ResetState( AccessibleStateType::SELECTED )) 1510 { 1511 vecxShapeRemove.push_back(pShape->second); 1512 } 1513 pShape->second->ResetState( AccessibleStateType::FOCUSED ); 1514 } 1515 } 1516 --nShapeCount; 1517 ++pShape; 1518 } 1519 1520 VEC_SHAPE::iterator vi =vecxShapeRemove.begin(); 1521 for (; vi != vecxShapeRemove.end(); ++vi) 1522 { 1523 ::accessibility::AccessibleShape *pAccShape = static_cast< ::accessibility::AccessibleShape * >(vi->getBodyPtr()); 1524 if (pAccShape) 1525 { 1526 pAccShape->CommitChange(AccessibleEventId::SELECTION_CHANGED_REMOVE, uno::Any(), uno::Any()); 1527 } 1528 } 1529 1530 pShape = pShapes; 1531 while( nShapes ) 1532 { 1533 //if( pShape->second.isValid() ) 1534 if (pShape->second.isValid() && IsInSameLevel(pShape->first, pFESh)) 1535 { 1536 // IA2 - why? 1537 // sal_Bool bChanged; 1538 if( pShape >= pSelShape ) 1539 { 1540 // IA2: first fire focus event 1541 // bChanged = pShape->second->SetState( AccessibleStateType::SELECTED ); 1542 1543 //first fire focus event 1544 if( bFocused && 1 == nSelShapes ) 1545 pShape->second->SetState( AccessibleStateType::FOCUSED ); 1546 else 1547 pShape->second->ResetState( AccessibleStateType::FOCUSED ); 1548 1549 // IA2 CWS: 1550 if(pShape->second->SetState( AccessibleStateType::SELECTED )) 1551 { 1552 vecxShapeAdd.push_back(pShape->second); 1553 } 1554 ++nCountSelectedShape; 1555 } 1556 /* MT: This still was in DEV300m80, but was removed in IA2 CWS. 1557 Someone needs to check what should happen here, see original diff CWS oo31ia2 vs. OOO310M11 1558 else 1559 { 1560 bChanged = 1561 pShape->second->ResetState( AccessibleStateType::SELECTED ); 1562 pShape->second->ResetState( AccessibleStateType::FOCUSED ); 1563 } 1564 if( bChanged ) 1565 { 1566 const SwFrm* pParent = SwAccessibleFrame::GetParent( 1567 SwAccessibleChild( pShape->first ), 1568 GetShell()->IsPreView() ); 1569 aParents.push_back( pParent ); 1570 } 1571 */ 1572 } 1573 1574 --nShapes; 1575 ++pShape; 1576 } 1577 1578 const unsigned int SELECTION_WITH_NUM = 10; 1579 if (vecxShapeAdd.size() > SELECTION_WITH_NUM ) 1580 { 1581 uno::Reference< XAccessible > xDoc = GetDocumentView( ); 1582 SwAccessibleContext * pCont = static_cast<SwAccessibleContext *>(xDoc.get()); 1583 if (pCont) 1584 { 1585 AccessibleEventObject aEvent; 1586 aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_WITHIN; 1587 pCont->FireAccessibleEvent(aEvent); 1588 } 1589 } 1590 else 1591 { 1592 short nEventID = AccessibleEventId::SELECTION_CHANGED_ADD; 1593 if (nCountSelectedShape <= 1 && vecxShapeAdd.size() == 1 ) 1594 { 1595 nEventID = AccessibleEventId::SELECTION_CHANGED; 1596 } 1597 vi = vecxShapeAdd.begin(); 1598 for (; vi != vecxShapeAdd.end(); ++vi) 1599 { 1600 ::accessibility::AccessibleShape *pAccShape = static_cast< ::accessibility::AccessibleShape * >(vi->getBodyPtr()); 1601 if (pAccShape) 1602 { 1603 pAccShape->CommitChange(nEventID, uno::Any(), uno::Any()); 1604 } 1605 } 1606 } 1607 1608 vi = vecxShapeAdd.begin(); 1609 for (; vi != vecxShapeAdd.end(); ++vi) 1610 { 1611 ::accessibility::AccessibleShape *pAccShape = static_cast< ::accessibility::AccessibleShape * >(vi->getBodyPtr()); 1612 if (pAccShape) 1613 { 1614 SdrObject *pObj = GetSdrObjectFromXShape(pAccShape->GetXShape()); 1615 SwFrmFmt *pFrmFmt = pObj ? FindFrmFmt( pObj ) : NULL; 1616 if (pFrmFmt) 1617 { 1618 const SwFmtAnchor& pAnchor = pFrmFmt->GetAnchor(); 1619 if( pAnchor.GetAnchorId() == FLY_AS_CHAR ) 1620 { 1621 uno::Reference< XAccessible > xPara = pAccShape->getAccessibleParent(); 1622 if (xPara.is()) 1623 { 1624 uno::Reference< XAccessibleContext > xParaContext = xPara->getAccessibleContext(); 1625 if (xParaContext.is() && xParaContext->getAccessibleRole() == AccessibleRole::PARAGRAPH) 1626 { 1627 SwAccessibleParagraph* pAccPara = static_cast< SwAccessibleParagraph *>(xPara.get()); 1628 if (pAccPara) 1629 { 1630 m_setParaAdd.insert(pAccPara); 1631 } 1632 } 1633 } 1634 } 1635 } 1636 } 1637 } 1638 vi = vecxShapeRemove.begin(); 1639 for (; vi != vecxShapeRemove.end(); ++vi) 1640 { 1641 ::accessibility::AccessibleShape *pAccShape = static_cast< ::accessibility::AccessibleShape * >(vi->getBodyPtr()); 1642 if (pAccShape) 1643 { 1644 uno::Reference< XAccessible > xPara = pAccShape->getAccessibleParent(); 1645 uno::Reference< XAccessibleContext > xParaContext = xPara->getAccessibleContext(); 1646 if (xParaContext.is() && xParaContext->getAccessibleRole() == AccessibleRole::PARAGRAPH) 1647 { 1648 SwAccessibleParagraph* pAccPara = static_cast< SwAccessibleParagraph *>(xPara.get()); 1649 if (m_setParaAdd.count(pAccPara) == 0 ) 1650 { 1651 m_setParaRemove.insert(pAccPara); 1652 } 1653 } 1654 } 1655 } 1656 delete[] pShapes; 1657 } 1658 } 1659 1660 //Marge with DoInvalidateShapeSelection 1661 /* 1662 void SwAccessibleMap::DoInvalidateShapeFocus() 1663 { 1664 const ViewShell *pVSh = GetShell(); 1665 const SwFEShell *pFESh = pVSh->ISA( SwFEShell ) ? 1666 static_cast< const SwFEShell * >( pVSh ) : 0; 1667 sal_uInt16 nSelShapes = pFESh ? pFESh->IsObjSelected() : 0; 1668 1669 if( nSelShapes != 1 ) 1670 return; 1671 1672 SwAccessibleObjShape_Impl *pShapes = 0; 1673 SwAccessibleObjShape_Impl *pSelShape = 0; 1674 size_t nShapes = 0; 1675 1676 1677 { 1678 vos::OGuard aGuard( maMutex ); 1679 if( mpShapeMap ) 1680 pShapes = mpShapeMap->Copy( nShapes, pFESh, &pSelShape ); 1681 } 1682 1683 if( pShapes ) 1684 { 1685 Window *pWin = GetShell()->GetWin(); 1686 sal_Bool bFocused = pWin && pWin->HasFocus(); 1687 SwAccessibleObjShape_Impl *pShape = pShapes; 1688 while( nShapes ) 1689 { 1690 if( pShape->second.isValid() ) 1691 { 1692 if( bFocused && pShape >= pSelShape ) 1693 pShape->second->SetState( AccessibleStateType::FOCUSED ); 1694 else 1695 pShape->second->ResetState( AccessibleStateType::FOCUSED ); 1696 } 1697 1698 --nShapes; 1699 ++pShape; 1700 } 1701 1702 delete[] pShapes; 1703 } 1704 } 1705 */ 1706 //-----IAccessibility2 Implementation 2009 1707 1708 SwAccessibleMap::SwAccessibleMap( ViewShell *pSh ) : 1709 mpFrmMap( 0 ), 1710 mpShapeMap( 0 ), 1711 mpShapes( 0 ), 1712 mpEvents( 0 ), 1713 mpEventMap( 0 ), 1714 // --> OD 2005-12-13 #i27301# 1715 mpSelectedParas( 0 ), 1716 // <-- 1717 mpVSh( pSh ), 1718 mpPreview( 0 ), 1719 mnPara( 1 ), 1720 mnFootnote( 1 ), 1721 mnEndnote( 1 ), 1722 mbShapeSelected( sal_False ), 1723 mpSeletedFrmMap(NULL)//IAccessibility2 Implementation 2009 1724 { 1725 pSh->GetLayout()->AddAccessibleShell(); 1726 } 1727 1728 SwAccessibleMap::~SwAccessibleMap() 1729 { 1730 uno::Reference < XAccessible > xAcc; 1731 { 1732 vos::OGuard aGuard( maMutex ); 1733 if( mpFrmMap ) 1734 { 1735 const SwRootFrm *pRootFrm = GetShell()->GetLayout(); 1736 SwAccessibleContextMap_Impl::iterator aIter = mpFrmMap->find( pRootFrm ); 1737 if( aIter != mpFrmMap->end() ) 1738 xAcc = (*aIter).second; 1739 if( !xAcc.is() ) 1740 xAcc = new SwAccessibleDocument( this ); 1741 } 1742 } 1743 1744 //IAccessibility2 Implementation 2009----- 1745 if(xAcc.is()) 1746 { 1747 SwAccessibleDocument *pAcc = 1748 static_cast< SwAccessibleDocument * >( xAcc.get() ); 1749 pAcc->Dispose( sal_True ); 1750 } 1751 if( mpFrmMap ) 1752 { 1753 SwAccessibleContextMap_Impl::iterator aIter = mpFrmMap->begin(); 1754 while( aIter != mpFrmMap->end() ) 1755 { 1756 uno::Reference < XAccessible > xTmp = (*aIter).second; 1757 if( xTmp.is() ) 1758 { 1759 SwAccessibleContext *pTmp = static_cast< SwAccessibleContext * >( xTmp.get() ); 1760 pTmp->SetMap(NULL); 1761 } 1762 ++aIter; 1763 } 1764 } 1765 //-----IAccessibility2 Implementation 2009 1766 { 1767 vos::OGuard aGuard( maMutex ); 1768 #ifdef DBG_UTIL 1769 ASSERT( !mpFrmMap || mpFrmMap->empty(), 1770 "Frame map should be empty after disposing the root frame" ); 1771 if( mpFrmMap ) 1772 { 1773 SwAccessibleContextMap_Impl::iterator aIter = mpFrmMap->begin(); 1774 while( aIter != mpFrmMap->end() ) 1775 { 1776 uno::Reference < XAccessible > xTmp = (*aIter).second; 1777 if( xTmp.is() ) 1778 { 1779 SwAccessibleContext *pTmp = 1780 static_cast< SwAccessibleContext * >( xTmp.get() ); 1781 (void) pTmp; 1782 } 1783 ++aIter; 1784 } 1785 } 1786 ASSERT( !mpShapeMap || mpShapeMap->empty(), 1787 "Object map should be empty after disposing the root frame" ); 1788 if( mpShapeMap ) 1789 { 1790 SwAccessibleShapeMap_Impl::iterator aIter = mpShapeMap->begin(); 1791 while( aIter != mpShapeMap->end() ) 1792 { 1793 uno::Reference < XAccessible > xTmp = (*aIter).second; 1794 if( xTmp.is() ) 1795 { 1796 ::accessibility::AccessibleShape *pTmp = 1797 static_cast< ::accessibility::AccessibleShape* >( xTmp.get() ); 1798 (void) pTmp; 1799 } 1800 ++aIter; 1801 } 1802 } 1803 #endif 1804 delete mpFrmMap; 1805 mpFrmMap = 0; 1806 delete mpShapeMap; 1807 mpShapeMap = 0; 1808 delete mpShapes; 1809 mpShapes = 0; 1810 // --> OD 2005-12-13 #i27301# 1811 delete mpSelectedParas; 1812 mpSelectedParas = 0; 1813 // <-- 1814 } 1815 1816 delete mpPreview; 1817 mpPreview = NULL; 1818 1819 { 1820 vos::OGuard aGuard( maEventMutex ); 1821 #ifdef DBG_UTIL 1822 ASSERT( !(mpEvents || mpEventMap), "pending events" ); 1823 if( mpEvents ) 1824 { 1825 SwAccessibleEventList_Impl::iterator aIter = mpEvents->begin(); 1826 while( aIter != mpEvents->end() ) 1827 { 1828 ++aIter; 1829 } 1830 } 1831 if( mpEventMap ) 1832 { 1833 SwAccessibleEventMap_Impl::iterator aIter = mpEventMap->begin(); 1834 while( aIter != mpEventMap->end() ) 1835 { 1836 ++aIter; 1837 } 1838 } 1839 #endif 1840 delete mpEventMap; 1841 mpEventMap = 0; 1842 delete mpEvents; 1843 mpEvents = 0; 1844 } 1845 mpVSh->GetLayout()->RemoveAccessibleShell(); 1846 delete mpSeletedFrmMap;//IAccessibility2 Implementation 2009 1847 } 1848 1849 uno::Reference< XAccessible > SwAccessibleMap::_GetDocumentView( 1850 sal_Bool bPagePreview ) 1851 { 1852 uno::Reference < XAccessible > xAcc; 1853 sal_Bool bSetVisArea = sal_False; 1854 1855 { 1856 vos::OGuard aGuard( maMutex ); 1857 1858 if( !mpFrmMap ) 1859 { 1860 mpFrmMap = new SwAccessibleContextMap_Impl; 1861 #ifdef DBG_UTIL 1862 mpFrmMap->mbLocked = sal_False; 1863 #endif 1864 } 1865 1866 #ifdef DBG_UTIL 1867 ASSERT( !mpFrmMap->mbLocked, "Map is locked" ); 1868 mpFrmMap->mbLocked = sal_True; 1869 #endif 1870 1871 const SwRootFrm *pRootFrm = GetShell()->GetLayout(); 1872 SwAccessibleContextMap_Impl::iterator aIter = mpFrmMap->find( pRootFrm ); 1873 if( aIter != mpFrmMap->end() ) 1874 xAcc = (*aIter).second; 1875 if( xAcc.is() ) 1876 { 1877 bSetVisArea = sal_True; // Set VisArea when map mutex is not 1878 // locked 1879 } 1880 else 1881 { 1882 if( bPagePreview ) 1883 xAcc = new SwAccessiblePreview( this ); 1884 else 1885 xAcc = new SwAccessibleDocument( this ); 1886 1887 if( aIter != mpFrmMap->end() ) 1888 { 1889 (*aIter).second = xAcc; 1890 } 1891 else 1892 { 1893 SwAccessibleContextMap_Impl::value_type aEntry( pRootFrm, xAcc ); 1894 mpFrmMap->insert( aEntry ); 1895 } 1896 } 1897 1898 #ifdef DBG_UTIL 1899 mpFrmMap->mbLocked = sal_False; 1900 #endif 1901 } 1902 1903 if( bSetVisArea ) 1904 { 1905 SwAccessibleDocumentBase *pAcc = 1906 static_cast< SwAccessibleDocumentBase * >( xAcc.get() ); 1907 pAcc->SetVisArea(); 1908 } 1909 1910 return xAcc; 1911 } 1912 1913 uno::Reference< XAccessible > SwAccessibleMap::GetDocumentView( ) 1914 { 1915 return _GetDocumentView( sal_False ); 1916 } 1917 1918 // OD 14.01.2003 #103492# - complete re-factoring of method due to new page/print 1919 // preview functionality. 1920 uno::Reference<XAccessible> SwAccessibleMap::GetDocumentPreview( 1921 const std::vector<PrevwPage*>& _rPrevwPages, 1922 const Fraction& _rScale, 1923 const SwPageFrm* _pSelectedPageFrm, 1924 const Size& _rPrevwWinSize ) 1925 { 1926 // create & update preview data object 1927 if( mpPreview == NULL ) 1928 mpPreview = new SwAccPreviewData(); 1929 mpPreview->Update( *this, _rPrevwPages, _rScale, _pSelectedPageFrm, _rPrevwWinSize ); 1930 1931 uno::Reference<XAccessible> xAcc = _GetDocumentView( sal_True ); 1932 return xAcc; 1933 } 1934 1935 uno::Reference< XAccessible> SwAccessibleMap::GetContext( const SwFrm *pFrm, 1936 sal_Bool bCreate ) 1937 { 1938 uno::Reference < XAccessible > xAcc; 1939 uno::Reference < XAccessible > xOldCursorAcc; 1940 sal_Bool bOldShapeSelected = sal_False; 1941 1942 { 1943 vos::OGuard aGuard( maMutex ); 1944 1945 if( !mpFrmMap && bCreate ) 1946 mpFrmMap = new SwAccessibleContextMap_Impl; 1947 if( mpFrmMap ) 1948 { 1949 SwAccessibleContextMap_Impl::iterator aIter = mpFrmMap->find( pFrm ); 1950 if( aIter != mpFrmMap->end() ) 1951 xAcc = (*aIter).second; 1952 1953 if( !xAcc.is() && bCreate ) 1954 { 1955 SwAccessibleContext *pAcc = 0; 1956 switch( pFrm->GetType() ) 1957 { 1958 case FRM_TXT: 1959 mnPara++; 1960 pAcc = new SwAccessibleParagraph( *this, 1961 static_cast< const SwTxtFrm& >( *pFrm ) ); 1962 break; 1963 case FRM_HEADER: 1964 pAcc = new SwAccessibleHeaderFooter( this, 1965 static_cast< const SwHeaderFrm *>( pFrm ) ); 1966 break; 1967 case FRM_FOOTER: 1968 pAcc = new SwAccessibleHeaderFooter( this, 1969 static_cast< const SwFooterFrm *>( pFrm ) ); 1970 break; 1971 case FRM_FTN: 1972 { 1973 const SwFtnFrm *pFtnFrm = 1974 static_cast < const SwFtnFrm * >( pFrm ); 1975 sal_Bool bIsEndnote = 1976 SwAccessibleFootnote::IsEndnote( pFtnFrm ); 1977 pAcc = new SwAccessibleFootnote( this, bIsEndnote, 1978 /*(bIsEndnote ? mnEndnote++ : mnFootnote++),*/ 1979 pFtnFrm ); 1980 } 1981 break; 1982 case FRM_FLY: 1983 { 1984 const SwFlyFrm *pFlyFrm = 1985 static_cast < const SwFlyFrm * >( pFrm ); 1986 switch( SwAccessibleFrameBase::GetNodeType( pFlyFrm ) ) 1987 { 1988 case ND_GRFNODE: 1989 pAcc = new SwAccessibleGraphic( this, pFlyFrm ); 1990 break; 1991 case ND_OLENODE: 1992 pAcc = new SwAccessibleEmbeddedObject( this, pFlyFrm ); 1993 break; 1994 default: 1995 pAcc = new SwAccessibleTextFrame( this, pFlyFrm ); 1996 break; 1997 } 1998 } 1999 break; 2000 case FRM_CELL: 2001 pAcc = new SwAccessibleCell( this, 2002 static_cast< const SwCellFrm *>( pFrm ) ); 2003 break; 2004 case FRM_TAB: 2005 pAcc = new SwAccessibleTable( this, 2006 static_cast< const SwTabFrm *>( pFrm ) ); 2007 break; 2008 case FRM_PAGE: 2009 DBG_ASSERT( GetShell()->IsPreView(), 2010 "accessible page frames only in PagePreview" ); 2011 pAcc = new SwAccessiblePage( this, pFrm ); 2012 break; 2013 } 2014 xAcc = pAcc; 2015 2016 ASSERT( xAcc.is(), "unknown frame type" ); 2017 if( xAcc.is() ) 2018 { 2019 if( aIter != mpFrmMap->end() ) 2020 { 2021 (*aIter).second = xAcc; 2022 } 2023 else 2024 { 2025 SwAccessibleContextMap_Impl::value_type aEntry( pFrm, xAcc ); 2026 mpFrmMap->insert( aEntry ); 2027 } 2028 2029 if( pAcc->HasCursor() && 2030 !AreInSameTable( mxCursorContext, pFrm ) ) 2031 { 2032 // If the new context has the focus, and if we know 2033 // another context that had the focus, then the focus 2034 // just moves from the old context to the new one. We 2035 // have to send a focus event and a caret event for 2036 // the old context then. We have to to that know, 2037 // because after we have left this method, anyone might 2038 // call getStates for the new context and will get a 2039 // focused state then. Sending the focus changes event 2040 // after that seems to be strange. However, we cannot 2041 // send a focus event fo the new context now, because 2042 // noone except us knows it. In any case, we remeber 2043 // the new context as the one that has the focus 2044 // currently. 2045 2046 xOldCursorAcc = mxCursorContext; 2047 mxCursorContext = xAcc; 2048 2049 bOldShapeSelected = mbShapeSelected; 2050 mbShapeSelected = sal_False; 2051 } 2052 } 2053 } 2054 } 2055 } 2056 2057 // Invalidate focus for old object when map is not locked 2058 if( xOldCursorAcc.is() ) 2059 InvalidateCursorPosition( xOldCursorAcc ); 2060 if( bOldShapeSelected ) 2061 InvalidateShapeSelection(); 2062 2063 return xAcc; 2064 } 2065 2066 ::vos::ORef < SwAccessibleContext > SwAccessibleMap::GetContextImpl( 2067 const SwFrm *pFrm, 2068 sal_Bool bCreate ) 2069 { 2070 uno::Reference < XAccessible > xAcc( GetContext( pFrm, bCreate ) ); 2071 2072 ::vos::ORef < SwAccessibleContext > xAccImpl( 2073 static_cast< SwAccessibleContext * >( xAcc.get() ) ); 2074 2075 return xAccImpl; 2076 } 2077 2078 uno::Reference< XAccessible> SwAccessibleMap::GetContext( 2079 const SdrObject *pObj, 2080 SwAccessibleContext *pParentImpl, 2081 sal_Bool bCreate ) 2082 { 2083 uno::Reference < XAccessible > xAcc; 2084 uno::Reference < XAccessible > xOldCursorAcc; 2085 2086 { 2087 vos::OGuard aGuard( maMutex ); 2088 2089 if( !mpShapeMap && bCreate ) 2090 mpShapeMap = new SwAccessibleShapeMap_Impl( this ); 2091 if( mpShapeMap ) 2092 { 2093 SwAccessibleShapeMap_Impl::iterator aIter = 2094 mpShapeMap->find( pObj ); 2095 if( aIter != mpShapeMap->end() ) 2096 xAcc = (*aIter).second; 2097 2098 if( !xAcc.is() && bCreate ) 2099 { 2100 ::accessibility::AccessibleShape *pAcc = 0; 2101 uno::Reference < drawing::XShape > xShape( 2102 const_cast< SdrObject * >( pObj )->getUnoShape(), 2103 uno::UNO_QUERY ); 2104 if( xShape.is() ) 2105 { 2106 ::accessibility::ShapeTypeHandler& rShapeTypeHandler = 2107 ::accessibility::ShapeTypeHandler::Instance(); 2108 uno::Reference < XAccessible > xParent( pParentImpl ); 2109 ::accessibility::AccessibleShapeInfo aShapeInfo( 2110 xShape, xParent, this ); 2111 2112 pAcc = rShapeTypeHandler.CreateAccessibleObject( 2113 aShapeInfo, mpShapeMap->GetInfo() ); 2114 } 2115 xAcc = pAcc; 2116 2117 ASSERT( xAcc.is(), "unknown shape type" ); 2118 if( xAcc.is() ) 2119 { 2120 pAcc->Init(); 2121 if( aIter != mpShapeMap->end() ) 2122 { 2123 (*aIter).second = xAcc; 2124 } 2125 else 2126 { 2127 SwAccessibleShapeMap_Impl::value_type aEntry( pObj, 2128 xAcc ); 2129 mpShapeMap->insert( aEntry ); 2130 } 2131 // TODO: focus!!! 2132 } 2133 //IAccessibility2 Implementation 2009----- 2134 if (xAcc.is()) 2135 AddGroupContext(pObj, xAcc); 2136 //-----IAccessibility2 Implementation 2009 2137 } 2138 } 2139 } 2140 2141 // Invalidate focus for old object when map is not locked 2142 if( xOldCursorAcc.is() ) 2143 InvalidateCursorPosition( xOldCursorAcc ); 2144 2145 return xAcc; 2146 } 2147 //IAccessibility2 Implementation 2009----- 2148 sal_Bool SwAccessibleMap::IsInSameLevel(const SdrObject* pObj, const SwFEShell* pFESh) 2149 { 2150 if (pFESh) 2151 return pFESh->IsObjSameLevelWithMarked(pObj); 2152 return sal_False; 2153 } 2154 void SwAccessibleMap::AddShapeContext(const SdrObject *pObj, uno::Reference < XAccessible > xAccShape) 2155 { 2156 vos::OGuard aGuard( maMutex ); 2157 2158 if( mpShapeMap ) 2159 { 2160 SwAccessibleShapeMap_Impl::value_type aEntry( pObj, xAccShape ); 2161 mpShapeMap->insert( aEntry ); 2162 } 2163 2164 } 2165 2166 //Added by yanjun for sym2_6407 2167 void SwAccessibleMap::RemoveGroupContext(const SdrObject *pParentObj, ::com::sun::star::uno::Reference < ::com::sun::star::accessibility::XAccessible > xAccParent) 2168 { 2169 vos::OGuard aGuard( maMutex ); 2170 if (mpShapeMap && pParentObj && pParentObj->IsGroupObject() && xAccParent.is()) 2171 { 2172 uno::Reference < XAccessibleContext > xContext = xAccParent->getAccessibleContext(); 2173 if (xContext.is()) 2174 { 2175 for (sal_Int32 i = 0; i < xContext->getAccessibleChildCount(); ++i) 2176 { 2177 uno::Reference < XAccessible > xChild = xContext->getAccessibleChild(i); 2178 if (xChild.is()) 2179 { 2180 uno::Reference < XAccessibleContext > xChildContext = xChild->getAccessibleContext(); 2181 if (xChildContext.is()) 2182 { 2183 if (xChildContext->getAccessibleRole() == AccessibleRole::SHAPE) 2184 { 2185 ::accessibility::AccessibleShape* pAccShape = static_cast < ::accessibility::AccessibleShape* >( xChild.get()); 2186 uno::Reference < drawing::XShape > xShape = pAccShape->GetXShape(); 2187 if (xShape.is()) 2188 { 2189 SdrObject* pObj = GetSdrObjectFromXShape(xShape); 2190 if (pObj) 2191 RemoveContext(pObj); 2192 } 2193 } 2194 } 2195 } 2196 } 2197 } 2198 } 2199 } 2200 //End 2201 2202 2203 void SwAccessibleMap::AddGroupContext(const SdrObject *pParentObj, uno::Reference < XAccessible > xAccParent) 2204 { 2205 vos::OGuard aGuard( maMutex ); 2206 if( mpShapeMap ) 2207 { 2208 //here get all the sub list. 2209 if (pParentObj->IsGroupObject()) 2210 { 2211 if (xAccParent.is()) 2212 { 2213 uno::Reference < XAccessibleContext > xContext = xAccParent->getAccessibleContext(); 2214 if (xContext.is()) 2215 { 2216 sal_Int32 nChildren = xContext->getAccessibleChildCount(); 2217 for(sal_Int32 i = 0; i<nChildren; i++) 2218 { 2219 uno::Reference < XAccessible > xChild = xContext->getAccessibleChild(i); 2220 if (xChild.is()) 2221 { 2222 uno::Reference < XAccessibleContext > xChildContext = xChild->getAccessibleContext(); 2223 if (xChildContext.is()) 2224 { 2225 short nRole = xChildContext->getAccessibleRole(); 2226 if (nRole == AccessibleRole::SHAPE) 2227 { 2228 ::accessibility::AccessibleShape* pAccShape = static_cast < ::accessibility::AccessibleShape* >( xChild.get()); 2229 uno::Reference < drawing::XShape > xShape = pAccShape->GetXShape(); 2230 if (xShape.is()) 2231 { 2232 SdrObject* pObj = GetSdrObjectFromXShape(xShape); 2233 AddShapeContext(pObj, xChild); 2234 AddGroupContext(pObj,xChild); 2235 } 2236 } 2237 } 2238 } 2239 } 2240 } 2241 } 2242 } 2243 } 2244 } 2245 //-----IAccessibility2 Implementation 2009 2246 2247 ::vos::ORef < ::accessibility::AccessibleShape > SwAccessibleMap::GetContextImpl( 2248 const SdrObject *pObj, 2249 SwAccessibleContext *pParentImpl, 2250 sal_Bool bCreate ) 2251 { 2252 uno::Reference < XAccessible > xAcc( GetContext( pObj, pParentImpl, bCreate ) ); 2253 2254 ::vos::ORef < ::accessibility::AccessibleShape > xAccImpl( 2255 static_cast< ::accessibility::AccessibleShape* >( xAcc.get() ) ); 2256 2257 return xAccImpl; 2258 } 2259 2260 2261 void SwAccessibleMap::RemoveContext( const SwFrm *pFrm ) 2262 { 2263 vos::OGuard aGuard( maMutex ); 2264 2265 if( mpFrmMap ) 2266 { 2267 SwAccessibleContextMap_Impl::iterator aIter = 2268 mpFrmMap->find( pFrm ); 2269 if( aIter != mpFrmMap->end() ) 2270 { 2271 mpFrmMap->erase( aIter ); 2272 2273 // Remove reference to old caret object. Though mxCursorContext 2274 // is a weak reference and cleared automatically, clearing it 2275 // directly makes sure to not keep a defunctional object. 2276 uno::Reference < XAccessible > xOldAcc( mxCursorContext ); 2277 if( xOldAcc.is() ) 2278 { 2279 SwAccessibleContext *pOldAccImpl = 2280 static_cast< SwAccessibleContext *>( xOldAcc.get() ); 2281 ASSERT( pOldAccImpl->GetFrm(), "old caret context is disposed" ); 2282 if( pOldAccImpl->GetFrm() == pFrm ) 2283 { 2284 xOldAcc.clear(); // get an empty ref 2285 mxCursorContext = xOldAcc; 2286 } 2287 } 2288 2289 if( mpFrmMap->empty() ) 2290 { 2291 delete mpFrmMap; 2292 mpFrmMap = 0; 2293 } 2294 } 2295 } 2296 } 2297 2298 void SwAccessibleMap::RemoveContext( const SdrObject *pObj ) 2299 { 2300 vos::OGuard aGuard( maMutex ); 2301 2302 if( mpShapeMap ) 2303 { 2304 SwAccessibleShapeMap_Impl::iterator aIter = 2305 mpShapeMap->find( pObj ); 2306 if( aIter != mpShapeMap->end() ) 2307 { 2308 //IAccessible2 Implementation 2009 ---- 2309 uno::Reference < XAccessible > xAcc( (*aIter).second ); 2310 mpShapeMap->erase( aIter ); 2311 RemoveGroupContext(pObj, xAcc); 2312 // The shape selection flag is not cleared, but one might do 2313 // so but has to make sure that the removed context is the one 2314 // that is selected. 2315 2316 if( mpShapeMap && mpShapeMap->empty() ) 2317 //---- IAccessible2 Implementation 2009 2318 { 2319 delete mpShapeMap; 2320 mpShapeMap = 0; 2321 } 2322 } 2323 } 2324 } 2325 2326 2327 void SwAccessibleMap::Dispose( const SwFrm *pFrm, 2328 const SdrObject *pObj, 2329 Window* pWindow, 2330 sal_Bool bRecursive ) 2331 { 2332 SwAccessibleChild aFrmOrObj( pFrm, pObj, pWindow ); 2333 2334 // Indeed, the following assert checks the frame's accessible flag, 2335 // because that's the one that is evaluated in the layout. The frame 2336 // might not be accessible anyway. That's the case for cell frames that 2337 // contain further cells. 2338 ASSERT( !aFrmOrObj.GetSwFrm() || aFrmOrObj.GetSwFrm()->IsAccessibleFrm(), 2339 "non accessible frame should be disposed" ); 2340 2341 if( aFrmOrObj.IsAccessible( GetShell()->IsPreView() ) ) 2342 { 2343 ::vos::ORef< SwAccessibleContext > xAccImpl; 2344 ::vos::ORef< SwAccessibleContext > xParentAccImpl; 2345 ::vos::ORef< ::accessibility::AccessibleShape > xShapeAccImpl; 2346 // get accessible context for frame 2347 { 2348 vos::OGuard aGuard( maMutex ); 2349 2350 // First of all look for an accessible context for a frame 2351 if( aFrmOrObj.GetSwFrm() && mpFrmMap ) 2352 { 2353 SwAccessibleContextMap_Impl::iterator aIter = 2354 mpFrmMap->find( aFrmOrObj.GetSwFrm() ); 2355 if( aIter != mpFrmMap->end() ) 2356 { 2357 uno::Reference < XAccessible > xAcc( (*aIter).second ); 2358 xAccImpl = 2359 static_cast< SwAccessibleContext *>( xAcc.get() ); 2360 } 2361 } 2362 if( !xAccImpl.isValid() && mpFrmMap ) 2363 { 2364 // If there is none, look if the parent is accessible. 2365 const SwFrm *pParent = 2366 SwAccessibleFrame::GetParent( aFrmOrObj, 2367 GetShell()->IsPreView()); 2368 2369 if( pParent ) 2370 { 2371 SwAccessibleContextMap_Impl::iterator aIter = 2372 mpFrmMap->find( pParent ); 2373 if( aIter != mpFrmMap->end() ) 2374 { 2375 uno::Reference < XAccessible > xAcc( (*aIter).second ); 2376 xParentAccImpl = 2377 static_cast< SwAccessibleContext *>( xAcc.get() ); 2378 } 2379 } 2380 } 2381 if( !xParentAccImpl.isValid() && !aFrmOrObj.GetSwFrm() && 2382 mpShapeMap ) 2383 { 2384 SwAccessibleShapeMap_Impl::iterator aIter = 2385 mpShapeMap->find( aFrmOrObj.GetDrawObject() ); 2386 if( aIter != mpShapeMap->end() ) 2387 { 2388 uno::Reference < XAccessible > xAcc( (*aIter).second ); 2389 xShapeAccImpl = 2390 static_cast< ::accessibility::AccessibleShape *>( xAcc.get() ); 2391 } 2392 } 2393 if( pObj && GetShell()->ActionPend() && 2394 (xParentAccImpl.isValid() || xShapeAccImpl.isValid()) ) 2395 { 2396 // Keep a reference to the XShape to avoid that it 2397 // is deleted with a SwFrmFmt::Modify. 2398 uno::Reference < drawing::XShape > xShape( 2399 const_cast< SdrObject * >( pObj )->getUnoShape(), 2400 uno::UNO_QUERY ); 2401 if( xShape.is() ) 2402 { 2403 if( !mpShapes ) 2404 mpShapes = new SwShapeList_Impl; 2405 mpShapes->push_back( xShape ); 2406 } 2407 } 2408 } 2409 2410 // remove events stored for the frame 2411 { 2412 vos::OGuard aGuard( maEventMutex ); 2413 if( mpEvents ) 2414 { 2415 SwAccessibleEventMap_Impl::iterator aIter = 2416 mpEventMap->find( aFrmOrObj ); 2417 if( aIter != mpEventMap->end() ) 2418 { 2419 SwAccessibleEvent_Impl aEvent( 2420 SwAccessibleEvent_Impl::DISPOSE, aFrmOrObj ); 2421 AppendEvent( aEvent ); 2422 } 2423 } 2424 } 2425 2426 // If the frame is accessible and there is a context for it, dispose 2427 // the frame. If the frame is no context for it but disposing should 2428 // take place recursive, the frame's children have to be disposed 2429 // anyway, so we have to create the context then. 2430 if( xAccImpl.isValid() ) 2431 { 2432 xAccImpl->Dispose( bRecursive ); 2433 } 2434 else if( xParentAccImpl.isValid() ) 2435 { 2436 // If the frame is a cell frame, the table must be notified. 2437 // If we are in an action, a table model change event will 2438 // be broadcasted at the end of the action to give the table 2439 // a chance to generate a single table change event. 2440 2441 xParentAccImpl->DisposeChild( aFrmOrObj, bRecursive ); 2442 } 2443 else if( xShapeAccImpl.isValid() ) 2444 { 2445 RemoveContext( aFrmOrObj.GetDrawObject() ); 2446 xShapeAccImpl->dispose(); 2447 } 2448 2449 if( mpPreview && pFrm && pFrm->IsPageFrm() ) 2450 mpPreview->DisposePage( static_cast< const SwPageFrm *>( pFrm ) ); 2451 } 2452 } 2453 2454 void SwAccessibleMap::InvalidatePosOrSize( const SwFrm *pFrm, 2455 const SdrObject *pObj, 2456 Window* pWindow, 2457 const SwRect& rOldBox ) 2458 { 2459 SwAccessibleChild aFrmOrObj( pFrm, pObj, pWindow ); 2460 if( aFrmOrObj.IsAccessible( GetShell()->IsPreView() ) ) 2461 { 2462 ::vos::ORef< SwAccessibleContext > xAccImpl; 2463 ::vos::ORef< SwAccessibleContext > xParentAccImpl; 2464 const SwFrm *pParent =NULL; //IAccessibility2 Implementation 2009 2465 { 2466 vos::OGuard aGuard( maMutex ); 2467 2468 if( mpFrmMap ) 2469 { 2470 if( aFrmOrObj.GetSwFrm() ) 2471 { 2472 SwAccessibleContextMap_Impl::iterator aIter = 2473 mpFrmMap->find( aFrmOrObj.GetSwFrm() ); 2474 if( aIter != mpFrmMap->end() ) 2475 { 2476 // If there is an accesible object already it is 2477 // notified directly. 2478 uno::Reference < XAccessible > xAcc( (*aIter).second ); 2479 xAccImpl = 2480 static_cast< SwAccessibleContext *>( xAcc.get() ); 2481 } 2482 } 2483 if( !xAccImpl.isValid() ) 2484 { 2485 // Otherwise we look if the parent is accessible. 2486 // If not, there is nothing to do. 2487 pParent = //IAccessibility2 Implementation 2009 2488 SwAccessibleFrame::GetParent( aFrmOrObj, 2489 GetShell()->IsPreView()); 2490 2491 if( pParent ) 2492 { 2493 SwAccessibleContextMap_Impl::iterator aIter = 2494 mpFrmMap->find( pParent ); 2495 if( aIter != mpFrmMap->end() ) 2496 { 2497 uno::Reference < XAccessible > xAcc( (*aIter).second ); 2498 xParentAccImpl = 2499 static_cast< SwAccessibleContext *>( xAcc.get() ); 2500 } 2501 } 2502 } 2503 } 2504 } 2505 2506 if( xAccImpl.isValid() ) 2507 { 2508 if( GetShell()->ActionPend() ) 2509 { 2510 SwAccessibleEvent_Impl aEvent( 2511 SwAccessibleEvent_Impl::POS_CHANGED, xAccImpl.getBodyPtr(), 2512 aFrmOrObj, rOldBox ); 2513 AppendEvent( aEvent ); 2514 } 2515 else 2516 { 2517 FireEvents(); 2518 xAccImpl->InvalidatePosOrSize( rOldBox ); 2519 } 2520 } 2521 else if( xParentAccImpl.isValid() ) 2522 { 2523 if( GetShell()->ActionPend() ) 2524 { 2525 SwAccessibleEvent_Impl aEvent( 2526 SwAccessibleEvent_Impl::CHILD_POS_CHANGED, 2527 xParentAccImpl.getBodyPtr(), aFrmOrObj, rOldBox ); 2528 AppendEvent( aEvent ); 2529 } 2530 else 2531 { 2532 FireEvents(); 2533 xParentAccImpl->InvalidateChildPosOrSize( aFrmOrObj, 2534 rOldBox ); 2535 } 2536 } 2537 //IAccessibility2 Implementation 2009----- 2538 else if(pParent) 2539 { 2540 /* 2541 For child graphic and it's parent paragraph,if split 2 graphic to 2 paragraph, 2542 will delete one graphic swfrm and new create 1 graphic swfrm , 2543 then the new paragraph and the new graphic SwFrm will add . 2544 but when add graphic SwFrm ,the accessible of the new Paragraph is not created yet. 2545 so the new graphic accessible 'parent is NULL, 2546 so run here: save the parent's SwFrm not the accessible object parent, 2547 */ 2548 sal_Bool bIsValidFrm = sal_False; 2549 sal_Bool bIsTxtParent = sal_False; 2550 if (aFrmOrObj.GetSwFrm()) 2551 { 2552 int nType = pFrm->GetType(); 2553 if ( FRM_FLY == nType ) 2554 { 2555 bIsValidFrm =sal_True; 2556 } 2557 } 2558 else if(pObj) 2559 { 2560 int nType = pParent->GetType(); 2561 if (FRM_TXT == nType) 2562 { 2563 bIsTxtParent =sal_True; 2564 } 2565 } 2566 // sal_Bool bIsVisibleChildrenOnly =aFrmOrObj.IsVisibleChildrenOnly() ; 2567 // sal_Bool bIsBoundAsChar =aFrmOrObj.IsBoundAsChar() ;//bIsVisibleChildrenOnly && bIsBoundAsChar && 2568 if((bIsValidFrm || bIsTxtParent) ) 2569 { 2570 if( GetShell()->ActionPend() ) 2571 { 2572 SwAccessibleEvent_Impl aEvent( 2573 SwAccessibleEvent_Impl::CHILD_POS_CHANGED, 2574 pParent, aFrmOrObj, rOldBox ); 2575 AppendEvent( aEvent ); 2576 } 2577 else 2578 { 2579 OSL_ENSURE(false,""); 2580 } 2581 } 2582 } 2583 } 2584 //-----IAccessibility2 Implementation 2009 2585 } 2586 2587 void SwAccessibleMap::InvalidateContent( const SwFrm *pFrm ) 2588 { 2589 SwAccessibleChild aFrmOrObj( pFrm ); 2590 if( aFrmOrObj.IsAccessible( GetShell()->IsPreView() ) ) 2591 { 2592 uno::Reference < XAccessible > xAcc; 2593 { 2594 vos::OGuard aGuard( maMutex ); 2595 2596 if( mpFrmMap ) 2597 { 2598 SwAccessibleContextMap_Impl::iterator aIter = 2599 mpFrmMap->find( aFrmOrObj.GetSwFrm() ); 2600 if( aIter != mpFrmMap->end() ) 2601 xAcc = (*aIter).second; 2602 } 2603 } 2604 2605 if( xAcc.is() ) 2606 { 2607 SwAccessibleContext *pAccImpl = 2608 static_cast< SwAccessibleContext *>( xAcc.get() ); 2609 if( GetShell()->ActionPend() ) 2610 { 2611 SwAccessibleEvent_Impl aEvent( 2612 SwAccessibleEvent_Impl::INVALID_CONTENT, pAccImpl, 2613 aFrmOrObj ); 2614 AppendEvent( aEvent ); 2615 } 2616 else 2617 { 2618 FireEvents(); 2619 pAccImpl->InvalidateContent(); 2620 } 2621 } 2622 } 2623 } 2624 2625 // --> OD 2009-01-06 #i88069# 2626 void SwAccessibleMap::InvalidateAttr( const SwTxtFrm& rTxtFrm ) 2627 { 2628 SwAccessibleChild aFrmOrObj( &rTxtFrm ); 2629 if( aFrmOrObj.IsAccessible( GetShell()->IsPreView() ) ) 2630 { 2631 uno::Reference < XAccessible > xAcc; 2632 { 2633 vos::OGuard aGuard( maMutex ); 2634 2635 if( mpFrmMap ) 2636 { 2637 SwAccessibleContextMap_Impl::iterator aIter = 2638 mpFrmMap->find( aFrmOrObj.GetSwFrm() ); 2639 if( aIter != mpFrmMap->end() ) 2640 xAcc = (*aIter).second; 2641 } 2642 } 2643 2644 if( xAcc.is() ) 2645 { 2646 SwAccessibleContext *pAccImpl = 2647 static_cast< SwAccessibleContext *>( xAcc.get() ); 2648 if( GetShell()->ActionPend() ) 2649 { 2650 SwAccessibleEvent_Impl aEvent( SwAccessibleEvent_Impl::INVALID_ATTR, 2651 pAccImpl, aFrmOrObj ); 2652 aEvent.SetStates( ACC_STATE_TEXT_ATTRIBUTE_CHANGED ); 2653 AppendEvent( aEvent ); 2654 } 2655 else 2656 { 2657 FireEvents(); 2658 pAccImpl->InvalidateAttr(); 2659 } 2660 } 2661 } 2662 } 2663 // <-- 2664 2665 void SwAccessibleMap::InvalidateCursorPosition( const SwFrm *pFrm ) 2666 { 2667 SwAccessibleChild aFrmOrObj( pFrm ); 2668 sal_Bool bShapeSelected = sal_False; 2669 const ViewShell *pVSh = GetShell(); 2670 if( pVSh->ISA( SwCrsrShell ) ) 2671 { 2672 const SwCrsrShell *pCSh = static_cast< const SwCrsrShell * >( pVSh ); 2673 if( pCSh->IsTableMode() ) 2674 { 2675 while( aFrmOrObj.GetSwFrm() && !aFrmOrObj.GetSwFrm()->IsCellFrm() ) 2676 aFrmOrObj = aFrmOrObj.GetSwFrm()->GetUpper(); 2677 } 2678 else if( pVSh->ISA( SwFEShell ) ) 2679 { 2680 sal_uInt16 nObjCount; 2681 const SwFEShell *pFESh = static_cast< const SwFEShell * >( pVSh ); 2682 const SwFrm *pFlyFrm = pFESh->GetCurrFlyFrm(); 2683 if( pFlyFrm ) 2684 { 2685 ASSERT( !pFrm || pFrm->FindFlyFrm() == pFlyFrm, 2686 "cursor is not contained in fly frame" ); 2687 aFrmOrObj = pFlyFrm; 2688 } 2689 else if( (nObjCount = pFESh->IsObjSelected()) > 0 ) 2690 { 2691 bShapeSelected = sal_True; 2692 aFrmOrObj = static_cast<const SwFrm *>( 0 ); 2693 } 2694 } 2695 } 2696 2697 ASSERT( bShapeSelected || aFrmOrObj.IsAccessible(GetShell()->IsPreView()), 2698 "frame is not accessible" ); 2699 2700 uno::Reference < XAccessible > xOldAcc; 2701 uno::Reference < XAccessible > xAcc; 2702 sal_Bool bOldShapeSelected = sal_False; 2703 2704 { 2705 vos::OGuard aGuard( maMutex ); 2706 2707 xOldAcc = mxCursorContext; 2708 mxCursorContext = xAcc; // clear reference 2709 2710 bOldShapeSelected = mbShapeSelected; 2711 mbShapeSelected = bShapeSelected; 2712 2713 if( aFrmOrObj.GetSwFrm() && mpFrmMap ) 2714 { 2715 SwAccessibleContextMap_Impl::iterator aIter = 2716 mpFrmMap->find( aFrmOrObj.GetSwFrm() ); 2717 if( aIter != mpFrmMap->end() ) 2718 xAcc = (*aIter).second; 2719 //IAccessibility2 Implementation 2009----- 2720 else 2721 { 2722 SwRect rcEmpty; 2723 const SwTabFrm* pTabFrm = aFrmOrObj.GetSwFrm()->FindTabFrm(); 2724 if (pTabFrm) 2725 { 2726 InvalidatePosOrSize(pTabFrm,0,0,rcEmpty); 2727 } 2728 else 2729 { 2730 InvalidatePosOrSize(aFrmOrObj.GetSwFrm(),0,0,rcEmpty); 2731 } 2732 2733 2734 aIter = 2735 mpFrmMap->find( aFrmOrObj.GetSwFrm() ); 2736 if( aIter != mpFrmMap->end() ) 2737 { 2738 xAcc = (*aIter).second; 2739 } 2740 } 2741 //-----IAccessibility2 Implementation 2009 2742 2743 // For cells, some extra thoughts are necessary, 2744 // because invalidating the cursor for one cell 2745 // invalidates the cursor for all cells of the same 2746 // table. For this reason, we don't want to 2747 // invalidate the cursor for the old cursor object 2748 // and the new one if they are within the same table, 2749 // because this would result in doing the work twice. 2750 // Moreover, we have to make sure to invalidate the 2751 // cursor even if the current cell has no accessible object. 2752 // If the old cursor objects exists and is in the same 2753 // table, its the best choice, because using it avoids 2754 // an unnessarary cursor invalidation cycle when creating 2755 // a new object for the current cell. 2756 if( aFrmOrObj.GetSwFrm()->IsCellFrm() ) 2757 { 2758 if( xOldAcc.is() && 2759 AreInSameTable( xOldAcc, aFrmOrObj.GetSwFrm() ) ) 2760 { 2761 if( xAcc.is() ) 2762 xOldAcc = xAcc; // avoid extra invalidation 2763 else 2764 xAcc = xOldAcc; // make sure ate least one 2765 } 2766 if( !xAcc.is() ) 2767 xAcc = GetContext( aFrmOrObj.GetSwFrm(), sal_True ); 2768 } 2769 } 2770 //IAccessibility2 Implementation 2009----- 2771 else if (bShapeSelected) 2772 { 2773 const SwFEShell *pFESh = pVSh ? static_cast< const SwFEShell * >( pVSh ) : NULL ; 2774 if(pFESh) 2775 { 2776 const SdrMarkList *pMarkList = pFESh->GetMarkList(); 2777 if (pMarkList != NULL && pMarkList->GetMarkCount() == 1) 2778 { 2779 SdrObject *pObj = pMarkList->GetMark( 0 )->GetMarkedSdrObj(); 2780 ::vos::ORef < ::accessibility::AccessibleShape > pAccShapeImpl = GetContextImpl(pObj,NULL,sal_False); 2781 if (!pAccShapeImpl.isValid()) 2782 { 2783 while (pObj && pObj->GetUpGroup()) 2784 { 2785 pObj = pObj->GetUpGroup(); 2786 } 2787 if (pObj != NULL) 2788 { 2789 const SwFrm *pParent = SwAccessibleFrame::GetParent( SwAccessibleChild(pObj), GetShell()->IsPreView() ); 2790 if( pParent ) 2791 { 2792 ::vos::ORef< SwAccessibleContext > xParentAccImpl = GetContextImpl(pParent,sal_False); 2793 if (!xParentAccImpl.isValid()) 2794 { 2795 const SwTabFrm* pTabFrm = pParent->FindTabFrm(); 2796 if (pTabFrm) 2797 { 2798 //The Table should not add in acc.because the "pParent" is not add to acc . 2799 uno::Reference< XAccessible> xAccParentTab = GetContext(pTabFrm,sal_True);//Should Create. 2800 2801 const SwFrm *pParentRoot = SwAccessibleFrame::GetParent( SwAccessibleChild(pTabFrm), GetShell()->IsPreView() ); 2802 if (pParentRoot) 2803 { 2804 ::vos::ORef< SwAccessibleContext > xParentAccImplRoot = GetContextImpl(pParentRoot,sal_False); 2805 if(xParentAccImplRoot.isValid()) 2806 { 2807 AccessibleEventObject aEvent; 2808 aEvent.EventId = AccessibleEventId::CHILD; 2809 aEvent.NewValue <<= xAccParentTab; 2810 xParentAccImplRoot->FireAccessibleEvent( aEvent ); 2811 } 2812 } 2813 2814 //Get "pParent" acc again. 2815 xParentAccImpl = GetContextImpl(pParent,sal_False); 2816 } 2817 else 2818 { 2819 //directly create this acc para . 2820 xParentAccImpl = GetContextImpl(pParent,sal_True);//Should Create. 2821 2822 const SwFrm *pParentRoot = SwAccessibleFrame::GetParent( SwAccessibleChild(pParent), GetShell()->IsPreView() ); 2823 2824 ::vos::ORef< SwAccessibleContext > xParentAccImplRoot = GetContextImpl(pParentRoot,sal_False); 2825 if(xParentAccImplRoot.isValid()) 2826 { 2827 AccessibleEventObject aEvent; 2828 aEvent.EventId = AccessibleEventId::CHILD; 2829 aEvent.NewValue <<= uno::Reference< XAccessible>(xParentAccImpl.getBodyPtr()); 2830 xParentAccImplRoot->FireAccessibleEvent( aEvent ); 2831 } 2832 } 2833 } 2834 if (xParentAccImpl.isValid()) 2835 { 2836 uno::Reference< XAccessible> xAccShape = 2837 GetContext(pObj,xParentAccImpl.getBodyPtr(),sal_True); 2838 2839 AccessibleEventObject aEvent; 2840 aEvent.EventId = AccessibleEventId::CHILD; 2841 aEvent.NewValue <<= xAccShape; 2842 xParentAccImpl->FireAccessibleEvent( aEvent ); 2843 } 2844 } 2845 } 2846 } 2847 } 2848 } 2849 } 2850 } 2851 2852 m_setParaAdd.clear(); 2853 m_setParaRemove.clear(); 2854 if( xOldAcc.is() && xOldAcc != xAcc ) 2855 InvalidateCursorPosition( xOldAcc ); 2856 if( bOldShapeSelected || bShapeSelected ) 2857 InvalidateShapeSelection(); 2858 if( xAcc.is() ) 2859 InvalidateCursorPosition( xAcc ); 2860 2861 InvalidateShapeInParaSelection(); 2862 2863 SET_PARA::iterator si = m_setParaRemove.begin(); 2864 for (; si != m_setParaRemove.end() ; ++si) 2865 { 2866 SwAccessibleParagraph* pAccPara = *si; 2867 if(pAccPara && pAccPara->getSelectedAccessibleChildCount() == 0 && pAccPara->getSelectedText().getLength() == 0) 2868 { 2869 if(pAccPara->SetSelectedState(sal_False)) 2870 { 2871 AccessibleEventObject aEvent; 2872 aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_REMOVE; 2873 pAccPara->FireAccessibleEvent( aEvent ); 2874 } 2875 } 2876 } 2877 si = m_setParaAdd.begin(); 2878 for (; si != m_setParaAdd.end() ; ++si) 2879 { 2880 SwAccessibleParagraph* pAccPara = *si; 2881 if(pAccPara && pAccPara->SetSelectedState(sal_True)) 2882 { 2883 AccessibleEventObject aEvent; 2884 aEvent.EventId = AccessibleEventId::SELECTION_CHANGED; 2885 pAccPara->FireAccessibleEvent( aEvent ); 2886 } 2887 } 2888 //-----IAccessibility2 Implementation 2009 2889 } 2890 2891 //IAccessibility2 Implementation 2009----- 2892 //Notify the page change event to bridge. 2893 void SwAccessibleMap::FirePageChangeEvent(sal_uInt16 nOldPage, sal_uInt16 nNewPage) 2894 { 2895 uno::Reference<XAccessible> xAcc = GetDocumentView( ); 2896 if ( xAcc.is() ) 2897 { 2898 SwAccessibleDocumentBase *pAcc = 2899 static_cast< SwAccessibleDocumentBase * >( xAcc.get() ); 2900 if (pAcc) 2901 { 2902 AccessibleEventObject aEvent; 2903 aEvent.EventId = AccessibleEventId::PAGE_CHANGED; 2904 aEvent.OldValue <<= nOldPage; 2905 aEvent.NewValue <<= nNewPage; 2906 pAcc->FireAccessibleEvent( aEvent ); 2907 } 2908 } 2909 } 2910 2911 void SwAccessibleMap::FireSectionChangeEvent(sal_uInt16 nOldSection, sal_uInt16 nNewSection) 2912 { 2913 uno::Reference<XAccessible> xAcc = GetDocumentView( ); 2914 if ( xAcc.is() ) 2915 { 2916 SwAccessibleDocumentBase *pAcc = 2917 static_cast< SwAccessibleDocumentBase * >( xAcc.get() ); 2918 if (pAcc) 2919 { 2920 AccessibleEventObject aEvent; 2921 aEvent.EventId = AccessibleEventId::SECTION_CHANGED; 2922 aEvent.OldValue <<= nOldSection; 2923 aEvent.NewValue <<= nNewSection; 2924 pAcc->FireAccessibleEvent( aEvent ); 2925 2926 } 2927 } 2928 } 2929 void SwAccessibleMap::FireColumnChangeEvent(sal_uInt16 nOldColumn, sal_uInt16 nNewColumn) 2930 { 2931 uno::Reference<XAccessible> xAcc = GetDocumentView( ); 2932 if ( xAcc.is() ) 2933 { 2934 SwAccessibleDocumentBase *pAcc = 2935 static_cast< SwAccessibleDocumentBase * >( xAcc.get() ); 2936 if (pAcc) 2937 { 2938 AccessibleEventObject aEvent; 2939 aEvent.EventId = AccessibleEventId::COLUMN_CHANGED; 2940 aEvent.OldValue <<= nOldColumn; 2941 aEvent.NewValue <<= nNewColumn; 2942 pAcc->FireAccessibleEvent( aEvent ); 2943 2944 } 2945 } 2946 } 2947 //-----IAccessibility2 Implementation 2009 2948 2949 void SwAccessibleMap::InvalidateFocus() 2950 { 2951 //IAccessibility2 Implementation 2009----- 2952 if(GetShell()->IsPreView()) 2953 { 2954 uno::Reference<XAccessible> xAcc = _GetDocumentView( sal_True ); 2955 if (xAcc.get()) 2956 { 2957 SwAccessiblePreview *pAccPreview = static_cast<SwAccessiblePreview *>(xAcc.get()); 2958 if (pAccPreview) 2959 { 2960 pAccPreview->InvalidateFocus(); 2961 return ; 2962 } 2963 } 2964 } 2965 //-----IAccessibility2 Implementation 2009 2966 uno::Reference < XAccessible > xAcc; 2967 sal_Bool bShapeSelected; 2968 { 2969 vos::OGuard aGuard( maMutex ); 2970 2971 xAcc = mxCursorContext; 2972 bShapeSelected = mbShapeSelected; 2973 } 2974 2975 if( xAcc.is() ) 2976 { 2977 SwAccessibleContext *pAccImpl = 2978 static_cast< SwAccessibleContext *>( xAcc.get() ); 2979 pAccImpl->InvalidateFocus(); 2980 } 2981 //IAccessibility2 Implementation 2009----- 2982 else 2983 { 2984 DoInvalidateShapeSelection(sal_True); 2985 } 2986 //-----IAccessibility2 Implementation 2009 2987 } 2988 2989 void SwAccessibleMap::SetCursorContext( 2990 const ::vos::ORef < SwAccessibleContext >& rCursorContext ) 2991 { 2992 vos::OGuard aGuard( maMutex ); 2993 uno::Reference < XAccessible > xAcc( rCursorContext.getBodyPtr() ); 2994 mxCursorContext = xAcc; 2995 } 2996 2997 // --> OD 2005-12-12 #i27301# - use new type definition for <_nStates> 2998 void SwAccessibleMap::InvalidateStates( tAccessibleStates _nStates, 2999 const SwFrm* _pFrm ) 3000 { 3001 // Start with the frame or the first upper that is accessible 3002 SwAccessibleChild aFrmOrObj( _pFrm ); 3003 while( aFrmOrObj.GetSwFrm() && 3004 !aFrmOrObj.IsAccessible( GetShell()->IsPreView() ) ) 3005 aFrmOrObj = aFrmOrObj.GetSwFrm()->GetUpper(); 3006 if( !aFrmOrObj.GetSwFrm() ) 3007 aFrmOrObj = GetShell()->GetLayout(); 3008 3009 uno::Reference< XAccessible > xAcc( GetContext( aFrmOrObj.GetSwFrm(), sal_True ) ); 3010 SwAccessibleContext *pAccImpl = 3011 static_cast< SwAccessibleContext *>( xAcc.get() ); 3012 if( GetShell()->ActionPend() ) 3013 { 3014 SwAccessibleEvent_Impl aEvent( SwAccessibleEvent_Impl::CARET_OR_STATES, 3015 pAccImpl, 3016 SwAccessibleChild(pAccImpl->GetFrm()), 3017 _nStates ); 3018 AppendEvent( aEvent ); 3019 } 3020 else 3021 { 3022 FireEvents(); 3023 pAccImpl->InvalidateStates( _nStates ); 3024 } 3025 } 3026 // <-- 3027 3028 void SwAccessibleMap::_InvalidateRelationSet( const SwFrm* pFrm, 3029 sal_Bool bFrom ) 3030 { 3031 // first, see if this frame is accessible, and if so, get the respective 3032 SwAccessibleChild aFrmOrObj( pFrm ); 3033 if( aFrmOrObj.IsAccessible( GetShell()->IsPreView() ) ) 3034 { 3035 uno::Reference < XAccessible > xAcc; 3036 { 3037 vos::OGuard aGuard( maMutex ); 3038 3039 if( mpFrmMap ) 3040 { 3041 SwAccessibleContextMap_Impl::iterator aIter = 3042 mpFrmMap->find( aFrmOrObj.GetSwFrm() ); 3043 if( aIter != mpFrmMap->end() ) 3044 { 3045 xAcc = (*aIter).second; 3046 } 3047 } 3048 } 3049 3050 // deliver event directly, or queue event 3051 if( xAcc.is() ) 3052 { 3053 SwAccessibleContext *pAccImpl = 3054 static_cast< SwAccessibleContext *>( xAcc.get() ); 3055 if( GetShell()->ActionPend() ) 3056 { 3057 SwAccessibleEvent_Impl aEvent( SwAccessibleEvent_Impl::CARET_OR_STATES, 3058 pAccImpl, SwAccessibleChild(pFrm), 3059 ( bFrom 3060 ? ACC_STATE_RELATION_FROM 3061 : ACC_STATE_RELATION_TO ) ); 3062 AppendEvent( aEvent ); 3063 } 3064 else 3065 { 3066 FireEvents(); 3067 pAccImpl->InvalidateRelation( bFrom 3068 ? AccessibleEventId::CONTENT_FLOWS_FROM_RELATION_CHANGED 3069 : AccessibleEventId::CONTENT_FLOWS_TO_RELATION_CHANGED ); 3070 } 3071 } 3072 } 3073 } 3074 3075 void SwAccessibleMap::InvalidateRelationSet( const SwFrm* pMaster, 3076 const SwFrm* pFollow ) 3077 { 3078 _InvalidateRelationSet( pMaster, sal_False ); 3079 _InvalidateRelationSet( pFollow, sal_True ); 3080 } 3081 3082 /** invalidation CONTENT_FLOW_FROM/_TO relation of a paragraph 3083 3084 OD 2005-12-01 #i27138# 3085 3086 @author OD 3087 */ 3088 void SwAccessibleMap::InvalidateParaFlowRelation( const SwTxtFrm& _rTxtFrm, 3089 const bool _bFrom ) 3090 { 3091 _InvalidateRelationSet( &_rTxtFrm, _bFrom ); 3092 } 3093 3094 /** invalidation of text selection of a paragraph 3095 3096 OD 2005-12-12 #i27301# 3097 3098 @author OD 3099 */ 3100 void SwAccessibleMap::InvalidateParaTextSelection( const SwTxtFrm& _rTxtFrm ) 3101 { 3102 // first, see if this frame is accessible, and if so, get the respective 3103 SwAccessibleChild aFrmOrObj( &_rTxtFrm ); 3104 if( aFrmOrObj.IsAccessible( GetShell()->IsPreView() ) ) 3105 { 3106 uno::Reference < XAccessible > xAcc; 3107 { 3108 vos::OGuard aGuard( maMutex ); 3109 3110 if( mpFrmMap ) 3111 { 3112 SwAccessibleContextMap_Impl::iterator aIter = 3113 mpFrmMap->find( aFrmOrObj.GetSwFrm() ); 3114 if( aIter != mpFrmMap->end() ) 3115 { 3116 xAcc = (*aIter).second; 3117 } 3118 } 3119 } 3120 3121 // deliver event directly, or queue event 3122 if( xAcc.is() ) 3123 { 3124 SwAccessibleContext *pAccImpl = 3125 static_cast< SwAccessibleContext *>( xAcc.get() ); 3126 if( GetShell()->ActionPend() ) 3127 { 3128 SwAccessibleEvent_Impl aEvent( 3129 SwAccessibleEvent_Impl::CARET_OR_STATES, 3130 pAccImpl, 3131 SwAccessibleChild( &_rTxtFrm ), 3132 ACC_STATE_TEXT_SELECTION_CHANGED ); 3133 AppendEvent( aEvent ); 3134 } 3135 else 3136 { 3137 FireEvents(); 3138 pAccImpl->InvalidateTextSelection(); 3139 } 3140 } 3141 } 3142 } 3143 3144 sal_Int32 SwAccessibleMap::GetChildIndex( const SwFrm& rParentFrm, 3145 Window& rChild ) const 3146 { 3147 sal_Int32 nIndex( -1 ); 3148 3149 SwAccessibleChild aFrmOrObj( &rParentFrm ); 3150 if( aFrmOrObj.IsAccessible( GetShell()->IsPreView() ) ) 3151 { 3152 uno::Reference < XAccessible > xAcc; 3153 { 3154 vos::OGuard aGuard( maMutex ); 3155 3156 if( mpFrmMap ) 3157 { 3158 SwAccessibleContextMap_Impl::iterator aIter = 3159 mpFrmMap->find( aFrmOrObj.GetSwFrm() ); 3160 if( aIter != mpFrmMap->end() ) 3161 { 3162 xAcc = (*aIter).second; 3163 } 3164 } 3165 } 3166 3167 if( xAcc.is() ) 3168 { 3169 SwAccessibleContext *pAccImpl = 3170 static_cast< SwAccessibleContext *>( xAcc.get() ); 3171 3172 nIndex = pAccImpl->GetChildIndex( const_cast<SwAccessibleMap&>(*this), 3173 SwAccessibleChild( &rChild ) ); 3174 } 3175 } 3176 3177 return nIndex; 3178 } 3179 3180 3181 // OD 15.01.2003 #103492# - complete re-factoring of method due to new page/print 3182 // preview functionality. 3183 void SwAccessibleMap::UpdatePreview( const std::vector<PrevwPage*>& _rPrevwPages, 3184 const Fraction& _rScale, 3185 const SwPageFrm* _pSelectedPageFrm, 3186 const Size& _rPrevwWinSize ) 3187 { 3188 DBG_ASSERT( GetShell()->IsPreView(), "no preview?" ); 3189 DBG_ASSERT( mpPreview != NULL, "no preview data?" ); 3190 3191 // OD 15.01.2003 #103492# - adjustments for changed method signature 3192 mpPreview->Update( *this, _rPrevwPages, _rScale, _pSelectedPageFrm, _rPrevwWinSize ); 3193 3194 // propagate change of VisArea through the document's 3195 // accessibility tree; this will also send appropriate scroll 3196 // events 3197 SwAccessibleContext* pDoc = 3198 GetContextImpl( GetShell()->GetLayout() ).getBodyPtr(); 3199 static_cast<SwAccessibleDocumentBase*>( pDoc )->SetVisArea(); 3200 3201 uno::Reference < XAccessible > xOldAcc; 3202 uno::Reference < XAccessible > xAcc; 3203 { 3204 vos::OGuard aGuard( maMutex ); 3205 3206 xOldAcc = mxCursorContext; 3207 3208 const SwPageFrm *pSelPage = mpPreview->GetSelPage(); 3209 if( pSelPage && mpFrmMap ) 3210 { 3211 SwAccessibleContextMap_Impl::iterator aIter = 3212 mpFrmMap->find( pSelPage ); 3213 if( aIter != mpFrmMap->end() ) 3214 xAcc = (*aIter).second; 3215 } 3216 } 3217 3218 if( xOldAcc.is() && xOldAcc != xAcc ) 3219 InvalidateCursorPosition( xOldAcc ); 3220 if( xAcc.is() ) 3221 InvalidateCursorPosition( xAcc ); 3222 } 3223 3224 void SwAccessibleMap::InvalidatePreViewSelection( sal_uInt16 nSelPage ) 3225 { 3226 DBG_ASSERT( GetShell()->IsPreView(), "no preview?" ); 3227 DBG_ASSERT( mpPreview != NULL, "no preview data?" ); 3228 3229 // OD 16.01.2003 #103492# - changed metthod call due to method signature change. 3230 mpPreview->InvalidateSelection( GetShell()->GetLayout()->GetPageByPageNum( nSelPage ) ); 3231 3232 uno::Reference < XAccessible > xOldAcc; 3233 uno::Reference < XAccessible > xAcc; 3234 { 3235 vos::OGuard aGuard( maMutex ); 3236 3237 xOldAcc = mxCursorContext; 3238 3239 const SwPageFrm *pSelPage = mpPreview->GetSelPage(); 3240 if( pSelPage && mpFrmMap ) 3241 { 3242 SwAccessibleContextMap_Impl::iterator aIter = 3243 mpFrmMap->find( pSelPage ); 3244 if( aIter != mpFrmMap->end() ) 3245 xAcc = (*aIter).second; 3246 } 3247 } 3248 3249 if( xOldAcc.is() && xOldAcc != xAcc ) 3250 InvalidateCursorPosition( xOldAcc ); 3251 if( xAcc.is() ) 3252 InvalidateCursorPosition( xAcc ); 3253 } 3254 3255 3256 sal_Bool SwAccessibleMap::IsPageSelected( const SwPageFrm *pPageFrm ) const 3257 { 3258 return mpPreview && mpPreview->GetSelPage() == pPageFrm; 3259 } 3260 3261 3262 void SwAccessibleMap::FireEvents() 3263 { 3264 { 3265 vos::OGuard aGuard( maEventMutex ); 3266 if( mpEvents ) 3267 { 3268 mpEvents->SetFiring(); 3269 //IAccessibility2 Implementation 2009----- 3270 mpEvents->MoveInvalidXAccToEnd(); 3271 //-----IAccessibility2 Implementation 2009 3272 SwAccessibleEventList_Impl::iterator aIter = mpEvents->begin(); 3273 while( aIter != mpEvents->end() ) 3274 { 3275 FireEvent( *aIter ); 3276 ++aIter; 3277 } 3278 3279 delete mpEventMap; 3280 mpEventMap = 0; 3281 3282 delete mpEvents; 3283 mpEvents = 0; 3284 } 3285 } 3286 { 3287 vos::OGuard aGuard( maMutex ); 3288 if( mpShapes ) 3289 { 3290 delete mpShapes; 3291 mpShapes = 0; 3292 } 3293 } 3294 3295 } 3296 3297 sal_Bool SwAccessibleMap::IsValid() const 3298 { 3299 return sal_True; 3300 } 3301 3302 Rectangle SwAccessibleMap::GetVisibleArea() const 3303 { 3304 MapMode aSrc( MAP_TWIP ); 3305 MapMode aDest( MAP_100TH_MM ); 3306 return OutputDevice::LogicToLogic( GetVisArea().SVRect(), aSrc, aDest ); 3307 } 3308 3309 // Convert a MM100 value realtive to the document root into a pixel value 3310 // realtive to the screen! 3311 Point SwAccessibleMap::LogicToPixel( const Point& rPoint ) const 3312 { 3313 MapMode aSrc( MAP_100TH_MM ); 3314 MapMode aDest( MAP_TWIP ); 3315 3316 Point aPoint = rPoint; 3317 3318 aPoint = OutputDevice::LogicToLogic( aPoint, aSrc, aDest ); 3319 Window *pWin = GetShell()->GetWin(); 3320 if( pWin ) 3321 { 3322 // OD 16.01.2003 #103492# - get mapping mode for LogicToPixel conversion 3323 MapMode aMapMode; 3324 GetMapMode( aPoint, aMapMode ); 3325 aPoint = pWin->LogicToPixel( aPoint, aMapMode ); 3326 aPoint = pWin->OutputToAbsoluteScreenPixel( aPoint ); 3327 } 3328 3329 return aPoint; 3330 } 3331 3332 Size SwAccessibleMap::LogicToPixel( const Size& rSize ) const 3333 { 3334 MapMode aSrc( MAP_100TH_MM ); 3335 MapMode aDest( MAP_TWIP ); 3336 Size aSize( OutputDevice::LogicToLogic( rSize, aSrc, aDest ) ); 3337 if( GetShell()->GetWin() ) 3338 { 3339 // OD 16.01.2003 #103492# - get mapping mode for LogicToPixel conversion 3340 MapMode aMapMode; 3341 GetMapMode( Point(0,0), aMapMode ); 3342 aSize = GetShell()->GetWin()->LogicToPixel( aSize, aMapMode ); 3343 } 3344 3345 return aSize; 3346 } 3347 3348 Point SwAccessibleMap::PixelToLogic( const Point& rPoint ) const 3349 { 3350 Point aPoint; 3351 Window *pWin = GetShell()->GetWin(); 3352 if( pWin ) 3353 { 3354 aPoint = pWin->ScreenToOutputPixel( rPoint ); 3355 // OD 16.01.2003 #103492# - get mapping mode for PixelToLogic conversion 3356 MapMode aMapMode; 3357 GetMapMode( aPoint, aMapMode ); 3358 aPoint = pWin->PixelToLogic( aPoint, aMapMode ); 3359 MapMode aSrc( MAP_TWIP ); 3360 MapMode aDest( MAP_100TH_MM ); 3361 aPoint = OutputDevice::LogicToLogic( aPoint, aSrc, aDest ); 3362 } 3363 3364 return aPoint; 3365 } 3366 3367 Size SwAccessibleMap::PixelToLogic( const Size& rSize ) const 3368 { 3369 Size aSize; 3370 if( GetShell()->GetWin() ) 3371 { 3372 // OD 16.01.2003 #103492# - get mapping mode for PixelToLogic conversion 3373 MapMode aMapMode; 3374 GetMapMode( Point(0,0), aMapMode ); 3375 aSize = GetShell()->GetWin()->PixelToLogic( rSize, aMapMode ); 3376 MapMode aSrc( MAP_TWIP ); 3377 MapMode aDest( MAP_100TH_MM ); 3378 aSize = OutputDevice::LogicToLogic( aSize, aSrc, aDest ); 3379 } 3380 3381 return aSize; 3382 } 3383 3384 sal_Bool SwAccessibleMap::ReplaceChild ( 3385 ::accessibility::AccessibleShape* pCurrentChild, 3386 const uno::Reference< drawing::XShape >& _rxShape, 3387 const long /*_nIndex*/, 3388 const ::accessibility::AccessibleShapeTreeInfo& /*_rShapeTreeInfo*/ 3389 ) throw (uno::RuntimeException) 3390 { 3391 const SdrObject *pObj = 0; 3392 { 3393 vos::OGuard aGuard( maMutex ); 3394 if( mpShapeMap ) 3395 { 3396 SwAccessibleShapeMap_Impl::const_iterator aIter = mpShapeMap->begin(); 3397 SwAccessibleShapeMap_Impl::const_iterator aEndIter = mpShapeMap->end(); 3398 while( aIter != aEndIter && !pObj ) 3399 { 3400 uno::Reference < XAccessible > xAcc( (*aIter).second ); 3401 ::accessibility::AccessibleShape *pAccShape = 3402 static_cast < ::accessibility::AccessibleShape* >( xAcc.get() ); 3403 if( pAccShape == pCurrentChild ) 3404 { 3405 pObj = (*aIter).first; 3406 } 3407 ++aIter; 3408 } 3409 } 3410 } 3411 if( !pObj ) 3412 return sal_False; 3413 3414 uno::Reference < drawing::XShape > xShape( _rxShape ); //keep reference to shape, because 3415 // we might be the only one that 3416 // hold it. 3417 // Also get keep parent. 3418 uno::Reference < XAccessible > xParent( pCurrentChild->getAccessibleParent() ); 3419 pCurrentChild = 0; // well be realease by dispose 3420 Dispose( 0, pObj, 0 ); 3421 3422 { 3423 vos::OGuard aGuard( maMutex ); 3424 3425 if( !mpShapeMap ) 3426 mpShapeMap = new SwAccessibleShapeMap_Impl( this ); 3427 3428 // create the new child 3429 ::accessibility::ShapeTypeHandler& rShapeTypeHandler = 3430 ::accessibility::ShapeTypeHandler::Instance(); 3431 ::accessibility::AccessibleShapeInfo aShapeInfo( 3432 xShape, xParent, this ); 3433 ::accessibility::AccessibleShape* pReplacement = 3434 rShapeTypeHandler.CreateAccessibleObject ( 3435 aShapeInfo, mpShapeMap->GetInfo() ); 3436 3437 uno::Reference < XAccessible > xAcc( pReplacement ); 3438 if( xAcc.is() ) 3439 { 3440 pReplacement->Init(); 3441 3442 SwAccessibleShapeMap_Impl::iterator aIter = 3443 mpShapeMap->find( pObj ); 3444 if( aIter != mpShapeMap->end() ) 3445 { 3446 (*aIter).second = xAcc; 3447 } 3448 else 3449 { 3450 SwAccessibleShapeMap_Impl::value_type aEntry( pObj, xAcc ); 3451 mpShapeMap->insert( aEntry ); 3452 } 3453 } 3454 } 3455 3456 SwRect aEmptyRect; 3457 InvalidatePosOrSize( 0, pObj, 0, aEmptyRect ); 3458 3459 return sal_True; 3460 } 3461 3462 //IAccessibility2 Implementation 2009----- 3463 //Get the accessible control shape from the model object, here model object is with XPropertySet type 3464 ::accessibility::AccessibleControlShape * SwAccessibleMap::GetAccControlShapeFromModel(::com::sun::star::beans::XPropertySet* pSet) throw (::com::sun::star::uno::RuntimeException) 3465 { 3466 if( mpShapeMap ) 3467 { 3468 SwAccessibleShapeMap_Impl::const_iterator aIter = mpShapeMap->begin(); 3469 SwAccessibleShapeMap_Impl::const_iterator aEndIter = mpShapeMap->end(); 3470 while( aIter != aEndIter) 3471 { 3472 uno::Reference < XAccessible > xAcc( (*aIter).second ); 3473 ::accessibility::AccessibleShape *pAccShape = 3474 static_cast < ::accessibility::AccessibleShape* >( xAcc.get() ); 3475 if(pAccShape && ::accessibility::ShapeTypeHandler::Instance().GetTypeId (pAccShape->GetXShape()) == ::accessibility::DRAWING_CONTROL) 3476 { 3477 ::accessibility::AccessibleControlShape *pCtlAccShape = static_cast < ::accessibility::AccessibleControlShape* >(pAccShape); 3478 if (pCtlAccShape && pCtlAccShape->GetControlModel() == pSet) 3479 return pCtlAccShape; 3480 } 3481 ++aIter; 3482 } 3483 } 3484 return NULL; 3485 } 3486 3487 ::com::sun::star::uno::Reference< XAccessible > 3488 SwAccessibleMap::GetAccessibleCaption (const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& xShape) 3489 throw (::com::sun::star::uno::RuntimeException) 3490 { 3491 SdrObject* captionedObject = GetSdrObjectFromXShape(xShape); 3492 3493 SwDrawContact *pContact = (SwDrawContact*)GetUserCall( captionedObject ); 3494 ASSERT( RES_DRAWFRMFMT == pContact->GetFmt()->Which(), 3495 "fail" ); 3496 if( !pContact ) 3497 return 0; 3498 3499 SwDrawFrmFmt *pCaptionedFmt = (SwDrawFrmFmt *)pContact->GetFmt(); 3500 if( !pCaptionedFmt ) 3501 return 0; 3502 3503 SwFlyFrm* pFrm = NULL; 3504 if (pCaptionedFmt->HasCaption()) 3505 { 3506 const SwFrmFmt *pCaptionFrmFmt = pCaptionedFmt->GetCaptionFmt(); 3507 SwClientIter aIter (*(SwModify*)pCaptionFrmFmt); 3508 pFrm = (SwFlyFrm*)aIter.First( TYPE ( SwFlyFrm )); 3509 } 3510 if (!pFrm) 3511 return 0; 3512 //SwFrmFmt* pFrm = pCaptionedFmt->GetCaptionFmt(); 3513 uno::Reference < XAccessible > xAcc( GetContext((SwFrm*)pFrm,sal_True) ); 3514 //Reference < XAccessibleShape > xAccShape( xAcc, UNO_QUERY ); 3515 3516 uno::Reference< XAccessibleContext > xAccContext = xAcc->getAccessibleContext(); 3517 if( xAccContext.is() ) 3518 { //get the parent of caption frame, which is paragaph 3519 uno::Reference< XAccessible > xAccParent = xAccContext->getAccessibleParent(); 3520 if(xAccParent.is()) 3521 { 3522 //get the great parent of caption frame which is text frame. 3523 uno::Reference< XAccessibleContext > xAccParentContext = xAccParent->getAccessibleContext(); 3524 uno::Reference< XAccessible > xAccGreatParent = xAccParentContext->getAccessibleParent(); 3525 if(xAccGreatParent.is()) 3526 { 3527 AccessibleEventObject aEvent; 3528 aEvent.EventId = AccessibleEventId::CHILD; 3529 aEvent.NewValue <<= xAccParent; 3530 ( static_cast< SwAccessibleContext * >(xAccGreatParent.get()) )->FireAccessibleEvent( aEvent ); 3531 3532 } 3533 3534 AccessibleEventObject aEvent; 3535 aEvent.EventId = AccessibleEventId::CHILD; 3536 aEvent.NewValue <<= xAcc; 3537 ( static_cast< SwAccessibleContext * >(xAccParent.get()) )->FireAccessibleEvent( aEvent ); 3538 } 3539 } 3540 3541 if(xAcc.get()) 3542 return xAcc; 3543 else 3544 return NULL; 3545 3546 } 3547 //-----IAccessibility2 Implementation 2009 3548 Point SwAccessibleMap::PixelToCore( const Point& rPoint ) const 3549 { 3550 Point aPoint; 3551 if( GetShell()->GetWin() ) 3552 { 3553 // OD 15.01.2003 #103492# - replace <PreviewAdjust(..)> by <GetMapMode(..)> 3554 MapMode aMapMode; 3555 GetMapMode( rPoint, aMapMode ); 3556 aPoint = GetShell()->GetWin()->PixelToLogic( rPoint, aMapMode ); 3557 } 3558 return aPoint; 3559 } 3560 3561 static inline long lcl_CorrectCoarseValue(long aCoarseValue, long aFineValue, 3562 long aRefValue, bool bToLower) 3563 { 3564 long aResult = aCoarseValue; 3565 3566 if (bToLower) 3567 { 3568 if (aFineValue < aRefValue) 3569 aResult -= 1; 3570 } 3571 else 3572 { 3573 if (aFineValue > aRefValue) 3574 aResult += 1; 3575 } 3576 3577 return aResult; 3578 } 3579 3580 static inline void lcl_CorrectRectangle(Rectangle & rRect, 3581 const Rectangle & rSource, 3582 const Rectangle & rInGrid) 3583 { 3584 rRect.nLeft = lcl_CorrectCoarseValue(rRect.nLeft, rSource.nLeft, 3585 rInGrid.nLeft, false); 3586 rRect.nTop = lcl_CorrectCoarseValue(rRect.nTop, rSource.nTop, 3587 rInGrid.nTop, false); 3588 rRect.nRight = lcl_CorrectCoarseValue(rRect.nRight, rSource.nRight, 3589 rInGrid.nRight, true); 3590 rRect.nBottom = lcl_CorrectCoarseValue(rRect.nBottom, rSource.nBottom, 3591 rInGrid.nBottom, true); 3592 } 3593 3594 Rectangle SwAccessibleMap::CoreToPixel( const Rectangle& rRect ) const 3595 { 3596 Rectangle aRect; 3597 if( GetShell()->GetWin() ) 3598 { 3599 // OD 15.01.2003 #103492# - replace <PreviewAdjust(..)> by <GetMapMode(..)> 3600 MapMode aMapMode; 3601 GetMapMode( rRect.TopLeft(), aMapMode ); 3602 aRect = GetShell()->GetWin()->LogicToPixel( rRect, aMapMode ); 3603 3604 Rectangle aTmpRect = GetShell()->GetWin()->PixelToLogic( aRect, aMapMode ); 3605 lcl_CorrectRectangle(aRect, rRect, aTmpRect); 3606 } 3607 3608 return aRect; 3609 } 3610 3611 /** get mapping mode for LogicToPixel and PixelToLogic conversions 3612 3613 OD 15.01.2003 #103492# 3614 Replacement method <PreviewAdjust(..)> by new method <GetMapMode>. 3615 Method returns mapping mode of current output device and adjusts it, 3616 if the shell is in page/print preview. 3617 Necessary, because <PreviewAdjust(..)> changes mapping mode at current 3618 output device for mapping logic document positions to page preview window 3619 positions and vice versa and doesn't take care to recover its changes. 3620 3621 @author OD 3622 */ 3623 void SwAccessibleMap::GetMapMode( const Point& _rPoint, 3624 MapMode& _orMapMode ) const 3625 { 3626 MapMode aMapMode = GetShell()->GetWin()->GetMapMode(); 3627 if( GetShell()->IsPreView() ) 3628 { 3629 DBG_ASSERT( mpPreview != NULL, "need preview data" ); 3630 3631 mpPreview->AdjustMapMode( aMapMode, _rPoint ); 3632 } 3633 _orMapMode = aMapMode; 3634 } 3635 3636 /** get size of a dedicated preview page 3637 3638 OD 15.01.2003 #103492# 3639 3640 @author OD 3641 */ 3642 Size SwAccessibleMap::GetPreViewPageSize( sal_uInt16 _nPrevwPageNum ) const 3643 { 3644 DBG_ASSERT( mpVSh->IsPreView(), "no page preview accessible." ); 3645 DBG_ASSERT( mpVSh->IsPreView() && ( mpPreview != NULL ), 3646 "missing accessible preview data at page preview" ); 3647 if ( mpVSh->IsPreView() && ( mpPreview != NULL ) ) 3648 { 3649 return mpVSh->PagePreviewLayout()->GetPrevwPageSizeByPageNum( _nPrevwPageNum ); 3650 } 3651 else 3652 { 3653 return Size( 0, 0 ); 3654 } 3655 } 3656 3657 /** method to build up a new data structure of the accessible pararaphs, 3658 which have a selection 3659 3660 OD 2005-12-13 #i27301# 3661 Important note: method has to used inside a mutual exclusive section 3662 3663 @author OD 3664 */ 3665 SwAccessibleSelectedParas_Impl* SwAccessibleMap::_BuildSelectedParas() 3666 { 3667 // no accessible contexts, no selection 3668 if ( !mpFrmMap ) 3669 { 3670 return 0L; 3671 } 3672 3673 // get cursor as an instance of its base class <SwPaM> 3674 SwPaM* pCrsr( 0L ); 3675 { 3676 SwCrsrShell* pCrsrShell = dynamic_cast<SwCrsrShell*>(GetShell()); 3677 if ( pCrsrShell ) 3678 { 3679 SwFEShell* pFEShell = dynamic_cast<SwFEShell*>(pCrsrShell); 3680 if ( !pFEShell || 3681 ( !pFEShell->IsFrmSelected() && 3682 pFEShell->IsObjSelected() == 0 ) ) 3683 { 3684 // get cursor without updating an existing table cursor. 3685 pCrsr = pCrsrShell->GetCrsr( sal_False ); 3686 } 3687 } 3688 } 3689 // no cursor, no selection 3690 if ( !pCrsr ) 3691 { 3692 return 0L; 3693 } 3694 3695 SwAccessibleSelectedParas_Impl* pRetSelectedParas( 0L ); 3696 3697 // loop on all cursors 3698 SwPaM* pRingStart = pCrsr; 3699 do { 3700 3701 // for a selection the cursor has to have a mark. 3702 // for savety reasons assure that point and mark are in text nodes 3703 if ( pCrsr->HasMark() && 3704 pCrsr->GetPoint()->nNode.GetNode().IsTxtNode() && 3705 pCrsr->GetMark()->nNode.GetNode().IsTxtNode() ) 3706 { 3707 SwPosition* pStartPos = pCrsr->Start(); 3708 SwPosition* pEndPos = pCrsr->End(); 3709 // loop on all text nodes inside the selection 3710 SwNodeIndex aIdx( pStartPos->nNode ); 3711 for ( ; aIdx.GetIndex() <= pEndPos->nNode.GetIndex(); ++aIdx ) 3712 { 3713 SwTxtNode* pTxtNode( aIdx.GetNode().GetTxtNode() ); 3714 if ( pTxtNode ) 3715 { 3716 // loop on all text frames registered at the text node. 3717 SwIterator<SwTxtFrm,SwTxtNode> aIter( *pTxtNode ); 3718 for( SwTxtFrm* pTxtFrm = aIter.First(); pTxtFrm; pTxtFrm = aIter.Next() ) 3719 { 3720 uno::WeakReference < XAccessible > xWeakAcc; 3721 SwAccessibleContextMap_Impl::iterator aMapIter = 3722 mpFrmMap->find( pTxtFrm ); 3723 if( aMapIter != mpFrmMap->end() ) 3724 { 3725 xWeakAcc = (*aMapIter).second; 3726 SwAccessibleParaSelection aDataEntry( 3727 pTxtNode == &(pStartPos->nNode.GetNode()) 3728 ? pStartPos->nContent.GetIndex() 3729 : 0, 3730 pTxtNode == &(pEndPos->nNode.GetNode()) 3731 ? pEndPos->nContent.GetIndex() 3732 : STRING_LEN ); 3733 SwAccessibleSelectedParas_Impl::value_type 3734 aEntry( xWeakAcc, aDataEntry ); 3735 if ( !pRetSelectedParas ) 3736 { 3737 pRetSelectedParas = 3738 new SwAccessibleSelectedParas_Impl; 3739 } 3740 pRetSelectedParas->insert( aEntry ); 3741 } 3742 } 3743 } 3744 } 3745 } 3746 3747 // prepare next turn: get next cursor in ring 3748 pCrsr = static_cast<SwPaM*>( pCrsr->GetNext() ); 3749 } while ( pCrsr != pRingStart ); 3750 3751 return pRetSelectedParas; 3752 } 3753 3754 /** invalidation of text selection of all paragraphs 3755 3756 OD 2005-12-13 #i27301# 3757 3758 @author OD 3759 */ 3760 void SwAccessibleMap::InvalidateTextSelectionOfAllParas() 3761 { 3762 vos::OGuard aGuard( maMutex ); 3763 3764 // keep previously known selected paragraphs 3765 SwAccessibleSelectedParas_Impl* pPrevSelectedParas( mpSelectedParas ); 3766 3767 // determine currently selected paragraphs 3768 mpSelectedParas = _BuildSelectedParas(); 3769 3770 // compare currently selected paragraphs with the previously selected 3771 // paragraphs and submit corresponding TEXT_SELECTION_CHANGED events. 3772 // first, search for new and changed selections. 3773 // on the run remove selections from previously known ones, if they are 3774 // also in the current ones. 3775 if ( mpSelectedParas ) 3776 { 3777 SwAccessibleSelectedParas_Impl::iterator aIter = mpSelectedParas->begin(); 3778 for ( ; aIter != mpSelectedParas->end(); ++aIter ) 3779 { 3780 bool bSubmitEvent( false ); 3781 if ( !pPrevSelectedParas ) 3782 { 3783 // new selection 3784 bSubmitEvent = true; 3785 } 3786 else 3787 { 3788 SwAccessibleSelectedParas_Impl::iterator aPrevSelected = 3789 pPrevSelectedParas->find( (*aIter).first ); 3790 if ( aPrevSelected != pPrevSelectedParas->end() ) 3791 { 3792 // check, if selection has changed 3793 if ( (*aIter).second.nStartOfSelection != 3794 (*aPrevSelected).second.nStartOfSelection || 3795 (*aIter).second.nEndOfSelection != 3796 (*aPrevSelected).second.nEndOfSelection ) 3797 { 3798 // changed selection 3799 bSubmitEvent = true; 3800 } 3801 pPrevSelectedParas->erase( aPrevSelected ); 3802 } 3803 else 3804 { 3805 // new selection 3806 bSubmitEvent = true; 3807 } 3808 } 3809 3810 if ( bSubmitEvent ) 3811 { 3812 uno::Reference < XAccessible > xAcc( (*aIter).first ); 3813 if ( xAcc.is() ) 3814 { 3815 ::vos::ORef < SwAccessibleContext > xAccImpl( 3816 static_cast<SwAccessibleContext*>( xAcc.get() ) ); 3817 if ( xAccImpl.isValid() && xAccImpl->GetFrm() ) 3818 { 3819 const SwTxtFrm* pTxtFrm( 3820 dynamic_cast<const SwTxtFrm*>(xAccImpl->GetFrm()) ); 3821 ASSERT( pTxtFrm, 3822 "<SwAccessibleMap::_SubmitTextSelectionChangedEvents()> - unexcepted type of frame" ); 3823 if ( pTxtFrm ) 3824 { 3825 InvalidateParaTextSelection( *pTxtFrm ); 3826 } 3827 } 3828 } 3829 } 3830 } 3831 } 3832 3833 // second, handle previous selections - after the first step the data 3834 // structure of the previously known only contains the 'old' selections 3835 if ( pPrevSelectedParas ) 3836 { 3837 SwAccessibleSelectedParas_Impl::iterator aIter = pPrevSelectedParas->begin(); 3838 for ( ; aIter != pPrevSelectedParas->end(); ++aIter ) 3839 { 3840 uno::Reference < XAccessible > xAcc( (*aIter).first ); 3841 if ( xAcc.is() ) 3842 { 3843 ::vos::ORef < SwAccessibleContext > xAccImpl( 3844 static_cast<SwAccessibleContext*>( xAcc.get() ) ); 3845 if ( xAccImpl.isValid() && xAccImpl->GetFrm() ) 3846 { 3847 const SwTxtFrm* pTxtFrm( 3848 dynamic_cast<const SwTxtFrm*>(xAccImpl->GetFrm()) ); 3849 ASSERT( pTxtFrm, 3850 "<SwAccessibleMap::_SubmitTextSelectionChangedEvents()> - unexcepted type of frame" ); 3851 if ( pTxtFrm ) 3852 { 3853 InvalidateParaTextSelection( *pTxtFrm ); 3854 } 3855 } 3856 } 3857 } 3858 3859 delete pPrevSelectedParas; 3860 } 3861 } 3862 3863 const SwRect& SwAccessibleMap::GetVisArea() const 3864 { 3865 DBG_ASSERT( !GetShell()->IsPreView() || (mpPreview != NULL), 3866 "preview without preview data?" ); 3867 3868 return GetShell()->IsPreView() 3869 ? mpPreview->GetVisArea() 3870 : GetShell()->VisArea(); 3871 } 3872 3873 //IAccessibility2 Implementation 2009----- 3874 sal_Bool SwAccessibleMap::IsDocumentSelAll() 3875 { 3876 return GetShell()->GetDoc()->IsPrepareSelAll(); 3877 } 3878 //-----IAccessibility2 Implementation 2009 3879 3880