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