xref: /AOO41X/main/sw/source/core/access/accmap.cxx (revision 903863900ce516b8d0e6faea1067a0fc394c398f)
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 {
operator ()SwFrmFunc96     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 
SwAccessibleContextMap_Impl()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 
SwDrawModellListener_Impl(SdrModel * pDrawModel)142 SwDrawModellListener_Impl::SwDrawModellListener_Impl( SdrModel *pDrawModel ) :
143     maEventListeners( maListenerMutex ),
144     mpDrawModel( pDrawModel )
145 {
146     StartListening( *mpDrawModel );
147 }
148 
~SwDrawModellListener_Impl()149 SwDrawModellListener_Impl::~SwDrawModellListener_Impl()
150 {
151     EndListening( *mpDrawModel );
152 }
153 
addEventListener(const uno::Reference<document::XEventListener> & xListener)154 void SAL_CALL SwDrawModellListener_Impl::addEventListener( const uno::Reference< document::XEventListener >& xListener ) throw (uno::RuntimeException)
155 {
156     maEventListeners.addInterface( xListener );
157 }
158 
removeEventListener(const uno::Reference<document::XEventListener> & xListener)159 void SAL_CALL SwDrawModellListener_Impl::removeEventListener( const uno::Reference< document::XEventListener >& xListener ) throw (uno::RuntimeException)
160 {
161     maEventListeners.removeInterface( xListener );
162 }
163 
Notify(SfxBroadcaster &,const SfxHint & rHint)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 
Dispose()212 void SwDrawModellListener_Impl::Dispose()
213 {
214     mpDrawModel = 0;
215 }
216 
217 //------------------------------------------------------------------------------
218 struct SwShapeFunc
219 {
operator ()SwShapeFunc220     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
SwAccessibleShapeMap_Impl(SwAccessibleMap * pMap)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 
GetInfo() const257     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 
~SwAccessibleShapeMap_Impl()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
Copy(size_t & rSize,const SwFEShell * pFESh,SwAccessibleObjShape_Impl ** pSelStart) const272     *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
IsNoXaccParentFrmSwAccessibleEvent_Impl353     sal_Bool IsNoXaccParentFrm() const
354     {
355         return CHILD_POS_CHANGED == meType && mpParentFrm != 0;
356     }
GetxAccSwAccessibleEvent_Impl357     uno::WeakReference < XAccessible > GetxAcc() const { return mxAcc;}
358 public:
SwAccessibleEvent_ImplSwAccessibleEvent_Impl359     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 
SwAccessibleEvent_ImplSwAccessibleEvent_Impl369     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 
SwAccessibleEvent_ImplSwAccessibleEvent_Impl380     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 
SwAccessibleEvent_ImplSwAccessibleEvent_Impl389     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>
SwAccessibleEvent_ImplSwAccessibleEvent_Impl406     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 
SwAccessibleEvent_ImplSwAccessibleEvent_Impl420     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(..)>
SetTypeSwAccessibleEvent_Impl434     inline void SetType( EventType eT )
435     {
436         meType = eT;
437     }
GetTypeSwAccessibleEvent_Impl438     inline EventType GetType() const
439     {
440         return meType;
441     }
442 
GetContextSwAccessibleEvent_Impl443     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 
GetOldBoxSwAccessibleEvent_Impl452     inline const SwRect& GetOldBox() const
453     {
454         return maOldBox;
455     }
456     // <SetOldBox(..)> only used in method <SwAccessibleMap::AppendEvent(..)>
SetOldBoxSwAccessibleEvent_Impl457     inline void SetOldBox( const SwRect& rOldBox )
458     {
459         maOldBox = rOldBox;
460     }
461 
GetFrmOrObjSwAccessibleEvent_Impl462     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>
SetStatesSwAccessibleEvent_Impl469     inline void SetStates( tAccessibleStates _nStates )
470     {
471         mnStates |= _nStates;
472     }
473     // <--
474 
IsUpdateCursorPosSwAccessibleEvent_Impl475     inline sal_Bool IsUpdateCursorPos() const
476     {
477         return (mnStates & ACC_STATE_CARET) != 0;
478     }
IsInvalidateStatesSwAccessibleEvent_Impl479     inline sal_Bool IsInvalidateStates() const
480     {
481         return (mnStates & ACC_STATE_MASK) != 0;
482     }
IsInvalidateRelationSwAccessibleEvent_Impl483     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
IsInvalidateTextSelectionSwAccessibleEvent_Impl488     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
IsInvalidateTextAttrsSwAccessibleEvent_Impl494     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
GetStatesSwAccessibleEvent_Impl501     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
GetAllStatesSwAccessibleEvent_Impl508     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 
SwAccessibleEventList_Impl()524     SwAccessibleEventList_Impl()
525         : mbFiring( sal_False )
526     {}
527 
SetFiring()528     inline void SetFiring()
529     {
530         mbFiring = sal_True;
531     }
IsFiring() const532     inline sal_Bool IsFiring() const
533     {
534         return mbFiring;
535     }
536     struct XAccisNULL
537     {
operator ()SwAccessibleEventList_Impl::XAccisNULL538         bool operator()(const SwAccessibleEvent_Impl& e)
539         {
540             return e.IsNoXaccParentFrm();
541         }
542     };
543     void MoveInvalidXAccToEnd();
544 };
545 
MoveInvalidXAccToEnd()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 
SwShapeList_Impl()591     SwShapeList_Impl() {}
592 };
593 
594 
595 //------------------------------------------------------------------------------
596 struct SwAccessibleChildFunc
597 {
operator ()SwAccessibleChildFunc598     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 
SwAccessibleParaSelectionSwAccessibleParaSelection630     SwAccessibleParaSelection( const xub_StrLen _nStartOfSelection,
631                                const xub_StrLen _nEndOfSelection )
632         : nStartOfSelection( _nStartOfSelection ),
633           nEndOfSelection( _nEndOfSelection )
634     {}
635 };
636 
637 struct SwXAccWeakRefComp
638 {
operator ()SwXAccWeakRefComp639     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 
GetSelPage() const716     inline const SwPageFrm *GetSelPage() const { return mpSelPage; }
717 
718     void DisposePage(const SwPageFrm *pPageFrm );
719 };
720 
SwAccPreviewData()721 SwAccPreviewData::SwAccPreviewData() :
722     mpSelPage( 0 )
723 {
724 }
725 
~SwAccPreviewData()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.
Update(const SwAccessibleMap & rAccMap,const std::vector<PrevwPage * > & _rPrevwPages,const Fraction & _rScale,const SwPageFrm * _pSelectedPageFrm,const Size & _rPrevwWinSize)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.
InvalidateSelection(const SwPageFrm * _pSelectedPageFrm)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;
ContainsPredicateContainsPredicate792     ContainsPredicate( const Point& rPoint ) : mrPoint(rPoint) {}
operator ()ContainsPredicate793     bool operator() ( const Rectangle& rRect ) const
794     {
795         return rRect.IsInside( mrPoint ) ? true : false;
796     }
797 };
798 
GetVisArea() const799 const SwRect& SwAccPreviewData::GetVisArea() const
800 {
801     return maVisArea;
802 }
803 
AdjustMapMode(MapMode & rMapMode,const Point & rPoint) const804 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 
DisposePage(const SwPageFrm * pPageFrm)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 */
AdjustLogicPgRectToVisibleArea(SwRect & _iorLogicPgSwRect,const SwRect & _rPrevwPgSwRect,const Size & _rPrevwWinSize)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 //------------------------------------------------------------------------------
AreInSameTable(const uno::Reference<XAccessible> & rAcc,const SwFrm * pFrm)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 
FireEvent(const SwAccessibleEvent_Impl & rEvent)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 
AppendEvent(const SwAccessibleEvent_Impl & rEvent)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 
InvalidateCursorPosition(const uno::Reference<XAccessible> & rAcc)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 
InvalidateShapeSelection()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.
InvalidateShapeInParaSelection()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
DoInvalidateShapeSelection(sal_Bool bInvalidateFocusMode)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 
SwAccessibleMap(ViewShell * pSh)1691 SwAccessibleMap::SwAccessibleMap( ViewShell *pSh ) :
1692     mpFrmMap( 0  ),
1693     mpShapeMap( 0  ),
1694     mpShapes( 0  ),
1695     mpEvents( 0  ),
1696     mpEventMap( 0  ),
1697     // --> OD 2005-12-13 #i27301#
1698     mpSelectedParas( 0 ),
1699     // <--
1700     mpVSh( pSh ),
1701         mpPreview( 0 ),
1702     mnPara( 1 ),
1703     mnFootnote( 1 ),
1704     mnEndnote( 1 ),
1705     mbShapeSelected( sal_False ),
1706     mpSeletedFrmMap(NULL)
1707 {
1708     pSh->GetLayout()->AddAccessibleShell();
1709 }
1710 
~SwAccessibleMap()1711 SwAccessibleMap::~SwAccessibleMap()
1712 {
1713     uno::Reference < XAccessible > xAcc;
1714     {
1715         vos::OGuard aGuard( maMutex );
1716         if( mpFrmMap )
1717         {
1718             const SwRootFrm *pRootFrm = GetShell()->GetLayout();
1719             SwAccessibleContextMap_Impl::iterator aIter = mpFrmMap->find( pRootFrm );
1720             if( aIter != mpFrmMap->end() )
1721                 xAcc = (*aIter).second;
1722             if( !xAcc.is() )
1723                 xAcc = new SwAccessibleDocument( this );
1724         }
1725     }
1726 
1727     if(xAcc.is())
1728     {
1729     SwAccessibleDocument *pAcc =
1730         static_cast< SwAccessibleDocument * >( xAcc.get() );
1731     pAcc->Dispose( sal_True );
1732     }
1733     if( mpFrmMap )
1734     {
1735         SwAccessibleContextMap_Impl::iterator aIter = mpFrmMap->begin();
1736         while( aIter != mpFrmMap->end() )
1737         {
1738             uno::Reference < XAccessible > xTmp = (*aIter).second;
1739             if( xTmp.is() )
1740             {
1741                 SwAccessibleContext *pTmp = static_cast< SwAccessibleContext * >( xTmp.get() );
1742                 pTmp->SetMap(NULL);
1743             }
1744             ++aIter;
1745         }
1746     }
1747     {
1748         vos::OGuard aGuard( maMutex );
1749 #ifdef DBG_UTIL
1750         ASSERT( !mpFrmMap || mpFrmMap->empty(),
1751                 "Frame map should be empty after disposing the root frame" );
1752         if( mpFrmMap )
1753         {
1754             SwAccessibleContextMap_Impl::iterator aIter = mpFrmMap->begin();
1755             while( aIter != mpFrmMap->end() )
1756             {
1757                 uno::Reference < XAccessible > xTmp = (*aIter).second;
1758                 if( xTmp.is() )
1759                 {
1760                     SwAccessibleContext *pTmp =
1761                         static_cast< SwAccessibleContext * >( xTmp.get() );
1762                     (void) pTmp;
1763                 }
1764                 ++aIter;
1765             }
1766         }
1767         ASSERT( !mpShapeMap || mpShapeMap->empty(),
1768                 "Object map should be empty after disposing the root frame" );
1769         if( mpShapeMap )
1770         {
1771             SwAccessibleShapeMap_Impl::iterator aIter = mpShapeMap->begin();
1772             while( aIter != mpShapeMap->end() )
1773             {
1774                 uno::Reference < XAccessible > xTmp = (*aIter).second;
1775                 if( xTmp.is() )
1776                 {
1777                     ::accessibility::AccessibleShape *pTmp =
1778                         static_cast< ::accessibility::AccessibleShape* >( xTmp.get() );
1779                     (void) pTmp;
1780                 }
1781                 ++aIter;
1782             }
1783         }
1784 #endif
1785         delete mpFrmMap;
1786         mpFrmMap = 0;
1787         delete mpShapeMap;
1788         mpShapeMap = 0;
1789         delete mpShapes;
1790         mpShapes = 0;
1791         // --> OD 2005-12-13 #i27301#
1792         delete mpSelectedParas;
1793         mpSelectedParas = 0;
1794         // <--
1795     }
1796 
1797     delete mpPreview;
1798     mpPreview = NULL;
1799 
1800     {
1801         vos::OGuard aGuard( maEventMutex );
1802 #ifdef DBG_UTIL
1803         ASSERT( !(mpEvents || mpEventMap), "pending events" );
1804         if( mpEvents )
1805         {
1806             SwAccessibleEventList_Impl::iterator aIter = mpEvents->begin();
1807             while( aIter != mpEvents->end() )
1808             {
1809                 ++aIter;
1810             }
1811         }
1812         if( mpEventMap )
1813         {
1814             SwAccessibleEventMap_Impl::iterator aIter = mpEventMap->begin();
1815             while( aIter != mpEventMap->end() )
1816             {
1817                 ++aIter;
1818             }
1819         }
1820 #endif
1821         delete mpEventMap;
1822         mpEventMap = 0;
1823         delete mpEvents;
1824         mpEvents = 0;
1825     }
1826     mpVSh->GetLayout()->RemoveAccessibleShell();
1827     delete mpSeletedFrmMap;
1828 }
1829 
_GetDocumentView(sal_Bool bPagePreview)1830 uno::Reference< XAccessible > SwAccessibleMap::_GetDocumentView(
1831     sal_Bool bPagePreview )
1832 {
1833     uno::Reference < XAccessible > xAcc;
1834     sal_Bool bSetVisArea = sal_False;
1835 
1836     {
1837         vos::OGuard aGuard( maMutex );
1838 
1839         if( !mpFrmMap )
1840         {
1841             mpFrmMap = new SwAccessibleContextMap_Impl;
1842 #ifdef DBG_UTIL
1843             mpFrmMap->mbLocked = sal_False;
1844 #endif
1845         }
1846 
1847 #ifdef DBG_UTIL
1848         ASSERT( !mpFrmMap->mbLocked, "Map is locked" );
1849         mpFrmMap->mbLocked = sal_True;
1850 #endif
1851 
1852         const SwRootFrm *pRootFrm = GetShell()->GetLayout();
1853         SwAccessibleContextMap_Impl::iterator aIter = mpFrmMap->find( pRootFrm );
1854         if( aIter != mpFrmMap->end() )
1855             xAcc = (*aIter).second;
1856         if( xAcc.is() )
1857         {
1858             bSetVisArea = sal_True; // Set VisArea when map mutex is not
1859                                     // locked
1860         }
1861         else
1862         {
1863             if( bPagePreview )
1864                 xAcc = new SwAccessiblePreview( this );
1865             else
1866                 xAcc = new SwAccessibleDocument( this );
1867 
1868             if( aIter != mpFrmMap->end() )
1869             {
1870                 (*aIter).second = xAcc;
1871             }
1872             else
1873             {
1874                 SwAccessibleContextMap_Impl::value_type aEntry( pRootFrm, xAcc );
1875                 mpFrmMap->insert( aEntry );
1876             }
1877         }
1878 
1879 #ifdef DBG_UTIL
1880         mpFrmMap->mbLocked = sal_False;
1881 #endif
1882     }
1883 
1884     if( bSetVisArea )
1885     {
1886         SwAccessibleDocumentBase *pAcc =
1887             static_cast< SwAccessibleDocumentBase * >( xAcc.get() );
1888         pAcc->SetVisArea();
1889     }
1890 
1891     return xAcc;
1892 }
1893 
GetDocumentView()1894 uno::Reference< XAccessible > SwAccessibleMap::GetDocumentView( )
1895 {
1896     return _GetDocumentView( sal_False );
1897 }
1898 
1899 // OD 14.01.2003 #103492# - complete re-factoring of method due to new page/print
1900 // preview functionality.
GetDocumentPreview(const std::vector<PrevwPage * > & _rPrevwPages,const Fraction & _rScale,const SwPageFrm * _pSelectedPageFrm,const Size & _rPrevwWinSize)1901 uno::Reference<XAccessible> SwAccessibleMap::GetDocumentPreview(
1902                                     const std::vector<PrevwPage*>& _rPrevwPages,
1903                                     const Fraction&  _rScale,
1904                                     const SwPageFrm* _pSelectedPageFrm,
1905                                     const Size&      _rPrevwWinSize )
1906 {
1907     // create & update preview data object
1908     if( mpPreview == NULL )
1909         mpPreview = new SwAccPreviewData();
1910     mpPreview->Update( *this, _rPrevwPages, _rScale, _pSelectedPageFrm, _rPrevwWinSize );
1911 
1912     uno::Reference<XAccessible> xAcc = _GetDocumentView( sal_True );
1913     return xAcc;
1914 }
1915 
GetContext(const SwFrm * pFrm,sal_Bool bCreate)1916 uno::Reference< XAccessible> SwAccessibleMap::GetContext( const SwFrm *pFrm,
1917                                                      sal_Bool bCreate )
1918 {
1919     uno::Reference < XAccessible > xAcc;
1920     uno::Reference < XAccessible > xOldCursorAcc;
1921     sal_Bool bOldShapeSelected = sal_False;
1922 
1923     {
1924         vos::OGuard aGuard( maMutex );
1925 
1926         if( !mpFrmMap && bCreate )
1927             mpFrmMap = new SwAccessibleContextMap_Impl;
1928         if( mpFrmMap )
1929         {
1930             SwAccessibleContextMap_Impl::iterator aIter = mpFrmMap->find( pFrm );
1931             if( aIter != mpFrmMap->end() )
1932                 xAcc = (*aIter).second;
1933 
1934             if( !xAcc.is() && bCreate )
1935             {
1936                 SwAccessibleContext *pAcc = 0;
1937                 switch( pFrm->GetType() )
1938                 {
1939                 case FRM_TXT:
1940                     mnPara++;
1941                     pAcc = new SwAccessibleParagraph( *this,
1942                                     static_cast< const SwTxtFrm& >( *pFrm ) );
1943                     break;
1944                 case FRM_HEADER:
1945                     pAcc = new SwAccessibleHeaderFooter( this,
1946                                     static_cast< const SwHeaderFrm *>( pFrm ) );
1947                     break;
1948                 case FRM_FOOTER:
1949                     pAcc = new SwAccessibleHeaderFooter( this,
1950                                     static_cast< const SwFooterFrm *>( pFrm ) );
1951                     break;
1952                 case FRM_FTN:
1953                     {
1954                         const SwFtnFrm *pFtnFrm =
1955                             static_cast < const SwFtnFrm * >( pFrm );
1956                         sal_Bool bIsEndnote =
1957                             SwAccessibleFootnote::IsEndnote( pFtnFrm );
1958                         pAcc = new SwAccessibleFootnote( this, bIsEndnote,
1959                                     /*(bIsEndnote ? mnEndnote++ : mnFootnote++),*/
1960                                     pFtnFrm );
1961                     }
1962                     break;
1963                 case FRM_FLY:
1964                     {
1965                         const SwFlyFrm *pFlyFrm =
1966                             static_cast < const SwFlyFrm * >( pFrm );
1967                         switch( SwAccessibleFrameBase::GetNodeType( pFlyFrm ) )
1968                         {
1969                         case ND_GRFNODE:
1970                             pAcc = new SwAccessibleGraphic( this, pFlyFrm );
1971                             break;
1972                         case ND_OLENODE:
1973                             pAcc = new SwAccessibleEmbeddedObject( this, pFlyFrm );
1974                             break;
1975                         default:
1976                             pAcc = new SwAccessibleTextFrame( this, pFlyFrm );
1977                             break;
1978                         }
1979                     }
1980                     break;
1981                 case FRM_CELL:
1982                     pAcc = new SwAccessibleCell( this,
1983                                     static_cast< const SwCellFrm *>( pFrm ) );
1984                     break;
1985                 case FRM_TAB:
1986                     pAcc = new SwAccessibleTable( this,
1987                                     static_cast< const SwTabFrm *>( pFrm ) );
1988                     break;
1989                 case FRM_PAGE:
1990                     DBG_ASSERT( GetShell()->IsPreView(),
1991                                 "accessible page frames only in PagePreview" );
1992                     pAcc = new SwAccessiblePage( this, pFrm );
1993                     break;
1994                 }
1995                 xAcc = pAcc;
1996 
1997                 ASSERT( xAcc.is(), "unknown frame type" );
1998                 if( xAcc.is() )
1999                 {
2000                     if( aIter != mpFrmMap->end() )
2001                     {
2002                         (*aIter).second = xAcc;
2003                     }
2004                     else
2005                     {
2006                         SwAccessibleContextMap_Impl::value_type aEntry( pFrm, xAcc );
2007                         mpFrmMap->insert( aEntry );
2008                     }
2009 
2010                     if( pAcc->HasCursor() &&
2011                         !AreInSameTable( mxCursorContext, pFrm ) )
2012                     {
2013                         // If the new context has the focus, and if we know
2014                         // another context that had the focus, then the focus
2015                         // just moves from the old context to the new one. We
2016                         // have to send a focus event and a caret event for
2017                         // the old context then. We have to to that know,
2018                         // because after we have left this method, anyone might
2019                         // call getStates for the new context and will get a
2020                         // focused state then. Sending the focus changes event
2021                         // after that seems to be strange. However, we cannot
2022                         // send a focus event fo the new context now, because
2023                         // noone except us knows it. In any case, we remeber
2024                         // the new context as the one that has the focus
2025                         // currently.
2026 
2027                         xOldCursorAcc = mxCursorContext;
2028                         mxCursorContext = xAcc;
2029 
2030                         bOldShapeSelected = mbShapeSelected;
2031                         mbShapeSelected = sal_False;
2032                     }
2033                 }
2034             }
2035         }
2036     }
2037 
2038     // Invalidate focus for old object when map is not locked
2039     if( xOldCursorAcc.is() )
2040         InvalidateCursorPosition( xOldCursorAcc );
2041     if( bOldShapeSelected )
2042         InvalidateShapeSelection();
2043 
2044     return xAcc;
2045 }
2046 
GetContextImpl(const SwFrm * pFrm,sal_Bool bCreate)2047 ::vos::ORef < SwAccessibleContext > SwAccessibleMap::GetContextImpl(
2048             const SwFrm *pFrm,
2049             sal_Bool bCreate )
2050 {
2051     uno::Reference < XAccessible > xAcc( GetContext( pFrm, bCreate ) );
2052 
2053     ::vos::ORef < SwAccessibleContext > xAccImpl(
2054          static_cast< SwAccessibleContext * >( xAcc.get() ) );
2055 
2056     return xAccImpl;
2057 }
2058 
GetContext(const SdrObject * pObj,SwAccessibleContext * pParentImpl,sal_Bool bCreate)2059 uno::Reference< XAccessible> SwAccessibleMap::GetContext(
2060         const SdrObject *pObj,
2061         SwAccessibleContext *pParentImpl,
2062         sal_Bool bCreate )
2063 {
2064     uno::Reference < XAccessible > xAcc;
2065     uno::Reference < XAccessible > xOldCursorAcc;
2066 
2067     {
2068         vos::OGuard aGuard( maMutex );
2069 
2070         if( !mpShapeMap && bCreate )
2071             mpShapeMap = new SwAccessibleShapeMap_Impl( this );
2072         if( mpShapeMap )
2073         {
2074             SwAccessibleShapeMap_Impl::iterator aIter =
2075                 mpShapeMap->find( pObj );
2076             if( aIter != mpShapeMap->end() )
2077                 xAcc = (*aIter).second;
2078 
2079             if( !xAcc.is() && bCreate )
2080             {
2081                 ::accessibility::AccessibleShape *pAcc = 0;
2082                 uno::Reference < drawing::XShape > xShape(
2083                     const_cast< SdrObject * >( pObj )->getUnoShape(),
2084                     uno::UNO_QUERY );
2085                 if( xShape.is() )
2086                 {
2087                     ::accessibility::ShapeTypeHandler& rShapeTypeHandler =
2088                                 ::accessibility::ShapeTypeHandler::Instance();
2089                     uno::Reference < XAccessible > xParent( pParentImpl );
2090                     ::accessibility::AccessibleShapeInfo aShapeInfo(
2091                             xShape, xParent, this );
2092 
2093                     pAcc = rShapeTypeHandler.CreateAccessibleObject(
2094                                 aShapeInfo, mpShapeMap->GetInfo() );
2095                 }
2096                 xAcc = pAcc;
2097 
2098                 ASSERT( xAcc.is(), "unknown shape type" );
2099                 if( xAcc.is() )
2100                 {
2101                     pAcc->Init();
2102                     if( aIter != mpShapeMap->end() )
2103                     {
2104                         (*aIter).second = xAcc;
2105                     }
2106                     else
2107                     {
2108                         SwAccessibleShapeMap_Impl::value_type aEntry( pObj,
2109                                                                       xAcc );
2110                         mpShapeMap->insert( aEntry );
2111                     }
2112                     // TODO: focus!!!
2113                 }
2114                 if (xAcc.is())
2115                     AddGroupContext(pObj, xAcc);
2116             }
2117         }
2118     }
2119 
2120     // Invalidate focus for old object when map is not locked
2121     if( xOldCursorAcc.is() )
2122         InvalidateCursorPosition( xOldCursorAcc );
2123 
2124     return xAcc;
2125 }
IsInSameLevel(const SdrObject * pObj,const SwFEShell * pFESh)2126 sal_Bool SwAccessibleMap::IsInSameLevel(const SdrObject* pObj, const SwFEShell* pFESh)
2127 {
2128     if (pFESh)
2129         return pFESh->IsObjSameLevelWithMarked(pObj);
2130     return sal_False;
2131 }
AddShapeContext(const SdrObject * pObj,uno::Reference<XAccessible> xAccShape)2132 void SwAccessibleMap::AddShapeContext(const SdrObject *pObj, uno::Reference < XAccessible > xAccShape)
2133 {
2134     vos::OGuard aGuard( maMutex );
2135 
2136     if( mpShapeMap )
2137     {
2138         SwAccessibleShapeMap_Impl::value_type aEntry( pObj, xAccShape );
2139         mpShapeMap->insert( aEntry );
2140     }
2141 
2142 }
2143 
2144 //Added by yanjun for sym2_6407
RemoveGroupContext(const SdrObject * pParentObj,::com::sun::star::uno::Reference<::com::sun::star::accessibility::XAccessible> xAccParent)2145 void SwAccessibleMap::RemoveGroupContext(const SdrObject *pParentObj, ::com::sun::star::uno::Reference < ::com::sun::star::accessibility::XAccessible > xAccParent)
2146 {
2147     vos::OGuard aGuard( maMutex );
2148     if (mpShapeMap && pParentObj && pParentObj->IsGroupObject() && xAccParent.is())
2149     {
2150         uno::Reference < XAccessibleContext > xContext = xAccParent->getAccessibleContext();
2151         if (xContext.is())
2152         {
2153             for (sal_Int32 i = 0; i < xContext->getAccessibleChildCount(); ++i)
2154             {
2155                 uno::Reference < XAccessible > xChild = xContext->getAccessibleChild(i);
2156                 if (xChild.is())
2157                 {
2158                     uno::Reference < XAccessibleContext > xChildContext = xChild->getAccessibleContext();
2159                     if (xChildContext.is())
2160                     {
2161                         if (xChildContext->getAccessibleRole() == AccessibleRole::SHAPE)
2162                         {
2163                             ::accessibility::AccessibleShape* pAccShape = static_cast < ::accessibility::AccessibleShape* >( xChild.get());
2164                             uno::Reference < drawing::XShape > xShape = pAccShape->GetXShape();
2165                             if (xShape.is())
2166                             {
2167                                 SdrObject* pObj = GetSdrObjectFromXShape(xShape);
2168                                 if (pObj)
2169                                     RemoveContext(pObj);
2170                             }
2171                         }
2172                     }
2173                 }
2174             }
2175         }
2176     }
2177 }
2178 //End
2179 
2180 
AddGroupContext(const SdrObject * pParentObj,uno::Reference<XAccessible> xAccParent)2181 void SwAccessibleMap::AddGroupContext(const SdrObject *pParentObj, uno::Reference < XAccessible > xAccParent)
2182 {
2183     vos::OGuard aGuard( maMutex );
2184     if( mpShapeMap )
2185     {
2186         //here get all the sub list.
2187         if (pParentObj->IsGroupObject())
2188         {
2189             if (xAccParent.is())
2190             {
2191                 uno::Reference < XAccessibleContext > xContext = xAccParent->getAccessibleContext();
2192                 if (xContext.is())
2193                 {
2194                     sal_Int32 nChildren = xContext->getAccessibleChildCount();
2195                     for(sal_Int32 i = 0; i<nChildren; i++)
2196                     {
2197                         uno::Reference < XAccessible > xChild = xContext->getAccessibleChild(i);
2198                         if (xChild.is())
2199                         {
2200                             uno::Reference < XAccessibleContext > xChildContext = xChild->getAccessibleContext();
2201                             if (xChildContext.is())
2202                             {
2203                                 short nRole = xChildContext->getAccessibleRole();
2204                                 if (nRole == AccessibleRole::SHAPE)
2205                                 {
2206                                     ::accessibility::AccessibleShape* pAccShape = static_cast < ::accessibility::AccessibleShape* >( xChild.get());
2207                                     uno::Reference < drawing::XShape > xShape = pAccShape->GetXShape();
2208                                     if (xShape.is())
2209                                     {
2210                                         SdrObject* pObj = GetSdrObjectFromXShape(xShape);
2211                                         AddShapeContext(pObj, xChild);
2212                                         AddGroupContext(pObj,xChild);
2213                                     }
2214                                 }
2215                             }
2216                         }
2217                     }
2218                 }
2219             }
2220         }
2221     }
2222 }
2223 
GetContextImpl(const SdrObject * pObj,SwAccessibleContext * pParentImpl,sal_Bool bCreate)2224 ::vos::ORef < ::accessibility::AccessibleShape > SwAccessibleMap::GetContextImpl(
2225             const SdrObject *pObj,
2226             SwAccessibleContext *pParentImpl,
2227             sal_Bool bCreate )
2228 {
2229     uno::Reference < XAccessible > xAcc( GetContext( pObj, pParentImpl, bCreate ) );
2230 
2231     ::vos::ORef < ::accessibility::AccessibleShape > xAccImpl(
2232          static_cast< ::accessibility::AccessibleShape* >( xAcc.get() ) );
2233 
2234     return xAccImpl;
2235 }
2236 
2237 
RemoveContext(const SwFrm * pFrm)2238 void SwAccessibleMap::RemoveContext( const SwFrm *pFrm )
2239 {
2240     vos::OGuard aGuard( maMutex );
2241 
2242     if( mpFrmMap )
2243     {
2244         SwAccessibleContextMap_Impl::iterator aIter =
2245             mpFrmMap->find( pFrm );
2246         if( aIter != mpFrmMap->end() )
2247         {
2248             mpFrmMap->erase( aIter );
2249 
2250             // Remove reference to old caret object. Though mxCursorContext
2251             // is a weak reference and cleared automatically, clearing it
2252             // directly makes sure to not keep a defunctional object.
2253             uno::Reference < XAccessible > xOldAcc( mxCursorContext );
2254             if( xOldAcc.is() )
2255             {
2256                 SwAccessibleContext *pOldAccImpl =
2257                     static_cast< SwAccessibleContext *>( xOldAcc.get() );
2258                 ASSERT( pOldAccImpl->GetFrm(), "old caret context is disposed" );
2259                 if( pOldAccImpl->GetFrm() == pFrm )
2260                 {
2261                     xOldAcc.clear();    // get an empty ref
2262                     mxCursorContext = xOldAcc;
2263                 }
2264             }
2265 
2266             if( mpFrmMap->empty() )
2267             {
2268                 delete mpFrmMap;
2269                 mpFrmMap = 0;
2270             }
2271         }
2272     }
2273 }
2274 
RemoveContext(const SdrObject * pObj)2275 void SwAccessibleMap::RemoveContext( const SdrObject *pObj )
2276 {
2277     vos::OGuard aGuard( maMutex );
2278 
2279     if( mpShapeMap )
2280     {
2281         SwAccessibleShapeMap_Impl::iterator aIter =
2282             mpShapeMap->find( pObj );
2283         if( aIter != mpShapeMap->end() )
2284         {
2285             uno::Reference < XAccessible > xAcc( (*aIter).second );
2286             mpShapeMap->erase( aIter );
2287             RemoveGroupContext(pObj, xAcc);
2288             // The shape selection flag is not cleared, but one might do
2289             // so but has to make sure that the removed context is the one
2290             // that is selected.
2291 
2292             if( mpShapeMap && mpShapeMap->empty() )
2293             {
2294                 delete mpShapeMap;
2295                 mpShapeMap = 0;
2296             }
2297         }
2298     }
2299 }
2300 
2301 
Dispose(const SwFrm * pFrm,const SdrObject * pObj,Window * pWindow,sal_Bool bRecursive)2302 void SwAccessibleMap::Dispose( const SwFrm *pFrm,
2303                                const SdrObject *pObj,
2304                                Window* pWindow,
2305                                sal_Bool bRecursive )
2306 {
2307     SwAccessibleChild aFrmOrObj( pFrm, pObj, pWindow );
2308 
2309     // Indeed, the following assert checks the frame's accessible flag,
2310     // because that's the one that is evaluated in the layout. The frame
2311     // might not be accessible anyway. That's the case for cell frames that
2312     // contain further cells.
2313     ASSERT( !aFrmOrObj.GetSwFrm() || aFrmOrObj.GetSwFrm()->IsAccessibleFrm(),
2314             "non accessible frame should be disposed" );
2315 
2316     if( aFrmOrObj.IsAccessible( GetShell()->IsPreView() ) )
2317     {
2318         ::vos::ORef< SwAccessibleContext > xAccImpl;
2319         ::vos::ORef< SwAccessibleContext > xParentAccImpl;
2320         ::vos::ORef< ::accessibility::AccessibleShape > xShapeAccImpl;
2321         // get accessible context for frame
2322         {
2323             vos::OGuard aGuard( maMutex );
2324 
2325             // First of all look for an accessible context for a frame
2326             if( aFrmOrObj.GetSwFrm() && mpFrmMap )
2327             {
2328                 SwAccessibleContextMap_Impl::iterator aIter =
2329                     mpFrmMap->find( aFrmOrObj.GetSwFrm() );
2330                 if( aIter != mpFrmMap->end() )
2331                 {
2332                     uno::Reference < XAccessible > xAcc( (*aIter).second );
2333                     xAccImpl =
2334                         static_cast< SwAccessibleContext *>( xAcc.get() );
2335                 }
2336             }
2337             if( !xAccImpl.isValid() && mpFrmMap )
2338             {
2339                 // If there is none, look if the parent is accessible.
2340                 const SwFrm *pParent =
2341                         SwAccessibleFrame::GetParent( aFrmOrObj,
2342                                                       GetShell()->IsPreView());
2343 
2344                 if( pParent )
2345                 {
2346                     SwAccessibleContextMap_Impl::iterator aIter =
2347                         mpFrmMap->find( pParent );
2348                     if( aIter != mpFrmMap->end() )
2349                     {
2350                         uno::Reference < XAccessible > xAcc( (*aIter).second );
2351                         xParentAccImpl =
2352                             static_cast< SwAccessibleContext *>( xAcc.get() );
2353                     }
2354                 }
2355             }
2356             if( !xParentAccImpl.isValid() && !aFrmOrObj.GetSwFrm() &&
2357                 mpShapeMap )
2358             {
2359                 SwAccessibleShapeMap_Impl::iterator aIter =
2360                     mpShapeMap->find( aFrmOrObj.GetDrawObject() );
2361                 if( aIter != mpShapeMap->end() )
2362                 {
2363                     uno::Reference < XAccessible > xAcc( (*aIter).second );
2364                     xShapeAccImpl =
2365                         static_cast< ::accessibility::AccessibleShape *>( xAcc.get() );
2366                 }
2367             }
2368             if( pObj && GetShell()->ActionPend() &&
2369                 (xParentAccImpl.isValid() || xShapeAccImpl.isValid()) )
2370             {
2371                 // Keep a reference to the XShape to avoid that it
2372                 // is deleted with a SwFrmFmt::Modify.
2373                 uno::Reference < drawing::XShape > xShape(
2374                     const_cast< SdrObject * >( pObj )->getUnoShape(),
2375                     uno::UNO_QUERY );
2376                 if( xShape.is() )
2377                 {
2378                     if( !mpShapes )
2379                         mpShapes = new SwShapeList_Impl;
2380                     mpShapes->push_back( xShape );
2381                 }
2382             }
2383         }
2384 
2385         // remove events stored for the frame
2386         {
2387             vos::OGuard aGuard( maEventMutex );
2388             if( mpEvents )
2389             {
2390                 SwAccessibleEventMap_Impl::iterator aIter =
2391                     mpEventMap->find( aFrmOrObj );
2392                 if( aIter != mpEventMap->end() )
2393                 {
2394                     SwAccessibleEvent_Impl aEvent(
2395                             SwAccessibleEvent_Impl::DISPOSE, aFrmOrObj );
2396                     AppendEvent( aEvent );
2397                 }
2398             }
2399         }
2400 
2401         // If the frame is accessible and there is a context for it, dispose
2402         // the frame. If the frame is no context for it but disposing should
2403         // take place recursive, the frame's children have to be disposed
2404         // anyway, so we have to create the context then.
2405         if( xAccImpl.isValid() )
2406         {
2407             xAccImpl->Dispose( bRecursive );
2408         }
2409         else if( xParentAccImpl.isValid() )
2410         {
2411             // If the frame is a cell frame, the table must be notified.
2412             // If we are in an action, a table model change event will
2413             // be broadcasted at the end of the action to give the table
2414             // a chance to generate a single table change event.
2415 
2416             xParentAccImpl->DisposeChild( aFrmOrObj, bRecursive );
2417         }
2418         else if( xShapeAccImpl.isValid() )
2419         {
2420             RemoveContext( aFrmOrObj.GetDrawObject() );
2421             xShapeAccImpl->dispose();
2422         }
2423 
2424         if( mpPreview && pFrm && pFrm->IsPageFrm() )
2425             mpPreview->DisposePage( static_cast< const SwPageFrm *>( pFrm ) );
2426     }
2427 }
2428 
InvalidatePosOrSize(const SwFrm * pFrm,const SdrObject * pObj,Window * pWindow,const SwRect & rOldBox)2429 void SwAccessibleMap::InvalidatePosOrSize( const SwFrm *pFrm,
2430                                            const SdrObject *pObj,
2431                                            Window* pWindow,
2432                                            const SwRect& rOldBox )
2433 {
2434     SwAccessibleChild aFrmOrObj( pFrm, pObj, pWindow );
2435     if( aFrmOrObj.IsAccessible( GetShell()->IsPreView() ) )
2436     {
2437         ::vos::ORef< SwAccessibleContext > xAccImpl;
2438         ::vos::ORef< SwAccessibleContext > xParentAccImpl;
2439         const SwFrm *pParent =NULL;
2440         {
2441             vos::OGuard aGuard( maMutex );
2442 
2443             if( mpFrmMap )
2444             {
2445                 if( aFrmOrObj.GetSwFrm() )
2446                 {
2447                     SwAccessibleContextMap_Impl::iterator aIter =
2448                         mpFrmMap->find( aFrmOrObj.GetSwFrm() );
2449                     if( aIter != mpFrmMap->end() )
2450                     {
2451                         // If there is an accesible object already it is
2452                         // notified directly.
2453                         uno::Reference < XAccessible > xAcc( (*aIter).second );
2454                         xAccImpl =
2455                             static_cast< SwAccessibleContext *>( xAcc.get() );
2456                     }
2457                 }
2458                 if( !xAccImpl.isValid() )
2459                 {
2460                     // Otherwise we look if the parent is accessible.
2461                     // If not, there is nothing to do.
2462                     pParent = SwAccessibleFrame::GetParent( aFrmOrObj,
2463                                                       GetShell()->IsPreView());
2464 
2465                     if( pParent )
2466                     {
2467                         SwAccessibleContextMap_Impl::iterator aIter =
2468                             mpFrmMap->find( pParent );
2469                         if( aIter != mpFrmMap->end() )
2470                         {
2471                             uno::Reference < XAccessible > xAcc( (*aIter).second );
2472                             xParentAccImpl =
2473                                 static_cast< SwAccessibleContext *>( xAcc.get() );
2474                         }
2475                     }
2476                 }
2477             }
2478         }
2479 
2480         if( xAccImpl.isValid() )
2481         {
2482             if( GetShell()->ActionPend() )
2483             {
2484                 SwAccessibleEvent_Impl aEvent(
2485                     SwAccessibleEvent_Impl::POS_CHANGED, xAccImpl.getBodyPtr(),
2486                     aFrmOrObj, rOldBox );
2487                 AppendEvent( aEvent );
2488             }
2489             else
2490             {
2491                 FireEvents();
2492                 xAccImpl->InvalidatePosOrSize( rOldBox );
2493             }
2494         }
2495         else if( xParentAccImpl.isValid() )
2496         {
2497             if( GetShell()->ActionPend() )
2498             {
2499                 SwAccessibleEvent_Impl aEvent(
2500                     SwAccessibleEvent_Impl::CHILD_POS_CHANGED,
2501                     xParentAccImpl.getBodyPtr(), aFrmOrObj, rOldBox );
2502                 AppendEvent( aEvent );
2503             }
2504             else
2505             {
2506                 FireEvents();
2507                 xParentAccImpl->InvalidateChildPosOrSize( aFrmOrObj,
2508                                                           rOldBox );
2509             }
2510         }
2511         else if(pParent)
2512         {
2513 /*
2514 For child graphic and it's parent paragraph,if split 2 graphic to 2 paragraph,
2515 will delete one graphic swfrm and new create 1 graphic swfrm ,
2516 then the new paragraph and the new graphic SwFrm will add .
2517 but when add graphic SwFrm ,the accessible of the new Paragraph is not created yet.
2518 so the new graphic accessible 'parent is NULL,
2519 so run here: save the parent's SwFrm not the accessible object parent,
2520 */
2521             sal_Bool bIsValidFrm = sal_False;
2522             sal_Bool bIsTxtParent = sal_False;
2523             if (aFrmOrObj.GetSwFrm())
2524             {
2525                 int nType = pFrm->GetType();
2526                 if ( FRM_FLY == nType )
2527                 {
2528                     bIsValidFrm =sal_True;
2529                 }
2530             }
2531             else if(pObj)
2532             {
2533                 int nType = pParent->GetType();
2534                 if (FRM_TXT == nType)
2535                 {
2536                     bIsTxtParent =sal_True;
2537                 }
2538             }
2539 //          sal_Bool bIsVisibleChildrenOnly =aFrmOrObj.IsVisibleChildrenOnly() ;
2540 //          sal_Bool bIsBoundAsChar =aFrmOrObj.IsBoundAsChar() ;//bIsVisibleChildrenOnly && bIsBoundAsChar &&
2541             if((bIsValidFrm || bIsTxtParent) )
2542             {
2543                 if( GetShell()->ActionPend() )
2544                 {
2545                     SwAccessibleEvent_Impl aEvent(
2546                         SwAccessibleEvent_Impl::CHILD_POS_CHANGED,
2547                         pParent, aFrmOrObj, rOldBox );
2548                     AppendEvent( aEvent );
2549                 }
2550                 else
2551                 {
2552                     OSL_ENSURE(false,"");
2553                 }
2554             }
2555         }
2556     }
2557 }
2558 
InvalidateContent(const SwFrm * pFrm)2559 void SwAccessibleMap::InvalidateContent( const SwFrm *pFrm )
2560 {
2561     SwAccessibleChild aFrmOrObj( pFrm );
2562     if( aFrmOrObj.IsAccessible( GetShell()->IsPreView() ) )
2563     {
2564         uno::Reference < XAccessible > xAcc;
2565         {
2566             vos::OGuard aGuard( maMutex );
2567 
2568             if( mpFrmMap )
2569             {
2570                 SwAccessibleContextMap_Impl::iterator aIter =
2571                     mpFrmMap->find( aFrmOrObj.GetSwFrm() );
2572                 if( aIter != mpFrmMap->end() )
2573                     xAcc = (*aIter).second;
2574             }
2575         }
2576 
2577         if( xAcc.is() )
2578         {
2579             SwAccessibleContext *pAccImpl =
2580                 static_cast< SwAccessibleContext *>( xAcc.get() );
2581             if( GetShell()->ActionPend() )
2582             {
2583                 SwAccessibleEvent_Impl aEvent(
2584                     SwAccessibleEvent_Impl::INVALID_CONTENT, pAccImpl,
2585                     aFrmOrObj );
2586                 AppendEvent( aEvent );
2587             }
2588             else
2589             {
2590                 FireEvents();
2591                 pAccImpl->InvalidateContent();
2592             }
2593         }
2594     }
2595 }
2596 
2597 // --> OD 2009-01-06 #i88069#
InvalidateAttr(const SwTxtFrm & rTxtFrm)2598 void SwAccessibleMap::InvalidateAttr( const SwTxtFrm& rTxtFrm )
2599 {
2600     SwAccessibleChild aFrmOrObj( &rTxtFrm );
2601     if( aFrmOrObj.IsAccessible( GetShell()->IsPreView() ) )
2602     {
2603         uno::Reference < XAccessible > xAcc;
2604         {
2605             vos::OGuard aGuard( maMutex );
2606 
2607             if( mpFrmMap )
2608             {
2609                 SwAccessibleContextMap_Impl::iterator aIter =
2610                     mpFrmMap->find( aFrmOrObj.GetSwFrm() );
2611                 if( aIter != mpFrmMap->end() )
2612                     xAcc = (*aIter).second;
2613             }
2614         }
2615 
2616         if( xAcc.is() )
2617         {
2618             SwAccessibleContext *pAccImpl =
2619                 static_cast< SwAccessibleContext *>( xAcc.get() );
2620             if( GetShell()->ActionPend() )
2621             {
2622                 SwAccessibleEvent_Impl aEvent( SwAccessibleEvent_Impl::INVALID_ATTR,
2623                                                pAccImpl, aFrmOrObj );
2624                 aEvent.SetStates( ACC_STATE_TEXT_ATTRIBUTE_CHANGED );
2625                 AppendEvent( aEvent );
2626             }
2627             else
2628             {
2629                 FireEvents();
2630                 pAccImpl->InvalidateAttr();
2631             }
2632         }
2633     }
2634 }
2635 // <--
2636 
InvalidateCursorPosition(const SwFrm * pFrm)2637 void SwAccessibleMap::InvalidateCursorPosition( const SwFrm *pFrm )
2638 {
2639     SwAccessibleChild aFrmOrObj( pFrm );
2640     sal_Bool bShapeSelected = sal_False;
2641     const ViewShell *pVSh = GetShell();
2642     if( pVSh->ISA( SwCrsrShell ) )
2643     {
2644         const SwCrsrShell *pCSh = static_cast< const SwCrsrShell * >( pVSh );
2645         if( pCSh->IsTableMode() )
2646         {
2647             while( aFrmOrObj.GetSwFrm() && !aFrmOrObj.GetSwFrm()->IsCellFrm() )
2648                 aFrmOrObj = aFrmOrObj.GetSwFrm()->GetUpper();
2649         }
2650         else if( pVSh->ISA( SwFEShell ) )
2651         {
2652             sal_uInt16 nObjCount;
2653             const SwFEShell *pFESh = static_cast< const SwFEShell * >( pVSh );
2654             const SwFrm *pFlyFrm = pFESh->GetCurrFlyFrm();
2655             if( pFlyFrm )
2656             {
2657                 ASSERT( !pFrm || pFrm->FindFlyFrm() == pFlyFrm,
2658                         "cursor is not contained in fly frame" );
2659                 aFrmOrObj = pFlyFrm;
2660             }
2661             else if( (nObjCount = pFESh->IsObjSelected()) > 0 )
2662             {
2663                 bShapeSelected = sal_True;
2664                 aFrmOrObj = static_cast<const SwFrm *>( 0 );
2665             }
2666         }
2667     }
2668 
2669     ASSERT( bShapeSelected || aFrmOrObj.IsAccessible(GetShell()->IsPreView()),
2670             "frame is not accessible" );
2671 
2672     uno::Reference < XAccessible > xOldAcc;
2673     uno::Reference < XAccessible > xAcc;
2674     sal_Bool bOldShapeSelected = sal_False;
2675 
2676     {
2677         vos::OGuard aGuard( maMutex );
2678 
2679         xOldAcc = mxCursorContext;
2680         mxCursorContext = xAcc; // clear reference
2681 
2682         bOldShapeSelected = mbShapeSelected;
2683         mbShapeSelected = bShapeSelected;
2684 
2685         if( aFrmOrObj.GetSwFrm() && mpFrmMap )
2686         {
2687             SwAccessibleContextMap_Impl::iterator aIter =
2688                 mpFrmMap->find( aFrmOrObj.GetSwFrm() );
2689             if( aIter != mpFrmMap->end() )
2690                 xAcc = (*aIter).second;
2691             else
2692             {
2693                 SwRect rcEmpty;
2694                 const SwTabFrm* pTabFrm = aFrmOrObj.GetSwFrm()->FindTabFrm();
2695                 if (pTabFrm)
2696                 {
2697                     InvalidatePosOrSize(pTabFrm,0,0,rcEmpty);
2698                 }
2699                 else
2700                 {
2701                     InvalidatePosOrSize(aFrmOrObj.GetSwFrm(),0,0,rcEmpty);
2702                 }
2703 
2704 
2705                 aIter =
2706                     mpFrmMap->find( aFrmOrObj.GetSwFrm() );
2707                 if( aIter != mpFrmMap->end() )
2708                 {
2709                     xAcc = (*aIter).second;
2710                 }
2711             }
2712 
2713             // For cells, some extra thoughts are necessary,
2714             // because invalidating the cursor for one cell
2715             // invalidates the cursor for all cells of the same
2716             // table. For this reason, we don't want to
2717             // invalidate the cursor for the old cursor object
2718             // and the new one if they are within the same table,
2719             // because this would result in doing the work twice.
2720             // Moreover, we have to make sure to invalidate the
2721             // cursor even if the current cell has no accessible object.
2722             // If the old cursor objects exists and is in the same
2723             // table, its the best choice, because using it avoids
2724             // an unnessarary cursor invalidation cycle when creating
2725             // a new object for the current cell.
2726             if( aFrmOrObj.GetSwFrm()->IsCellFrm() )
2727             {
2728                 if( xOldAcc.is() &&
2729                     AreInSameTable( xOldAcc, aFrmOrObj.GetSwFrm() ) )
2730                 {
2731                     if( xAcc.is() )
2732                         xOldAcc = xAcc; // avoid extra invalidation
2733                     else
2734                         xAcc = xOldAcc; // make sure ate least one
2735                 }
2736                 if( !xAcc.is() )
2737                     xAcc = GetContext( aFrmOrObj.GetSwFrm(), sal_True );
2738             }
2739         }
2740         else if (bShapeSelected)
2741         {
2742             const SwFEShell *pFESh = pVSh ? static_cast< const SwFEShell * >( pVSh ) : NULL ;
2743             if(pFESh)
2744             {
2745                 const SdrMarkList *pMarkList = pFESh->GetMarkList();
2746                 if (pMarkList != NULL && pMarkList->GetMarkCount() == 1)
2747                 {
2748                     SdrObject *pObj = pMarkList->GetMark( 0 )->GetMarkedSdrObj();
2749                     ::vos::ORef < ::accessibility::AccessibleShape > pAccShapeImpl = GetContextImpl(pObj,NULL,sal_False);
2750                     if (!pAccShapeImpl.isValid())
2751                     {
2752                         while (pObj && pObj->GetUpGroup())
2753                         {
2754                             pObj = pObj->GetUpGroup();
2755                         }
2756                         if (pObj != NULL)
2757                         {
2758                             const SwFrm *pParent = SwAccessibleFrame::GetParent( SwAccessibleChild(pObj), GetShell()->IsPreView() );
2759                             if( pParent )
2760                             {
2761                                 ::vos::ORef< SwAccessibleContext > xParentAccImpl = GetContextImpl(pParent,sal_False);
2762                                 if (!xParentAccImpl.isValid())
2763                                 {
2764                                     const SwTabFrm* pTabFrm = pParent->FindTabFrm();
2765                                     if (pTabFrm)
2766                                     {
2767                                         //The Table should not add in acc.because the "pParent" is not add to acc .
2768                                         uno::Reference< XAccessible>  xAccParentTab = GetContext(pTabFrm,sal_True);//Should Create.
2769 
2770                                         const SwFrm *pParentRoot = SwAccessibleFrame::GetParent( SwAccessibleChild(pTabFrm), GetShell()->IsPreView() );
2771                                         if (pParentRoot)
2772                                         {
2773                                             ::vos::ORef< SwAccessibleContext > xParentAccImplRoot = GetContextImpl(pParentRoot,sal_False);
2774                                             if(xParentAccImplRoot.isValid())
2775                                             {
2776                                                 AccessibleEventObject aEvent;
2777                                                 aEvent.EventId = AccessibleEventId::CHILD;
2778                                                 aEvent.NewValue <<= xAccParentTab;
2779                                                 xParentAccImplRoot->FireAccessibleEvent( aEvent );
2780                                             }
2781                                         }
2782 
2783                                         //Get "pParent" acc again.
2784                                         xParentAccImpl = GetContextImpl(pParent,sal_False);
2785                                     }
2786                                     else
2787                                     {
2788                                         //directly create this acc para .
2789                                         xParentAccImpl = GetContextImpl(pParent,sal_True);//Should Create.
2790 
2791                                         const SwFrm *pParentRoot = SwAccessibleFrame::GetParent( SwAccessibleChild(pParent), GetShell()->IsPreView() );
2792 
2793                                         ::vos::ORef< SwAccessibleContext > xParentAccImplRoot = GetContextImpl(pParentRoot,sal_False);
2794                                         if(xParentAccImplRoot.isValid())
2795                                         {
2796                                             AccessibleEventObject aEvent;
2797                                             aEvent.EventId = AccessibleEventId::CHILD;
2798                                             aEvent.NewValue <<= uno::Reference< XAccessible>(xParentAccImpl.getBodyPtr());
2799                                             xParentAccImplRoot->FireAccessibleEvent( aEvent );
2800                                         }
2801                                     }
2802                                 }
2803                                 if (xParentAccImpl.isValid())
2804                                 {
2805                                     uno::Reference< XAccessible>  xAccShape =
2806                                         GetContext(pObj,xParentAccImpl.getBodyPtr(),sal_True);
2807 
2808                                     AccessibleEventObject aEvent;
2809                                     aEvent.EventId = AccessibleEventId::CHILD;
2810                                     aEvent.NewValue <<= xAccShape;
2811                                     xParentAccImpl->FireAccessibleEvent( aEvent );
2812                                 }
2813                             }
2814                         }
2815                     }
2816                 }
2817             }
2818         }
2819     }
2820 
2821     m_setParaAdd.clear();
2822     m_setParaRemove.clear();
2823     if( xOldAcc.is() && xOldAcc != xAcc )
2824         InvalidateCursorPosition( xOldAcc );
2825     if( bOldShapeSelected || bShapeSelected )
2826         InvalidateShapeSelection();
2827     if( xAcc.is() )
2828         InvalidateCursorPosition( xAcc );
2829 
2830     InvalidateShapeInParaSelection();
2831 
2832     SET_PARA::iterator si = m_setParaRemove.begin();
2833     for (; si != m_setParaRemove.end() ; ++si)
2834     {
2835         SwAccessibleParagraph* pAccPara = *si;
2836         if(pAccPara && pAccPara->getSelectedAccessibleChildCount() == 0 && pAccPara->getSelectedText().getLength() == 0)
2837         {
2838             if(pAccPara->SetSelectedState(sal_False))
2839             {
2840                 AccessibleEventObject aEvent;
2841                 aEvent.EventId = AccessibleEventId::SELECTION_CHANGED_REMOVE;
2842                 pAccPara->FireAccessibleEvent( aEvent );
2843             }
2844         }
2845     }
2846     si = m_setParaAdd.begin();
2847     for (; si != m_setParaAdd.end() ; ++si)
2848     {
2849         SwAccessibleParagraph* pAccPara = *si;
2850         if(pAccPara && pAccPara->SetSelectedState(sal_True))
2851         {
2852             AccessibleEventObject aEvent;
2853             aEvent.EventId = AccessibleEventId::SELECTION_CHANGED;
2854             pAccPara->FireAccessibleEvent( aEvent );
2855         }
2856     }
2857 }
2858 
2859 //Notify the page change event to bridge.
FirePageChangeEvent(sal_uInt16 nOldPage,sal_uInt16 nNewPage)2860 void SwAccessibleMap::FirePageChangeEvent(sal_uInt16 nOldPage, sal_uInt16 nNewPage)
2861 {
2862     uno::Reference<XAccessible> xAcc = GetDocumentView( );
2863         if ( xAcc.is() )
2864         {
2865             SwAccessibleDocumentBase *pAcc =
2866             static_cast< SwAccessibleDocumentBase * >( xAcc.get() );
2867             if (pAcc)
2868             {
2869                 AccessibleEventObject aEvent;
2870                 aEvent.EventId = AccessibleEventId::PAGE_CHANGED;
2871                 aEvent.OldValue <<= nOldPage;
2872                 aEvent.NewValue <<= nNewPage;
2873                 pAcc->FireAccessibleEvent( aEvent );
2874             }
2875         }
2876 }
2877 
FireSectionChangeEvent(sal_uInt16 nOldSection,sal_uInt16 nNewSection)2878 void SwAccessibleMap::FireSectionChangeEvent(sal_uInt16 nOldSection, sal_uInt16 nNewSection)
2879 {
2880     uno::Reference<XAccessible> xAcc = GetDocumentView( );
2881         if ( xAcc.is() )
2882         {
2883             SwAccessibleDocumentBase *pAcc =
2884             static_cast< SwAccessibleDocumentBase * >( xAcc.get() );
2885             if (pAcc)
2886             {
2887                 AccessibleEventObject aEvent;
2888                 aEvent.EventId = AccessibleEventId::SECTION_CHANGED;
2889                 aEvent.OldValue <<= nOldSection;
2890                 aEvent.NewValue <<= nNewSection;
2891                 pAcc->FireAccessibleEvent( aEvent );
2892 
2893             }
2894         }
2895 }
FireColumnChangeEvent(sal_uInt16 nOldColumn,sal_uInt16 nNewColumn)2896 void SwAccessibleMap::FireColumnChangeEvent(sal_uInt16 nOldColumn, sal_uInt16 nNewColumn)
2897 {
2898     uno::Reference<XAccessible> xAcc = GetDocumentView( );
2899         if ( xAcc.is() )
2900         {
2901             SwAccessibleDocumentBase *pAcc =
2902             static_cast< SwAccessibleDocumentBase * >( xAcc.get() );
2903         if (pAcc)
2904         {
2905                 AccessibleEventObject aEvent;
2906                 aEvent.EventId = AccessibleEventId::COLUMN_CHANGED;
2907                 aEvent.OldValue <<= nOldColumn;
2908                 aEvent.NewValue <<= nNewColumn;
2909                 pAcc->FireAccessibleEvent( aEvent );
2910 
2911         }
2912         }
2913 }
2914 
InvalidateFocus()2915 void SwAccessibleMap::InvalidateFocus()
2916 {
2917     if(GetShell()->IsPreView())
2918     {
2919         uno::Reference<XAccessible> xAcc = _GetDocumentView( sal_True );
2920         if (xAcc.get())
2921         {
2922             SwAccessiblePreview *pAccPreview = static_cast<SwAccessiblePreview *>(xAcc.get());
2923             if (pAccPreview)
2924             {
2925                 pAccPreview->InvalidateFocus();
2926                 return ;
2927             }
2928         }
2929     }
2930     uno::Reference < XAccessible > xAcc;
2931     sal_Bool bShapeSelected;
2932     {
2933         vos::OGuard aGuard( maMutex );
2934 
2935         xAcc = mxCursorContext;
2936         bShapeSelected = mbShapeSelected;
2937     }
2938 
2939     if( xAcc.is() )
2940     {
2941         SwAccessibleContext *pAccImpl =
2942             static_cast< SwAccessibleContext *>( xAcc.get() );
2943         pAccImpl->InvalidateFocus();
2944     }
2945     else
2946     {
2947         DoInvalidateShapeSelection(sal_True);
2948     }
2949 }
2950 
SetCursorContext(const::vos::ORef<SwAccessibleContext> & rCursorContext)2951 void SwAccessibleMap::SetCursorContext(
2952         const ::vos::ORef < SwAccessibleContext >& rCursorContext )
2953 {
2954     vos::OGuard aGuard( maMutex );
2955     uno::Reference < XAccessible > xAcc( rCursorContext.getBodyPtr() );
2956     mxCursorContext = xAcc;
2957 }
2958 
2959 // --> OD 2005-12-12 #i27301# - use new type definition for <_nStates>
InvalidateStates(tAccessibleStates _nStates,const SwFrm * _pFrm)2960 void SwAccessibleMap::InvalidateStates( tAccessibleStates _nStates,
2961                                         const SwFrm* _pFrm )
2962 {
2963     // Start with the frame or the first upper that is accessible
2964     SwAccessibleChild aFrmOrObj( _pFrm );
2965     while( aFrmOrObj.GetSwFrm() &&
2966             !aFrmOrObj.IsAccessible( GetShell()->IsPreView() ) )
2967         aFrmOrObj = aFrmOrObj.GetSwFrm()->GetUpper();
2968     if( !aFrmOrObj.GetSwFrm() )
2969         aFrmOrObj = GetShell()->GetLayout();
2970 
2971     uno::Reference< XAccessible > xAcc( GetContext( aFrmOrObj.GetSwFrm(), sal_True ) );
2972     SwAccessibleContext *pAccImpl =
2973         static_cast< SwAccessibleContext *>( xAcc.get() );
2974     if( GetShell()->ActionPend() )
2975     {
2976         SwAccessibleEvent_Impl aEvent( SwAccessibleEvent_Impl::CARET_OR_STATES,
2977                                        pAccImpl,
2978                                        SwAccessibleChild(pAccImpl->GetFrm()),
2979                                        _nStates );
2980         AppendEvent( aEvent );
2981     }
2982     else
2983     {
2984         FireEvents();
2985         pAccImpl->InvalidateStates( _nStates );
2986     }
2987 }
2988 // <--
2989 
_InvalidateRelationSet(const SwFrm * pFrm,sal_Bool bFrom)2990 void SwAccessibleMap::_InvalidateRelationSet( const SwFrm* pFrm,
2991                                               sal_Bool bFrom )
2992 {
2993     // first, see if this frame is accessible, and if so, get the respective
2994     SwAccessibleChild aFrmOrObj( pFrm );
2995     if( aFrmOrObj.IsAccessible( GetShell()->IsPreView() ) )
2996     {
2997         uno::Reference < XAccessible > xAcc;
2998         {
2999             vos::OGuard aGuard( maMutex );
3000 
3001             if( mpFrmMap )
3002             {
3003                 SwAccessibleContextMap_Impl::iterator aIter =
3004                                         mpFrmMap->find( aFrmOrObj.GetSwFrm() );
3005                 if( aIter != mpFrmMap->end() )
3006                 {
3007                     xAcc = (*aIter).second;
3008                 }
3009             }
3010         }
3011 
3012         // deliver event directly, or queue event
3013         if( xAcc.is() )
3014         {
3015             SwAccessibleContext *pAccImpl =
3016                             static_cast< SwAccessibleContext *>( xAcc.get() );
3017             if( GetShell()->ActionPend() )
3018             {
3019                 SwAccessibleEvent_Impl aEvent( SwAccessibleEvent_Impl::CARET_OR_STATES,
3020                                                pAccImpl, SwAccessibleChild(pFrm),
3021                                                ( bFrom
3022                                                  ? ACC_STATE_RELATION_FROM
3023                                                  : ACC_STATE_RELATION_TO ) );
3024                 AppendEvent( aEvent );
3025             }
3026             else
3027             {
3028                 FireEvents();
3029                 pAccImpl->InvalidateRelation( bFrom
3030                         ? AccessibleEventId::CONTENT_FLOWS_FROM_RELATION_CHANGED
3031                         : AccessibleEventId::CONTENT_FLOWS_TO_RELATION_CHANGED );
3032             }
3033         }
3034     }
3035 }
3036 
InvalidateRelationSet(const SwFrm * pMaster,const SwFrm * pFollow)3037 void SwAccessibleMap::InvalidateRelationSet( const SwFrm* pMaster,
3038                                              const SwFrm* pFollow )
3039 {
3040     _InvalidateRelationSet( pMaster, sal_False );
3041     _InvalidateRelationSet( pFollow, sal_True );
3042 }
3043 
3044 /** invalidation CONTENT_FLOW_FROM/_TO relation of a paragraph
3045 
3046     OD 2005-12-01 #i27138#
3047 
3048     @author OD
3049 */
InvalidateParaFlowRelation(const SwTxtFrm & _rTxtFrm,const bool _bFrom)3050 void SwAccessibleMap::InvalidateParaFlowRelation( const SwTxtFrm& _rTxtFrm,
3051                                                   const bool _bFrom )
3052 {
3053     _InvalidateRelationSet( &_rTxtFrm, _bFrom );
3054 }
3055 
3056 /** invalidation of text selection of a paragraph
3057 
3058     OD 2005-12-12 #i27301#
3059 
3060     @author OD
3061 */
InvalidateParaTextSelection(const SwTxtFrm & _rTxtFrm)3062 void SwAccessibleMap::InvalidateParaTextSelection( const SwTxtFrm& _rTxtFrm )
3063 {
3064     // first, see if this frame is accessible, and if so, get the respective
3065     SwAccessibleChild aFrmOrObj( &_rTxtFrm );
3066     if( aFrmOrObj.IsAccessible( GetShell()->IsPreView() ) )
3067     {
3068         uno::Reference < XAccessible > xAcc;
3069         {
3070             vos::OGuard aGuard( maMutex );
3071 
3072             if( mpFrmMap )
3073             {
3074                 SwAccessibleContextMap_Impl::iterator aIter =
3075                                         mpFrmMap->find( aFrmOrObj.GetSwFrm() );
3076                 if( aIter != mpFrmMap->end() )
3077                 {
3078                     xAcc = (*aIter).second;
3079                 }
3080             }
3081         }
3082 
3083         // deliver event directly, or queue event
3084         if( xAcc.is() )
3085         {
3086             SwAccessibleContext *pAccImpl =
3087                             static_cast< SwAccessibleContext *>( xAcc.get() );
3088             if( GetShell()->ActionPend() )
3089             {
3090                 SwAccessibleEvent_Impl aEvent(
3091                     SwAccessibleEvent_Impl::CARET_OR_STATES,
3092                     pAccImpl,
3093                     SwAccessibleChild( &_rTxtFrm ),
3094                     ACC_STATE_TEXT_SELECTION_CHANGED );
3095                 AppendEvent( aEvent );
3096             }
3097             else
3098             {
3099                 FireEvents();
3100                 pAccImpl->InvalidateTextSelection();
3101             }
3102         }
3103     }
3104 }
3105 
GetChildIndex(const SwFrm & rParentFrm,Window & rChild) const3106 sal_Int32 SwAccessibleMap::GetChildIndex( const SwFrm& rParentFrm,
3107                                           Window& rChild ) const
3108 {
3109     sal_Int32 nIndex( -1 );
3110 
3111     SwAccessibleChild aFrmOrObj( &rParentFrm );
3112     if( aFrmOrObj.IsAccessible( GetShell()->IsPreView() ) )
3113     {
3114         uno::Reference < XAccessible > xAcc;
3115         {
3116             vos::OGuard aGuard( maMutex );
3117 
3118             if( mpFrmMap )
3119             {
3120                 SwAccessibleContextMap_Impl::iterator aIter =
3121                                         mpFrmMap->find( aFrmOrObj.GetSwFrm() );
3122                 if( aIter != mpFrmMap->end() )
3123                 {
3124                     xAcc = (*aIter).second;
3125                 }
3126             }
3127         }
3128 
3129         if( xAcc.is() )
3130         {
3131             SwAccessibleContext *pAccImpl =
3132                             static_cast< SwAccessibleContext *>( xAcc.get() );
3133 
3134             nIndex = pAccImpl->GetChildIndex( const_cast<SwAccessibleMap&>(*this),
3135                                               SwAccessibleChild( &rChild ) );
3136         }
3137     }
3138 
3139     return nIndex;
3140 }
3141 
3142 
3143 // OD 15.01.2003 #103492# - complete re-factoring of method due to new page/print
3144 // preview functionality.
UpdatePreview(const std::vector<PrevwPage * > & _rPrevwPages,const Fraction & _rScale,const SwPageFrm * _pSelectedPageFrm,const Size & _rPrevwWinSize)3145 void SwAccessibleMap::UpdatePreview( const std::vector<PrevwPage*>& _rPrevwPages,
3146                                      const Fraction&  _rScale,
3147                                      const SwPageFrm* _pSelectedPageFrm,
3148                                      const Size&      _rPrevwWinSize )
3149 {
3150     DBG_ASSERT( GetShell()->IsPreView(), "no preview?" );
3151     DBG_ASSERT( mpPreview != NULL, "no preview data?" );
3152 
3153     // OD 15.01.2003 #103492# - adjustments for changed method signature
3154     mpPreview->Update( *this, _rPrevwPages, _rScale, _pSelectedPageFrm, _rPrevwWinSize );
3155 
3156     // propagate change of VisArea through the document's
3157     // accessibility tree; this will also send appropriate scroll
3158     // events
3159     SwAccessibleContext* pDoc =
3160         GetContextImpl( GetShell()->GetLayout() ).getBodyPtr();
3161     static_cast<SwAccessibleDocumentBase*>( pDoc )->SetVisArea();
3162 
3163     uno::Reference < XAccessible > xOldAcc;
3164     uno::Reference < XAccessible > xAcc;
3165     {
3166         vos::OGuard aGuard( maMutex );
3167 
3168         xOldAcc = mxCursorContext;
3169 
3170         const SwPageFrm *pSelPage = mpPreview->GetSelPage();
3171         if( pSelPage && mpFrmMap )
3172         {
3173             SwAccessibleContextMap_Impl::iterator aIter =
3174                 mpFrmMap->find( pSelPage );
3175             if( aIter != mpFrmMap->end() )
3176                 xAcc = (*aIter).second;
3177         }
3178     }
3179 
3180     if( xOldAcc.is() && xOldAcc != xAcc )
3181         InvalidateCursorPosition( xOldAcc );
3182     if( xAcc.is() )
3183         InvalidateCursorPosition( xAcc );
3184 }
3185 
InvalidatePreViewSelection(sal_uInt16 nSelPage)3186 void SwAccessibleMap::InvalidatePreViewSelection( sal_uInt16 nSelPage )
3187 {
3188     DBG_ASSERT( GetShell()->IsPreView(), "no preview?" );
3189     DBG_ASSERT( mpPreview != NULL, "no preview data?" );
3190 
3191     // OD 16.01.2003 #103492# - changed metthod call due to method signature change.
3192     mpPreview->InvalidateSelection( GetShell()->GetLayout()->GetPageByPageNum( nSelPage ) );
3193 
3194     uno::Reference < XAccessible > xOldAcc;
3195     uno::Reference < XAccessible > xAcc;
3196     {
3197         vos::OGuard aGuard( maMutex );
3198 
3199         xOldAcc = mxCursorContext;
3200 
3201         const SwPageFrm *pSelPage = mpPreview->GetSelPage();
3202         if( pSelPage && mpFrmMap )
3203         {
3204             SwAccessibleContextMap_Impl::iterator aIter =
3205                 mpFrmMap->find( pSelPage );
3206             if( aIter != mpFrmMap->end() )
3207                 xAcc = (*aIter).second;
3208         }
3209     }
3210 
3211     if( xOldAcc.is() && xOldAcc != xAcc )
3212         InvalidateCursorPosition( xOldAcc );
3213     if( xAcc.is() )
3214         InvalidateCursorPosition( xAcc );
3215 }
3216 
3217 
IsPageSelected(const SwPageFrm * pPageFrm) const3218 sal_Bool SwAccessibleMap::IsPageSelected( const SwPageFrm *pPageFrm ) const
3219 {
3220     return mpPreview && mpPreview->GetSelPage() == pPageFrm;
3221 }
3222 
3223 
FireEvents()3224 void SwAccessibleMap::FireEvents()
3225 {
3226     {
3227         vos::OGuard aGuard( maEventMutex );
3228         if( mpEvents )
3229         {
3230             mpEvents->SetFiring();
3231             mpEvents->MoveInvalidXAccToEnd();
3232             SwAccessibleEventList_Impl::iterator aIter = mpEvents->begin();
3233             while( aIter != mpEvents->end() )
3234             {
3235                 FireEvent( *aIter );
3236                 ++aIter;
3237             }
3238 
3239             delete mpEventMap;
3240             mpEventMap = 0;
3241 
3242             delete mpEvents;
3243             mpEvents = 0;
3244         }
3245     }
3246     {
3247         vos::OGuard aGuard( maMutex );
3248         if( mpShapes )
3249         {
3250             delete mpShapes;
3251             mpShapes = 0;
3252         }
3253     }
3254 
3255 }
3256 
IsValid() const3257 sal_Bool SwAccessibleMap::IsValid() const
3258 {
3259     return sal_True;
3260 }
3261 
GetVisibleArea() const3262 Rectangle SwAccessibleMap::GetVisibleArea() const
3263 {
3264     MapMode aSrc( MAP_TWIP );
3265     MapMode aDest( MAP_100TH_MM );
3266     return OutputDevice::LogicToLogic( GetVisArea().SVRect(), aSrc, aDest );
3267 }
3268 
3269 // Convert a MM100 value realtive to the document root into a pixel value
3270 // realtive to the screen!
LogicToPixel(const Point & rPoint) const3271 Point SwAccessibleMap::LogicToPixel( const Point& rPoint ) const
3272 {
3273     MapMode aSrc( MAP_100TH_MM );
3274     MapMode aDest( MAP_TWIP );
3275 
3276     Point aPoint = rPoint;
3277 
3278     aPoint = OutputDevice::LogicToLogic( aPoint, aSrc, aDest );
3279     Window *pWin = GetShell()->GetWin();
3280     if( pWin )
3281     {
3282         // OD 16.01.2003 #103492# - get mapping mode for LogicToPixel conversion
3283         MapMode aMapMode;
3284         GetMapMode( aPoint, aMapMode );
3285         aPoint = pWin->LogicToPixel( aPoint, aMapMode );
3286         aPoint = pWin->OutputToAbsoluteScreenPixel( aPoint );
3287     }
3288 
3289     return aPoint;
3290 }
3291 
LogicToPixel(const Size & rSize) const3292 Size SwAccessibleMap::LogicToPixel( const Size& rSize ) const
3293 {
3294     MapMode aSrc( MAP_100TH_MM );
3295     MapMode aDest( MAP_TWIP );
3296     Size aSize( OutputDevice::LogicToLogic( rSize, aSrc, aDest ) );
3297     if( GetShell()->GetWin() )
3298     {
3299         // OD 16.01.2003 #103492# - get mapping mode for LogicToPixel conversion
3300         MapMode aMapMode;
3301         GetMapMode( Point(0,0), aMapMode );
3302         aSize = GetShell()->GetWin()->LogicToPixel( aSize, aMapMode );
3303     }
3304 
3305     return aSize;
3306 }
3307 
PixelToLogic(const Point & rPoint) const3308 Point SwAccessibleMap::PixelToLogic( const Point& rPoint ) const
3309 {
3310     Point aPoint;
3311     Window *pWin = GetShell()->GetWin();
3312     if( pWin )
3313     {
3314         aPoint = pWin->ScreenToOutputPixel( rPoint );
3315         // OD 16.01.2003 #103492# - get mapping mode for PixelToLogic conversion
3316         MapMode aMapMode;
3317         GetMapMode( aPoint, aMapMode );
3318         aPoint = pWin->PixelToLogic( aPoint, aMapMode );
3319         MapMode aSrc( MAP_TWIP );
3320         MapMode aDest( MAP_100TH_MM );
3321         aPoint = OutputDevice::LogicToLogic( aPoint, aSrc, aDest );
3322     }
3323 
3324     return aPoint;
3325 }
3326 
PixelToLogic(const Size & rSize) const3327 Size SwAccessibleMap::PixelToLogic( const Size& rSize ) const
3328 {
3329     Size aSize;
3330     if( GetShell()->GetWin() )
3331     {
3332         // OD 16.01.2003 #103492# - get mapping mode for PixelToLogic conversion
3333         MapMode aMapMode;
3334         GetMapMode( Point(0,0), aMapMode );
3335         aSize = GetShell()->GetWin()->PixelToLogic( rSize, aMapMode );
3336         MapMode aSrc( MAP_TWIP );
3337         MapMode aDest( MAP_100TH_MM );
3338         aSize = OutputDevice::LogicToLogic( aSize, aSrc, aDest );
3339     }
3340 
3341     return aSize;
3342 }
3343 
ReplaceChild(::accessibility::AccessibleShape * pCurrentChild,const uno::Reference<drawing::XShape> & _rxShape,const long,const::accessibility::AccessibleShapeTreeInfo &)3344 sal_Bool SwAccessibleMap::ReplaceChild (
3345         ::accessibility::AccessibleShape* pCurrentChild,
3346         const uno::Reference< drawing::XShape >& _rxShape,
3347         const long /*_nIndex*/,
3348         const ::accessibility::AccessibleShapeTreeInfo& /*_rShapeTreeInfo*/
3349     )   throw (uno::RuntimeException)
3350 {
3351     const SdrObject *pObj = 0;
3352     {
3353         vos::OGuard aGuard( maMutex );
3354         if( mpShapeMap )
3355         {
3356             SwAccessibleShapeMap_Impl::const_iterator aIter = mpShapeMap->begin();
3357             SwAccessibleShapeMap_Impl::const_iterator aEndIter = mpShapeMap->end();
3358             while( aIter != aEndIter && !pObj )
3359             {
3360                 uno::Reference < XAccessible > xAcc( (*aIter).second );
3361                 ::accessibility::AccessibleShape *pAccShape =
3362                     static_cast < ::accessibility::AccessibleShape* >( xAcc.get() );
3363                 if( pAccShape == pCurrentChild )
3364                 {
3365                     pObj = (*aIter).first;
3366                 }
3367                 ++aIter;
3368             }
3369         }
3370     }
3371     if( !pObj )
3372         return sal_False;
3373 
3374     uno::Reference < drawing::XShape > xShape( _rxShape ); //keep reference to shape, because
3375                                              // we might be the only one that
3376                                              // hold it.
3377     // Also get keep parent.
3378     uno::Reference < XAccessible > xParent( pCurrentChild->getAccessibleParent() );
3379     pCurrentChild = 0;  // well be realease by dispose
3380     Dispose( 0, pObj, 0 );
3381 
3382     {
3383         vos::OGuard aGuard( maMutex );
3384 
3385         if( !mpShapeMap )
3386             mpShapeMap = new SwAccessibleShapeMap_Impl( this );
3387 
3388         // create the new child
3389         ::accessibility::ShapeTypeHandler& rShapeTypeHandler =
3390                         ::accessibility::ShapeTypeHandler::Instance();
3391         ::accessibility::AccessibleShapeInfo aShapeInfo(
3392                                             xShape, xParent, this );
3393         ::accessibility::AccessibleShape* pReplacement =
3394             rShapeTypeHandler.CreateAccessibleObject (
3395                 aShapeInfo, mpShapeMap->GetInfo() );
3396 
3397         uno::Reference < XAccessible > xAcc( pReplacement );
3398         if( xAcc.is() )
3399         {
3400             pReplacement->Init();
3401 
3402             SwAccessibleShapeMap_Impl::iterator aIter =
3403                 mpShapeMap->find( pObj );
3404             if( aIter != mpShapeMap->end() )
3405             {
3406                 (*aIter).second = xAcc;
3407             }
3408             else
3409             {
3410                 SwAccessibleShapeMap_Impl::value_type aEntry( pObj, xAcc );
3411                 mpShapeMap->insert( aEntry );
3412             }
3413         }
3414     }
3415 
3416     SwRect aEmptyRect;
3417     InvalidatePosOrSize( 0, pObj, 0, aEmptyRect );
3418 
3419     return sal_True;
3420 }
3421 
3422 //Get the accessible control shape from the model object, here model object is with XPropertySet type
GetAccControlShapeFromModel(::com::sun::star::beans::XPropertySet * pSet)3423 ::accessibility::AccessibleControlShape * SwAccessibleMap::GetAccControlShapeFromModel(::com::sun::star::beans::XPropertySet* pSet) throw (::com::sun::star::uno::RuntimeException)
3424 {
3425     if( mpShapeMap )
3426     {
3427         SwAccessibleShapeMap_Impl::const_iterator aIter = mpShapeMap->begin();
3428         SwAccessibleShapeMap_Impl::const_iterator aEndIter = mpShapeMap->end();
3429         while( aIter != aEndIter)
3430         {
3431             uno::Reference < XAccessible > xAcc( (*aIter).second );
3432             ::accessibility::AccessibleShape *pAccShape =
3433                 static_cast < ::accessibility::AccessibleShape* >( xAcc.get() );
3434             if(pAccShape && ::accessibility::ShapeTypeHandler::Instance().GetTypeId (pAccShape->GetXShape()) == ::accessibility::DRAWING_CONTROL)
3435             {
3436                 ::accessibility::AccessibleControlShape *pCtlAccShape = static_cast < ::accessibility::AccessibleControlShape* >(pAccShape);
3437                 if (pCtlAccShape && pCtlAccShape->GetControlModel() == pSet)
3438                     return pCtlAccShape;
3439             }
3440             ++aIter;
3441         }
3442     }
3443     return NULL;
3444 }
3445 
3446 ::com::sun::star::uno::Reference< XAccessible >
GetAccessibleCaption(const::com::sun::star::uno::Reference<::com::sun::star::drawing::XShape> & xShape)3447     SwAccessibleMap::GetAccessibleCaption (const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& xShape)
3448     throw (::com::sun::star::uno::RuntimeException)
3449 {
3450         SdrObject* captionedObject = GetSdrObjectFromXShape(xShape);
3451 
3452         SwDrawContact *pContact = (SwDrawContact*)GetUserCall( captionedObject );
3453         ASSERT( RES_DRAWFRMFMT == pContact->GetFmt()->Which(),
3454                 "fail" );
3455         if( !pContact )
3456             return 0;
3457 
3458         SwDrawFrmFmt *pCaptionedFmt = (SwDrawFrmFmt *)pContact->GetFmt();
3459         if( !pCaptionedFmt )
3460             return 0;
3461 
3462         SwFlyFrm* pFrm = NULL;
3463         if (pCaptionedFmt->HasCaption())
3464         {
3465             const SwFrmFmt *pCaptionFrmFmt = pCaptionedFmt->GetCaptionFmt();
3466             SwClientIter aIter (*(SwModify*)pCaptionFrmFmt);
3467             pFrm = (SwFlyFrm*)aIter.First( TYPE ( SwFlyFrm ));
3468         }
3469         if (!pFrm)
3470             return 0;
3471         //SwFrmFmt* pFrm = pCaptionedFmt->GetCaptionFmt();
3472         uno::Reference < XAccessible > xAcc( GetContext((SwFrm*)pFrm,sal_True) );
3473         //Reference < XAccessibleShape > xAccShape( xAcc, UNO_QUERY );
3474 
3475         uno::Reference< XAccessibleContext > xAccContext = xAcc->getAccessibleContext();
3476         if( xAccContext.is() )
3477         {   //get the parent of caption frame, which is paragaph
3478             uno::Reference< XAccessible > xAccParent = xAccContext->getAccessibleParent();
3479             if(xAccParent.is())
3480             {
3481                 //get the great parent of caption frame which is text frame.
3482                 uno::Reference< XAccessibleContext > xAccParentContext = xAccParent->getAccessibleContext();
3483                 uno::Reference< XAccessible > xAccGreatParent = xAccParentContext->getAccessibleParent();
3484                 if(xAccGreatParent.is())
3485                 {
3486                     AccessibleEventObject aEvent;
3487                     aEvent.EventId = AccessibleEventId::CHILD;
3488                     aEvent.NewValue <<= xAccParent;
3489                     ( static_cast< SwAccessibleContext * >(xAccGreatParent.get()) )->FireAccessibleEvent( aEvent );
3490 
3491                 }
3492 
3493                 AccessibleEventObject aEvent;
3494                 aEvent.EventId = AccessibleEventId::CHILD;
3495                 aEvent.NewValue <<= xAcc;
3496                 ( static_cast< SwAccessibleContext * >(xAccParent.get()) )->FireAccessibleEvent( aEvent );
3497             }
3498         }
3499 
3500         if(xAcc.get())
3501             return xAcc;
3502         else
3503             return NULL;
3504 
3505 }
PixelToCore(const Point & rPoint) const3506 Point SwAccessibleMap::PixelToCore( const Point& rPoint ) const
3507 {
3508     Point aPoint;
3509     if( GetShell()->GetWin() )
3510     {
3511         // OD 15.01.2003 #103492# - replace <PreviewAdjust(..)> by <GetMapMode(..)>
3512         MapMode aMapMode;
3513         GetMapMode( rPoint, aMapMode );
3514         aPoint = GetShell()->GetWin()->PixelToLogic( rPoint, aMapMode );
3515     }
3516     return aPoint;
3517 }
3518 
lcl_CorrectCoarseValue(long aCoarseValue,long aFineValue,long aRefValue,bool bToLower)3519 static inline long lcl_CorrectCoarseValue(long aCoarseValue, long aFineValue,
3520                                           long aRefValue, bool bToLower)
3521 {
3522     long aResult = aCoarseValue;
3523 
3524     if (bToLower)
3525     {
3526         if (aFineValue < aRefValue)
3527             aResult -= 1;
3528     }
3529     else
3530     {
3531         if (aFineValue > aRefValue)
3532             aResult += 1;
3533     }
3534 
3535     return aResult;
3536 }
3537 
lcl_CorrectRectangle(Rectangle & rRect,const Rectangle & rSource,const Rectangle & rInGrid)3538 static inline void lcl_CorrectRectangle(Rectangle & rRect,
3539                                         const Rectangle & rSource,
3540                                         const Rectangle & rInGrid)
3541 {
3542     rRect.nLeft = lcl_CorrectCoarseValue(rRect.nLeft, rSource.nLeft,
3543                                          rInGrid.nLeft, false);
3544     rRect.nTop = lcl_CorrectCoarseValue(rRect.nTop, rSource.nTop,
3545                                         rInGrid.nTop, false);
3546     rRect.nRight = lcl_CorrectCoarseValue(rRect.nRight, rSource.nRight,
3547                                           rInGrid.nRight, true);
3548     rRect.nBottom = lcl_CorrectCoarseValue(rRect.nBottom, rSource.nBottom,
3549                                            rInGrid.nBottom, true);
3550 }
3551 
CoreToPixel(const Rectangle & rRect) const3552 Rectangle SwAccessibleMap::CoreToPixel( const Rectangle& rRect ) const
3553 {
3554     Rectangle aRect;
3555     if( GetShell()->GetWin() )
3556     {
3557         // OD 15.01.2003 #103492# - replace <PreviewAdjust(..)> by <GetMapMode(..)>
3558         MapMode aMapMode;
3559         GetMapMode( rRect.TopLeft(), aMapMode );
3560         aRect = GetShell()->GetWin()->LogicToPixel( rRect, aMapMode );
3561 
3562         Rectangle aTmpRect = GetShell()->GetWin()->PixelToLogic( aRect, aMapMode );
3563         lcl_CorrectRectangle(aRect, rRect, aTmpRect);
3564     }
3565 
3566     return aRect;
3567 }
3568 
3569 /** get mapping mode for LogicToPixel and PixelToLogic conversions
3570 
3571     OD 15.01.2003 #103492#
3572     Replacement method <PreviewAdjust(..)> by new method <GetMapMode>.
3573     Method returns mapping mode of current output device and adjusts it,
3574     if the shell is in page/print preview.
3575     Necessary, because <PreviewAdjust(..)> changes mapping mode at current
3576     output device for mapping logic document positions to page preview window
3577     positions and vice versa and doesn't take care to recover its changes.
3578 
3579     @author OD
3580 */
GetMapMode(const Point & _rPoint,MapMode & _orMapMode) const3581 void SwAccessibleMap::GetMapMode( const Point& _rPoint,
3582                                   MapMode&     _orMapMode ) const
3583 {
3584     MapMode aMapMode = GetShell()->GetWin()->GetMapMode();
3585     if( GetShell()->IsPreView() )
3586     {
3587         DBG_ASSERT( mpPreview != NULL, "need preview data" );
3588 
3589         mpPreview->AdjustMapMode( aMapMode, _rPoint );
3590     }
3591     _orMapMode = aMapMode;
3592 }
3593 
3594 /** get size of a dedicated preview page
3595 
3596     OD 15.01.2003 #103492#
3597 
3598     @author OD
3599 */
GetPreViewPageSize(sal_uInt16 _nPrevwPageNum) const3600 Size SwAccessibleMap::GetPreViewPageSize( sal_uInt16 _nPrevwPageNum ) const
3601 {
3602     DBG_ASSERT( mpVSh->IsPreView(), "no page preview accessible." );
3603     DBG_ASSERT( mpVSh->IsPreView() && ( mpPreview != NULL ),
3604                 "missing accessible preview data at page preview" );
3605     if ( mpVSh->IsPreView() && ( mpPreview != NULL ) )
3606     {
3607         return mpVSh->PagePreviewLayout()->GetPrevwPageSizeByPageNum( _nPrevwPageNum );
3608     }
3609     else
3610     {
3611         return Size( 0, 0 );
3612     }
3613 }
3614 
3615 /** method to build up a new data structure of the accessible pararaphs,
3616     which have a selection
3617 
3618     OD 2005-12-13 #i27301#
3619     Important note: method has to used inside a mutual exclusive section
3620 
3621     @author OD
3622 */
_BuildSelectedParas()3623 SwAccessibleSelectedParas_Impl* SwAccessibleMap::_BuildSelectedParas()
3624 {
3625     // no accessible contexts, no selection
3626     if ( !mpFrmMap )
3627     {
3628         return 0L;
3629     }
3630 
3631     // get cursor as an instance of its base class <SwPaM>
3632     SwPaM* pCrsr( 0L );
3633     {
3634         SwCrsrShell* pCrsrShell = dynamic_cast<SwCrsrShell*>(GetShell());
3635         if ( pCrsrShell )
3636         {
3637             SwFEShell* pFEShell = dynamic_cast<SwFEShell*>(pCrsrShell);
3638             if ( !pFEShell ||
3639                  ( !pFEShell->IsFrmSelected() &&
3640                    pFEShell->IsObjSelected() == 0 ) )
3641             {
3642                 // get cursor without updating an existing table cursor.
3643                 pCrsr = pCrsrShell->GetCrsr( sal_False );
3644             }
3645         }
3646     }
3647     // no cursor, no selection
3648     if ( !pCrsr )
3649     {
3650         return 0L;
3651     }
3652 
3653     SwAccessibleSelectedParas_Impl* pRetSelectedParas( 0L );
3654 
3655     // loop on all cursors
3656     SwPaM* pRingStart = pCrsr;
3657     do {
3658 
3659         // for a selection the cursor has to have a mark.
3660         // for savety reasons assure that point and mark are in text nodes
3661         if ( pCrsr->HasMark() &&
3662              pCrsr->GetPoint()->nNode.GetNode().IsTxtNode() &&
3663              pCrsr->GetMark()->nNode.GetNode().IsTxtNode() )
3664         {
3665             SwPosition* pStartPos = pCrsr->Start();
3666             SwPosition* pEndPos = pCrsr->End();
3667             // loop on all text nodes inside the selection
3668             SwNodeIndex aIdx( pStartPos->nNode );
3669             for ( ; aIdx.GetIndex() <= pEndPos->nNode.GetIndex(); ++aIdx )
3670             {
3671                 SwTxtNode* pTxtNode( aIdx.GetNode().GetTxtNode() );
3672                 if ( pTxtNode )
3673                 {
3674                     // loop on all text frames registered at the text node.
3675                     SwIterator<SwTxtFrm,SwTxtNode> aIter( *pTxtNode );
3676                     for( SwTxtFrm* pTxtFrm = aIter.First(); pTxtFrm; pTxtFrm = aIter.Next() )
3677                         {
3678                             uno::WeakReference < XAccessible > xWeakAcc;
3679                             SwAccessibleContextMap_Impl::iterator aMapIter =
3680                                                     mpFrmMap->find( pTxtFrm );
3681                             if( aMapIter != mpFrmMap->end() )
3682                             {
3683                                 xWeakAcc = (*aMapIter).second;
3684                                 SwAccessibleParaSelection aDataEntry(
3685                                     pTxtNode == &(pStartPos->nNode.GetNode())
3686                                                 ? pStartPos->nContent.GetIndex()
3687                                                 : 0,
3688                                     pTxtNode == &(pEndPos->nNode.GetNode())
3689                                                 ? pEndPos->nContent.GetIndex()
3690                                                 : STRING_LEN );
3691                                 SwAccessibleSelectedParas_Impl::value_type
3692                                                 aEntry( xWeakAcc, aDataEntry );
3693                                 if ( !pRetSelectedParas )
3694                                 {
3695                                     pRetSelectedParas =
3696                                             new SwAccessibleSelectedParas_Impl;
3697                                 }
3698                                 pRetSelectedParas->insert( aEntry );
3699                             }
3700                         }
3701                     }
3702                 }
3703             }
3704 
3705         // prepare next turn: get next cursor in ring
3706         pCrsr = static_cast<SwPaM*>( pCrsr->GetNext() );
3707     } while ( pCrsr != pRingStart );
3708 
3709     return pRetSelectedParas;
3710 }
3711 
3712 /** invalidation of text selection of all paragraphs
3713 
3714     OD 2005-12-13 #i27301#
3715 
3716     @author OD
3717 */
InvalidateTextSelectionOfAllParas()3718 void SwAccessibleMap::InvalidateTextSelectionOfAllParas()
3719 {
3720     vos::OGuard aGuard( maMutex );
3721 
3722     // keep previously known selected paragraphs
3723     SwAccessibleSelectedParas_Impl* pPrevSelectedParas( mpSelectedParas );
3724 
3725     // determine currently selected paragraphs
3726     mpSelectedParas = _BuildSelectedParas();
3727 
3728     // compare currently selected paragraphs with the previously selected
3729     // paragraphs and submit corresponding TEXT_SELECTION_CHANGED events.
3730     // first, search for new and changed selections.
3731     // on the run remove selections from previously known ones, if they are
3732     // also in the current ones.
3733     if ( mpSelectedParas )
3734     {
3735         SwAccessibleSelectedParas_Impl::iterator aIter = mpSelectedParas->begin();
3736         for ( ; aIter != mpSelectedParas->end(); ++aIter )
3737         {
3738             bool bSubmitEvent( false );
3739             if ( !pPrevSelectedParas )
3740             {
3741                 // new selection
3742                 bSubmitEvent = true;
3743             }
3744             else
3745             {
3746                 SwAccessibleSelectedParas_Impl::iterator aPrevSelected =
3747                                         pPrevSelectedParas->find( (*aIter).first );
3748                 if ( aPrevSelected != pPrevSelectedParas->end() )
3749                 {
3750                     // check, if selection has changed
3751                     if ( (*aIter).second.nStartOfSelection !=
3752                                     (*aPrevSelected).second.nStartOfSelection ||
3753                          (*aIter).second.nEndOfSelection !=
3754                                     (*aPrevSelected).second.nEndOfSelection )
3755                     {
3756                         // changed selection
3757                         bSubmitEvent = true;
3758                     }
3759                     pPrevSelectedParas->erase( aPrevSelected );
3760                 }
3761                 else
3762                 {
3763                     // new selection
3764                     bSubmitEvent = true;
3765                 }
3766             }
3767 
3768             if ( bSubmitEvent )
3769             {
3770                 uno::Reference < XAccessible > xAcc( (*aIter).first );
3771                 if ( xAcc.is() )
3772                 {
3773                     ::vos::ORef < SwAccessibleContext > xAccImpl(
3774                                 static_cast<SwAccessibleContext*>( xAcc.get() ) );
3775                     if ( xAccImpl.isValid() && xAccImpl->GetFrm() )
3776                     {
3777                         const SwTxtFrm* pTxtFrm(
3778                             dynamic_cast<const SwTxtFrm*>(xAccImpl->GetFrm()) );
3779                         ASSERT( pTxtFrm,
3780                                 "<SwAccessibleMap::_SubmitTextSelectionChangedEvents()> - unexcepted type of frame" );
3781                         if ( pTxtFrm )
3782                         {
3783                             InvalidateParaTextSelection( *pTxtFrm );
3784                         }
3785                     }
3786                 }
3787             }
3788         }
3789     }
3790 
3791     // second, handle previous selections - after the first step the data
3792     // structure of the previously known only contains the 'old' selections
3793     if ( pPrevSelectedParas )
3794     {
3795         SwAccessibleSelectedParas_Impl::iterator aIter = pPrevSelectedParas->begin();
3796         for ( ; aIter != pPrevSelectedParas->end(); ++aIter )
3797         {
3798             uno::Reference < XAccessible > xAcc( (*aIter).first );
3799             if ( xAcc.is() )
3800             {
3801                 ::vos::ORef < SwAccessibleContext > xAccImpl(
3802                             static_cast<SwAccessibleContext*>( xAcc.get() ) );
3803                 if ( xAccImpl.isValid() && xAccImpl->GetFrm() )
3804                 {
3805                     const SwTxtFrm* pTxtFrm(
3806                             dynamic_cast<const SwTxtFrm*>(xAccImpl->GetFrm()) );
3807                     ASSERT( pTxtFrm,
3808                             "<SwAccessibleMap::_SubmitTextSelectionChangedEvents()> - unexcepted type of frame" );
3809                     if ( pTxtFrm )
3810                     {
3811                         InvalidateParaTextSelection( *pTxtFrm );
3812                     }
3813                 }
3814             }
3815         }
3816 
3817         delete pPrevSelectedParas;
3818     }
3819 }
3820 
GetVisArea() const3821 const SwRect& SwAccessibleMap::GetVisArea() const
3822 {
3823     DBG_ASSERT( !GetShell()->IsPreView() || (mpPreview != NULL),
3824                 "preview without preview data?" );
3825 
3826     return GetShell()->IsPreView()
3827            ? mpPreview->GetVisArea()
3828            : GetShell()->VisArea();
3829 }
3830 
IsDocumentSelAll()3831 sal_Bool SwAccessibleMap::IsDocumentSelAll()
3832 {
3833     return GetShell()->GetDoc()->IsPrepareSelAll();
3834 }
3835 
3836