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