xref: /aoo42x/main/sw/source/core/access/acccontext.cxx (revision cdf0e10c)
1  /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sw.hxx"
30 #if (OSL_DEBUG_LEVEL > 1) && defined TEST_MIB
31 	#ifndef _STRING_HXX
32 	#include <tools/string.hxx>
33 	#endif
34 
35 	#ifndef _STREAM_HXX
36 	#include <tools/stream.hxx>
37 	#endif
38 #endif // #if (OSL_DEBUG_LEVEL > 1) && defined TEST_MIB
39 #include <tools/debug.hxx>
40 #include <vcl/window.hxx>
41 #include <errhdl.hxx>
42 #include <swtypes.hxx>
43 
44 #include <com/sun/star/accessibility/XAccessible.hpp>
45 #include <com/sun/star/accessibility/XAccessibleStateSet.hpp>
46 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
47 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
48 #include <vos/mutex.hxx>
49 #include <vcl/svapp.hxx>
50 #include <unotools/accessiblestatesethelper.hxx>
51 #include <unotools/accessiblerelationsethelper.hxx>
52 #include <viewsh.hxx>
53 #include <crsrsh.hxx>
54 #include <fesh.hxx>
55 #include <txtfrm.hxx>
56 #include <ndtxt.hxx>
57 #include <pagefrm.hxx>
58 #include <flyfrm.hxx>
59 #include <dflyobj.hxx>
60 #include <pam.hxx>
61 #include <viewimp.hxx>
62 #include <accmap.hxx>
63 #include <accfrmobjslist.hxx>
64 #include <acccontext.hxx>
65 #include <svx/AccessibleShape.hxx>
66 #include <comphelper/accessibleeventnotifier.hxx>
67 #include <PostItMgr.hxx>
68 
69 using namespace sw::access;
70 
71 #if (OSL_DEBUG_LEVEL > 1) && defined TEST_MIB
72 #define DBG_MSG( _msg ) \
73 	lcl_SwAccessibleContext_DbgMsg( this, _msg, 0, sal_False );
74 #define DBG_MSG_CD( _msg ) \
75 	lcl_SwAccessibleContext_DbgMsg( this, _msg, 0, sal_True );
76 #define DBG_MSG_PARAM( _msg, _param ) \
77 	lcl_SwAccessibleContext_DbgMsg( this, _msg, _param, sal_False );
78 #define DBG_MSG_THIS_PARAM( _msg, _this, _param ) \
79 	lcl_SwAccessibleContext_DbgMsg( _this, _msg, _param, sal_False );
80 
81 void lcl_SwAccessibleContext_DbgMsg( SwAccessibleContext *pThisAcc,
82 									 const char *pMsg,
83 								     SwAccessibleContext *pChildAcc,
84 								  	 sal_Bool bConstrDestr );
85 #else
86 #define DBG_MSG( _msg )
87 #define DBG_MSG_PARAM( _msg, _param )
88 #define DBG_MSG_THIS_PARAM( _msg, _this, _param )
89 #define DBG_MSG_CD( _msg )
90 #endif
91 
92 using namespace ::com::sun::star;
93 using namespace ::com::sun::star::accessibility;
94 using ::rtl::OUString;
95 
96 void SwAccessibleContext::InitStates()
97 {
98     bIsShowingState = GetMap() ? IsShowing( *(GetMap()) ) : sal_False;
99 
100 	ViewShell *pVSh = GetMap()->GetShell();
101     bIsEditableState = pVSh && IsEditable( pVSh );
102 	bIsOpaqueState = pVSh && IsOpaque( pVSh );
103 	bIsDefuncState = sal_False;
104 }
105 
106 void SwAccessibleContext::SetParent( SwAccessibleContext *pParent )
107 {
108 	vos::OGuard aGuard( aMutex );
109 
110 	uno::Reference < XAccessible > xParent( pParent );
111 	xWeakParent = xParent;
112 }
113 
114 uno::Reference< XAccessible > SwAccessibleContext::GetWeakParent() const
115 {
116 	vos::OGuard aGuard( aMutex );
117 
118 	uno::Reference< XAccessible > xParent( xWeakParent );
119 	return xParent;
120 }
121 
122 Window *SwAccessibleContext::GetWindow()
123 {
124 	Window *pWin = 0;
125 
126 	if( GetMap() )
127 	{
128 		const ViewShell *pVSh = GetMap()->GetShell();
129 		ASSERT( pVSh, "no view shell" );
130 		if( pVSh )
131 			pWin = pVSh->GetWin();
132 
133 		ASSERT( pWin, "no window" );
134 	}
135 
136 	return pWin;
137 }
138 
139 // get ViewShell from accessibility map, and cast to cursor shell
140 SwCrsrShell* SwAccessibleContext::GetCrsrShell()
141 {
142     SwCrsrShell* pCrsrShell;
143     ViewShell* pViewShell = GetMap() ? GetMap()->GetShell() : 0;
144 	ASSERT( pViewShell, "no view shell" );
145     if( pViewShell && pViewShell->ISA( SwCrsrShell ) )
146         pCrsrShell = static_cast<SwCrsrShell*>( pViewShell );
147     else
148         pCrsrShell = NULL;
149 
150     return pCrsrShell;
151 }
152 
153 const SwCrsrShell* SwAccessibleContext::GetCrsrShell() const
154 {
155     // just like non-const GetCrsrShell
156     const SwCrsrShell* pCrsrShell;
157     const ViewShell* pViewShell = GetMap() ? GetMap()->GetShell() : 0;
158 	ASSERT( pViewShell, "no view shell" );
159     if( pViewShell && pViewShell->ISA( SwCrsrShell ) )
160         pCrsrShell = static_cast<const SwCrsrShell*>( pViewShell );
161     else
162         pCrsrShell = NULL;
163 
164     return pCrsrShell;
165 }
166 
167 
168 enum Action { NONE, SCROLLED, SCROLLED_WITHIN,
169 						  SCROLLED_IN, SCROLLED_OUT };
170 
171 void SwAccessibleContext::ChildrenScrolled( const SwFrm *pFrm,
172                                             const SwRect& rOldVisArea )
173 {
174 	const SwRect& rNewVisArea = GetVisArea();
175     const bool bVisibleChildrenOnly = SwAccessibleChild( pFrm ).IsVisibleChildrenOnly();
176 
177     const SwAccessibleChildSList aList( *pFrm, *(GetMap()) );
178     SwAccessibleChildSList::const_iterator aIter( aList.begin() );
179 	while( aIter != aList.end() )
180 	{
181         const SwAccessibleChild& rLower = *aIter;
182         const SwRect aBox( rLower.GetBox( *(GetMap()) ) );
183 		if( rLower.IsAccessible( GetShell()->IsPreView() ) )
184 		{
185 			Action eAction = NONE;
186 			if( aBox.IsOver( rNewVisArea ) )
187 			{
188 				if( aBox.IsOver( rOldVisArea ) )
189 				{
190 					eAction = SCROLLED_WITHIN;
191 				}
192 				else
193 				{
194                     if ( bVisibleChildrenOnly &&
195                          !rLower.AlwaysIncludeAsChild() )
196                     {
197 						eAction = SCROLLED_IN;
198                     }
199 					else
200                     {
201 						eAction = SCROLLED;
202                     }
203 				}
204 			}
205 			else if( aBox.IsOver( rOldVisArea ) )
206 			{
207                 if ( bVisibleChildrenOnly &&
208                      !rLower.AlwaysIncludeAsChild() )
209                 {
210 					eAction = SCROLLED_OUT;
211                 }
212 				else
213                 {
214 					eAction = SCROLLED;
215                 }
216 			}
217             else if( !bVisibleChildrenOnly ||
218                      rLower.AlwaysIncludeAsChild() )
219 			{
220 				// This wouldn't be required if the SwAccessibleFrame,
221 				// wouldn't know about the vis area.
222 				eAction = SCROLLED;
223 			}
224 			if( NONE != eAction )
225 			{
226                 if ( rLower.GetSwFrm() )
227 				{
228                     ASSERT( !rLower.AlwaysIncludeAsChild(),
229                             "<SwAccessibleContext::ChildrenScrolled(..)> - always included child not considered!" );
230                     const SwFrm* pLower( rLower.GetSwFrm() );
231 					::vos::ORef< SwAccessibleContext > xAccImpl =
232 						GetMap()->GetContextImpl( pLower, SCROLLED_OUT == eAction ||
233 												SCROLLED_IN == eAction );
234 					if( xAccImpl.isValid() )
235 					{
236 						switch( eAction )
237 						{
238 						case SCROLLED:
239 							xAccImpl->Scrolled( rOldVisArea );
240 							break;
241 						case SCROLLED_WITHIN:
242 							xAccImpl->ScrolledWithin( rOldVisArea );
243 							break;
244 						case SCROLLED_IN:
245 							xAccImpl->ScrolledIn();
246 							break;
247 						case SCROLLED_OUT:
248 							xAccImpl->ScrolledOut( rOldVisArea );
249 							break;
250 						case NONE:
251 							break;
252 						}
253 					}
254 					else
255 					{
256 						ChildrenScrolled( pLower, rOldVisArea );
257 					}
258 				}
259                 else if ( rLower.GetDrawObject() )
260 				{
261                     ASSERT( !rLower.AlwaysIncludeAsChild(),
262                             "<SwAccessibleContext::ChildrenScrolled(..)> - always included child not considered!" );
263 					::vos::ORef< ::accessibility::AccessibleShape > xAccImpl =
264                         GetMap()->GetContextImpl( rLower.GetDrawObject(),
265 												  this,
266 												  SCROLLED_OUT == eAction ||
267 												  SCROLLED_IN == eAction );
268 					if( xAccImpl.isValid() )
269 					{
270 						switch( eAction )
271 						{
272 						case SCROLLED:
273 						case SCROLLED_WITHIN:
274 							xAccImpl->ViewForwarderChanged(
275 								::accessibility::IAccessibleViewForwarderListener::VISIBLE_AREA,
276 								GetMap() );
277 							break;
278 						case SCROLLED_IN:
279                             ScrolledInShape( rLower.GetDrawObject(),
280 											 xAccImpl.getBodyPtr() );
281 							break;
282 						case SCROLLED_OUT:
283 							{
284 								xAccImpl->ViewForwarderChanged(
285 									::accessibility::IAccessibleViewForwarderListener::VISIBLE_AREA,
286 									GetMap() );
287                                 DisposeShape( rLower.GetDrawObject(),
288 											  xAccImpl.getBodyPtr() );
289 							}
290 							break;
291 						case NONE:
292 							break;
293 						}
294 					}
295 				}
296                 else if ( rLower.GetWindow() )
297                 {
298                     // nothing to do - as such children are always included as children.
299                     ASSERT( rLower.AlwaysIncludeAsChild(),
300                             "<SwAccessibleContext::ChildrenScrolled(..)> - not always included child not considered!" );
301                 }
302 			}
303 		}
304         else if ( rLower.GetSwFrm() &&
305                   ( !bVisibleChildrenOnly ||
306                     aBox.IsOver( rOldVisArea ) ||
307                     aBox.IsOver( rNewVisArea ) ) )
308 		{
309 			// There are no unaccessible SdrObjects that need to be notified
310             ChildrenScrolled( rLower.GetSwFrm(), rOldVisArea );
311 		}
312 		++aIter;
313 	}
314 }
315 
316 void SwAccessibleContext::Scrolled( const SwRect& rOldVisArea )
317 {
318 	SetVisArea( GetMap()->GetVisArea() );
319 
320 	ChildrenScrolled( GetFrm(), rOldVisArea );
321 
322 	sal_Bool bIsOldShowingState;
323     sal_Bool bIsNewShowingState = IsShowing( *(GetMap()) );
324 	{
325 		vos::OGuard aGuard( aMutex );
326 		bIsOldShowingState = bIsShowingState;
327 		bIsShowingState = bIsNewShowingState;
328 	}
329 
330 	if( bIsOldShowingState != bIsNewShowingState )
331 		FireStateChangedEvent( AccessibleStateType::SHOWING,
332 							   bIsNewShowingState  );
333 }
334 
335 void SwAccessibleContext::ScrolledWithin( const SwRect& rOldVisArea )
336 {
337 	SetVisArea( GetMap()->GetVisArea() );
338 
339 	ChildrenScrolled( GetFrm(), rOldVisArea );
340 
341 	FireVisibleDataEvent();
342 }
343 
344 void SwAccessibleContext::ScrolledIn()
345 {
346 	// This accessible should be freshly created, because it
347 	// was not visisble before. Therefor, its vis area must already
348 	// reflect the scrolling.
349 	ASSERT( GetVisArea() == GetMap()->GetVisArea(),
350 			"Vis area of child is wrong. Did it exist already?" );
351 
352 	// Send child event at parent. That's all we have to do here.
353     const SwFrm* pParent = GetParent();
354 	::vos::ORef< SwAccessibleContext > xParentImpl(
355 		 GetMap()->GetContextImpl( pParent, sal_False ) );
356 	uno::Reference < XAccessibleContext > xThis( this );
357 	if( xParentImpl.isValid() )
358 	{
359 		SetParent( xParentImpl.getBodyPtr() );
360 
361 		AccessibleEventObject aEvent;
362 		aEvent.EventId = AccessibleEventId::CHILD;
363 		aEvent.NewValue <<= xThis;
364 
365 		xParentImpl->FireAccessibleEvent( aEvent );
366 		DBG_MSG_PARAM( "AccessibleChild (added)", xChildImpl.getBodyPtr() );
367 
368 		if( HasCursor() )
369 		{
370 			Window *pWin = GetWindow();
371 			if( pWin && pWin->HasFocus() )
372 			{
373 				FireStateChangedEvent( AccessibleStateType::FOCUSED, sal_True );
374 			}
375 		}
376 
377 	}
378 }
379 
380 void SwAccessibleContext::ScrolledOut( const SwRect& rOldVisArea )
381 {
382 	SetVisArea( GetMap()->GetVisArea() );
383 
384 	// First of all, update the children. That's required to dispose
385 	// all children that are existing only if they are visible. They
386 	// are not disposed by the recusive Dispose call that follows later on,
387 	// because this call will only dispose children that are in the
388 	// new vis area. The children we want to dispode however are in the
389 	// old vis area all.
390 	ChildrenScrolled( GetFrm(), rOldVisArea );
391 
392 	// Broadcast a state changed event for the showing state.
393 	// It might be that the child is freshly created just to send
394 	// the child event. In this case no listener will exist.
395 	FireStateChangedEvent( AccessibleStateType::SHOWING, sal_False );
396 
397 	// We now dispose the frame
398 	Dispose( sal_True );
399 }
400 
401 // --> OD 2005-12-12 #i27301# - use new type definition for <_nStates>
402 void SwAccessibleContext::InvalidateChildrenStates( const SwFrm* _pFrm,
403                                                     tAccessibleStates _nStates )
404 {
405     const SwAccessibleChildSList aVisList( GetVisArea(), *_pFrm, *(GetMap()) );
406 
407     SwAccessibleChildSList::const_iterator aIter( aVisList.begin() );
408 	while( aIter != aVisList.end() )
409 	{
410         const SwAccessibleChild& rLower = *aIter;
411         const SwFrm* pLower = rLower.GetSwFrm();
412 		if( pLower )
413 		{
414 			::vos::ORef< SwAccessibleContext > xAccImpl;
415 			if( rLower.IsAccessible( GetShell()->IsPreView() ) )
416 				xAccImpl = GetMap()->GetContextImpl( pLower, sal_False );
417 			if( xAccImpl.isValid() )
418                 xAccImpl->InvalidateStates( _nStates );
419 			else
420                 InvalidateChildrenStates( pLower, _nStates );
421 		}
422         else if ( rLower.GetDrawObject() )
423 		{
424 			// TODO: SdrObjects
425 		}
426         else if ( rLower.GetWindow() )
427         {
428             // nothing to do ?
429         }
430 
431 		++aIter;
432 	}
433 }
434 // <--
435 
436 void SwAccessibleContext::DisposeChildren( const SwFrm *pFrm,
437 									   sal_Bool bRecursive )
438 {
439     const SwAccessibleChildSList aVisList( GetVisArea(), *pFrm, *(GetMap()) );
440     SwAccessibleChildSList::const_iterator aIter( aVisList.begin() );
441 	while( aIter != aVisList.end() )
442 	{
443         const SwAccessibleChild& rLower = *aIter;
444         const SwFrm* pLower = rLower.GetSwFrm();
445 		if( pLower )
446 		{
447 			::vos::ORef< SwAccessibleContext > xAccImpl;
448 			if( rLower.IsAccessible( GetShell()->IsPreView() ) )
449 				xAccImpl = GetMap()->GetContextImpl( pLower, sal_False );
450 			if( xAccImpl.isValid() )
451 				xAccImpl->Dispose( bRecursive );
452 			else if( bRecursive )
453 				DisposeChildren( pLower, bRecursive );
454 		}
455         else if ( rLower.GetDrawObject() )
456 		{
457 			::vos::ORef< ::accessibility::AccessibleShape > xAccImpl(
458                     GetMap()->GetContextImpl( rLower.GetDrawObject(),
459 										  this, sal_False )  );
460 			if( xAccImpl.isValid() )
461                 DisposeShape( rLower.GetDrawObject(), xAccImpl.getBodyPtr() );
462 		}
463         else if ( rLower.GetWindow() )
464         {
465             DisposeChild( rLower, sal_False );
466         }
467 		++aIter;
468 	}
469 }
470 
471 void SwAccessibleContext::_InvalidateContent( sal_Bool )
472 {
473 }
474 
475 void SwAccessibleContext::_InvalidateCursorPos()
476 {
477 }
478 
479 void SwAccessibleContext::_InvalidateFocus()
480 {
481 }
482 
483 void SwAccessibleContext::FireAccessibleEvent( AccessibleEventObject& rEvent )
484 {
485 	ASSERT( GetFrm(), "fire event for diposed frame?" );
486 	if( !GetFrm() )
487 		return;
488 
489 	if( !rEvent.Source.is() )
490 	{
491 		uno::Reference < XAccessibleContext > xThis( this );
492 		rEvent.Source = xThis;
493 	}
494 
495 	if (nClientId)
496 		comphelper::AccessibleEventNotifier::addEvent( nClientId, rEvent );
497 }
498 
499 void SwAccessibleContext::FireVisibleDataEvent()
500 {
501 	AccessibleEventObject aEvent;
502 	aEvent.EventId = AccessibleEventId::VISIBLE_DATA_CHANGED;
503 
504 	FireAccessibleEvent( aEvent );
505 	DBG_MSG( "AccessibleVisibleData" )
506 }
507 
508 void SwAccessibleContext::FireStateChangedEvent( sal_Int16 nState,
509 												 sal_Bool bNewState )
510 {
511 	AccessibleEventObject aEvent;
512 
513 	aEvent.EventId = AccessibleEventId::STATE_CHANGED;
514 	if( bNewState )
515 		aEvent.NewValue <<= nState;
516 	else
517 		aEvent.OldValue <<= nState;
518 
519 	FireAccessibleEvent( aEvent );
520 	DBG_MSG( "StateChanged" )
521 }
522 
523 void SwAccessibleContext::GetStates(
524 		::utl::AccessibleStateSetHelper& rStateSet )
525 {
526 	vos::OGuard aGuard(Application::GetSolarMutex());
527 
528 	// SHOWING
529 	if( bIsShowingState )
530 		rStateSet.AddState( AccessibleStateType::SHOWING );
531 
532 	// EDITABLE
533 	if( bIsEditableState )
534 		rStateSet.AddState( AccessibleStateType::EDITABLE );
535 
536 	// ENABLED
537 	rStateSet.AddState( AccessibleStateType::ENABLED );
538 
539 	// OPAQUE
540 	if( bIsOpaqueState )
541 		rStateSet.AddState( AccessibleStateType::OPAQUE );
542 
543 	// VISIBLE
544 	rStateSet.AddState( AccessibleStateType::VISIBLE );
545 
546 	if( bIsDefuncState )
547 		rStateSet.AddState( AccessibleStateType::DEFUNC );
548 }
549 
550 sal_Bool SwAccessibleContext::IsEditableState()
551 {
552 	sal_Bool bRet;
553 	{
554 		vos::OGuard aGuard( aMutex );
555 		bRet = bIsEditableState;
556 	}
557 
558 	return bRet;
559 }
560 
561 SwAccessibleContext::SwAccessibleContext( SwAccessibleMap *pM,
562 										  sal_Int16 nR,
563                                           const SwFrm *pF )
564     : SwAccessibleFrame( pM->GetVisArea().SVRect(), pF,
565                          pM->GetShell()->IsPreView() )
566     , pMap( pM )
567     , nClientId(0)
568     , nRole( nR )
569     , bDisposing( sal_False )
570     , bRegisteredAtAccessibleMap( true )
571 {
572 	InitStates();
573 	DBG_MSG_CD( "constructed" )
574 }
575 
576 SwAccessibleContext::~SwAccessibleContext()
577 {
578 	vos::OGuard aGuard(Application::GetSolarMutex());
579 
580 	DBG_MSG_CD( "destructed" )
581     RemoveFrmFromAccessibleMap();
582 }
583 
584 uno::Reference< XAccessibleContext > SAL_CALL
585 	SwAccessibleContext::getAccessibleContext( void )
586         throw (uno::RuntimeException)
587 {
588 	uno::Reference < XAccessibleContext > xRet( this );
589 	return xRet;
590 }
591 
592 sal_Int32 SAL_CALL SwAccessibleContext::getAccessibleChildCount( void )
593         throw (uno::RuntimeException)
594 {
595 	vos::OGuard aGuard(Application::GetSolarMutex());
596 
597 	CHECK_FOR_DEFUNC( XAccessibleContext )
598 
599     return bDisposing ? 0 : GetChildCount( *(GetMap()) );
600 }
601 
602 uno::Reference< XAccessible> SAL_CALL
603 	SwAccessibleContext::getAccessibleChild( sal_Int32 nIndex )
604         throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
605 {
606 	vos::OGuard aGuard(Application::GetSolarMutex());
607 
608 	CHECK_FOR_DEFUNC( XAccessibleContext )
609 
610     const SwAccessibleChild aChild( GetChild( *(GetMap()), nIndex ) );
611 	if( !aChild.IsValid() )
612 	{
613 		uno::Reference < XAccessibleContext > xThis( this );
614 		lang::IndexOutOfBoundsException aExcept(
615 				OUString( RTL_CONSTASCII_USTRINGPARAM("index out of bounds") ),
616 				xThis );
617 		throw aExcept;
618 	}
619 
620 	uno::Reference< XAccessible > xChild;
621 	if( aChild.GetSwFrm() )
622 	{
623 		::vos::ORef < SwAccessibleContext > xChildImpl(
624 				GetMap()->GetContextImpl( aChild.GetSwFrm(), !bDisposing )  );
625 		if( xChildImpl.isValid() )
626 		{
627 			xChildImpl->SetParent( this );
628 			xChild = xChildImpl.getBodyPtr();
629 		}
630 	}
631     else if ( aChild.GetDrawObject() )
632 	{
633 		::vos::ORef < ::accessibility::AccessibleShape > xChildImpl(
634                 GetMap()->GetContextImpl( aChild.GetDrawObject(),
635 										  this, !bDisposing )  );
636 		if( xChildImpl.isValid() )
637 			xChild = xChildImpl.getBodyPtr();
638 	}
639     else if ( aChild.GetWindow() )
640     {
641         xChild = aChild.GetWindow()->GetAccessible();
642     }
643 
644 	return xChild;
645 }
646 
647 uno::Reference< XAccessible> SAL_CALL SwAccessibleContext::getAccessibleParent (void)
648         throw (uno::RuntimeException)
649 {
650 	vos::OGuard aGuard(Application::GetSolarMutex());
651 
652 	CHECK_FOR_DEFUNC( XAccessibleContext )
653 
654 	const SwFrm *pUpper = GetParent();
655 	ASSERT( pUpper != 0 || bDisposing, "no upper found" );
656 
657 	uno::Reference< XAccessible > xAcc;
658 	if( pUpper )
659 		xAcc = GetMap()->GetContext( pUpper, !bDisposing );
660 
661 	ASSERT( xAcc.is() || bDisposing, "no parent found" );
662 
663 	// Remember the parent as weak ref.
664 	{
665         vos::OGuard aWeakParentGuard( aMutex );
666 		xWeakParent = xAcc;
667 	}
668 
669 	return xAcc;
670 }
671 
672 sal_Int32 SAL_CALL SwAccessibleContext::getAccessibleIndexInParent (void)
673         throw (uno::RuntimeException)
674 {
675 	vos::OGuard aGuard(Application::GetSolarMutex());
676 
677 	CHECK_FOR_DEFUNC( XAccessibleContext )
678 
679 	const SwFrm *pUpper = GetParent();
680 	ASSERT( pUpper != 0 || bDisposing, "no upper found" );
681 
682 	sal_Int32 nIndex = -1;
683 	if( pUpper )
684 	{
685 		::vos::ORef < SwAccessibleContext > xAccImpl(
686 			GetMap()->GetContextImpl( pUpper, !bDisposing )  );
687 		ASSERT( xAccImpl.isValid() || bDisposing, "no parent found" );
688 		if( xAccImpl.isValid() )
689             nIndex = xAccImpl->GetChildIndex( *(GetMap()), SwAccessibleChild(GetFrm()) );
690 	}
691 
692 	return nIndex;
693 }
694 
695 sal_Int16 SAL_CALL SwAccessibleContext::getAccessibleRole (void)
696         throw (uno::RuntimeException)
697 {
698 	return nRole;
699 }
700 
701 OUString SAL_CALL SwAccessibleContext::getAccessibleDescription (void)
702         throw (uno::RuntimeException)
703 {
704 	ASSERT( !this, "description needs to be overloaded" );
705 	THROW_RUNTIME_EXCEPTION( XAccessibleContext, "internal error (method must be overloaded)" );
706 }
707 
708 OUString SAL_CALL SwAccessibleContext::getAccessibleName (void)
709         throw (uno::RuntimeException)
710 {
711 	return sName;
712 }
713 
714 uno::Reference< XAccessibleRelationSet> SAL_CALL
715 	SwAccessibleContext::getAccessibleRelationSet (void)
716         throw (uno::RuntimeException)
717 {
718 	// by default there are no relations
719 	uno::Reference< XAccessibleRelationSet> xRet( new utl::AccessibleRelationSetHelper() );
720 	return xRet;
721 }
722 
723 uno::Reference<XAccessibleStateSet> SAL_CALL
724 	SwAccessibleContext::getAccessibleStateSet (void)
725         throw (uno::RuntimeException)
726 {
727 	vos::OGuard aGuard(Application::GetSolarMutex());
728 
729 	CHECK_FOR_DEFUNC( XAccessibleContext )
730 
731 	::utl::AccessibleStateSetHelper *pStateSet =
732 		new ::utl::AccessibleStateSetHelper;
733 
734 	uno::Reference<XAccessibleStateSet> xStateSet( pStateSet );
735 	GetStates( *pStateSet );
736 
737 	return xStateSet;
738 }
739 
740 lang::Locale SAL_CALL SwAccessibleContext::getLocale (void)
741 		throw (IllegalAccessibleComponentStateException, uno::RuntimeException)
742 {
743 	vos::OGuard aGuard(Application::GetSolarMutex());
744 
745 	lang::Locale aLoc( Application::GetSettings().GetLocale() );
746 	return aLoc;
747 }
748 
749 void SAL_CALL SwAccessibleContext::addEventListener(
750 			const uno::Reference< XAccessibleEventListener >& xListener )
751 		throw (uno::RuntimeException)
752 {
753 	DBG_MSG( "accessible event listener added" )
754 
755 	if (xListener.is())
756     {
757     	vos::OGuard aGuard(Application::GetSolarMutex());
758 		if (!nClientId)
759             nClientId = comphelper::AccessibleEventNotifier::registerClient( );
760 		comphelper::AccessibleEventNotifier::addEventListener( nClientId, xListener );
761     }
762 }
763 
764 void SAL_CALL SwAccessibleContext::removeEventListener(
765 			const uno::Reference< XAccessibleEventListener >& xListener )
766 		throw (uno::RuntimeException)
767 {
768 	DBG_MSG( "accessible event listener removed" )
769 
770 	if (xListener.is())
771 	{
772     	vos::OGuard aGuard(Application::GetSolarMutex());
773 		sal_Int32 nListenerCount = comphelper::AccessibleEventNotifier::removeEventListener( nClientId, xListener );
774 		if ( !nListenerCount )
775 		{
776 			// no listeners anymore
777 			// -> revoke ourself. This may lead to the notifier thread dying (if we were the last client),
778 			// and at least to us not firing any events anymore, in case somebody calls
779 			// NotifyAccessibleEvent, again
780 			comphelper::AccessibleEventNotifier::revokeClient( nClientId );
781 			nClientId = 0;
782 		}
783 	}
784 }
785 
786 static sal_Bool lcl_PointInRectangle(const awt::Point & aPoint,
787                                      const awt::Rectangle & aRect)
788 {
789     long nDiffX = aPoint.X - aRect.X;
790     long nDiffY = aPoint.Y - aRect.Y;
791 
792     return
793         nDiffX >= 0 && nDiffX < aRect.Width && nDiffY >= 0 &&
794         nDiffY < aRect.Height;
795 
796 }
797 
798 sal_Bool SAL_CALL SwAccessibleContext::containsPoint(
799 			const awt::Point& aPoint )
800 		throw (uno::RuntimeException)
801 {
802     awt::Rectangle aPixBounds = getBoundsImpl(sal_True);
803     aPixBounds.X = 0;
804     aPixBounds.Y = 0;
805 
806     return lcl_PointInRectangle(aPoint, aPixBounds);
807 }
808 
809 uno::Reference< XAccessible > SAL_CALL SwAccessibleContext::getAccessibleAtPoint(
810 				const awt::Point& aPoint )
811 		throw (uno::RuntimeException)
812 {
813 	vos::OGuard aGuard(Application::GetSolarMutex());
814 
815 	CHECK_FOR_DEFUNC( XAccessibleComponent )
816 
817 	uno::Reference< XAccessible > xAcc;
818 
819 	Window *pWin = GetWindow();
820 	CHECK_FOR_WINDOW( XAccessibleComponent, pWin )
821 
822 	Point aPixPoint( aPoint.X, aPoint.Y ); // px rel to parent
823 	if( !GetFrm()->IsRootFrm() )
824 	{
825         SwRect aLogBounds( GetBounds( *(GetMap()), GetFrm() ) ); // twip rel to doc root
826 		Point aPixPos( GetMap()->CoreToPixel( aLogBounds.SVRect() ).TopLeft() );
827 		aPixPoint.X() += aPixPos.X();
828 		aPixPoint.Y() += aPixPos.Y();
829 	}
830 
831     const SwAccessibleChild aChild( GetChildAtPixel( aPixPoint, *(GetMap()) ) );
832 	if( aChild.GetSwFrm() )
833 	{
834 		xAcc = GetMap()->GetContext( aChild.GetSwFrm() );
835 	}
836     else if( aChild.GetDrawObject() )
837 	{
838         xAcc = GetMap()->GetContext( aChild.GetDrawObject(), this );
839 	}
840     else if ( aChild.GetWindow() )
841     {
842         xAcc = aChild.GetWindow()->GetAccessible();
843     }
844 
845 	return xAcc;
846 }
847 
848 
849 /**
850    Get bounding box.
851 
852    There are two modes.
853 
854    - realative
855 
856      Return bounding box relative to parent if parent is no root
857      frame. Otherwise return the absolute bounding box.
858 
859    - absolute
860 
861      Return the absolute bounding box.
862 
863    @param bRelative
864    true: Use relative mode.
865    false: Use absolute mode.
866 */
867 awt::Rectangle SAL_CALL SwAccessibleContext::getBoundsImpl(sal_Bool bRelative)
868 		throw (uno::RuntimeException)
869 {
870 	vos::OGuard aGuard(Application::GetSolarMutex());
871 
872 	CHECK_FOR_DEFUNC( XAccessibleComponent )
873 
874 	const SwFrm *pParent = GetParent();
875 	ASSERT( pParent, "no Parent found" );
876 	Window *pWin = GetWindow();
877 
878 	CHECK_FOR_WINDOW( XAccessibleComponent, pWin && pParent )
879 
880     SwRect aLogBounds( GetBounds( *(GetMap()), GetFrm() ) ); // twip rel to doc root
881 	Rectangle aPixBounds( 0, 0, 0, 0 );
882 	if( GetFrm()->IsPageFrm() &&
883 		static_cast < const SwPageFrm * >( GetFrm() )->IsEmptyPage() )
884 	{
885 		ASSERT( GetShell()->IsPreView(), "empty page accessible?" );
886 		if( GetShell()->IsPreView() )
887         {
888             // OD 15.01.2003 #103492# - adjust method call <GetMap()->GetPreViewPageSize()>
889             sal_uInt16 nPageNum =
890                 static_cast < const SwPageFrm * >( GetFrm() )->GetPhyPageNum();
891             aLogBounds.SSize( GetMap()->GetPreViewPageSize( nPageNum ) );
892         }
893 	}
894 	if( !aLogBounds.IsEmpty() )
895 	{
896 		aPixBounds = GetMap()->CoreToPixel( aLogBounds.SVRect() );
897 		if( !pParent->IsRootFrm() && bRelative)
898 		{
899             SwRect aParentLogBounds( GetBounds( *(GetMap()), pParent ) ); // twip rel to doc root
900 			Point aParentPixPos( GetMap()->CoreToPixel( aParentLogBounds.SVRect() ).TopLeft() );
901 			aPixBounds.Move( -aParentPixPos.X(), -aParentPixPos.Y() );
902 		}
903 	}
904 
905 	awt::Rectangle aBox( aPixBounds.Left(), aPixBounds.Top(),
906 						 aPixBounds.GetWidth(), aPixBounds.GetHeight() );
907 
908 	return aBox;
909 }
910 
911 
912 awt::Rectangle SAL_CALL SwAccessibleContext::getBounds()
913 		throw (uno::RuntimeException)
914 {
915     return getBoundsImpl(sal_True);
916 }
917 
918 awt::Point SAL_CALL SwAccessibleContext::getLocation()
919     throw (uno::RuntimeException)
920 {
921     awt::Rectangle aRect = getBoundsImpl(sal_True);
922     awt::Point aPoint(aRect.X, aRect.Y);
923 
924     return aPoint;
925 }
926 
927 
928 
929 awt::Point SAL_CALL SwAccessibleContext::getLocationOnScreen()
930 		throw (uno::RuntimeException)
931 {
932     awt::Rectangle aRect = getBoundsImpl(sal_False);
933 
934     Point aPixPos(aRect.X, aRect.Y);
935 
936     /* getBoundsImpl already checked that GetWindow returns valid pointer. */
937     aPixPos = GetWindow()->OutputToAbsoluteScreenPixel(aPixPos);
938     awt::Point aPoint(aPixPos.X(), aPixPos.Y());
939 
940     return aPoint;
941 }
942 
943 
944 awt::Size SAL_CALL SwAccessibleContext::getSize()
945 		throw (uno::RuntimeException)
946 {
947     awt::Rectangle aRect = getBoundsImpl(sal_False);
948 	awt::Size aSize( aRect.Width, aRect.Height );
949 
950 	return aSize;
951 }
952 
953 void SAL_CALL SwAccessibleContext::grabFocus()
954 		throw (uno::RuntimeException)
955 {
956 	vos::OGuard aGuard(Application::GetSolarMutex());
957 
958 	CHECK_FOR_DEFUNC( XAccessibleContext );
959 
960 	if( GetFrm()->IsFlyFrm() )
961 	{
962 		const SdrObject *pObj =
963 			static_cast < const SwFlyFrm * >( GetFrm() )->GetVirtDrawObj();
964 		if( pObj )
965 			Select( const_cast < SdrObject * >( pObj ), sal_False );
966 	}
967 	else
968 	{
969 		const SwCntntFrm *pCFrm = 0;
970 		if( GetFrm()->IsCntntFrm() )
971 			pCFrm = static_cast< const SwCntntFrm * >( GetFrm() );
972 		else if( GetFrm()->IsLayoutFrm() )
973 			pCFrm = static_cast< const SwLayoutFrm * >( GetFrm() )->ContainsCntnt();
974 
975 		if( pCFrm && pCFrm->IsTxtFrm() )
976 		{
977 			const SwTxtFrm *pTxtFrm = static_cast< const SwTxtFrm * >( pCFrm );
978 			const SwTxtNode *pTxtNd = pTxtFrm->GetTxtNode();
979 			if( pTxtNd )
980 			{
981 				// create pam for selection
982 				SwIndex aIndex( const_cast< SwTxtNode * >( pTxtNd ),
983 								pTxtFrm->GetOfst() );
984 				SwPosition aStartPos( *pTxtNd, aIndex );
985 				SwPaM aPaM( aStartPos );
986 
987 				// set PaM at cursor shell
988 				Select( aPaM );
989 			}
990 		}
991 	}
992 }
993 
994 
995 uno::Any SAL_CALL SwAccessibleContext::getAccessibleKeyBinding()
996 		throw (uno::RuntimeException)
997 {
998 	// There are no key bindings
999 	return uno::Any();
1000 }
1001 
1002 sal_Int32 SAL_CALL SwAccessibleContext::getForeground()
1003 		throw (uno::RuntimeException)
1004 {
1005 	return 0;
1006 }
1007 
1008 sal_Int32 SAL_CALL SwAccessibleContext::getBackground()
1009 		throw (uno::RuntimeException)
1010 {
1011 	return 0xffffff;
1012 }
1013 
1014 
1015 OUString SAL_CALL SwAccessibleContext::getImplementationName()
1016         throw( uno::RuntimeException )
1017 {
1018 	ASSERT( !this, "implementation name needs to be overloaded" );
1019 
1020 	THROW_RUNTIME_EXCEPTION( lang::XServiceInfo, "implementation name needs to be overloaded" )
1021 }
1022 
1023 sal_Bool SAL_CALL
1024     SwAccessibleContext::supportsService (const ::rtl::OUString& )
1025         throw (uno::RuntimeException)
1026 {
1027 	ASSERT( !this, "supports service needs to be overloaded" );
1028 	THROW_RUNTIME_EXCEPTION( lang::XServiceInfo, "supports service needs to be overloaded" )
1029 }
1030 
1031 uno::Sequence< OUString > SAL_CALL SwAccessibleContext::getSupportedServiceNames()
1032 		throw( uno::RuntimeException )
1033 {
1034 	ASSERT( !this, "supported services names needs to be overloaded" );
1035 	THROW_RUNTIME_EXCEPTION( lang::XServiceInfo, "supported services needs to be overloaded" )
1036 }
1037 
1038 void SwAccessibleContext::DisposeShape( const SdrObject *pObj,
1039 								::accessibility::AccessibleShape *pAccImpl )
1040 {
1041 	::vos::ORef< ::accessibility::AccessibleShape > xAccImpl( pAccImpl );
1042 	if( !xAccImpl.isValid() )
1043 		xAccImpl = GetMap()->GetContextImpl( pObj, this, sal_True );
1044 
1045 	AccessibleEventObject aEvent;
1046 	aEvent.EventId = AccessibleEventId::CHILD;
1047 	uno::Reference< XAccessible > xAcc( xAccImpl.getBodyPtr() );
1048 	aEvent.OldValue <<= xAcc;
1049 	FireAccessibleEvent( aEvent );
1050 
1051 	GetMap()->RemoveContext( pObj );
1052 	xAccImpl->dispose();
1053 }
1054 
1055 void SwAccessibleContext::ScrolledInShape( const SdrObject* ,
1056 								::accessibility::AccessibleShape *pAccImpl )
1057 {
1058 	AccessibleEventObject aEvent;
1059 	aEvent.EventId = AccessibleEventId::CHILD;
1060 	uno::Reference< XAccessible > xAcc( pAccImpl );
1061 	aEvent.NewValue <<= xAcc;
1062 	FireAccessibleEvent( aEvent );
1063 
1064 	if( pAccImpl->GetState( AccessibleStateType::FOCUSED ) )
1065 	{
1066 		Window *pWin = GetWindow();
1067 		if( pWin && pWin->HasFocus() )
1068 		{
1069             AccessibleEventObject aStateChangedEvent;
1070             aStateChangedEvent.EventId = AccessibleEventId::STATE_CHANGED;
1071             aStateChangedEvent.NewValue <<= AccessibleStateType::FOCUSED;
1072             aStateChangedEvent.Source = xAcc;
1073 
1074             FireAccessibleEvent( aStateChangedEvent );
1075 		}
1076 	}
1077 }
1078 
1079 void SwAccessibleContext::Dispose( sal_Bool bRecursive )
1080 {
1081 	vos::OGuard aGuard(Application::GetSolarMutex());
1082 
1083 	ASSERT( GetFrm() && GetMap(), "already disposed" );
1084 	ASSERT( GetMap()->GetVisArea() == GetVisArea(),
1085 				"invalid vis area for dispose" );
1086 
1087 	bDisposing = sal_True;
1088 
1089 	// dispose children
1090 	if( bRecursive )
1091 		DisposeChildren( GetFrm(), bRecursive );
1092 
1093 	// get parent
1094 	uno::Reference< XAccessible > xParent( GetWeakParent() );
1095 	uno::Reference < XAccessibleContext > xThis( this );
1096 
1097 	// send child event at parent
1098 	if( xParent.is() )
1099 	{
1100 		SwAccessibleContext *pAcc = (SwAccessibleContext *)xParent.get();
1101 
1102 		AccessibleEventObject aEvent;
1103 		aEvent.EventId = AccessibleEventId::CHILD;
1104 		aEvent.OldValue <<= xThis;
1105 		pAcc->FireAccessibleEvent( aEvent );
1106 		DBG_MSG_THIS_PARAM( "AccessibleChild (removed)", pAcc, this )
1107 	}
1108 
1109 	// set defunc state (its not required to broadcast a state changed
1110 	// event if the object is diposed afterwards)
1111 	{
1112         vos::OGuard aDefuncStateGuard( aMutex );
1113 		bIsDefuncState = sal_True;
1114 	}
1115 
1116 	// broadcast dispose event
1117 	if ( nClientId )
1118 	{
1119         comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( nClientId, *this );
1120 		nClientId =  0;
1121 		DBG_MSG_CD( "dispose" )
1122 	}
1123 
1124     RemoveFrmFromAccessibleMap();
1125 	ClearFrm();
1126 	pMap = 0;
1127 
1128 	bDisposing = sal_False;
1129 }
1130 
1131 void SwAccessibleContext::DisposeChild( const SwAccessibleChild& rChildFrmOrObj,
1132 										sal_Bool bRecursive )
1133 {
1134 	vos::OGuard aGuard(Application::GetSolarMutex());
1135 
1136     if ( IsShowing( *(GetMap()), rChildFrmOrObj ) ||
1137          rChildFrmOrObj.AlwaysIncludeAsChild() ||
1138          !SwAccessibleChild( GetFrm() ).IsVisibleChildrenOnly() )
1139 	{
1140 		// If the object could have existed before, than there is nothing to do,
1141 		// because no wrapper exists now and therefor no one is interested to
1142 		// get notified of the movement.
1143 		if( rChildFrmOrObj.GetSwFrm() )
1144 		{
1145 			::vos::ORef< SwAccessibleContext > xAccImpl =
1146 					GetMap()->GetContextImpl( rChildFrmOrObj.GetSwFrm(),
1147 											  sal_True );
1148 			xAccImpl->Dispose( bRecursive );
1149 		}
1150         else if ( rChildFrmOrObj.GetDrawObject() )
1151 		{
1152 			::vos::ORef< ::accessibility::AccessibleShape > xAccImpl =
1153                     GetMap()->GetContextImpl( rChildFrmOrObj.GetDrawObject(),
1154 											  this, sal_True );
1155             DisposeShape( rChildFrmOrObj.GetDrawObject(),
1156 						  xAccImpl.getBodyPtr() );
1157 		}
1158         else if ( rChildFrmOrObj.GetWindow() )
1159         {
1160             AccessibleEventObject aEvent;
1161             aEvent.EventId = AccessibleEventId::CHILD;
1162             uno::Reference< XAccessible > xAcc =
1163                                     rChildFrmOrObj.GetWindow()->GetAccessible();
1164             aEvent.OldValue <<= xAcc;
1165             FireAccessibleEvent( aEvent );
1166         }
1167 	}
1168 	else if( bRecursive && rChildFrmOrObj.GetSwFrm() )
1169 		DisposeChildren( rChildFrmOrObj.GetSwFrm(), bRecursive );
1170 }
1171 
1172 void SwAccessibleContext::InvalidatePosOrSize( const SwRect& )
1173 {
1174 	vos::OGuard aGuard(Application::GetSolarMutex());
1175 
1176 	ASSERT( GetFrm() && !GetFrm()->Frm().IsEmpty(), "context should have a size" );
1177 
1178 	sal_Bool bIsOldShowingState;
1179     sal_Bool bIsNewShowingState = IsShowing( *(GetMap()) );
1180 	{
1181         vos::OGuard aShowingStateGuard( aMutex );
1182 		bIsOldShowingState = bIsShowingState;
1183 		bIsShowingState = bIsNewShowingState;
1184 	}
1185 
1186 	if( bIsOldShowingState != bIsNewShowingState )
1187 	{
1188 		FireStateChangedEvent( AccessibleStateType::SHOWING,
1189 							   bIsNewShowingState  );
1190 	}
1191 	else if( bIsNewShowingState )
1192 	{
1193 		// The frame stays visible -> broadcast event
1194 		FireVisibleDataEvent();
1195 	}
1196 
1197     if( !bIsNewShowingState &&
1198         SwAccessibleChild( GetParent() ).IsVisibleChildrenOnly() )
1199 	{
1200 		// The frame is now invisible -> dispose it
1201 		Dispose( sal_True );
1202 	}
1203 	else
1204 	{
1205 		_InvalidateContent( sal_True );
1206 	}
1207 }
1208 
1209 void SwAccessibleContext::InvalidateChildPosOrSize(
1210                     const SwAccessibleChild& rChildFrmOrObj,
1211 					const SwRect& rOldFrm )
1212 {
1213 	vos::OGuard aGuard(Application::GetSolarMutex());
1214 
1215 	ASSERT( !rChildFrmOrObj.GetSwFrm() ||
1216 			!rChildFrmOrObj.GetSwFrm()->Frm().IsEmpty(),
1217 			"child context should have a size" );
1218 
1219     if ( rChildFrmOrObj.AlwaysIncludeAsChild() )
1220     {
1221         // nothing to do;
1222         return;
1223     }
1224 
1225     const bool bVisibleChildrenOnly = SwAccessibleChild( GetFrm() ).IsVisibleChildrenOnly();
1226     const bool bNew = rOldFrm.IsEmpty() ||
1227                      ( rOldFrm.Left() == 0 && rOldFrm.Top() == 0 );
1228     if( IsShowing( *(GetMap()), rChildFrmOrObj ) )
1229 	{
1230 		// If the object could have existed before, than there is nothing to do,
1231 		// because no wrapper exists now and therefor no one is interested to
1232 		// get notified of the movement.
1233         if( bNew || (bVisibleChildrenOnly && !IsShowing( rOldFrm )) )
1234 		{
1235 			if( rChildFrmOrObj.GetSwFrm() )
1236 			{
1237 				// The frame becomes visible. A child event must be send.
1238 				::vos::ORef< SwAccessibleContext > xAccImpl =
1239 					GetMap()->GetContextImpl( rChildFrmOrObj.GetSwFrm(),
1240 											  sal_True );
1241 				xAccImpl->ScrolledIn();
1242 			}
1243             else if ( rChildFrmOrObj.GetDrawObject() )
1244 			{
1245 				::vos::ORef< ::accessibility::AccessibleShape > xAccImpl =
1246                         GetMap()->GetContextImpl( rChildFrmOrObj.GetDrawObject(),
1247 												  this, sal_True );
1248                 // --> OD 2004-11-29 #i37790#
1249                 if ( xAccImpl.isValid() )
1250                 {
1251                     ScrolledInShape( rChildFrmOrObj.GetDrawObject(),
1252                                      xAccImpl.getBodyPtr() );
1253                 }
1254                 else
1255                 {
1256                     ASSERT( false ,
1257                             "<SwAccessibleContext::InvalidateChildPosOrSize(..)> - no accessible shape found." );
1258                 }
1259                 // <--
1260 			}
1261             else if ( rChildFrmOrObj.GetWindow() )
1262             {
1263                 AccessibleEventObject aEvent;
1264                 aEvent.EventId = AccessibleEventId::CHILD;
1265                 aEvent.NewValue <<= (rChildFrmOrObj.GetWindow()->GetAccessible());
1266                 FireAccessibleEvent( aEvent );
1267             }
1268 		}
1269 	}
1270 	else
1271 	{
1272 		// If the frame was visible before, than a child event for the parent
1273 		// needs to be send. However, there is no wrapper existing, and so
1274 		// no notifications for grandchildren are required. If the are
1275 		// grandgrandchildren, they would be notified by the layout.
1276         if( bVisibleChildrenOnly &&
1277 			!bNew && IsShowing( rOldFrm ) )
1278 		{
1279 			if( rChildFrmOrObj.GetSwFrm() )
1280 			{
1281 				::vos::ORef< SwAccessibleContext > xAccImpl =
1282 					GetMap()->GetContextImpl( rChildFrmOrObj.GetSwFrm(),
1283 											  sal_True );
1284 				xAccImpl->SetParent( this );
1285 				xAccImpl->Dispose( sal_True );
1286 			}
1287             else if ( rChildFrmOrObj.GetDrawObject() )
1288 			{
1289 				::vos::ORef< ::accessibility::AccessibleShape > xAccImpl =
1290                         GetMap()->GetContextImpl( rChildFrmOrObj.GetDrawObject(),
1291 												  this, sal_True );
1292                 DisposeShape( rChildFrmOrObj.GetDrawObject(),
1293 						  xAccImpl.getBodyPtr() );
1294 			}
1295             else if ( rChildFrmOrObj.GetWindow() )
1296             {
1297                 ASSERT( false,
1298                         "<SwAccessibleContext::InvalidateChildPosOrSize(..)> - not expected to handle dispose of child of type <Window>." );
1299             }
1300 		}
1301 	}
1302 }
1303 
1304 void SwAccessibleContext::InvalidateContent()
1305 {
1306 	vos::OGuard aGuard(Application::GetSolarMutex());
1307 
1308 	_InvalidateContent( sal_False );
1309 }
1310 
1311 void SwAccessibleContext::InvalidateCursorPos()
1312 {
1313 	vos::OGuard aGuard(Application::GetSolarMutex());
1314 
1315 	_InvalidateCursorPos();
1316 }
1317 
1318 void SwAccessibleContext::InvalidateFocus()
1319 {
1320 	vos::OGuard aGuard(Application::GetSolarMutex());
1321 
1322 	_InvalidateFocus();
1323 }
1324 
1325 // --> OD 2005-12-12 #i27301# - use new type definition for <_nStates>
1326 void SwAccessibleContext::InvalidateStates( tAccessibleStates _nStates )
1327 {
1328 	if( GetMap() )
1329 	{
1330 		ViewShell *pVSh = GetMap()->GetShell();
1331 		if( pVSh )
1332 		{
1333             if( (_nStates & ACC_STATE_EDITABLE) != 0 )
1334 			{
1335 				sal_Bool bIsOldEditableState;
1336 				sal_Bool bIsNewEditableState = IsEditable( pVSh );
1337 				{
1338 					vos::OGuard aGuard( aMutex );
1339 					bIsOldEditableState = bIsEditableState;
1340 					bIsEditableState = bIsNewEditableState;
1341 				}
1342 
1343 				if( bIsOldEditableState != bIsNewEditableState )
1344 					FireStateChangedEvent( AccessibleStateType::EDITABLE,
1345 										   bIsNewEditableState  );
1346 			}
1347             if( (_nStates & ACC_STATE_OPAQUE) != 0 )
1348 			{
1349 				sal_Bool bIsOldOpaqueState;
1350 				sal_Bool bIsNewOpaqueState = IsOpaque( pVSh );
1351 				{
1352 					vos::OGuard aGuard( aMutex );
1353 					bIsOldOpaqueState = bIsOpaqueState;
1354 					bIsOpaqueState = bIsNewOpaqueState;
1355 				}
1356 
1357 				if( bIsOldOpaqueState != bIsNewOpaqueState )
1358 					FireStateChangedEvent( AccessibleStateType::OPAQUE,
1359 										   bIsNewOpaqueState  );
1360 			}
1361 		}
1362 
1363         InvalidateChildrenStates( GetFrm(), _nStates );
1364 	}
1365 }
1366 // <--
1367 
1368 void SwAccessibleContext::InvalidateRelation( sal_uInt16 nType )
1369 {
1370 	AccessibleEventObject aEvent;
1371 	aEvent.EventId = nType;
1372 
1373     FireAccessibleEvent( aEvent );
1374 }
1375 
1376 /** text selection has changed
1377 
1378     OD 2005-12-14 #i27301#
1379 
1380     @author OD
1381 */
1382 void SwAccessibleContext::InvalidateTextSelection()
1383 {
1384     AccessibleEventObject aEvent;
1385     aEvent.EventId = AccessibleEventId::TEXT_SELECTION_CHANGED;
1386 
1387     FireAccessibleEvent( aEvent );
1388 }
1389 
1390 /** attributes has changed
1391 
1392     OD 2009-01-06 #i88069#
1393 
1394     @author OD
1395 */
1396 void SwAccessibleContext::InvalidateAttr()
1397 {
1398     AccessibleEventObject aEvent;
1399     aEvent.EventId = AccessibleEventId::TEXT_ATTRIBUTE_CHANGED;
1400 
1401     FireAccessibleEvent( aEvent );
1402 }
1403 
1404 sal_Bool SwAccessibleContext::HasCursor()
1405 {
1406 	return sal_False;
1407 }
1408 
1409 sal_Bool SwAccessibleContext::Select( SwPaM *pPaM, SdrObject *pObj,
1410 									  sal_Bool bAdd )
1411 {
1412     SwCrsrShell* pCrsrShell = GetCrsrShell();
1413 	if( !pCrsrShell )
1414 		return sal_False;
1415 
1416     SwFEShell* pFEShell = pCrsrShell->ISA( SwFEShell )
1417 								? static_cast<SwFEShell*>( pCrsrShell )
1418 								: 0;
1419 	// Get rid of activated OLE object
1420 	if( pFEShell )
1421 		pFEShell->FinishOLEObj();
1422 
1423 	sal_Bool bRet = sal_False;
1424 	if( pObj )
1425 	{
1426 		if( pFEShell )
1427 		{
1428 			Point aDummy;
1429 			sal_uInt8 nFlags = bAdd ? SW_ADD_SELECT : 0;
1430 			pFEShell->SelectObj( aDummy, nFlags, pObj );
1431 			bRet = sal_True;
1432 		}
1433 	}
1434 	else if( pPaM )
1435 	{
1436 		// Get rid of frame selection. If there is one, make text cursor
1437 		// visible again.
1438 		sal_Bool bCallShowCrsr = sal_False;
1439 		if( pFEShell && (pFEShell->IsFrmSelected() ||
1440 						 pFEShell->IsObjSelected()) )
1441 		{
1442 			Point aPt( LONG_MIN, LONG_MIN );
1443 			pFEShell->SelectObj( aPt, 0 );
1444 			bCallShowCrsr = sal_True;
1445 		}
1446         pCrsrShell->KillPams();
1447         pCrsrShell->SetSelection( *pPaM );
1448 		if( bCallShowCrsr )
1449 			pCrsrShell->ShowCrsr();
1450 		bRet = sal_True;
1451 	}
1452 
1453 	return bRet;
1454 }
1455 
1456 OUString SwAccessibleContext::GetResource( sal_uInt16 nResId,
1457 										   const OUString *pArg1,
1458 										   const OUString *pArg2 )
1459 {
1460 	String sStr;
1461 	{
1462 		vos::OGuard aGuard(Application::GetSolarMutex());
1463 
1464 		sStr = SW_RES( nResId );
1465 	}
1466 
1467 	if( pArg1 )
1468 	{
1469 		sStr.SearchAndReplace( String::CreateFromAscii(
1470 									RTL_CONSTASCII_STRINGPARAM( "$(ARG1)" )),
1471 							   String( *pArg1 ) );
1472 	}
1473 	if( pArg2 )
1474 	{
1475 		sStr.SearchAndReplace( String::CreateFromAscii(
1476 									RTL_CONSTASCII_STRINGPARAM( "$(ARG2)" )),
1477 							   String( *pArg2 ) );
1478 	}
1479 
1480 	return OUString( sStr );
1481 }
1482 
1483 void SwAccessibleContext::RemoveFrmFromAccessibleMap()
1484 {
1485     if( bRegisteredAtAccessibleMap && GetFrm() && GetMap() )
1486         GetMap()->RemoveContext( GetFrm() );
1487 }
1488 
1489 bool SwAccessibleContext::HasAdditionalAccessibleChildren()
1490 {
1491     bool bRet( false );
1492 
1493     if ( GetFrm()->IsTxtFrm() )
1494     {
1495         SwPostItMgr* pPostItMgr = GetMap()->GetShell()->GetPostItMgr();
1496         if ( pPostItMgr && pPostItMgr->HasNotes() && pPostItMgr->ShowNotes() )
1497         {
1498             bRet = pPostItMgr->HasFrmConnectedSidebarWins( *(GetFrm()) );
1499         }
1500     }
1501 
1502     return bRet;
1503 }
1504 /** get additional accessible child by index
1505 
1506     OD 2010-01-27 #i88070#
1507 
1508     @author OD
1509 */
1510 Window* SwAccessibleContext::GetAdditionalAccessibleChild( const sal_Int32 nIndex )
1511 {
1512     Window* pAdditionalAccessibleChild( 0 );
1513 
1514     if ( GetFrm()->IsTxtFrm() )
1515     {
1516         SwPostItMgr* pPostItMgr = GetMap()->GetShell()->GetPostItMgr();
1517         if ( pPostItMgr && pPostItMgr->HasNotes() && pPostItMgr->ShowNotes() )
1518         {
1519             pAdditionalAccessibleChild =
1520                     pPostItMgr->GetSidebarWinForFrmByIndex( *(GetFrm()), nIndex );
1521         }
1522     }
1523 
1524     return pAdditionalAccessibleChild;
1525 }
1526 
1527 /** get all additional accessible children
1528 
1529     OD 2010-01-27 #i88070#
1530 
1531     @author OD
1532 */
1533 void SwAccessibleContext::GetAdditionalAccessibleChildren( std::vector< Window* >* pChildren )
1534 {
1535     if ( GetFrm()->IsTxtFrm() )
1536     {
1537         SwPostItMgr* pPostItMgr = GetMap()->GetShell()->GetPostItMgr();
1538         if ( pPostItMgr && pPostItMgr->HasNotes() && pPostItMgr->ShowNotes() )
1539         {
1540             pPostItMgr->GetAllSidebarWinForFrm( *(GetFrm()), pChildren );
1541         }
1542     }
1543 }
1544 
1545 #if (OSL_DEBUG_LEVEL > 1) && defined TEST_MIB
1546 void lcl_SwAccessibleContext_DbgMsg( SwAccessibleContext *pThisAcc,
1547 									 const char *pMsg,
1548 								     SwAccessibleContext *pChildAcc,
1549 								  	 sal_Bool bConstrDestr )
1550 {
1551 	static SvFileStream aStrm( String::CreateFromAscii("j:\\acc.log"),
1552 					STREAM_WRITE|STREAM_TRUNC|STREAM_SHARE_DENYNONE	);
1553 	ByteString aName( String(pThisAcc->GetName()),
1554 					  RTL_TEXTENCODING_ISO_8859_1 );
1555 	if( aName.Len() )
1556 	{
1557 		aStrm << aName.GetBuffer()
1558 			  << ": ";
1559 	}
1560 	aStrm << pMsg;
1561 	if( pChildAcc )
1562 	{
1563 		ByteString aChild( String(pChildAcc->GetName()),
1564 						   RTL_TEXTENCODING_ISO_8859_1 );
1565 		aStrm << ": "
1566 		      << aChild.GetBuffer();
1567 	}
1568 	aStrm << "\r\n    (";
1569 
1570 	if( !bConstrDestr )
1571 	{
1572 		ByteString aDesc( String(pThisAcc->getAccessibleDescription()),
1573 						   RTL_TEXTENCODING_ISO_8859_1 );
1574 		aStrm << aDesc.GetBuffer()
1575 			  << ", ";
1576 	}
1577 
1578 	Rectangle aVisArea( pThisAcc->GetVisArea() );
1579 	aStrm << "VA: "
1580 		  << ByteString::CreateFromInt32( aVisArea.Left() ).GetBuffer()
1581 		  << ","
1582 		  << ByteString::CreateFromInt32( aVisArea.Top() ).GetBuffer()
1583 		  << ","
1584 		  << ByteString::CreateFromInt32( aVisArea.GetWidth() ).GetBuffer()
1585 		  << ","
1586 		  << ByteString::CreateFromInt32( aVisArea.GetHeight() ).GetBuffer();
1587 
1588 	if( pThisAcc->GetFrm() )
1589 	{
1590 		Rectangle aBounds( pThisAcc->GetBounds( pThisAcc->GetFrm() ) );
1591 		aStrm << ", BB: "
1592 			  << ByteString::CreateFromInt32( aBounds.Left() ).GetBuffer()
1593 			  << ","
1594 			  << ByteString::CreateFromInt32( aBounds.Top() ).GetBuffer()
1595 			  << ","
1596 			  << ByteString::CreateFromInt32( aBounds.GetWidth() ).GetBuffer()
1597 			  << ","
1598 			  << ByteString::CreateFromInt32( aBounds.GetHeight() ).GetBuffer()
1599 			  << ")\r\n";
1600 	}
1601 
1602 	aStrm.Flush();
1603 }
1604 #endif
1605