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