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