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