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