editeng/source/accessibility/AccessibleEditableTextPara.cxx | 4007 +++++------- editeng/source/accessibility/AccessibleHyperlink.cxx | 130 editeng/source/accessibility/AccessibleHyperlink.hxx | 44 editeng/source/accessibility/AccessibleImageBullet.cxx | 670 +- editeng/source/accessibility/AccessibleParaManager.cxx | 545 - editeng/source/accessibility/AccessibleSelectionBase.cxx | 85 editeng/source/accessibility/AccessibleStaticTextBase.cxx | 1325 +-- include/editeng/AccessibleEditableTextPara.hxx | 583 - include/editeng/AccessibleParaManager.hxx | 361 - include/editeng/AccessibleSelectionBase.hxx | 37 include/editeng/AccessibleStaticTextBase.hxx | 374 - include/editeng/editrids.hrc | 1 sd/qa/unit/a11y/layout.cxx | 93 sw/qa/extras/accessibility/dialogs.cxx | 6 14 files changed, 4106 insertions(+), 4155 deletions(-)
New commits: commit 9b892757d2ccae1fe74e616158f378c31a67ae6d Author: Michael Weghorn <m.wegh...@posteo.de> AuthorDate: Wed Apr 2 12:15:06 2025 +0200 Commit: Michael Weghorn <m.wegh...@posteo.de> CommitDate: Thu Apr 3 22:29:57 2025 +0200 editeng a11y: Drop extra indentation level Change-Id: I5f2d99730cfda9490c3fa9fa43242e0d5219ca82 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/183626 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.wegh...@posteo.de> diff --git a/editeng/source/accessibility/AccessibleEditableTextPara.cxx b/editeng/source/accessibility/AccessibleEditableTextPara.cxx index b8a00af82f7c..23d90285f842 100644 --- a/editeng/source/accessibility/AccessibleEditableTextPara.cxx +++ b/editeng/source/accessibility/AccessibleEditableTextPara.cxx @@ -83,2534 +83,2535 @@ using namespace ::com::sun::star::accessibility; namespace accessibility { - static const SvxItemPropertySet* ImplGetSvxCharAndParaPropertiesSet() - { - // PropertyMap for character and paragraph properties - static const SfxItemPropertyMapEntry aPropMap[] = - { - SVX_UNOEDIT_OUTLINER_PROPERTIES, - SVX_UNOEDIT_CHAR_PROPERTIES, - SVX_UNOEDIT_PARA_PROPERTIES, - SVX_UNOEDIT_NUMBERING_PROPERTY, - { u"TextUserDefinedAttributes"_ustr, EE_CHAR_XMLATTRIBS, cppu::UnoType<css::container::XNameContainer>::get(), 0, 0}, - { u"ParaUserDefinedAttributes"_ustr, EE_PARA_XMLATTRIBS, cppu::UnoType<css::container::XNameContainer>::get(), 0, 0}, - }; - static SvxItemPropertySet aPropSet( aPropMap, EditEngine::GetGlobalItemPool() ); - return &aPropSet; - } - - // #i27138# - add parameter <_pParaManager> - AccessibleEditableTextPara::AccessibleEditableTextPara( - uno::Reference< XAccessible > xParent, - const AccessibleParaManager* _pParaManager ) - : mnParagraphIndex( 0 ), - mnIndexInParent( 0 ), - mpEditSource( nullptr ), - maEEOffset( 0, 0 ), - mxParent(std::move( xParent )), - // well, that's strictly (UNO) exception safe, though not - // really robust. We rely on the fact that this member is - // constructed last, and that the constructor body catches - // exceptions, thus no chance for exceptions once the Id is - // fetched. Nevertheless, normally should employ RAII here... - mnNotifierClientId(::comphelper::AccessibleEventNotifier::registerClient()), - // #i27138# - mpParaManager( _pParaManager ) - { - - // Create the state set. - mnStateSet = 0; - - // these are always on - mnStateSet |= AccessibleStateType::MULTI_LINE; - mnStateSet |= AccessibleStateType::FOCUSABLE; - mnStateSet |= AccessibleStateType::VISIBLE; - mnStateSet |= AccessibleStateType::SHOWING; - mnStateSet |= AccessibleStateType::ENABLED; - mnStateSet |= AccessibleStateType::SENSITIVE; - } - - AccessibleEditableTextPara::~AccessibleEditableTextPara() - { - // sign off from event notifier - if( getNotifierClientId() != -1 ) - { - try - { - ::comphelper::AccessibleEventNotifier::revokeClient( getNotifierClientId() ); - } - catch (const uno::Exception&) - { - } - } - } - OUString AccessibleEditableTextPara::implGetText() - { - return GetTextRange( 0, GetTextLen() ); - } +static const SvxItemPropertySet* ImplGetSvxCharAndParaPropertiesSet() +{ + // PropertyMap for character and paragraph properties + static const SfxItemPropertyMapEntry aPropMap[] = + { + SVX_UNOEDIT_OUTLINER_PROPERTIES, + SVX_UNOEDIT_CHAR_PROPERTIES, + SVX_UNOEDIT_PARA_PROPERTIES, + SVX_UNOEDIT_NUMBERING_PROPERTY, + { u"TextUserDefinedAttributes"_ustr, EE_CHAR_XMLATTRIBS, cppu::UnoType<css::container::XNameContainer>::get(), 0, 0}, + { u"ParaUserDefinedAttributes"_ustr, EE_PARA_XMLATTRIBS, cppu::UnoType<css::container::XNameContainer>::get(), 0, 0}, + }; + static SvxItemPropertySet aPropSet( aPropMap, EditEngine::GetGlobalItemPool() ); + return &aPropSet; +} - css::lang::Locale AccessibleEditableTextPara::implGetLocale() - { - DBG_ASSERT(GetParagraphIndex() >= 0, - "AccessibleEditableTextPara::getLocale: paragraph index value overflow"); +// #i27138# - add parameter <_pParaManager> +AccessibleEditableTextPara::AccessibleEditableTextPara( + uno::Reference< XAccessible > xParent, + const AccessibleParaManager* _pParaManager ) + : mnParagraphIndex( 0 ), + mnIndexInParent( 0 ), + mpEditSource( nullptr ), + maEEOffset( 0, 0 ), + mxParent(std::move( xParent )), + // well, that's strictly (UNO) exception safe, though not + // really robust. We rely on the fact that this member is + // constructed last, and that the constructor body catches + // exceptions, thus no chance for exceptions once the Id is + // fetched. Nevertheless, normally should employ RAII here... + mnNotifierClientId(::comphelper::AccessibleEventNotifier::registerClient()), + // #i27138# + mpParaManager( _pParaManager ) +{ - // return locale of first character in the paragraph - return LanguageTag(GetTextForwarder().GetLanguage( GetParagraphIndex(), 0 )).getLocale(); - } + // Create the state set. + mnStateSet = 0; - void AccessibleEditableTextPara::implGetSelection( sal_Int32& nStartIndex, sal_Int32& nEndIndex ) - { - sal_Int32 nStart, nEnd; + // these are always on + mnStateSet |= AccessibleStateType::MULTI_LINE; + mnStateSet |= AccessibleStateType::FOCUSABLE; + mnStateSet |= AccessibleStateType::VISIBLE; + mnStateSet |= AccessibleStateType::SHOWING; + mnStateSet |= AccessibleStateType::ENABLED; + mnStateSet |= AccessibleStateType::SENSITIVE; +} - if( GetSelection( nStart, nEnd ) ) +AccessibleEditableTextPara::~AccessibleEditableTextPara() +{ + // sign off from event notifier + if( getNotifierClientId() != -1 ) + { + try { - nStartIndex = nStart; - nEndIndex = nEnd; + ::comphelper::AccessibleEventNotifier::revokeClient( getNotifierClientId() ); } - else + catch (const uno::Exception&) { - // #102234# No exception, just set to 'invalid' - nStartIndex = -1; - nEndIndex = -1; } } +} - void AccessibleEditableTextPara::implGetParagraphBoundary( const OUString& rText, css::i18n::Boundary& rBoundary, sal_Int32 /*nIndex*/ ) - { - SAL_INFO( "editeng", "AccessibleEditableTextPara::implGetParagraphBoundary: only a base implementation, ignoring the index" ); +OUString AccessibleEditableTextPara::implGetText() +{ + return GetTextRange( 0, GetTextLen() ); +} - rBoundary.startPos = 0; - rBoundary.endPos = rText.getLength(); - } +css::lang::Locale AccessibleEditableTextPara::implGetLocale() +{ + DBG_ASSERT(GetParagraphIndex() >= 0, + "AccessibleEditableTextPara::getLocale: paragraph index value overflow"); + + // return locale of first character in the paragraph + return LanguageTag(GetTextForwarder().GetLanguage( GetParagraphIndex(), 0 )).getLocale(); +} + +void AccessibleEditableTextPara::implGetSelection( sal_Int32& nStartIndex, sal_Int32& nEndIndex ) +{ + sal_Int32 nStart, nEnd; - void AccessibleEditableTextPara::implGetLineBoundary( const OUString&, css::i18n::Boundary& rBoundary, sal_Int32 nIndex ) + if( GetSelection( nStart, nEnd ) ) { - SvxTextForwarder& rCacheTF = GetTextForwarder(); - const sal_Int32 nParaIndex = GetParagraphIndex(); + nStartIndex = nStart; + nEndIndex = nEnd; + } + else + { + // #102234# No exception, just set to 'invalid' + nStartIndex = -1; + nEndIndex = -1; + } +} - DBG_ASSERT(nParaIndex >= 0, - "AccessibleEditableTextPara::implGetLineBoundary: paragraph index value overflow"); +void AccessibleEditableTextPara::implGetParagraphBoundary( const OUString& rText, css::i18n::Boundary& rBoundary, sal_Int32 /*nIndex*/ ) +{ + SAL_INFO( "editeng", "AccessibleEditableTextPara::implGetParagraphBoundary: only a base implementation, ignoring the index" ); - const sal_Int32 nTextLen = rCacheTF.GetTextLen( nParaIndex ); + rBoundary.startPos = 0; + rBoundary.endPos = rText.getLength(); +} - CheckPosition(nIndex); +void AccessibleEditableTextPara::implGetLineBoundary( const OUString&, css::i18n::Boundary& rBoundary, sal_Int32 nIndex ) +{ + SvxTextForwarder& rCacheTF = GetTextForwarder(); + const sal_Int32 nParaIndex = GetParagraphIndex(); - rBoundary.startPos = rBoundary.endPos = -1; + DBG_ASSERT(nParaIndex >= 0, + "AccessibleEditableTextPara::implGetLineBoundary: paragraph index value overflow"); - const sal_Int32 nLineCount=rCacheTF.GetLineCount( nParaIndex ); + const sal_Int32 nTextLen = rCacheTF.GetTextLen( nParaIndex ); - if( nIndex == nTextLen ) - { - // #i17014# Special-casing one-behind-the-end character - if( nLineCount <= 1 ) - rBoundary.startPos = 0; - else - rBoundary.startPos = nTextLen - rCacheTF.GetLineLen( nParaIndex, - nLineCount-1 ); + CheckPosition(nIndex); - rBoundary.endPos = nTextLen; - } + rBoundary.startPos = rBoundary.endPos = -1; + + const sal_Int32 nLineCount=rCacheTF.GetLineCount( nParaIndex ); + + if( nIndex == nTextLen ) + { + // #i17014# Special-casing one-behind-the-end character + if( nLineCount <= 1 ) + rBoundary.startPos = 0; else + rBoundary.startPos = nTextLen - rCacheTF.GetLineLen( nParaIndex, + nLineCount-1 ); + + rBoundary.endPos = nTextLen; + } + else + { + // normal line search + sal_Int32 nLine; + sal_Int32 nCurIndex; + for( nLine=0, nCurIndex=0; nLine<nLineCount; ++nLine ) { - // normal line search - sal_Int32 nLine; - sal_Int32 nCurIndex; - for( nLine=0, nCurIndex=0; nLine<nLineCount; ++nLine ) - { - nCurIndex += rCacheTF.GetLineLen( nParaIndex, nLine); + nCurIndex += rCacheTF.GetLineLen( nParaIndex, nLine); - if( nCurIndex > nIndex ) - { - rBoundary.startPos = nCurIndex - rCacheTF.GetLineLen( nParaIndex, nLine); - rBoundary.endPos = nCurIndex; - break; - } + if( nCurIndex > nIndex ) + { + rBoundary.startPos = nCurIndex - rCacheTF.GetLineLen( nParaIndex, nLine); + rBoundary.endPos = nCurIndex; + break; } } } +} - void AccessibleEditableTextPara::SetIndexInParent( sal_Int32 nIndex ) - { - mnIndexInParent = nIndex; - } +void AccessibleEditableTextPara::SetIndexInParent( sal_Int32 nIndex ) +{ + mnIndexInParent = nIndex; +} - void AccessibleEditableTextPara::SetParagraphIndex( sal_Int32 nIndex ) - { - sal_Int32 nOldIndex = mnParagraphIndex; +void AccessibleEditableTextPara::SetParagraphIndex( sal_Int32 nIndex ) +{ + sal_Int32 nOldIndex = mnParagraphIndex; - mnParagraphIndex = nIndex; + mnParagraphIndex = nIndex; - auto aChild( maImageBullet.get() ); - if( aChild.is() ) - aChild->SetParagraphIndex(mnParagraphIndex); + auto aChild( maImageBullet.get() ); + if( aChild.is() ) + aChild->SetParagraphIndex(mnParagraphIndex); - try + try + { + if( nOldIndex != nIndex ) { - if( nOldIndex != nIndex ) - { - uno::Any aOldDesc; - uno::Any aOldName; + uno::Any aOldDesc; + uno::Any aOldName; - try - { - aOldDesc <<= getAccessibleDescription(); - aOldName <<= getAccessibleName(); - } - catch (const uno::Exception&) // optional behaviour - { - } - // index and therefore description changed - FireEvent( AccessibleEventId::DESCRIPTION_CHANGED, uno::Any( getAccessibleDescription() ), aOldDesc ); - FireEvent( AccessibleEventId::NAME_CHANGED, uno::Any( getAccessibleName() ), aOldName ); + try + { + aOldDesc <<= getAccessibleDescription(); + aOldName <<= getAccessibleName(); } - } - catch (const uno::Exception&) // optional behaviour - { + catch (const uno::Exception&) // optional behaviour + { + } + // index and therefore description changed + FireEvent( AccessibleEventId::DESCRIPTION_CHANGED, uno::Any( getAccessibleDescription() ), aOldDesc ); + FireEvent( AccessibleEventId::NAME_CHANGED, uno::Any( getAccessibleName() ), aOldName ); } } - - - void AccessibleEditableTextPara::Dispose() + catch (const uno::Exception&) // optional behaviour { - int nClientId( getNotifierClientId() ); + } +} - // #108212# drop all references before notifying dispose - mxParent = nullptr; - mnNotifierClientId = -1; - mpEditSource = nullptr; - // notify listeners - if( nClientId == -1 ) - return; +void AccessibleEditableTextPara::Dispose() +{ + int nClientId( getNotifierClientId() ); - try - { - uno::Reference < XAccessibleContext > xThis = getAccessibleContext(); + // #108212# drop all references before notifying dispose + mxParent = nullptr; + mnNotifierClientId = -1; + mpEditSource = nullptr; - // #106234# Delegate to EventNotifier - ::comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( nClientId, xThis ); - } - catch (const uno::Exception&) - { - } - } + // notify listeners + if( nClientId == -1 ) + return; - void AccessibleEditableTextPara::SetEditSource( SvxEditSourceAdapter* pEditSource ) + try { - auto aChild( maImageBullet.get() ); - if( aChild.is() ) - aChild->SetEditSource(pEditSource); + uno::Reference < XAccessibleContext > xThis = getAccessibleContext(); - if( !pEditSource ) - { - // going defunc - UnSetState( AccessibleStateType::SHOWING ); - UnSetState( AccessibleStateType::VISIBLE ); - SetState( AccessibleStateType::INVALID ); - SetState( AccessibleStateType::DEFUNC ); - - Dispose(); - } - mpEditSource = pEditSource; - // #108900# Init last text content - try - { - TextChanged(); - } - catch (const uno::RuntimeException&) - { - } + // #106234# Delegate to EventNotifier + ::comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( nClientId, xThis ); } - - ESelection AccessibleEditableTextPara::MakeSelection( sal_Int32 nStartEEIndex, sal_Int32 nEndEEIndex ) + catch (const uno::Exception&) { - // check overflow - DBG_ASSERT(nStartEEIndex >= 0 && - nEndEEIndex >= 0 && - GetParagraphIndex() >= 0, - "AccessibleEditableTextPara::MakeSelection: index value overflow"); - - sal_Int32 nParaIndex = GetParagraphIndex(); - return ESelection(nParaIndex, nStartEEIndex, nParaIndex, nEndEEIndex); } +} - ESelection AccessibleEditableTextPara::MakeSelection( sal_Int32 nEEIndex ) - { - return MakeSelection( nEEIndex, nEEIndex+1 ); - } +void AccessibleEditableTextPara::SetEditSource( SvxEditSourceAdapter* pEditSource ) +{ + auto aChild( maImageBullet.get() ); + if( aChild.is() ) + aChild->SetEditSource(pEditSource); - ESelection AccessibleEditableTextPara::MakeCursor( sal_Int32 nEEIndex ) + if( !pEditSource ) { - return MakeSelection( nEEIndex, nEEIndex ); - } + // going defunc + UnSetState( AccessibleStateType::SHOWING ); + UnSetState( AccessibleStateType::VISIBLE ); + SetState( AccessibleStateType::INVALID ); + SetState( AccessibleStateType::DEFUNC ); - void AccessibleEditableTextPara::CheckIndex( sal_Int32 nIndex ) - { - if( nIndex < 0 || nIndex >= getCharacterCount() ) - throw lang::IndexOutOfBoundsException(u"AccessibleEditableTextPara: character index out of bounds"_ustr, - getXWeak() ); + Dispose(); } - - void AccessibleEditableTextPara::CheckPosition( sal_Int32 nIndex ) + mpEditSource = pEditSource; + // #108900# Init last text content + try { - if( nIndex < 0 || nIndex > getCharacterCount() ) - throw lang::IndexOutOfBoundsException(u"AccessibleEditableTextPara: character position out of bounds"_ustr, - getXWeak() ); + TextChanged(); } - - void AccessibleEditableTextPara::CheckRange( sal_Int32 nStart, sal_Int32 nEnd ) + catch (const uno::RuntimeException&) { - CheckPosition( nStart ); - CheckPosition( nEnd ); } +} - bool AccessibleEditableTextPara::GetSelection(sal_Int32 &nStartPos, sal_Int32 &nEndPos) - { - ESelection aSelection; - sal_Int32 nPara = GetParagraphIndex(); - if( !GetEditViewForwarder().GetSelection( aSelection ) ) - return false; +ESelection AccessibleEditableTextPara::MakeSelection( sal_Int32 nStartEEIndex, sal_Int32 nEndEEIndex ) +{ + // check overflow + DBG_ASSERT(nStartEEIndex >= 0 && + nEndEEIndex >= 0 && + GetParagraphIndex() >= 0, + "AccessibleEditableTextPara::MakeSelection: index value overflow"); + + sal_Int32 nParaIndex = GetParagraphIndex(); + return ESelection(nParaIndex, nStartEEIndex, nParaIndex, nEndEEIndex); +} - if( aSelection.start.nPara < aSelection.end.nPara ) - { - if( aSelection.start.nPara > nPara || - aSelection.end.nPara < nPara ) - return false; +ESelection AccessibleEditableTextPara::MakeSelection( sal_Int32 nEEIndex ) +{ + return MakeSelection( nEEIndex, nEEIndex+1 ); +} - if( nPara == aSelection.start.nPara ) - nStartPos = aSelection.start.nIndex; - else - nStartPos = 0; +ESelection AccessibleEditableTextPara::MakeCursor( sal_Int32 nEEIndex ) +{ + return MakeSelection( nEEIndex, nEEIndex ); +} - if( nPara == aSelection.end.nPara ) - nEndPos = aSelection.end.nIndex; - else - nEndPos = GetTextLen(); - } - else - { - if( aSelection.start.nPara < nPara || - aSelection.end.nPara > nPara ) - return false; +void AccessibleEditableTextPara::CheckIndex( sal_Int32 nIndex ) +{ + if( nIndex < 0 || nIndex >= getCharacterCount() ) + throw lang::IndexOutOfBoundsException(u"AccessibleEditableTextPara: character index out of bounds"_ustr, + getXWeak() ); +} - if( nPara == aSelection.start.nPara ) - nStartPos = aSelection.start.nIndex; - else - nStartPos = GetTextLen(); +void AccessibleEditableTextPara::CheckPosition( sal_Int32 nIndex ) +{ + if( nIndex < 0 || nIndex > getCharacterCount() ) + throw lang::IndexOutOfBoundsException(u"AccessibleEditableTextPara: character position out of bounds"_ustr, + getXWeak() ); +} - if( nPara == aSelection.end.nPara ) - nEndPos = aSelection.end.nIndex; - else - nEndPos = 0; - } +void AccessibleEditableTextPara::CheckRange( sal_Int32 nStart, sal_Int32 nEnd ) +{ + CheckPosition( nStart ); + CheckPosition( nEnd ); +} - return true; - } +bool AccessibleEditableTextPara::GetSelection(sal_Int32 &nStartPos, sal_Int32 &nEndPos) +{ + ESelection aSelection; + sal_Int32 nPara = GetParagraphIndex(); + if( !GetEditViewForwarder().GetSelection( aSelection ) ) + return false; - OUString AccessibleEditableTextPara::GetTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) + if( aSelection.start.nPara < aSelection.end.nPara ) { - return GetTextForwarder().GetText( MakeSelection(nStartIndex, nEndIndex) ); - } + if( aSelection.start.nPara > nPara || + aSelection.end.nPara < nPara ) + return false; - sal_Int32 AccessibleEditableTextPara::GetTextLen() const - { - return GetTextForwarder().GetTextLen(GetParagraphIndex()); - } + if( nPara == aSelection.start.nPara ) + nStartPos = aSelection.start.nIndex; + else + nStartPos = 0; - SvxEditSourceAdapter& AccessibleEditableTextPara::GetEditSource() const - { - if( !mpEditSource ) - throw uno::RuntimeException(u"No edit source, object is defunct"_ustr, - const_cast< AccessibleEditableTextPara* > (this)->getXWeak() ); - return *mpEditSource; + if( nPara == aSelection.end.nPara ) + nEndPos = aSelection.end.nIndex; + else + nEndPos = GetTextLen(); } - - SvxAccessibleTextAdapter& AccessibleEditableTextPara::GetTextForwarder() const + else { - SvxEditSourceAdapter& rEditSource = GetEditSource(); - SvxAccessibleTextAdapter* pTextForwarder = rEditSource.GetTextForwarderAdapter(); + if( aSelection.start.nPara < nPara || + aSelection.end.nPara > nPara ) + return false; - if( !pTextForwarder ) - throw uno::RuntimeException(u"Unable to fetch text forwarder, object is defunct"_ustr, - const_cast< AccessibleEditableTextPara* > (this)->getXWeak() ); + if( nPara == aSelection.start.nPara ) + nStartPos = aSelection.start.nIndex; + else + nStartPos = GetTextLen(); - if( !pTextForwarder->IsValid() ) - throw uno::RuntimeException(u"Text forwarder is invalid, object is defunct"_ustr, - const_cast< AccessibleEditableTextPara* > (this)->getXWeak() ); - return *pTextForwarder; + if( nPara == aSelection.end.nPara ) + nEndPos = aSelection.end.nIndex; + else + nEndPos = 0; } - SvxViewForwarder& AccessibleEditableTextPara::GetViewForwarder() const + return true; +} + +OUString AccessibleEditableTextPara::GetTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) +{ + return GetTextForwarder().GetText( MakeSelection(nStartIndex, nEndIndex) ); +} + +sal_Int32 AccessibleEditableTextPara::GetTextLen() const +{ + return GetTextForwarder().GetTextLen(GetParagraphIndex()); +} + +SvxEditSourceAdapter& AccessibleEditableTextPara::GetEditSource() const +{ + if( !mpEditSource ) + throw uno::RuntimeException(u"No edit source, object is defunct"_ustr, + const_cast< AccessibleEditableTextPara* > (this)->getXWeak() ); + return *mpEditSource; +} + +SvxAccessibleTextAdapter& AccessibleEditableTextPara::GetTextForwarder() const +{ + SvxEditSourceAdapter& rEditSource = GetEditSource(); + SvxAccessibleTextAdapter* pTextForwarder = rEditSource.GetTextForwarderAdapter(); + + if( !pTextForwarder ) + throw uno::RuntimeException(u"Unable to fetch text forwarder, object is defunct"_ustr, + const_cast< AccessibleEditableTextPara* > (this)->getXWeak() ); + + if( !pTextForwarder->IsValid() ) + throw uno::RuntimeException(u"Text forwarder is invalid, object is defunct"_ustr, + const_cast< AccessibleEditableTextPara* > (this)->getXWeak() ); + return *pTextForwarder; +} + +SvxViewForwarder& AccessibleEditableTextPara::GetViewForwarder() const +{ + SvxEditSource& rEditSource = GetEditSource(); + SvxViewForwarder* pViewForwarder = rEditSource.GetViewForwarder(); + + if( !pViewForwarder ) { - SvxEditSource& rEditSource = GetEditSource(); - SvxViewForwarder* pViewForwarder = rEditSource.GetViewForwarder(); + throw uno::RuntimeException(u"Unable to fetch view forwarder, object is defunct"_ustr, + const_cast< AccessibleEditableTextPara* > (this)->getXWeak() ); + } - if( !pViewForwarder ) - { + if( !pViewForwarder->IsValid() ) + throw uno::RuntimeException(u"View forwarder is invalid, object is defunct"_ustr, + const_cast< AccessibleEditableTextPara* > (this)->getXWeak() ); + return *pViewForwarder; +} + +SvxAccessibleTextEditViewAdapter& AccessibleEditableTextPara::GetEditViewForwarder( bool bCreate ) const +{ + SvxEditSourceAdapter& rEditSource = GetEditSource(); + SvxAccessibleTextEditViewAdapter* pTextEditViewForwarder = rEditSource.GetEditViewForwarderAdapter( bCreate ); + + if( !pTextEditViewForwarder ) + { + if( bCreate ) throw uno::RuntimeException(u"Unable to fetch view forwarder, object is defunct"_ustr, const_cast< AccessibleEditableTextPara* > (this)->getXWeak() ); - } - - if( !pViewForwarder->IsValid() ) - throw uno::RuntimeException(u"View forwarder is invalid, object is defunct"_ustr, + else + throw uno::RuntimeException(u"No view forwarder, object not in edit mode"_ustr, const_cast< AccessibleEditableTextPara* > (this)->getXWeak() ); - return *pViewForwarder; } - SvxAccessibleTextEditViewAdapter& AccessibleEditableTextPara::GetEditViewForwarder( bool bCreate ) const + if( pTextEditViewForwarder->IsValid() ) + return *pTextEditViewForwarder; + else { - SvxEditSourceAdapter& rEditSource = GetEditSource(); - SvxAccessibleTextEditViewAdapter* pTextEditViewForwarder = rEditSource.GetEditViewForwarderAdapter( bCreate ); - - if( !pTextEditViewForwarder ) - { - if( bCreate ) - throw uno::RuntimeException(u"Unable to fetch view forwarder, object is defunct"_ustr, - const_cast< AccessibleEditableTextPara* > (this)->getXWeak() ); - else - throw uno::RuntimeException(u"No view forwarder, object not in edit mode"_ustr, - const_cast< AccessibleEditableTextPara* > (this)->getXWeak() ); - } - - if( pTextEditViewForwarder->IsValid() ) - return *pTextEditViewForwarder; + if( bCreate ) + throw uno::RuntimeException(u"View forwarder is invalid, object is defunct"_ustr, + const_cast< AccessibleEditableTextPara* > (this)->getXWeak() ); else - { - if( bCreate ) - throw uno::RuntimeException(u"View forwarder is invalid, object is defunct"_ustr, - const_cast< AccessibleEditableTextPara* > (this)->getXWeak() ); - else - throw uno::RuntimeException(u"View forwarder is invalid, object not in edit mode"_ustr, - const_cast< AccessibleEditableTextPara* > (this)->getXWeak() ); - } + throw uno::RuntimeException(u"View forwarder is invalid, object not in edit mode"_ustr, + const_cast< AccessibleEditableTextPara* > (this)->getXWeak() ); } +} - bool AccessibleEditableTextPara::HaveEditView() const - { - SvxEditSource& rEditSource = GetEditSource(); - SvxEditViewForwarder* pViewForwarder = rEditSource.GetEditViewForwarder(); +bool AccessibleEditableTextPara::HaveEditView() const +{ + SvxEditSource& rEditSource = GetEditSource(); + SvxEditViewForwarder* pViewForwarder = rEditSource.GetEditViewForwarder(); - if( !pViewForwarder ) - return false; + if( !pViewForwarder ) + return false; - if( !pViewForwarder->IsValid() ) - return false; + if( !pViewForwarder->IsValid() ) + return false; - return true; - } + return true; +} - bool AccessibleEditableTextPara::HaveChildren() - { - DBG_ASSERT(GetParagraphIndex() >= 0, - "AccessibleEditableTextPara::HaveChildren: paragraph index value overflow"); +bool AccessibleEditableTextPara::HaveChildren() +{ + DBG_ASSERT(GetParagraphIndex() >= 0, + "AccessibleEditableTextPara::HaveChildren: paragraph index value overflow"); - return GetTextForwarder().HaveImageBullet( GetParagraphIndex() ); - } + return GetTextForwarder().HaveImageBullet( GetParagraphIndex() ); +} - tools::Rectangle AccessibleEditableTextPara::LogicToPixel( const tools::Rectangle& rRect, const MapMode& rMapMode, SvxViewForwarder const & rForwarder ) - { - // convert to screen coordinates - return tools::Rectangle( rForwarder.LogicToPixel( rRect.TopLeft(), rMapMode ), - rForwarder.LogicToPixel( rRect.BottomRight(), rMapMode ) ); - } +tools::Rectangle AccessibleEditableTextPara::LogicToPixel( const tools::Rectangle& rRect, const MapMode& rMapMode, SvxViewForwarder const & rForwarder ) +{ + // convert to screen coordinates + return tools::Rectangle( rForwarder.LogicToPixel( rRect.TopLeft(), rMapMode ), + rForwarder.LogicToPixel( rRect.BottomRight(), rMapMode ) ); +} - void AccessibleEditableTextPara::SetEEOffset( const Point& rOffset ) - { - auto aChild( maImageBullet.get() ); - if( aChild.is() ) - aChild->SetEEOffset(rOffset); +void AccessibleEditableTextPara::SetEEOffset( const Point& rOffset ) +{ + auto aChild( maImageBullet.get() ); + if( aChild.is() ) + aChild->SetEEOffset(rOffset); - maEEOffset = rOffset; - } + maEEOffset = rOffset; +} - void AccessibleEditableTextPara::FireEvent(const sal_Int16 nEventId, const uno::Any& rNewValue, const uno::Any& rOldValue) const - { - uno::Reference < XAccessibleContext > xThis( const_cast< AccessibleEditableTextPara* > (this)->getAccessibleContext() ); +void AccessibleEditableTextPara::FireEvent(const sal_Int16 nEventId, const uno::Any& rNewValue, const uno::Any& rOldValue) const +{ + uno::Reference < XAccessibleContext > xThis( const_cast< AccessibleEditableTextPara* > (this)->getAccessibleContext() ); - AccessibleEventObject aEvent(xThis, nEventId, rNewValue, rOldValue, -1); + AccessibleEventObject aEvent(xThis, nEventId, rNewValue, rOldValue, -1); - // #106234# Delegate to EventNotifier - if( getNotifierClientId() != -1 ) - ::comphelper::AccessibleEventNotifier::addEvent( getNotifierClientId(), - aEvent ); - } + // #106234# Delegate to EventNotifier + if( getNotifierClientId() != -1 ) + ::comphelper::AccessibleEventNotifier::addEvent( getNotifierClientId(), + aEvent ); +} - void AccessibleEditableTextPara::SetState( const sal_Int64 nStateId ) +void AccessibleEditableTextPara::SetState( const sal_Int64 nStateId ) +{ + if( !(mnStateSet & nStateId) ) { - if( !(mnStateSet & nStateId) ) - { - mnStateSet |= nStateId; - FireEvent( AccessibleEventId::STATE_CHANGED, uno::Any( nStateId ) ); - } + mnStateSet |= nStateId; + FireEvent( AccessibleEventId::STATE_CHANGED, uno::Any( nStateId ) ); } +} - void AccessibleEditableTextPara::UnSetState( const sal_Int64 nStateId ) +void AccessibleEditableTextPara::UnSetState( const sal_Int64 nStateId ) +{ + if( mnStateSet & nStateId ) { - if( mnStateSet & nStateId ) - { - mnStateSet &= ~nStateId; - FireEvent( AccessibleEventId::STATE_CHANGED, uno::Any(), uno::Any( nStateId ) ); - } + mnStateSet &= ~nStateId; + FireEvent( AccessibleEventId::STATE_CHANGED, uno::Any(), uno::Any( nStateId ) ); } +} - void AccessibleEditableTextPara::TextChanged() +void AccessibleEditableTextPara::TextChanged() +{ + OUString aCurrentString( implGetText() ); + uno::Any aDeleted; + uno::Any aInserted; + if( OCommonAccessibleText::implInitTextChangedEvent( maLastTextString, aCurrentString, + aDeleted, aInserted) ) { - OUString aCurrentString( implGetText() ); - uno::Any aDeleted; - uno::Any aInserted; - if( OCommonAccessibleText::implInitTextChangedEvent( maLastTextString, aCurrentString, - aDeleted, aInserted) ) - { - FireEvent( AccessibleEventId::TEXT_CHANGED, aInserted, aDeleted ); - maLastTextString = aCurrentString; - } + FireEvent( AccessibleEventId::TEXT_CHANGED, aInserted, aDeleted ); + maLastTextString = aCurrentString; } +} - bool AccessibleEditableTextPara::GetAttributeRun( sal_Int32& nStartIndex, sal_Int32& nEndIndex, sal_Int32 nIndex ) - { - DBG_ASSERT(nIndex >= 0, - "AccessibleEditableTextPara::GetAttributeRun: index value overflow"); - - DBG_ASSERT(GetParagraphIndex() >= 0, - "AccessibleEditableTextPara::getLocale: paragraph index value overflow"); +bool AccessibleEditableTextPara::GetAttributeRun( sal_Int32& nStartIndex, sal_Int32& nEndIndex, sal_Int32 nIndex ) +{ + DBG_ASSERT(nIndex >= 0, + "AccessibleEditableTextPara::GetAttributeRun: index value overflow"); - return GetTextForwarder().GetAttributeRun( nStartIndex, - nEndIndex, - GetParagraphIndex(), - nIndex ); - } + DBG_ASSERT(GetParagraphIndex() >= 0, + "AccessibleEditableTextPara::getLocale: paragraph index value overflow"); - uno::Any SAL_CALL AccessibleEditableTextPara::queryInterface (const uno::Type & rType) - { - uno::Any aRet; + return GetTextForwarder().GetAttributeRun( nStartIndex, + nEndIndex, + GetParagraphIndex(), + nIndex ); +} - // must provide XAccessibleText by hand, since it comes publicly inherited by XAccessibleEditableText - if ( rType == cppu::UnoType<XAccessibleText>::get()) - { - uno::Reference< XAccessibleText > aAccText = static_cast< XAccessibleEditableText * >(this); - aRet <<= aAccText; - } - else if ( rType == cppu::UnoType<XAccessibleEditableText>::get()) - { - uno::Reference< XAccessibleEditableText > aAccEditText = this; - aRet <<= aAccEditText; - } - else if ( rType == cppu::UnoType<XAccessibleHypertext>::get()) - { - uno::Reference< XAccessibleHypertext > aAccHyperText = this; - aRet <<= aAccHyperText; - } - else - { - aRet = AccessibleTextParaInterfaceBase::queryInterface(rType); - } +uno::Any SAL_CALL AccessibleEditableTextPara::queryInterface (const uno::Type & rType) +{ + uno::Any aRet; - return aRet; + // must provide XAccessibleText by hand, since it comes publicly inherited by XAccessibleEditableText + if ( rType == cppu::UnoType<XAccessibleText>::get()) + { + uno::Reference< XAccessibleText > aAccText = static_cast< XAccessibleEditableText * >(this); + aRet <<= aAccText; } - - // XAccessible - uno::Reference< XAccessibleContext > SAL_CALL AccessibleEditableTextPara::getAccessibleContext() + else if ( rType == cppu::UnoType<XAccessibleEditableText>::get()) { - // We implement the XAccessibleContext interface in the same object - return uno::Reference< XAccessibleContext > ( this ); + uno::Reference< XAccessibleEditableText > aAccEditText = this; + aRet <<= aAccEditText; } - - // XAccessibleContext - sal_Int64 SAL_CALL AccessibleEditableTextPara::getAccessibleChildCount() + else if ( rType == cppu::UnoType<XAccessibleHypertext>::get()) { - SolarMutexGuard aGuard; - - return HaveChildren() ? 1 : 0; + uno::Reference< XAccessibleHypertext > aAccHyperText = this; + aRet <<= aAccHyperText; } - - uno::Reference< XAccessible > SAL_CALL AccessibleEditableTextPara::getAccessibleChild( sal_Int64 i ) + else { - SolarMutexGuard aGuard; + aRet = AccessibleTextParaInterfaceBase::queryInterface(rType); + } - if( !HaveChildren() ) - throw lang::IndexOutOfBoundsException(u"No children available"_ustr, - getXWeak() ); + return aRet; +} - if( i != 0 ) - throw lang::IndexOutOfBoundsException(u"Invalid child index"_ustr, - getXWeak() ); +// XAccessible +uno::Reference< XAccessibleContext > SAL_CALL AccessibleEditableTextPara::getAccessibleContext() +{ + // We implement the XAccessibleContext interface in the same object + return uno::Reference< XAccessibleContext > ( this ); +} - auto aChild( maImageBullet.get() ); +// XAccessibleContext +sal_Int64 SAL_CALL AccessibleEditableTextPara::getAccessibleChildCount() +{ + SolarMutexGuard aGuard; - if( !aChild.is() ) - { - // there is no hard reference available, create object then - aChild = new AccessibleImageBullet(this); + return HaveChildren() ? 1 : 0; +} - aChild->SetEditSource( &GetEditSource() ); - aChild->SetParagraphIndex( GetParagraphIndex() ); - aChild->SetIndexInParent( i ); +uno::Reference< XAccessible > SAL_CALL AccessibleEditableTextPara::getAccessibleChild( sal_Int64 i ) +{ + SolarMutexGuard aGuard; - maImageBullet = aChild; - } + if( !HaveChildren() ) + throw lang::IndexOutOfBoundsException(u"No children available"_ustr, + getXWeak() ); - return aChild; - } + if( i != 0 ) + throw lang::IndexOutOfBoundsException(u"Invalid child index"_ustr, + getXWeak() ); - uno::Reference< XAccessible > SAL_CALL AccessibleEditableTextPara::getAccessibleParent() - { - SAL_WARN_IF(!mxParent.is(), "editeng", "AccessibleEditableTextPara::getAccessibleParent: no frontend set, did somebody forgot to call AccessibleTextHelper::SetEventSource()?"); - - return mxParent; - } + auto aChild( maImageBullet.get() ); - sal_Int64 SAL_CALL AccessibleEditableTextPara::getAccessibleIndexInParent() + if( !aChild.is() ) { - return mnIndexInParent; - } + // there is no hard reference available, create object then + aChild = new AccessibleImageBullet(this); - sal_Int16 SAL_CALL AccessibleEditableTextPara::getAccessibleRole() - { - return AccessibleRole::PARAGRAPH; - } + aChild->SetEditSource( &GetEditSource() ); + aChild->SetParagraphIndex( GetParagraphIndex() ); + aChild->SetIndexInParent( i ); - OUString SAL_CALL AccessibleEditableTextPara::getAccessibleDescription() - { - return OUString(); + maImageBullet = aChild; } - OUString SAL_CALL AccessibleEditableTextPara::getAccessibleName() - { - //See tdf#101003 before implementing a body - return OUString(); - } + return aChild; +} - uno::Reference< XAccessibleRelationSet > SAL_CALL AccessibleEditableTextPara::getAccessibleRelationSet() - { - // #i27138# - provide relations CONTENT_FLOWS_FROM - // and CONTENT_FLOWS_TO - if ( mpParaManager ) - { - rtl::Reference<utl::AccessibleRelationSetHelper> pAccRelSetHelper = - new utl::AccessibleRelationSetHelper(); - sal_Int32 nMyParaIndex( GetParagraphIndex() ); - // relation CONTENT_FLOWS_FROM - if ( nMyParaIndex > 0 && - mpParaManager->IsReferencable( nMyParaIndex - 1 ) ) - { - uno::Sequence<uno::Reference<XAccessible>> aSequence - { mpParaManager->GetChild( nMyParaIndex - 1 ).first.get() }; - AccessibleRelation aAccRel(AccessibleRelationType_CONTENT_FLOWS_FROM, - aSequence ); - pAccRelSetHelper->AddRelation( aAccRel ); - } +uno::Reference< XAccessible > SAL_CALL AccessibleEditableTextPara::getAccessibleParent() +{ + SAL_WARN_IF(!mxParent.is(), "editeng", "AccessibleEditableTextPara::getAccessibleParent: no frontend set, did somebody forgot to call AccessibleTextHelper::SetEventSource()?"); - // relation CONTENT_FLOWS_TO - if ( (nMyParaIndex + 1) < mpParaManager->GetNum() && - mpParaManager->IsReferencable( nMyParaIndex + 1 ) ) - { - uno::Sequence<uno::Reference<XAccessible>> aSequence - { mpParaManager->GetChild( nMyParaIndex + 1 ).first.get() }; - AccessibleRelation aAccRel(AccessibleRelationType_CONTENT_FLOWS_TO, - aSequence ); - pAccRelSetHelper->AddRelation( aAccRel ); - } + return mxParent; +} - return pAccRelSetHelper; - } - else - { - // no relations, therefore empty - return uno::Reference< XAccessibleRelationSet >(); - } - } +sal_Int64 SAL_CALL AccessibleEditableTextPara::getAccessibleIndexInParent() +{ + return mnIndexInParent; +} - static uno::Sequence< OUString > const & getAttributeNames() - { - static const uno::Sequence<OUString> aNames{ - u"CharColor"_ustr, - u"CharContoured"_ustr, - u"CharEmphasis"_ustr, - u"CharEscapement"_ustr, - u"CharFontName"_ustr, - u"CharHeight"_ustr, - u"CharPosture"_ustr, - u"CharShadowed"_ustr, - u"CharStrikeout"_ustr, - u"CharCaseMap"_ustr, - u"CharUnderline"_ustr, - u"CharUnderlineColor"_ustr, - u"CharWeight"_ustr, - u"NumberingLevel"_ustr, - u"NumberingRules"_ustr, - u"ParaAdjust"_ustr, - u"ParaBottomMargin"_ustr, - u"ParaFirstLineIndent"_ustr, - u"ParaLeftMargin"_ustr, - u"ParaLineSpacing"_ustr, - u"ParaRightMargin"_ustr, - u"ParaTabStops"_ustr}; - - return aNames; - } - - namespace { - - struct IndexCompare - { - const uno::Sequence<beans::PropertyValue>& m_rValues; - explicit IndexCompare(const uno::Sequence<beans::PropertyValue>& rValues) - : m_rValues(rValues) - { - } - bool operator() ( sal_Int32 a, sal_Int32 b ) const - { - return m_rValues[a].Name < m_rValues[b].Name; - } - }; +sal_Int16 SAL_CALL AccessibleEditableTextPara::getAccessibleRole() +{ + return AccessibleRole::PARAGRAPH; +} - } +OUString SAL_CALL AccessibleEditableTextPara::getAccessibleDescription() +{ + return OUString(); } -namespace +OUString SAL_CALL AccessibleEditableTextPara::getAccessibleName() { - OUString GetFieldTypeNameFromField(EFieldInfo const &ree) - { - OUString strFldType; - sal_Int32 nFieldType = -1; - if (ree.pFieldItem) - { - // So we get a field, check its type now. - nFieldType = ree.pFieldItem->GetField()->GetClassId() ; - } - switch (nFieldType) - { - case text::textfield::Type::DATE: - { - const SvxDateField* pDateField = static_cast< const SvxDateField* >(ree.pFieldItem->GetField()); - if (pDateField) - { - if (pDateField->GetType() == SvxDateType::Fix) - strFldType = "date (fixed)"; - else if (pDateField->GetType() == SvxDateType::Var) - strFldType = "date (variable)"; - } - break; - } - case text::textfield::Type::PAGE: - strFldType = "page-number"; - break; - //support the sheet name & pages fields - case text::textfield::Type::PAGES: - strFldType = "page-count"; - break; - case text::textfield::Type::TABLE: - strFldType = "sheet-name"; - break; - //End - case text::textfield::Type::TIME: - strFldType = "time"; - break; - case text::textfield::Type::EXTENDED_TIME: - { - const SvxExtTimeField* pTimeField = static_cast< const SvxExtTimeField* >(ree.pFieldItem->GetField()); - if (pTimeField) - { - if (pTimeField->GetType() == SvxTimeType::Fix) - strFldType = "time (fixed)"; - else if (pTimeField->GetType() == SvxTimeType::Var) - strFldType = "time (variable)"; - } - break; - } - case text::textfield::Type::AUTHOR: - strFldType = "author"; - break; - case text::textfield::Type::EXTENDED_FILE: - case text::textfield::Type::DOCINFO_TITLE: - strFldType = "file name"; - break; - case text::textfield::Type::DOCINFO_CUSTOM: - strFldType = "custom document property"; - break; - default: - break; - } - return strFldType; - } + //See tdf#101003 before implementing a body + return OUString(); } -namespace accessibility +uno::Reference< XAccessibleRelationSet > SAL_CALL AccessibleEditableTextPara::getAccessibleRelationSet() { - OUString AccessibleEditableTextPara::GetFieldTypeNameAtIndex(sal_Int32 nIndex) + // #i27138# - provide relations CONTENT_FLOWS_FROM + // and CONTENT_FLOWS_TO + if ( mpParaManager ) { - SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); - //For field object info - sal_Int32 nParaIndex = GetParagraphIndex(); - sal_Int32 nAllFieldLen = 0; - std::vector<EFieldInfo> aFieldInfos = rCacheTF.GetFieldInfo(nParaIndex); - for (const EFieldInfo& ree : aFieldInfos) + rtl::Reference<utl::AccessibleRelationSetHelper> pAccRelSetHelper = + new utl::AccessibleRelationSetHelper(); + sal_Int32 nMyParaIndex( GetParagraphIndex() ); + // relation CONTENT_FLOWS_FROM + if ( nMyParaIndex > 0 && + mpParaManager->IsReferencable( nMyParaIndex - 1 ) ) { - sal_Int32 reeBegin = ree.aPosition.nIndex + nAllFieldLen; - sal_Int32 reeEnd = reeBegin + ree.aCurrentText.getLength(); - nAllFieldLen += (ree.aCurrentText.getLength() - 1); - if (nIndex < reeBegin) - break; - if (nIndex < reeEnd) - return GetFieldTypeNameFromField(ree); + uno::Sequence<uno::Reference<XAccessible>> aSequence + { mpParaManager->GetChild( nMyParaIndex - 1 ).first.get() }; + AccessibleRelation aAccRel(AccessibleRelationType_CONTENT_FLOWS_FROM, + aSequence ); + pAccRelSetHelper->AddRelation( aAccRel ); } - return OUString(); - } - sal_Int64 SAL_CALL AccessibleEditableTextPara::getAccessibleStateSet() - { - SolarMutexGuard aGuard; - - // Create a copy of the state set and return it. - - sal_Int64 nParentStates = 0; - if (getAccessibleParent().is()) - { - uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext(); - nParentStates = xParentContext->getAccessibleStateSet(); - } - if (nParentStates & AccessibleStateType::EDITABLE) + // relation CONTENT_FLOWS_TO + if ( (nMyParaIndex + 1) < mpParaManager->GetNum() && + mpParaManager->IsReferencable( nMyParaIndex + 1 ) ) { - mnStateSet |= AccessibleStateType::EDITABLE; + uno::Sequence<uno::Reference<XAccessible>> aSequence + { mpParaManager->GetChild( nMyParaIndex + 1 ).first.get() }; + AccessibleRelation aAccRel(AccessibleRelationType_CONTENT_FLOWS_TO, + aSequence ); + pAccRelSetHelper->AddRelation( aAccRel ); } - return mnStateSet; - } - lang::Locale SAL_CALL AccessibleEditableTextPara::getLocale() + return pAccRelSetHelper; + } + else { - SolarMutexGuard aGuard; - - return implGetLocale(); + // no relations, therefore empty + return uno::Reference< XAccessibleRelationSet >(); } +} + +static uno::Sequence< OUString > const & getAttributeNames() +{ + static const uno::Sequence<OUString> aNames{ + u"CharColor"_ustr, + u"CharContoured"_ustr, + u"CharEmphasis"_ustr, + u"CharEscapement"_ustr, + u"CharFontName"_ustr, + u"CharHeight"_ustr, + u"CharPosture"_ustr, + u"CharShadowed"_ustr, + u"CharStrikeout"_ustr, + u"CharCaseMap"_ustr, + u"CharUnderline"_ustr, + u"CharUnderlineColor"_ustr, + u"CharWeight"_ustr, + u"NumberingLevel"_ustr, + u"NumberingRules"_ustr, + u"ParaAdjust"_ustr, + u"ParaBottomMargin"_ustr, + u"ParaFirstLineIndent"_ustr, + u"ParaLeftMargin"_ustr, + u"ParaLineSpacing"_ustr, + u"ParaRightMargin"_ustr, + u"ParaTabStops"_ustr}; + + return aNames; +} - void SAL_CALL AccessibleEditableTextPara::addAccessibleEventListener( const uno::Reference< XAccessibleEventListener >& xListener ) +namespace { + +struct IndexCompare +{ + const uno::Sequence<beans::PropertyValue>& m_rValues; + explicit IndexCompare(const uno::Sequence<beans::PropertyValue>& rValues) + : m_rValues(rValues) { - if( getNotifierClientId() != -1 ) - ::comphelper::AccessibleEventNotifier::addEventListener( getNotifierClientId(), xListener ); } - - void SAL_CALL AccessibleEditableTextPara::removeAccessibleEventListener( const uno::Reference< XAccessibleEventListener >& xListener ) + bool operator() ( sal_Int32 a, sal_Int32 b ) const { - if( getNotifierClientId() == -1 ) - return; + return m_rValues[a].Name < m_rValues[b].Name; + } +}; - const sal_Int32 nListenerCount = ::comphelper::AccessibleEventNotifier::removeEventListener( getNotifierClientId(), xListener ); - if ( !nListenerCount ) +} +} + +namespace +{ +OUString GetFieldTypeNameFromField(EFieldInfo const &ree) +{ + OUString strFldType; + sal_Int32 nFieldType = -1; + if (ree.pFieldItem) + { + // So we get a field, check its type now. + nFieldType = ree.pFieldItem->GetField()->GetClassId() ; + } + switch (nFieldType) + { + case text::textfield::Type::DATE: + { + const SvxDateField* pDateField = static_cast< const SvxDateField* >(ree.pFieldItem->GetField()); + if (pDateField) + { + if (pDateField->GetType() == SvxDateType::Fix) + strFldType = "date (fixed)"; + else if (pDateField->GetType() == SvxDateType::Var) + strFldType = "date (variable)"; + } + break; + } + case text::textfield::Type::PAGE: + strFldType = "page-number"; + break; + //support the sheet name & pages fields + case text::textfield::Type::PAGES: + strFldType = "page-count"; + break; + case text::textfield::Type::TABLE: + strFldType = "sheet-name"; + break; + //End + case text::textfield::Type::TIME: + strFldType = "time"; + break; + case text::textfield::Type::EXTENDED_TIME: { - // 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::TClientId nId( getNotifierClientId() ); - mnNotifierClientId = -1; - ::comphelper::AccessibleEventNotifier::revokeClient( nId ); + const SvxExtTimeField* pTimeField = static_cast< const SvxExtTimeField* >(ree.pFieldItem->GetField()); + if (pTimeField) + { + if (pTimeField->GetType() == SvxTimeType::Fix) + strFldType = "time (fixed)"; + else if (pTimeField->GetType() == SvxTimeType::Var) + strFldType = "time (variable)"; + } + break; } + case text::textfield::Type::AUTHOR: + strFldType = "author"; + break; + case text::textfield::Type::EXTENDED_FILE: + case text::textfield::Type::DOCINFO_TITLE: + strFldType = "file name"; + break; + case text::textfield::Type::DOCINFO_CUSTOM: + strFldType = "custom document property"; + break; + default: + break; } + return strFldType; +} +} - // XAccessibleComponent - sal_Bool SAL_CALL AccessibleEditableTextPara::containsPoint( const awt::Point& aTmpPoint ) - { - SolarMutexGuard aGuard; +namespace accessibility +{ +OUString AccessibleEditableTextPara::GetFieldTypeNameAtIndex(sal_Int32 nIndex) +{ + SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); + //For field object info + sal_Int32 nParaIndex = GetParagraphIndex(); + sal_Int32 nAllFieldLen = 0; + std::vector<EFieldInfo> aFieldInfos = rCacheTF.GetFieldInfo(nParaIndex); + for (const EFieldInfo& ree : aFieldInfos) + { + sal_Int32 reeBegin = ree.aPosition.nIndex + nAllFieldLen; + sal_Int32 reeEnd = reeBegin + ree.aCurrentText.getLength(); + nAllFieldLen += (ree.aCurrentText.getLength() - 1); + if (nIndex < reeBegin) + break; + if (nIndex < reeEnd) + return GetFieldTypeNameFromField(ree); + } + return OUString(); +} - DBG_ASSERT(GetParagraphIndex() >= 0, - "AccessibleEditableTextPara::contains: index value overflow"); +sal_Int64 SAL_CALL AccessibleEditableTextPara::getAccessibleStateSet() +{ + SolarMutexGuard aGuard; - awt::Rectangle aTmpRect = getBounds(); - tools::Rectangle aRect( Point(aTmpRect.X, aTmpRect.Y), Size(aTmpRect.Width, aTmpRect.Height) ); - Point aPoint( aTmpPoint.X, aTmpPoint.Y ); + // Create a copy of the state set and return it. - return aRect.Contains( aPoint ); + sal_Int64 nParentStates = 0; + if (getAccessibleParent().is()) + { + uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext(); + nParentStates = xParentContext->getAccessibleStateSet(); } - - uno::Reference< XAccessible > SAL_CALL AccessibleEditableTextPara::getAccessibleAtPoint( const awt::Point& _aPoint ) + if (nParentStates & AccessibleStateType::EDITABLE) { - SolarMutexGuard aGuard; - - if( HaveChildren() ) - { - // #103862# No longer need to make given position relative - Point aPoint( _aPoint.X, _aPoint.Y ); - - // respect EditEngine offset to surrounding shape/cell - aPoint -= GetEEOffset(); - - // convert to EditEngine coordinate system - SvxTextForwarder& rCacheTF = GetTextForwarder(); - Point aLogPoint( GetViewForwarder().PixelToLogic( aPoint, rCacheTF.GetMapMode() ) ); + mnStateSet |= AccessibleStateType::EDITABLE; + } + return mnStateSet; +} - EBulletInfo aBulletInfo = rCacheTF.GetBulletInfo(GetParagraphIndex()); +lang::Locale SAL_CALL AccessibleEditableTextPara::getLocale() +{ + SolarMutexGuard aGuard; - if( aBulletInfo.nParagraph != EE_PARA_MAX && - aBulletInfo.bVisible && - aBulletInfo.nType == SVX_NUM_BITMAP ) - { - tools::Rectangle aRect = aBulletInfo.aBounds; + return implGetLocale(); +} - if( aRect.Contains( aLogPoint ) ) - return getAccessibleChild(0); - } - } +void SAL_CALL AccessibleEditableTextPara::addAccessibleEventListener( const uno::Reference< XAccessibleEventListener >& xListener ) +{ + if( getNotifierClientId() != -1 ) + ::comphelper::AccessibleEventNotifier::addEventListener( getNotifierClientId(), xListener ); +} - // no children at all, or none at given position - return uno::Reference< XAccessible >(); - } +void SAL_CALL AccessibleEditableTextPara::removeAccessibleEventListener( const uno::Reference< XAccessibleEventListener >& xListener ) +{ + if( getNotifierClientId() == -1 ) + return; - awt::Rectangle SAL_CALL AccessibleEditableTextPara::getBounds() + const sal_Int32 nListenerCount = ::comphelper::AccessibleEventNotifier::removeEventListener( getNotifierClientId(), xListener ); + if ( !nListenerCount ) { - SolarMutexGuard aGuard; + // 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::TClientId nId( getNotifierClientId() ); + mnNotifierClientId = -1; + ::comphelper::AccessibleEventNotifier::revokeClient( nId ); + } +} - DBG_ASSERT(GetParagraphIndex() >= 0, - "AccessibleEditableTextPara::getBounds: index value overflow"); +// XAccessibleComponent +sal_Bool SAL_CALL AccessibleEditableTextPara::containsPoint( const awt::Point& aTmpPoint ) +{ + SolarMutexGuard aGuard; - SvxTextForwarder& rCacheTF = GetTextForwarder(); - tools::Rectangle aRect = rCacheTF.GetParaBounds( GetParagraphIndex() ); + DBG_ASSERT(GetParagraphIndex() >= 0, + "AccessibleEditableTextPara::contains: index value overflow"); - // convert to screen coordinates - tools::Rectangle aScreenRect = AccessibleEditableTextPara::LogicToPixel( aRect, - rCacheTF.GetMapMode(), - GetViewForwarder() ); + awt::Rectangle aTmpRect = getBounds(); + tools::Rectangle aRect( Point(aTmpRect.X, aTmpRect.Y), Size(aTmpRect.Width, aTmpRect.Height) ); + Point aPoint( aTmpPoint.X, aTmpPoint.Y ); - // offset from shape/cell - Point aOffset = GetEEOffset(); + return aRect.Contains( aPoint ); +} - return awt::Rectangle( aScreenRect.Left() + aOffset.X(), - aScreenRect.Top() + aOffset.Y(), - aScreenRect.GetSize().Width(), - aScreenRect.GetSize().Height() ); - } +uno::Reference< XAccessible > SAL_CALL AccessibleEditableTextPara::getAccessibleAtPoint( const awt::Point& _aPoint ) +{ + SolarMutexGuard aGuard; - awt::Point SAL_CALL AccessibleEditableTextPara::getLocation( ) + if( HaveChildren() ) { - SolarMutexGuard aGuard; + // #103862# No longer need to make given position relative + Point aPoint( _aPoint.X, _aPoint.Y ); - awt::Rectangle aRect = getBounds(); + // respect EditEngine offset to surrounding shape/cell + aPoint -= GetEEOffset(); - return awt::Point( aRect.X, aRect.Y ); - } + // convert to EditEngine coordinate system + SvxTextForwarder& rCacheTF = GetTextForwarder(); + Point aLogPoint( GetViewForwarder().PixelToLogic( aPoint, rCacheTF.GetMapMode() ) ); - awt::Point SAL_CALL AccessibleEditableTextPara::getLocationOnScreen( ) - { - SolarMutexGuard aGuard; + EBulletInfo aBulletInfo = rCacheTF.GetBulletInfo(GetParagraphIndex()); - // relate us to parent - uno::Reference< XAccessible > xParent = getAccessibleParent(); - if( xParent.is() ) + if( aBulletInfo.nParagraph != EE_PARA_MAX && + aBulletInfo.bVisible && + aBulletInfo.nType == SVX_NUM_BITMAP ) { - uno::Reference< XAccessibleContext > xParentContext = xParent->getAccessibleContext(); - if ( xParentContext.is() ) - { - uno::Reference< XAccessibleComponent > xParentContextComponent( xParentContext, uno::UNO_QUERY ); - if( xParentContextComponent.is() ) - { - awt::Point aRefPoint = xParentContextComponent->getLocationOnScreen(); - awt::Point aPoint = getLocation(); - aPoint.X += aRefPoint.X; - aPoint.Y += aRefPoint.Y; + tools::Rectangle aRect = aBulletInfo.aBounds; - return aPoint; - } - } + if( aRect.Contains( aLogPoint ) ) + return getAccessibleChild(0); } - - throw uno::RuntimeException(u"Cannot access parent"_ustr, - uno::Reference< uno::XInterface > - ( static_cast< XAccessible* > (this) ) ); // disambiguate hierarchy } - awt::Size SAL_CALL AccessibleEditableTextPara::getSize( ) - { - SolarMutexGuard aGuard; + // no children at all, or none at given position + return uno::Reference< XAccessible >(); +} - awt::Rectangle aRect = getBounds(); +awt::Rectangle SAL_CALL AccessibleEditableTextPara::getBounds() +{ + SolarMutexGuard aGuard; - return awt::Size( aRect.Width, aRect.Height ); - } + DBG_ASSERT(GetParagraphIndex() >= 0, + "AccessibleEditableTextPara::getBounds: index value overflow"); - void SAL_CALL AccessibleEditableTextPara::grabFocus( ) - { - // set cursor to this paragraph - setSelection(0,0); - } + SvxTextForwarder& rCacheTF = GetTextForwarder(); + tools::Rectangle aRect = rCacheTF.GetParaBounds( GetParagraphIndex() ); - sal_Int32 SAL_CALL AccessibleEditableTextPara::getForeground( ) - { - // #104444# Added to XAccessibleComponent interface - svtools::ColorConfig aColorConfig; - Color nColor = aColorConfig.GetColorValue( svtools::FONTCOLOR ).nColor; - return static_cast<sal_Int32>(nColor); - } + // convert to screen coordinates + tools::Rectangle aScreenRect = AccessibleEditableTextPara::LogicToPixel( aRect, + rCacheTF.GetMapMode(), + GetViewForwarder() ); - sal_Int32 SAL_CALL AccessibleEditableTextPara::getBackground( ) - { - // #104444# Added to XAccessibleComponent interface - Color aColor( Application::GetSettings().GetStyleSettings().GetWindowColor() ); + // offset from shape/cell + Point aOffset = GetEEOffset(); + + return awt::Rectangle( aScreenRect.Left() + aOffset.X(), + aScreenRect.Top() + aOffset.Y(), + aScreenRect.GetSize().Width(), + aScreenRect.GetSize().Height() ); +} - // the background is transparent - aColor.SetAlpha(0); +awt::Point SAL_CALL AccessibleEditableTextPara::getLocation( ) +{ + SolarMutexGuard aGuard; - return static_cast<sal_Int32>( aColor ); - } + awt::Rectangle aRect = getBounds(); - // XAccessibleText - sal_Int32 SAL_CALL AccessibleEditableTextPara::getCaretPosition() - { - SolarMutexGuard aGuard; + return awt::Point( aRect.X, aRect.Y ); +} - if( !HaveEditView() ) - return -1; +awt::Point SAL_CALL AccessibleEditableTextPara::getLocationOnScreen( ) +{ + SolarMutexGuard aGuard; - ESelection aSelection; - if( GetEditViewForwarder().GetSelection( aSelection ) && - GetParagraphIndex() == aSelection.end.nPara ) + // relate us to parent + uno::Reference< XAccessible > xParent = getAccessibleParent(); + if( xParent.is() ) + { + uno::Reference< XAccessibleContext > xParentContext = xParent->getAccessibleContext(); + if ( xParentContext.is() ) { - // caret is always nEndPara,nEndPos - EBulletInfo aBulletInfo = GetTextForwarder().GetBulletInfo(GetParagraphIndex()); - if( aBulletInfo.nParagraph != EE_PARA_MAX && - aBulletInfo.bVisible && - aBulletInfo.nType != SVX_NUM_BITMAP ) + uno::Reference< XAccessibleComponent > xParentContextComponent( xParentContext, uno::UNO_QUERY ); + if( xParentContextComponent.is() ) { - sal_Int32 nBulletLen = aBulletInfo.aText.getLength(); - if( aSelection.end.nIndex - nBulletLen >= 0 ) - return aSelection.end.nIndex - nBulletLen; + awt::Point aRefPoint = xParentContextComponent->getLocationOnScreen(); + awt::Point aPoint = getLocation(); + aPoint.X += aRefPoint.X; + aPoint.Y += aRefPoint.Y; + + return aPoint; } - return aSelection.end.nIndex; } - - // not within this paragraph - return -1; } - sal_Bool SAL_CALL AccessibleEditableTextPara::setCaretPosition( sal_Int32 nIndex ) - { - return setSelection(nIndex, nIndex); - } + throw uno::RuntimeException(u"Cannot access parent"_ustr, + uno::Reference< uno::XInterface > + ( static_cast< XAccessible* > (this) ) ); // disambiguate hierarchy +} - sal_Unicode SAL_CALL AccessibleEditableTextPara::getCharacter( sal_Int32 nIndex ) - { - SolarMutexGuard aGuard; +awt::Size SAL_CALL AccessibleEditableTextPara::getSize( ) +{ + SolarMutexGuard aGuard; - DBG_ASSERT(GetParagraphIndex() >= 0, - "AccessibleEditableTextPara::getCharacter: index value overflow"); + awt::Rectangle aRect = getBounds(); - return OCommonAccessibleText::implGetCharacter( implGetText(), nIndex ); - } + return awt::Size( aRect.Width, aRect.Height ); +} - uno::Sequence< beans::PropertyValue > SAL_CALL AccessibleEditableTextPara::getCharacterAttributes( sal_Int32 nIndex, const css::uno::Sequence< OUString >& rRequestedAttributes ) - { - SolarMutexGuard aGuard; +void SAL_CALL AccessibleEditableTextPara::grabFocus( ) +{ + // set cursor to this paragraph + setSelection(0,0); +} - //Skip the bullet range to ignore the bullet text - SvxTextForwarder& rCacheTF = GetTextForwarder(); - EBulletInfo aBulletInfo = rCacheTF.GetBulletInfo(GetParagraphIndex()); - if (aBulletInfo.bVisible) - nIndex += aBulletInfo.aText.getLength(); - CheckIndex(nIndex); // may throw IndexOutOfBoundsException +sal_Int32 SAL_CALL AccessibleEditableTextPara::getForeground( ) +{ + // #104444# Added to XAccessibleComponent interface + svtools::ColorConfig aColorConfig; + Color nColor = aColorConfig.GetColorValue( svtools::FONTCOLOR ).nColor; + return static_cast<sal_Int32>(nColor); +} - bool bSupplementalMode = false; - uno::Sequence< OUString > aPropertyNames = rRequestedAttributes; - if (!aPropertyNames.hasElements()) - { - bSupplementalMode = true; - aPropertyNames = getAttributeNames(); - } +sal_Int32 SAL_CALL AccessibleEditableTextPara::getBackground( ) +{ + // #104444# Added to XAccessibleComponent interface + Color aColor( Application::GetSettings().GetStyleSettings().GetWindowColor() ); - // get default attributes... - ::comphelper::SequenceAsHashMap aPropHashMap( getDefaultAttributes( aPropertyNames ) ); + // the background is transparent + aColor.SetAlpha(0); - // ... and override them with the direct attributes from the specific position - const uno::Sequence< beans::PropertyValue > aRunAttribs( getRunAttributes( nIndex, aPropertyNames ) ); - for (auto const& rRunAttrib : aRunAttribs) - { - aPropHashMap[ rRunAttrib.Name ] = rRunAttrib.Value; //!! should not only be the value !! - } + return static_cast<sal_Int32>( aColor ); +} - // get resulting sequence - uno::Sequence< beans::PropertyValue > aRes; - aPropHashMap >> aRes; +// XAccessibleText +sal_Int32 SAL_CALL AccessibleEditableTextPara::getCaretPosition() +{ + SolarMutexGuard aGuard; - // since SequenceAsHashMap ignores property handles and property state - // we have to restore the property state here (property handles are - // of no use to the accessibility API). - for (beans::PropertyValue & rRes : asNonConstRange(aRes)) - { - bool bIsDirectVal = false; - for (auto const& rRunAttrib : aRunAttribs) - { - bIsDirectVal = rRes.Name == rRunAttrib.Name; - if (bIsDirectVal) - break; - } - rRes.Handle = -1; - rRes.State = bIsDirectVal ? PropertyState_DIRECT_VALUE : PropertyState_DEFAULT_VALUE; - } - if( bSupplementalMode ) + if( !HaveEditView() ) + return -1; + + ESelection aSelection; + if( GetEditViewForwarder().GetSelection( aSelection ) && + GetParagraphIndex() == aSelection.end.nPara ) + { + // caret is always nEndPara,nEndPos + EBulletInfo aBulletInfo = GetTextForwarder().GetBulletInfo(GetParagraphIndex()); + if( aBulletInfo.nParagraph != EE_PARA_MAX && + aBulletInfo.bVisible && + aBulletInfo.nType != SVX_NUM_BITMAP ) { - _correctValues( aRes ); - // NumberingPrefix - sal_Int32 nRes = aRes.getLength(); - aRes.realloc( nRes + 1 ); - beans::PropertyValue &rRes = aRes.getArray()[nRes]; - rRes.Name = "NumberingPrefix"; - OUString numStr; - if (aBulletInfo.nType != SVX_NUM_CHAR_SPECIAL && aBulletInfo.nType != SVX_NUM_BITMAP) - numStr = aBulletInfo.aText; - rRes.Value <<= numStr; - rRes.Handle = -1; - rRes.State = PropertyState_DIRECT_VALUE; - //For field object. - OUString strFieldType = GetFieldTypeNameAtIndex(nIndex); - if (!strFieldType.isEmpty()) - { - nRes = aRes.getLength(); - aRes.realloc( nRes + 1 ); - beans::PropertyValue &rResField = aRes.getArray()[nRes]; - rResField.Name = "FieldType"; - rResField.Value <<= strFieldType.toAsciiLowerCase(); - rResField.Handle = -1; - rResField.State = PropertyState_DIRECT_VALUE; - } - //sort property values - // build sorted index array - sal_Int32 nLength = aRes.getLength(); - std::vector<sal_Int32> indices(nLength); - std::iota(indices.begin(), indices.end(), 0); - std::sort(indices.begin(), indices.end(), IndexCompare(aRes)); - // create sorted sequences according to index array - uno::Sequence<beans::PropertyValue> aNewValues( nLength ); - std::transform(indices.begin(), indices.end(), aNewValues.getArray(), - [&aRes](sal_Int32 index) -> const beans::PropertyValue& { return aRes[index]; }); - - return aNewValues; + sal_Int32 nBulletLen = aBulletInfo.aText.getLength(); + if( aSelection.end.nIndex - nBulletLen >= 0 ) + return aSelection.end.nIndex - nBulletLen; } - return aRes; + return aSelection.end.nIndex; } - awt::Rectangle SAL_CALL AccessibleEditableTextPara::getCharacterBounds( sal_Int32 nIndex ) - { - SolarMutexGuard aGuard; + // not within this paragraph + return -1; +} - DBG_ASSERT(GetParagraphIndex() >= 0, - "AccessibleEditableTextPara::getCharacterBounds: index value overflow"); +sal_Bool SAL_CALL AccessibleEditableTextPara::setCaretPosition( sal_Int32 nIndex ) +{ + return setSelection(nIndex, nIndex); +} - // #108900# Have position semantics now for nIndex, as - // one-past-the-end values are legal, too. - CheckPosition( nIndex ); +sal_Unicode SAL_CALL AccessibleEditableTextPara::getCharacter( sal_Int32 nIndex ) +{ + SolarMutexGuard aGuard; - SvxTextForwarder& rCacheTF = GetTextForwarder(); - tools::Rectangle aRect = rCacheTF.GetCharBounds(GetParagraphIndex(), nIndex); + DBG_ASSERT(GetParagraphIndex() >= 0, + "AccessibleEditableTextPara::getCharacter: index value overflow"); - // convert to screen - tools::Rectangle aScreenRect = AccessibleEditableTextPara::LogicToPixel( aRect, - rCacheTF.GetMapMode(), - GetViewForwarder() ); - // #109864# offset from parent (paragraph), but in screen - // coordinates. This makes sure the internal text offset in - // the outline view forwarder gets cancelled out here - awt::Rectangle aParaRect( getBounds() ); - aScreenRect.Move( -aParaRect.X, -aParaRect.Y ); + return OCommonAccessibleText::implGetCharacter( implGetText(), nIndex ); +} - // offset from shape/cell - Point aOffset = GetEEOffset(); +uno::Sequence< beans::PropertyValue > SAL_CALL AccessibleEditableTextPara::getCharacterAttributes( sal_Int32 nIndex, const css::uno::Sequence< OUString >& rRequestedAttributes ) +{ + SolarMutexGuard aGuard; - return awt::Rectangle( aScreenRect.Left() + aOffset.X(), - aScreenRect.Top() + aOffset.Y(), - aScreenRect.GetSize().Width(), - aScreenRect.GetSize().Height() ); - } + //Skip the bullet range to ignore the bullet text + SvxTextForwarder& rCacheTF = GetTextForwarder(); + EBulletInfo aBulletInfo = rCacheTF.GetBulletInfo(GetParagraphIndex()); + if (aBulletInfo.bVisible) + nIndex += aBulletInfo.aText.getLength(); + CheckIndex(nIndex); // may throw IndexOutOfBoundsException - sal_Int32 SAL_CALL AccessibleEditableTextPara::getCharacterCount() + bool bSupplementalMode = false; + uno::Sequence< OUString > aPropertyNames = rRequestedAttributes; + if (!aPropertyNames.hasElements()) { - SolarMutexGuard aGuard; + bSupplementalMode = true; + aPropertyNames = getAttributeNames(); + } - DBG_ASSERT(GetParagraphIndex() >= 0, - "AccessibleEditableTextPara::getCharacterCount: index value overflow"); + // get default attributes... + ::comphelper::SequenceAsHashMap aPropHashMap( getDefaultAttributes( aPropertyNames ) ); - return implGetText().getLength(); + // ... and override them with the direct attributes from the specific position + const uno::Sequence< beans::PropertyValue > aRunAttribs( getRunAttributes( nIndex, aPropertyNames ) ); + for (auto const& rRunAttrib : aRunAttribs) + { + aPropHashMap[ rRunAttrib.Name ] = rRunAttrib.Value; //!! should not only be the value !! } - sal_Int32 SAL_CALL AccessibleEditableTextPara::getIndexAtPoint( const awt::Point& rPoint ) + // get resulting sequence + uno::Sequence< beans::PropertyValue > aRes; + aPropHashMap >> aRes; + + // since SequenceAsHashMap ignores property handles and property state + // we have to restore the property state here (property handles are + // of no use to the accessibility API). + for (beans::PropertyValue & rRes : asNonConstRange(aRes)) { - SolarMutexGuard aGuard; + bool bIsDirectVal = false; + for (auto const& rRunAttrib : aRunAttribs) + { + bIsDirectVal = rRes.Name == rRunAttrib.Name; + if (bIsDirectVal) + break; + } + rRes.Handle = -1; + rRes.State = bIsDirectVal ? PropertyState_DIRECT_VALUE : PropertyState_DEFAULT_VALUE; + } + if( bSupplementalMode ) + { + _correctValues( aRes ); + // NumberingPrefix + sal_Int32 nRes = aRes.getLength(); + aRes.realloc( nRes + 1 ); + beans::PropertyValue &rRes = aRes.getArray()[nRes]; + rRes.Name = "NumberingPrefix"; + OUString numStr; + if (aBulletInfo.nType != SVX_NUM_CHAR_SPECIAL && aBulletInfo.nType != SVX_NUM_BITMAP) + numStr = aBulletInfo.aText; + rRes.Value <<= numStr; + rRes.Handle = -1; + rRes.State = PropertyState_DIRECT_VALUE; + //For field object. + OUString strFieldType = GetFieldTypeNameAtIndex(nIndex); + if (!strFieldType.isEmpty()) + { + nRes = aRes.getLength(); + aRes.realloc( nRes + 1 ); + beans::PropertyValue &rResField = aRes.getArray()[nRes]; + rResField.Name = "FieldType"; + rResField.Value <<= strFieldType.toAsciiLowerCase(); + rResField.Handle = -1; + rResField.State = PropertyState_DIRECT_VALUE; + } + //sort property values + // build sorted index array + sal_Int32 nLength = aRes.getLength(); + std::vector<sal_Int32> indices(nLength); + std::iota(indices.begin(), indices.end(), 0); + std::sort(indices.begin(), indices.end(), IndexCompare(aRes)); + // create sorted sequences according to index array + uno::Sequence<beans::PropertyValue> aNewValues( nLength ); + std::transform(indices.begin(), indices.end(), aNewValues.getArray(), + [&aRes](sal_Int32 index) -> const beans::PropertyValue& { return aRes[index]; }); + + return aNewValues; + } + return aRes; +} + +awt::Rectangle SAL_CALL AccessibleEditableTextPara::getCharacterBounds( sal_Int32 nIndex ) +{ + SolarMutexGuard aGuard; + + DBG_ASSERT(GetParagraphIndex() >= 0, + "AccessibleEditableTextPara::getCharacterBounds: index value overflow"); + + // #108900# Have position semantics now for nIndex, as + // one-past-the-end values are legal, too. + CheckPosition( nIndex ); + + SvxTextForwarder& rCacheTF = GetTextForwarder(); + tools::Rectangle aRect = rCacheTF.GetCharBounds(GetParagraphIndex(), nIndex); + + // convert to screen + tools::Rectangle aScreenRect = AccessibleEditableTextPara::LogicToPixel( aRect, + rCacheTF.GetMapMode(), + GetViewForwarder() ); + // #109864# offset from parent (paragraph), but in screen + // coordinates. This makes sure the internal text offset in + // the outline view forwarder gets cancelled out here + awt::Rectangle aParaRect( getBounds() ); + aScreenRect.Move( -aParaRect.X, -aParaRect.Y ); + + // offset from shape/cell + Point aOffset = GetEEOffset(); + + return awt::Rectangle( aScreenRect.Left() + aOffset.X(), + aScreenRect.Top() + aOffset.Y(), + aScreenRect.GetSize().Width(), + aScreenRect.GetSize().Height() ); +} - sal_Int32 nPara; - sal_Int32 nIndex; +sal_Int32 SAL_CALL AccessibleEditableTextPara::getCharacterCount() +{ + SolarMutexGuard aGuard; - // offset from surrounding cell/shape - Point aOffset( GetEEOffset() ); - Point aPoint( rPoint.X - aOffset.X(), rPoint.Y - aOffset.Y() ); + DBG_ASSERT(GetParagraphIndex() >= 0, + "AccessibleEditableTextPara::getCharacterCount: index value overflow"); - // convert to logical coordinates - SvxTextForwarder& rCacheTF = GetTextForwarder(); - Point aLogPoint( GetViewForwarder().PixelToLogic( aPoint, rCacheTF.GetMapMode() ) ); + return implGetText().getLength(); +} - // re-offset to parent (paragraph) - tools::Rectangle aParaRect = rCacheTF.GetParaBounds( GetParagraphIndex() ); - aLogPoint.Move( aParaRect.Left(), aParaRect.Top() ); +sal_Int32 SAL_CALL AccessibleEditableTextPara::getIndexAtPoint( const awt::Point& rPoint ) +{ + SolarMutexGuard aGuard; + + sal_Int32 nPara; + sal_Int32 nIndex; + + // offset from surrounding cell/shape + Point aOffset( GetEEOffset() ); + Point aPoint( rPoint.X - aOffset.X(), rPoint.Y - aOffset.Y() ); + + // convert to logical coordinates + SvxTextForwarder& rCacheTF = GetTextForwarder(); + Point aLogPoint( GetViewForwarder().PixelToLogic( aPoint, rCacheTF.GetMapMode() ) ); - if( rCacheTF.GetIndexAtPoint( aLogPoint, nPara, nIndex ) && - GetParagraphIndex() == nPara ) + // re-offset to parent (paragraph) + tools::Rectangle aParaRect = rCacheTF.GetParaBounds( GetParagraphIndex() ); + aLogPoint.Move( aParaRect.Left(), aParaRect.Top() ); + + if( rCacheTF.GetIndexAtPoint( aLogPoint, nPara, nIndex ) && + GetParagraphIndex() == nPara ) + { + // #102259# Double-check if we're _really_ on the given character + try { - // #102259# Double-check if we're _really_ on the given character - try - { - awt::Rectangle aRect1( getCharacterBounds(nIndex) ); - tools::Rectangle aRect2( aRect1.X, aRect1.Y, - aRect1.Width + aRect1.X, aRect1.Height + aRect1.Y ); - if( aRect2.Contains( Point( rPoint.X, rPoint.Y ) ) ) - return nIndex; - else - return -1; - } - catch (const lang::IndexOutOfBoundsException&) - { - // #103927# Don't throw for invalid nIndex values + awt::Rectangle aRect1( getCharacterBounds(nIndex) ); + tools::Rectangle aRect2( aRect1.X, aRect1.Y, + aRect1.Width + aRect1.X, aRect1.Height + aRect1.Y ); + if( aRect2.Contains( Point( rPoint.X, rPoint.Y ) ) ) + return nIndex; + else return -1; - } } - else + catch (const lang::IndexOutOfBoundsException&) { - // not within our paragraph + // #103927# Don't throw for invalid nIndex values return -1; } } - - OUString SAL_CALL AccessibleEditableTextPara::getSelectedText() + else { - SolarMutexGuard aGuard; + // not within our paragraph + return -1; + } +} - DBG_ASSERT(GetParagraphIndex() >= 0, - "AccessibleEditableTextPara::getSelectedText: index value overflow"); +OUString SAL_CALL AccessibleEditableTextPara::getSelectedText() +{ + SolarMutexGuard aGuard; - if( !HaveEditView() ) - return OUString(); + DBG_ASSERT(GetParagraphIndex() >= 0, + "AccessibleEditableTextPara::getSelectedText: index value overflow"); - return OCommonAccessibleText::getSelectedText(); - } + if( !HaveEditView() ) + return OUString(); - sal_Int32 SAL_CALL AccessibleEditableTextPara::getSelectionStart() - { - SolarMutexGuard aGuard; + return OCommonAccessibleText::getSelectedText(); +} - DBG_ASSERT(GetParagraphIndex() >= 0, - "AccessibleEditableTextPara::getSelectionStart: index value overflow"); +sal_Int32 SAL_CALL AccessibleEditableTextPara::getSelectionStart() +{ + SolarMutexGuard aGuard; - if( !HaveEditView() ) - return -1; + DBG_ASSERT(GetParagraphIndex() >= 0, + "AccessibleEditableTextPara::getSelectionStart: index value overflow"); - return OCommonAccessibleText::getSelectionStart(); - } + if( !HaveEditView() ) + return -1; - sal_Int32 SAL_CALL AccessibleEditableTextPara::getSelectionEnd() - { - SolarMutexGuard aGuard; + return OCommonAccessibleText::getSelectionStart(); +} - DBG_ASSERT(GetParagraphIndex() >= 0, - "AccessibleEditableTextPara::getSelectionEnd: index value overflow"); +sal_Int32 SAL_CALL AccessibleEditableTextPara::getSelectionEnd() +{ + SolarMutexGuard aGuard; - if( !HaveEditView() ) - return -1; + DBG_ASSERT(GetParagraphIndex() >= 0, + "AccessibleEditableTextPara::getSelectionEnd: index value overflow"); - return OCommonAccessibleText::getSelectionEnd(); - } + if( !HaveEditView() ) + return -1; - sal_Bool SAL_CALL AccessibleEditableTextPara::setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) - { - SolarMutexGuard aGuard; + return OCommonAccessibleText::getSelectionEnd(); +} - DBG_ASSERT(GetParagraphIndex() >= 0, - "AccessibleEditableTextPara::setSelection: paragraph index value overflow"); +sal_Bool SAL_CALL AccessibleEditableTextPara::setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) +{ + SolarMutexGuard aGuard; - CheckRange(nStartIndex, nEndIndex); + DBG_ASSERT(GetParagraphIndex() >= 0, + "AccessibleEditableTextPara::setSelection: paragraph index value overflow"); - try - { - SvxEditViewForwarder& rCacheVF = GetEditViewForwarder( true ); - return rCacheVF.SetSelection( MakeSelection(nStartIndex, nEndIndex) ); - } - catch (const uno::RuntimeException&) - { - return false; - } - } + CheckRange(nStartIndex, nEndIndex); - OUString SAL_CALL AccessibleEditableTextPara::getText() + try + { + SvxEditViewForwarder& rCacheVF = GetEditViewForwarder( true ); + return rCacheVF.SetSelection( MakeSelection(nStartIndex, nEndIndex) ); + } + catch (const uno::RuntimeException&) { - SolarMutexGuard aGuard; + return false; + } +} - DBG_ASSERT(GetParagraphIndex() >= 0, - "AccessibleEditableTextPara::getText: paragraph index value overflow"); +OUString SAL_CALL AccessibleEditableTextPara::getText() +{ + SolarMutexGuard aGuard; - return implGetText(); - } + DBG_ASSERT(GetParagraphIndex() >= 0, + "AccessibleEditableTextPara::getText: paragraph index value overflow"); - OUString SAL_CALL AccessibleEditableTextPara::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) - { - SolarMutexGuard aGuard; + return implGetText(); +} - DBG_ASSERT(GetParagraphIndex() >= 0, - "AccessibleEditableTextPara::getTextRange: paragraph index value overflow"); +OUString SAL_CALL AccessibleEditableTextPara::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) +{ + SolarMutexGuard aGuard; - return OCommonAccessibleText::implGetTextRange(implGetText(), nStartIndex, nEndIndex); - } + DBG_ASSERT(GetParagraphIndex() >= 0, + "AccessibleEditableTextPara::getTextRange: paragraph index value overflow"); - void AccessibleEditableTextPara::_correctValues( uno::Sequence< PropertyValue >& rValues) - { - SvxTextForwarder& rCacheTF = GetTextForwarder(); - sal_Int32 nRes = rValues.getLength(); - beans::PropertyValue *pRes = rValues.getArray(); - for (sal_Int32 i = 0; i < nRes; ++i) - { - beans::PropertyValue &rRes = pRes[i]; - // Char color - if (rRes.Name == "CharColor") + return OCommonAccessibleText::implGetTextRange(implGetText(), nStartIndex, nEndIndex); +} + +void AccessibleEditableTextPara::_correctValues( uno::Sequence< PropertyValue >& rValues) +{ + SvxTextForwarder& rCacheTF = GetTextForwarder(); + sal_Int32 nRes = rValues.getLength(); + beans::PropertyValue *pRes = rValues.getArray(); + for (sal_Int32 i = 0; i < nRes; ++i) + { + beans::PropertyValue &rRes = pRes[i]; + // Char color + if (rRes.Name == "CharColor") + { + uno::Any &anyChar = rRes.Value; + Color crChar; + anyChar >>= crChar; + if (COL_AUTO == crChar ) { - uno::Any &anyChar = rRes.Value; - Color crChar; - anyChar >>= crChar; - if (COL_AUTO == crChar ) + uno::Reference< css::accessibility::XAccessibleComponent > xComponent(mxParent,uno::UNO_QUERY); + if (xComponent.is()) { - uno::Reference< css::accessibility::XAccessibleComponent > xComponent(mxParent,uno::UNO_QUERY); - if (xComponent.is()) + uno::Reference< css::accessibility::XAccessibleContext > xContext(xComponent,uno::UNO_QUERY); + if (xContext->getAccessibleRole() == AccessibleRole::SHAPE + || xContext->getAccessibleRole() == AccessibleRole::TABLE_CELL) + { + anyChar <<= COL_BLACK; + } + else { - uno::Reference< css::accessibility::XAccessibleContext > xContext(xComponent,uno::UNO_QUERY); - if (xContext->getAccessibleRole() == AccessibleRole::SHAPE - || xContext->getAccessibleRole() == AccessibleRole::TABLE_CELL) - { - anyChar <<= COL_BLACK; - } - else - { - Color cr(ColorTransparency, xComponent->getBackground()); - crChar = cr.IsDark() ? COL_WHITE : COL_BLACK; - anyChar <<= crChar; - } + Color cr(ColorTransparency, xComponent->getBackground()); + crChar = cr.IsDark() ? COL_WHITE : COL_BLACK; + anyChar <<= crChar; } } - continue; - } - // Underline - if (rRes.Name == "CharUnderline") - { - continue; } - // Underline color && Mis-spell - if (rRes.Name == "CharUnderlineColor") + continue; + } + // Underline + if (rRes.Name == "CharUnderline") + { + continue; + } + // Underline color && Mis-spell + if (rRes.Name == "CharUnderlineColor") + { + uno::Any &anyCharUnderLine = rRes.Value; + Color crCharUnderLine; + anyCharUnderLine >>= crCharUnderLine; + if (COL_AUTO == crCharUnderLine ) { - uno::Any &anyCharUnderLine = rRes.Value; - Color crCharUnderLine; - anyCharUnderLine >>= crCharUnderLine; - if (COL_AUTO == crCharUnderLine ) + uno::Reference< css::accessibility::XAccessibleComponent > xComponent(mxParent,uno::UNO_QUERY); + if (xComponent.is()) { - uno::Reference< css::accessibility::XAccessibleComponent > xComponent(mxParent,uno::UNO_QUERY); - if (xComponent.is()) + uno::Reference< css::accessibility::XAccessibleContext > xContext(xComponent,uno::UNO_QUERY); + if (xContext->getAccessibleRole() == AccessibleRole::SHAPE + || xContext->getAccessibleRole() == AccessibleRole::TABLE_CELL) + { + anyCharUnderLine <<= COL_BLACK; + } + else { - uno::Reference< css::accessibility::XAccessibleContext > xContext(xComponent,uno::UNO_QUERY); - if (xContext->getAccessibleRole() == AccessibleRole::SHAPE - || xContext->getAccessibleRole() == AccessibleRole::TABLE_CELL) - { - anyCharUnderLine <<= COL_BLACK; - } - else - { - Color cr(ColorTransparency, xComponent->getBackground()); - crCharUnderLine = cr.IsDark() ? COL_WHITE : COL_BLACK; - anyCharUnderLine <<= crCharUnderLine; - } + Color cr(ColorTransparency, xComponent->getBackground()); + crCharUnderLine = cr.IsDark() ? COL_WHITE : COL_BLACK; + anyCharUnderLine <<= crCharUnderLine; } } - continue; } - // NumberingLevel - if (rRes.Name == "NumberingLevel") + continue; + } + // NumberingLevel + if (rRes.Name == "NumberingLevel") + { + if(rCacheTF.GetParaAttribs(GetParagraphIndex()).Get(EE_PARA_NUMBULLET).GetNumRule().GetLevelCount()==0) + { + rRes.Value <<= sal_Int16(-1); + rRes.Handle = -1; + rRes.State = PropertyState_DIRECT_VALUE; + } + else { - if(rCacheTF.GetParaAttribs(GetParagraphIndex()).Get(EE_PARA_NUMBULLET).GetNumRule().GetLevelCount()==0) - { - rRes.Value <<= sal_Int16(-1); - rRes.Handle = -1; - rRes.State = PropertyState_DIRECT_VALUE; - } - else - { // SvxAccessibleTextPropertySet aPropSet( &GetEditSource(), // ImplGetSvxCharAndParaPropertiesMap() ); - // MT IA2 TODO: Check if this is the correct replacement for ImplGetSvxCharAndParaPropertiesMap - rtl::Reference< SvxAccessibleTextPropertySet > xPropSet( new SvxAccessibleTextPropertySet( &GetEditSource(), ImplGetSvxTextPortionSvxPropertySet() ) ); + // MT IA2 TODO: Check if this is the correct replacement for ImplGetSvxCharAndParaPropertiesMap + rtl::Reference< SvxAccessibleTextPropertySet > xPropSet( new SvxAccessibleTextPropertySet( &GetEditSource(), ImplGetSvxTextPortionSvxPropertySet() ) ); - xPropSet->SetSelection( MakeSelection( 0, GetTextLen() ) ); - rRes.Value = xPropSet->_getPropertyValue( rRes.Name, mnParagraphIndex ); - rRes.State = xPropSet->_getPropertyState( rRes.Name, mnParagraphIndex ); - rRes.Handle = -1; - } - continue; - } - // NumberingRules - if (rRes.Name == "NumberingRules") - { - SfxItemSet aAttribs = rCacheTF.GetParaAttribs(GetParagraphIndex()); - bool bVis = aAttribs.Get( EE_PARA_BULLETSTATE ).GetValue(); - if(bVis) - { - rRes.Value <<= sal_Int16(-1); - rRes.Handle = -1; - rRes.State = PropertyState_DIRECT_VALUE; - } - else - { - // MT IA2 TODO: Check if this is the correct replacement for ImplGetSvxCharAndParaPropertiesMap - rtl::Reference< SvxAccessibleTextPropertySet > xPropSet( new SvxAccessibleTextPropertySet( &GetEditSource(), ImplGetSvxTextPortionSvxPropertySet() ) ); - xPropSet->SetSelection( MakeSelection( 0, GetTextLen() ) ); - rRes.Value = xPropSet->_getPropertyValue( rRes.Name, mnParagraphIndex ); - rRes.State = xPropSet->_getPropertyState( rRes.Name, mnParagraphIndex ); - rRes.Handle = -1; - } - continue; + xPropSet->SetSelection( MakeSelection( 0, GetTextLen() ) ); + rRes.Value = xPropSet->_getPropertyValue( rRes.Name, mnParagraphIndex ); + rRes.State = xPropSet->_getPropertyState( rRes.Name, mnParagraphIndex ); + rRes.Handle = -1; } + continue; } - } - sal_Int32 AccessibleEditableTextPara::SkipField(sal_Int32 nIndex, bool bForward) - { - sal_Int32 nParaIndex = GetParagraphIndex(); - SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); - sal_Int32 nAllFieldLen = 0; - sal_Int32 nFoundFieldIndex = -1; - std::vector<EFieldInfo> aFieldInfos = rCacheTF.GetFieldInfo(nParaIndex); - sal_Int32 reeBegin=0, reeEnd=0; - sal_Int32 j = 0; - for (const EFieldInfo& ree : aFieldInfos) + // NumberingRules + if (rRes.Name == "NumberingRules") { - reeBegin = ree.aPosition.nIndex + nAllFieldLen; - reeEnd = reeBegin + ree.aCurrentText.getLength(); - nAllFieldLen += (ree.aCurrentText.getLength() - 1); - if (nIndex < reeBegin) - break; - if (!ree.pFieldItem) - continue; - if (nIndex < reeEnd) + SfxItemSet aAttribs = rCacheTF.GetParaAttribs(GetParagraphIndex()); + bool bVis = aAttribs.Get( EE_PARA_BULLETSTATE ).GetValue(); + if(bVis) { - if (ree.pFieldItem->GetField()->GetClassId() != text::textfield::Type::URL) - { - nFoundFieldIndex = j; - break; - } -e ... etc. - the rest is truncated