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