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 throw (uno::RuntimeException)
601 {
602 uno::Reference < XAccessibleContext > xRet( this );
603 return xRet;
604 }
605
getAccessibleChildCount(void)606 sal_Int32 SAL_CALL SwAccessibleContext::getAccessibleChildCount( void )
607 throw (uno::RuntimeException)
608 {
609 vos::OGuard aGuard(Application::GetSolarMutex());
610
611 CHECK_FOR_DEFUNC( XAccessibleContext )
612 //Solution:Notify the frame is a document
613 if( nRole == AccessibleRole::DOCUMENT )
614 bIsAccDocUse = sal_True;
615
616 return bDisposing ? 0 : GetChildCount( *(GetMap()) );
617 }
618
619 uno::Reference< XAccessible> SAL_CALL
getAccessibleChild(sal_Int32 nIndex)620 SwAccessibleContext::getAccessibleChild( sal_Int32 nIndex )
621 throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
622 {
623 vos::OGuard aGuard(Application::GetSolarMutex());
624
625 CHECK_FOR_DEFUNC( XAccessibleContext )
626
627 //Solution:Notify the frame is a document
628 if( nRole == AccessibleRole::DOCUMENT )
629 bIsAccDocUse = sal_True;
630
631 const SwAccessibleChild aChild( GetChild( *(GetMap()), nIndex ) );
632 if( !aChild.IsValid() )
633 {
634 uno::Reference < XAccessibleContext > xThis( this );
635 lang::IndexOutOfBoundsException aExcept(
636 OUString( RTL_CONSTASCII_USTRINGPARAM("index out of bounds") ),
637 xThis );
638 throw aExcept;
639 }
640
641 uno::Reference< XAccessible > xChild;
642 if( aChild.GetSwFrm() )
643 {
644 ::vos::ORef < SwAccessibleContext > xChildImpl(
645 GetMap()->GetContextImpl( aChild.GetSwFrm(), !bDisposing ) );
646 //Solution:Send out accessible event when begin load.
647 if( bBeginDocumentLoad && nRole == AccessibleRole::DOCUMENT )
648 {
649
650 FireStateChangedEvent( AccessibleStateType::FOCUSABLE,sal_True );
651 FireStateChangedEvent( AccessibleStateType::BUSY,sal_True );
652 if( !isIfAsynLoad )
653 {
654 FireStateChangedEvent( AccessibleStateType::FOCUSED,sal_True );
655 // IA2 CWS. MT: OFFSCREEN == !SHOWING, should stay consistent
656 // FireStateChangedEvent( AccessibleStateType::OFFSCREEN,sal_True );
657 FireStateChangedEvent( AccessibleStateType::SHOWING,sal_True );
658 FireStateChangedEvent( AccessibleStateType::BUSY,sal_False );
659 // MT: OFFSCREEN again?
660 // FireStateChangedEvent( AccessibleStateType::OFFSCREEN,sal_False );
661 }
662 bBeginDocumentLoad = sal_False;
663 }
664 if( xChildImpl.isValid() )
665 {
666 xChildImpl->SetParent( this );
667 xChild = xChildImpl.getBodyPtr();
668 }
669 }
670 else if ( aChild.GetDrawObject() )
671 {
672 ::vos::ORef < ::accessibility::AccessibleShape > xChildImpl(
673 GetMap()->GetContextImpl( aChild.GetDrawObject(),
674 this, !bDisposing ) );
675 if( xChildImpl.isValid() )
676 xChild = xChildImpl.getBodyPtr();
677 }
678 else if ( aChild.GetWindow() )
679 {
680 xChild = aChild.GetWindow()->GetAccessible();
681 }
682
683 return xChild;
684 }
685
getAccessibleParent(void)686 uno::Reference< XAccessible> SAL_CALL SwAccessibleContext::getAccessibleParent (void)
687 throw (uno::RuntimeException)
688 {
689 vos::OGuard aGuard(Application::GetSolarMutex());
690
691 CHECK_FOR_DEFUNC( XAccessibleContext )
692
693 const SwFrm *pUpper = GetParent();
694 ASSERT( pUpper != 0 || bDisposing, "no upper found" );
695
696 uno::Reference< XAccessible > xAcc;
697 if( pUpper )
698 xAcc = GetMap()->GetContext( pUpper, !bDisposing );
699
700 ASSERT( xAcc.is() || bDisposing, "no parent found" );
701
702 // Remember the parent as weak ref.
703 {
704 vos::OGuard aWeakParentGuard( aMutex );
705 xWeakParent = xAcc;
706 }
707
708 return xAcc;
709 }
710
getAccessibleIndexInParent(void)711 sal_Int32 SAL_CALL SwAccessibleContext::getAccessibleIndexInParent (void)
712 throw (uno::RuntimeException)
713 {
714 vos::OGuard aGuard(Application::GetSolarMutex());
715
716 CHECK_FOR_DEFUNC( XAccessibleContext )
717
718 const SwFrm *pUpper = GetParent();
719 ASSERT( pUpper != 0 || bDisposing, "no upper found" );
720
721 sal_Int32 nIndex = -1;
722 if( pUpper )
723 {
724 ::vos::ORef < SwAccessibleContext > xAccImpl(
725 GetMap()->GetContextImpl( pUpper, !bDisposing ) );
726 ASSERT( xAccImpl.isValid() || bDisposing, "no parent found" );
727 if( xAccImpl.isValid() )
728 nIndex = xAccImpl->GetChildIndex( *(GetMap()), SwAccessibleChild(GetFrm()) );
729 }
730
731 return nIndex;
732 }
733
getAccessibleRole(void)734 sal_Int16 SAL_CALL SwAccessibleContext::getAccessibleRole (void)
735 throw (uno::RuntimeException)
736 {
737 return nRole;
738 }
739
getAccessibleDescription(void)740 OUString SAL_CALL SwAccessibleContext::getAccessibleDescription (void)
741 throw (uno::RuntimeException)
742 {
743 ASSERT( sal_False, "description needs to be overloaded" );
744 THROW_RUNTIME_EXCEPTION( XAccessibleContext, "internal error (method must be overloaded)" );
745 }
746
getAccessibleName(void)747 OUString SAL_CALL SwAccessibleContext::getAccessibleName (void)
748 throw (uno::RuntimeException)
749 {
750 return sName;
751 }
752
753 uno::Reference< XAccessibleRelationSet> SAL_CALL
getAccessibleRelationSet(void)754 SwAccessibleContext::getAccessibleRelationSet (void)
755 throw (uno::RuntimeException)
756 {
757 // by default there are no relations
758 uno::Reference< XAccessibleRelationSet> xRet( new utl::AccessibleRelationSetHelper() );
759 return xRet;
760 }
761
762 uno::Reference<XAccessibleStateSet> SAL_CALL
getAccessibleStateSet(void)763 SwAccessibleContext::getAccessibleStateSet (void)
764 throw (uno::RuntimeException)
765 {
766 vos::OGuard aGuard(Application::GetSolarMutex());
767
768 CHECK_FOR_DEFUNC( XAccessibleContext )
769
770 ::utl::AccessibleStateSetHelper *pStateSet =
771 new ::utl::AccessibleStateSetHelper;
772
773 if( bIsSeletedInDoc )
774 pStateSet->AddState( AccessibleStateType::SELECTED );
775
776 uno::Reference<XAccessibleStateSet> xStateSet( pStateSet );
777 GetStates( *pStateSet );
778
779 return xStateSet;
780 }
781
getLocale(void)782 lang::Locale SAL_CALL SwAccessibleContext::getLocale (void)
783 throw (IllegalAccessibleComponentStateException, uno::RuntimeException)
784 {
785 vos::OGuard aGuard(Application::GetSolarMutex());
786
787 lang::Locale aLoc( Application::GetSettings().GetLocale() );
788 return aLoc;
789 }
790
addEventListener(const uno::Reference<XAccessibleEventListener> & xListener)791 void SAL_CALL SwAccessibleContext::addEventListener(
792 const uno::Reference< XAccessibleEventListener >& xListener )
793 throw (uno::RuntimeException)
794 {
795 DBG_MSG( "accessible event listener added" )
796
797 if (xListener.is())
798 {
799 vos::OGuard aGuard(Application::GetSolarMutex());
800 if (!nClientId)
801 nClientId = comphelper::AccessibleEventNotifier::registerClient( );
802 comphelper::AccessibleEventNotifier::addEventListener( nClientId, xListener );
803 }
804 }
805
removeEventListener(const uno::Reference<XAccessibleEventListener> & xListener)806 void SAL_CALL SwAccessibleContext::removeEventListener(
807 const uno::Reference< XAccessibleEventListener >& xListener )
808 throw (uno::RuntimeException)
809 {
810 DBG_MSG( "accessible event listener removed" )
811
812 if (xListener.is())
813 {
814 vos::OGuard aGuard(Application::GetSolarMutex());
815 sal_Int32 nListenerCount = comphelper::AccessibleEventNotifier::removeEventListener( nClientId, xListener );
816 if ( !nListenerCount )
817 {
818 // no listeners anymore
819 // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client),
820 // and at least to us not firing any events anymore, in case somebody calls
821 // NotifyAccessibleEvent, again
822 comphelper::AccessibleEventNotifier::revokeClient( nClientId );
823 nClientId = 0;
824 }
825 }
826 }
827
lcl_PointInRectangle(const awt::Point & aPoint,const awt::Rectangle & aRect)828 static sal_Bool lcl_PointInRectangle(const awt::Point & aPoint,
829 const awt::Rectangle & aRect)
830 {
831 long nDiffX = aPoint.X - aRect.X;
832 long nDiffY = aPoint.Y - aRect.Y;
833
834 return
835 nDiffX >= 0 && nDiffX < aRect.Width && nDiffY >= 0 &&
836 nDiffY < aRect.Height;
837
838 }
839
containsPoint(const awt::Point & aPoint)840 sal_Bool SAL_CALL SwAccessibleContext::containsPoint(
841 const awt::Point& aPoint )
842 throw (uno::RuntimeException)
843 {
844 awt::Rectangle aPixBounds = getBoundsImpl(sal_True);
845 aPixBounds.X = 0;
846 aPixBounds.Y = 0;
847
848 return lcl_PointInRectangle(aPoint, aPixBounds);
849 }
850
getAccessibleAtPoint(const awt::Point & aPoint)851 uno::Reference< XAccessible > SAL_CALL SwAccessibleContext::getAccessibleAtPoint(
852 const awt::Point& aPoint )
853 throw (uno::RuntimeException)
854 {
855 vos::OGuard aGuard(Application::GetSolarMutex());
856
857 CHECK_FOR_DEFUNC( XAccessibleComponent )
858
859 uno::Reference< XAccessible > xAcc;
860
861 Window *pWin = GetWindow();
862 CHECK_FOR_WINDOW( XAccessibleComponent, pWin )
863
864 Point aPixPoint( aPoint.X, aPoint.Y ); // px rel to parent
865 if( !GetFrm()->IsRootFrm() )
866 {
867 SwRect aLogBounds( GetBounds( *(GetMap()), GetFrm() ) ); // twip rel to doc root
868 Point aPixPos( GetMap()->CoreToPixel( aLogBounds.SVRect() ).TopLeft() );
869 aPixPoint.X() += aPixPos.X();
870 aPixPoint.Y() += aPixPos.Y();
871 }
872
873 const SwAccessibleChild aChild( GetChildAtPixel( aPixPoint, *(GetMap()) ) );
874 if( aChild.GetSwFrm() )
875 {
876 xAcc = GetMap()->GetContext( aChild.GetSwFrm() );
877 }
878 else if( aChild.GetDrawObject() )
879 {
880 xAcc = GetMap()->GetContext( aChild.GetDrawObject(), this );
881 }
882 else if ( aChild.GetWindow() )
883 {
884 xAcc = aChild.GetWindow()->GetAccessible();
885 }
886
887 return xAcc;
888 }
889
890
891 /**
892 Get bounding box.
893
894 There are two modes.
895
896 - realative
897
898 Return bounding box relative to parent if parent is no root
899 frame. Otherwise return the absolute bounding box.
900
901 - absolute
902
903 Return the absolute bounding box.
904
905 @param bRelative
906 true: Use relative mode.
907 false: Use absolute mode.
908 */
getBoundsImpl(sal_Bool bRelative)909 awt::Rectangle SAL_CALL SwAccessibleContext::getBoundsImpl(sal_Bool bRelative)
910 throw (uno::RuntimeException)
911 {
912 vos::OGuard aGuard(Application::GetSolarMutex());
913
914 CHECK_FOR_DEFUNC( XAccessibleComponent )
915
916 const SwFrm *pParent = GetParent();
917 ASSERT( pParent, "no Parent found" );
918 Window *pWin = GetWindow();
919
920 CHECK_FOR_WINDOW( XAccessibleComponent, pWin && pParent )
921
922 SwRect aLogBounds( GetBounds( *(GetMap()), GetFrm() ) ); // twip rel to doc root
923 Rectangle aPixBounds( 0, 0, 0, 0 );
924 if( GetFrm()->IsPageFrm() &&
925 static_cast < const SwPageFrm * >( GetFrm() )->IsEmptyPage() )
926 {
927 ASSERT( GetShell()->IsPreView(), "empty page accessible?" );
928 if( GetShell()->IsPreView() )
929 {
930 // OD 15.01.2003 #103492# - adjust method call <GetMap()->GetPreViewPageSize()>
931 sal_uInt16 nPageNum =
932 static_cast < const SwPageFrm * >( GetFrm() )->GetPhyPageNum();
933 aLogBounds.SSize( GetMap()->GetPreViewPageSize( nPageNum ) );
934 }
935 }
936 if( !aLogBounds.IsEmpty() )
937 {
938 aPixBounds = GetMap()->CoreToPixel( aLogBounds.SVRect() );
939 if( !pParent->IsRootFrm() && bRelative)
940 {
941 SwRect aParentLogBounds( GetBounds( *(GetMap()), pParent ) ); // twip rel to doc root
942 Point aParentPixPos( GetMap()->CoreToPixel( aParentLogBounds.SVRect() ).TopLeft() );
943 aPixBounds.Move( -aParentPixPos.X(), -aParentPixPos.Y() );
944 }
945 }
946
947 awt::Rectangle aBox( aPixBounds.Left(), aPixBounds.Top(),
948 aPixBounds.GetWidth(), aPixBounds.GetHeight() );
949
950 return aBox;
951 }
952
953
getBounds()954 awt::Rectangle SAL_CALL SwAccessibleContext::getBounds()
955 throw (uno::RuntimeException)
956 {
957 return getBoundsImpl(sal_True);
958 }
959
getLocation()960 awt::Point SAL_CALL SwAccessibleContext::getLocation()
961 throw (uno::RuntimeException)
962 {
963 awt::Rectangle aRect = getBoundsImpl(sal_True);
964 awt::Point aPoint(aRect.X, aRect.Y);
965
966 return aPoint;
967 }
968
969
970
getLocationOnScreen()971 awt::Point SAL_CALL SwAccessibleContext::getLocationOnScreen()
972 throw (uno::RuntimeException)
973 {
974 awt::Rectangle aRect = getBoundsImpl(sal_False);
975
976 Point aPixPos(aRect.X, aRect.Y);
977
978 /* getBoundsImpl already checked that GetWindow returns valid pointer. */
979 aPixPos = GetWindow()->OutputToAbsoluteScreenPixel(aPixPos);
980 awt::Point aPoint(aPixPos.X(), aPixPos.Y());
981
982 return aPoint;
983 }
984
985
getSize()986 awt::Size SAL_CALL SwAccessibleContext::getSize()
987 throw (uno::RuntimeException)
988 {
989 awt::Rectangle aRect = getBoundsImpl(sal_False);
990 awt::Size aSize( aRect.Width, aRect.Height );
991
992 return aSize;
993 }
994
grabFocus()995 void SAL_CALL SwAccessibleContext::grabFocus()
996 throw (uno::RuntimeException)
997 {
998 vos::OGuard aGuard(Application::GetSolarMutex());
999
1000 CHECK_FOR_DEFUNC( XAccessibleContext );
1001
1002 if( GetFrm()->IsFlyFrm() )
1003 {
1004 const SdrObject *pObj =
1005 static_cast < const SwFlyFrm * >( GetFrm() )->GetVirtDrawObj();
1006 if( pObj )
1007 Select( const_cast < SdrObject * >( pObj ), sal_False );
1008 }
1009 else
1010 {
1011 const SwCntntFrm *pCFrm = 0;
1012 if( GetFrm()->IsCntntFrm() )
1013 pCFrm = static_cast< const SwCntntFrm * >( GetFrm() );
1014 else if( GetFrm()->IsLayoutFrm() )
1015 pCFrm = static_cast< const SwLayoutFrm * >( GetFrm() )->ContainsCntnt();
1016
1017 if( pCFrm && pCFrm->IsTxtFrm() )
1018 {
1019 const SwTxtFrm *pTxtFrm = static_cast< const SwTxtFrm * >( pCFrm );
1020 const SwTxtNode *pTxtNd = pTxtFrm->GetTxtNode();
1021 if( pTxtNd )
1022 {
1023 // create pam for selection
1024 SwIndex aIndex( const_cast< SwTxtNode * >( pTxtNd ),
1025 pTxtFrm->GetOfst() );
1026 SwPosition aStartPos( *pTxtNd, aIndex );
1027 SwPaM aPaM( aStartPos );
1028
1029 // set PaM at cursor shell
1030 Select( aPaM );
1031 }
1032 }
1033 }
1034 }
1035
1036
getAccessibleKeyBinding()1037 uno::Any SAL_CALL SwAccessibleContext::getAccessibleKeyBinding()
1038 throw (uno::RuntimeException)
1039 {
1040 // There are no key bindings
1041 return uno::Any();
1042 }
1043
getForeground()1044 sal_Int32 SAL_CALL SwAccessibleContext::getForeground()
1045 throw (uno::RuntimeException)
1046 {
1047 return COL_BLACK;
1048 }
1049
getBackground()1050 sal_Int32 SAL_CALL SwAccessibleContext::getBackground()
1051 throw (uno::RuntimeException)
1052 {
1053 return COL_WHITE;
1054 }
1055
1056
getImplementationName()1057 OUString SAL_CALL SwAccessibleContext::getImplementationName()
1058 throw( uno::RuntimeException )
1059 {
1060 ASSERT( sal_False, "implementation name needs to be overloaded" );
1061
1062 THROW_RUNTIME_EXCEPTION( lang::XServiceInfo, "implementation name needs to be overloaded" )
1063 }
1064
1065 sal_Bool SAL_CALL
supportsService(const::rtl::OUString &)1066 SwAccessibleContext::supportsService (const ::rtl::OUString& )
1067 throw (uno::RuntimeException)
1068 {
1069 ASSERT( sal_False, "supports service needs to be overloaded" );
1070 THROW_RUNTIME_EXCEPTION( lang::XServiceInfo, "supports service needs to be overloaded" )
1071 }
1072
getSupportedServiceNames()1073 uno::Sequence< OUString > SAL_CALL SwAccessibleContext::getSupportedServiceNames()
1074 throw( uno::RuntimeException )
1075 {
1076 ASSERT( sal_False, "supported services names needs to be overloaded" );
1077 THROW_RUNTIME_EXCEPTION( lang::XServiceInfo, "supported services needs to be overloaded" )
1078 }
1079
DisposeShape(const SdrObject * pObj,::accessibility::AccessibleShape * pAccImpl)1080 void SwAccessibleContext::DisposeShape( const SdrObject *pObj,
1081 ::accessibility::AccessibleShape *pAccImpl )
1082 {
1083 ::vos::ORef< ::accessibility::AccessibleShape > xAccImpl( pAccImpl );
1084 if( !xAccImpl.isValid() )
1085 xAccImpl = GetMap()->GetContextImpl( pObj, this, sal_True );
1086
1087 AccessibleEventObject aEvent;
1088 aEvent.EventId = AccessibleEventId::CHILD;
1089 uno::Reference< XAccessible > xAcc( xAccImpl.getBodyPtr() );
1090 aEvent.OldValue <<= xAcc;
1091 FireAccessibleEvent( aEvent );
1092
1093 GetMap()->RemoveContext( pObj );
1094 xAccImpl->dispose();
1095 }
1096
ScrolledInShape(const SdrObject *,::accessibility::AccessibleShape * pAccImpl)1097 void SwAccessibleContext::ScrolledInShape( const SdrObject* ,
1098 ::accessibility::AccessibleShape *pAccImpl )
1099 {
1100 if(NULL == pAccImpl)
1101 {
1102 return ;
1103 }
1104 AccessibleEventObject aEvent;
1105 aEvent.EventId = AccessibleEventId::CHILD;
1106 uno::Reference< XAccessible > xAcc( pAccImpl );
1107 aEvent.NewValue <<= xAcc;
1108 FireAccessibleEvent( aEvent );
1109
1110 if( pAccImpl->GetState( AccessibleStateType::FOCUSED ) )
1111 {
1112 Window *pWin = GetWindow();
1113 if( pWin && pWin->HasFocus() )
1114 {
1115 AccessibleEventObject aStateChangedEvent;
1116 aStateChangedEvent.EventId = AccessibleEventId::STATE_CHANGED;
1117 aStateChangedEvent.NewValue <<= AccessibleStateType::FOCUSED;
1118 aStateChangedEvent.Source = xAcc;
1119
1120 FireAccessibleEvent( aStateChangedEvent );
1121 }
1122 }
1123 }
1124
Dispose(sal_Bool bRecursive)1125 void SwAccessibleContext::Dispose( sal_Bool bRecursive )
1126 {
1127 vos::OGuard aGuard(Application::GetSolarMutex());
1128
1129 ASSERT( GetFrm() && GetMap(), "already disposed" );
1130 ASSERT( GetMap()->GetVisArea() == GetVisArea(),
1131 "invalid vis area for dispose" );
1132
1133 bDisposing = sal_True;
1134
1135 // dispose children
1136 if( bRecursive )
1137 DisposeChildren( GetFrm(), bRecursive );
1138
1139 // get parent
1140 uno::Reference< XAccessible > xParent( GetWeakParent() );
1141 uno::Reference < XAccessibleContext > xThis( this );
1142
1143 // send child event at parent
1144 if( xParent.is() )
1145 {
1146 SwAccessibleContext *pAcc = (SwAccessibleContext *)xParent.get();
1147
1148 AccessibleEventObject aEvent;
1149 aEvent.EventId = AccessibleEventId::CHILD;
1150 aEvent.OldValue <<= xThis;
1151 pAcc->FireAccessibleEvent( aEvent );
1152 DBG_MSG_THIS_PARAM( "AccessibleChild (removed)", pAcc, this )
1153 }
1154
1155 // set defunc state (its not required to broadcast a state changed
1156 // event if the object is diposed afterwards)
1157 {
1158 vos::OGuard aDefuncStateGuard( aMutex );
1159 bIsDefuncState = sal_True;
1160 }
1161
1162 // broadcast dispose event
1163 if ( nClientId )
1164 {
1165 comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( nClientId, *this );
1166 nClientId = 0;
1167 DBG_MSG_CD( "dispose" )
1168 }
1169
1170 RemoveFrmFromAccessibleMap();
1171 ClearFrm();
1172 pMap = 0;
1173
1174 bDisposing = sal_False;
1175 }
1176
DisposeChild(const SwAccessibleChild & rChildFrmOrObj,sal_Bool bRecursive)1177 void SwAccessibleContext::DisposeChild( const SwAccessibleChild& rChildFrmOrObj,
1178 sal_Bool bRecursive )
1179 {
1180 vos::OGuard aGuard(Application::GetSolarMutex());
1181
1182 if ( IsShowing( *(GetMap()), rChildFrmOrObj ) ||
1183 rChildFrmOrObj.AlwaysIncludeAsChild() ||
1184 !SwAccessibleChild( GetFrm() ).IsVisibleChildrenOnly() )
1185 {
1186 // If the object could have existed before, than there is nothing to do,
1187 // because no wrapper exists now and therefor no one is interested to
1188 // get notified of the movement.
1189 if( rChildFrmOrObj.GetSwFrm() )
1190 {
1191 ::vos::ORef< SwAccessibleContext > xAccImpl =
1192 GetMap()->GetContextImpl( rChildFrmOrObj.GetSwFrm(),
1193 sal_True );
1194 xAccImpl->Dispose( bRecursive );
1195 }
1196 else if ( rChildFrmOrObj.GetDrawObject() )
1197 {
1198 ::vos::ORef< ::accessibility::AccessibleShape > xAccImpl =
1199 GetMap()->GetContextImpl( rChildFrmOrObj.GetDrawObject(),
1200 this, sal_True );
1201 DisposeShape( rChildFrmOrObj.GetDrawObject(),
1202 xAccImpl.getBodyPtr() );
1203 }
1204 else if ( rChildFrmOrObj.GetWindow() )
1205 {
1206 AccessibleEventObject aEvent;
1207 aEvent.EventId = AccessibleEventId::CHILD;
1208 uno::Reference< XAccessible > xAcc =
1209 rChildFrmOrObj.GetWindow()->GetAccessible();
1210 aEvent.OldValue <<= xAcc;
1211 FireAccessibleEvent( aEvent );
1212 }
1213 }
1214 else if( bRecursive && rChildFrmOrObj.GetSwFrm() )
1215 DisposeChildren( rChildFrmOrObj.GetSwFrm(), bRecursive );
1216 }
1217
InvalidatePosOrSize(const SwRect &)1218 void SwAccessibleContext::InvalidatePosOrSize( const SwRect& )
1219 {
1220 vos::OGuard aGuard(Application::GetSolarMutex());
1221
1222 ASSERT( GetFrm() && !GetFrm()->Frm().IsEmpty(), "context should have a size" );
1223
1224 sal_Bool bIsOldShowingState;
1225 sal_Bool bIsNewShowingState = IsShowing( *(GetMap()) );
1226 {
1227 vos::OGuard aShowingStateGuard( aMutex );
1228 bIsOldShowingState = bIsShowingState;
1229 bIsShowingState = bIsNewShowingState;
1230 }
1231
1232 if( bIsOldShowingState != bIsNewShowingState )
1233 {
1234 FireStateChangedEvent( AccessibleStateType::SHOWING,
1235 bIsNewShowingState );
1236 }
1237 else if( bIsNewShowingState )
1238 {
1239 // The frame stays visible -> broadcast event
1240 FireVisibleDataEvent();
1241 }
1242
1243 if( !bIsNewShowingState &&
1244 SwAccessibleChild( GetParent() ).IsVisibleChildrenOnly() )
1245 {
1246 // The frame is now invisible -> dispose it
1247 //Remove
1248 //Dispose( sal_True );
1249 }
1250 else
1251 {
1252 _InvalidateContent( sal_True );
1253 }
1254 }
1255
InvalidateChildPosOrSize(const SwAccessibleChild & rChildFrmOrObj,const SwRect & rOldFrm)1256 void SwAccessibleContext::InvalidateChildPosOrSize(
1257 const SwAccessibleChild& rChildFrmOrObj,
1258 const SwRect& rOldFrm )
1259 {
1260 vos::OGuard aGuard(Application::GetSolarMutex());
1261
1262 ASSERT( !rChildFrmOrObj.GetSwFrm() ||
1263 !rChildFrmOrObj.GetSwFrm()->Frm().IsEmpty(),
1264 "child context should have a size" );
1265
1266 if ( rChildFrmOrObj.AlwaysIncludeAsChild() )
1267 {
1268 // nothing to do;
1269 return;
1270 }
1271
1272 const bool bVisibleChildrenOnly = SwAccessibleChild( GetFrm() ).IsVisibleChildrenOnly();
1273 const bool bNew = rOldFrm.IsEmpty() ||
1274 ( rOldFrm.Left() == 0 && rOldFrm.Top() == 0 );
1275 if( IsShowing( *(GetMap()), rChildFrmOrObj ) )
1276 {
1277 // If the object could have existed before, than there is nothing to do,
1278 // because no wrapper exists now and therefor no one is interested to
1279 // get notified of the movement.
1280 if( bNew || (bVisibleChildrenOnly && !IsShowing( rOldFrm )) )
1281 {
1282 if( rChildFrmOrObj.GetSwFrm() )
1283 {
1284 // The frame becomes visible. A child event must be send.
1285 ::vos::ORef< SwAccessibleContext > xAccImpl =
1286 GetMap()->GetContextImpl( rChildFrmOrObj.GetSwFrm(),
1287 sal_True );
1288 xAccImpl->ScrolledIn();
1289 }
1290 else if ( rChildFrmOrObj.GetDrawObject() )
1291 {
1292 ::vos::ORef< ::accessibility::AccessibleShape > xAccImpl =
1293 GetMap()->GetContextImpl( rChildFrmOrObj.GetDrawObject(),
1294 this, sal_True );
1295 // --> OD 2004-11-29 #i37790#
1296 if ( xAccImpl.isValid() )
1297 {
1298 ScrolledInShape( rChildFrmOrObj.GetDrawObject(),
1299 xAccImpl.getBodyPtr() );
1300 }
1301 else
1302 {
1303 ASSERT( false ,
1304 "<SwAccessibleContext::InvalidateChildPosOrSize(..)> - no accessible shape found." );
1305 }
1306 // <--
1307 }
1308 else if ( rChildFrmOrObj.GetWindow() )
1309 {
1310 AccessibleEventObject aEvent;
1311 aEvent.EventId = AccessibleEventId::CHILD;
1312 aEvent.NewValue <<= (rChildFrmOrObj.GetWindow()->GetAccessible());
1313 FireAccessibleEvent( aEvent );
1314 }
1315 }
1316 }
1317 else
1318 {
1319 // If the frame was visible before, than a child event for the parent
1320 // needs to be send. However, there is no wrapper existing, and so
1321 // no notifications for grandchildren are required. If the are
1322 // grandgrandchildren, they would be notified by the layout.
1323 if( bVisibleChildrenOnly &&
1324 !bNew && IsShowing( rOldFrm ) )
1325 {
1326 if( rChildFrmOrObj.GetSwFrm() )
1327 {
1328 ::vos::ORef< SwAccessibleContext > xAccImpl =
1329 GetMap()->GetContextImpl( rChildFrmOrObj.GetSwFrm(),
1330 sal_True );
1331 xAccImpl->SetParent( this );
1332 xAccImpl->Dispose( sal_True );
1333 }
1334 else if ( rChildFrmOrObj.GetDrawObject() )
1335 {
1336 ::vos::ORef< ::accessibility::AccessibleShape > xAccImpl =
1337 GetMap()->GetContextImpl( rChildFrmOrObj.GetDrawObject(),
1338 this, sal_True );
1339 DisposeShape( rChildFrmOrObj.GetDrawObject(),
1340 xAccImpl.getBodyPtr() );
1341 }
1342 else if ( rChildFrmOrObj.GetWindow() )
1343 {
1344 ASSERT( false,
1345 "<SwAccessibleContext::InvalidateChildPosOrSize(..)> - not expected to handle dispose of child of type <Window>." );
1346 }
1347 }
1348 }
1349 }
1350
InvalidateContent()1351 void SwAccessibleContext::InvalidateContent()
1352 {
1353 vos::OGuard aGuard(Application::GetSolarMutex());
1354
1355 _InvalidateContent( sal_False );
1356 }
1357
InvalidateCursorPos()1358 void SwAccessibleContext::InvalidateCursorPos()
1359 {
1360 vos::OGuard aGuard(Application::GetSolarMutex());
1361
1362 _InvalidateCursorPos();
1363 }
1364
InvalidateFocus()1365 void SwAccessibleContext::InvalidateFocus()
1366 {
1367 vos::OGuard aGuard(Application::GetSolarMutex());
1368
1369 _InvalidateFocus();
1370 }
1371
1372 // --> OD 2005-12-12 #i27301# - use new type definition for <_nStates>
InvalidateStates(tAccessibleStates _nStates)1373 void SwAccessibleContext::InvalidateStates( tAccessibleStates _nStates )
1374 {
1375 if( GetMap() )
1376 {
1377 ViewShell *pVSh = GetMap()->GetShell();
1378 if( pVSh )
1379 {
1380 if( (_nStates & ACC_STATE_EDITABLE) != 0 )
1381 {
1382 sal_Bool bIsOldEditableState;
1383 sal_Bool bIsNewEditableState = IsEditable( pVSh );
1384 {
1385 vos::OGuard aGuard( aMutex );
1386 bIsOldEditableState = bIsEditableState;
1387 bIsEditableState = bIsNewEditableState;
1388 }
1389
1390 if( bIsOldEditableState != bIsNewEditableState )
1391 FireStateChangedEvent( AccessibleStateType::EDITABLE,
1392 bIsNewEditableState );
1393 }
1394 if( (_nStates & ACC_STATE_OPAQUE) != 0 )
1395 {
1396 sal_Bool bIsOldOpaqueState;
1397 sal_Bool bIsNewOpaqueState = IsOpaque( pVSh );
1398 {
1399 vos::OGuard aGuard( aMutex );
1400 bIsOldOpaqueState = bIsOpaqueState;
1401 bIsOpaqueState = bIsNewOpaqueState;
1402 }
1403
1404 if( bIsOldOpaqueState != bIsNewOpaqueState )
1405 FireStateChangedEvent( AccessibleStateType::OPAQUE,
1406 bIsNewOpaqueState );
1407 }
1408 }
1409
1410 InvalidateChildrenStates( GetFrm(), _nStates );
1411 }
1412 }
1413 // <--
1414
InvalidateRelation(sal_uInt16 nType)1415 void SwAccessibleContext::InvalidateRelation( sal_uInt16 nType )
1416 {
1417 AccessibleEventObject aEvent;
1418 aEvent.EventId = nType;
1419
1420 FireAccessibleEvent( aEvent );
1421 }
1422
1423 /** text selection has changed
1424
1425 OD 2005-12-14 #i27301#
1426
1427 @author OD
1428 */
InvalidateTextSelection()1429 void SwAccessibleContext::InvalidateTextSelection()
1430 {
1431 AccessibleEventObject aEvent;
1432 aEvent.EventId = AccessibleEventId::TEXT_SELECTION_CHANGED;
1433
1434 FireAccessibleEvent( aEvent );
1435 }
1436
1437 /** attributes has changed
1438
1439 OD 2009-01-06 #i88069#
1440
1441 @author OD
1442 */
InvalidateAttr()1443 void SwAccessibleContext::InvalidateAttr()
1444 {
1445 AccessibleEventObject aEvent;
1446 aEvent.EventId = AccessibleEventId::TEXT_ATTRIBUTE_CHANGED;
1447
1448 FireAccessibleEvent( aEvent );
1449 }
1450
HasCursor()1451 sal_Bool SwAccessibleContext::HasCursor()
1452 {
1453 return sal_False;
1454 }
1455
Select(SwPaM * pPaM,SdrObject * pObj,sal_Bool bAdd)1456 sal_Bool SwAccessibleContext::Select( SwPaM *pPaM, SdrObject *pObj,
1457 sal_Bool bAdd )
1458 {
1459 SwCrsrShell* pCrsrShell = GetCrsrShell();
1460 if( !pCrsrShell )
1461 return sal_False;
1462
1463 SwFEShell* pFEShell = pCrsrShell->ISA( SwFEShell )
1464 ? static_cast<SwFEShell*>( pCrsrShell )
1465 : 0;
1466 // Get rid of activated OLE object
1467 if( pFEShell )
1468 pFEShell->FinishOLEObj();
1469
1470 sal_Bool bRet = sal_False;
1471 if( pObj )
1472 {
1473 if( pFEShell )
1474 {
1475 Point aDummy;
1476 sal_uInt8 nFlags = bAdd ? SW_ADD_SELECT : 0;
1477 pFEShell->SelectObj( aDummy, nFlags, pObj );
1478 bRet = sal_True;
1479 }
1480 }
1481 else if( pPaM )
1482 {
1483 // Get rid of frame selection. If there is one, make text cursor
1484 // visible again.
1485 sal_Bool bCallShowCrsr = sal_False;
1486 if( pFEShell && (pFEShell->IsFrmSelected() ||
1487 pFEShell->IsObjSelected()) )
1488 {
1489 Point aPt( LONG_MIN, LONG_MIN );
1490 pFEShell->SelectObj( aPt, 0 );
1491 bCallShowCrsr = sal_True;
1492 }
1493 pCrsrShell->KillPams();
1494 pCrsrShell->SetSelection( *pPaM );
1495 if( bCallShowCrsr )
1496 pCrsrShell->ShowCrsr();
1497 bRet = sal_True;
1498 }
1499
1500 return bRet;
1501 }
1502
GetResource(sal_uInt16 nResId,const OUString * pArg1,const OUString * pArg2)1503 OUString SwAccessibleContext::GetResource( sal_uInt16 nResId,
1504 const OUString *pArg1,
1505 const OUString *pArg2 )
1506 {
1507 String sStr;
1508 {
1509 vos::OGuard aGuard(Application::GetSolarMutex());
1510
1511 sStr = SW_RES( nResId );
1512 }
1513
1514 if( pArg1 )
1515 {
1516 sStr.SearchAndReplace( String::CreateFromAscii(
1517 RTL_CONSTASCII_STRINGPARAM( "$(ARG1)" )),
1518 String( *pArg1 ) );
1519 }
1520 if( pArg2 )
1521 {
1522 sStr.SearchAndReplace( String::CreateFromAscii(
1523 RTL_CONSTASCII_STRINGPARAM( "$(ARG2)" )),
1524 String( *pArg2 ) );
1525 }
1526
1527 return OUString( sStr );
1528 }
1529
RemoveFrmFromAccessibleMap()1530 void SwAccessibleContext::RemoveFrmFromAccessibleMap()
1531 {
1532 if( bRegisteredAtAccessibleMap && GetFrm() && GetMap() )
1533 GetMap()->RemoveContext( GetFrm() );
1534 }
1535
HasAdditionalAccessibleChildren()1536 bool SwAccessibleContext::HasAdditionalAccessibleChildren()
1537 {
1538 bool bRet( false );
1539
1540 if ( GetFrm()->IsTxtFrm() )
1541 {
1542 SwPostItMgr* pPostItMgr = GetMap()->GetShell()->GetPostItMgr();
1543 if ( pPostItMgr && pPostItMgr->HasNotes() && pPostItMgr->ShowNotes() )
1544 {
1545 bRet = pPostItMgr->HasFrmConnectedSidebarWins( *(GetFrm()) );
1546 }
1547 }
1548
1549 return bRet;
1550 }
1551 /** get additional accessible child by index
1552
1553 OD 2010-01-27 #i88070#
1554
1555 @author OD
1556 */
GetAdditionalAccessibleChild(const sal_Int32 nIndex)1557 Window* SwAccessibleContext::GetAdditionalAccessibleChild( const sal_Int32 nIndex )
1558 {
1559 Window* pAdditionalAccessibleChild( 0 );
1560
1561 if ( GetFrm()->IsTxtFrm() )
1562 {
1563 SwPostItMgr* pPostItMgr = GetMap()->GetShell()->GetPostItMgr();
1564 if ( pPostItMgr && pPostItMgr->HasNotes() && pPostItMgr->ShowNotes() )
1565 {
1566 pAdditionalAccessibleChild =
1567 pPostItMgr->GetSidebarWinForFrmByIndex( *(GetFrm()), nIndex );
1568 }
1569 }
1570
1571 return pAdditionalAccessibleChild;
1572 }
1573
1574 /** get all additional accessible children
1575
1576 OD 2010-01-27 #i88070#
1577
1578 @author OD
1579 */
GetAdditionalAccessibleChildren(std::vector<Window * > * pChildren)1580 void SwAccessibleContext::GetAdditionalAccessibleChildren( std::vector< Window* >* pChildren )
1581 {
1582 if ( GetFrm()->IsTxtFrm() )
1583 {
1584 SwPostItMgr* pPostItMgr = GetMap()->GetShell()->GetPostItMgr();
1585 if ( pPostItMgr && pPostItMgr->HasNotes() && pPostItMgr->ShowNotes() )
1586 {
1587 pPostItMgr->GetAllSidebarWinForFrm( *(GetFrm()), pChildren );
1588 }
1589 }
1590 }
1591
1592 #if (OSL_DEBUG_LEVEL > 1) && defined TEST_MIB
lcl_SwAccessibleContext_DbgMsg(SwAccessibleContext * pThisAcc,const char * pMsg,SwAccessibleContext * pChildAcc,sal_Bool bConstrDestr)1593 void lcl_SwAccessibleContext_DbgMsg( SwAccessibleContext *pThisAcc,
1594 const char *pMsg,
1595 SwAccessibleContext *pChildAcc,
1596 sal_Bool bConstrDestr )
1597 {
1598 static SvFileStream aStrm( String::CreateFromAscii("j:\\acc.log"),
1599 STREAM_WRITE|STREAM_TRUNC|STREAM_SHARE_DENYNONE );
1600 ByteString aName( String(pThisAcc->GetName()),
1601 RTL_TEXTENCODING_ISO_8859_1 );
1602 if( aName.Len() )
1603 {
1604 aStrm << aName.GetBuffer()
1605 << ": ";
1606 }
1607 aStrm << pMsg;
1608 if( pChildAcc )
1609 {
1610 ByteString aChild( String(pChildAcc->GetName()),
1611 RTL_TEXTENCODING_ISO_8859_1 );
1612 aStrm << ": "
1613 << aChild.GetBuffer();
1614 }
1615 aStrm << "\r\n (";
1616
1617 if( !bConstrDestr )
1618 {
1619 ByteString aDesc( String(pThisAcc->getAccessibleDescription()),
1620 RTL_TEXTENCODING_ISO_8859_1 );
1621 aStrm << aDesc.GetBuffer()
1622 << ", ";
1623 }
1624
1625 Rectangle aVisArea( pThisAcc->GetVisArea() );
1626 aStrm << "VA: "
1627 << ByteString::CreateFromInt32( aVisArea.Left() ).GetBuffer()
1628 << ","
1629 << ByteString::CreateFromInt32( aVisArea.Top() ).GetBuffer()
1630 << ","
1631 << ByteString::CreateFromInt32( aVisArea.GetWidth() ).GetBuffer()
1632 << ","
1633 << ByteString::CreateFromInt32( aVisArea.GetHeight() ).GetBuffer();
1634
1635 if( pThisAcc->GetFrm() )
1636 {
1637 Rectangle aBounds( pThisAcc->GetBounds( pThisAcc->GetFrm() ) );
1638 aStrm << ", BB: "
1639 << ByteString::CreateFromInt32( aBounds.Left() ).GetBuffer()
1640 << ","
1641 << ByteString::CreateFromInt32( aBounds.Top() ).GetBuffer()
1642 << ","
1643 << ByteString::CreateFromInt32( aBounds.GetWidth() ).GetBuffer()
1644 << ","
1645 << ByteString::CreateFromInt32( aBounds.GetHeight() ).GetBuffer()
1646 << ")\r\n";
1647 }
1648
1649 aStrm.Flush();
1650 }
1651 #endif
SetSelectedState(sal_Bool bSeleted)1652 sal_Bool SwAccessibleContext::SetSelectedState(sal_Bool bSeleted)
1653 {
1654 if(bIsSeletedInDoc != bSeleted)
1655 {
1656 bIsSeletedInDoc = bSeleted;
1657 FireStateChangedEvent( AccessibleStateType::SELECTED, bSeleted );
1658 return sal_True;
1659 }
1660 return sal_False;
1661 };
1662