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