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