From 06d14411a447cd798d1f0678a3c5e06f5278a1cb Mon Sep 17 00:00:00 2001 From: Eike Rathke Date: Wed, 23 Aug 2017 17:44:16 +0200 Subject: Related: tdf#108795 a shared SvxAutoCorrect instance can not be stateful An SvxAutoCorrect instance is shared via SvxAutoCorrCfg::Get().GetAutoCorrect(). Since commit 284eb106767d094fc5c547efd6c11cc390e3538a and following the SvxAutoCorrect::bRunNext/HasRunNext() introduced a state whether a previously inserted NO-BREAK SPACE should be removed again, depending on the next character input. That does not work, for example, if SvxAutoCorrect::DoAutoCorrect() is called from two different EditEngine instances, like it is the case in the Calc input line and cell which are synchronized; or any other two or more instances for that matter. The caller has to pass and remember a flag that is maintained by SvxAutoCorrect. Change-Id: I79a26d2ba44cc40771979a78b686c89f0c80b412 Reviewed-on: https://gerrit.libreoffice.org/41475 Reviewed-by: Eike Rathke Tested-by: Jenkins --- sw/inc/editsh.hxx | 12 ++++++++++++ sw/source/core/edit/autofmt.cxx | 5 +++-- sw/source/core/edit/edws.cxx | 7 ++++--- sw/source/uibase/docvw/edtwin.cxx | 5 ++--- 4 files changed, 21 insertions(+), 8 deletions(-) (limited to 'sw') diff --git a/sw/inc/editsh.hxx b/sw/inc/editsh.hxx index df4d0de6e148..411c8eed3921 100644 --- a/sw/inc/editsh.hxx +++ b/sw/inc/editsh.hxx @@ -947,6 +947,8 @@ public: character attribute dialog. */ sal_uInt16 GetScalingOfSelectedText() const; + bool IsNbspRunNext() const { return m_bNbspRunNext; } + /// Ctor/Dtor. SwEditShell( SwDoc&, vcl::Window*, const SwViewOption *pOpt ); @@ -957,6 +959,16 @@ public: private: SwEditShell(const SwEditShell &) = delete; const SwEditShell &operator=(const SwEditShell &) = delete; + + /* TODO: this flag may have to be invalidated / reset to false at various + * places if it was true and the edit cursor position changes. It's somehow + * overkill though because it can only be true if a NO-BREAK SPACE was + * inserted by the last DoAutoCorrect() call (in French language), any + * subsequent call will reset it anyway and just if the cursor is + * positioned behind "x :" and the next character inserted is not a space + * the existing nb-space will be removed. Bear this in mind if that problem + * arises. */ + bool m_bNbspRunNext; ///< NO-BREAK SPACE state flag passed to and maintained by SvxAutoCorrect::DoAutoCorrect() }; inline const sfx2::LinkManager& SwEditShell::GetLinkManager() const diff --git a/sw/source/core/edit/autofmt.cxx b/sw/source/core/edit/autofmt.cxx index 2dcae5d94d73..7ce2f7d0a068 100644 --- a/sw/source/core/edit/autofmt.cxx +++ b/sw/source/core/edit/autofmt.cxx @@ -1831,6 +1831,7 @@ void SwAutoFormat::AutoCorrect( sal_Int32 nPos ) sal_Int32 nSttPos, nLastBlank = nPos; bool bFirst = m_aFlags.bCapitalStartSentence, bFirstSent = bFirst; sal_Unicode cChar = 0; + bool bNbspRunNext = false; CharClass& rAppCC = GetAppCharClass(); @@ -1984,7 +1985,7 @@ void SwAutoFormat::AutoCorrect( sal_Int32 nPos ) : LANGUAGE_SYSTEM; SetRedlineText( STR_AUTOFMTREDL_NON_BREAK_SPACE ); - if ( pATst->FnAddNonBrkSpace( aACorrDoc, *pText, nPos, eLang ) ) + if ( pATst->FnAddNonBrkSpace( aACorrDoc, *pText, nPos, eLang, bNbspRunNext ) ) --nPos; } break; @@ -2041,7 +2042,7 @@ void SwAutoFormat::AutoCorrect( sal_Int32 nPos ) if ( m_aFlags.bAddNonBrkSpace ) { SetRedlineText( STR_AUTOFMTREDL_NON_BREAK_SPACE ); - pATst->FnAddNonBrkSpace( aACorrDoc, *pText, nPos, eLang ); + pATst->FnAddNonBrkSpace( aACorrDoc, *pText, nPos, eLang, bNbspRunNext ); } if( ( m_aFlags.bChgOrdinalNumber && diff --git a/sw/source/core/edit/edws.cxx b/sw/source/core/edit/edws.cxx index 46e5e48687fe..3a719b11736f 100644 --- a/sw/source/core/edit/edws.cxx +++ b/sw/source/core/edit/edws.cxx @@ -35,12 +35,13 @@ // masqueraded copy constructor SwEditShell::SwEditShell( SwEditShell& rEdSH, vcl::Window *pWindow ) - : SwCursorShell( rEdSH, pWindow ) + : SwCursorShell( rEdSH, pWindow ), + m_bNbspRunNext(false) // TODO: would copying that make sense? only if editing continues { } SwEditShell::SwEditShell( SwDoc& rDoc, vcl::Window *pWindow, const SwViewOption *pOptions ) - : SwCursorShell( rDoc, pWindow, pOptions ) + : SwCursorShell( rDoc, pWindow, pOptions ), m_bNbspRunNext(false) { if (0 < officecfg::Office::Common::Undo::Steps::get()) { @@ -257,7 +258,7 @@ void SwEditShell::AutoCorrect( SvxAutoCorrect& rACorr, bool bInsert, OUString const& rNodeText(pTNd->GetText()); rACorr.DoAutoCorrect( aSwAutoCorrDoc, rNodeText, pCursor->GetPoint()->nContent.GetIndex(), - cChar, bInsert, GetWin() ); + cChar, bInsert, m_bNbspRunNext, GetWin() ); if( cChar ) SaveTableBoxContent( pCursor->GetPoint() ); EndAllAction(); diff --git a/sw/source/uibase/docvw/edtwin.cxx b/sw/source/uibase/docvw/edtwin.cxx index 5d432fd11fa5..41c8b841a6e6 100644 --- a/sw/source/uibase/docvw/edtwin.cxx +++ b/sw/source/uibase/docvw/edtwin.cxx @@ -2430,8 +2430,7 @@ KEYINPUT_CHECKTABLE_INSDEL: } const bool bIsAutoCorrectChar = SvxAutoCorrect::IsAutoCorrectChar( aCh ); - const bool bRunNext = pACorr != nullptr && pACorr->HasRunNext(); - if( !aKeyEvent.GetRepeat() && pACorr && ( bIsAutoCorrectChar || bRunNext ) && + if( !aKeyEvent.GetRepeat() && pACorr && ( bIsAutoCorrectChar || rSh.IsNbspRunNext() ) && pACfg->IsAutoFormatByInput() && (( pACorr->IsAutoCorrFlag( ChgWeightUnderl ) && ( '*' == aCh || '_' == aCh ) ) || @@ -2443,7 +2442,7 @@ KEYINPUT_CHECKTABLE_INSDEL: if( '\"' != aCh && '\'' != aCh ) // only call when "*_"! rSh.UpdateAttr(); } - else if( !aKeyEvent.GetRepeat() && pACorr && ( bIsAutoCorrectChar || bRunNext ) && + else if( !aKeyEvent.GetRepeat() && pACorr && ( bIsAutoCorrectChar || rSh.IsNbspRunNext() ) && pACfg->IsAutoFormatByInput() && pACorr->IsAutoCorrFlag( CapitalStartSentence | CapitalStartWord | ChgOrdinalNumber | AddNonBrkSpace | -- cgit