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