android: Update app-specific/MIME type icons
[LibreOffice.git] / sw / source / core / access / acccontext.cxx
blob46d1d12f35f17b89ef21c4ba843528fdcb01a0d1
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <vcl/window.hxx>
21 #include <swtypes.hxx>
23 #include <com/sun/star/accessibility/XAccessible.hpp>
24 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
25 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
26 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
27 #include <sal/log.hxx>
28 #include <vcl/svapp.hxx>
29 #include <vcl/settings.hxx>
30 #include <i18nlangtag/languagetag.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 <accmap.hxx>
43 #include "accfrmobjslist.hxx"
44 #include "acccontext.hxx"
45 #include <svx/AccessibleShape.hxx>
46 #include <comphelper/accessibleeventnotifier.hxx>
47 #include <cppuhelper/supportsservice.hxx>
48 #include <PostItMgr.hxx>
50 using namespace sw::access;
51 using namespace ::com::sun::star;
52 using namespace ::com::sun::star::accessibility;
54 void SwAccessibleContext::InitStates()
56 m_isShowingState = GetMap() && IsShowing( *(GetMap()) );
58 SwViewShell *pVSh = GetMap()->GetShell();
59 m_isEditableState = pVSh && IsEditable( pVSh );
60 m_isOpaqueState = pVSh && IsOpaque( pVSh );
61 m_isDefuncState = false;
64 void SwAccessibleContext::SetParent( SwAccessibleContext *pParent )
66 std::scoped_lock aGuard( m_Mutex );
68 uno::Reference < XAccessible > xParent( pParent );
69 m_xWeakParent = xParent;
72 uno::Reference< XAccessible > SwAccessibleContext::GetWeakParent() const
74 std::scoped_lock aGuard( m_Mutex );
76 uno::Reference< XAccessible > xParent( m_xWeakParent );
77 return xParent;
80 vcl::Window *SwAccessibleContext::GetWindow()
82 vcl::Window *pWin = nullptr;
84 if( GetMap() )
86 const SwViewShell *pVSh = GetMap()->GetShell();
87 OSL_ENSURE( pVSh, "no view shell" );
88 if( pVSh )
89 pWin = pVSh->GetWin();
91 OSL_ENSURE( pWin, "no window" );
94 return pWin;
97 // get SwViewShell from accessibility map, and cast to cursor shell
98 SwCursorShell* SwAccessibleContext::GetCursorShell()
100 SwViewShell* pViewShell = GetMap() ? GetMap()->GetShell() : nullptr;
101 OSL_ENSURE( pViewShell, "no view shell" );
102 return dynamic_cast<SwCursorShell*>( pViewShell);
105 const SwCursorShell* SwAccessibleContext::GetCursorShell() const
107 // just like non-const GetCursorShell
108 const SwViewShell* pViewShell = GetMap() ? GetMap()->GetShell() : nullptr;
109 OSL_ENSURE( pViewShell, "no view shell" );
110 return dynamic_cast<const SwCursorShell*>( pViewShell);
113 namespace {
115 enum class Action { NONE, SCROLLED, SCROLLED_WITHIN,
116 SCROLLED_IN, SCROLLED_OUT };
120 void SwAccessibleContext::ChildrenScrolled( const SwFrame *pFrame,
121 const SwRect& rOldVisArea )
123 const SwRect& rNewVisArea = GetVisArea();
124 const bool bVisibleChildrenOnly = SwAccessibleChild( pFrame ).IsVisibleChildrenOnly();
126 const SwAccessibleChildSList aList( *pFrame, *(GetMap()) );
127 SwAccessibleChildSList::const_iterator aIter( aList.begin() );
128 while( aIter != aList.end() )
130 const SwAccessibleChild& rLower = *aIter;
131 const SwRect aBox( rLower.GetBox( *(GetMap()) ) );
132 if( rLower.IsAccessible( GetShell()->IsPreview() ) )
134 Action eAction = Action::NONE;
135 if( aBox.Overlaps( rNewVisArea ) )
137 if( aBox.Overlaps( rOldVisArea ) )
139 eAction = Action::SCROLLED_WITHIN;
141 else
143 if ( bVisibleChildrenOnly &&
144 !rLower.AlwaysIncludeAsChild() )
146 eAction = Action::SCROLLED_IN;
148 else
150 eAction = Action::SCROLLED;
154 else if( aBox.Overlaps( rOldVisArea ) )
156 if ( bVisibleChildrenOnly &&
157 !rLower.AlwaysIncludeAsChild() )
159 eAction = Action::SCROLLED_OUT;
161 else
163 eAction = Action::SCROLLED;
166 else if( !bVisibleChildrenOnly ||
167 rLower.AlwaysIncludeAsChild() )
169 // This wouldn't be required if the SwAccessibleFrame,
170 // wouldn't know about the visible area.
171 eAction = Action::SCROLLED;
173 if( Action::NONE != eAction )
175 if ( rLower.GetSwFrame() )
177 OSL_ENSURE( !rLower.AlwaysIncludeAsChild(),
178 "<SwAccessibleContext::ChildrenScrolled(..)> - always included child not considered!" );
179 const SwFrame* pLower( rLower.GetSwFrame() );
180 ::rtl::Reference< SwAccessibleContext > xAccImpl =
181 GetMap()->GetContextImpl( pLower );
182 if( xAccImpl.is() )
184 switch( eAction )
186 case Action::SCROLLED:
187 xAccImpl->Scrolled( rOldVisArea );
188 break;
189 case Action::SCROLLED_WITHIN:
190 xAccImpl->ScrolledWithin( rOldVisArea );
191 break;
192 case Action::SCROLLED_IN:
193 xAccImpl->ScrolledIn();
194 break;
195 case Action::SCROLLED_OUT:
196 xAccImpl->ScrolledOut( rOldVisArea );
197 break;
198 case Action::NONE:
199 break;
202 else
204 ChildrenScrolled( pLower, rOldVisArea );
207 else if ( rLower.GetDrawObject() )
209 OSL_ENSURE( !rLower.AlwaysIncludeAsChild(),
210 "<SwAccessibleContext::ChildrenScrolled(..)> - always included child not considered!" );
211 ::rtl::Reference< ::accessibility::AccessibleShape > xAccImpl =
212 GetMap()->GetContextImpl( rLower.GetDrawObject(),
213 this );
214 if( xAccImpl.is() )
216 switch( eAction )
218 case Action::SCROLLED:
219 case Action::SCROLLED_WITHIN:
220 xAccImpl->ViewForwarderChanged();
221 break;
222 case Action::SCROLLED_IN:
223 ScrolledInShape( xAccImpl.get() );
224 break;
225 case Action::SCROLLED_OUT:
227 xAccImpl->ViewForwarderChanged();
228 // this DisposeShape call was removed by
229 // IAccessibility2 implementation
230 // without giving any reason why
231 DisposeShape( rLower.GetDrawObject(),
232 xAccImpl.get() );
234 break;
235 // coverity[dead_error_begin] - following conditions exist to avoid compiler warning
236 case Action::NONE:
237 break;
241 else if ( rLower.GetWindow() )
243 // nothing to do - as such children are always included as children.
244 OSL_ENSURE( rLower.AlwaysIncludeAsChild(),
245 "<SwAccessibleContext::ChildrenScrolled(..)> - not always included child not considered!" );
249 else if ( rLower.GetSwFrame() &&
250 ( !bVisibleChildrenOnly ||
251 aBox.Overlaps( rOldVisArea ) ||
252 aBox.Overlaps( rNewVisArea ) ) )
254 // There are no unaccessible SdrObjects that need to be notified
255 ChildrenScrolled( rLower.GetSwFrame(), rOldVisArea );
257 ++aIter;
261 void SwAccessibleContext::Scrolled( const SwRect& rOldVisArea )
263 SetVisArea( GetMap()->GetVisArea() );
265 ChildrenScrolled( GetFrame(), rOldVisArea );
267 bool bIsOldShowingState;
268 bool bIsNewShowingState = IsShowing( *(GetMap()) );
270 std::scoped_lock aGuard( m_Mutex );
271 bIsOldShowingState = m_isShowingState;
272 m_isShowingState = bIsNewShowingState;
275 if( bIsOldShowingState != bIsNewShowingState )
276 FireStateChangedEvent( AccessibleStateType::SHOWING,
277 bIsNewShowingState );
280 void SwAccessibleContext::ScrolledWithin( const SwRect& rOldVisArea )
282 SetVisArea( GetMap()->GetVisArea() );
284 ChildrenScrolled( GetFrame(), rOldVisArea );
286 FireVisibleDataEvent();
289 void SwAccessibleContext::ScrolledIn()
291 // This accessible should be freshly created, because it
292 // was not visible before. Therefore, its visible area must already
293 // reflect the scrolling.
294 OSL_ENSURE( GetVisArea() == GetMap()->GetVisArea(),
295 "Visible area of child is wrong. Did it exist already?" );
297 // Send child event at parent. That's all we have to do here.
298 const SwFrame* pParent = GetParent();
299 ::rtl::Reference< SwAccessibleContext > xParentImpl(
300 GetMap()->GetContextImpl( pParent, false ) );
301 uno::Reference < XAccessibleContext > xThis( this );
302 if( !xParentImpl.is() )
303 return;
305 SetParent( xParentImpl.get() );
307 AccessibleEventObject aEvent;
308 aEvent.EventId = AccessibleEventId::CHILD;
309 aEvent.NewValue <<= xThis;
310 aEvent.IndexHint = -1;
312 xParentImpl->FireAccessibleEvent( aEvent );
314 if( HasCursor() )
316 vcl::Window *pWin = GetWindow();
317 if( pWin && pWin->HasFocus() )
319 FireStateChangedEvent( AccessibleStateType::FOCUSED, true );
324 void SwAccessibleContext::ScrolledOut( const SwRect& rOldVisArea )
326 SetVisArea( GetMap()->GetVisArea() );
328 // First of all, update the children. That's required to dispose
329 // all children that are existing only if they are visible. They
330 // are not disposed by the recursive Dispose call that follows later on,
331 // because this call will only dispose children that are in the
332 // new visible area. The children we want to dispose however are in the
333 // old visible area all.
334 ChildrenScrolled( GetFrame(), rOldVisArea );
336 // Broadcast a state changed event for the showing state.
337 // It might be that the child is freshly created just to send
338 // the child event. In this case no listener will exist.
339 FireStateChangedEvent( AccessibleStateType::SHOWING, false );
341 // this Dispose call was removed by IAccessibility2 implementation
342 // without giving any reason why - without it we get stale
343 // entries in SwAccessibleMap::mpFrameMap.
344 Dispose(true);
347 // #i27301# - use new type definition for <_nStates>
348 void SwAccessibleContext::InvalidateChildrenStates( const SwFrame* _pFrame,
349 AccessibleStates _nStates )
351 const SwAccessibleChildSList aVisList( GetVisArea(), *_pFrame, *(GetMap()) );
353 SwAccessibleChildSList::const_iterator aIter( aVisList.begin() );
354 while( aIter != aVisList.end() )
356 const SwAccessibleChild& rLower = *aIter;
357 const SwFrame* pLower = rLower.GetSwFrame();
358 if( pLower )
360 ::rtl::Reference< SwAccessibleContext > xAccImpl;
361 if( rLower.IsAccessible( GetShell()->IsPreview() ) )
362 xAccImpl = GetMap()->GetContextImpl( pLower, false );
363 if( xAccImpl.is() )
364 xAccImpl->InvalidateStates( _nStates );
365 else
366 InvalidateChildrenStates( pLower, _nStates );
368 else if ( rLower.GetDrawObject() )
370 // TODO: SdrObjects
372 else if ( rLower.GetWindow() )
374 // nothing to do ?
377 ++aIter;
381 void SwAccessibleContext::DisposeChildren(const SwFrame *pFrame,
382 bool bRecursive,
383 bool bCanSkipInvisible)
385 const SwAccessibleChildSList aVisList( GetVisArea(), *pFrame, *(GetMap()) );
386 SwAccessibleChildSList::const_iterator aIter( aVisList.begin() );
387 while( aIter != aVisList.end() )
389 const SwAccessibleChild& rLower = *aIter;
390 const SwFrame* pLower = rLower.GetSwFrame();
391 if( pLower )
393 // tdf#117601 dispose the darn thing if it ever was accessible
394 ::rtl::Reference<SwAccessibleContext> xAccImpl = GetMap()->GetContextImpl(pLower, false);
395 if( xAccImpl.is() )
396 xAccImpl->Dispose( bRecursive );
397 else
399 // it's possible that the xAccImpl *does* exist with a
400 // ref-count of 0 and blocked in its dtor in another thread -
401 // this call here could be from SwAccessibleMap dtor so
402 // remove it from any maps now!
403 GetMap()->RemoveContext(pLower);
404 // in this case the context will check with a weak_ptr
405 // that the map is still alive so it's not necessary
406 // to clear its m_pMap here.
407 if (bRecursive)
409 DisposeChildren(pLower, bRecursive, bCanSkipInvisible);
413 else if ( rLower.GetDrawObject() )
415 ::rtl::Reference< ::accessibility::AccessibleShape > xAccImpl(
416 GetMap()->GetContextImpl( rLower.GetDrawObject(),
417 this, false ) );
418 if( xAccImpl.is() )
419 DisposeShape( rLower.GetDrawObject(), xAccImpl.get() );
421 else if ( rLower.GetWindow() )
423 DisposeChild(rLower, false, bCanSkipInvisible);
425 ++aIter;
429 void SwAccessibleContext::InvalidateContent_( bool )
433 void SwAccessibleContext::InvalidateCursorPos_()
437 void SwAccessibleContext::InvalidateFocus_()
441 void SwAccessibleContext::FireAccessibleEvent( AccessibleEventObject& rEvent )
443 if( !GetFrame() )
445 SAL_INFO("sw.a11y", "SwAccessibleContext::FireAccessibleEvent called for already disposed frame?");
446 return;
449 if( !rEvent.Source.is() )
451 uno::Reference < XAccessibleContext > xThis( this );
452 rEvent.Source = xThis;
455 if (m_nClientId)
456 comphelper::AccessibleEventNotifier::addEvent( m_nClientId, rEvent );
459 void SwAccessibleContext::FireVisibleDataEvent()
461 AccessibleEventObject aEvent;
462 aEvent.EventId = AccessibleEventId::VISIBLE_DATA_CHANGED;
464 FireAccessibleEvent( aEvent );
467 void SwAccessibleContext::FireStateChangedEvent( sal_Int64 nState,
468 bool bNewState )
470 AccessibleEventObject aEvent;
472 aEvent.EventId = AccessibleEventId::STATE_CHANGED;
473 if( bNewState )
474 aEvent.NewValue <<= nState;
475 else
476 aEvent.OldValue <<= nState;
478 FireAccessibleEvent( aEvent );
481 void SwAccessibleContext::GetStates( sal_Int64& rStateSet )
483 SolarMutexGuard aGuard;
485 // SHOWING
486 if (m_isShowingState)
487 rStateSet |= AccessibleStateType::SHOWING;
489 // EDITABLE
490 if (m_isEditableState)
491 //Set editable state to graphic and other object when the document is editable
493 rStateSet |= AccessibleStateType::EDITABLE;
494 rStateSet |= AccessibleStateType::RESIZABLE;
495 rStateSet |= AccessibleStateType::MOVEABLE;
497 // ENABLED
498 rStateSet |= AccessibleStateType::ENABLED;
500 // OPAQUE
501 if (m_isOpaqueState)
502 rStateSet |= AccessibleStateType::OPAQUE;
504 // VISIBLE
505 rStateSet |= AccessibleStateType::VISIBLE;
507 if (m_isDefuncState)
508 rStateSet |= AccessibleStateType::DEFUNC;
511 bool SwAccessibleContext::IsEditableState()
513 bool bRet;
515 std::scoped_lock aGuard( m_Mutex );
516 bRet = m_isEditableState;
519 return bRet;
522 bool SwAccessibleContext::IsDisposed() const
524 return !(GetFrame() && GetMap());
527 void SwAccessibleContext::ThrowIfDisposed()
529 if (IsDisposed())
531 throw lang::DisposedException("object is nonfunctional",
532 static_cast<cppu::OWeakObject*>(this));
536 SwAccessibleContext::SwAccessibleContext(std::shared_ptr<SwAccessibleMap> const& pMap,
537 sal_Int16 const nRole,
538 const SwFrame *pF )
539 : SwAccessibleFrame( pMap->GetVisArea(), pF,
540 pMap->GetShell()->IsPreview() )
541 , m_pMap(pMap.get())
542 , m_wMap(pMap)
543 , m_nClientId(0)
544 , m_nRole(nRole)
545 , m_isDisposing( false )
546 , m_isRegisteredAtAccessibleMap( true )
547 , m_isSelectedInDoc(false)
549 InitStates();
552 SwAccessibleContext::~SwAccessibleContext()
554 // must have for 2 reasons: 2. as long as this thread has SolarMutex
555 // another thread cannot destroy the SwAccessibleMap so our temporary
556 // taking a hard ref to SwAccessibleMap won't delay its destruction
557 SolarMutexGuard aGuard;
558 // must check with weak_ptr that m_pMap is still alive
559 std::shared_ptr<SwAccessibleMap> pMap(m_wMap.lock());
560 if (m_isRegisteredAtAccessibleMap && GetFrame() && pMap)
562 pMap->RemoveContext( GetFrame() );
566 uno::Reference< XAccessibleContext > SAL_CALL
567 SwAccessibleContext::getAccessibleContext()
569 uno::Reference < XAccessibleContext > xRet( this );
570 return xRet;
573 sal_Int64 SAL_CALL SwAccessibleContext::getAccessibleChildCount()
575 SolarMutexGuard aGuard;
577 ThrowIfDisposed();
579 return m_isDisposing ? 0 : GetChildCount( *(GetMap()) );
582 uno::Reference< XAccessible> SAL_CALL
583 SwAccessibleContext::getAccessibleChild( sal_Int64 nIndex )
585 SolarMutexGuard aGuard;
587 ThrowIfDisposed();
589 if (nIndex < 0 || nIndex >= getAccessibleChildCount())
590 throw lang::IndexOutOfBoundsException();
592 const SwAccessibleChild aChild( GetChild( *(GetMap()), nIndex ) );
593 if( !aChild.IsValid() )
595 uno::Reference < XAccessibleContext > xThis( this );
596 lang::IndexOutOfBoundsException aExcept(
597 "index out of bounds",
598 xThis );
599 throw aExcept;
602 uno::Reference< XAccessible > xChild;
603 if( aChild.GetSwFrame() )
605 ::rtl::Reference < SwAccessibleContext > xChildImpl(
606 GetMap()->GetContextImpl( aChild.GetSwFrame(), !m_isDisposing ) );
607 if( xChildImpl.is() )
609 xChildImpl->SetParent( this );
610 xChild = xChildImpl.get();
613 else if ( aChild.GetDrawObject() )
615 ::rtl::Reference < ::accessibility::AccessibleShape > xChildImpl(
616 GetMap()->GetContextImpl( aChild.GetDrawObject(),
617 this, !m_isDisposing) );
618 if( xChildImpl.is() )
619 xChild = xChildImpl.get();
621 else if ( aChild.GetWindow() )
623 xChild = aChild.GetWindow()->GetAccessible();
626 return xChild;
629 css::uno::Sequence<uno::Reference<XAccessible>> SAL_CALL
630 SwAccessibleContext::getAccessibleChildren()
632 SolarMutexGuard aGuard;
634 ThrowIfDisposed();
636 std::list< sw::access::SwAccessibleChild > aChildren;
637 GetChildren( *GetMap(), aChildren );
639 std::vector<uno::Reference<XAccessible>> aRet;
640 aRet.reserve(aChildren.size());
641 for (const auto & rSwChild : aChildren)
643 uno::Reference< XAccessible > xChild;
644 if( rSwChild.GetSwFrame() )
646 ::rtl::Reference < SwAccessibleContext > xChildImpl(
647 GetMap()->GetContextImpl( rSwChild.GetSwFrame(), !m_isDisposing ) );
648 if( xChildImpl.is() )
650 xChildImpl->SetParent( this );
651 xChild = xChildImpl.get();
654 else if ( rSwChild.GetDrawObject() )
656 ::rtl::Reference < ::accessibility::AccessibleShape > xChildImpl(
657 GetMap()->GetContextImpl( rSwChild.GetDrawObject(),
658 this, !m_isDisposing) );
659 if( xChildImpl.is() )
660 xChild = xChildImpl.get();
662 else if ( rSwChild.GetWindow() )
664 xChild = rSwChild.GetWindow()->GetAccessible();
666 aRet.push_back(xChild);
668 return comphelper::containerToSequence(aRet);
671 uno::Reference< XAccessible> SwAccessibleContext::getAccessibleParentImpl()
673 SolarMutexGuard aGuard;
675 const SwFrame *pUpper = GetParent();
676 OSL_ENSURE( pUpper != nullptr || m_isDisposing, "no upper found" );
678 uno::Reference< XAccessible > xAcc;
679 if( pUpper )
680 xAcc = GetMap()->GetContext( pUpper, !m_isDisposing );
682 OSL_ENSURE( xAcc.is() || m_isDisposing, "no parent found" );
684 // Remember the parent as weak ref.
686 std::scoped_lock aWeakParentGuard( m_Mutex );
687 m_xWeakParent = xAcc;
690 return xAcc;
693 uno::Reference< XAccessible> SAL_CALL SwAccessibleContext::getAccessibleParent()
695 SolarMutexGuard aGuard;
697 ThrowIfDisposed();
699 return getAccessibleParentImpl();
702 sal_Int64 SAL_CALL SwAccessibleContext::getAccessibleIndexInParent()
704 SolarMutexGuard aGuard;
706 ThrowIfDisposed();
708 const SwFrame *pUpper = GetParent();
709 OSL_ENSURE( pUpper != nullptr || m_isDisposing, "no upper found" );
711 sal_Int64 nIndex = -1;
712 if( pUpper )
714 ::rtl::Reference < SwAccessibleContext > xAccImpl(
715 GetMap()->GetContextImpl(pUpper, !m_isDisposing) );
716 OSL_ENSURE( xAccImpl.is() || m_isDisposing, "no parent found" );
717 if( xAccImpl.is() )
718 nIndex = xAccImpl->GetChildIndex( *(GetMap()), SwAccessibleChild(GetFrame()) );
721 return nIndex;
724 sal_Int16 SAL_CALL SwAccessibleContext::getAccessibleRole()
726 return m_nRole;
729 OUString SAL_CALL SwAccessibleContext::getAccessibleName()
731 return m_sName;
734 uno::Reference< XAccessibleRelationSet> SAL_CALL
735 SwAccessibleContext::getAccessibleRelationSet()
737 // by default there are no relations
738 uno::Reference< XAccessibleRelationSet> xRet( new utl::AccessibleRelationSetHelper() );
739 return xRet;
742 sal_Int64 SAL_CALL SwAccessibleContext::getAccessibleStateSet()
744 SolarMutexGuard aGuard;
746 ThrowIfDisposed();
748 sal_Int64 nStateSet = 0;
750 if (m_isSelectedInDoc)
751 nStateSet |= AccessibleStateType::SELECTED;
753 GetStates( nStateSet );
755 return nStateSet;
758 lang::Locale SAL_CALL SwAccessibleContext::getLocale()
760 SolarMutexGuard aGuard;
762 lang::Locale aLoc( Application::GetSettings().GetLanguageTag().getLocale() );
763 return aLoc;
766 void SAL_CALL SwAccessibleContext::addAccessibleEventListener(
767 const uno::Reference< XAccessibleEventListener >& xListener )
769 if (xListener.is())
771 SolarMutexGuard aGuard;
772 if (!m_nClientId)
773 m_nClientId = comphelper::AccessibleEventNotifier::registerClient( );
774 comphelper::AccessibleEventNotifier::addEventListener( m_nClientId, xListener );
778 void SAL_CALL SwAccessibleContext::removeAccessibleEventListener(
779 const uno::Reference< XAccessibleEventListener >& xListener )
781 if (!(xListener.is() && m_nClientId))
782 return;
784 SolarMutexGuard aGuard;
785 sal_Int32 nListenerCount = comphelper::AccessibleEventNotifier::removeEventListener( m_nClientId, xListener );
786 if ( !nListenerCount )
788 // no listeners anymore
789 // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client),
790 // and at least to us not firing any events anymore, in case somebody calls
791 // NotifyAccessibleEvent, again
792 comphelper::AccessibleEventNotifier::revokeClient( m_nClientId );
793 m_nClientId = 0;
797 static bool lcl_PointInRectangle(const awt::Point & aPoint,
798 const awt::Rectangle & aRect)
800 tools::Long nDiffX = aPoint.X - aRect.X;
801 tools::Long nDiffY = aPoint.Y - aRect.Y;
803 return
804 nDiffX >= 0 && nDiffX < aRect.Width && nDiffY >= 0 &&
805 nDiffY < aRect.Height;
809 sal_Bool SAL_CALL SwAccessibleContext::containsPoint(
810 const awt::Point& aPoint )
812 awt::Rectangle aPixBounds = getBoundsImpl(true);
813 aPixBounds.X = 0;
814 aPixBounds.Y = 0;
816 return lcl_PointInRectangle(aPoint, aPixBounds);
819 uno::Reference< XAccessible > SAL_CALL SwAccessibleContext::getAccessibleAtPoint(
820 const awt::Point& aPoint )
822 SolarMutexGuard aGuard;
824 ThrowIfDisposed();
826 uno::Reference< XAccessible > xAcc;
828 vcl::Window *pWin = GetWindow();
829 if (!pWin)
831 throw uno::RuntimeException("no Window", static_cast<cppu::OWeakObject*>(this));
834 Point aPixPoint( aPoint.X, aPoint.Y ); // px rel to parent
835 if( !GetFrame()->IsRootFrame() )
837 SwRect aLogBounds( GetBounds( *(GetMap()), GetFrame() ) ); // twip rel to doc root
838 Point aPixPos( GetMap()->CoreToPixel( aLogBounds ).TopLeft() );
839 aPixPoint.setX(aPixPoint.getX() + aPixPos.getX());
840 aPixPoint.setY(aPixPoint.getY() + aPixPos.getY());
843 const SwAccessibleChild aChild( GetChildAtPixel( aPixPoint, *(GetMap()) ) );
844 if( aChild.GetSwFrame() )
846 xAcc = GetMap()->GetContext( aChild.GetSwFrame() );
848 else if( aChild.GetDrawObject() )
850 xAcc = GetMap()->GetContext( aChild.GetDrawObject(), this );
852 else if ( aChild.GetWindow() )
854 xAcc = aChild.GetWindow()->GetAccessible();
857 return xAcc;
861 Get bounding box.
863 There are two modes.
865 - relative
867 Return bounding box relative to parent if parent is no root
868 frame. Otherwise return the absolute bounding box.
870 - absolute
872 Return the absolute bounding box.
874 @param bRelative
875 true: Use relative mode.
876 false: Use absolute mode.
878 awt::Rectangle SwAccessibleContext::getBoundsImpl(bool bRelative)
880 SolarMutexGuard aGuard;
882 ThrowIfDisposed();
884 const SwFrame *pParent = GetParent();
885 OSL_ENSURE( pParent, "no Parent found" );
886 vcl::Window *pWin = GetWindow();
888 if (!pParent)
890 throw uno::RuntimeException("no Parent", static_cast<cppu::OWeakObject*>(this));
892 if (!pWin)
894 throw uno::RuntimeException("no Window", static_cast<cppu::OWeakObject*>(this));
897 SwRect aLogBounds( GetBounds( *(GetMap()), GetFrame() ) ); // twip relative to document root
898 tools::Rectangle aPixBounds( 0, 0, 0, 0 );
899 if( GetFrame()->IsPageFrame() &&
900 static_cast < const SwPageFrame * >( GetFrame() )->IsEmptyPage() )
902 OSL_ENSURE( GetShell()->IsPreview(), "empty page accessible?" );
903 if( GetShell()->IsPreview() )
905 // adjust method call <GetMap()->GetPreviewPageSize()>
906 sal_uInt16 nPageNum =
907 static_cast < const SwPageFrame * >( GetFrame() )->GetPhyPageNum();
908 aLogBounds.SSize( GetMap()->GetPreviewPageSize( nPageNum ) );
911 if( !aLogBounds.IsEmpty() )
913 aPixBounds = GetMap()->CoreToPixel( aLogBounds );
914 if( !pParent->IsRootFrame() && bRelative)
916 SwRect aParentLogBounds( GetBounds( *(GetMap()), pParent ) ); // twip rel to doc root
917 Point aParentPixPos( GetMap()->CoreToPixel( aParentLogBounds ).TopLeft() );
918 aPixBounds.Move( -aParentPixPos.getX(), -aParentPixPos.getY() );
922 awt::Rectangle aBox( aPixBounds.Left(), aPixBounds.Top(),
923 aPixBounds.GetWidth(), aPixBounds.GetHeight() );
925 return aBox;
928 awt::Rectangle SAL_CALL SwAccessibleContext::getBounds()
930 return getBoundsImpl(true);
933 awt::Point SAL_CALL SwAccessibleContext::getLocation()
935 awt::Rectangle aRect = getBoundsImpl(true);
936 awt::Point aPoint(aRect.X, aRect.Y);
938 return aPoint;
941 awt::Point SAL_CALL SwAccessibleContext::getLocationOnScreen()
943 awt::Rectangle aRect = getBoundsImpl(false);
945 Point aPixPos(aRect.X, aRect.Y);
947 vcl::Window *pWin = GetWindow();
948 if (!pWin)
950 throw uno::RuntimeException("no Window", static_cast<cppu::OWeakObject*>(this));
953 aPixPos = pWin->OutputToAbsoluteScreenPixel(aPixPos);
954 awt::Point aPoint(aPixPos.getX(), aPixPos.getY());
956 return aPoint;
959 awt::Size SAL_CALL SwAccessibleContext::getSize()
961 awt::Rectangle aRect = getBoundsImpl(false);
962 awt::Size aSize( aRect.Width, aRect.Height );
964 return aSize;
967 void SAL_CALL SwAccessibleContext::grabFocus()
969 SolarMutexGuard aGuard;
971 ThrowIfDisposed();
973 if( GetFrame()->IsFlyFrame() )
975 const SdrObject *pObj =
976 static_cast < const SwFlyFrame * >( GetFrame() )->GetVirtDrawObj();
977 if( pObj )
978 Select( const_cast < SdrObject * >( pObj ), false );
980 else
982 const SwContentFrame *pCFrame = nullptr;
983 if( GetFrame()->IsContentFrame() )
984 pCFrame = static_cast< const SwContentFrame * >( GetFrame() );
985 else if( GetFrame()->IsLayoutFrame() )
986 pCFrame = static_cast< const SwLayoutFrame * >( GetFrame() )->ContainsContent();
988 if( pCFrame && pCFrame->IsTextFrame() )
990 const SwTextFrame *pTextFrame = static_cast< const SwTextFrame * >( pCFrame );
991 const SwTextNode *pTextNd = pTextFrame->GetTextNodeFirst();
992 assert(pTextNd); // can it actually be null? probably not=>simplify
993 if( pTextNd )
995 // create pam for selection
996 SwPosition const aStartPos(pTextFrame->MapViewToModelPos(pTextFrame->GetOffset()));
997 SwPaM aPaM( aStartPos );
999 // set PaM at cursor shell
1000 Select( aPaM );
1006 sal_Int32 SAL_CALL SwAccessibleContext::getForeground()
1008 return sal_Int32(COL_BLACK);
1011 sal_Int32 SAL_CALL SwAccessibleContext::getBackground()
1013 return sal_Int32(COL_WHITE);
1016 sal_Bool SAL_CALL SwAccessibleContext::supportsService (const OUString& ServiceName)
1018 return cppu::supportsService(this, ServiceName);
1021 void SwAccessibleContext::DisposeShape( const SdrObject *pObj,
1022 ::accessibility::AccessibleShape *pAccImpl )
1024 ::rtl::Reference< ::accessibility::AccessibleShape > xAccImpl( pAccImpl );
1025 if( !xAccImpl.is() )
1026 xAccImpl = GetMap()->GetContextImpl( pObj, this );
1028 AccessibleEventObject aEvent;
1029 aEvent.EventId = AccessibleEventId::CHILD;
1030 uno::Reference< XAccessible > xAcc( xAccImpl );
1031 aEvent.OldValue <<= xAcc;
1032 aEvent.IndexHint = -1;
1033 FireAccessibleEvent( aEvent );
1035 GetMap()->RemoveContext( pObj );
1036 xAccImpl->dispose();
1039 void SwAccessibleContext::ScrolledInShape( ::accessibility::AccessibleShape *pAccImpl )
1041 if(nullptr == pAccImpl)
1043 return ;
1045 AccessibleEventObject aEvent;
1046 aEvent.EventId = AccessibleEventId::CHILD;
1047 uno::Reference< XAccessible > xAcc( pAccImpl );
1048 aEvent.NewValue <<= xAcc;
1049 aEvent.IndexHint = -1;
1050 FireAccessibleEvent( aEvent );
1052 if( !pAccImpl->GetState( AccessibleStateType::FOCUSED ) )
1053 return;
1055 vcl::Window *pWin = GetWindow();
1056 if( pWin && pWin->HasFocus() )
1058 AccessibleEventObject aStateChangedEvent;
1059 aStateChangedEvent.EventId = AccessibleEventId::STATE_CHANGED;
1060 aStateChangedEvent.NewValue <<= AccessibleStateType::FOCUSED;
1061 aStateChangedEvent.Source = xAcc;
1063 FireAccessibleEvent( aStateChangedEvent );
1067 void SwAccessibleContext::Dispose(bool bRecursive, bool bCanSkipInvisible)
1069 SolarMutexGuard aGuard;
1071 OSL_ENSURE( GetFrame() && GetMap(), "already disposed" );
1072 OSL_ENSURE( GetMap()->GetVisArea() == GetVisArea(),
1073 "invalid visible area for dispose" );
1075 m_isDisposing = true;
1077 // dispose children
1078 if( bRecursive )
1079 DisposeChildren(GetFrame(), bRecursive, bCanSkipInvisible);
1081 // get parent
1082 uno::Reference< XAccessible > xParent( GetWeakParent() );
1083 uno::Reference < XAccessibleContext > xThis( this );
1085 // send child event at parent
1086 if( xParent.is() )
1088 SwAccessibleContext *pAcc = static_cast<SwAccessibleContext *>(xParent.get());
1090 AccessibleEventObject aEvent;
1091 aEvent.EventId = AccessibleEventId::CHILD;
1092 aEvent.OldValue <<= xThis;
1093 aEvent.IndexHint = -1;
1094 pAcc->FireAccessibleEvent( aEvent );
1097 // set defunc state (it's not required to broadcast a state changed
1098 // event if the object is disposed afterwards)
1100 std::scoped_lock aDefuncStateGuard( m_Mutex );
1101 m_isDefuncState = true;
1104 // broadcast dispose event
1105 if (m_nClientId)
1107 comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( m_nClientId, *this );
1108 m_nClientId = 0;
1111 RemoveFrameFromAccessibleMap();
1112 ClearFrame();
1113 m_pMap = nullptr;
1114 m_wMap.reset();
1116 m_isDisposing = false;
1119 void SwAccessibleContext::DisposeChild( const SwAccessibleChild& rChildFrameOrObj,
1120 bool bRecursive, bool bCanSkipInvisible )
1122 SolarMutexGuard aGuard;
1124 if ( !bCanSkipInvisible ||
1125 rChildFrameOrObj.AlwaysIncludeAsChild() ||
1126 IsShowing( *(GetMap()), rChildFrameOrObj ) ||
1127 !SwAccessibleChild( GetFrame() ).IsVisibleChildrenOnly() )
1129 // If the object could have existed before, then there is nothing to do,
1130 // because no wrapper exists now and therefore no one is interested to
1131 // get notified of the movement.
1132 if( rChildFrameOrObj.GetSwFrame() )
1134 ::rtl::Reference< SwAccessibleContext > xAccImpl =
1135 GetMap()->GetContextImpl( rChildFrameOrObj.GetSwFrame(), false );
1136 if (xAccImpl)
1137 xAccImpl->Dispose( bRecursive );
1139 else if ( rChildFrameOrObj.GetDrawObject() )
1141 ::rtl::Reference< ::accessibility::AccessibleShape > xAccImpl =
1142 GetMap()->GetContextImpl( rChildFrameOrObj.GetDrawObject(),
1143 this, false );
1144 if (xAccImpl)
1145 DisposeShape( rChildFrameOrObj.GetDrawObject(),
1146 xAccImpl.get() );
1148 else if ( rChildFrameOrObj.GetWindow() )
1150 AccessibleEventObject aEvent;
1151 aEvent.EventId = AccessibleEventId::CHILD;
1152 uno::Reference< XAccessible > xAcc =
1153 rChildFrameOrObj.GetWindow()->GetAccessible();
1154 aEvent.OldValue <<= xAcc;
1155 aEvent.IndexHint = -1;
1156 FireAccessibleEvent( aEvent );
1159 else if( bRecursive && rChildFrameOrObj.GetSwFrame() )
1160 DisposeChildren(rChildFrameOrObj.GetSwFrame(), bRecursive, bCanSkipInvisible);
1163 void SwAccessibleContext::InvalidatePosOrSize( const SwRect& )
1165 SolarMutexGuard aGuard;
1167 OSL_ENSURE( GetFrame() && !GetFrame()->getFrameArea().IsEmpty(), "context should have a size" );
1169 bool bIsOldShowingState;
1170 bool bIsNewShowingState = IsShowing( *(GetMap()) );
1172 std::scoped_lock aShowingStateGuard( m_Mutex );
1173 bIsOldShowingState = m_isShowingState;
1174 m_isShowingState = bIsNewShowingState;
1177 if( bIsOldShowingState != bIsNewShowingState )
1179 FireStateChangedEvent( AccessibleStateType::SHOWING,
1180 bIsNewShowingState );
1182 else if( bIsNewShowingState )
1184 // The frame stays visible -> broadcast event
1185 FireVisibleDataEvent();
1188 // note: InvalidatePosOrSize must call InvalidateContent_ so that
1189 // SwAccessibleParagraph updates its portions, or dispose it
1190 // (see accmap.cxx: INVALID_CONTENT is contained in POS_CHANGED)
1191 if( !bIsNewShowingState &&
1192 SwAccessibleChild( GetParent() ).IsVisibleChildrenOnly() )
1194 // this Dispose call was removed by IAccessibility2 implementation
1195 // without giving any reason why - without it we get stale
1196 // entries in SwAccessibleMap::mpFrameMap.
1197 Dispose(true);
1199 else
1201 InvalidateContent_( true );
1205 void SwAccessibleContext::InvalidateChildPosOrSize(
1206 const SwAccessibleChild& rChildFrameOrObj,
1207 const SwRect& rOldFrame )
1209 SolarMutexGuard aGuard;
1211 // this happens during layout, e.g. when a page is deleted and next page's
1212 // header/footer moves backward such an event is generated
1213 SAL_INFO_IF(rChildFrameOrObj.GetSwFrame() &&
1214 rChildFrameOrObj.GetSwFrame()->getFrameArea().IsEmpty(),
1215 "sw.a11y", "child context should have a size");
1217 if ( rChildFrameOrObj.AlwaysIncludeAsChild() )
1219 // nothing to do;
1220 return;
1223 const bool bVisibleChildrenOnly = SwAccessibleChild( GetFrame() ).IsVisibleChildrenOnly();
1224 const bool bNew = rOldFrame.IsEmpty() ||
1225 ( rOldFrame.Left() == 0 && rOldFrame.Top() == 0 );
1226 if( IsShowing( *(GetMap()), rChildFrameOrObj ) )
1228 // If the object could have existed before, then there is nothing to do,
1229 // because no wrapper exists now and therefore no one is interested to
1230 // get notified of the movement.
1231 if( bNew || (bVisibleChildrenOnly && !IsShowing( rOldFrame )) )
1233 if( rChildFrameOrObj.GetSwFrame() )
1235 // The frame becomes visible. A child event must be send.
1236 ::rtl::Reference< SwAccessibleContext > xAccImpl =
1237 GetMap()->GetContextImpl( rChildFrameOrObj.GetSwFrame() );
1238 xAccImpl->ScrolledIn();
1240 else if ( rChildFrameOrObj.GetDrawObject() )
1242 ::rtl::Reference< ::accessibility::AccessibleShape > xAccImpl =
1243 GetMap()->GetContextImpl( rChildFrameOrObj.GetDrawObject(),
1244 this );
1245 // #i37790#
1246 if ( xAccImpl.is() )
1248 ScrolledInShape( xAccImpl.get() );
1250 else
1252 OSL_FAIL( "<SwAccessibleContext::InvalidateChildPosOrSize(..)> - no accessible shape found." );
1255 else if ( rChildFrameOrObj.GetWindow() )
1257 AccessibleEventObject aEvent;
1258 aEvent.EventId = AccessibleEventId::CHILD;
1259 aEvent.NewValue <<= rChildFrameOrObj.GetWindow()->GetAccessible();
1260 FireAccessibleEvent( aEvent );
1264 else
1266 // If the frame was visible before, then a child event for the parent
1267 // needs to be send. However, there is no wrapper existing, and so
1268 // no notifications for grandchildren are required. If the are
1269 // grandgrandchildren, they would be notified by the layout.
1270 if( bVisibleChildrenOnly &&
1271 !bNew && IsShowing( rOldFrame ) )
1273 if( rChildFrameOrObj.GetSwFrame() )
1275 ::rtl::Reference< SwAccessibleContext > xAccImpl =
1276 GetMap()->GetContextImpl( rChildFrameOrObj.GetSwFrame() );
1277 xAccImpl->SetParent( this );
1278 xAccImpl->Dispose( true );
1280 else if ( rChildFrameOrObj.GetDrawObject() )
1282 ::rtl::Reference< ::accessibility::AccessibleShape > xAccImpl =
1283 GetMap()->GetContextImpl( rChildFrameOrObj.GetDrawObject(),
1284 this );
1285 DisposeShape( rChildFrameOrObj.GetDrawObject(),
1286 xAccImpl.get() );
1288 else if ( rChildFrameOrObj.GetWindow() )
1290 OSL_FAIL( "<SwAccessibleContext::InvalidateChildPosOrSize(..)> - not expected to handle dispose of child of type <vcl::Window>." );
1296 void SwAccessibleContext::InvalidateContent()
1298 SolarMutexGuard aGuard;
1300 InvalidateContent_( false );
1303 void SwAccessibleContext::InvalidateCursorPos()
1305 SolarMutexGuard aGuard;
1307 InvalidateCursorPos_();
1310 void SwAccessibleContext::InvalidateFocus()
1312 SolarMutexGuard aGuard;
1314 InvalidateFocus_();
1317 // #i27301# - use new type definition for <_nStates>
1318 void SwAccessibleContext::InvalidateStates( AccessibleStates _nStates )
1320 if( !GetMap() )
1321 return;
1323 SwViewShell *pVSh = GetMap()->GetShell();
1324 if( pVSh )
1326 if( _nStates & AccessibleStates::EDITABLE )
1328 bool bIsOldEditableState;
1329 bool bIsNewEditableState = IsEditable( pVSh );
1331 std::scoped_lock aGuard( m_Mutex );
1332 bIsOldEditableState = m_isEditableState;
1333 m_isEditableState = bIsNewEditableState;
1336 if( bIsOldEditableState != bIsNewEditableState )
1337 FireStateChangedEvent( AccessibleStateType::EDITABLE,
1338 bIsNewEditableState );
1340 if( _nStates & AccessibleStates::OPAQUE )
1342 bool bIsOldOpaqueState;
1343 bool bIsNewOpaqueState = IsOpaque( pVSh );
1345 std::scoped_lock aGuard( m_Mutex );
1346 bIsOldOpaqueState = m_isOpaqueState;
1347 m_isOpaqueState = bIsNewOpaqueState;
1350 if( bIsOldOpaqueState != bIsNewOpaqueState )
1351 FireStateChangedEvent( AccessibleStateType::OPAQUE,
1352 bIsNewOpaqueState );
1356 InvalidateChildrenStates( GetFrame(), _nStates );
1359 void SwAccessibleContext::InvalidateRelation( sal_uInt16 nType )
1361 AccessibleEventObject aEvent;
1362 aEvent.EventId = nType;
1364 FireAccessibleEvent( aEvent );
1367 /** #i27301# - text selection has changed */
1368 void SwAccessibleContext::InvalidateTextSelection()
1370 AccessibleEventObject aEvent;
1371 aEvent.EventId = AccessibleEventId::TEXT_SELECTION_CHANGED;
1373 FireAccessibleEvent( aEvent );
1376 /** #i88069# - attributes has changed */
1377 void SwAccessibleContext::InvalidateAttr()
1379 AccessibleEventObject aEvent;
1380 aEvent.EventId = AccessibleEventId::TEXT_ATTRIBUTE_CHANGED;
1382 FireAccessibleEvent( aEvent );
1385 bool SwAccessibleContext::HasCursor()
1387 return false;
1390 bool SwAccessibleContext::Select( SwPaM *pPaM, SdrObject *pObj,
1391 bool bAdd )
1393 SwCursorShell* pCursorShell = GetCursorShell();
1394 if( !pCursorShell )
1395 return false;
1397 SwFEShell* pFEShell = dynamic_cast<SwFEShell*>(pCursorShell);
1398 // Get rid of activated OLE object
1399 if( pFEShell )
1400 pFEShell->FinishOLEObj();
1402 SwWrtShell* pWrtShell = dynamic_cast<SwWrtShell*>(pCursorShell);
1404 bool bRet = false;
1405 if( pObj )
1407 if( pFEShell )
1409 sal_uInt8 nFlags = bAdd ? SW_ADD_SELECT : 0;
1410 pFEShell->SelectObj( Point(), nFlags, pObj );
1411 bRet = true;
1414 else if( pPaM )
1416 // Get rid of frame selection. If there is one, make text cursor
1417 // visible again.
1418 bool bCallShowCursor = false;
1419 if( pFEShell && (pFEShell->IsFrameSelected() ||
1420 pFEShell->IsObjSelected()) )
1422 Point aPt( LONG_MIN, LONG_MIN );
1423 pFEShell->SelectObj( aPt );
1424 bCallShowCursor = true;
1426 pCursorShell->KillPams();
1427 if( pWrtShell && pPaM->HasMark() )
1428 // We have to do this or SwWrtShell can't figure out that it needs
1429 // to kill the selection later, when the user moves the cursor.
1430 pWrtShell->SttSelect();
1431 pCursorShell->SetSelection( *pPaM );
1432 if( pPaM->HasMark() && *pPaM->GetPoint() == *pPaM->GetMark())
1433 // Setting a "Selection" that starts and ends at the same spot
1434 // should remove the selection rather than create an empty one, so
1435 // that we get defined behavior if accessibility sets the cursor
1436 // later.
1437 pCursorShell->ClearMark();
1438 if( bCallShowCursor )
1439 pCursorShell->ShowCursor();
1440 bRet = true;
1443 return bRet;
1446 OUString SwAccessibleContext::GetResource(TranslateId pResId,
1447 const OUString *pArg1,
1448 const OUString *pArg2)
1450 OUString sStr = SwResId(pResId);
1452 if( pArg1 )
1454 sStr = sStr.replaceFirst( "$(ARG1)", *pArg1 );
1456 if( pArg2 )
1458 sStr = sStr.replaceFirst( "$(ARG2)", *pArg2 );
1461 return sStr;
1464 void SwAccessibleContext::RemoveFrameFromAccessibleMap()
1466 assert(m_refCount > 0); // must be alive to do this without using m_wMap
1467 if (m_isRegisteredAtAccessibleMap && GetFrame() && GetMap())
1468 GetMap()->RemoveContext( GetFrame() );
1471 bool SwAccessibleContext::HasAdditionalAccessibleChildren()
1473 bool bRet( false );
1475 if ( GetFrame()->IsTextFrame() )
1477 SwPostItMgr* pPostItMgr = GetMap()->GetShell()->GetPostItMgr();
1478 if ( pPostItMgr && pPostItMgr->HasNotes() && pPostItMgr->ShowNotes() )
1480 bRet = pPostItMgr->HasFrameConnectedSidebarWins( *(GetFrame()) );
1484 return bRet;
1487 /** #i88070# - get additional accessible child by index */
1488 vcl::Window* SwAccessibleContext::GetAdditionalAccessibleChild( const sal_Int32 nIndex )
1490 vcl::Window* pAdditionalAccessibleChild( nullptr );
1492 if ( GetFrame()->IsTextFrame() )
1494 SwPostItMgr* pPostItMgr = GetMap()->GetShell()->GetPostItMgr();
1495 if ( pPostItMgr && pPostItMgr->HasNotes() && pPostItMgr->ShowNotes() )
1497 pAdditionalAccessibleChild =
1498 pPostItMgr->GetSidebarWinForFrameByIndex( *(GetFrame()), nIndex );
1502 return pAdditionalAccessibleChild;
1505 /** #i88070# - get all additional accessible children */
1506 void SwAccessibleContext::GetAdditionalAccessibleChildren( std::vector< vcl::Window* >* pChildren )
1508 if ( GetFrame()->IsTextFrame() )
1510 SwPostItMgr* pPostItMgr = GetMap()->GetShell()->GetPostItMgr();
1511 if ( pPostItMgr && pPostItMgr->HasNotes() && pPostItMgr->ShowNotes() )
1513 pPostItMgr->GetAllSidebarWinForFrame( *(GetFrame()), pChildren );
1518 bool SwAccessibleContext::SetSelectedState(bool const bSelected)
1520 if (m_isSelectedInDoc != bSelected)
1522 m_isSelectedInDoc = bSelected;
1523 FireStateChangedEvent( AccessibleStateType::SELECTED, bSelected );
1524 return true;
1526 return false;
1529 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */