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