diff options
author | Eike Rathke <erack@redhat.com> | 2017-08-23 17:44:16 +0200 |
---|---|---|
committer | Eike Rathke <erack@redhat.com> | 2017-08-24 00:30:37 +0200 |
commit | 06d14411a447cd798d1f0678a3c5e06f5278a1cb (patch) | |
tree | 37fd5ccedaff3491bb8d17a1072d60371d3801a0 /editeng | |
parent | 5a9b20c8bd0c2d7065cde37ebef330aaee0056e2 (diff) |
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 <erack@redhat.com>
Tested-by: Jenkins <ci@libreoffice.org>
Diffstat (limited to 'editeng')
-rw-r--r-- | editeng/qa/unit/core-test.cxx | 18 | ||||
-rw-r--r-- | editeng/source/editeng/editeng.cxx | 3 | ||||
-rw-r--r-- | editeng/source/editeng/impedit.hxx | 6 | ||||
-rw-r--r-- | editeng/source/editeng/impedit2.cxx | 5 | ||||
-rw-r--r-- | editeng/source/misc/svxacorr.cxx | 16 |
5 files changed, 29 insertions, 19 deletions
diff --git a/editeng/qa/unit/core-test.cxx b/editeng/qa/unit/core-test.cxx index f806a056ff26..6345473d4257 100644 --- a/editeng/qa/unit/core-test.cxx +++ b/editeng/qa/unit/core-test.cxx @@ -353,9 +353,10 @@ void Test::testAutocorrect() OUString sInput("TEst-TEst"); sal_Unicode const cNextChar(' '); OUString const sExpected("Test-Test "); + bool bNbspRunNext = false; TestAutoCorrDoc aFoo(sInput, LANGUAGE_ENGLISH_US); - aAutoCorrect.DoAutoCorrect(aFoo, sInput, sInput.getLength(), cNextChar, true); + aAutoCorrect.DoAutoCorrect(aFoo, sInput, sInput.getLength(), cNextChar, true, bNbspRunNext); CPPUNIT_ASSERT_EQUAL_MESSAGE("autocorrect", sExpected, aFoo.getResult()); } @@ -364,9 +365,10 @@ void Test::testAutocorrect() OUString sInput("TEst/TEst"); sal_Unicode const cNextChar(' '); OUString const sExpected("Test/Test "); + bool bNbspRunNext = false; TestAutoCorrDoc aFoo(sInput, LANGUAGE_ENGLISH_US); - aAutoCorrect.DoAutoCorrect(aFoo, sInput, sInput.getLength(), cNextChar, true); + aAutoCorrect.DoAutoCorrect(aFoo, sInput, sInput.getLength(), cNextChar, true, bNbspRunNext); CPPUNIT_ASSERT_EQUAL_MESSAGE("autocorrect", sExpected, aFoo.getResult()); } @@ -376,9 +378,10 @@ void Test::testAutocorrect() OUString sInput("*foo"); sal_Unicode const cNextChar('*'); OUString const sExpected("foo"); + bool bNbspRunNext = false; TestAutoCorrDoc aFoo(sInput, LANGUAGE_ENGLISH_US); - aAutoCorrect.DoAutoCorrect(aFoo, sInput, sInput.getLength(), cNextChar, true); + aAutoCorrect.DoAutoCorrect(aFoo, sInput, sInput.getLength(), cNextChar, true, bNbspRunNext); CPPUNIT_ASSERT_EQUAL(sExpected, aFoo.getResult()); } @@ -387,9 +390,10 @@ void Test::testAutocorrect() OUString sInput("Test. test"); sal_Unicode const cNextChar(' '); OUString const sExpected("Test. Test "); + bool bNbspRunNext = false; TestAutoCorrDoc aFoo(sInput, LANGUAGE_ENGLISH_US); - aAutoCorrect.DoAutoCorrect(aFoo, sInput, sInput.getLength(), cNextChar, true); + aAutoCorrect.DoAutoCorrect(aFoo, sInput, sInput.getLength(), cNextChar, true, bNbspRunNext); CPPUNIT_ASSERT_EQUAL_MESSAGE("autocorrect", sExpected, aFoo.getResult()); } @@ -399,9 +403,10 @@ void Test::testAutocorrect() OUString sInput("Test. \x01 test"); sal_Unicode const cNextChar(' '); OUString const sExpected("Test. \x01 test "); + bool bNbspRunNext = false; TestAutoCorrDoc aFoo(sInput, LANGUAGE_ENGLISH_US); - aAutoCorrect.DoAutoCorrect(aFoo, sInput, sInput.getLength(), cNextChar, true); + aAutoCorrect.DoAutoCorrect(aFoo, sInput, sInput.getLength(), cNextChar, true, bNbspRunNext); CPPUNIT_ASSERT_EQUAL_MESSAGE("autocorrect", sExpected, aFoo.getResult()); } @@ -412,10 +417,11 @@ void Test::testAutocorrect() sal_Unicode const cNextChar('"'); const sal_Unicode EXPECTED[] = { 'T', 0x01, 0x0201d }; OUString sExpected(EXPECTED, SAL_N_ELEMENTS(EXPECTED)); + bool bNbspRunNext = false; TestAutoCorrDoc aFoo(sInput, LANGUAGE_ENGLISH_US); aAutoCorrect.SetAutoCorrFlag(ChgQuotes, true); - aAutoCorrect.DoAutoCorrect(aFoo, sInput, sInput.getLength(), cNextChar, true); + aAutoCorrect.DoAutoCorrect(aFoo, sInput, sInput.getLength(), cNextChar, true, bNbspRunNext); fprintf(stderr, "text is %x\n", aFoo.getResult()[aFoo.getResult().getLength() - 1]); CPPUNIT_ASSERT_EQUAL_MESSAGE("autocorrect", sExpected, aFoo.getResult()); diff --git a/editeng/source/editeng/editeng.cxx b/editeng/source/editeng/editeng.cxx index ed915b09a15f..287d219712ed 100644 --- a/editeng/source/editeng/editeng.cxx +++ b/editeng/source/editeng/editeng.cxx @@ -1270,10 +1270,9 @@ bool EditEngine::PostKeyEvent( const KeyEvent& rKeyEvent, EditView* pEditView, v sal_Unicode nCharCode = rKeyEvent.GetCharCode(); pEditView->pImpEditView->DrawSelectionXOR(); // Autocorrection? - SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect(); if ( ( pImpEditEngine->GetStatus().DoAutoCorrect() ) && ( SvxAutoCorrect::IsAutoCorrectChar( nCharCode ) || - pAutoCorrect->HasRunNext() ) ) + pImpEditEngine->IsNbspRunNext() ) ) { aCurSel = pImpEditEngine->AutoCorrect( aCurSel, nCharCode, !pEditView->IsInsertMode(), pFrameWin ); diff --git a/editeng/source/editeng/impedit.hxx b/editeng/source/editeng/impedit.hxx index 9bcab368ee80..9cf5de4e22ab 100644 --- a/editeng/source/editeng/impedit.hxx +++ b/editeng/source/editeng/impedit.hxx @@ -538,6 +538,8 @@ private: bool mbLastTryMerge:1; bool mbReplaceLeadingSingleQuotationMark:1; + bool mbNbspRunNext; // can't be a bitfield as it is passed as bool& + // Methods... @@ -1053,6 +1055,10 @@ public: mark (apostrophe) or not (default is on) */ void SetReplaceLeadingSingleQuotationMark( bool bReplace ) { mbReplaceLeadingSingleQuotationMark = bReplace; } bool IsReplaceLeadingSingleQuotationMark() const { return mbReplaceLeadingSingleQuotationMark; } + + /** Whether last AutoCorrect inserted a NO-BREAK SPACE that may need to be removed again. */ + bool IsNbspRunNext() const { return mbNbspRunNext; } + void Dispose(); }; diff --git a/editeng/source/editeng/impedit2.cxx b/editeng/source/editeng/impedit2.cxx index eaec3beb77bd..b31066b8e660 100644 --- a/editeng/source/editeng/impedit2.cxx +++ b/editeng/source/editeng/impedit2.cxx @@ -107,7 +107,8 @@ ImpEditEngine::ImpEditEngine( EditEngine* pEE, SfxItemPool* pItemPool ) : bCallParaInsertedOrDeleted(false), bFirstWordCapitalization(true), mbLastTryMerge(false), - mbReplaceLeadingSingleQuotationMark(true) + mbReplaceLeadingSingleQuotationMark(true), + mbNbspRunNext(false) { pEditEngine = pEE; pRefDev = nullptr; @@ -2571,7 +2572,7 @@ EditPaM ImpEditEngine::AutoCorrect( const EditSelection& rCurSel, sal_Unicode c, // FIXME: this _must_ be called with reference to the actual node text! OUString const& rNodeString(pNode->GetString()); pAutoCorrect->DoAutoCorrect( - aAuto, rNodeString, nIndex, c, !bOverwrite, pFrameWin ); + aAuto, rNodeString, nIndex, c, !bOverwrite, mbNbspRunNext, pFrameWin ); aSel.Max().SetIndex( aAuto.GetCursor() ); // #i78661 since the SvxAutoCorrect object used here is diff --git a/editeng/source/misc/svxacorr.cxx b/editeng/source/misc/svxacorr.cxx index d97961831540..51571e1af1ca 100644 --- a/editeng/source/misc/svxacorr.cxx +++ b/editeng/source/misc/svxacorr.cxx @@ -296,7 +296,6 @@ SvxAutoCorrect::SvxAutoCorrect( const OUString& rShareAutocorrFile, const OUString& rUserAutocorrFile ) : sShareAutoCorrFile( rShareAutocorrFile ) , sUserAutoCorrFile( rUserAutocorrFile ) - , bRunNext( false ) , eCharClassLang( LANGUAGE_DONTKNOW ) , nFlags(SvxAutoCorrect::GetDefaultFlags()) , cStartDQuote( 0 ) @@ -312,7 +311,6 @@ SvxAutoCorrect::SvxAutoCorrect( const SvxAutoCorrect& rCpy ) : sShareAutoCorrFile( rCpy.sShareAutoCorrFile ) , sUserAutoCorrFile( rCpy.sUserAutoCorrFile ) , aSwFlags( rCpy.aSwFlags ) - , bRunNext( false ) , eCharClassLang(rCpy.eCharClassLang) , nFlags( rCpy.nFlags & ~(ChgWordLstLoad|CplSttLstLoad|WrdSttLstLoad)) , cStartDQuote( rCpy.cStartDQuote ) @@ -630,7 +628,7 @@ bool SvxAutoCorrect::FnChgToEnEmDash( bool SvxAutoCorrect::FnAddNonBrkSpace( SvxAutoCorrDoc& rDoc, const OUString& rTxt, sal_Int32 nEndPos, - LanguageType eLang ) + LanguageType eLang, bool& io_bNbspRunNext ) { bool bRet = false; @@ -689,11 +687,11 @@ bool SvxAutoCorrect::FnAddNonBrkSpace( // Add the non-breaking space at the end pos if ( bHasSpace ) rDoc.Insert( nPos, OUString(cNonBreakingSpace) ); - bRunNext = true; + io_bNbspRunNext = true; bRet = true; } else if ( chars.indexOf( cPrevChar ) != -1 ) - bRunNext = true; + io_bNbspRunNext = true; } } else if ( cChar == '/' && nEndPos > 1 && rTxt.getLength() > (nEndPos - 1) ) @@ -1234,10 +1232,10 @@ OUString SvxAutoCorrect::GetQuote( SvxAutoCorrDoc const & rDoc, sal_Int32 nInsPo void SvxAutoCorrect::DoAutoCorrect( SvxAutoCorrDoc& rDoc, const OUString& rTxt, sal_Int32 nInsPos, sal_Unicode cChar, - bool bInsert, vcl::Window const * pFrameWin ) + bool bInsert, bool& io_bNbspRunNext, vcl::Window const * pFrameWin ) { - bool bIsNextRun = bRunNext; - bRunNext = false; // if it was set, then it has to be turned off + bool bIsNextRun = io_bNbspRunNext; + io_bNbspRunNext = false; // if it was set, then it has to be turned off do{ // only for middle check loop !! if( cChar ) @@ -1276,7 +1274,7 @@ void SvxAutoCorrect::DoAutoCorrect( SvxAutoCorrDoc& rDoc, const OUString& rTxt, if ( IsAutoCorrFlag( AddNonBrkSpace ) ) { if ( NeedsHardspaceAutocorr( cChar ) && - FnAddNonBrkSpace( rDoc, rTxt, nInsPos, rDoc.GetLanguage( nInsPos ) ) ) + FnAddNonBrkSpace( rDoc, rTxt, nInsPos, rDoc.GetLanguage( nInsPos ), io_bNbspRunNext ) ) { ; } |