xref: /trunk/main/sw/source/core/access/acccontext.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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