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