sw/inc/editsh.hxx                   |    4 +++
 sw/source/core/edit/eddel.cxx       |   46 ++++++++++++++++++++++++++++++++++++
 sw/source/core/edit/edlingu.cxx     |   15 -----------
 sw/source/uibase/shells/textsh1.cxx |   23 ++----------------
 4 files changed, 54 insertions(+), 34 deletions(-)

New commits:
commit 6da9d629f7f17ec569e7fb6d0f1931dd410b1d28
Author:     EMartinGube <martin.g...@web.de>
AuthorDate: Thu Jul 20 23:33:37 2023 +0200
Commit:     Mike Kaganski <mike.kagan...@collabora.com>
CommitDate: Sun Oct 15 07:42:07 2023 +0200

    tdf#156250: sw: Keep comments when spell correction replaces a word
    
    New method SwEditShell:ReplaceKeepComments for comment preserving
    spell correction.
    
    Change-Id: Ifdb9d5664ab8d457a16ad8f7ec62dd968c89d580
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/154761
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>

diff --git a/sw/inc/editsh.hxx b/sw/inc/editsh.hxx
index 8fc1afb9483a..a3b181440237 100644
--- a/sw/inc/editsh.hxx
+++ b/sw/inc/editsh.hxx
@@ -172,6 +172,10 @@ public:
            --> "xx\t<Tab>..zzz..&" */
     bool Replace( const OUString& rNewStr, bool bRegExpRplc );
 
+    /** Replace a selected range in a TextNode by given string.
+     Possible comments will be kept (moved to the end of the selection). */
+    bool ReplaceKeepComments( const OUString& rNewStr);
+
     /** Delete content of all ranges.
      If whole nodes are selected, these nodes get deleted. */
     bool Delete(bool isArtificialSelection = false);
diff --git a/sw/source/core/edit/eddel.cxx b/sw/source/core/edit/eddel.cxx
index 10d086bbac63..989cddfd3a28 100644
--- a/sw/source/core/edit/eddel.cxx
+++ b/sw/source/core/edit/eddel.cxx
@@ -359,6 +359,52 @@ bool SwEditShell::Replace( const OUString& rNewStr, bool 
bRegExpRplc )
     return bRet;
 }
 
+/** Replace a selected area in a text node with a given string.
+ *
+ * Method to replace a text selection with a new string while
+ * keeping possible comments (they will be moved to the end
+ * of the selection).
+ *
+ * @param rNewStr     the new string which the selected area is to be replaced 
with
+ * @return            true, if something has been replaced, false otherwise.
+ */
+bool SwEditShell::ReplaceKeepComments( const OUString& rNewStr)
+{
+    bool bRet       = false;
+    SwPaM *pCursor  = GetCursor();
+
+    if(pCursor != nullptr)
+    {
+        // go sure that the text selection pointed to by pCursor is valid
+        if(pCursor->HasMark())
+        {
+            // preserve comments inside of the number by deleting number 
portions starting from the back
+            OUString aSelectedText = pCursor->GetText();
+            sal_Int32 nCommentPos(aSelectedText.lastIndexOf(CH_TXTATR_INWORD));
+            // go sure that we have a valid selection and a comment has been 
found
+            while((nCommentPos > -1) && (aSelectedText.getLength() > 0) && 
(pCursor->HasMark()))
+            {
+                // select the part of the text after the last found comment
+                // selection start:
+                pCursor->GetPoint()->AdjustContent(nCommentPos + 1);
+                // selection end ist left where it is -> will be adjusted 
later on
+                // delete the part of the word after the last found comment
+                Replace(OUString(), false);
+                // put the selection start back to the beginning of the word
+                pCursor->GetPoint()->AdjustContent(-(nCommentPos + 1));
+                // adjust the selection end, so that the last comment is no 
longer selected:
+                pCursor->GetMark()->AdjustContent(-1);
+                // search for the next possible comment
+                aSelectedText = pCursor->GetText();
+                nCommentPos = aSelectedText.lastIndexOf(CH_TXTATR_INWORD);
+            }
+            bRet = Replace(rNewStr, false);
+        }
+    }
+
+    return bRet;
+}
+
 /// special method for JOE's wizards
 bool SwEditShell::DelFullPara()
 {
diff --git a/sw/source/core/edit/edlingu.cxx b/sw/source/core/edit/edlingu.cxx
index ab89fc5b7241..63ea37ba8233 100644
--- a/sw/source/core/edit/edlingu.cxx
+++ b/sw/source/core/edit/edlingu.cxx
@@ -1167,20 +1167,7 @@ void SwEditShell::ApplyChangedSentence(const 
svx::SpellPortions& rNewPortions, b
 
                 // if there is a comment inside the original word, don't 
delete it:
                 // but keep it at the end of the replacement
-                // TODO: keep all the comments with a recursive function
-                sal_Int32 
nCommentPos(pCursor->GetText().indexOf(OUStringChar(CH_TXTATR_INWORD)));
-                if ( nCommentPos > -1 )
-                {
-                    // delete the original word after the comment
-                    pCursor->GetPoint()->AdjustContent(nCommentPos + 1);
-
-                    
mxDoc->getIDocumentContentOperations().ReplaceRange(*pCursor, OUString(), 
false);
-                    // and select only the remaining part before the comment
-                    pCursor->GetPoint()->AdjustContent(-(nCommentPos + 1));
-                    pCursor->GetMark()->AdjustContent(-1);
-                }
-
-                mxDoc->getIDocumentContentOperations().ReplaceRange(*pCursor, 
aCurrentNewPortion->sText, false);
+                ReplaceKeepComments(aCurrentNewPortion->sText);
             }
             else if(aCurrentNewPortion->eLanguage != 
aCurrentOldPortion->eLanguage)
             {
diff --git a/sw/source/uibase/shells/textsh1.cxx 
b/sw/source/uibase/shells/textsh1.cxx
index c92384dbd103..e93fa6613309 100644
--- a/sw/source/uibase/shells/textsh1.cxx
+++ b/sw/source/uibase/shells/textsh1.cxx
@@ -2128,26 +2128,9 @@ void SwTextShell::Execute(SfxRequest &rReq)
         rWrtSh.StartUndo(SwUndoId::UI_REPLACE, &aRewriter);
         rWrtSh.StartAction();
 
-        // if there is a comment inside the original word, don't delete it:
-        // but keep it at the end of the replacement
-        // TODO: keep all the comments with a recursive function
-
-        if (SwPaM *pPaM = rWrtSh.GetCursor())
-        {
-            sal_Int32 
nCommentPos(pPaM->GetText().indexOf(OUStringChar(CH_TXTATR_INWORD)));
-            if ( nCommentPos > -1 )
-            {
-
-                // delete the original word after the comment
-                pPaM->GetPoint()->AdjustContent(nCommentPos + 1);
-                rWrtSh.Replace(OUString(), false);
-                // and select only the remaining part before the comment
-                pPaM->GetPoint()->AdjustContent(-(nCommentPos + 1));
-                pPaM->GetMark()->AdjustContent(-1);
-            }
-        }
-
-        rWrtSh.Replace(aTmp, false);
+        // keep comments at the end of the replacement in case spelling 
correction is
+        // invoked via the context menu. The spell check dialog does the 
correction in edlingu.cxx.
+        rWrtSh.ReplaceKeepComments(aTmp);
 
         rWrtSh.EndAction();
         rWrtSh.EndUndo();

Reply via email to