xref: /aoo42x/main/sw/source/core/access/accmap.cxx (revision cdf0e10c)
1  /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sw.hxx"
30 
31 
32 #include <vos/ref.hxx>
33 #include <cppuhelper/weakref.hxx>
34 #include <vcl/window.hxx>
35 #include <svx/svdmodel.hxx>
36 #include <svx/unomod.hxx>
37 #include <tools/debug.hxx>
38 
39 #include <map>
40 #include <list>
41 #include <accmap.hxx>
42 #include <acccontext.hxx>
43 #include <accdoc.hxx>
44 #include <accpreview.hxx>
45 #include <accpage.hxx>
46 #include <accpara.hxx>
47 #include <accheaderfooter.hxx>
48 #include <accfootnote.hxx>
49 #include <acctextframe.hxx>
50 #include <accgraphic.hxx>
51 #include <accembedded.hxx>
52 #include <acccell.hxx>
53 #include <acctable.hxx>
54 #include <fesh.hxx>
55 #include <rootfrm.hxx>
56 #include <txtfrm.hxx>
57 #include <hffrm.hxx>
58 #include <ftnfrm.hxx>
59 #include <cellfrm.hxx>
60 #include <tabfrm.hxx>
61 #include <pagefrm.hxx>
62 #include <flyfrm.hxx>
63 #include <ndtyp.hxx>
64 #include <IDocumentDrawModelAccess.hxx>
65 #include <svx/ShapeTypeHandler.hxx>
66 #include <vcl/svapp.hxx>
67 #include <com/sun/star/accessibility/AccessibleRelationType.hpp>
68 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
69 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
70 #include <cppuhelper/implbase1.hxx>
71 #include <pagepreviewlayout.hxx>
72 #include <pam.hxx>
73 #include <ndtxt.hxx>
74 #include <dflyobj.hxx>
75 #include <prevwpage.hxx>
76 #include <switerator.hxx>
77 
78 using namespace ::com::sun::star;
79 using namespace ::com::sun::star::accessibility;
80 using ::rtl::OUString;
81 using namespace ::sw::access;
82 
83 struct SwFrmFunc
84 {
85 	sal_Bool operator()( const SwFrm * p1,
86 				    	 const SwFrm * p2) const
87 	{
88 		return p1 < p2;
89 	}
90 };
91 
92 typedef ::std::map < const SwFrm *, uno::WeakReference < XAccessible >, SwFrmFunc > _SwAccessibleContextMap_Impl;
93 
94 class SwAccessibleContextMap_Impl: public _SwAccessibleContextMap_Impl
95 {
96 public:
97 
98 #ifdef DBG_UTIL
99 	sal_Bool mbLocked;
100 #endif
101 
102 	SwAccessibleContextMap_Impl()
103 #ifdef DBG_UTIL
104 		: mbLocked( sal_False )
105 #endif
106 	{}
107 
108 };
109 
110 //------------------------------------------------------------------------------
111 class SwDrawModellListener_Impl : public SfxListener,
112 	public ::cppu::WeakImplHelper1< document::XEventBroadcaster >
113 {
114 	mutable ::osl::Mutex maListenerMutex;
115 	::cppu::OInterfaceContainerHelper maEventListeners;
116 	SdrModel *mpDrawModel;
117 protected:
118 	virtual ~SwDrawModellListener_Impl();
119 public:
120 
121 	SwDrawModellListener_Impl( SdrModel *pDrawModel );
122 
123 
124     virtual void SAL_CALL addEventListener( const uno::Reference< document::XEventListener >& xListener ) throw (uno::RuntimeException);
125     virtual void SAL_CALL removeEventListener( const uno::Reference< document::XEventListener >& xListener ) throw (uno::RuntimeException);
126 
127 	virtual void		Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
128 	void Dispose();
129 };
130 
131 SwDrawModellListener_Impl::SwDrawModellListener_Impl( SdrModel *pDrawModel ) :
132 	maEventListeners( maListenerMutex ),
133 	mpDrawModel( pDrawModel )
134 {
135 	StartListening( *mpDrawModel );
136 }
137 
138 SwDrawModellListener_Impl::~SwDrawModellListener_Impl()
139 {
140 	EndListening( *mpDrawModel );
141 }
142 
143 void SAL_CALL SwDrawModellListener_Impl::addEventListener( const uno::Reference< document::XEventListener >& xListener ) throw (uno::RuntimeException)
144 {
145 	maEventListeners.addInterface( xListener );
146 }
147 
148 void SAL_CALL SwDrawModellListener_Impl::removeEventListener( const uno::Reference< document::XEventListener >& xListener ) throw (uno::RuntimeException)
149 {
150 	maEventListeners.removeInterface( xListener );
151 }
152 
153 void SwDrawModellListener_Impl::Notify( SfxBroadcaster& /*rBC*/,
154 		const SfxHint& rHint )
155 {
156 	// do not broadcast notifications for writer fly frames, because there
157 	// are no shapes that need to know about them.
158     // OD 01.07.2003 #110554# - correct condition in order not to broadcast
159     // notifications for writer fly frames.
160     // OD 01.07.2003 #110554# - do not broadcast notifications for plane
161     // <SdrObject>objects
162 	const SdrHint *pSdrHint = PTR_CAST( SdrHint, &rHint );
163     if ( !pSdrHint ||
164          ( pSdrHint->GetObject() &&
165            ( pSdrHint->GetObject()->ISA(SwFlyDrawObj) ||
166              pSdrHint->GetObject()->ISA(SwVirtFlyDrawObj) ||
167              IS_TYPE(SdrObject,pSdrHint->GetObject()) ) ) )
168     {
169         return;
170     }
171 
172 	ASSERT( mpDrawModel, "draw model listener is disposed" );
173 	if( !mpDrawModel )
174 		return;
175 
176 	document::EventObject aEvent;
177 	if( !SvxUnoDrawMSFactory::createEvent( mpDrawModel, pSdrHint, aEvent ) )
178 		return;
179 
180 	::cppu::OInterfaceIteratorHelper aIter( maEventListeners );
181 	while( aIter.hasMoreElements() )
182 	{
183 		uno::Reference < document::XEventListener > xListener( aIter.next(),
184 												uno::UNO_QUERY );
185 		try
186 		{
187 			xListener->notifyEvent( aEvent );
188 		}
189 		catch( uno::RuntimeException const & r )
190 		{
191             (void)r;
192 #if OSL_DEBUG_LEVEL > 1
193 			ByteString aError( "Runtime exception caught while notifying shape.:\n" );
194 			aError += ByteString( String( r.Message), RTL_TEXTENCODING_ASCII_US );
195 			DBG_ERROR( aError.GetBuffer() );
196 #endif
197 		}
198 	}
199 }
200 
201 void SwDrawModellListener_Impl::Dispose()
202 {
203 	mpDrawModel = 0;
204 }
205 
206 //------------------------------------------------------------------------------
207 struct SwShapeFunc
208 {
209 	sal_Bool operator()( const SdrObject * p1,
210 				    	 const SdrObject * p2) const
211 	{
212 		return p1 < p2;
213 	}
214 };
215 typedef ::std::map < const SdrObject *, uno::WeakReference < XAccessible >, SwShapeFunc > _SwAccessibleShapeMap_Impl;
216 typedef ::std::pair < const SdrObject *, ::vos::ORef < ::accessibility::AccessibleShape > > SwAccessibleObjShape_Impl;
217 
218 class SwAccessibleShapeMap_Impl: public _SwAccessibleShapeMap_Impl
219 
220 {
221 	::accessibility::AccessibleShapeTreeInfo maInfo;
222 
223 public:
224 
225 #ifdef DBG_UTIL
226 	sal_Bool mbLocked;
227 #endif
228 	SwAccessibleShapeMap_Impl( SwAccessibleMap *pMap )
229 #ifdef DBG_UTIL
230 		: mbLocked( sal_False )
231 #endif
232 	{
233 		maInfo.SetSdrView( pMap->GetShell()->GetDrawView() );
234 		maInfo.SetWindow( pMap->GetShell()->GetWin() );
235 		maInfo.SetViewForwarder( pMap );
236         // --> OD 2005-08-08 #i52858# - method name changed
237 		uno::Reference < document::XEventBroadcaster > xModelBroadcaster =
238 			new SwDrawModellListener_Impl(
239                     pMap->GetShell()->getIDocumentDrawModelAccess()->GetOrCreateDrawModel() );
240         // <--
241 		maInfo.SetControllerBroadcaster( xModelBroadcaster );
242 	}
243 
244 	~SwAccessibleShapeMap_Impl();
245 
246 	const ::accessibility::AccessibleShapeTreeInfo& GetInfo() const { return maInfo; }
247 
248 	SwAccessibleObjShape_Impl *Copy( size_t& rSize,
249 		const SwFEShell *pFESh = 0,
250 		SwAccessibleObjShape_Impl  **pSelShape = 0 ) const;
251 };
252 
253 SwAccessibleShapeMap_Impl::~SwAccessibleShapeMap_Impl()
254 {
255 	uno::Reference < document::XEventBroadcaster > xBrd( maInfo.GetControllerBroadcaster() );
256 	if( xBrd.is() )
257 		static_cast < SwDrawModellListener_Impl * >( xBrd.get() )->Dispose();
258 }
259 
260 SwAccessibleObjShape_Impl
261 	*SwAccessibleShapeMap_Impl::Copy(
262 			size_t& rSize, const SwFEShell *pFESh,
263 			SwAccessibleObjShape_Impl **pSelStart ) const
264 {
265 	SwAccessibleObjShape_Impl *pShapes = 0;
266 	SwAccessibleObjShape_Impl *pSelShape = 0;
267 
268 	sal_uInt16 nSelShapes = pFESh ? pFESh->IsObjSelected() : 0;
269 	rSize = size();
270 
271 	if( rSize > 0 )
272 	{
273 		pShapes =
274 			new SwAccessibleObjShape_Impl[rSize];
275 
276 		const_iterator aIter = begin();
277 		const_iterator aEndIter = end();
278 
279 		SwAccessibleObjShape_Impl *pShape = pShapes;
280 		pSelShape = &(pShapes[rSize]);
281 		while( aIter != aEndIter )
282 		{
283 			const SdrObject *pObj = (*aIter).first;
284 			uno::Reference < XAccessible > xAcc( (*aIter).second );
285 			if( nSelShapes && pFESh->IsObjSelected( *pObj ) )
286 			{
287 				// selected objects are inserted from the back
288 				--pSelShape;
289 				pSelShape->first = pObj;
290 				pSelShape->second =
291 					static_cast < ::accessibility::AccessibleShape* >(
292 													xAcc.get() );
293 				--nSelShapes;
294 			}
295 			else
296 			{
297 				pShape->first = pObj;
298 				pShape->second =
299 					static_cast < ::accessibility::AccessibleShape* >(
300 													xAcc.get() );
301 				++pShape;
302 			}
303 			++aIter;
304 		}
305 		ASSERT( pSelShape == pShape, "copying shapes went wrong!" );
306 	}
307 
308 	if( pSelStart )
309 		*pSelStart = pSelShape;
310 
311 	return pShapes;
312 }
313 
314 //------------------------------------------------------------------------------
315 struct SwAccessibleEvent_Impl
316 {
317 public:
318     enum EventType { CARET_OR_STATES,
319                      INVALID_CONTENT,
320                      POS_CHANGED,
321                      CHILD_POS_CHANGED,
322                      SHAPE_SELECTION,
323                      DISPOSE,
324                      INVALID_ATTR };
325 
326 private:
327 	SwRect		maOldBox;				// the old bounds for CHILD_POS_CHANGED
328 										// and POS_CHANGED
329 	uno::WeakReference < XAccessible > mxAcc;	// The object that fires the event
330     SwAccessibleChild   maFrmOrObj;             // the child for CHILD_POS_CHANGED and
331 										// the same as xAcc for any other
332 										// event type
333 	EventType 	meType;					// The event type
334     // --> OD 2005-12-12 #i27301# - use new type definition for <mnStates>
335     tAccessibleStates mnStates;         // check states or update caret pos
336     // <--
337 
338 	SwAccessibleEvent_Impl& operator==( const SwAccessibleEvent_Impl& );
339 
340 public:
341     SwAccessibleEvent_Impl( EventType eT,
342                             SwAccessibleContext *pA,
343                             const SwAccessibleChild& rFrmOrObj )
344         : mxAcc( pA ),
345           maFrmOrObj( rFrmOrObj ),
346           meType( eT ),
347           mnStates( 0 )
348 	{}
349 
350     SwAccessibleEvent_Impl( EventType eT,
351                             const SwAccessibleChild& rFrmOrObj )
352         : maFrmOrObj( rFrmOrObj ),
353           meType( eT ),
354           mnStates( 0 )
355 	{
356 		ASSERT( SwAccessibleEvent_Impl::DISPOSE == meType,
357 				"wrong event constructor, DISPOSE only" );
358 	}
359 
360     SwAccessibleEvent_Impl( EventType eT )
361         : meType( eT ),
362           mnStates( 0 )
363 	{
364         ASSERT( SwAccessibleEvent_Impl::SHAPE_SELECTION == meType,
365 				"wrong event constructor, SHAPE_SELECTION only" );
366 	}
367 
368     SwAccessibleEvent_Impl( EventType eT,
369                             SwAccessibleContext *pA,
370                             const SwAccessibleChild& rFrmOrObj,
371                             const SwRect& rR )
372         : maOldBox( rR ),
373           mxAcc( pA ),
374           maFrmOrObj( rFrmOrObj ),
375           meType( eT ),
376           mnStates( 0 )
377 	{
378 		ASSERT( SwAccessibleEvent_Impl::CHILD_POS_CHANGED == meType ||
379 				SwAccessibleEvent_Impl::POS_CHANGED == meType,
380 				"wrong event constructor, (CHILD_)POS_CHANGED only" );
381 	}
382 
383     // --> OD 2005-12-12 #i27301# - use new type definition for parameter <_nStates>
384     SwAccessibleEvent_Impl( EventType eT,
385                             SwAccessibleContext *pA,
386                             const SwAccessibleChild& rFrmOrObj,
387                             const tAccessibleStates _nStates )
388         : mxAcc( pA ),
389           maFrmOrObj( rFrmOrObj ),
390           meType( eT ),
391           mnStates( _nStates )
392 	{
393 		ASSERT( SwAccessibleEvent_Impl::CARET_OR_STATES == meType,
394 				"wrong event constructor, CARET_OR_STATES only" );
395 	}
396 
397     // <SetType(..)> only used in method <SwAccessibleMap::AppendEvent(..)>
398     inline void SetType( EventType eT )
399     {
400         meType = eT;
401     }
402     inline EventType GetType() const
403     {
404         return meType;
405     }
406 
407     inline ::vos::ORef < SwAccessibleContext > GetContext() const
408     {
409         uno::Reference < XAccessible > xTmp( mxAcc );
410         ::vos::ORef < SwAccessibleContext > xAccImpl(
411                             static_cast<SwAccessibleContext*>( xTmp.get() ) );
412 
413         return xAccImpl;
414     }
415 
416     inline const SwRect& GetOldBox() const
417     {
418         return maOldBox;
419     }
420     // <SetOldBox(..)> only used in method <SwAccessibleMap::AppendEvent(..)>
421     inline void SetOldBox( const SwRect& rOldBox )
422     {
423         maOldBox = rOldBox;
424     }
425 
426     inline const SwAccessibleChild& GetFrmOrObj() const
427     {
428         return maFrmOrObj;
429     }
430 
431     // <SetStates(..)> only used in method <SwAccessibleMap::AppendEvent(..)>
432     // --> OD 2005-12-12 #i27301# - use new type definition for parameter <_nStates>
433     inline void SetStates( tAccessibleStates _nStates )
434     {
435         mnStates |= _nStates;
436     }
437     // <--
438 
439     inline sal_Bool IsUpdateCursorPos() const
440     {
441         return (mnStates & ACC_STATE_CARET) != 0;
442     }
443     inline sal_Bool IsInvalidateStates() const
444     {
445         return (mnStates & ACC_STATE_MASK) != 0;
446     }
447     inline sal_Bool IsInvalidateRelation() const
448     {
449         return (mnStates & ACC_STATE_RELATION_MASK) != 0;
450     }
451     // --> OD 2005-12-12 #i27301# - new event TEXT_SELECTION_CHANGED
452     inline sal_Bool IsInvalidateTextSelection() const
453     {
454         return ( mnStates & ACC_STATE_TEXT_SELECTION_CHANGED ) != 0;
455     }
456     // <--
457     // --> OD 2009-01-07 #i88069# - new event TEXT_ATTRIBUTE_CHANGED
458     inline sal_Bool IsInvalidateTextAttrs() const
459     {
460         return ( mnStates & ACC_STATE_TEXT_ATTRIBUTE_CHANGED ) != 0;
461     }
462     // <--
463     // --> OD 2005-12-12 #i27301# - use new type definition <tAccessibleStates>
464     // for return value
465     inline tAccessibleStates GetStates() const
466     {
467         return mnStates & ACC_STATE_MASK;
468     }
469     // <--
470     // --> OD 2005-12-12 #i27301# - use new type definition <tAccessibleStates>
471     // for return value
472     inline tAccessibleStates GetAllStates() const
473     {
474         return mnStates;
475     }
476     // <--
477 };
478 
479 //------------------------------------------------------------------------------
480 typedef ::std::list < SwAccessibleEvent_Impl > _SwAccessibleEventList_Impl;
481 
482 class SwAccessibleEventList_Impl: public _SwAccessibleEventList_Impl
483 {
484 	sal_Bool mbFiring;
485 
486 public:
487 
488     SwAccessibleEventList_Impl()
489         : mbFiring( sal_False )
490     {}
491 
492     inline void SetFiring()
493     {
494         mbFiring = sal_True;
495     }
496     inline sal_Bool IsFiring() const
497     {
498         return mbFiring;
499     }
500 };
501 
502 //------------------------------------------------------------------------------
503 // The shape list is filled if an accessible shape is destroyed. It
504 // simply keeps a reference to the accessible shape's XShape. These
505 // references are destroyed within the EndAction when firing events,
506 // There are twp reason for this. First of all, a new accessible shape
507 // for the XShape might be created soon. It's then cheaper if the XShape
508 // still exists. The other reason are situations where an accessible shape
509 // is destroyed within an SwFrmFmt::Modify. In this case, destryoing
510 // the XShape at the same time (indirectly by destroying the accessible
511 // shape) leads to an assert, because a client of the Modify is destroyed
512 // within a Modify call.
513 
514 typedef ::std::list < uno::Reference < drawing::XShape > > _SwShapeList_Impl;
515 
516 class SwShapeList_Impl: public _SwShapeList_Impl
517 {
518 public:
519 
520 	SwShapeList_Impl() {}
521 };
522 
523 
524 //------------------------------------------------------------------------------
525 struct SwAccessibleChildFunc
526 {
527     sal_Bool operator()( const SwAccessibleChild& r1,
528                          const SwAccessibleChild& r2 ) const
529 	{
530 		const void *p1 = r1.GetSwFrm()
531                          ? static_cast < const void * >( r1.GetSwFrm())
532                          : ( r1.GetDrawObject()
533                              ? static_cast < const void * >( r1.GetDrawObject() )
534                              : static_cast < const void * >( r1.GetWindow() ) );
535 		const void *p2 = r2.GetSwFrm()
536                          ? static_cast < const void * >( r2.GetSwFrm())
537                          : ( r2.GetDrawObject()
538                              ? static_cast < const void * >( r2.GetDrawObject() )
539                              : static_cast < const void * >( r2.GetWindow() ) );
540 		return p1 < p2;
541 	}
542 };
543 typedef ::std::map < SwAccessibleChild, SwAccessibleEventList_Impl::iterator,
544                      SwAccessibleChildFunc > _SwAccessibleEventMap_Impl;
545 
546 class SwAccessibleEventMap_Impl: public _SwAccessibleEventMap_Impl
547 {
548 };
549 
550 //------------------------------------------------------------------------------
551 // --> OD 2005-12-13 #i27301# - map containing the accessible paragraph, which
552 // have a selection. Needed to keep this information to submit corresponding
553 // TEXT_SELECTION_CHANGED events.
554 struct SwAccessibleParaSelection
555 {
556     xub_StrLen nStartOfSelection;
557     xub_StrLen nEndOfSelection;
558 
559     SwAccessibleParaSelection( const xub_StrLen _nStartOfSelection,
560                                const xub_StrLen _nEndOfSelection )
561         : nStartOfSelection( _nStartOfSelection ),
562           nEndOfSelection( _nEndOfSelection )
563     {}
564 };
565 
566 struct SwXAccWeakRefComp
567 {
568     sal_Bool operator()( const uno::WeakReference<XAccessible>& _rXAccWeakRef1,
569                          const uno::WeakReference<XAccessible>& _rXAccWeakRef2 ) const
570     {
571         return _rXAccWeakRef1.get() < _rXAccWeakRef2.get();
572     }
573 };
574 
575 typedef ::std::map< uno::WeakReference < XAccessible >,
576                     SwAccessibleParaSelection,
577                     SwXAccWeakRefComp > _SwAccessibleSelectedParas_Impl;
578 
579 class SwAccessibleSelectedParas_Impl: public _SwAccessibleSelectedParas_Impl
580 {};
581 // <--
582 
583 // helper class that stores preview data
584 class SwAccPreviewData
585 {
586     typedef std::vector<Rectangle> Rectangles;
587     Rectangles maPreviewRects;
588     Rectangles maLogicRects;
589 
590     SwRect maVisArea;
591     Fraction maScale;
592 
593     const SwPageFrm *mpSelPage;
594 
595     /** adjust logic page retangle to its visible part
596 
597         OD 17.01.2003 #103492#
598 
599         @author OD
600 
601         @param _iorLogicPgSwRect
602         input/output parameter - reference to the logic page rectangle, which
603         has to be adjusted.
604 
605         @param _rPrevwPgSwRect
606         input parameter - constant reference to the corresponding preview page
607         rectangle; needed to determine the visible part of the logic page rectangle.
608 
609         @param _rPrevwWinSize
610         input paramter - constant reference to the preview window size in TWIP;
611         needed to determine the visible part of the logic page rectangle
612     */
613     void AdjustLogicPgRectToVisibleArea( SwRect&         _iorLogicPgSwRect,
614                                          const SwRect&   _rPrevwPgSwRect,
615                                          const Size&     _rPrevwWinSize );
616 
617 public:
618     SwAccPreviewData();
619     ~SwAccPreviewData();
620 
621     // OD 14.01.2003 #103492# - complete re-factoring of method due to new
622     // page/print preview functionality.
623     void Update( const SwAccessibleMap& rAccMap,
624                  const std::vector<PrevwPage*>& _rPrevwPages,
625                  const Fraction&  _rScale,
626                  const SwPageFrm* _pSelectedPageFrm,
627                  const Size&      _rPrevwWinSize );
628 
629     // OD 14.01.2003 #103492# - complete re-factoring of method due to new
630     // page/print preview functionality.
631     void InvalidateSelection( const SwPageFrm* _pSelectedPageFrm );
632 
633     const SwRect& GetVisArea() const;
634 
635     MapMode GetMapModeForPreview( ) const;
636 
637     /** Adjust the MapMode so that the preview page appears at the
638      * proper position. rPoint identifies the page for which the
639      * MapMode should be adjusted. If bFromPreview is true, rPoint is
640      * a preview coordinate; else it's a document coordinate. */
641     // OD 17.01.2003 #103492# - delete unused 3rd parameter.
642     void AdjustMapMode( MapMode& rMapMode,
643                         const Point& rPoint ) const;
644 
645     inline const SwPageFrm *GetSelPage() const { return mpSelPage; }
646 
647     void DisposePage(const SwPageFrm *pPageFrm );
648 };
649 
650 SwAccPreviewData::SwAccPreviewData() :
651     mpSelPage( 0 )
652 {
653 }
654 
655 SwAccPreviewData::~SwAccPreviewData()
656 {
657 }
658 
659 // OD 13.01.2003 #103492# - complete re-factoring of method due to new page/print
660 // preview functionality.
661 void SwAccPreviewData::Update( const SwAccessibleMap& rAccMap,
662                                const std::vector<PrevwPage*>& _rPrevwPages,
663                                const Fraction&  _rScale,
664                                const SwPageFrm* _pSelectedPageFrm,
665                                const Size&      _rPrevwWinSize )
666 {
667     // store preview scaling, maximal preview page size and selected page
668     maScale = _rScale;
669     mpSelPage = _pSelectedPageFrm;
670 
671     // prepare loop on preview pages
672     maPreviewRects.clear();
673     maLogicRects.clear();
674     SwAccessibleChild aPage;
675     maVisArea.Clear();
676 
677     // loop on preview pages to calculate <maPreviewRects>, <maLogicRects> and
678     // <maVisArea>
679     for ( std::vector<PrevwPage*>::const_iterator aPageIter = _rPrevwPages.begin();
680           aPageIter != _rPrevwPages.end();
681           ++aPageIter )
682     {
683         aPage = (*aPageIter)->pPage;
684 
685         // add preview page rectangle to <maPreviewRects>
686         Rectangle aPrevwPgRect( (*aPageIter)->aPrevwWinPos, (*aPageIter)->aPageSize );
687         maPreviewRects.push_back( aPrevwPgRect );
688 
689         // add logic page rectangle to <maLogicRects>
690         SwRect aLogicPgSwRect( aPage.GetBox( rAccMap ) );
691         Rectangle aLogicPgRect( aLogicPgSwRect.SVRect() );
692         maLogicRects.push_back( aLogicPgRect );
693         // union visible area with visible part of logic page rectangle
694         if ( (*aPageIter)->bVisible )
695         {
696             if ( !(*aPageIter)->pPage->IsEmptyPage() )
697             {
698                 AdjustLogicPgRectToVisibleArea( aLogicPgSwRect,
699                                                 SwRect( aPrevwPgRect ),
700                                                 _rPrevwWinSize );
701             }
702             if ( maVisArea.IsEmpty() )
703                 maVisArea = aLogicPgSwRect;
704             else
705                 maVisArea.Union( aLogicPgSwRect );
706         }
707     }
708 }
709 
710 // OD 16.01.2003 #103492# - complete re-factoring of method due to new page/print
711 // preview functionality.
712 void SwAccPreviewData::InvalidateSelection( const SwPageFrm* _pSelectedPageFrm )
713 {
714     mpSelPage = _pSelectedPageFrm;
715     ASSERT( mpSelPage, "selected page not found" );
716 }
717 
718 struct ContainsPredicate
719 {
720     const Point& mrPoint;
721     ContainsPredicate( const Point& rPoint ) : mrPoint(rPoint) {}
722     bool operator() ( const Rectangle& rRect ) const
723     {
724         return rRect.IsInside( mrPoint ) ? true : false;
725     }
726 };
727 
728 const SwRect& SwAccPreviewData::GetVisArea() const
729 {
730     return maVisArea;
731 }
732 
733 void SwAccPreviewData::AdjustMapMode( MapMode& rMapMode,
734                                       const Point& rPoint ) const
735 {
736     // adjust scale
737     rMapMode.SetScaleX( maScale );
738     rMapMode.SetScaleY( maScale );
739 
740     // find proper rectangle
741     Rectangles::const_iterator aBegin = maLogicRects.begin();
742     Rectangles::const_iterator aEnd = maLogicRects.end();
743     Rectangles::const_iterator aFound = ::std::find_if( aBegin, aEnd,
744                                                  ContainsPredicate( rPoint ) );
745 
746     if( aFound != aEnd )
747     {
748         // found! set new origin
749         Point aPoint = (maPreviewRects.begin() + (aFound - aBegin))->TopLeft();
750         aPoint -= (maLogicRects.begin() + (aFound-aBegin))->TopLeft();
751         rMapMode.SetOrigin( aPoint );
752     }
753     // else: don't adjust MapMode
754 }
755 
756 void SwAccPreviewData::DisposePage(const SwPageFrm *pPageFrm )
757 {
758     if( mpSelPage == pPageFrm )
759         mpSelPage = 0;
760 }
761 
762 /** adjust logic page retangle to its visible part
763 
764     OD 17.01.2003 #103492#
765 
766     @author OD
767 */
768 void SwAccPreviewData::AdjustLogicPgRectToVisibleArea(
769                             SwRect&         _iorLogicPgSwRect,
770                             const SwRect&   _rPrevwPgSwRect,
771                             const Size&     _rPrevwWinSize )
772 {
773     // determine preview window rectangle
774     const SwRect aPrevwWinSwRect( Point( 0, 0 ), _rPrevwWinSize );
775     // calculate visible preview page rectangle
776     SwRect aVisPrevwPgSwRect( _rPrevwPgSwRect );
777     aVisPrevwPgSwRect.Intersection( aPrevwWinSwRect );
778     // adjust logic page rectangle
779     SwTwips nTmpDiff;
780     // left
781     nTmpDiff = aVisPrevwPgSwRect.Left() - _rPrevwPgSwRect.Left();
782     if ( nTmpDiff > 0 )
783         _iorLogicPgSwRect.Left( _iorLogicPgSwRect.Left() + nTmpDiff );
784     // top
785     nTmpDiff = aVisPrevwPgSwRect.Top() - _rPrevwPgSwRect.Top();
786     if ( nTmpDiff > 0 )
787         _iorLogicPgSwRect.Top( _iorLogicPgSwRect.Top() + nTmpDiff );
788     // right
789     nTmpDiff = _rPrevwPgSwRect.Right() - aVisPrevwPgSwRect.Right();
790     if ( nTmpDiff > 0 )
791         _iorLogicPgSwRect.Right( _iorLogicPgSwRect.Right() - nTmpDiff );
792     // bottom
793     nTmpDiff = _rPrevwPgSwRect.Bottom() - aVisPrevwPgSwRect.Bottom();
794     if ( nTmpDiff > 0 )
795         _iorLogicPgSwRect.Bottom( _iorLogicPgSwRect.Bottom() - nTmpDiff );
796 }
797 
798 //------------------------------------------------------------------------------
799 static sal_Bool AreInSameTable( const uno::Reference< XAccessible >& rAcc,
800 					  		    const SwFrm *pFrm )
801 {
802 	sal_Bool bRet = sal_False;
803 
804 	if( pFrm && pFrm->IsCellFrm() && rAcc.is() )
805 	{
806 		// Is it in the same table? We check that
807 		// by comparing the last table frame in the
808 		// follow chain, because that's cheaper than
809 		// searching the first one.
810 		SwAccessibleContext *pAccImpl =
811 			static_cast< SwAccessibleContext *>( rAcc.get() );
812 		if( pAccImpl->GetFrm()->IsCellFrm() )
813 		{
814 			const SwTabFrm *pTabFrm1 = pAccImpl->GetFrm()->FindTabFrm();
815 			while( pTabFrm1->GetFollow() )
816 				   pTabFrm1 = pTabFrm1->GetFollow();
817 
818 			const SwTabFrm *pTabFrm2 = pFrm->FindTabFrm();
819 			while( pTabFrm2->GetFollow() )
820 				   pTabFrm2 = pTabFrm2->GetFollow();
821 
822 			bRet = (pTabFrm1 == pTabFrm2);
823 		}
824 	}
825 
826 	return bRet;
827 }
828 
829 void SwAccessibleMap::FireEvent( const SwAccessibleEvent_Impl& rEvent )
830 {
831 	::vos::ORef < SwAccessibleContext > xAccImpl( rEvent.GetContext() );
832 	if( SwAccessibleEvent_Impl::SHAPE_SELECTION == rEvent.GetType() )
833 	{
834 		DoInvalidateShapeSelection();
835 	}
836 	else if( xAccImpl.isValid() && xAccImpl->GetFrm() )
837 	{
838         // --> OD 2009-01-07 #i88069#
839         if ( rEvent.GetType() != SwAccessibleEvent_Impl::DISPOSE &&
840              rEvent.IsInvalidateTextAttrs() )
841         {
842             xAccImpl->InvalidateAttr();
843         }
844         // <--
845 		switch( rEvent.GetType() )
846 		{
847 		case SwAccessibleEvent_Impl::INVALID_CONTENT:
848 			xAccImpl->InvalidateContent();
849 			break;
850 		case SwAccessibleEvent_Impl::POS_CHANGED:
851 			xAccImpl->InvalidatePosOrSize( rEvent.GetOldBox() );
852 			break;
853 		case SwAccessibleEvent_Impl::CHILD_POS_CHANGED:
854 			xAccImpl->InvalidateChildPosOrSize( rEvent.GetFrmOrObj(),
855 									   rEvent.GetOldBox() );
856 			break;
857 		case SwAccessibleEvent_Impl::DISPOSE:
858 			ASSERT( xAccImpl.isValid(),
859 					"dispose event has been stored" );
860 			break;
861         // --> OD 2009-01-06 #i88069#
862         case SwAccessibleEvent_Impl::INVALID_ATTR:
863             // nothing to do here - handled above
864             break;
865         // <--
866 		default:
867 			break;
868 		}
869 		if( SwAccessibleEvent_Impl::DISPOSE != rEvent.GetType() )
870 		{
871 			if( rEvent.IsUpdateCursorPos() )
872 				xAccImpl->InvalidateCursorPos();
873 			if( rEvent.IsInvalidateStates() )
874 				xAccImpl->InvalidateStates( rEvent.GetStates() );
875             if( rEvent.IsInvalidateRelation() )
876             {
877                 // --> OD 2005-12-01 #i27138#
878                 // both events CONTENT_FLOWS_FROM_RELATION_CHANGED and
879                 // CONTENT_FLOWS_TO_RELATION_CHANGED are possible
880                 if ( rEvent.GetAllStates() & ACC_STATE_RELATION_FROM )
881                 {
882                     xAccImpl->InvalidateRelation(
883                         AccessibleEventId::CONTENT_FLOWS_FROM_RELATION_CHANGED );
884                 }
885                 if ( rEvent.GetAllStates() & ACC_STATE_RELATION_TO )
886                 {
887                     xAccImpl->InvalidateRelation(
888                         AccessibleEventId::CONTENT_FLOWS_TO_RELATION_CHANGED );
889                 }
890                 // <--
891             }
892             // --> OD 2005-12-12 #i27301# - submit event TEXT_SELECTION_CHANGED
893             if ( rEvent.IsInvalidateTextSelection() )
894             {
895                 xAccImpl->InvalidateTextSelection();
896             }
897             // <--
898 		}
899 	}
900 }
901 
902 void SwAccessibleMap::AppendEvent( const SwAccessibleEvent_Impl& rEvent )
903 {
904 	vos::OGuard aGuard( maEventMutex );
905 
906 	if( !mpEvents )
907 		mpEvents = new SwAccessibleEventList_Impl;
908 	if( !mpEventMap )
909 		mpEventMap = new SwAccessibleEventMap_Impl;
910 
911 	if( mpEvents->IsFiring() )
912 	{
913 		// While events are fired new ones are generated. They have to be fired
914 		// now. This does not work for DISPOSE events!
915 		ASSERT( rEvent.GetType() != SwAccessibleEvent_Impl::DISPOSE,
916 				"dispose event while firing events" );
917 		FireEvent( rEvent );
918 	}
919 	else
920 	{
921 
922 		SwAccessibleEventMap_Impl::iterator aIter =
923                                         mpEventMap->find( rEvent.GetFrmOrObj() );
924 		if( aIter != mpEventMap->end() )
925 		{
926 			SwAccessibleEvent_Impl aEvent( *(*aIter).second );
927 			ASSERT( aEvent.GetType() != SwAccessibleEvent_Impl::DISPOSE,
928 					"dispose events should not be stored" );
929 			sal_Bool bAppendEvent = sal_True;
930 			switch( rEvent.GetType() )
931 			{
932 			case SwAccessibleEvent_Impl::CARET_OR_STATES:
933 				// A CARET_OR_STATES event is added to any other
934 				// event only. It is broadcasted after any other event, so the
935 				// event should be put to the back.
936                 ASSERT( aEvent.GetType() != SwAccessibleEvent_Impl::CHILD_POS_CHANGED,
937 						"invalid event combination" );
938 				aEvent.SetStates( rEvent.GetAllStates() );
939 				break;
940 			case SwAccessibleEvent_Impl::INVALID_CONTENT:
941 				// An INVALID_CONTENT event overwrites a CARET_OR_STATES
942 				// event (but keeps its flags) and it is contained in a
943 				// POS_CHANGED event.
944 				// Therefor, the event's type has to be adapted and the event
945 				// has to be put at the end.
946                 ASSERT( aEvent.GetType() != SwAccessibleEvent_Impl::CHILD_POS_CHANGED,
947 						"invalid event combination" );
948                 if( aEvent.GetType() == SwAccessibleEvent_Impl::CARET_OR_STATES )
949 					aEvent.SetType( SwAccessibleEvent_Impl::INVALID_CONTENT );
950 				break;
951 			case SwAccessibleEvent_Impl::POS_CHANGED:
952 				// A pos changed event overwrites CARET_STATES (keeping its
953 				// flags) as well as INVALID_CONTENT. The old box position
954 				// has to be stored however if the old event is not a
955 				// POS_CHANGED itself.
956                 ASSERT( aEvent.GetType() != SwAccessibleEvent_Impl::CHILD_POS_CHANGED,
957 						"invalid event combination" );
958 				if( aEvent.GetType() != SwAccessibleEvent_Impl::POS_CHANGED )
959 					aEvent.SetOldBox( rEvent.GetOldBox() );
960 				aEvent.SetType( SwAccessibleEvent_Impl::POS_CHANGED );
961 				break;
962 			case SwAccessibleEvent_Impl::CHILD_POS_CHANGED:
963 				// CHILD_POS_CHANGED events can only follow CHILD_POS_CHANGED
964 				// events. The only action that needs to be done again is
965 				// to put the old event to the back. The new one cannot be used,
966 				// because we are interested in the old frame bounds.
967                 ASSERT( aEvent.GetType() == SwAccessibleEvent_Impl::CHILD_POS_CHANGED,
968 						"invalid event combination" );
969 				break;
970 			case SwAccessibleEvent_Impl::SHAPE_SELECTION:
971                 ASSERT( aEvent.GetType() == SwAccessibleEvent_Impl::SHAPE_SELECTION,
972 						"invalid event combination" );
973 				break;
974 			case SwAccessibleEvent_Impl::DISPOSE:
975 				// DISPOSE events overwrite all others. They are not stored
976 				// but executed immediatly to avoid broadcasting of
977 				// defunctional objects. So what needs to be done here is to
978 				// remove all events for the frame in question.
979 				bAppendEvent = sal_False;
980 				break;
981             // --> OD 2009-01-06 #i88069#
982             case SwAccessibleEvent_Impl::INVALID_ATTR:
983                 ASSERT( aEvent.GetType() == SwAccessibleEvent_Impl::INVALID_ATTR,
984                         "invalid event combination" );
985                 break;
986             // <--
987 			}
988 			if( bAppendEvent )
989 			{
990 				mpEvents->erase( (*aIter).second );
991 				(*aIter).second = mpEvents->insert( mpEvents->end(), aEvent );
992 			}
993 			else
994 			{
995 				mpEvents->erase( (*aIter).second );
996 				mpEventMap->erase( aIter );
997 			}
998 		}
999 		else if( SwAccessibleEvent_Impl::DISPOSE != rEvent.GetType() )
1000 		{
1001 			SwAccessibleEventMap_Impl::value_type aEntry( rEvent.GetFrmOrObj(),
1002 					mpEvents->insert( mpEvents->end(), rEvent ) );
1003 			mpEventMap->insert( aEntry );
1004 		}
1005 	}
1006 }
1007 
1008 void SwAccessibleMap::InvalidateCursorPosition(
1009 		const uno::Reference< XAccessible >& rAcc )
1010 {
1011 	SwAccessibleContext *pAccImpl =
1012 		static_cast< SwAccessibleContext *>( rAcc.get() );
1013 	ASSERT( pAccImpl, "no caret context" );
1014 	ASSERT( pAccImpl->GetFrm(), "caret context is disposed" );
1015 	if( GetShell()->ActionPend() )
1016 	{
1017         SwAccessibleEvent_Impl aEvent( SwAccessibleEvent_Impl::CARET_OR_STATES,
1018                                        pAccImpl,
1019                                        SwAccessibleChild(pAccImpl->GetFrm()),
1020                                        ACC_STATE_CARET );
1021 		AppendEvent( aEvent );
1022 	}
1023 	else
1024 	{
1025 		FireEvents();
1026 		// While firing events the current frame might have
1027 		// been disposed because it moved out of the vis area.
1028 		// Setting the cursor for such frames is useless and even
1029 		// causes asserts.
1030 		if( pAccImpl->GetFrm() )
1031 			pAccImpl->InvalidateCursorPos();
1032 	}
1033 }
1034 
1035 void SwAccessibleMap::InvalidateShapeSelection()
1036 {
1037 	if( GetShell()->ActionPend() )
1038 	{
1039 		SwAccessibleEvent_Impl aEvent(
1040 			SwAccessibleEvent_Impl::SHAPE_SELECTION );
1041 		AppendEvent( aEvent );
1042 	}
1043 	else
1044 	{
1045 		FireEvents();
1046 		DoInvalidateShapeSelection();
1047 	}
1048 }
1049 
1050 void SwAccessibleMap::DoInvalidateShapeSelection()
1051 {
1052 	SwAccessibleObjShape_Impl *pShapes = 0;
1053 	SwAccessibleObjShape_Impl *pSelShape = 0;
1054 	size_t nShapes = 0;
1055 
1056 	const ViewShell *pVSh = GetShell();
1057 	const SwFEShell *pFESh = pVSh->ISA( SwFEShell ) ?
1058 							static_cast< const SwFEShell * >( pVSh ) : 0;
1059 	sal_uInt16 nSelShapes = pFESh ? pFESh->IsObjSelected() : 0;
1060 
1061 	{
1062 		vos::OGuard aGuard( maMutex );
1063 		if( mpShapeMap )
1064 			pShapes = mpShapeMap->Copy( nShapes, pFESh, &pSelShape );
1065 	}
1066 
1067 	if( pShapes )
1068 	{
1069 		::std::list< const SwFrm * > aParents;
1070 		Window *pWin = GetShell()->GetWin();
1071 		sal_Bool bFocused = pWin && pWin->HasFocus();
1072 		SwAccessibleObjShape_Impl *pShape = pShapes;
1073 		while( nShapes )
1074 		{
1075 			if( pShape->second.isValid() )
1076 			{
1077 				sal_Bool bChanged;
1078 				if( pShape >= pSelShape )
1079 				{
1080 					bChanged =
1081 						pShape->second->SetState( AccessibleStateType::SELECTED );
1082 					if( bFocused && 1 == nSelShapes )
1083 						pShape->second->SetState( AccessibleStateType::FOCUSED );
1084 					else
1085 						pShape->second->ResetState( AccessibleStateType::FOCUSED );
1086 				}
1087 				else
1088 				{
1089 					bChanged =
1090 						pShape->second->ResetState( AccessibleStateType::SELECTED );
1091 					pShape->second->ResetState( AccessibleStateType::FOCUSED );
1092 				}
1093 				if( bChanged )
1094 				{
1095                     const SwFrm* pParent = SwAccessibleFrame::GetParent(
1096                                                     SwAccessibleChild( pShape->first ),
1097                                                     GetShell()->IsPreView() );
1098                     aParents.push_back( pParent );
1099 				}
1100 			}
1101 
1102 			--nShapes;
1103 			++pShape;
1104 		}
1105 		if( aParents.size() > 0 )
1106 		{
1107 			::std::list< const SwFrm * >::const_iterator aIter = aParents.begin();
1108 			::std::list< const SwFrm * >::const_iterator aEndIter = aParents.end();
1109 			while( aIter != aEndIter )
1110 			{
1111 				::vos::ORef< SwAccessibleContext > xParentAccImpl;
1112 				{
1113 					vos::OGuard aGuard( maMutex );
1114 					if(  mpFrmMap )
1115 					{
1116 						SwAccessibleContextMap_Impl::const_iterator aMapIter =
1117 							mpFrmMap->find( *aIter );
1118 						if( aMapIter != mpFrmMap->end() )
1119 						{
1120 							uno::Reference < XAccessible > xAcc( (*aMapIter).second );
1121 							xParentAccImpl =
1122 								static_cast< SwAccessibleContext *>( xAcc.get() );
1123 						}
1124 					}
1125 				}
1126 				if( xParentAccImpl.isValid() )
1127 				{
1128 					AccessibleEventObject aEvent;
1129 					aEvent.EventId = AccessibleEventId::SELECTION_CHANGED;
1130 					xParentAccImpl->FireAccessibleEvent( aEvent );
1131 				}
1132 
1133 				++aIter;
1134 			}
1135 		}
1136 
1137 		delete[] pShapes;
1138 	}
1139 }
1140 
1141 void SwAccessibleMap::DoInvalidateShapeFocus()
1142 {
1143 	const ViewShell *pVSh = GetShell();
1144 	const SwFEShell *pFESh = pVSh->ISA( SwFEShell ) ?
1145 							static_cast< const SwFEShell * >( pVSh ) : 0;
1146 	sal_uInt16 nSelShapes = pFESh ? pFESh->IsObjSelected() : 0;
1147 
1148 	if( nSelShapes != 1 )
1149 		return;
1150 
1151 	SwAccessibleObjShape_Impl *pShapes = 0;
1152 	SwAccessibleObjShape_Impl *pSelShape = 0;
1153 	size_t nShapes = 0;
1154 
1155 
1156 	{
1157 		vos::OGuard aGuard( maMutex );
1158 		if( mpShapeMap )
1159 			pShapes = mpShapeMap->Copy( nShapes, pFESh, &pSelShape );
1160 	}
1161 
1162 	if( pShapes )
1163 	{
1164 		Window *pWin = GetShell()->GetWin();
1165 		sal_Bool bFocused = pWin && pWin->HasFocus();
1166 		SwAccessibleObjShape_Impl  *pShape = pShapes;
1167 		while( nShapes )
1168 		{
1169 			if( pShape->second.isValid() )
1170 			{
1171 				if( bFocused && pShape >= pSelShape )
1172 					pShape->second->SetState( AccessibleStateType::FOCUSED );
1173 				else
1174 					pShape->second->ResetState( AccessibleStateType::FOCUSED );
1175 			}
1176 
1177 			--nShapes;
1178 			++pShape;
1179 		}
1180 
1181 		delete[] pShapes;
1182 	}
1183 }
1184 
1185 
1186 SwAccessibleMap::SwAccessibleMap( ViewShell *pSh ) :
1187 	mpFrmMap( 0  ),
1188 	mpShapeMap( 0  ),
1189 	mpShapes( 0  ),
1190 	mpEvents( 0  ),
1191 	mpEventMap( 0  ),
1192     // --> OD 2005-12-13 #i27301#
1193     mpSelectedParas( 0 ),
1194     // <--
1195 	mpVSh( pSh ),
1196     	mpPreview( 0 ),
1197 	mnPara( 1 ),
1198 	mnFootnote( 1 ),
1199 	mnEndnote( 1 ),
1200 	mbShapeSelected( sal_False )
1201 {
1202 	pSh->GetLayout()->AddAccessibleShell();
1203 }
1204 
1205 SwAccessibleMap::~SwAccessibleMap()
1206 {
1207 	uno::Reference < XAccessible > xAcc;
1208 	{
1209 		vos::OGuard aGuard( maMutex );
1210 		if( mpFrmMap )
1211 		{
1212 			const SwRootFrm *pRootFrm = GetShell()->GetLayout();
1213 			SwAccessibleContextMap_Impl::iterator aIter = mpFrmMap->find( pRootFrm );
1214 			if( aIter != mpFrmMap->end() )
1215 				xAcc = (*aIter).second;
1216 			if( !xAcc.is() )
1217 				xAcc = new SwAccessibleDocument( this );
1218 		}
1219 	}
1220 
1221 	SwAccessibleDocument *pAcc =
1222 		static_cast< SwAccessibleDocument * >( xAcc.get() );
1223 	pAcc->Dispose( sal_True );
1224 
1225 	{
1226 		vos::OGuard aGuard( maMutex );
1227 #ifdef DBG_UTIL
1228 		ASSERT( !mpFrmMap || mpFrmMap->empty(),
1229 				"Frame map should be empty after disposing the root frame" );
1230 		if( mpFrmMap )
1231 		{
1232 			SwAccessibleContextMap_Impl::iterator aIter = mpFrmMap->begin();
1233 			while( aIter != mpFrmMap->end() )
1234 			{
1235 				uno::Reference < XAccessible > xTmp = (*aIter).second;
1236 				if( xTmp.is() )
1237 				{
1238 					SwAccessibleContext *pTmp =
1239 						static_cast< SwAccessibleContext * >( xTmp.get() );
1240 					(void) pTmp;
1241 				}
1242 				++aIter;
1243 			}
1244 		}
1245 		ASSERT( !mpShapeMap || mpShapeMap->empty(),
1246 				"Object map should be empty after disposing the root frame" );
1247 		if( mpShapeMap )
1248 		{
1249 			SwAccessibleShapeMap_Impl::iterator aIter = mpShapeMap->begin();
1250 			while( aIter != mpShapeMap->end() )
1251 			{
1252 				uno::Reference < XAccessible > xTmp = (*aIter).second;
1253 				if( xTmp.is() )
1254 				{
1255 					::accessibility::AccessibleShape *pTmp =
1256 						static_cast< ::accessibility::AccessibleShape* >( xTmp.get() );
1257 					(void) pTmp;
1258 				}
1259 				++aIter;
1260 			}
1261 		}
1262 #endif
1263 		delete mpFrmMap;
1264 		mpFrmMap = 0;
1265 		delete mpShapeMap;
1266 		mpShapeMap = 0;
1267 		delete mpShapes;
1268 		mpShapes = 0;
1269         // --> OD 2005-12-13 #i27301#
1270         delete mpSelectedParas;
1271         mpSelectedParas = 0;
1272         // <--
1273 	}
1274 
1275 	delete mpPreview;
1276 	mpPreview = NULL;
1277 
1278     {
1279 		vos::OGuard aGuard( maEventMutex );
1280 #ifdef DBG_UTIL
1281 		ASSERT( !(mpEvents || mpEventMap), "pending events" );
1282 		if( mpEvents )
1283 		{
1284 			SwAccessibleEventList_Impl::iterator aIter = mpEvents->begin();
1285 			while( aIter != mpEvents->end() )
1286 			{
1287 				++aIter;
1288 			}
1289 		}
1290 		if( mpEventMap )
1291 		{
1292 			SwAccessibleEventMap_Impl::iterator aIter = mpEventMap->begin();
1293 			while( aIter != mpEventMap->end() )
1294 			{
1295 				++aIter;
1296 			}
1297 		}
1298 #endif
1299 		delete mpEventMap;
1300 		mpEventMap = 0;
1301 		delete mpEvents;
1302 		mpEvents = 0;
1303 	}
1304 	mpVSh->GetLayout()->RemoveAccessibleShell();
1305 }
1306 
1307 uno::Reference< XAccessible > SwAccessibleMap::_GetDocumentView(
1308     sal_Bool bPagePreview )
1309 {
1310 	uno::Reference < XAccessible > xAcc;
1311 	sal_Bool bSetVisArea = sal_False;
1312 
1313 	{
1314 		vos::OGuard aGuard( maMutex );
1315 
1316 		if( !mpFrmMap )
1317 		{
1318 			mpFrmMap = new SwAccessibleContextMap_Impl;
1319 #ifdef DBG_UTIL
1320 			mpFrmMap->mbLocked = sal_False;
1321 #endif
1322 		}
1323 
1324 #ifdef DBG_UTIL
1325 		ASSERT( !mpFrmMap->mbLocked, "Map is locked" );
1326 		mpFrmMap->mbLocked = sal_True;
1327 #endif
1328 
1329 		const SwRootFrm *pRootFrm = GetShell()->GetLayout();
1330 		SwAccessibleContextMap_Impl::iterator aIter = mpFrmMap->find( pRootFrm );
1331 		if( aIter != mpFrmMap->end() )
1332 			xAcc = (*aIter).second;
1333 		if( xAcc.is() )
1334 		{
1335 			bSetVisArea = sal_True; // Set VisArea when map mutex is not
1336 									// locked
1337 		}
1338 		else
1339 		{
1340             if( bPagePreview )
1341                 xAcc = new SwAccessiblePreview( this );
1342             else
1343                 xAcc = new SwAccessibleDocument( this );
1344 
1345 			if( aIter != mpFrmMap->end() )
1346 			{
1347 				(*aIter).second = xAcc;
1348 			}
1349 			else
1350 			{
1351 				SwAccessibleContextMap_Impl::value_type aEntry( pRootFrm, xAcc );
1352 				mpFrmMap->insert( aEntry );
1353 			}
1354 		}
1355 
1356 #ifdef DBG_UTIL
1357 		mpFrmMap->mbLocked = sal_False;
1358 #endif
1359 	}
1360 
1361 	if( bSetVisArea )
1362 	{
1363 		SwAccessibleDocumentBase *pAcc =
1364 			static_cast< SwAccessibleDocumentBase * >( xAcc.get() );
1365 		pAcc->SetVisArea();
1366 	}
1367 
1368 	return xAcc;
1369 }
1370 
1371 uno::Reference< XAccessible > SwAccessibleMap::GetDocumentView( )
1372 {
1373     return _GetDocumentView( sal_False );
1374 }
1375 
1376 // OD 14.01.2003 #103492# - complete re-factoring of method due to new page/print
1377 // preview functionality.
1378 uno::Reference<XAccessible> SwAccessibleMap::GetDocumentPreview(
1379                                     const std::vector<PrevwPage*>& _rPrevwPages,
1380                                     const Fraction&  _rScale,
1381                                     const SwPageFrm* _pSelectedPageFrm,
1382                                     const Size&      _rPrevwWinSize )
1383 {
1384     // create & update preview data object
1385     if( mpPreview == NULL )
1386         mpPreview = new SwAccPreviewData();
1387     mpPreview->Update( *this, _rPrevwPages, _rScale, _pSelectedPageFrm, _rPrevwWinSize );
1388 
1389     uno::Reference<XAccessible> xAcc = _GetDocumentView( sal_True );
1390     return xAcc;
1391 }
1392 
1393 uno::Reference< XAccessible> SwAccessibleMap::GetContext( const SwFrm *pFrm,
1394 												     sal_Bool bCreate )
1395 {
1396 	uno::Reference < XAccessible > xAcc;
1397 	uno::Reference < XAccessible > xOldCursorAcc;
1398 	sal_Bool bOldShapeSelected = sal_False;
1399 
1400 	{
1401 		vos::OGuard aGuard( maMutex );
1402 
1403 		if( !mpFrmMap && bCreate )
1404 			mpFrmMap = new SwAccessibleContextMap_Impl;
1405 		if( mpFrmMap )
1406 		{
1407 			SwAccessibleContextMap_Impl::iterator aIter = mpFrmMap->find( pFrm );
1408 			if( aIter != mpFrmMap->end() )
1409 				xAcc = (*aIter).second;
1410 
1411 			if( !xAcc.is() && bCreate )
1412 			{
1413 				SwAccessibleContext *pAcc = 0;
1414 				switch( pFrm->GetType() )
1415 				{
1416 				case FRM_TXT:
1417                     mnPara++;
1418                     pAcc = new SwAccessibleParagraph( *this,
1419                                     static_cast< const SwTxtFrm& >( *pFrm ) );
1420 					break;
1421 				case FRM_HEADER:
1422 					pAcc = new SwAccessibleHeaderFooter( this,
1423 									static_cast< const SwHeaderFrm *>( pFrm ) );
1424 					break;
1425 				case FRM_FOOTER:
1426 					pAcc = new SwAccessibleHeaderFooter( this,
1427 									static_cast< const SwFooterFrm *>( pFrm ) );
1428 					break;
1429 				case FRM_FTN:
1430 					{
1431 						const SwFtnFrm *pFtnFrm =
1432 							static_cast < const SwFtnFrm * >( pFrm );
1433 						sal_Bool bIsEndnote =
1434 							SwAccessibleFootnote::IsEndnote( pFtnFrm );
1435 						pAcc = new SwAccessibleFootnote( this, bIsEndnote,
1436 									(bIsEndnote ? mnEndnote++ : mnFootnote++),
1437 									pFtnFrm );
1438 					}
1439 					break;
1440 				case FRM_FLY:
1441 					{
1442 						const SwFlyFrm *pFlyFrm =
1443 							static_cast < const SwFlyFrm * >( pFrm );
1444 						switch( SwAccessibleFrameBase::GetNodeType( pFlyFrm ) )
1445 						{
1446 						case ND_GRFNODE:
1447 							pAcc = new SwAccessibleGraphic( this, pFlyFrm );
1448 							break;
1449 						case ND_OLENODE:
1450 							pAcc = new SwAccessibleEmbeddedObject( this, pFlyFrm );
1451 							break;
1452 						default:
1453 							pAcc = new SwAccessibleTextFrame( this, pFlyFrm );
1454 							break;
1455 						}
1456 					}
1457 					break;
1458 				case FRM_CELL:
1459 					pAcc = new SwAccessibleCell( this,
1460 									static_cast< const SwCellFrm *>( pFrm ) );
1461 					break;
1462 				case FRM_TAB:
1463                     pAcc = new SwAccessibleTable( this,
1464 									static_cast< const SwTabFrm *>( pFrm ) );
1465 					break;
1466                 case FRM_PAGE:
1467                     DBG_ASSERT( GetShell()->IsPreView(),
1468                                 "accessible page frames only in PagePreview" );
1469                     pAcc = new SwAccessiblePage( this, pFrm );
1470                     break;
1471 				}
1472 				xAcc = pAcc;
1473 
1474 				ASSERT( xAcc.is(), "unknown frame type" );
1475 				if( xAcc.is() )
1476 				{
1477 					if( aIter != mpFrmMap->end() )
1478 					{
1479 						(*aIter).second = xAcc;
1480 					}
1481 					else
1482 					{
1483 						SwAccessibleContextMap_Impl::value_type aEntry( pFrm, xAcc );
1484 						mpFrmMap->insert( aEntry );
1485 					}
1486 
1487 					if( pAcc->HasCursor() &&
1488 						!AreInSameTable( mxCursorContext, pFrm ) )
1489 					{
1490 						// If the new context has the focus, and if we know
1491 						// another context that had the focus, then the focus
1492 						// just moves from the old context to the new one. We
1493 						// have to send a focus event and a caret event for
1494 						// the old context then. We have to to that know,
1495 						// because after we have left this method, anyone might
1496 						// call getStates for the new context and will get a
1497 						// focused state then. Sending the focus changes event
1498 						// after that seems to be strange. However, we cannot
1499 						// send a focus event fo the new context now, because
1500 					    // noone except us knows it. In any case, we remeber
1501 						// the new context as the one that has the focus
1502 						// currently.
1503 
1504 						xOldCursorAcc = mxCursorContext;
1505 						mxCursorContext = xAcc;
1506 
1507 						bOldShapeSelected = mbShapeSelected;
1508 						mbShapeSelected = sal_False;
1509 					}
1510 				}
1511 			}
1512 		}
1513 	}
1514 
1515 	// Invalidate focus for old object when map is not locked
1516 	if( xOldCursorAcc.is() )
1517 		InvalidateCursorPosition( xOldCursorAcc );
1518 	if( bOldShapeSelected )
1519 		InvalidateShapeSelection();
1520 
1521 	return xAcc;
1522 }
1523 
1524 ::vos::ORef < SwAccessibleContext > SwAccessibleMap::GetContextImpl(
1525 			const SwFrm *pFrm,
1526 			sal_Bool bCreate )
1527 {
1528 	uno::Reference < XAccessible > xAcc( GetContext( pFrm, bCreate ) );
1529 
1530 	::vos::ORef < SwAccessibleContext > xAccImpl(
1531 		 static_cast< SwAccessibleContext * >( xAcc.get() ) );
1532 
1533 	return xAccImpl;
1534 }
1535 
1536 uno::Reference< XAccessible> SwAccessibleMap::GetContext(
1537 		const SdrObject *pObj,
1538 		SwAccessibleContext *pParentImpl,
1539 		sal_Bool bCreate )
1540 {
1541 	uno::Reference < XAccessible > xAcc;
1542 	uno::Reference < XAccessible > xOldCursorAcc;
1543 
1544 	{
1545 		vos::OGuard aGuard( maMutex );
1546 
1547 		if( !mpShapeMap && bCreate )
1548 			mpShapeMap = new SwAccessibleShapeMap_Impl( this );
1549 		if( mpShapeMap )
1550 		{
1551 			SwAccessibleShapeMap_Impl::iterator aIter =
1552 			   	mpShapeMap->find( pObj );
1553 			if( aIter != mpShapeMap->end() )
1554 				xAcc = (*aIter).second;
1555 
1556 			if( !xAcc.is() && bCreate )
1557 			{
1558 				::accessibility::AccessibleShape *pAcc = 0;
1559 				uno::Reference < drawing::XShape > xShape(
1560 					const_cast< SdrObject * >( pObj )->getUnoShape(),
1561 					uno::UNO_QUERY );
1562 				if( xShape.is() )
1563 				{
1564 					::accessibility::ShapeTypeHandler& rShapeTypeHandler =
1565 								::accessibility::ShapeTypeHandler::Instance();
1566 					uno::Reference < XAccessible > xParent( pParentImpl );
1567 					::accessibility::AccessibleShapeInfo aShapeInfo(
1568 							xShape, xParent, this );
1569 
1570 					pAcc = rShapeTypeHandler.CreateAccessibleObject(
1571 								aShapeInfo, mpShapeMap->GetInfo() );
1572 				}
1573 				xAcc = pAcc;
1574 
1575 				ASSERT( xAcc.is(), "unknown shape type" );
1576 				if( xAcc.is() )
1577 				{
1578 					pAcc->Init();
1579 					if( aIter != mpShapeMap->end() )
1580 					{
1581 						(*aIter).second = xAcc;
1582 					}
1583 					else
1584 					{
1585 						SwAccessibleShapeMap_Impl::value_type aEntry( pObj,
1586 																	  xAcc );
1587 						mpShapeMap->insert( aEntry );
1588 					}
1589 					// TODO: focus!!!
1590 				}
1591 			}
1592 		}
1593 	}
1594 
1595 	// Invalidate focus for old object when map is not locked
1596 	if( xOldCursorAcc.is() )
1597 		InvalidateCursorPosition( xOldCursorAcc );
1598 
1599 	return xAcc;
1600 }
1601 
1602 ::vos::ORef < ::accessibility::AccessibleShape > SwAccessibleMap::GetContextImpl(
1603 			const SdrObject *pObj,
1604 			SwAccessibleContext *pParentImpl,
1605 			sal_Bool bCreate )
1606 {
1607 	uno::Reference < XAccessible > xAcc( GetContext( pObj, pParentImpl, bCreate ) );
1608 
1609 	::vos::ORef < ::accessibility::AccessibleShape > xAccImpl(
1610 		 static_cast< ::accessibility::AccessibleShape* >( xAcc.get() ) );
1611 
1612 	return xAccImpl;
1613 }
1614 
1615 
1616 void SwAccessibleMap::RemoveContext( const SwFrm *pFrm )
1617 {
1618 	vos::OGuard aGuard( maMutex );
1619 
1620 	if( mpFrmMap )
1621 	{
1622 		SwAccessibleContextMap_Impl::iterator aIter =
1623 			mpFrmMap->find( pFrm );
1624 		if( aIter != mpFrmMap->end() )
1625 		{
1626 			mpFrmMap->erase( aIter );
1627 
1628 			// Remove reference to old caret object. Though mxCursorContext
1629 			// is a weak reference and cleared automatically, clearing it
1630 			// directly makes sure to not keep a defunctional object.
1631 			uno::Reference < XAccessible > xOldAcc( mxCursorContext );
1632 			if( xOldAcc.is() )
1633 			{
1634 				SwAccessibleContext *pOldAccImpl =
1635 					static_cast< SwAccessibleContext *>( xOldAcc.get() );
1636 				ASSERT( pOldAccImpl->GetFrm(), "old caret context is disposed" );
1637 				if( pOldAccImpl->GetFrm() == pFrm )
1638 				{
1639 					xOldAcc.clear();	// get an empty ref
1640 					mxCursorContext = xOldAcc;
1641 				}
1642 			}
1643 
1644 			if( mpFrmMap->empty() )
1645 			{
1646 				delete mpFrmMap;
1647 				mpFrmMap = 0;
1648 			}
1649 		}
1650 	}
1651 }
1652 
1653 void SwAccessibleMap::RemoveContext( const SdrObject *pObj )
1654 {
1655 	vos::OGuard aGuard( maMutex );
1656 
1657 	if( mpShapeMap )
1658 	{
1659 		SwAccessibleShapeMap_Impl::iterator aIter =
1660 			mpShapeMap->find( pObj );
1661 		if( aIter != mpShapeMap->end() )
1662 		{
1663 			mpShapeMap->erase( aIter );
1664 
1665 			// The shape selection flag is not cleared, but one might do
1666 			// so but has to make sure that the removed context is the one
1667 			// that is selected.
1668 
1669 			if( mpShapeMap->empty() )
1670 			{
1671 				delete mpShapeMap;
1672 				mpShapeMap = 0;
1673 			}
1674 		}
1675 	}
1676 }
1677 
1678 
1679 void SwAccessibleMap::Dispose( const SwFrm *pFrm,
1680                                const SdrObject *pObj,
1681                                Window* pWindow,
1682 							   sal_Bool bRecursive )
1683 {
1684     SwAccessibleChild aFrmOrObj( pFrm, pObj, pWindow );
1685 
1686 	// Indeed, the following assert checks the frame's accessible flag,
1687 	// because that's the one that is evaluated in the layout. The frame
1688 	// might not be accessible anyway. That's the case for cell frames that
1689 	// contain further cells.
1690 	ASSERT( !aFrmOrObj.GetSwFrm() || aFrmOrObj.GetSwFrm()->IsAccessibleFrm(),
1691 			"non accessible frame should be disposed" );
1692 
1693 	if( aFrmOrObj.IsAccessible( GetShell()->IsPreView() ) )
1694 	{
1695         ::vos::ORef< SwAccessibleContext > xAccImpl;
1696         ::vos::ORef< SwAccessibleContext > xParentAccImpl;
1697         ::vos::ORef< ::accessibility::AccessibleShape > xShapeAccImpl;
1698 		// get accessible context for frame
1699 		{
1700 			vos::OGuard aGuard( maMutex );
1701 
1702 			// First of all look for an accessible context for a frame
1703 			if( aFrmOrObj.GetSwFrm() && mpFrmMap )
1704 			{
1705 				SwAccessibleContextMap_Impl::iterator aIter =
1706 					mpFrmMap->find( aFrmOrObj.GetSwFrm() );
1707 				if( aIter != mpFrmMap->end() )
1708 				{
1709 					uno::Reference < XAccessible > xAcc( (*aIter).second );
1710 					xAccImpl =
1711 						static_cast< SwAccessibleContext *>( xAcc.get() );
1712 				}
1713 			}
1714 			if( !xAccImpl.isValid() && mpFrmMap )
1715 			{
1716 				// If there is none, look if the parent is accessible.
1717 				const SwFrm *pParent =
1718 						SwAccessibleFrame::GetParent( aFrmOrObj,
1719                                                       GetShell()->IsPreView());
1720 
1721 				if( pParent )
1722 				{
1723 					SwAccessibleContextMap_Impl::iterator aIter =
1724 						mpFrmMap->find( pParent );
1725 					if( aIter != mpFrmMap->end() )
1726 					{
1727 						uno::Reference < XAccessible > xAcc( (*aIter).second );
1728 						xParentAccImpl =
1729 							static_cast< SwAccessibleContext *>( xAcc.get() );
1730 					}
1731 				}
1732 			}
1733 			if( !xParentAccImpl.isValid() && !aFrmOrObj.GetSwFrm() &&
1734 				mpShapeMap )
1735 			{
1736 				SwAccessibleShapeMap_Impl::iterator aIter =
1737                     mpShapeMap->find( aFrmOrObj.GetDrawObject() );
1738 				if( aIter != mpShapeMap->end() )
1739 				{
1740 					uno::Reference < XAccessible > xAcc( (*aIter).second );
1741 					xShapeAccImpl =
1742 						static_cast< ::accessibility::AccessibleShape *>( xAcc.get() );
1743 				}
1744 			}
1745 			if( pObj && GetShell()->ActionPend() &&
1746 				(xParentAccImpl.isValid() || xShapeAccImpl.isValid()) )
1747 			{
1748 				// Keep a reference to the XShape to avoid that it
1749 				// is deleted with a SwFrmFmt::Modify.
1750 				uno::Reference < drawing::XShape > xShape(
1751 					const_cast< SdrObject * >( pObj )->getUnoShape(),
1752 					uno::UNO_QUERY );
1753 				if( xShape.is() )
1754 				{
1755 					if( !mpShapes )
1756 						mpShapes = new SwShapeList_Impl;
1757 					mpShapes->push_back( xShape );
1758 				}
1759 			}
1760 		}
1761 
1762 		// remove events stored for the frame
1763 		{
1764 			vos::OGuard aGuard( maEventMutex );
1765 			if( mpEvents )
1766 			{
1767 				SwAccessibleEventMap_Impl::iterator aIter =
1768 					mpEventMap->find( aFrmOrObj );
1769 				if( aIter != mpEventMap->end() )
1770 				{
1771 					SwAccessibleEvent_Impl aEvent(
1772 							SwAccessibleEvent_Impl::DISPOSE, aFrmOrObj );
1773 					AppendEvent( aEvent );
1774 				}
1775 			}
1776 		}
1777 
1778 		// If the frame is accessible and there is a context for it, dispose
1779 		// the frame. If the frame is no context for it but disposing should
1780 		// take place recursive, the frame's children have to be disposed
1781 		// anyway, so we have to create the context then.
1782 		if( xAccImpl.isValid() )
1783 		{
1784 			xAccImpl->Dispose( bRecursive );
1785 		}
1786 		else if( xParentAccImpl.isValid() )
1787 		{
1788 			// If the frame is a cell frame, the table must be notified.
1789 			// If we are in an action, a table model change event will
1790 			// be broadcasted at the end of the action to give the table
1791 			// a chance to generate a single table change event.
1792 
1793 			xParentAccImpl->DisposeChild( aFrmOrObj, bRecursive );
1794 		}
1795 		else if( xShapeAccImpl.isValid() )
1796 		{
1797             RemoveContext( aFrmOrObj.GetDrawObject() );
1798 			xShapeAccImpl->dispose();
1799 		}
1800 
1801 		if( mpPreview && pFrm && pFrm->IsPageFrm() )
1802 			mpPreview->DisposePage( static_cast< const SwPageFrm *>( pFrm ) );
1803 	}
1804 }
1805 
1806 void SwAccessibleMap::InvalidatePosOrSize( const SwFrm *pFrm,
1807 										   const SdrObject *pObj,
1808                                            Window* pWindow,
1809 										   const SwRect& rOldBox )
1810 {
1811     SwAccessibleChild aFrmOrObj( pFrm, pObj, pWindow );
1812 	if( aFrmOrObj.IsAccessible( GetShell()->IsPreView() ) )
1813 	{
1814 		::vos::ORef< SwAccessibleContext > xAccImpl;
1815 		::vos::ORef< SwAccessibleContext > xParentAccImpl;
1816 		{
1817 			vos::OGuard aGuard( maMutex );
1818 
1819 			if( mpFrmMap )
1820 			{
1821 				if( aFrmOrObj.GetSwFrm() )
1822 				{
1823 					SwAccessibleContextMap_Impl::iterator aIter =
1824 						mpFrmMap->find( aFrmOrObj.GetSwFrm() );
1825 					if( aIter != mpFrmMap->end() )
1826 					{
1827 						// If there is an accesible object already it is
1828 						// notified directly.
1829 						uno::Reference < XAccessible > xAcc( (*aIter).second );
1830 						xAccImpl =
1831 							static_cast< SwAccessibleContext *>( xAcc.get() );
1832 					}
1833 				}
1834 				if( !xAccImpl.isValid() )
1835 				{
1836 					// Otherwise we look if the parent is accessible.
1837 					// If not, there is nothing to do.
1838 					const SwFrm *pParent =
1839 						SwAccessibleFrame::GetParent( aFrmOrObj,
1840                                                       GetShell()->IsPreView());
1841 
1842 					if( pParent )
1843 					{
1844 						SwAccessibleContextMap_Impl::iterator aIter =
1845 							mpFrmMap->find( pParent );
1846 						if( aIter != mpFrmMap->end() )
1847 						{
1848 							uno::Reference < XAccessible > xAcc( (*aIter).second );
1849 							xParentAccImpl =
1850 								static_cast< SwAccessibleContext *>( xAcc.get() );
1851 						}
1852 					}
1853 				}
1854 			}
1855 		}
1856 
1857 		if( xAccImpl.isValid() )
1858 		{
1859 			if( GetShell()->ActionPend() )
1860 			{
1861 				SwAccessibleEvent_Impl aEvent(
1862 					SwAccessibleEvent_Impl::POS_CHANGED, xAccImpl.getBodyPtr(),
1863 					aFrmOrObj, rOldBox );
1864 				AppendEvent( aEvent );
1865 			}
1866 			else
1867 			{
1868 				FireEvents();
1869 				xAccImpl->InvalidatePosOrSize( rOldBox );
1870 			}
1871 		}
1872 		else if( xParentAccImpl.isValid() )
1873 		{
1874 			if( GetShell()->ActionPend() )
1875 			{
1876 				SwAccessibleEvent_Impl aEvent(
1877 					SwAccessibleEvent_Impl::CHILD_POS_CHANGED,
1878 					xParentAccImpl.getBodyPtr(), aFrmOrObj, rOldBox );
1879 				AppendEvent( aEvent );
1880 			}
1881 			else
1882 			{
1883 				FireEvents();
1884 				xParentAccImpl->InvalidateChildPosOrSize( aFrmOrObj,
1885 														  rOldBox );
1886 			}
1887 		}
1888 	}
1889 }
1890 
1891 void SwAccessibleMap::InvalidateContent( const SwFrm *pFrm )
1892 {
1893     SwAccessibleChild aFrmOrObj( pFrm );
1894 	if( aFrmOrObj.IsAccessible( GetShell()->IsPreView() ) )
1895 	{
1896 		uno::Reference < XAccessible > xAcc;
1897 		{
1898 			vos::OGuard aGuard( maMutex );
1899 
1900 			if( mpFrmMap )
1901 			{
1902 				SwAccessibleContextMap_Impl::iterator aIter =
1903 					mpFrmMap->find( aFrmOrObj.GetSwFrm() );
1904 				if( aIter != mpFrmMap->end() )
1905 					xAcc = (*aIter).second;
1906 			}
1907 		}
1908 
1909 		if( xAcc.is() )
1910 		{
1911 			SwAccessibleContext *pAccImpl =
1912 				static_cast< SwAccessibleContext *>( xAcc.get() );
1913 			if( GetShell()->ActionPend() )
1914 			{
1915 				SwAccessibleEvent_Impl aEvent(
1916 					SwAccessibleEvent_Impl::INVALID_CONTENT, pAccImpl,
1917 					aFrmOrObj );
1918 				AppendEvent( aEvent );
1919 			}
1920 			else
1921 			{
1922 				FireEvents();
1923 				pAccImpl->InvalidateContent();
1924 			}
1925 		}
1926 	}
1927 }
1928 
1929 // --> OD 2009-01-06 #i88069#
1930 void SwAccessibleMap::InvalidateAttr( const SwTxtFrm& rTxtFrm )
1931 {
1932     SwAccessibleChild aFrmOrObj( &rTxtFrm );
1933     if( aFrmOrObj.IsAccessible( GetShell()->IsPreView() ) )
1934     {
1935         uno::Reference < XAccessible > xAcc;
1936         {
1937             vos::OGuard aGuard( maMutex );
1938 
1939             if( mpFrmMap )
1940             {
1941                 SwAccessibleContextMap_Impl::iterator aIter =
1942                     mpFrmMap->find( aFrmOrObj.GetSwFrm() );
1943                 if( aIter != mpFrmMap->end() )
1944                     xAcc = (*aIter).second;
1945             }
1946         }
1947 
1948         if( xAcc.is() )
1949         {
1950             SwAccessibleContext *pAccImpl =
1951                 static_cast< SwAccessibleContext *>( xAcc.get() );
1952             if( GetShell()->ActionPend() )
1953             {
1954                 SwAccessibleEvent_Impl aEvent( SwAccessibleEvent_Impl::INVALID_ATTR,
1955                                                pAccImpl, aFrmOrObj );
1956                 aEvent.SetStates( ACC_STATE_TEXT_ATTRIBUTE_CHANGED );
1957                 AppendEvent( aEvent );
1958             }
1959             else
1960             {
1961                 FireEvents();
1962                 pAccImpl->InvalidateAttr();
1963             }
1964         }
1965     }
1966 }
1967 // <--
1968 
1969 void SwAccessibleMap::InvalidateCursorPosition( const SwFrm *pFrm )
1970 {
1971     SwAccessibleChild aFrmOrObj( pFrm );
1972 	sal_Bool bShapeSelected = sal_False;
1973 	const ViewShell *pVSh = GetShell();
1974 	if( pVSh->ISA( SwCrsrShell ) )
1975 	{
1976 		const SwCrsrShell *pCSh = static_cast< const SwCrsrShell * >( pVSh );
1977 		if( pCSh->IsTableMode() )
1978 		{
1979 			while( aFrmOrObj.GetSwFrm() && !aFrmOrObj.GetSwFrm()->IsCellFrm() )
1980 				aFrmOrObj = aFrmOrObj.GetSwFrm()->GetUpper();
1981 		}
1982 		else if( pVSh->ISA( SwFEShell ) )
1983 		{
1984 			sal_uInt16 nObjCount;
1985 			const SwFEShell *pFESh = static_cast< const SwFEShell * >( pVSh );
1986 			const SwFrm *pFlyFrm = pFESh->GetCurrFlyFrm();
1987 			if( pFlyFrm )
1988 			{
1989 				ASSERT( !pFrm || pFrm->FindFlyFrm() == pFlyFrm,
1990 						"cursor is not contained in fly frame" );
1991 				aFrmOrObj = pFlyFrm;
1992 			}
1993 			else if( (nObjCount = pFESh->IsObjSelected()) > 0 )
1994 			{
1995 				bShapeSelected = sal_True;
1996 				aFrmOrObj = static_cast<const SwFrm *>( 0 );
1997 			}
1998 		}
1999 	}
2000 
2001 	ASSERT( bShapeSelected || aFrmOrObj.IsAccessible(GetShell()->IsPreView()),
2002 			"frame is not accessible" );
2003 
2004 	uno::Reference < XAccessible > xOldAcc;
2005 	uno::Reference < XAccessible > xAcc;
2006 	sal_Bool bOldShapeSelected = sal_False;
2007 
2008 	{
2009 		vos::OGuard aGuard( maMutex );
2010 
2011 		xOldAcc = mxCursorContext;
2012 		mxCursorContext = xAcc;	// clear reference
2013 
2014 		bOldShapeSelected = mbShapeSelected;
2015 		mbShapeSelected = bShapeSelected;
2016 
2017 		if( aFrmOrObj.GetSwFrm() && mpFrmMap )
2018 		{
2019 			SwAccessibleContextMap_Impl::iterator aIter =
2020 				mpFrmMap->find( aFrmOrObj.GetSwFrm() );
2021 			if( aIter != mpFrmMap->end() )
2022 				xAcc = (*aIter).second;
2023 
2024 			// For cells, some extra thoughts are necessary,
2025 			// because invalidating the cursor for one cell
2026 			// invalidates the cursor for all cells of the same
2027 			// table. For this reason, we don't want to
2028 			// invalidate the cursor for the old cursor object
2029 			// and the new one if they are within the same table,
2030 			// because this would result in doing the work twice.
2031 			// Moreover, we have to make sure to invalidate the
2032 			// cursor even if the current cell has no accessible object.
2033 			// If the old cursor objects exists and is in the same
2034 			// table, its the best choice, because using it avoids
2035 			// an unnessarary cursor invalidation cycle when creating
2036 			// a new object for the current cell.
2037 			if( aFrmOrObj.GetSwFrm()->IsCellFrm() )
2038 			{
2039 				if( xOldAcc.is() &&
2040 					AreInSameTable( xOldAcc, aFrmOrObj.GetSwFrm() ) )
2041 				{
2042 					if( xAcc.is() )
2043 						xOldAcc = xAcc;	// avoid extra invalidation
2044 					else
2045 						xAcc = xOldAcc;	// make sure ate least one
2046 				}
2047 				if( !xAcc.is() )
2048 					xAcc = GetContext( aFrmOrObj.GetSwFrm(), sal_True );
2049 			}
2050 		}
2051 	}
2052 
2053 	if( xOldAcc.is() && xOldAcc != xAcc )
2054 		InvalidateCursorPosition( xOldAcc );
2055 	if( bOldShapeSelected || bShapeSelected )
2056 		InvalidateShapeSelection();
2057 	if( xAcc.is() )
2058 		InvalidateCursorPosition( xAcc );
2059 }
2060 
2061 void SwAccessibleMap::InvalidateFocus()
2062 {
2063 	uno::Reference < XAccessible > xAcc;
2064 	sal_Bool bShapeSelected;
2065 	{
2066 		vos::OGuard aGuard( maMutex );
2067 
2068 		xAcc = mxCursorContext;
2069 		bShapeSelected = mbShapeSelected;
2070 	}
2071 
2072 	if( xAcc.is() )
2073 	{
2074 		SwAccessibleContext *pAccImpl =
2075 			static_cast< SwAccessibleContext *>( xAcc.get() );
2076 		pAccImpl->InvalidateFocus();
2077 	}
2078 	else if( bShapeSelected  )
2079 	{
2080 		DoInvalidateShapeFocus();
2081 	}
2082 }
2083 
2084 void SwAccessibleMap::SetCursorContext(
2085 		const ::vos::ORef < SwAccessibleContext >& rCursorContext )
2086 {
2087 	vos::OGuard aGuard( maMutex );
2088 	uno::Reference < XAccessible > xAcc( rCursorContext.getBodyPtr() );
2089 	mxCursorContext = xAcc;
2090 }
2091 
2092 // --> OD 2005-12-12 #i27301# - use new type definition for <_nStates>
2093 void SwAccessibleMap::InvalidateStates( tAccessibleStates _nStates,
2094                                         const SwFrm* _pFrm )
2095 {
2096 	// Start with the frame or the first upper that is accessible
2097     SwAccessibleChild aFrmOrObj( _pFrm );
2098 	while( aFrmOrObj.GetSwFrm() &&
2099 			!aFrmOrObj.IsAccessible( GetShell()->IsPreView() ) )
2100 		aFrmOrObj = aFrmOrObj.GetSwFrm()->GetUpper();
2101 	if( !aFrmOrObj.GetSwFrm() )
2102 		aFrmOrObj = GetShell()->GetLayout();
2103 
2104 	uno::Reference< XAccessible > xAcc( GetContext( aFrmOrObj.GetSwFrm(), sal_True ) );
2105 	SwAccessibleContext *pAccImpl =
2106 		static_cast< SwAccessibleContext *>( xAcc.get() );
2107 	if( GetShell()->ActionPend() )
2108 	{
2109         SwAccessibleEvent_Impl aEvent( SwAccessibleEvent_Impl::CARET_OR_STATES,
2110                                        pAccImpl,
2111                                        SwAccessibleChild(pAccImpl->GetFrm()),
2112                                        _nStates );
2113 		AppendEvent( aEvent );
2114 	}
2115 	else
2116 	{
2117 		FireEvents();
2118         pAccImpl->InvalidateStates( _nStates );
2119 	}
2120 }
2121 // <--
2122 
2123 void SwAccessibleMap::_InvalidateRelationSet( const SwFrm* pFrm,
2124                                               sal_Bool bFrom )
2125 {
2126     // first, see if this frame is accessible, and if so, get the respective
2127     SwAccessibleChild aFrmOrObj( pFrm );
2128 	if( aFrmOrObj.IsAccessible( GetShell()->IsPreView() ) )
2129 	{
2130 		uno::Reference < XAccessible > xAcc;
2131 		{
2132 			vos::OGuard aGuard( maMutex );
2133 
2134 			if( mpFrmMap )
2135 			{
2136 				SwAccessibleContextMap_Impl::iterator aIter =
2137                                         mpFrmMap->find( aFrmOrObj.GetSwFrm() );
2138 				if( aIter != mpFrmMap->end() )
2139 				{
2140 					xAcc = (*aIter).second;
2141 				}
2142 			}
2143 		}
2144 
2145         // deliver event directly, or queue event
2146 		if( xAcc.is() )
2147 		{
2148 			SwAccessibleContext *pAccImpl =
2149                             static_cast< SwAccessibleContext *>( xAcc.get() );
2150             if( GetShell()->ActionPend() )
2151             {
2152                 SwAccessibleEvent_Impl aEvent( SwAccessibleEvent_Impl::CARET_OR_STATES,
2153                                                pAccImpl, SwAccessibleChild(pFrm),
2154                                                ( bFrom
2155                                                  ? ACC_STATE_RELATION_FROM
2156                                                  : ACC_STATE_RELATION_TO ) );
2157                 AppendEvent( aEvent );
2158             }
2159             else
2160             {
2161 				FireEvents();
2162                 pAccImpl->InvalidateRelation( bFrom
2163                         ? AccessibleEventId::CONTENT_FLOWS_FROM_RELATION_CHANGED
2164                         : AccessibleEventId::CONTENT_FLOWS_TO_RELATION_CHANGED );
2165             }
2166         }
2167     }
2168 }
2169 
2170 void SwAccessibleMap::InvalidateRelationSet( const SwFrm* pMaster,
2171                                              const SwFrm* pFollow )
2172 {
2173     _InvalidateRelationSet( pMaster, sal_False );
2174     _InvalidateRelationSet( pFollow, sal_True );
2175 }
2176 
2177 /** invalidation CONTENT_FLOW_FROM/_TO relation of a paragraph
2178 
2179     OD 2005-12-01 #i27138#
2180 
2181     @author OD
2182 */
2183 void SwAccessibleMap::InvalidateParaFlowRelation( const SwTxtFrm& _rTxtFrm,
2184                                                   const bool _bFrom )
2185 {
2186     _InvalidateRelationSet( &_rTxtFrm, _bFrom );
2187 }
2188 
2189 /** invalidation of text selection of a paragraph
2190 
2191     OD 2005-12-12 #i27301#
2192 
2193     @author OD
2194 */
2195 void SwAccessibleMap::InvalidateParaTextSelection( const SwTxtFrm& _rTxtFrm )
2196 {
2197     // first, see if this frame is accessible, and if so, get the respective
2198     SwAccessibleChild aFrmOrObj( &_rTxtFrm );
2199     if( aFrmOrObj.IsAccessible( GetShell()->IsPreView() ) )
2200     {
2201         uno::Reference < XAccessible > xAcc;
2202         {
2203             vos::OGuard aGuard( maMutex );
2204 
2205             if( mpFrmMap )
2206             {
2207                 SwAccessibleContextMap_Impl::iterator aIter =
2208                                         mpFrmMap->find( aFrmOrObj.GetSwFrm() );
2209                 if( aIter != mpFrmMap->end() )
2210                 {
2211                     xAcc = (*aIter).second;
2212                 }
2213             }
2214         }
2215 
2216         // deliver event directly, or queue event
2217         if( xAcc.is() )
2218         {
2219             SwAccessibleContext *pAccImpl =
2220                             static_cast< SwAccessibleContext *>( xAcc.get() );
2221             if( GetShell()->ActionPend() )
2222             {
2223                 SwAccessibleEvent_Impl aEvent(
2224                     SwAccessibleEvent_Impl::CARET_OR_STATES,
2225                     pAccImpl,
2226                     SwAccessibleChild( &_rTxtFrm ),
2227                     ACC_STATE_TEXT_SELECTION_CHANGED );
2228                 AppendEvent( aEvent );
2229             }
2230             else
2231             {
2232                 FireEvents();
2233                 pAccImpl->InvalidateTextSelection();
2234             }
2235         }
2236     }
2237 }
2238 
2239 sal_Int32 SwAccessibleMap::GetChildIndex( const SwFrm& rParentFrm,
2240                                           Window& rChild ) const
2241 {
2242     sal_Int32 nIndex( -1 );
2243 
2244     SwAccessibleChild aFrmOrObj( &rParentFrm );
2245     if( aFrmOrObj.IsAccessible( GetShell()->IsPreView() ) )
2246     {
2247         uno::Reference < XAccessible > xAcc;
2248         {
2249             vos::OGuard aGuard( maMutex );
2250 
2251             if( mpFrmMap )
2252             {
2253                 SwAccessibleContextMap_Impl::iterator aIter =
2254                                         mpFrmMap->find( aFrmOrObj.GetSwFrm() );
2255                 if( aIter != mpFrmMap->end() )
2256                 {
2257                     xAcc = (*aIter).second;
2258                 }
2259             }
2260         }
2261 
2262         if( xAcc.is() )
2263         {
2264             SwAccessibleContext *pAccImpl =
2265                             static_cast< SwAccessibleContext *>( xAcc.get() );
2266 
2267             nIndex = pAccImpl->GetChildIndex( const_cast<SwAccessibleMap&>(*this),
2268                                               SwAccessibleChild( &rChild ) );
2269         }
2270     }
2271 
2272     return nIndex;
2273 }
2274 
2275 
2276 // OD 15.01.2003 #103492# - complete re-factoring of method due to new page/print
2277 // preview functionality.
2278 void SwAccessibleMap::UpdatePreview( const std::vector<PrevwPage*>& _rPrevwPages,
2279                                      const Fraction&  _rScale,
2280                                      const SwPageFrm* _pSelectedPageFrm,
2281                                      const Size&      _rPrevwWinSize )
2282 {
2283     DBG_ASSERT( GetShell()->IsPreView(), "no preview?" );
2284     DBG_ASSERT( mpPreview != NULL, "no preview data?" );
2285 
2286     // OD 15.01.2003 #103492# - adjustments for changed method signature
2287     mpPreview->Update( *this, _rPrevwPages, _rScale, _pSelectedPageFrm, _rPrevwWinSize );
2288 
2289     // propagate change of VisArea through the document's
2290     // accessibility tree; this will also send appropriate scroll
2291     // events
2292     SwAccessibleContext* pDoc =
2293         GetContextImpl( GetShell()->GetLayout() ).getBodyPtr();
2294     static_cast<SwAccessibleDocumentBase*>( pDoc )->SetVisArea();
2295 
2296 	uno::Reference < XAccessible > xOldAcc;
2297 	uno::Reference < XAccessible > xAcc;
2298 	{
2299 		vos::OGuard aGuard( maMutex );
2300 
2301 		xOldAcc = mxCursorContext;
2302 
2303 		const SwPageFrm *pSelPage = mpPreview->GetSelPage();
2304 		if( pSelPage && mpFrmMap )
2305 		{
2306 			SwAccessibleContextMap_Impl::iterator aIter =
2307 				mpFrmMap->find( pSelPage );
2308 			if( aIter != mpFrmMap->end() )
2309 				xAcc = (*aIter).second;
2310 		}
2311 	}
2312 
2313 	if( xOldAcc.is() && xOldAcc != xAcc )
2314 		InvalidateCursorPosition( xOldAcc );
2315 	if( xAcc.is() )
2316 		InvalidateCursorPosition( xAcc );
2317 }
2318 
2319 void SwAccessibleMap::InvalidatePreViewSelection( sal_uInt16 nSelPage )
2320 {
2321     DBG_ASSERT( GetShell()->IsPreView(), "no preview?" );
2322     DBG_ASSERT( mpPreview != NULL, "no preview data?" );
2323 
2324     // OD 16.01.2003 #103492# - changed metthod call due to method signature change.
2325     mpPreview->InvalidateSelection( GetShell()->GetLayout()->GetPageByPageNum( nSelPage ) );
2326 
2327 	uno::Reference < XAccessible > xOldAcc;
2328 	uno::Reference < XAccessible > xAcc;
2329 	{
2330 		vos::OGuard aGuard( maMutex );
2331 
2332 		xOldAcc = mxCursorContext;
2333 
2334 		const SwPageFrm *pSelPage = mpPreview->GetSelPage();
2335 		if( pSelPage && mpFrmMap )
2336 		{
2337 			SwAccessibleContextMap_Impl::iterator aIter =
2338 				mpFrmMap->find( pSelPage );
2339 			if( aIter != mpFrmMap->end() )
2340 				xAcc = (*aIter).second;
2341 		}
2342 	}
2343 
2344 	if( xOldAcc.is() && xOldAcc != xAcc )
2345 		InvalidateCursorPosition( xOldAcc );
2346 	if( xAcc.is() )
2347 		InvalidateCursorPosition( xAcc );
2348 }
2349 
2350 
2351 sal_Bool SwAccessibleMap::IsPageSelected( const SwPageFrm *pPageFrm ) const
2352 {
2353 	return mpPreview && mpPreview->GetSelPage() == pPageFrm;
2354 }
2355 
2356 
2357 void SwAccessibleMap::FireEvents()
2358 {
2359 	{
2360 		vos::OGuard aGuard( maEventMutex );
2361 		if( mpEvents )
2362 		{
2363 			mpEvents->SetFiring();
2364 			SwAccessibleEventList_Impl::iterator aIter = mpEvents->begin();
2365 			while( aIter != mpEvents->end() )
2366 			{
2367 				FireEvent( *aIter );
2368 				++aIter;
2369 			}
2370 
2371 			delete mpEventMap;
2372 			mpEventMap = 0;
2373 
2374 			delete mpEvents;
2375 			mpEvents = 0;
2376 		}
2377 	}
2378 	{
2379 		vos::OGuard aGuard( maMutex );
2380 		if( mpShapes )
2381 		{
2382 			delete mpShapes;
2383 			mpShapes = 0;
2384 		}
2385 	}
2386 
2387 }
2388 
2389 sal_Bool SwAccessibleMap::IsValid() const
2390 {
2391 	return sal_True;
2392 }
2393 
2394 Rectangle SwAccessibleMap::GetVisibleArea() const
2395 {
2396     MapMode aSrc( MAP_TWIP );
2397 	MapMode aDest( MAP_100TH_MM );
2398 	return OutputDevice::LogicToLogic( GetVisArea().SVRect(), aSrc, aDest );
2399 }
2400 
2401 // Convert a MM100 value realtive to the document root into a pixel value
2402 // realtive to the screen!
2403 Point SwAccessibleMap::LogicToPixel( const Point& rPoint ) const
2404 {
2405 	MapMode aSrc( MAP_100TH_MM );
2406 	MapMode aDest( MAP_TWIP );
2407 
2408     Point aPoint = rPoint;
2409 
2410 	aPoint = OutputDevice::LogicToLogic( aPoint, aSrc, aDest );
2411 	Window *pWin = GetShell()->GetWin();
2412 	if( pWin )
2413     {
2414         // OD 16.01.2003 #103492# - get mapping mode for LogicToPixel conversion
2415         MapMode aMapMode;
2416         GetMapMode( aPoint, aMapMode );
2417         aPoint = pWin->LogicToPixel( aPoint, aMapMode );
2418 		aPoint = pWin->OutputToAbsoluteScreenPixel( aPoint );
2419     }
2420 
2421 	return aPoint;
2422 }
2423 
2424 Size SwAccessibleMap::LogicToPixel( const Size& rSize ) const
2425 {
2426 	MapMode aSrc( MAP_100TH_MM );
2427 	MapMode aDest( MAP_TWIP );
2428 	Size aSize( OutputDevice::LogicToLogic( rSize, aSrc, aDest ) );
2429 	if( GetShell()->GetWin() )
2430     {
2431         // OD 16.01.2003 #103492# - get mapping mode for LogicToPixel conversion
2432         MapMode aMapMode;
2433         GetMapMode( Point(0,0), aMapMode );
2434         aSize = GetShell()->GetWin()->LogicToPixel( aSize, aMapMode );
2435     }
2436 
2437 	return aSize;
2438 }
2439 
2440 Point SwAccessibleMap::PixelToLogic( const Point& rPoint ) const
2441 {
2442 	Point aPoint;
2443 	Window *pWin = GetShell()->GetWin();
2444 	if( pWin )
2445 	{
2446 		aPoint = pWin->ScreenToOutputPixel( rPoint );
2447         // OD 16.01.2003 #103492# - get mapping mode for PixelToLogic conversion
2448         MapMode aMapMode;
2449         GetMapMode( aPoint, aMapMode );
2450         aPoint = pWin->PixelToLogic( aPoint, aMapMode );
2451 		MapMode aSrc( MAP_TWIP );
2452 		MapMode aDest( MAP_100TH_MM );
2453 		aPoint = OutputDevice::LogicToLogic( aPoint, aSrc, aDest );
2454 	}
2455 
2456 	return aPoint;
2457 }
2458 
2459 Size SwAccessibleMap::PixelToLogic( const Size& rSize ) const
2460 {
2461 	Size aSize;
2462 	if( GetShell()->GetWin() )
2463 	{
2464         // OD 16.01.2003 #103492# - get mapping mode for PixelToLogic conversion
2465         MapMode aMapMode;
2466         GetMapMode( Point(0,0), aMapMode );
2467         aSize = GetShell()->GetWin()->PixelToLogic( rSize, aMapMode );
2468 		MapMode aSrc( MAP_TWIP );
2469 		MapMode aDest( MAP_100TH_MM );
2470 		aSize = OutputDevice::LogicToLogic( aSize, aSrc, aDest );
2471 	}
2472 
2473 	return aSize;
2474 }
2475 
2476 sal_Bool SwAccessibleMap::ReplaceChild (
2477         ::accessibility::AccessibleShape* pCurrentChild,
2478 		const uno::Reference< drawing::XShape >& _rxShape,
2479         const long /*_nIndex*/,
2480         const ::accessibility::AccessibleShapeTreeInfo& /*_rShapeTreeInfo*/
2481 	)	throw (uno::RuntimeException)
2482 {
2483 	const SdrObject *pObj = 0;
2484 	{
2485 		vos::OGuard aGuard( maMutex );
2486 		if( mpShapeMap )
2487 		{
2488 			SwAccessibleShapeMap_Impl::const_iterator aIter = mpShapeMap->begin();
2489 			SwAccessibleShapeMap_Impl::const_iterator aEndIter = mpShapeMap->end();
2490 			while( aIter != aEndIter && !pObj )
2491 			{
2492 				uno::Reference < XAccessible > xAcc( (*aIter).second );
2493 				::accessibility::AccessibleShape *pAccShape =
2494 					static_cast < ::accessibility::AccessibleShape* >( xAcc.get() );
2495 				if( pAccShape == pCurrentChild )
2496 				{
2497 					pObj = (*aIter).first;
2498 				}
2499 				++aIter;
2500 			}
2501 		}
2502 	}
2503 	if( !pObj )
2504 		return sal_False;
2505 
2506 	uno::Reference < drawing::XShape > xShape( _rxShape ); //keep reference to shape, because
2507 											 // we might be the only one that
2508 											 // hold it.
2509 	// Also get keep parent.
2510 	uno::Reference < XAccessible > xParent( pCurrentChild->getAccessibleParent() );
2511 	pCurrentChild = 0;	// well be realease by dispose
2512     Dispose( 0, pObj, 0 );
2513 
2514 	{
2515 		vos::OGuard aGuard( maMutex );
2516 
2517 		if( !mpShapeMap )
2518 			mpShapeMap = new SwAccessibleShapeMap_Impl( this );
2519 
2520 		// create the new child
2521 		::accessibility::ShapeTypeHandler& rShapeTypeHandler =
2522 						::accessibility::ShapeTypeHandler::Instance();
2523 		::accessibility::AccessibleShapeInfo aShapeInfo(
2524 											xShape, xParent, this );
2525 		::accessibility::AccessibleShape* pReplacement =
2526 			rShapeTypeHandler.CreateAccessibleObject (
2527 				aShapeInfo, mpShapeMap->GetInfo() );
2528 
2529 		uno::Reference < XAccessible > xAcc( pReplacement );
2530 		if( xAcc.is() )
2531 		{
2532 			pReplacement->Init();
2533 
2534 			SwAccessibleShapeMap_Impl::iterator aIter =
2535 				mpShapeMap->find( pObj );
2536 			if( aIter != mpShapeMap->end() )
2537 			{
2538 				(*aIter).second = xAcc;
2539 			}
2540 			else
2541 			{
2542 				SwAccessibleShapeMap_Impl::value_type aEntry( pObj, xAcc );
2543 				mpShapeMap->insert( aEntry );
2544 			}
2545 		}
2546 	}
2547 
2548 	SwRect aEmptyRect;
2549     InvalidatePosOrSize( 0, pObj, 0, aEmptyRect );
2550 
2551 	return sal_True;
2552 }
2553 
2554 Point SwAccessibleMap::PixelToCore( const Point& rPoint ) const
2555 {
2556 	Point aPoint;
2557 	if( GetShell()->GetWin() )
2558 	{
2559         // OD 15.01.2003 #103492# - replace <PreviewAdjust(..)> by <GetMapMode(..)>
2560         MapMode aMapMode;
2561         GetMapMode( rPoint, aMapMode );
2562         aPoint = GetShell()->GetWin()->PixelToLogic( rPoint, aMapMode );
2563 	}
2564 	return aPoint;
2565 }
2566 
2567 static inline long lcl_CorrectCoarseValue(long aCoarseValue, long aFineValue,
2568                                           long aRefValue, bool bToLower)
2569 {
2570     long aResult = aCoarseValue;
2571 
2572     if (bToLower)
2573     {
2574         if (aFineValue < aRefValue)
2575             aResult -= 1;
2576     }
2577     else
2578     {
2579         if (aFineValue > aRefValue)
2580             aResult += 1;
2581     }
2582 
2583     return aResult;
2584 }
2585 
2586 static inline void lcl_CorrectRectangle(Rectangle & rRect,
2587                                         const Rectangle & rSource,
2588                                         const Rectangle & rInGrid)
2589 {
2590     rRect.nLeft = lcl_CorrectCoarseValue(rRect.nLeft, rSource.nLeft,
2591                                          rInGrid.nLeft, false);
2592     rRect.nTop = lcl_CorrectCoarseValue(rRect.nTop, rSource.nTop,
2593                                         rInGrid.nTop, false);
2594     rRect.nRight = lcl_CorrectCoarseValue(rRect.nRight, rSource.nRight,
2595                                           rInGrid.nRight, true);
2596     rRect.nBottom = lcl_CorrectCoarseValue(rRect.nBottom, rSource.nBottom,
2597                                            rInGrid.nBottom, true);
2598 }
2599 
2600 Rectangle SwAccessibleMap::CoreToPixel( const Rectangle& rRect ) const
2601 {
2602     Rectangle aRect;
2603 	if( GetShell()->GetWin() )
2604     {
2605         // OD 15.01.2003 #103492# - replace <PreviewAdjust(..)> by <GetMapMode(..)>
2606         MapMode aMapMode;
2607         GetMapMode( rRect.TopLeft(), aMapMode );
2608         aRect = GetShell()->GetWin()->LogicToPixel( rRect, aMapMode );
2609 
2610         Rectangle aTmpRect = GetShell()->GetWin()->PixelToLogic( aRect, aMapMode );
2611         lcl_CorrectRectangle(aRect, rRect, aTmpRect);
2612     }
2613 
2614 	return aRect;
2615 }
2616 
2617 /** get mapping mode for LogicToPixel and PixelToLogic conversions
2618 
2619     OD 15.01.2003 #103492#
2620     Replacement method <PreviewAdjust(..)> by new method <GetMapMode>.
2621     Method returns mapping mode of current output device and adjusts it,
2622     if the shell is in page/print preview.
2623     Necessary, because <PreviewAdjust(..)> changes mapping mode at current
2624     output device for mapping logic document positions to page preview window
2625     positions and vice versa and doesn't take care to recover its changes.
2626 
2627     @author OD
2628 */
2629 void SwAccessibleMap::GetMapMode( const Point& _rPoint,
2630                                   MapMode&     _orMapMode ) const
2631 {
2632     MapMode aMapMode = GetShell()->GetWin()->GetMapMode();
2633     if( GetShell()->IsPreView() )
2634     {
2635         DBG_ASSERT( mpPreview != NULL, "need preview data" );
2636 
2637         mpPreview->AdjustMapMode( aMapMode, _rPoint );
2638     }
2639     _orMapMode = aMapMode;
2640 }
2641 
2642 /** get size of a dedicated preview page
2643 
2644     OD 15.01.2003 #103492#
2645 
2646     @author OD
2647 */
2648 Size SwAccessibleMap::GetPreViewPageSize( sal_uInt16 _nPrevwPageNum ) const
2649 {
2650     DBG_ASSERT( mpVSh->IsPreView(), "no page preview accessible." );
2651     DBG_ASSERT( mpVSh->IsPreView() && ( mpPreview != NULL ),
2652                 "missing accessible preview data at page preview" );
2653     if ( mpVSh->IsPreView() && ( mpPreview != NULL ) )
2654     {
2655         return mpVSh->PagePreviewLayout()->GetPrevwPageSizeByPageNum( _nPrevwPageNum );
2656     }
2657     else
2658     {
2659         return Size( 0, 0 );
2660     }
2661 }
2662 
2663 /** method to build up a new data structure of the accessible pararaphs,
2664     which have a selection
2665 
2666     OD 2005-12-13 #i27301#
2667     Important note: method has to used inside a mutual exclusive section
2668 
2669     @author OD
2670 */
2671 SwAccessibleSelectedParas_Impl* SwAccessibleMap::_BuildSelectedParas()
2672 {
2673     // no accessible contexts, no selection
2674     if ( !mpFrmMap )
2675     {
2676         return 0L;
2677     }
2678 
2679     // get cursor as an instance of its base class <SwPaM>
2680     SwPaM* pCrsr( 0L );
2681     {
2682         SwCrsrShell* pCrsrShell = dynamic_cast<SwCrsrShell*>(GetShell());
2683         if ( pCrsrShell )
2684         {
2685             SwFEShell* pFEShell = dynamic_cast<SwFEShell*>(pCrsrShell);
2686             if ( !pFEShell ||
2687                  ( !pFEShell->IsFrmSelected() &&
2688                    pFEShell->IsObjSelected() == 0 ) )
2689             {
2690                 // get cursor without updating an existing table cursor.
2691                 pCrsr = pCrsrShell->GetCrsr( sal_False );
2692             }
2693         }
2694     }
2695     // no cursor, no selection
2696     if ( !pCrsr )
2697     {
2698         return 0L;
2699     }
2700 
2701     SwAccessibleSelectedParas_Impl* pRetSelectedParas( 0L );
2702 
2703     // loop on all cursors
2704     SwPaM* pRingStart = pCrsr;
2705     do {
2706 
2707         // for a selection the cursor has to have a mark.
2708         // for savety reasons assure that point and mark are in text nodes
2709         if ( pCrsr->HasMark() &&
2710              pCrsr->GetPoint()->nNode.GetNode().IsTxtNode() &&
2711              pCrsr->GetMark()->nNode.GetNode().IsTxtNode() )
2712         {
2713             SwPosition* pStartPos = pCrsr->Start();
2714             SwPosition* pEndPos = pCrsr->End();
2715             // loop on all text nodes inside the selection
2716             SwNodeIndex aIdx( pStartPos->nNode );
2717             for ( ; aIdx.GetIndex() <= pEndPos->nNode.GetIndex(); ++aIdx )
2718             {
2719                 SwTxtNode* pTxtNode( aIdx.GetNode().GetTxtNode() );
2720                 if ( pTxtNode )
2721                 {
2722                     // loop on all text frames registered at the text node.
2723                     SwIterator<SwTxtFrm,SwTxtNode> aIter( *pTxtNode );
2724                     for( SwTxtFrm* pTxtFrm = aIter.First(); pTxtFrm; pTxtFrm = aIter.Next() )
2725                         {
2726                             uno::WeakReference < XAccessible > xWeakAcc;
2727                             SwAccessibleContextMap_Impl::iterator aMapIter =
2728                                                     mpFrmMap->find( pTxtFrm );
2729                             if( aMapIter != mpFrmMap->end() )
2730                             {
2731                                 xWeakAcc = (*aMapIter).second;
2732                                 SwAccessibleParaSelection aDataEntry(
2733                                     pTxtNode == &(pStartPos->nNode.GetNode())
2734                                                 ? pStartPos->nContent.GetIndex()
2735                                                 : 0,
2736                                     pTxtNode == &(pEndPos->nNode.GetNode())
2737                                                 ? pEndPos->nContent.GetIndex()
2738                                                 : STRING_LEN );
2739                                 SwAccessibleSelectedParas_Impl::value_type
2740                                                 aEntry( xWeakAcc, aDataEntry );
2741                                 if ( !pRetSelectedParas )
2742                                 {
2743                                     pRetSelectedParas =
2744                                             new SwAccessibleSelectedParas_Impl;
2745                                 }
2746                                 pRetSelectedParas->insert( aEntry );
2747                             }
2748                         }
2749                     }
2750                 }
2751             }
2752 
2753         // prepare next turn: get next cursor in ring
2754         pCrsr = static_cast<SwPaM*>( pCrsr->GetNext() );
2755     } while ( pCrsr != pRingStart );
2756 
2757     return pRetSelectedParas;
2758 }
2759 
2760 /** invalidation of text selection of all paragraphs
2761 
2762     OD 2005-12-13 #i27301#
2763 
2764     @author OD
2765 */
2766 void SwAccessibleMap::InvalidateTextSelectionOfAllParas()
2767 {
2768     vos::OGuard aGuard( maMutex );
2769 
2770     // keep previously known selected paragraphs
2771     SwAccessibleSelectedParas_Impl* pPrevSelectedParas( mpSelectedParas );
2772 
2773     // determine currently selected paragraphs
2774     mpSelectedParas = _BuildSelectedParas();
2775 
2776     // compare currently selected paragraphs with the previously selected
2777     // paragraphs and submit corresponding TEXT_SELECTION_CHANGED events.
2778     // first, search for new and changed selections.
2779     // on the run remove selections from previously known ones, if they are
2780     // also in the current ones.
2781     if ( mpSelectedParas )
2782     {
2783         SwAccessibleSelectedParas_Impl::iterator aIter = mpSelectedParas->begin();
2784         for ( ; aIter != mpSelectedParas->end(); ++aIter )
2785         {
2786             bool bSubmitEvent( false );
2787             if ( !pPrevSelectedParas )
2788             {
2789                 // new selection
2790                 bSubmitEvent = true;
2791             }
2792             else
2793             {
2794                 SwAccessibleSelectedParas_Impl::iterator aPrevSelected =
2795                                         pPrevSelectedParas->find( (*aIter).first );
2796                 if ( aPrevSelected != pPrevSelectedParas->end() )
2797                 {
2798                     // check, if selection has changed
2799                     if ( (*aIter).second.nStartOfSelection !=
2800                                     (*aPrevSelected).second.nStartOfSelection ||
2801                          (*aIter).second.nEndOfSelection !=
2802                                     (*aPrevSelected).second.nEndOfSelection )
2803                     {
2804                         // changed selection
2805                         bSubmitEvent = true;
2806                     }
2807                     pPrevSelectedParas->erase( aPrevSelected );
2808                 }
2809                 else
2810                 {
2811                     // new selection
2812                     bSubmitEvent = true;
2813                 }
2814             }
2815 
2816             if ( bSubmitEvent )
2817             {
2818                 uno::Reference < XAccessible > xAcc( (*aIter).first );
2819                 if ( xAcc.is() )
2820                 {
2821                     ::vos::ORef < SwAccessibleContext > xAccImpl(
2822                                 static_cast<SwAccessibleContext*>( xAcc.get() ) );
2823                     if ( xAccImpl.isValid() && xAccImpl->GetFrm() )
2824                     {
2825                         const SwTxtFrm* pTxtFrm(
2826                             dynamic_cast<const SwTxtFrm*>(xAccImpl->GetFrm()) );
2827                         ASSERT( pTxtFrm,
2828                                 "<SwAccessibleMap::_SubmitTextSelectionChangedEvents()> - unexcepted type of frame" );
2829                         if ( pTxtFrm )
2830                         {
2831                             InvalidateParaTextSelection( *pTxtFrm );
2832                         }
2833                     }
2834                 }
2835             }
2836         }
2837     }
2838 
2839     // second, handle previous selections - after the first step the data
2840     // structure of the previously known only contains the 'old' selections
2841     if ( pPrevSelectedParas )
2842     {
2843         SwAccessibleSelectedParas_Impl::iterator aIter = pPrevSelectedParas->begin();
2844         for ( ; aIter != pPrevSelectedParas->end(); ++aIter )
2845         {
2846             uno::Reference < XAccessible > xAcc( (*aIter).first );
2847             if ( xAcc.is() )
2848             {
2849                 ::vos::ORef < SwAccessibleContext > xAccImpl(
2850                             static_cast<SwAccessibleContext*>( xAcc.get() ) );
2851                 if ( xAccImpl.isValid() && xAccImpl->GetFrm() )
2852                 {
2853                     const SwTxtFrm* pTxtFrm(
2854                             dynamic_cast<const SwTxtFrm*>(xAccImpl->GetFrm()) );
2855                     ASSERT( pTxtFrm,
2856                             "<SwAccessibleMap::_SubmitTextSelectionChangedEvents()> - unexcepted type of frame" );
2857                     if ( pTxtFrm )
2858                     {
2859                         InvalidateParaTextSelection( *pTxtFrm );
2860                     }
2861                 }
2862             }
2863         }
2864 
2865         delete pPrevSelectedParas;
2866     }
2867 }
2868 
2869 const SwRect& SwAccessibleMap::GetVisArea() const
2870 {
2871     DBG_ASSERT( !GetShell()->IsPreView() || (mpPreview != NULL),
2872                 "preview without preview data?" );
2873 
2874     return GetShell()->IsPreView()
2875            ? mpPreview->GetVisArea()
2876            : GetShell()->VisArea();
2877 }
2878 
2879