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