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