diff options
Diffstat (limited to 'sw/source/core/access/acccontext.cxx')
-rw-r--r-- | sw/source/core/access/acccontext.cxx | 1526 |
1 files changed, 1526 insertions, 0 deletions
diff --git a/sw/source/core/access/acccontext.cxx b/sw/source/core/access/acccontext.cxx new file mode 100644 index 000000000..3b9f0f1e6 --- /dev/null +++ b/sw/source/core/access/acccontext.cxx @@ -0,0 +1,1526 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <vcl/window.hxx> +#include <swtypes.hxx> + +#include <com/sun/star/accessibility/XAccessible.hpp> +#include <com/sun/star/accessibility/XAccessibleStateSet.hpp> +#include <com/sun/star/accessibility/AccessibleStateType.hpp> +#include <com/sun/star/accessibility/AccessibleEventId.hpp> +#include <com/sun/star/lang/IndexOutOfBoundsException.hpp> +#include <osl/mutex.hxx> +#include <sal/log.hxx> +#include <vcl/svapp.hxx> +#include <vcl/settings.hxx> +#include <i18nlangtag/languagetag.hxx> +#include <unotools/accessiblestatesethelper.hxx> +#include <unotools/accessiblerelationsethelper.hxx> +#include <viewsh.hxx> +#include <crsrsh.hxx> +#include <fesh.hxx> +#include <wrtsh.hxx> +#include <txtfrm.hxx> +#include <ndtxt.hxx> +#include <pagefrm.hxx> +#include <flyfrm.hxx> +#include <dflyobj.hxx> +#include <pam.hxx> +#include <accmap.hxx> +#include "accfrmobjslist.hxx" +#include "acccontext.hxx" +#include <svx/AccessibleShape.hxx> +#include <comphelper/accessibleeventnotifier.hxx> +#include <cppuhelper/supportsservice.hxx> +#include <PostItMgr.hxx> + +using namespace sw::access; +using namespace ::com::sun::star; +using namespace ::com::sun::star::accessibility; + +void SwAccessibleContext::InitStates() +{ + m_isShowingState = GetMap() && IsShowing( *(GetMap()) ); + + SwViewShell *pVSh = GetMap()->GetShell(); + m_isEditableState = pVSh && IsEditable( pVSh ); + m_isOpaqueState = pVSh && IsOpaque( pVSh ); + m_isDefuncState = false; +} + +void SwAccessibleContext::SetParent( SwAccessibleContext *pParent ) +{ + osl::MutexGuard aGuard( m_Mutex ); + + uno::Reference < XAccessible > xParent( pParent ); + m_xWeakParent = xParent; +} + +uno::Reference< XAccessible > SwAccessibleContext::GetWeakParent() const +{ + osl::MutexGuard aGuard( m_Mutex ); + + uno::Reference< XAccessible > xParent( m_xWeakParent ); + return xParent; +} + +vcl::Window *SwAccessibleContext::GetWindow() +{ + vcl::Window *pWin = nullptr; + + if( GetMap() ) + { + const SwViewShell *pVSh = GetMap()->GetShell(); + OSL_ENSURE( pVSh, "no view shell" ); + if( pVSh ) + pWin = pVSh->GetWin(); + + OSL_ENSURE( pWin, "no window" ); + } + + return pWin; +} + +// get SwViewShell from accessibility map, and cast to cursor shell +SwCursorShell* SwAccessibleContext::GetCursorShell() +{ + SwViewShell* pViewShell = GetMap() ? GetMap()->GetShell() : nullptr; + OSL_ENSURE( pViewShell, "no view shell" ); + return dynamic_cast<SwCursorShell*>( pViewShell); +} + +const SwCursorShell* SwAccessibleContext::GetCursorShell() const +{ + // just like non-const GetCursorShell + const SwViewShell* pViewShell = GetMap() ? GetMap()->GetShell() : nullptr; + OSL_ENSURE( pViewShell, "no view shell" ); + return dynamic_cast<const SwCursorShell*>( pViewShell); +} + +namespace { + +enum class Action { NONE, SCROLLED, SCROLLED_WITHIN, + SCROLLED_IN, SCROLLED_OUT }; + +} + +void SwAccessibleContext::ChildrenScrolled( const SwFrame *pFrame, + const SwRect& rOldVisArea ) +{ + const SwRect& rNewVisArea = GetVisArea(); + const bool bVisibleChildrenOnly = SwAccessibleChild( pFrame ).IsVisibleChildrenOnly(); + + const SwAccessibleChildSList aList( *pFrame, *(GetMap()) ); + SwAccessibleChildSList::const_iterator aIter( aList.begin() ); + while( aIter != aList.end() ) + { + const SwAccessibleChild& rLower = *aIter; + const SwRect aBox( rLower.GetBox( *(GetMap()) ) ); + if( rLower.IsAccessible( GetShell()->IsPreview() ) ) + { + Action eAction = Action::NONE; + if( aBox.IsOver( rNewVisArea ) ) + { + if( aBox.IsOver( rOldVisArea ) ) + { + eAction = Action::SCROLLED_WITHIN; + } + else + { + if ( bVisibleChildrenOnly && + !rLower.AlwaysIncludeAsChild() ) + { + eAction = Action::SCROLLED_IN; + } + else + { + eAction = Action::SCROLLED; + } + } + } + else if( aBox.IsOver( rOldVisArea ) ) + { + if ( bVisibleChildrenOnly && + !rLower.AlwaysIncludeAsChild() ) + { + eAction = Action::SCROLLED_OUT; + } + else + { + eAction = Action::SCROLLED; + } + } + else if( !bVisibleChildrenOnly || + rLower.AlwaysIncludeAsChild() ) + { + // This wouldn't be required if the SwAccessibleFrame, + // wouldn't know about the visible area. + eAction = Action::SCROLLED; + } + if( Action::NONE != eAction ) + { + if ( rLower.GetSwFrame() ) + { + OSL_ENSURE( !rLower.AlwaysIncludeAsChild(), + "<SwAccessibleContext::ChildrenScrolled(..)> - always included child not considered!" ); + const SwFrame* pLower( rLower.GetSwFrame() ); + ::rtl::Reference< SwAccessibleContext > xAccImpl = + GetMap()->GetContextImpl( pLower ); + if( xAccImpl.is() ) + { + switch( eAction ) + { + case Action::SCROLLED: + xAccImpl->Scrolled( rOldVisArea ); + break; + case Action::SCROLLED_WITHIN: + xAccImpl->ScrolledWithin( rOldVisArea ); + break; + case Action::SCROLLED_IN: + xAccImpl->ScrolledIn(); + break; + case Action::SCROLLED_OUT: + xAccImpl->ScrolledOut( rOldVisArea ); + break; + case Action::NONE: + break; + } + } + else + { + ChildrenScrolled( pLower, rOldVisArea ); + } + } + else if ( rLower.GetDrawObject() ) + { + OSL_ENSURE( !rLower.AlwaysIncludeAsChild(), + "<SwAccessibleContext::ChildrenScrolled(..)> - always included child not considered!" ); + ::rtl::Reference< ::accessibility::AccessibleShape > xAccImpl = + GetMap()->GetContextImpl( rLower.GetDrawObject(), + this ); + if( xAccImpl.is() ) + { + switch( eAction ) + { + case Action::SCROLLED: + case Action::SCROLLED_WITHIN: + xAccImpl->ViewForwarderChanged(); + break; + case Action::SCROLLED_IN: + ScrolledInShape( xAccImpl.get() ); + break; + case Action::SCROLLED_OUT: + { + xAccImpl->ViewForwarderChanged(); + // this DisposeShape call was removed by + // IAccessibility2 implementation + // without giving any reason why + DisposeShape( rLower.GetDrawObject(), + xAccImpl.get() ); + } + break; + // coverity[dead_error_begin] - following conditions exist to avoid compiler warning + case Action::NONE: + break; + } + } + } + else if ( rLower.GetWindow() ) + { + // nothing to do - as such children are always included as children. + OSL_ENSURE( rLower.AlwaysIncludeAsChild(), + "<SwAccessibleContext::ChildrenScrolled(..)> - not always included child not considered!" ); + } + } + } + else if ( rLower.GetSwFrame() && + ( !bVisibleChildrenOnly || + aBox.IsOver( rOldVisArea ) || + aBox.IsOver( rNewVisArea ) ) ) + { + // There are no unaccessible SdrObjects that need to be notified + ChildrenScrolled( rLower.GetSwFrame(), rOldVisArea ); + } + ++aIter; + } +} + +void SwAccessibleContext::Scrolled( const SwRect& rOldVisArea ) +{ + SetVisArea( GetMap()->GetVisArea() ); + + ChildrenScrolled( GetFrame(), rOldVisArea ); + + bool bIsOldShowingState; + bool bIsNewShowingState = IsShowing( *(GetMap()) ); + { + osl::MutexGuard aGuard( m_Mutex ); + bIsOldShowingState = m_isShowingState; + m_isShowingState = bIsNewShowingState; + } + + if( bIsOldShowingState != bIsNewShowingState ) + FireStateChangedEvent( AccessibleStateType::SHOWING, + bIsNewShowingState ); +} + +void SwAccessibleContext::ScrolledWithin( const SwRect& rOldVisArea ) +{ + SetVisArea( GetMap()->GetVisArea() ); + + ChildrenScrolled( GetFrame(), rOldVisArea ); + + FireVisibleDataEvent(); +} + +void SwAccessibleContext::ScrolledIn() +{ + // This accessible should be freshly created, because it + // was not visible before. Therefore, its visible area must already + // reflect the scrolling. + OSL_ENSURE( GetVisArea() == GetMap()->GetVisArea(), + "Visible area of child is wrong. Did it exist already?" ); + + // Send child event at parent. That's all we have to do here. + const SwFrame* pParent = GetParent(); + ::rtl::Reference< SwAccessibleContext > xParentImpl( + GetMap()->GetContextImpl( pParent, false ) ); + uno::Reference < XAccessibleContext > xThis( this ); + if( xParentImpl.is() ) + { + SetParent( xParentImpl.get() ); + + AccessibleEventObject aEvent; + aEvent.EventId = AccessibleEventId::CHILD; + aEvent.NewValue <<= xThis; + + xParentImpl->FireAccessibleEvent( aEvent ); + + if( HasCursor() ) + { + vcl::Window *pWin = GetWindow(); + if( pWin && pWin->HasFocus() ) + { + FireStateChangedEvent( AccessibleStateType::FOCUSED, true ); + } + } + + } +} + +void SwAccessibleContext::ScrolledOut( const SwRect& rOldVisArea ) +{ + SetVisArea( GetMap()->GetVisArea() ); + + // First of all, update the children. That's required to dispose + // all children that are existing only if they are visible. They + // are not disposed by the recursive Dispose call that follows later on, + // because this call will only dispose children that are in the + // new visible area. The children we want to dispose however are in the + // old visible area all. + ChildrenScrolled( GetFrame(), rOldVisArea ); + + // Broadcast a state changed event for the showing state. + // It might be that the child is freshly created just to send + // the child event. In this case no listener will exist. + FireStateChangedEvent( AccessibleStateType::SHOWING, false ); + + // this Dispose call was removed by IAccessibility2 implementation + // without giving any reason why - without it we get stale + // entries in SwAccessibleMap::mpFrameMap. + Dispose(true); +} + +// #i27301# - use new type definition for <_nStates> +void SwAccessibleContext::InvalidateChildrenStates( const SwFrame* _pFrame, + AccessibleStates _nStates ) +{ + const SwAccessibleChildSList aVisList( GetVisArea(), *_pFrame, *(GetMap()) ); + + SwAccessibleChildSList::const_iterator aIter( aVisList.begin() ); + while( aIter != aVisList.end() ) + { + const SwAccessibleChild& rLower = *aIter; + const SwFrame* pLower = rLower.GetSwFrame(); + if( pLower ) + { + ::rtl::Reference< SwAccessibleContext > xAccImpl; + if( rLower.IsAccessible( GetShell()->IsPreview() ) ) + xAccImpl = GetMap()->GetContextImpl( pLower, false ); + if( xAccImpl.is() ) + xAccImpl->InvalidateStates( _nStates ); + else + InvalidateChildrenStates( pLower, _nStates ); + } + else if ( rLower.GetDrawObject() ) + { + // TODO: SdrObjects + } + else if ( rLower.GetWindow() ) + { + // nothing to do ? + } + + ++aIter; + } +} + +void SwAccessibleContext::DisposeChildren(const SwFrame *pFrame, + bool bRecursive, + bool bCanSkipInvisible) +{ + const SwAccessibleChildSList aVisList( GetVisArea(), *pFrame, *(GetMap()) ); + SwAccessibleChildSList::const_iterator aIter( aVisList.begin() ); + while( aIter != aVisList.end() ) + { + const SwAccessibleChild& rLower = *aIter; + const SwFrame* pLower = rLower.GetSwFrame(); + if( pLower ) + { + // tdf#117601 dispose the darn thing if it ever was accessible + ::rtl::Reference<SwAccessibleContext> xAccImpl = GetMap()->GetContextImpl(pLower, false); + if( xAccImpl.is() ) + xAccImpl->Dispose( bRecursive ); + else + { + // it's possible that the xAccImpl *does* exist with a + // ref-count of 0 and blocked in its dtor in another thread - + // this call here could be from SwAccessibleMap dtor so + // remove it from any maps now! + GetMap()->RemoveContext(pLower); + // in this case the context will check with a weak_ptr + // that the map is still alive so it's not necessary + // to clear its m_pMap here. + if (bRecursive) + { + DisposeChildren(pLower, bRecursive, bCanSkipInvisible); + } + } + } + else if ( rLower.GetDrawObject() ) + { + ::rtl::Reference< ::accessibility::AccessibleShape > xAccImpl( + GetMap()->GetContextImpl( rLower.GetDrawObject(), + this, false ) ); + if( xAccImpl.is() ) + DisposeShape( rLower.GetDrawObject(), xAccImpl.get() ); + } + else if ( rLower.GetWindow() ) + { + DisposeChild(rLower, false, bCanSkipInvisible); + } + ++aIter; + } +} + +void SwAccessibleContext::InvalidateContent_( bool ) +{ +} + +void SwAccessibleContext::InvalidateCursorPos_() +{ +} + +void SwAccessibleContext::InvalidateFocus_() +{ +} + +void SwAccessibleContext::FireAccessibleEvent( AccessibleEventObject& rEvent ) +{ + OSL_ENSURE( GetFrame(), "fire event for disposed frame?" ); + if( !GetFrame() ) + return; + + if( !rEvent.Source.is() ) + { + uno::Reference < XAccessibleContext > xThis( this ); + rEvent.Source = xThis; + } + + if (m_nClientId) + comphelper::AccessibleEventNotifier::addEvent( m_nClientId, rEvent ); +} + +void SwAccessibleContext::FireVisibleDataEvent() +{ + AccessibleEventObject aEvent; + aEvent.EventId = AccessibleEventId::VISIBLE_DATA_CHANGED; + + FireAccessibleEvent( aEvent ); +} + +void SwAccessibleContext::FireStateChangedEvent( sal_Int16 nState, + bool bNewState ) +{ + AccessibleEventObject aEvent; + + aEvent.EventId = AccessibleEventId::STATE_CHANGED; + if( bNewState ) + aEvent.NewValue <<= nState; + else + aEvent.OldValue <<= nState; + + FireAccessibleEvent( aEvent ); +} + +void SwAccessibleContext::GetStates( + ::utl::AccessibleStateSetHelper& rStateSet ) +{ + SolarMutexGuard aGuard; + + // SHOWING + if (m_isShowingState) + rStateSet.AddState( AccessibleStateType::SHOWING ); + + // EDITABLE + if (m_isEditableState) + //Set editable state to graphic and other object when the document is editable + { + rStateSet.AddState( AccessibleStateType::EDITABLE ); + rStateSet.AddState( AccessibleStateType::RESIZABLE ); + rStateSet.AddState( AccessibleStateType::MOVEABLE ); + } + // ENABLED + rStateSet.AddState( AccessibleStateType::ENABLED ); + + // OPAQUE + if (m_isOpaqueState) + rStateSet.AddState( AccessibleStateType::OPAQUE ); + + // VISIBLE + rStateSet.AddState( AccessibleStateType::VISIBLE ); + + if (m_isDefuncState) + rStateSet.AddState( AccessibleStateType::DEFUNC ); +} + +bool SwAccessibleContext::IsEditableState() +{ + bool bRet; + { + osl::MutexGuard aGuard( m_Mutex ); + bRet = m_isEditableState; + } + + return bRet; +} + +void SwAccessibleContext::ThrowIfDisposed() +{ + if (!(GetFrame() && GetMap())) + { + throw lang::DisposedException("object is nonfunctional", + static_cast<cppu::OWeakObject*>(this)); + } +} + +SwAccessibleContext::SwAccessibleContext(std::shared_ptr<SwAccessibleMap> const& pMap, + sal_Int16 const nRole, + const SwFrame *pF ) + : SwAccessibleFrame( pMap->GetVisArea().SVRect(), pF, + pMap->GetShell()->IsPreview() ) + , m_pMap(pMap.get()) + , m_wMap(pMap) + , m_nClientId(0) + , m_nRole(nRole) + , m_isDisposing( false ) + , m_isRegisteredAtAccessibleMap( true ) + , m_isSelectedInDoc(false) +{ + InitStates(); +} + +SwAccessibleContext::~SwAccessibleContext() +{ + // must have for 2 reasons: 2. as long as this thread has SolarMutex + // another thread cannot destroy the SwAccessibleMap so our temporary + // taking a hard ref to SwAccessibleMap won't delay its destruction + SolarMutexGuard aGuard; + // must check with weak_ptr that m_pMap is still alive + std::shared_ptr<SwAccessibleMap> pMap(m_wMap.lock()); + if (m_isRegisteredAtAccessibleMap && GetFrame() && pMap) + { + pMap->RemoveContext( GetFrame() ); + } +} + +uno::Reference< XAccessibleContext > SAL_CALL + SwAccessibleContext::getAccessibleContext() +{ + uno::Reference < XAccessibleContext > xRet( this ); + return xRet; +} + +sal_Int32 SAL_CALL SwAccessibleContext::getAccessibleChildCount() +{ + SolarMutexGuard aGuard; + + ThrowIfDisposed(); + + return m_isDisposing ? 0 : GetChildCount( *(GetMap()) ); +} + +uno::Reference< XAccessible> SAL_CALL + SwAccessibleContext::getAccessibleChild( sal_Int32 nIndex ) +{ + SolarMutexGuard aGuard; + + ThrowIfDisposed(); + + const SwAccessibleChild aChild( GetChild( *(GetMap()), nIndex ) ); + if( !aChild.IsValid() ) + { + uno::Reference < XAccessibleContext > xThis( this ); + lang::IndexOutOfBoundsException aExcept( + "index out of bounds", + xThis ); + throw aExcept; + } + + uno::Reference< XAccessible > xChild; + if( aChild.GetSwFrame() ) + { + ::rtl::Reference < SwAccessibleContext > xChildImpl( + GetMap()->GetContextImpl( aChild.GetSwFrame(), !m_isDisposing ) ); + if( xChildImpl.is() ) + { + xChildImpl->SetParent( this ); + xChild = xChildImpl.get(); + } + } + else if ( aChild.GetDrawObject() ) + { + ::rtl::Reference < ::accessibility::AccessibleShape > xChildImpl( + GetMap()->GetContextImpl( aChild.GetDrawObject(), + this, !m_isDisposing) ); + if( xChildImpl.is() ) + xChild = xChildImpl.get(); + } + else if ( aChild.GetWindow() ) + { + xChild = aChild.GetWindow()->GetAccessible(); + } + + return xChild; +} + +css::uno::Sequence<uno::Reference<XAccessible>> SAL_CALL + SwAccessibleContext::getAccessibleChildren() +{ + SolarMutexGuard aGuard; + + ThrowIfDisposed(); + + std::list< sw::access::SwAccessibleChild > aChildren; + GetChildren( *GetMap(), aChildren ); + + std::vector<uno::Reference<XAccessible>> aRet; + aRet.reserve(aChildren.size()); + for (const auto & rSwChild : aChildren) + { + uno::Reference< XAccessible > xChild; + if( rSwChild.GetSwFrame() ) + { + ::rtl::Reference < SwAccessibleContext > xChildImpl( + GetMap()->GetContextImpl( rSwChild.GetSwFrame(), !m_isDisposing ) ); + if( xChildImpl.is() ) + { + xChildImpl->SetParent( this ); + xChild = xChildImpl.get(); + } + } + else if ( rSwChild.GetDrawObject() ) + { + ::rtl::Reference < ::accessibility::AccessibleShape > xChildImpl( + GetMap()->GetContextImpl( rSwChild.GetDrawObject(), + this, !m_isDisposing) ); + if( xChildImpl.is() ) + xChild = xChildImpl.get(); + } + else if ( rSwChild.GetWindow() ) + { + xChild = rSwChild.GetWindow()->GetAccessible(); + } + aRet.push_back(xChild); + } + return comphelper::containerToSequence(aRet); +} + +uno::Reference< XAccessible> SwAccessibleContext::getAccessibleParentImpl() +{ + SolarMutexGuard aGuard; + + const SwFrame *pUpper = GetParent(); + OSL_ENSURE( pUpper != nullptr || m_isDisposing, "no upper found" ); + + uno::Reference< XAccessible > xAcc; + if( pUpper ) + xAcc = GetMap()->GetContext( pUpper, !m_isDisposing ); + + OSL_ENSURE( xAcc.is() || m_isDisposing, "no parent found" ); + + // Remember the parent as weak ref. + { + osl::MutexGuard aWeakParentGuard( m_Mutex ); + m_xWeakParent = xAcc; + } + + return xAcc; +} + +uno::Reference< XAccessible> SAL_CALL SwAccessibleContext::getAccessibleParent() +{ + SolarMutexGuard aGuard; + + ThrowIfDisposed(); + + return getAccessibleParentImpl(); +} + +sal_Int32 SAL_CALL SwAccessibleContext::getAccessibleIndexInParent() +{ + SolarMutexGuard aGuard; + + ThrowIfDisposed(); + + const SwFrame *pUpper = GetParent(); + OSL_ENSURE( pUpper != nullptr || m_isDisposing, "no upper found" ); + + sal_Int32 nIndex = -1; + if( pUpper ) + { + ::rtl::Reference < SwAccessibleContext > xAccImpl( + GetMap()->GetContextImpl(pUpper, !m_isDisposing) ); + OSL_ENSURE( xAccImpl.is() || m_isDisposing, "no parent found" ); + if( xAccImpl.is() ) + nIndex = xAccImpl->GetChildIndex( *(GetMap()), SwAccessibleChild(GetFrame()) ); + } + + return nIndex; +} + +sal_Int16 SAL_CALL SwAccessibleContext::getAccessibleRole() +{ + return m_nRole; +} + +OUString SAL_CALL SwAccessibleContext::getAccessibleName() +{ + return m_sName; +} + +uno::Reference< XAccessibleRelationSet> SAL_CALL + SwAccessibleContext::getAccessibleRelationSet() +{ + // by default there are no relations + uno::Reference< XAccessibleRelationSet> xRet( new utl::AccessibleRelationSetHelper() ); + return xRet; +} + +uno::Reference<XAccessibleStateSet> SAL_CALL + SwAccessibleContext::getAccessibleStateSet() +{ + SolarMutexGuard aGuard; + + ThrowIfDisposed(); + + ::utl::AccessibleStateSetHelper *pStateSet = + new ::utl::AccessibleStateSetHelper; + + if (m_isSelectedInDoc) + pStateSet->AddState( AccessibleStateType::SELECTED ); + + uno::Reference<XAccessibleStateSet> xStateSet( pStateSet ); + GetStates( *pStateSet ); + + return xStateSet; +} + +lang::Locale SAL_CALL SwAccessibleContext::getLocale() +{ + SolarMutexGuard aGuard; + + lang::Locale aLoc( Application::GetSettings().GetLanguageTag().getLocale() ); + return aLoc; +} + +void SAL_CALL SwAccessibleContext::addAccessibleEventListener( + const uno::Reference< XAccessibleEventListener >& xListener ) +{ + if (xListener.is()) + { + SolarMutexGuard aGuard; + if (!m_nClientId) + m_nClientId = comphelper::AccessibleEventNotifier::registerClient( ); + comphelper::AccessibleEventNotifier::addEventListener( m_nClientId, xListener ); + } +} + +void SAL_CALL SwAccessibleContext::removeAccessibleEventListener( + const uno::Reference< XAccessibleEventListener >& xListener ) +{ + if (xListener.is() && m_nClientId) + { + SolarMutexGuard aGuard; + sal_Int32 nListenerCount = comphelper::AccessibleEventNotifier::removeEventListener( m_nClientId, xListener ); + if ( !nListenerCount ) + { + // no listeners anymore + // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client), + // and at least to us not firing any events anymore, in case somebody calls + // NotifyAccessibleEvent, again + comphelper::AccessibleEventNotifier::revokeClient( m_nClientId ); + m_nClientId = 0; + } + } +} + +static bool lcl_PointInRectangle(const awt::Point & aPoint, + const awt::Rectangle & aRect) +{ + long nDiffX = aPoint.X - aRect.X; + long nDiffY = aPoint.Y - aRect.Y; + + return + nDiffX >= 0 && nDiffX < aRect.Width && nDiffY >= 0 && + nDiffY < aRect.Height; + +} + +sal_Bool SAL_CALL SwAccessibleContext::containsPoint( + const awt::Point& aPoint ) +{ + awt::Rectangle aPixBounds = getBoundsImpl(true); + aPixBounds.X = 0; + aPixBounds.Y = 0; + + return lcl_PointInRectangle(aPoint, aPixBounds); +} + +uno::Reference< XAccessible > SAL_CALL SwAccessibleContext::getAccessibleAtPoint( + const awt::Point& aPoint ) +{ + SolarMutexGuard aGuard; + + ThrowIfDisposed(); + + uno::Reference< XAccessible > xAcc; + + vcl::Window *pWin = GetWindow(); + if (!pWin) + { + throw uno::RuntimeException("no Window", static_cast<cppu::OWeakObject*>(this)); + } + + Point aPixPoint( aPoint.X, aPoint.Y ); // px rel to parent + if( !GetFrame()->IsRootFrame() ) + { + SwRect aLogBounds( GetBounds( *(GetMap()), GetFrame() ) ); // twip rel to doc root + Point aPixPos( GetMap()->CoreToPixel( aLogBounds.SVRect() ).TopLeft() ); + aPixPoint.setX(aPixPoint.getX() + aPixPos.getX()); + aPixPoint.setY(aPixPoint.getY() + aPixPos.getY()); + } + + const SwAccessibleChild aChild( GetChildAtPixel( aPixPoint, *(GetMap()) ) ); + if( aChild.GetSwFrame() ) + { + xAcc = GetMap()->GetContext( aChild.GetSwFrame() ); + } + else if( aChild.GetDrawObject() ) + { + xAcc = GetMap()->GetContext( aChild.GetDrawObject(), this ); + } + else if ( aChild.GetWindow() ) + { + xAcc = aChild.GetWindow()->GetAccessible(); + } + + return xAcc; +} + +/** + Get bounding box. + + There are two modes. + + - relative + + Return bounding box relative to parent if parent is no root + frame. Otherwise return the absolute bounding box. + + - absolute + + Return the absolute bounding box. + + @param bRelative + true: Use relative mode. + false: Use absolute mode. +*/ +awt::Rectangle SwAccessibleContext::getBoundsImpl(bool bRelative) +{ + SolarMutexGuard aGuard; + + ThrowIfDisposed(); + + const SwFrame *pParent = GetParent(); + OSL_ENSURE( pParent, "no Parent found" ); + vcl::Window *pWin = GetWindow(); + + if (!pParent) + { + throw uno::RuntimeException("no Parent", static_cast<cppu::OWeakObject*>(this)); + } + if (!pWin) + { + throw uno::RuntimeException("no Window", static_cast<cppu::OWeakObject*>(this)); + } + + SwRect aLogBounds( GetBounds( *(GetMap()), GetFrame() ) ); // twip relative to document root + tools::Rectangle aPixBounds( 0, 0, 0, 0 ); + if( GetFrame()->IsPageFrame() && + static_cast < const SwPageFrame * >( GetFrame() )->IsEmptyPage() ) + { + OSL_ENSURE( GetShell()->IsPreview(), "empty page accessible?" ); + if( GetShell()->IsPreview() ) + { + // adjust method call <GetMap()->GetPreviewPageSize()> + sal_uInt16 nPageNum = + static_cast < const SwPageFrame * >( GetFrame() )->GetPhyPageNum(); + aLogBounds.SSize( GetMap()->GetPreviewPageSize( nPageNum ) ); + } + } + if( !aLogBounds.IsEmpty() ) + { + aPixBounds = GetMap()->CoreToPixel( aLogBounds.SVRect() ); + if( !pParent->IsRootFrame() && bRelative) + { + SwRect aParentLogBounds( GetBounds( *(GetMap()), pParent ) ); // twip rel to doc root + Point aParentPixPos( GetMap()->CoreToPixel( aParentLogBounds.SVRect() ).TopLeft() ); + aPixBounds.Move( -aParentPixPos.getX(), -aParentPixPos.getY() ); + } + } + + awt::Rectangle aBox( aPixBounds.Left(), aPixBounds.Top(), + aPixBounds.GetWidth(), aPixBounds.GetHeight() ); + + return aBox; +} + +awt::Rectangle SAL_CALL SwAccessibleContext::getBounds() +{ + return getBoundsImpl(true); +} + +awt::Point SAL_CALL SwAccessibleContext::getLocation() +{ + awt::Rectangle aRect = getBoundsImpl(true); + awt::Point aPoint(aRect.X, aRect.Y); + + return aPoint; +} + +awt::Point SAL_CALL SwAccessibleContext::getLocationOnScreen() +{ + awt::Rectangle aRect = getBoundsImpl(false); + + Point aPixPos(aRect.X, aRect.Y); + + vcl::Window *pWin = GetWindow(); + if (!pWin) + { + throw uno::RuntimeException("no Window", static_cast<cppu::OWeakObject*>(this)); + } + + aPixPos = pWin->OutputToAbsoluteScreenPixel(aPixPos); + awt::Point aPoint(aPixPos.getX(), aPixPos.getY()); + + return aPoint; +} + +awt::Size SAL_CALL SwAccessibleContext::getSize() +{ + awt::Rectangle aRect = getBoundsImpl(false); + awt::Size aSize( aRect.Width, aRect.Height ); + + return aSize; +} + +void SAL_CALL SwAccessibleContext::grabFocus() +{ + SolarMutexGuard aGuard; + + ThrowIfDisposed(); + + if( GetFrame()->IsFlyFrame() ) + { + const SdrObject *pObj = + static_cast < const SwFlyFrame * >( GetFrame() )->GetVirtDrawObj(); + if( pObj ) + Select( const_cast < SdrObject * >( pObj ), false ); + } + else + { + const SwContentFrame *pCFrame = nullptr; + if( GetFrame()->IsContentFrame() ) + pCFrame = static_cast< const SwContentFrame * >( GetFrame() ); + else if( GetFrame()->IsLayoutFrame() ) + pCFrame = static_cast< const SwLayoutFrame * >( GetFrame() )->ContainsContent(); + + if( pCFrame && pCFrame->IsTextFrame() ) + { + const SwTextFrame *pTextFrame = static_cast< const SwTextFrame * >( pCFrame ); + const SwTextNode *pTextNd = pTextFrame->GetTextNodeFirst(); + assert(pTextNd); // can it actually be null? probably not=>simplify + if( pTextNd ) + { + // create pam for selection + SwPosition const aStartPos(pTextFrame->MapViewToModelPos(pTextFrame->GetOffset())); + SwPaM aPaM( aStartPos ); + + // set PaM at cursor shell + Select( aPaM ); + } + } + } +} + +sal_Int32 SAL_CALL SwAccessibleContext::getForeground() +{ + return sal_Int32(COL_BLACK); +} + +sal_Int32 SAL_CALL SwAccessibleContext::getBackground() +{ + return sal_Int32(COL_WHITE); +} + +sal_Bool SAL_CALL SwAccessibleContext::supportsService (const OUString& ServiceName) +{ + return cppu::supportsService(this, ServiceName); +} + +void SwAccessibleContext::DisposeShape( const SdrObject *pObj, + ::accessibility::AccessibleShape *pAccImpl ) +{ + ::rtl::Reference< ::accessibility::AccessibleShape > xAccImpl( pAccImpl ); + if( !xAccImpl.is() ) + xAccImpl = GetMap()->GetContextImpl( pObj, this ); + + AccessibleEventObject aEvent; + aEvent.EventId = AccessibleEventId::CHILD; + uno::Reference< XAccessible > xAcc( xAccImpl.get() ); + aEvent.OldValue <<= xAcc; + FireAccessibleEvent( aEvent ); + + GetMap()->RemoveContext( pObj ); + xAccImpl->dispose(); +} + +void SwAccessibleContext::ScrolledInShape( ::accessibility::AccessibleShape *pAccImpl ) +{ + if(nullptr == pAccImpl) + { + return ; + } + AccessibleEventObject aEvent; + aEvent.EventId = AccessibleEventId::CHILD; + uno::Reference< XAccessible > xAcc( pAccImpl ); + aEvent.NewValue <<= xAcc; + FireAccessibleEvent( aEvent ); + + if( pAccImpl->GetState( AccessibleStateType::FOCUSED ) ) + { + vcl::Window *pWin = GetWindow(); + if( pWin && pWin->HasFocus() ) + { + AccessibleEventObject aStateChangedEvent; + aStateChangedEvent.EventId = AccessibleEventId::STATE_CHANGED; + aStateChangedEvent.NewValue <<= AccessibleStateType::FOCUSED; + aStateChangedEvent.Source = xAcc; + + FireAccessibleEvent( aStateChangedEvent ); + } + } +} + +void SwAccessibleContext::Dispose(bool bRecursive, bool bCanSkipInvisible) +{ + SolarMutexGuard aGuard; + + OSL_ENSURE( GetFrame() && GetMap(), "already disposed" ); + OSL_ENSURE( GetMap()->GetVisArea() == GetVisArea(), + "invalid visible area for dispose" ); + + m_isDisposing = true; + + // dispose children + if( bRecursive ) + DisposeChildren(GetFrame(), bRecursive, bCanSkipInvisible); + + // get parent + uno::Reference< XAccessible > xParent( GetWeakParent() ); + uno::Reference < XAccessibleContext > xThis( this ); + + // send child event at parent + if( xParent.is() ) + { + SwAccessibleContext *pAcc = static_cast<SwAccessibleContext *>(xParent.get()); + + AccessibleEventObject aEvent; + aEvent.EventId = AccessibleEventId::CHILD; + aEvent.OldValue <<= xThis; + pAcc->FireAccessibleEvent( aEvent ); + } + + // set defunc state (it's not required to broadcast a state changed + // event if the object is disposed afterwards) + { + osl::MutexGuard aDefuncStateGuard( m_Mutex ); + m_isDefuncState = true; + } + + // broadcast dispose event + if (m_nClientId) + { + comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( m_nClientId, *this ); + m_nClientId = 0; + } + + RemoveFrameFromAccessibleMap(); + ClearFrame(); + m_pMap = nullptr; + m_wMap.reset(); + + m_isDisposing = false; +} + +void SwAccessibleContext::DisposeChild( const SwAccessibleChild& rChildFrameOrObj, + bool bRecursive, bool bCanSkipInvisible ) +{ + SolarMutexGuard aGuard; + + if ( !bCanSkipInvisible || + rChildFrameOrObj.AlwaysIncludeAsChild() || + IsShowing( *(GetMap()), rChildFrameOrObj ) || + !SwAccessibleChild( GetFrame() ).IsVisibleChildrenOnly() ) + { + // If the object could have existed before, then there is nothing to do, + // because no wrapper exists now and therefore no one is interested to + // get notified of the movement. + if( rChildFrameOrObj.GetSwFrame() ) + { + ::rtl::Reference< SwAccessibleContext > xAccImpl = + GetMap()->GetContextImpl( rChildFrameOrObj.GetSwFrame(), false ); + if (xAccImpl) + xAccImpl->Dispose( bRecursive ); + } + else if ( rChildFrameOrObj.GetDrawObject() ) + { + ::rtl::Reference< ::accessibility::AccessibleShape > xAccImpl = + GetMap()->GetContextImpl( rChildFrameOrObj.GetDrawObject(), + this, false ); + if (xAccImpl) + DisposeShape( rChildFrameOrObj.GetDrawObject(), + xAccImpl.get() ); + } + else if ( rChildFrameOrObj.GetWindow() ) + { + AccessibleEventObject aEvent; + aEvent.EventId = AccessibleEventId::CHILD; + uno::Reference< XAccessible > xAcc = + rChildFrameOrObj.GetWindow()->GetAccessible(); + aEvent.OldValue <<= xAcc; + FireAccessibleEvent( aEvent ); + } + } + else if( bRecursive && rChildFrameOrObj.GetSwFrame() ) + DisposeChildren(rChildFrameOrObj.GetSwFrame(), bRecursive, bCanSkipInvisible); +} + +void SwAccessibleContext::InvalidatePosOrSize( const SwRect& ) +{ + SolarMutexGuard aGuard; + + OSL_ENSURE( GetFrame() && !GetFrame()->getFrameArea().IsEmpty(), "context should have a size" ); + + bool bIsOldShowingState; + bool bIsNewShowingState = IsShowing( *(GetMap()) ); + { + osl::MutexGuard aShowingStateGuard( m_Mutex ); + bIsOldShowingState = m_isShowingState; + m_isShowingState = bIsNewShowingState; + } + + if( bIsOldShowingState != bIsNewShowingState ) + { + FireStateChangedEvent( AccessibleStateType::SHOWING, + bIsNewShowingState ); + } + else if( bIsNewShowingState ) + { + // The frame stays visible -> broadcast event + FireVisibleDataEvent(); + } + + // note: InvalidatePosOrSize must call InvalidateContent_ so that + // SwAccessibleParagraph updates its portions, or dispose it + // (see accmap.cxx: INVALID_CONTENT is contained in POS_CHANGED) + if( !bIsNewShowingState && + SwAccessibleChild( GetParent() ).IsVisibleChildrenOnly() ) + { + // this Dispose call was removed by IAccessibility2 implementation + // without giving any reason why - without it we get stale + // entries in SwAccessibleMap::mpFrameMap. + Dispose(true); + } + else + { + InvalidateContent_( true ); + } +} + +void SwAccessibleContext::InvalidateChildPosOrSize( + const SwAccessibleChild& rChildFrameOrObj, + const SwRect& rOldFrame ) +{ + SolarMutexGuard aGuard; + + // this happens during layout, e.g. when a page is deleted and next page's + // header/footer moves backward such an event is generated + SAL_INFO_IF(rChildFrameOrObj.GetSwFrame() && + rChildFrameOrObj.GetSwFrame()->getFrameArea().IsEmpty(), + "sw.a11y", "child context should have a size"); + + if ( rChildFrameOrObj.AlwaysIncludeAsChild() ) + { + // nothing to do; + return; + } + + const bool bVisibleChildrenOnly = SwAccessibleChild( GetFrame() ).IsVisibleChildrenOnly(); + const bool bNew = rOldFrame.IsEmpty() || + ( rOldFrame.Left() == 0 && rOldFrame.Top() == 0 ); + if( IsShowing( *(GetMap()), rChildFrameOrObj ) ) + { + // If the object could have existed before, then there is nothing to do, + // because no wrapper exists now and therefore no one is interested to + // get notified of the movement. + if( bNew || (bVisibleChildrenOnly && !IsShowing( rOldFrame )) ) + { + if( rChildFrameOrObj.GetSwFrame() ) + { + // The frame becomes visible. A child event must be send. + ::rtl::Reference< SwAccessibleContext > xAccImpl = + GetMap()->GetContextImpl( rChildFrameOrObj.GetSwFrame() ); + xAccImpl->ScrolledIn(); + } + else if ( rChildFrameOrObj.GetDrawObject() ) + { + ::rtl::Reference< ::accessibility::AccessibleShape > xAccImpl = + GetMap()->GetContextImpl( rChildFrameOrObj.GetDrawObject(), + this ); + // #i37790# + if ( xAccImpl.is() ) + { + ScrolledInShape( xAccImpl.get() ); + } + else + { + OSL_FAIL( "<SwAccessibleContext::InvalidateChildPosOrSize(..)> - no accessible shape found." ); + } + } + else if ( rChildFrameOrObj.GetWindow() ) + { + AccessibleEventObject aEvent; + aEvent.EventId = AccessibleEventId::CHILD; + aEvent.NewValue <<= rChildFrameOrObj.GetWindow()->GetAccessible(); + FireAccessibleEvent( aEvent ); + } + } + } + else + { + // If the frame was visible before, then a child event for the parent + // needs to be send. However, there is no wrapper existing, and so + // no notifications for grandchildren are required. If the are + // grandgrandchildren, they would be notified by the layout. + if( bVisibleChildrenOnly && + !bNew && IsShowing( rOldFrame ) ) + { + if( rChildFrameOrObj.GetSwFrame() ) + { + ::rtl::Reference< SwAccessibleContext > xAccImpl = + GetMap()->GetContextImpl( rChildFrameOrObj.GetSwFrame() ); + xAccImpl->SetParent( this ); + xAccImpl->Dispose( true ); + } + else if ( rChildFrameOrObj.GetDrawObject() ) + { + ::rtl::Reference< ::accessibility::AccessibleShape > xAccImpl = + GetMap()->GetContextImpl( rChildFrameOrObj.GetDrawObject(), + this ); + DisposeShape( rChildFrameOrObj.GetDrawObject(), + xAccImpl.get() ); + } + else if ( rChildFrameOrObj.GetWindow() ) + { + OSL_FAIL( "<SwAccessibleContext::InvalidateChildPosOrSize(..)> - not expected to handle dispose of child of type <vcl::Window>." ); + } + } + } +} + +void SwAccessibleContext::InvalidateContent() +{ + SolarMutexGuard aGuard; + + InvalidateContent_( false ); +} + +void SwAccessibleContext::InvalidateCursorPos() +{ + SolarMutexGuard aGuard; + + InvalidateCursorPos_(); +} + +void SwAccessibleContext::InvalidateFocus() +{ + SolarMutexGuard aGuard; + + InvalidateFocus_(); +} + +// #i27301# - use new type definition for <_nStates> +void SwAccessibleContext::InvalidateStates( AccessibleStates _nStates ) +{ + if( GetMap() ) + { + SwViewShell *pVSh = GetMap()->GetShell(); + if( pVSh ) + { + if( _nStates & AccessibleStates::EDITABLE ) + { + bool bIsOldEditableState; + bool bIsNewEditableState = IsEditable( pVSh ); + { + osl::MutexGuard aGuard( m_Mutex ); + bIsOldEditableState = m_isEditableState; + m_isEditableState = bIsNewEditableState; + } + + if( bIsOldEditableState != bIsNewEditableState ) + FireStateChangedEvent( AccessibleStateType::EDITABLE, + bIsNewEditableState ); + } + if( _nStates & AccessibleStates::OPAQUE ) + { + bool bIsOldOpaqueState; + bool bIsNewOpaqueState = IsOpaque( pVSh ); + { + osl::MutexGuard aGuard( m_Mutex ); + bIsOldOpaqueState = m_isOpaqueState; + m_isOpaqueState = bIsNewOpaqueState; + } + + if( bIsOldOpaqueState != bIsNewOpaqueState ) + FireStateChangedEvent( AccessibleStateType::OPAQUE, + bIsNewOpaqueState ); + } + } + + InvalidateChildrenStates( GetFrame(), _nStates ); + } +} + +void SwAccessibleContext::InvalidateRelation( sal_uInt16 nType ) +{ + AccessibleEventObject aEvent; + aEvent.EventId = nType; + + FireAccessibleEvent( aEvent ); +} + +/** #i27301# - text selection has changed */ +void SwAccessibleContext::InvalidateTextSelection() +{ + AccessibleEventObject aEvent; + aEvent.EventId = AccessibleEventId::TEXT_SELECTION_CHANGED; + + FireAccessibleEvent( aEvent ); +} + +/** #i88069# - attributes has changed */ +void SwAccessibleContext::InvalidateAttr() +{ + AccessibleEventObject aEvent; + aEvent.EventId = AccessibleEventId::TEXT_ATTRIBUTE_CHANGED; + + FireAccessibleEvent( aEvent ); +} + +bool SwAccessibleContext::HasCursor() +{ + return false; +} + +bool SwAccessibleContext::Select( SwPaM *pPaM, SdrObject *pObj, + bool bAdd ) +{ + SwCursorShell* pCursorShell = GetCursorShell(); + if( !pCursorShell ) + return false; + + SwFEShell* pFEShell = dynamic_cast<const SwFEShell*>( pCursorShell) != nullptr + ? static_cast<SwFEShell*>( pCursorShell ) + : nullptr; + // Get rid of activated OLE object + if( pFEShell ) + pFEShell->FinishOLEObj(); + + SwWrtShell* pWrtShell = dynamic_cast<const SwWrtShell*>( pCursorShell) != nullptr + ? static_cast<SwWrtShell*>( pCursorShell ) + : nullptr; + + bool bRet = false; + if( pObj ) + { + if( pFEShell ) + { + sal_uInt8 nFlags = bAdd ? SW_ADD_SELECT : 0; + pFEShell->SelectObj( Point(), nFlags, pObj ); + bRet = true; + } + } + else if( pPaM ) + { + // Get rid of frame selection. If there is one, make text cursor + // visible again. + bool bCallShowCursor = false; + if( pFEShell && (pFEShell->IsFrameSelected() || + pFEShell->IsObjSelected()) ) + { + Point aPt( LONG_MIN, LONG_MIN ); + pFEShell->SelectObj( aPt ); + bCallShowCursor = true; + } + pCursorShell->KillPams(); + if( pWrtShell && pPaM->HasMark() ) + // We have to do this or SwWrtShell can't figure out that it needs + // to kill the selection later, when the user moves the cursor. + pWrtShell->SttSelect(); + pCursorShell->SetSelection( *pPaM ); + if( pPaM->HasMark() && *pPaM->GetPoint() == *pPaM->GetMark()) + // Setting a "Selection" that starts and ends at the same spot + // should remove the selection rather than create an empty one, so + // that we get defined behavior if accessibility sets the cursor + // later. + pCursorShell->ClearMark(); + if( bCallShowCursor ) + pCursorShell->ShowCursor(); + bRet = true; + } + + return bRet; +} + +OUString SwAccessibleContext::GetResource(const char* pResId, + const OUString *pArg1, + const OUString *pArg2) +{ + OUString sStr = SwResId(pResId); + + if( pArg1 ) + { + sStr = sStr.replaceFirst( "$(ARG1)", *pArg1 ); + } + if( pArg2 ) + { + sStr = sStr.replaceFirst( "$(ARG2)", *pArg2 ); + } + + return sStr; +} + +void SwAccessibleContext::RemoveFrameFromAccessibleMap() +{ + assert(m_refCount > 0); // must be alive to do this without using m_wMap + if (m_isRegisteredAtAccessibleMap && GetFrame() && GetMap()) + GetMap()->RemoveContext( GetFrame() ); +} + +bool SwAccessibleContext::HasAdditionalAccessibleChildren() +{ + bool bRet( false ); + + if ( GetFrame()->IsTextFrame() ) + { + SwPostItMgr* pPostItMgr = GetMap()->GetShell()->GetPostItMgr(); + if ( pPostItMgr && pPostItMgr->HasNotes() && pPostItMgr->ShowNotes() ) + { + bRet = pPostItMgr->HasFrameConnectedSidebarWins( *(GetFrame()) ); + } + } + + return bRet; +} + +/** #i88070# - get additional accessible child by index */ +vcl::Window* SwAccessibleContext::GetAdditionalAccessibleChild( const sal_Int32 nIndex ) +{ + vcl::Window* pAdditionalAccessibleChild( nullptr ); + + if ( GetFrame()->IsTextFrame() ) + { + SwPostItMgr* pPostItMgr = GetMap()->GetShell()->GetPostItMgr(); + if ( pPostItMgr && pPostItMgr->HasNotes() && pPostItMgr->ShowNotes() ) + { + pAdditionalAccessibleChild = + pPostItMgr->GetSidebarWinForFrameByIndex( *(GetFrame()), nIndex ); + } + } + + return pAdditionalAccessibleChild; +} + +/** #i88070# - get all additional accessible children */ +void SwAccessibleContext::GetAdditionalAccessibleChildren( std::vector< vcl::Window* >* pChildren ) +{ + if ( GetFrame()->IsTextFrame() ) + { + SwPostItMgr* pPostItMgr = GetMap()->GetShell()->GetPostItMgr(); + if ( pPostItMgr && pPostItMgr->HasNotes() && pPostItMgr->ShowNotes() ) + { + pPostItMgr->GetAllSidebarWinForFrame( *(GetFrame()), pChildren ); + } + } +} + +bool SwAccessibleContext::SetSelectedState(bool const bSelected) +{ + if (m_isSelectedInDoc != bSelected) + { + m_isSelectedInDoc = bSelected; + FireStateChangedEvent( AccessibleStateType::SELECTED, bSelected ); + return true; + } + return false; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |