[Libreoffice-commits] core.git: Branch 'libreoffice-5-4' - editeng/qa editeng/source include/editeng sc/source sw/inc sw/source

Eike Rathke erack at redhat.com
Tue Sep 5 14:24:36 UTC 2017


 editeng/qa/unit/core-test.cxx       |   15 ++++++++----
 editeng/source/editeng/editeng.cxx  |    3 --
 editeng/source/editeng/impedit.hxx  |    6 +++++
 editeng/source/editeng/impedit2.cxx |    5 ++--
 editeng/source/misc/svxacorr.cxx    |   42 ++++++++++++++++++------------------
 include/editeng/svxacorr.hxx        |   18 ++++++++-------
 sc/source/ui/app/inputhdl.cxx       |    8 ++++++
 sc/source/ui/app/inputwin.cxx       |    6 +++++
 sc/source/ui/inc/inputhdl.hxx       |    1 
 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 +---
 13 files changed, 87 insertions(+), 46 deletions(-)

New commits:
commit c5fcab1ec72be1cf2868215ee71d3cb2668498c1
Author: Eike Rathke <erack at redhat.com>
Date:   Wed Aug 23 17:44:16 2017 +0200

    Resolves: tdf#108795 merge table EditEngine language attributes to input line
    
    ... and change SvxAutoCorrect to be stateless again to make that work.
    
     This is a combination of 3 commits.
    
    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.
    
    Reviewed-on: https://gerrit.libreoffice.org/41475
    Reviewed-by: Eike Rathke <erack at redhat.com>
    Tested-by: Jenkins <ci at libreoffice.org>
    (cherry picked from commit 06d14411a447cd798d1f0678a3c5e06f5278a1cb)
    
    Backported.
    
    Related: tdf#108795 never use an unresolved LANGUAGE_SYSTEM in SvxAutoCorrect
    
    Substitute with the current work locale, using MsLangId::getSystemLanguage()
    instead was also wrong.
    
    Reviewed-on: https://gerrit.libreoffice.org/41476
    Reviewed-by: Eike Rathke <erack at redhat.com>
    Tested-by: Jenkins <ci at libreoffice.org>
    (cherry picked from commit 311be7d70146e4963e4dfd1f39d6c71d45d241ca)
    
    Resolves: tdf#108795 merge table EditEngine language attributes to input line
    
    ... when editing there, so the SvxAutoCorrect behaviour is synchronized.
    Depends on commit 06d14411a447cd798d1f0678a3c5e06f5278a1cb that disentangles
    the stateful SvxAutoCorrect instance.
    
    Reviewed-on: https://gerrit.libreoffice.org/41521
    Reviewed-by: Eike Rathke <erack at redhat.com>
    Tested-by: Eike Rathke <erack at redhat.com>
    (cherry picked from commit d31a8263d564ebd7886f6debdf36cedd031915ea)
    
    55db3bc1f76329320afc1f366d7426a8c2f66fb2
    c6aac1f2acc36b500144be50a20a4784a3ba62dc
    
    Change-Id: I79a26d2ba44cc40771979a78b686c89f0c80b412
    Reviewed-on: https://gerrit.libreoffice.org/41525
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>

diff --git a/editeng/qa/unit/core-test.cxx b/editeng/qa/unit/core-test.cxx
index f620a72d8843..d2b8affea7a1 100644
--- a/editeng/qa/unit/core-test.cxx
+++ b/editeng/qa/unit/core-test.cxx
@@ -334,9 +334,10 @@ void Test::testAutocorrect()
         OUString sInput("TEst-TEst");
         sal_Unicode cNextChar(' ');
         OUString 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());
     }
@@ -345,9 +346,10 @@ void Test::testAutocorrect()
         OUString sInput("TEst/TEst");
         sal_Unicode cNextChar(' ');
         OUString 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());
     }
@@ -357,9 +359,10 @@ void Test::testAutocorrect()
         OUString sInput("*foo");
         sal_Unicode cNextChar('*');
         OUString 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());
     }
@@ -368,9 +371,10 @@ void Test::testAutocorrect()
         OUString sInput("Test. test");
         sal_Unicode cNextChar(' ');
         OUString 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());
     }
@@ -379,9 +383,10 @@ void Test::testAutocorrect()
         OUString sInput("Test. \x01 test");
         sal_Unicode cNextChar(' ');
         OUString 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());
     }
diff --git a/editeng/source/editeng/editeng.cxx b/editeng/source/editeng/editeng.cxx
index 556cbaa8eace..e52377d85596 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->DrawSelection();
                     // 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 a125a97e34f0..442f35e7c3b9 100644
--- a/editeng/source/editeng/impedit.hxx
+++ b/editeng/source/editeng/impedit.hxx
@@ -520,6 +520,8 @@ private:
     bool            mbLastTryMerge:1;
     bool            mbReplaceLeadingSingleQuotationMark:1;
 
+    bool            mbNbspRunNext;  // can't be a bitfield as it is passed as bool&
+
 
     // Methods...
 
@@ -1037,6 +1039,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 950a5bf79f1b..1bb1cc58be50 100644
--- a/editeng/source/editeng/impedit2.cxx
+++ b/editeng/source/editeng/impedit2.cxx
@@ -105,7 +105,8 @@ ImpEditEngine::ImpEditEngine( EditEngine* pEE, SfxItemPool* pItemPool ) :
     bImpConvertFirstCall(false),
     bFirstWordCapitalization(true),
     mbLastTryMerge(false),
-    mbReplaceLeadingSingleQuotationMark(true)
+    mbReplaceLeadingSingleQuotationMark(true),
+    mbNbspRunNext(false)
 {
     pEditEngine         = pEE;
     pRefDev             = nullptr;
@@ -2566,7 +2567,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 f112d3d536f8..7f0b303c1f4c 100644
--- a/editeng/source/misc/svxacorr.cxx
+++ b/editeng/source/misc/svxacorr.cxx
@@ -203,6 +203,16 @@ static const LanguageTag& GetAppLang()
 {
     return Application::GetSettings().GetLanguageTag();
 }
+
+/// Never use an unresolved LANGUAGE_SYSTEM.
+static LanguageType GetDocLanguage( const SvxAutoCorrDoc& rDoc, sal_Int32 nPos )
+{
+    LanguageType eLang = rDoc.GetLanguage( nPos );
+    if (eLang == LANGUAGE_SYSTEM)
+        eLang = GetAppLang().getLanguageType();     // the current work locale
+    return eLang;
+}
+
 static LocaleDataWrapper& GetLocaleDataWrapper( LanguageType nLang )
 {
     static LocaleDataWrapper aLclDtWrp( GetAppLang() );
@@ -296,7 +306,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 +321,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 +638,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 +697,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) )
@@ -1167,7 +1175,7 @@ void SvxAutoCorrect::InsertQuote( SvxAutoCorrDoc& rDoc, sal_Int32 nInsPos,
                                     sal_Unicode cInsChar, bool bSttQuote,
                                     bool bIns )
 {
-    LanguageType eLang = rDoc.GetLanguage( nInsPos );
+    const LanguageType eLang = GetDocLanguage( rDoc, nInsPos );
     sal_Unicode cRet = GetQuote( cInsChar, bSttQuote, eLang );
 
     OUString sChg( cInsChar );
@@ -1180,8 +1188,6 @@ void SvxAutoCorrect::InsertQuote( SvxAutoCorrDoc& rDoc, sal_Int32 nInsPos,
 
     if( '\"' == cInsChar )
     {
-        if( LANGUAGE_SYSTEM == eLang )
-            eLang = GetAppLang().getLanguageType();
         if( eLang.anyOf(
             LANGUAGE_FRENCH,
             LANGUAGE_FRENCH_BELGIAN,
@@ -1207,15 +1213,13 @@ void SvxAutoCorrect::InsertQuote( SvxAutoCorrDoc& rDoc, sal_Int32 nInsPos,
 OUString SvxAutoCorrect::GetQuote( SvxAutoCorrDoc& rDoc, sal_Int32 nInsPos,
                                 sal_Unicode cInsChar, bool bSttQuote )
 {
-    LanguageType eLang = rDoc.GetLanguage( nInsPos );
+    const LanguageType eLang = GetDocLanguage( rDoc, nInsPos );
     sal_Unicode cRet = GetQuote( cInsChar, bSttQuote, eLang );
 
     OUString sRet = OUString(cRet);
 
     if( '\"' == cInsChar )
     {
-        if( LANGUAGE_SYSTEM == eLang )
-            eLang = GetAppLang().getLanguageType();
         if( eLang.anyOf(
              LANGUAGE_FRENCH,
              LANGUAGE_FRENCH_BELGIAN,
@@ -1234,10 +1238,10 @@ OUString SvxAutoCorrect::GetQuote( SvxAutoCorrDoc& rDoc, sal_Int32 nInsPos,
 
 void SvxAutoCorrect::DoAutoCorrect( SvxAutoCorrDoc& rDoc, const OUString& rTxt,
                                     sal_Int32 nInsPos, sal_Unicode cChar,
-                                    bool bInsert, vcl::Window* pFrameWin )
+                                    bool bInsert, bool& io_bNbspRunNext, vcl::Window* 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 +1280,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, GetDocLanguage( rDoc, nInsPos ), io_bNbspRunNext ) )
                 {
                     ;
                 }
@@ -1333,9 +1337,7 @@ void SvxAutoCorrect::DoAutoCorrect( SvxAutoCorrDoc& rDoc, const OUString& rTxt,
         if( !nPos && !IsWordDelim( rTxt[ 0 ]))
             --nCapLttrPos;          // begin of paragraph and no blank
 
-        LanguageType eLang = rDoc.GetLanguage( nCapLttrPos );
-        if( LANGUAGE_SYSTEM == eLang )
-            eLang = MsLangId::getSystemLanguage();
+        const LanguageType eLang = GetDocLanguage( rDoc, nCapLttrPos );
         CharClass& rCC = GetCharClass( eLang );
 
         // no symbol characters
@@ -1546,9 +1548,7 @@ bool SvxAutoCorrect::GetPrevAutoCorrWord( SvxAutoCorrDoc& rDoc,
     if( 3 > nEnde - nCapLttrPos )
         return false;
 
-    LanguageType eLang = rDoc.GetLanguage( nCapLttrPos );
-    if( LANGUAGE_SYSTEM == eLang )
-        eLang = MsLangId::getSystemLanguage();
+    const LanguageType eLang = GetDocLanguage( rDoc, nCapLttrPos );
 
     SvxAutoCorrect* pThis = const_cast<SvxAutoCorrect*>(this);
     CharClass& rCC = pThis->GetCharClass( eLang );
diff --git a/include/editeng/svxacorr.hxx b/include/editeng/svxacorr.hxx
index 1cc14c0214ae..30ce54016545 100644
--- a/include/editeng/svxacorr.hxx
+++ b/include/editeng/svxacorr.hxx
@@ -236,8 +236,6 @@ class EDITENG_DLLPUBLIC SvxAutoCorrect
     std::map<LanguageTag, sal_Int64> aLastFileTable;
     std::unique_ptr<CharClass> pCharClass;
 
-    bool bRunNext;
-
     LanguageType eCharClassLang;
 
     long nFlags;
@@ -274,13 +272,19 @@ public:
     SvxAutoCorrect( const SvxAutoCorrect& );
     virtual ~SvxAutoCorrect();
 
-    // Execute an AutoCorrect.
-    // Returns what has been executed, according to the above flags
+    /** Execute an AutoCorrect.
+        Returns what has been executed, according to the above auto correct flags.
+        @param  io_bNbspRunNext
+                Remembers if a NO-BREAK SPACE was added (eg. in "fr" language)
+                (set to <TRUE/>) at the last character input that may have to
+                be removed again depending on what character is following.
+     */
     // FIXME: this has the horrible flaw that the rTxt must be a reference
     // to the actual SwTxtNode/EditNode string because it inserts the character
     // in rDoc and expects that to side-effect rTxt
     void DoAutoCorrect( SvxAutoCorrDoc& rDoc, const OUString& rTxt,
-                           sal_Int32 nPos, sal_Unicode cInsChar, bool bInsert, vcl::Window* pFrameWin = nullptr );
+                           sal_Int32 nPos, sal_Unicode cInsChar, bool bInsert, bool& io_bNbspRunNext,
+                           vcl::Window* pFrameWin = nullptr );
 
     // Return for the autotext expansion the previous word,
     // AutoCorrect - corresponding algorithm
@@ -383,7 +387,7 @@ public:
                                 LanguageType eLang );
     bool FnAddNonBrkSpace( SvxAutoCorrDoc&, const OUString&,
                                 sal_Int32 nEndPos,
-                                LanguageType eLang );
+                                LanguageType eLang, bool& io_bNbspRunNext );
     bool FnSetINetAttr( SvxAutoCorrDoc&, const OUString&,
                                 sal_Int32 nSttPos, sal_Int32 nEndPos,
                                 LanguageType eLang );
@@ -396,8 +400,6 @@ public:
                             sal_Int32 nSttPos, sal_Int32 nEndPos,
                             LanguageType eLang );
 
-    bool                HasRunNext() { return bRunNext; }
-
     static long         GetDefaultFlags();
 
 // returns sal_True for characters where the function
diff --git a/sc/source/ui/app/inputhdl.cxx b/sc/source/ui/app/inputhdl.cxx
index dfbd1c43bbb3..cc702882c72e 100644
--- a/sc/source/ui/app/inputhdl.cxx
+++ b/sc/source/ui/app/inputhdl.cxx
@@ -2184,6 +2184,14 @@ bool ScInputHandler::StartTable( sal_Unicode cTyped, bool bFromCommand, bool bIn
     return bNewTable;
 }
 
+void ScInputHandler::MergeLanguageAttributes( ScEditEngineDefaulter& rDestEngine ) const
+{
+    const SfxItemSet& rSrcSet = mpEditEngine->GetDefaults();
+    rDestEngine.SetDefaultItem( rSrcSet.Get( EE_CHAR_LANGUAGE ));
+    rDestEngine.SetDefaultItem( rSrcSet.Get( EE_CHAR_LANGUAGE_CJK ));
+    rDestEngine.SetDefaultItem( rSrcSet.Get( EE_CHAR_LANGUAGE_CTL ));
+}
+
 static void lcl_SetTopSelection( EditView* pEditView, ESelection& rSel )
 {
     OSL_ENSURE( rSel.nStartPara==0 && rSel.nEndPara==0, "SetTopSelection: Para != 0" );
diff --git a/sc/source/ui/app/inputwin.cxx b/sc/source/ui/app/inputwin.cxx
index 243783490cbb..6ef5adab11c2 100644
--- a/sc/source/ui/app/inputwin.cxx
+++ b/sc/source/ui/app/inputwin.cxx
@@ -1108,7 +1108,13 @@ void ScTextWnd::StartEditEngine()
 
     ScInputHandler* pHdl = mpViewShell->GetInputHandler();
     if (pHdl)
+    {
+        bool bStarting = !pHdl->IsEditMode();
         pHdl->SetMode(SC_INPUT_TOP);
+        if (bStarting)
+            // necessary to sync SvxAutoCorrect behavior
+            pHdl->MergeLanguageAttributes( *mpEditEngine);
+    }
 
     SfxViewFrame* pViewFrm = SfxViewFrame::Current();
     if (pViewFrm)
diff --git a/sc/source/ui/inc/inputhdl.hxx b/sc/source/ui/inc/inputhdl.hxx
index dd36ff84219b..b4c98b3edc2b 100644
--- a/sc/source/ui/inc/inputhdl.hxx
+++ b/sc/source/ui/inc/inputhdl.hxx
@@ -180,6 +180,7 @@ public:
     const ScAddress& GetCursorPos() const   { return aCursorPos; }
 
     bool            GetTextAndFields( ScEditEngineDefaulter& rDestEngine );
+    void            MergeLanguageAttributes( ScEditEngineDefaulter& rDestEngine ) const;
 
     bool            KeyInput( const KeyEvent& rKEvt, bool bStartEdit );
     void            EnterHandler( ScEnterMode nBlockMode = ScEnterMode::NORMAL );
diff --git a/sw/inc/editsh.hxx b/sw/inc/editsh.hxx
index 6f3669a95ba1..a36155dc73a0 100644
--- a/sw/inc/editsh.hxx
+++ b/sw/inc/editsh.hxx
@@ -942,6 +942,8 @@ public:
      character attribute dialog. */
     sal_uInt16 GetScalingOfSelectedText() const;
 
+    bool IsNbspRunNext() const { return m_bNbspRunNext; }
+
     /// Ctor/Dtor.
     SwEditShell( SwDoc&, vcl::Window*, const SwViewOption *pOpt );
 
@@ -952,6 +954,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 f9a992833f10..3323b4cd0a52 100644
--- a/sw/source/core/edit/autofmt.cxx
+++ b/sw/source/core/edit/autofmt.cxx
@@ -1832,6 +1832,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();
 
@@ -1985,7 +1986,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;
@@ -2042,7 +2043,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 ab99d1eebf8f..8fef364315c0 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 f69e8c64184d..e9097d19fc72 100644
--- a/sw/source/uibase/docvw/edtwin.cxx
+++ b/sw/source/uibase/docvw/edtwin.cxx
@@ -2429,8 +2429,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 ) ) ||
@@ -2442,7 +2441,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 |


More information about the Libreoffice-commits mailing list