editeng/source/accessibility/AccessibleParaManager.cxx | 25 - editeng/source/accessibility/AccessibleStaticTextBase.cxx | 332 ++++---------- include/editeng/AccessibleStaticTextBase.hxx | 52 +- sc/source/ui/Accessibility/AccessibleCell.cxx | 7 sc/source/ui/inc/AccessibleCell.hxx | 2 5 files changed, 149 insertions(+), 269 deletions(-)
New commits: commit 037896a309b7c386be0427ba2f05bb0d3da874dd Author: Michael Weghorn <m.wegh...@posteo.de> AuthorDate: Wed Apr 2 14:25:42 2025 +0200 Commit: Michael Weghorn <m.wegh...@posteo.de> CommitDate: Thu Apr 3 22:30:20 2025 +0200 editeng a11y: Replace ReleaseChild class with lambda Change-Id: I0b036aebb481e3fe45fcad890a7f2227bc734142 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/183662 Reviewed-by: Michael Weghorn <m.wegh...@posteo.de> Tested-by: Jenkins diff --git a/editeng/source/accessibility/AccessibleParaManager.cxx b/editeng/source/accessibility/AccessibleParaManager.cxx index 01b358a9a9e9..27ef0d356fab 100644 --- a/editeng/source/accessibility/AccessibleParaManager.cxx +++ b/editeng/source/accessibility/AccessibleParaManager.cxx @@ -354,22 +354,6 @@ void AccessibleParaManager::FireEvent( sal_Int32 nStartPara, } } -namespace { - -class ReleaseChild -{ -public: - AccessibleParaManager::WeakChild operator()( const AccessibleParaManager::WeakChild& rPara ) - { - AccessibleParaManager::ShutdownPara( rPara ); - - // clear reference - return AccessibleParaManager::WeakChild(); - } -}; - -} - void AccessibleParaManager::Release( sal_Int32 nStartPara, sal_Int32 nEndPara ) { DBG_ASSERT( 0 <= nStartPara && 0 <= nEndPara && @@ -387,7 +371,14 @@ void AccessibleParaManager::Release( sal_Int32 nStartPara, sal_Int32 nEndPara ) std::advance( front, nStartPara ); std::advance( back, nEndPara ); - std::transform( front, back, front, ReleaseChild() ); + std::transform(front, back, front, + [](const AccessibleParaManager::WeakChild& rPara) + { + AccessibleParaManager::ShutdownPara(rPara); + + // clear reference + return AccessibleParaManager::WeakChild(); + }); } } commit a39bc80a3a7a3634fdccefaeda8792f7a7689368 Author: Michael Weghorn <m.wegh...@posteo.de> AuthorDate: Wed Apr 2 14:11:07 2025 +0200 Commit: Michael Weghorn <m.wegh...@posteo.de> CommitDate: Thu Apr 3 22:30:13 2025 +0200 editeng a11y: Drop AccessibleStaticTextBase::mpThis etc. AccessibleStaticTextBase::mpThis is only used to pass it to Exception ctors, so it seems a bit overkill to have to manage it for that purpose. Drop it and the corresponding setter AccessibleStaticTextBase::SetEventSource. Its doc says that the interface is also used as the event source for a11y events, but that's not actually the case. Also drop ScAccessibleCell::Init which now no longer needs to override the base class implementation, ScAccessibleCellBase::Init. Change-Id: Ide64cf2e59bfb9ae7df41171cc36e1df0c86eb9f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/183628 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.wegh...@posteo.de> diff --git a/editeng/source/accessibility/AccessibleStaticTextBase.cxx b/editeng/source/accessibility/AccessibleStaticTextBase.cxx index 8e24dc939f9d..253bc1b496fc 100644 --- a/editeng/source/accessibility/AccessibleStaticTextBase.cxx +++ b/editeng/source/accessibility/AccessibleStaticTextBase.cxx @@ -101,7 +101,7 @@ AccessibleEditableTextPara& AccessibleStaticTextBase::GetParagraph( sal_Int32 nP { if( !mxTextParagraph.is() ) - throw lang::DisposedException (u"object has been already disposed"_ustr, mpThis ); + throw lang::DisposedException (u"object has been already disposed"_ustr); // TODO: Have a different method on AccessibleEditableTextPara // that does not care about state changes @@ -158,8 +158,7 @@ EPaM AccessibleStaticTextBase::ImpCalcInternal(sal_Int32 nFlatIndex, bool bExclu { if( nFlatIndex < 0 ) - throw lang::IndexOutOfBoundsException(u"AccessibleStaticTextBase_Impl::Index2Internal: character index out of bounds"_ustr, - mpThis); + throw lang::IndexOutOfBoundsException(u"AccessibleStaticTextBase_Impl::Index2Internal: character index out of bounds"_ustr); // gratuitously accepting larger indices here, AccessibleEditableTextPara will throw eventually sal_Int32 nCurrPara, nCurrIndex, nParas, nCurrCount; @@ -190,8 +189,7 @@ EPaM AccessibleStaticTextBase::ImpCalcInternal(sal_Int32 nFlatIndex, bool bExclu } // not found? Out of bounds - throw lang::IndexOutOfBoundsException(u"AccessibleStaticTextBase::Index2Internal: character index out of bounds"_ustr, - mpThis); + throw lang::IndexOutOfBoundsException(u"AccessibleStaticTextBase::Index2Internal: character index out of bounds"_ustr); } bool AccessibleStaticTextBase::SetSelection( sal_Int32 nStartPara, sal_Int32 nStartIndex, @@ -293,11 +291,10 @@ bool AccessibleStaticTextBase::RemoveLineBreakCount( sal_Int32& rIndex ) return false; } -AccessibleStaticTextBase::AccessibleStaticTextBase( std::unique_ptr< SvxEditSource > && pEditSource ) : - mpThis(nullptr) +AccessibleStaticTextBase::AccessibleStaticTextBase(std::unique_ptr<SvxEditSource>&& pEditSource) // TODO: this is still somewhat of a hack, all the more since // now the maTextParagraph has an empty parent reference set - , mxTextParagraph(new AccessibleEditableTextPara(nullptr)) + : mxTextParagraph(new AccessibleEditableTextPara(nullptr)) { SolarMutexGuard aGuard; @@ -318,11 +315,6 @@ void AccessibleStaticTextBase::SetEditSource( std::unique_ptr< SvxEditSource > & mxTextParagraph->SetEditSource(&maEditSource); } -void AccessibleStaticTextBase::SetEventSource( const uno::Reference< XAccessible >& rInterface ) -{ - mpThis = rInterface.get(); -} - void AccessibleStaticTextBase::SetOffset( const Point& rPoint ) { // precondition: solar mutex locked @@ -338,8 +330,7 @@ void AccessibleStaticTextBase::Dispose() if (mxTextParagraph.is()) mxTextParagraph->Dispose(); - // drop references - mpThis = nullptr; + // drop reference mxTextParagraph.clear(); } diff --git a/include/editeng/AccessibleStaticTextBase.hxx b/include/editeng/AccessibleStaticTextBase.hxx index 24a7bc695878..a0003f8dffd0 100644 --- a/include/editeng/AccessibleStaticTextBase.hxx +++ b/include/editeng/AccessibleStaticTextBase.hxx @@ -140,18 +140,6 @@ public: */ void SetEditSource( ::std::unique_ptr< SvxEditSource > && pEditSource ); - /** Set the event source - - @attention When setting a reference here, you should call - Dispose() when you as the owner are disposing, since until - then this object will hold that reference - - @param rInterface - The interface that should be set as the source for - accessibility events sent by this object. - */ - void SetEventSource( const css::uno::Reference< css::accessibility::XAccessible >& rInterface ); - /** Set offset of EditEngine from parent @attention You are required to have the solar mutex @@ -250,11 +238,6 @@ private: bool RemoveLineBreakCount(sal_Int32& rIndex); - // our frontend class (the one implementing the actual - // interface). That's not necessarily the one containing the impl - // pointer. Note that this is not an uno::Reference to prevent ref-counting cycles and leaks. - css::accessibility::XAccessible* mpThis; - // implements our functionality, we're just an adapter (guarded by solar mutex) mutable rtl::Reference<AccessibleEditableTextPara> mxTextParagraph; diff --git a/sc/source/ui/Accessibility/AccessibleCell.cxx b/sc/source/ui/Accessibility/AccessibleCell.cxx index dd7f189738b9..8cda34ab2170 100644 --- a/sc/source/ui/Accessibility/AccessibleCell.cxx +++ b/sc/source/ui/Accessibility/AccessibleCell.cxx @@ -92,13 +92,6 @@ ScAccessibleCell::~ScAccessibleCell() } } -void ScAccessibleCell::Init() -{ - ScAccessibleCellBase::Init(); - - SetEventSource(this); -} - void SAL_CALL ScAccessibleCell::disposing() { SolarMutexGuard aGuard; diff --git a/sc/source/ui/inc/AccessibleCell.hxx b/sc/source/ui/inc/AccessibleCell.hxx index f5c3f8d2821f..aa8edcf12278 100644 --- a/sc/source/ui/inc/AccessibleCell.hxx +++ b/sc/source/ui/inc/AccessibleCell.hxx @@ -66,8 +66,6 @@ private: ScSplitPos eSplitPos, ScAccessibleDocument* pAccDoc); - virtual void Init() override; - using ScAccessibleCellBase::disposing; virtual void SAL_CALL disposing() override; commit 385b1fa3d3e18e1be5650cb7047a3eaad1e0426d Author: Michael Weghorn <m.wegh...@posteo.de> AuthorDate: Wed Apr 2 13:59:23 2025 +0200 Commit: Michael Weghorn <m.wegh...@posteo.de> CommitDate: Thu Apr 3 22:30:05 2025 +0200 editeng a11y: Merge AccessibleStaticTextBase{,_Impl} Merge AccessibleStaticTextBase_Impl into AccessibleStaticTextBase. Further simplification will be possible in upcoming commits. Change-Id: I4f0067c2cf1cb5b2f464b8075bc4a64f44d7babc Reviewed-on: https://gerrit.libreoffice.org/c/core/+/183627 Reviewed-by: Michael Weghorn <m.wegh...@posteo.de> Tested-by: Jenkins diff --git a/editeng/source/accessibility/AccessibleStaticTextBase.cxx b/editeng/source/accessibility/AccessibleStaticTextBase.cxx index 4525a421dc29..8e24dc939f9d 100644 --- a/editeng/source/accessibility/AccessibleStaticTextBase.cxx +++ b/editeng/source/accessibility/AccessibleStaticTextBase.cxx @@ -40,9 +40,7 @@ #include <editeng/editdata.hxx> -#include <editeng/unoedprx.hxx> #include <editeng/AccessibleStaticTextBase.hxx> -#include <editeng/AccessibleEditableTextPara.hxx> using namespace ::com::sun::star; @@ -99,120 +97,7 @@ static ESelection MakeSelection( sal_Int32 nStartPara, sal_Int32 nStartIndex, } -// AccessibleStaticTextBase_Impl declaration - - -/** AccessibleStaticTextBase_Impl - - This class implements the AccessibleStaticTextBase - functionality, mainly by forwarding the calls to an aggregated - AccessibleEditableTextPara. As this is a therefore non-trivial - adapter, factoring out the common functionality from - AccessibleEditableTextPara might be a profitable future task. - */ -class AccessibleStaticTextBase_Impl -{ - friend class AccessibleStaticTextBase; -public: - - // receive pointer to our frontend class and view window - AccessibleStaticTextBase_Impl(); - - void SetEditSource( std::unique_ptr< SvxEditSource > && pEditSource ); - - void SetEventSource( const uno::Reference< XAccessible >& rInterface ) - { - mpThis = rInterface.get(); - } - - void SetOffset( const Point& ); - - void Dispose(); - - AccessibleEditableTextPara& GetParagraph( sal_Int32 nPara ) const; - sal_Int32 GetParagraphCount() const; - - EPaM Index2Internal( sal_Int32 nFlatIndex ) const - { - - return ImpCalcInternal( nFlatIndex, false ); - } - - EPaM Range2Internal( sal_Int32 nFlatIndex ) const - { - - return ImpCalcInternal( nFlatIndex, true ); - } - - sal_Int32 Internal2Index( EPaM nEEIndex ) const; - - void CorrectTextSegment( TextSegment& aTextSegment, - int nPara ) const; - - bool SetSelection( sal_Int32 nStartPara, sal_Int32 nStartIndex, - sal_Int32 nEndPara, sal_Int32 nEndIndex ); - bool CopyText( sal_Int32 nStartPara, sal_Int32 nStartIndex, - sal_Int32 nEndPara, sal_Int32 nEndIndex ); - - tools::Rectangle GetParagraphBoundingBox() const; - bool RemoveLineBreakCount( sal_Int32& rIndex ); - -private: - - EPaM ImpCalcInternal( sal_Int32 nFlatIndex, bool bExclusive ) const; - - // our frontend class (the one implementing the actual - // interface). That's not necessarily the one containing the impl - // pointer. Note that this is not an uno::Reference to prevent ref-counting cycles and leaks. - XAccessible* mpThis; - - // implements our functionality, we're just an adapter (guarded by solar mutex) - mutable rtl::Reference<AccessibleEditableTextPara> mxTextParagraph; - - // a wrapper for the text forwarders (guarded by solar mutex) - mutable SvxEditSourceAdapter maEditSource; -}; - - -// AccessibleStaticTextBase_Impl implementation - - -AccessibleStaticTextBase_Impl::AccessibleStaticTextBase_Impl() - : mpThis(nullptr) - , mxTextParagraph(new AccessibleEditableTextPara(nullptr)) -{ - - // TODO: this is still somewhat of a hack, all the more since - // now the maTextParagraph has an empty parent reference set -} - -void AccessibleStaticTextBase_Impl::SetEditSource( std::unique_ptr< SvxEditSource > && pEditSource ) -{ - - maEditSource.SetEditSource( std::move(pEditSource) ); - if( mxTextParagraph.is() ) - mxTextParagraph->SetEditSource( &maEditSource ); -} - -void AccessibleStaticTextBase_Impl::SetOffset( const Point& rPoint ) -{ - if( mxTextParagraph.is() ) - mxTextParagraph->SetEEOffset( rPoint ); -} - -void AccessibleStaticTextBase_Impl::Dispose() -{ - - // we're the owner of the paragraph, so destroy it, too - if( mxTextParagraph.is() ) - mxTextParagraph->Dispose(); - - // drop references - mpThis = nullptr; - mxTextParagraph.clear(); -} - -AccessibleEditableTextPara& AccessibleStaticTextBase_Impl::GetParagraph( sal_Int32 nPara ) const +AccessibleEditableTextPara& AccessibleStaticTextBase::GetParagraph( sal_Int32 nPara ) const { if( !mxTextParagraph.is() ) @@ -225,7 +110,7 @@ AccessibleEditableTextPara& AccessibleStaticTextBase_Impl::GetParagraph( sal_Int return *mxTextParagraph; } -sal_Int32 AccessibleStaticTextBase_Impl::GetParagraphCount() const +sal_Int32 AccessibleStaticTextBase::GetParagraphCount() const { if( !mxTextParagraph.is() ) @@ -234,7 +119,7 @@ sal_Int32 AccessibleStaticTextBase_Impl::GetParagraphCount() const return mxTextParagraph->GetTextForwarder().GetParagraphCount(); } -sal_Int32 AccessibleStaticTextBase_Impl::Internal2Index(EPaM nEEIndex) const +sal_Int32 AccessibleStaticTextBase::Internal2Index(EPaM nEEIndex) const { // XXX checks for overflow and returns maximum if so sal_Int32 aRes(0); @@ -251,8 +136,8 @@ sal_Int32 AccessibleStaticTextBase_Impl::Internal2Index(EPaM nEEIndex) const return aRes + nEEIndex.nIndex; } -void AccessibleStaticTextBase_Impl::CorrectTextSegment( TextSegment& aTextSegment, - int nPara ) const +void AccessibleStaticTextBase::CorrectTextSegment(TextSegment& aTextSegment, + int nPara) const { // Keep 'invalid' values at the TextSegment if( aTextSegment.SegmentStart != -1 && @@ -269,7 +154,7 @@ void AccessibleStaticTextBase_Impl::CorrectTextSegment( TextSegment& aTextSeg } } -EPaM AccessibleStaticTextBase_Impl::ImpCalcInternal(sal_Int32 nFlatIndex, bool bExclusive) const +EPaM AccessibleStaticTextBase::ImpCalcInternal(sal_Int32 nFlatIndex, bool bExclusive) const { if( nFlatIndex < 0 ) @@ -287,7 +172,7 @@ EPaM AccessibleStaticTextBase_Impl::ImpCalcInternal(sal_Int32 nFlatIndex, bool b // check overflow DBG_ASSERT(nCurrPara >= 0 && nFlatIndex - nCurrIndex + nCurrCount >= 0, - "AccessibleStaticTextBase_Impl::Index2Internal: index value overflow"); + "AccessibleStaticTextBase::Index2Internal: index value overflow"); return EPaM(nCurrPara, nFlatIndex - nCurrIndex + nCurrCount); } @@ -299,17 +184,17 @@ EPaM AccessibleStaticTextBase_Impl::ImpCalcInternal(sal_Int32 nFlatIndex, bool b // check overflow DBG_ASSERT(nCurrPara > 0 && nFlatIndex - nCurrIndex + nCurrCount >= 0, - "AccessibleStaticTextBase_Impl::Index2Internal: index value overflow"); + "AccessibleStaticTextBase::Index2Internal: index value overflow"); return EPaM(nCurrPara - 1, nFlatIndex - nCurrIndex + nCurrCount); } // not found? Out of bounds - throw lang::IndexOutOfBoundsException(u"AccessibleStaticTextBase_Impl::Index2Internal: character index out of bounds"_ustr, + throw lang::IndexOutOfBoundsException(u"AccessibleStaticTextBase::Index2Internal: character index out of bounds"_ustr, mpThis); } -bool AccessibleStaticTextBase_Impl::SetSelection( sal_Int32 nStartPara, sal_Int32 nStartIndex, +bool AccessibleStaticTextBase::SetSelection( sal_Int32 nStartPara, sal_Int32 nStartIndex, sal_Int32 nEndPara, sal_Int32 nEndIndex ) { @@ -327,7 +212,7 @@ bool AccessibleStaticTextBase_Impl::SetSelection( sal_Int32 nStartPara, sal_Int3 } } -bool AccessibleStaticTextBase_Impl::CopyText( sal_Int32 nStartPara, sal_Int32 nStartIndex, +bool AccessibleStaticTextBase::CopyText( sal_Int32 nStartPara, sal_Int32 nStartIndex, sal_Int32 nEndPara, sal_Int32 nEndIndex ) { @@ -356,24 +241,10 @@ bool AccessibleStaticTextBase_Impl::CopyText( sal_Int32 nStartPara, sal_Int32 nS } } -tools::Rectangle AccessibleStaticTextBase_Impl::GetParagraphBoundingBox() const -{ - tools::Rectangle aRect; - if( mxTextParagraph.is() ) - { - awt::Rectangle aAwtRect = mxTextParagraph->getBounds(); - aRect = tools::Rectangle( Point( aAwtRect.X, aAwtRect.Y ), Size( aAwtRect.Width, aAwtRect.Height ) ); - } - else - { - aRect.SetEmpty(); - } - return aRect; -} //the input argument is the index(including " " ) in the string. //the function will calculate the actual index(not including " ") in the string. //and return true if the index is just at a " " -bool AccessibleStaticTextBase_Impl::RemoveLineBreakCount( sal_Int32& rIndex ) +bool AccessibleStaticTextBase::RemoveLineBreakCount( sal_Int32& rIndex ) { // get the total char number inside the cell. sal_Int32 i, nCount, nParas; @@ -422,11 +293,11 @@ bool AccessibleStaticTextBase_Impl::RemoveLineBreakCount( sal_Int32& rIndex ) return false; } - -// AccessibleStaticTextBase implementation - AccessibleStaticTextBase::AccessibleStaticTextBase( std::unique_ptr< SvxEditSource > && pEditSource ) : - mpImpl( new AccessibleStaticTextBase_Impl() ) + mpThis(nullptr) + // TODO: this is still somewhat of a hack, all the more since + // now the maTextParagraph has an empty parent reference set + , mxTextParagraph(new AccessibleEditableTextPara(nullptr)) { SolarMutexGuard aGuard; @@ -442,13 +313,14 @@ void AccessibleStaticTextBase::SetEditSource( std::unique_ptr< SvxEditSource > & // precondition: solar mutex locked DBG_TESTSOLARMUTEX(); - mpImpl->SetEditSource( std::move(pEditSource) ); + maEditSource.SetEditSource(std::move(pEditSource)); + if (mxTextParagraph.is()) + mxTextParagraph->SetEditSource(&maEditSource); } void AccessibleStaticTextBase::SetEventSource( const uno::Reference< XAccessible >& rInterface ) { - mpImpl->SetEventSource( rInterface ); - + mpThis = rInterface.get(); } void AccessibleStaticTextBase::SetOffset( const Point& rPoint ) @@ -456,13 +328,19 @@ void AccessibleStaticTextBase::SetOffset( const Point& rPoint ) // precondition: solar mutex locked DBG_TESTSOLARMUTEX(); - mpImpl->SetOffset( rPoint ); + if (mxTextParagraph.is()) + mxTextParagraph->SetEEOffset(rPoint); } void AccessibleStaticTextBase::Dispose() { - mpImpl->Dispose(); + // we're the owner of the paragraph, so destroy it, too + if (mxTextParagraph.is()) + mxTextParagraph->Dispose(); + // drop references + mpThis = nullptr; + mxTextParagraph.clear(); } // XAccessibleContext @@ -490,9 +368,9 @@ sal_Int32 SAL_CALL AccessibleStaticTextBase::getCaretPosition() SolarMutexGuard aGuard; sal_Int32 i, nPos, nParas; - for( i=0, nPos=-1, nParas=mpImpl->GetParagraphCount(); i<nParas; ++i ) + for (i = 0, nPos = -1, nParas = GetParagraphCount(); i<nParas; ++i ) { - if( (nPos=mpImpl->GetParagraph(i).getCaretPosition()) != -1 ) + if ((nPos = GetParagraph(i).getCaretPosition()) != -1) return nPos; } @@ -508,9 +386,9 @@ sal_Unicode SAL_CALL AccessibleStaticTextBase::getCharacter( sal_Int32 nIndex ) { SolarMutexGuard aGuard; - EPaM aPos(mpImpl->Index2Internal(nIndex)); + EPaM aPos(Index2Internal(nIndex)); - return mpImpl->GetParagraph( aPos.nPara ).getCharacter( aPos.nIndex ); + return GetParagraph(aPos.nPara).getCharacter(aPos.nIndex); } uno::Sequence< beans::PropertyValue > SAL_CALL AccessibleStaticTextBase::getCharacterAttributes( sal_Int32 nIndex, const css::uno::Sequence< OUString >& aRequestedAttributes ) @@ -518,11 +396,11 @@ uno::Sequence< beans::PropertyValue > SAL_CALL AccessibleStaticTextBase::getChar SolarMutexGuard aGuard; //get the actual index without " " - mpImpl->RemoveLineBreakCount( nIndex ); + RemoveLineBreakCount(nIndex); - EPaM aPos(mpImpl->Index2Internal(nIndex)); + EPaM aPos(Index2Internal(nIndex)); - return mpImpl->GetParagraph( aPos.nPara ).getCharacterAttributes( aPos.nIndex, aRequestedAttributes ); + return GetParagraph( aPos.nPara ).getCharacterAttributes( aPos.nIndex, aRequestedAttributes ); } awt::Rectangle SAL_CALL AccessibleStaticTextBase::getCharacterBounds( sal_Int32 nIndex ) @@ -531,10 +409,10 @@ awt::Rectangle SAL_CALL AccessibleStaticTextBase::getCharacterBounds( sal_Int32 // #108900# Allow ranges for nIndex, as one-past-the-end // values are now legal, too. - EPaM aPos(mpImpl->Range2Internal(nIndex)); + EPaM aPos(Range2Internal(nIndex)); // #i70916# Text in spread sheet cells return the wrong extents - AccessibleEditableTextPara& rPara = mpImpl->GetParagraph( aPos.nPara ); + AccessibleEditableTextPara& rPara = GetParagraph( aPos.nPara ); awt::Rectangle aParaBounds( rPara.getBounds() ); awt::Rectangle aBounds( rPara.getCharacterBounds( aPos.nIndex ) ); aBounds.X += aParaBounds.X; @@ -548,8 +426,8 @@ sal_Int32 SAL_CALL AccessibleStaticTextBase::getCharacterCount() SolarMutexGuard aGuard; sal_Int32 i, nCount, nParas; - for( i=0, nCount=0, nParas=mpImpl->GetParagraphCount(); i<nParas; ++i ) - nCount += mpImpl->GetParagraph(i).getCharacterCount(); + for (i = 0, nCount = 0, nParas = GetParagraphCount(); i < nParas; ++i) + nCount += GetParagraph(i).getCharacterCount(); //count on the number of " " which equals number of paragraphs decrease 1. nCount = nCount + (nParas-1); return nCount; @@ -559,7 +437,7 @@ sal_Int32 SAL_CALL AccessibleStaticTextBase::getIndexAtPoint( const awt::Point& { SolarMutexGuard aGuard; - const sal_Int32 nParas( mpImpl->GetParagraphCount() ); + const sal_Int32 nParas(GetParagraphCount()); sal_Int32 nIndex; int i; for( i=0; i<nParas; ++i ) @@ -568,7 +446,7 @@ sal_Int32 SAL_CALL AccessibleStaticTextBase::getIndexAtPoint( const awt::Point& // ordered vertically for early exit // #i70916# Text in spread sheet cells return the wrong extents - AccessibleEditableTextPara& rPara = mpImpl->GetParagraph( i ); + AccessibleEditableTextPara& rPara = GetParagraph(i); awt::Rectangle aParaBounds( rPara.getBounds() ); awt::Point aPoint( rPoint ); aPoint.X -= aParaBounds.X; @@ -576,7 +454,7 @@ sal_Int32 SAL_CALL AccessibleStaticTextBase::getIndexAtPoint( const awt::Point& // #112814# Use correct index offset if ( ( nIndex = rPara.getIndexAtPoint( aPoint ) ) != -1 ) - return mpImpl->Internal2Index(EPaM(i, nIndex)); + return Internal2Index(EPaM(i, nIndex)); } return -1; @@ -601,9 +479,9 @@ sal_Int32 SAL_CALL AccessibleStaticTextBase::getSelectionStart() SolarMutexGuard aGuard; sal_Int32 i, nPos, nParas; - for( i=0, nPos=-1, nParas=mpImpl->GetParagraphCount(); i<nParas; ++i ) + for (i = 0, nPos = -1, nParas = GetParagraphCount(); i < nParas; ++i) { - if( (nPos=mpImpl->GetParagraph(i).getSelectionStart()) != -1 ) + if ((nPos=GetParagraph(i).getSelectionStart()) != -1) return nPos; } @@ -615,9 +493,9 @@ sal_Int32 SAL_CALL AccessibleStaticTextBase::getSelectionEnd() SolarMutexGuard aGuard; sal_Int32 i, nPos, nParas; - for( i=0, nPos=-1, nParas=mpImpl->GetParagraphCount(); i<nParas; ++i ) + for (i = 0, nPos = -1, nParas = GetParagraphCount(); i < nParas; ++i) { - if( (nPos=mpImpl->GetParagraph(i).getSelectionEnd()) != -1 ) + if ((nPos = GetParagraph(i).getSelectionEnd()) != -1) return nPos; } @@ -628,11 +506,11 @@ sal_Bool SAL_CALL AccessibleStaticTextBase::setSelection( sal_Int32 nStartIndex, { SolarMutexGuard aGuard; - EPaM aStartIndex(mpImpl->Range2Internal(nStartIndex)); - EPaM aEndIndex(mpImpl->Range2Internal(nEndIndex)); + EPaM aStartIndex(Range2Internal(nStartIndex)); + EPaM aEndIndex(Range2Internal(nEndIndex)); - return mpImpl->SetSelection( aStartIndex.nPara, aStartIndex.nIndex, - aEndIndex.nPara, aEndIndex.nIndex ); + return SetSelection(aStartIndex.nPara, aStartIndex.nIndex, + aEndIndex.nPara, aEndIndex.nIndex); } OUString SAL_CALL AccessibleStaticTextBase::getText() @@ -641,8 +519,8 @@ OUString SAL_CALL AccessibleStaticTextBase::getText() sal_Int32 i, nParas; OUStringBuffer aRes; - for( i=0, nParas=mpImpl->GetParagraphCount(); i<nParas; ++i ) - aRes.append(mpImpl->GetParagraph(i).getText()); + for (i = 0, nParas = GetParagraphCount(); i < nParas; ++i) + aRes.append(GetParagraph(i).getText()); return aRes.makeStringAndClear(); } @@ -658,7 +536,7 @@ OUString SAL_CALL AccessibleStaticTextBase::getTextRange( sal_Int32 nStartIndex, { return OUString(); } - bool bStart = mpImpl->RemoveLineBreakCount( nStartIndex ); + bool bStart = RemoveLineBreakCount(nStartIndex); //if the start index is just at a " ", we need to begin from the next char if ( bStart ) { @@ -667,8 +545,8 @@ OUString SAL_CALL AccessibleStaticTextBase::getTextRange( sal_Int32 nStartIndex, //we need to find out whether the previous position of the current endindex is at " " or not //if yes we need to mark it and add " " at the end of the result sal_Int32 nTemp = nEndIndex - 1; - bool bEnd = mpImpl->RemoveLineBreakCount( nTemp ); - bool bTemp = mpImpl->RemoveLineBreakCount( nEndIndex ); + bool bEnd = RemoveLineBreakCount(nTemp); + bool bTemp = RemoveLineBreakCount(nEndIndex); //if the below condition is true it indicates an empty paragraph with just a " " //so we need to set one " " flag to avoid duplication. if ( bStart && bEnd && ( nStartIndex == nEndIndex) ) @@ -683,26 +561,26 @@ OUString SAL_CALL AccessibleStaticTextBase::getTextRange( sal_Int32 nStartIndex, nEndIndex++; } OUStringBuffer aRes; - EPaM aStartIndex(mpImpl->Range2Internal(nStartIndex)); - EPaM aEndIndex(mpImpl->Range2Internal(nEndIndex)); + EPaM aStartIndex(Range2Internal(nStartIndex)); + EPaM aEndIndex(Range2Internal(nEndIndex)); // #102170# Special case: start and end paragraph are identical if( aStartIndex.nPara == aEndIndex.nPara ) { //we don't return the string directly now for that we have to do some further process for " " - aRes = mpImpl->GetParagraph( aStartIndex.nPara ).getTextRange( aStartIndex.nIndex, aEndIndex.nIndex ); + aRes = GetParagraph( aStartIndex.nPara ).getTextRange( aStartIndex.nIndex, aEndIndex.nIndex ); } else { sal_Int32 i( aStartIndex.nPara ); - aRes = mpImpl->GetParagraph(i).getTextRange( aStartIndex.nIndex, - mpImpl->GetParagraph(i).getCharacterCount()/*-1*/); + aRes = GetParagraph(i).getTextRange(aStartIndex.nIndex, + GetParagraph(i).getCharacterCount()/*-1*/); ++i; // paragraphs inbetween are fully included for( ; i<aEndIndex.nPara; ++i ) { - aRes.append(OUStringChar(cNewLine) + mpImpl->GetParagraph(i).getText()); + aRes.append(OUStringChar(cNewLine) + GetParagraph(i).getText()); } if( i<=aEndIndex.nPara ) @@ -713,7 +591,7 @@ OUString SAL_CALL AccessibleStaticTextBase::getTextRange( sal_Int32 nStartIndex, { aRes.append(cNewLine); } - aRes.append(mpImpl->GetParagraph(i).getTextRange( 0, aEndIndex.nIndex )); + aRes.append(GetParagraph(i).getTextRange( 0, aEndIndex.nIndex )); } } //According to the flag we marked before, we have to add " " at the beginning @@ -733,8 +611,8 @@ css::accessibility::TextSegment SAL_CALL AccessibleStaticTextBase::getTextAtInde { SolarMutexGuard aGuard; - bool bLineBreak = mpImpl->RemoveLineBreakCount( nIndex ); - EPaM aPos(mpImpl->Range2Internal(nIndex)); + bool bLineBreak = RemoveLineBreakCount(nIndex); + EPaM aPos(Range2Internal(nIndex)); css::accessibility::TextSegment aResult; @@ -747,15 +625,15 @@ css::accessibility::TextSegment SAL_CALL AccessibleStaticTextBase::getTextAtInde // in aPos.nPara. // retrieve full text of the paragraph - aResult.SegmentText = mpImpl->GetParagraph( aPos.nPara ).getText(); + aResult.SegmentText = GetParagraph( aPos.nPara ).getText(); // #112814# Adapt the start index with the paragraph offset - aResult.SegmentStart = mpImpl->Internal2Index(EPaM(aPos.nPara, 0)); + aResult.SegmentStart = Internal2Index(EPaM(aPos.nPara, 0)); aResult.SegmentEnd = aResult.SegmentStart + aResult.SegmentText.getLength(); } else if ( AccessibleTextType::ATTRIBUTE_RUN == aTextType ) { - SvxAccessibleTextAdapter& rTextForwarder = mpImpl->GetParagraph( aPos.nIndex ).GetTextForwarder(); + SvxAccessibleTextAdapter& rTextForwarder = GetParagraph( aPos.nIndex ).GetTextForwarder(); sal_Int32 nStartIndex, nEndIndex; if ( rTextForwarder.GetAttributeRun( nStartIndex, nEndIndex, aPos.nPara, aPos.nIndex, true ) ) { @@ -767,10 +645,10 @@ css::accessibility::TextSegment SAL_CALL AccessibleStaticTextBase::getTextAtInde else { // No special handling required, forward to wrapped class - aResult = mpImpl->GetParagraph( aPos.nPara ).getTextAtIndex( aPos.nIndex, aTextType ); + aResult = GetParagraph( aPos.nPara ).getTextAtIndex( aPos.nIndex, aTextType ); // #112814# Adapt the start index with the paragraph offset - mpImpl->CorrectTextSegment( aResult, aPos.nPara ); + CorrectTextSegment( aResult, aPos.nPara ); if ( bLineBreak ) { aResult.SegmentText = OUString(cNewLine); @@ -785,27 +663,27 @@ css::accessibility::TextSegment SAL_CALL AccessibleStaticTextBase::getTextBefore SolarMutexGuard aGuard; sal_Int32 nOldIdx = nIndex; - bool bLineBreak = mpImpl->RemoveLineBreakCount( nIndex ); - EPaM aPos(mpImpl->Range2Internal(nIndex)); + bool bLineBreak = RemoveLineBreakCount(nIndex); + EPaM aPos(Range2Internal(nIndex)); css::accessibility::TextSegment aResult; if( AccessibleTextType::PARAGRAPH == aTextType ) { - if( aPos.nIndex == mpImpl->GetParagraph( aPos.nPara ).getCharacterCount() ) + if( aPos.nIndex == GetParagraph( aPos.nPara ).getCharacterCount() ) { // #103589# Special casing one behind the last paragraph - aResult.SegmentText = mpImpl->GetParagraph( aPos.nPara ).getText(); + aResult.SegmentText = GetParagraph( aPos.nPara ).getText(); // #112814# Adapt the start index with the paragraph offset - aResult.SegmentStart = mpImpl->Internal2Index(EPaM(aPos.nPara, 0)); + aResult.SegmentStart = Internal2Index(EPaM(aPos.nPara, 0)); } else if( aPos.nPara > 0 ) { - aResult.SegmentText = mpImpl->GetParagraph( aPos.nPara - 1 ).getText(); + aResult.SegmentText = GetParagraph( aPos.nPara - 1 ).getText(); // #112814# Adapt the start index with the paragraph offset - aResult.SegmentStart = mpImpl->Internal2Index(EPaM(aPos.nPara - 1, 0)); + aResult.SegmentStart = Internal2Index(EPaM(aPos.nPara - 1, 0)); } aResult.SegmentEnd = aResult.SegmentStart + aResult.SegmentText.getLength(); @@ -813,10 +691,10 @@ css::accessibility::TextSegment SAL_CALL AccessibleStaticTextBase::getTextBefore else { // No special handling required, forward to wrapped class - aResult = mpImpl->GetParagraph( aPos.nPara ).getTextBeforeIndex( aPos.nIndex, aTextType ); + aResult = GetParagraph( aPos.nPara ).getTextBeforeIndex( aPos.nIndex, aTextType ); // #112814# Adapt the start index with the paragraph offset - mpImpl->CorrectTextSegment( aResult, aPos.nPara ); + CorrectTextSegment( aResult, aPos.nPara ); if ( bLineBreak && (nOldIdx-1) >= 0) { aResult = getTextAtIndex( nOldIdx-1, aTextType ); @@ -831,9 +709,9 @@ css::accessibility::TextSegment SAL_CALL AccessibleStaticTextBase::getTextBehind SolarMutexGuard aGuard; sal_Int32 nTemp = nIndex+1; - bool bLineBreak = mpImpl->RemoveLineBreakCount( nTemp ); - mpImpl->RemoveLineBreakCount( nIndex ); - EPaM aPos(mpImpl->Range2Internal(nIndex)); + bool bLineBreak = RemoveLineBreakCount(nTemp); + RemoveLineBreakCount(nIndex); + EPaM aPos(Range2Internal(nIndex)); css::accessibility::TextSegment aResult; @@ -842,22 +720,22 @@ css::accessibility::TextSegment SAL_CALL AccessibleStaticTextBase::getTextBehind // Special casing one behind the last paragraph is not // necessary, this case is invalid here for // getTextBehindIndex - if( aPos.nPara + 1 < mpImpl->GetParagraphCount() ) + if (aPos.nPara + 1 < GetParagraphCount()) { - aResult.SegmentText = mpImpl->GetParagraph( aPos.nPara + 1 ).getText(); + aResult.SegmentText = GetParagraph( aPos.nPara + 1 ).getText(); // #112814# Adapt the start index with the paragraph offset - aResult.SegmentStart = mpImpl->Internal2Index(EPaM(aPos.nPara + 1, 0)); + aResult.SegmentStart = Internal2Index(EPaM(aPos.nPara + 1, 0)); aResult.SegmentEnd = aResult.SegmentStart + aResult.SegmentText.getLength(); } } else { // No special handling required, forward to wrapped class - aResult = mpImpl->GetParagraph( aPos.nPara ).getTextBehindIndex( aPos.nIndex, aTextType ); + aResult = GetParagraph( aPos.nPara ).getTextBehindIndex( aPos.nIndex, aTextType ); // #112814# Adapt the start index with the paragraph offset - mpImpl->CorrectTextSegment( aResult, aPos.nPara ); + CorrectTextSegment( aResult, aPos.nPara ); if ( bLineBreak ) { aResult.SegmentText = OUStringChar(cNewLine) + aResult.SegmentText; @@ -874,11 +752,10 @@ sal_Bool SAL_CALL AccessibleStaticTextBase::copyText( sal_Int32 nStartIndex, sal if( nStartIndex > nEndIndex ) std::swap(nStartIndex, nEndIndex); - EPaM aStartIndex(mpImpl->Range2Internal(nStartIndex)); - EPaM aEndIndex(mpImpl->Range2Internal(nEndIndex)); + EPaM aStartIndex(Range2Internal(nStartIndex)); + EPaM aEndIndex(Range2Internal(nEndIndex)); - return mpImpl->CopyText( aStartIndex.nPara, aStartIndex.nIndex, - aEndIndex.nPara, aEndIndex.nIndex ); + return CopyText(aStartIndex.nPara, aStartIndex.nIndex, aEndIndex.nPara, aEndIndex.nIndex); } sal_Bool SAL_CALL AccessibleStaticTextBase::scrollSubstringTo( sal_Int32, sal_Int32, AccessibleScrollType ) @@ -894,12 +771,12 @@ uno::Sequence< beans::PropertyValue > AccessibleStaticTextBase::getDefaultAttrib SolarMutexGuard aGuard; PropertyValueVector aDefAttrVec( - comphelper::sequenceToContainer<PropertyValueVector>(mpImpl->GetParagraph( 0 ).getDefaultAttributes( RequestedAttributes )) ); + comphelper::sequenceToContainer<PropertyValueVector>(GetParagraph( 0 ).getDefaultAttributes( RequestedAttributes )) ); - const sal_Int32 nParaCount = mpImpl->GetParagraphCount(); + const sal_Int32 nParaCount = GetParagraphCount(); for ( sal_Int32 nPara = 1; nPara < nParaCount; ++nPara ) { - uno::Sequence< beans::PropertyValue > aSeq = mpImpl->GetParagraph( nPara ).getDefaultAttributes( RequestedAttributes ); + uno::Sequence< beans::PropertyValue > aSeq = GetParagraph( nPara ).getDefaultAttributes( RequestedAttributes ); PropertyValueVector aIntersectionVec; for ( const auto& rDefAttr : aDefAttrVec ) @@ -927,8 +804,8 @@ uno::Sequence< beans::PropertyValue > SAL_CALL AccessibleStaticTextBase::getRunA SolarMutexGuard aGuard; - EPaM aPos(mpImpl->Index2Internal(nIndex)); - AccessibleEditableTextPara& rPara = mpImpl->GetParagraph( aPos.nPara ); + EPaM aPos(Index2Internal(nIndex)); + AccessibleEditableTextPara& rPara = GetParagraph( aPos.nPara ); uno::Sequence< beans::PropertyValue > aDefAttrSeq = rPara.getDefaultAttributes( RequestedAttributes ); uno::Sequence< beans::PropertyValue > aRunAttrSeq = rPara.getRunAttributes( aPos.nIndex, RequestedAttributes ); uno::Sequence< beans::PropertyValue > aIntersectionSeq = getDefaultAttributes( RequestedAttributes ); @@ -949,7 +826,17 @@ uno::Sequence< beans::PropertyValue > SAL_CALL AccessibleStaticTextBase::getRunA tools::Rectangle AccessibleStaticTextBase::GetParagraphBoundingBox() const { - return mpImpl->GetParagraphBoundingBox(); + tools::Rectangle aRect; + if (mxTextParagraph.is()) + { + awt::Rectangle aAwtRect = mxTextParagraph->getBounds(); + aRect = tools::Rectangle(Point(aAwtRect.X, aAwtRect.Y), Size(aAwtRect.Width, aAwtRect.Height)); + } + else + { + aRect.SetEmpty(); + } + return aRect; } } // end of namespace accessibility diff --git a/include/editeng/AccessibleStaticTextBase.hxx b/include/editeng/AccessibleStaticTextBase.hxx index b836bf946f5d..24a7bc695878 100644 --- a/include/editeng/AccessibleStaticTextBase.hxx +++ b/include/editeng/AccessibleStaticTextBase.hxx @@ -28,7 +28,10 @@ #include <com/sun/star/accessibility/XAccessibleText.hpp> #include <com/sun/star/accessibility/XAccessibleTextAttributes.hpp> #include <com/sun/star/accessibility/TextSegment.hpp> +#include <editeng/AccessibleEditableTextPara.hxx> +#include <editeng/EPaM.hxx> #include <editeng/editengdllapi.h> +#include <editeng/unoedprx.hxx> namespace com::sun::star::accessibility { class XAccessible; } @@ -37,8 +40,6 @@ class SvxEditSource; namespace accessibility { -class AccessibleStaticTextBase_Impl; - typedef ::cppu::ImplHelper2< css::accessibility::XAccessibleText, css::accessibility::XAccessibleTextAttributes > AccessibleStaticTextBase_BASE; @@ -221,8 +222,44 @@ protected: private: - /// @dyn - const std::unique_ptr< AccessibleStaticTextBase_Impl > mpImpl; + EPaM ImpCalcInternal(sal_Int32 nFlatIndex, bool bExclusive) const; + + EPaM Index2Internal(sal_Int32 nFlatIndex) const + { + + return ImpCalcInternal(nFlatIndex, false); + } + + EPaM Range2Internal(sal_Int32 nFlatIndex) const + { + + return ImpCalcInternal(nFlatIndex, true); + } + + AccessibleEditableTextPara& GetParagraph(sal_Int32 nPara) const; + sal_Int32 GetParagraphCount() const; + + sal_Int32 Internal2Index(EPaM nEEIndex) const; + + void CorrectTextSegment(css::accessibility::TextSegment& aTextSegment, int nPara) const; + + bool SetSelection(sal_Int32 nStartPara, sal_Int32 nStartIndex, + sal_Int32 nEndPara, sal_Int32 nEndIndex); + bool CopyText(sal_Int32 nStartPara, sal_Int32 nStartIndex, + sal_Int32 nEndPara, sal_Int32 nEndIndex); + + bool RemoveLineBreakCount(sal_Int32& rIndex); + + // our frontend class (the one implementing the actual + // interface). That's not necessarily the one containing the impl + // pointer. Note that this is not an uno::Reference to prevent ref-counting cycles and leaks. + css::accessibility::XAccessible* mpThis; + + // implements our functionality, we're just an adapter (guarded by solar mutex) + mutable rtl::Reference<AccessibleEditableTextPara> mxTextParagraph; + + // a wrapper for the text forwarders (guarded by solar mutex) + mutable SvxEditSourceAdapter maEditSource; };