sw/qa/extras/uiwriter/uiwriter7.cxx |   20 ++++++++++++++++++--
 sw/source/uibase/shells/textsh1.cxx |   10 ++++++----
 2 files changed, 24 insertions(+), 6 deletions(-)

New commits:
commit 00ae2560e32d4a2f40a4580a602d495450465d8f
Author:     Mike Kaganski <mike.kagan...@collabora.com>
AuthorDate: Wed Aug 28 17:18:09 2024 +0500
Commit:     Xisco Fauli <xiscofa...@libreoffice.org>
CommitDate: Mon Sep 2 09:37:16 2024 +0200

    tdf#162656: make sure to replace correct range
    
    ToggleUnicodeCodepoint::CharsToDelete returns number of codepoints,
    while SwWrtShell::DelLeft operates glyphs, which may consist of a
    number of combining codepoints.
    
    Change-Id: I394ee76c576f2e6f921cb30d125cce2f83559608
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/172532
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>
    Signed-off-by: Xisco Fauli <xiscofa...@libreoffice.org>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/172548

diff --git a/sw/qa/extras/uiwriter/uiwriter7.cxx 
b/sw/qa/extras/uiwriter/uiwriter7.cxx
index 7281f45073cb..d8744f7f95d0 100644
--- a/sw/qa/extras/uiwriter/uiwriter7.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter7.cxx
@@ -2399,11 +2399,27 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest7, 
testUnicodeNotationToggle)
     dispatchCommand(mxComponent, u".uno:UnicodeNotationToggle"_ustr, 
aPropertyValues);
     sExpectedString = "u+";
     sDocString = 
pWrtShell->GetCursor()->GetPointNode().GetTextNode()->GetText();
-    CPPUNIT_ASSERT_EQUAL(sDocString, sExpectedString);
+    CPPUNIT_ASSERT_EQUAL(sExpectedString, sDocString);
 
     dispatchCommand(mxComponent, u".uno:UnicodeNotationToggle"_ustr, 
aPropertyValues);
     sDocString = 
pWrtShell->GetCursor()->GetPointNode().GetTextNode()->GetText();
-    CPPUNIT_ASSERT_EQUAL(sDocString, sOriginalDocString);
+    CPPUNIT_ASSERT_EQUAL(sOriginalDocString, sDocString);
+
+    constexpr OUString sWithCombiningSMPName = u"xyzU+e0101"_ustr;
+    constexpr OUString sWithCombiningSMP = u"xyz\U000e0101"_ustr;
+    pWrtShell->SplitNode();
+    pWrtShell->Insert2(sWithCombiningSMPName);
+    dispatchCommand(mxComponent, u".uno:UnicodeNotationToggle"_ustr, 
aPropertyValues);
+    sDocString = 
pWrtShell->GetCursor()->GetPointNode().GetTextNode()->GetText();
+    CPPUNIT_ASSERT_EQUAL(sWithCombiningSMP, sDocString);
+
+    dispatchCommand(mxComponent, u".uno:UnicodeNotationToggle"_ustr, 
aPropertyValues);
+    sDocString = 
pWrtShell->GetCursor()->GetPointNode().GetTextNode()->GetText();
+    // Before tdf#162656 fix, this failed with
+    // - Expected: xyzU+e0101
+    // - Actual  : xyU+e0101
+    // i.e., one codepoint to the left of the combining codepoint was removed
+    CPPUNIT_ASSERT_EQUAL(sWithCombiningSMPName, sDocString);
 }
 
 CPPUNIT_TEST_FIXTURE(SwUiWriterTest7, testTdf34957)
diff --git a/sw/source/uibase/shells/textsh1.cxx 
b/sw/source/uibase/shells/textsh1.cxx
index 0144b01dbfaf..2ef36ff57c9a 100644
--- a/sw/source/uibase/shells/textsh1.cxx
+++ b/sw/source/uibase/shells/textsh1.cxx
@@ -815,8 +815,9 @@ void SwTextShell::Execute(SfxRequest &rReq)
                     rWrtSh.InfoReadOnlyDialog(false);
                     break;
                 }
+                OUString stringToReplace = aToggle.StringToReplace();
                 SwRewriter aRewriter;
-                aRewriter.AddRule( UndoArg1, aToggle.StringToReplace() );
+                aRewriter.AddRule( UndoArg1, stringToReplace );
                 aRewriter.AddRule( UndoArg2, SwResId(STR_YIELDS) );
                 aRewriter.AddRule( UndoArg3, sReplacement );
                 rWrtSh.StartUndo(SwUndoId::REPLACE, &aRewriter);
@@ -825,9 +826,10 @@ void SwTextShell::Execute(SfxRequest &rReq)
                 rWrtSh.ClearMark();
                 if( rWrtSh.IsInSelect() )  // cancel any in-progress keyboard 
selection as well
                     rWrtSh.EndSelect();
-
-                for( sal_uInt32 i=aToggle.CharsToDelete(); i > 0; --i )
-                    rWrtSh.DelLeft();
+                // Select exactly what was chosen for replacement
+                rWrtSh.GetCursor()->SetMark();
+                
rWrtSh.GetCursor()->GetPoint()->AdjustContent(-stringToReplace.getLength());
+                rWrtSh.DelLeft();
                 rWrtSh.Insert2( sReplacement );
                 rWrtSh.EndUndo(SwUndoId::REPLACE, &aRewriter);
             }

Reply via email to