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