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