sw/qa/core/doc/DocumentRedlineManager.cxx     |   32 ++++++++++++++++++++++++++
 sw/qa/core/doc/data/ins-then-format-self.docx |binary
 sw/source/core/doc/DocumentRedlineManager.cxx |    9 ++++++-
 3 files changed, 40 insertions(+), 1 deletion(-)

New commits:
commit c80832085d6606a082c7052d07262d95d20cb0db
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Tue Jul 15 08:23:09 2025 +0200
Commit:     Xisco Fauli <xiscofa...@libreoffice.org>
CommitDate: Tue Jul 15 17:33:20 2025 +0200

    tdf#166319 sw interdependent redlines: handle deleting a self ins-then-fmt
    
    The bugdoc has <ins>A<format>B</format>C</ins>, go to the end, delete C,
    result is <ins>A<format>B</format></ins> given that this was a
    self-insert, but the next delete results in <ins>A</ins><del>B</del>.
    
    The problem is that we have special code to deal with delete on
    self-insert (it's fine to just remove such content from the model), but
    this code won't handle insert-then-format as insert, while Word does.
    
    Fix the problem by extending
    DocumentRedlineManager::PreAppendDeleteRedline() to look "through" just
    format redlines to see the underlying insert.
    
    Note that the same is not needed for delete-then-format, since insert is
    always inserted next to an existing content or redlined content, so
    there is no overlap.
    
    Change-Id: I8b47839ffaa470714a5dd37722aa26ac0002c0bc
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/187907
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Tested-by: Jenkins
    (cherry picked from commit f66d63da05dbe2f254ffaf428257684a38523f66)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/187921
    Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org>

diff --git a/sw/qa/core/doc/DocumentRedlineManager.cxx 
b/sw/qa/core/doc/DocumentRedlineManager.cxx
index 77f36c8012f1..8fac406a45aa 100644
--- a/sw/qa/core/doc/DocumentRedlineManager.cxx
+++ b/sw/qa/core/doc/DocumentRedlineManager.cxx
@@ -10,12 +10,15 @@
 #include <swmodeltestbase.hxx>
 
 #include <editeng/wghtitem.hxx>
+#include <comphelper/scopeguard.hxx>
 
 #include <IDocumentRedlineAccess.hxx>
 #include <docsh.hxx>
 #include <redline.hxx>
 #include <view.hxx>
 #include <wrtsh.hxx>
+#include <swmodule.hxx>
+#include <strings.hrc>
 
 namespace
 {
@@ -96,6 +99,35 @@ CPPUNIT_TEST_FIXTURE(Test, testRedlineIns)
         CPPUNIT_ASSERT_EQUAL(RedlineType::Insert, rRedlines[2]->GetType());
     }
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testInsThenFormatSelf)
+{
+    // Given a document with <ins>A<format>B</format>C</ins> redlines, created 
by Alice:
+    createSwDoc("ins-then-format-self.docx");
+    SwModule* pModule = SwModule::get();
+    pModule->SetRedlineAuthor("Alice");
+    comphelper::ScopeGuard g(
+        [pModule] { 
pModule->SetRedlineAuthor(SwResId(STR_REDLINE_UNKNOWN_AUTHOR)); });
+    SwDocShell* pDocShell = getSwDocShell();
+    SwWrtShell* pWrtShell = pDocShell->GetWrtShell();
+    pWrtShell->SttEndDoc(/*bStt=*/false);
+    SwDoc* pDoc = pDocShell->GetDoc();
+    IDocumentRedlineAccess& rIDRA = pDoc->getIDocumentRedlineAccess();
+    SwRedlineTable& rRedlines = rIDRA.GetRedlineTable();
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), rRedlines.size());
+    pWrtShell->DelLeft();
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), rRedlines.size());
+
+    // When deleting B:
+    pWrtShell->DelLeft();
+
+    // Then make sure that B is removed from the document (since this is a 
self-insert):
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: 1
+    // - Actual  : 2
+    // i.e. a delete was created instead of removing the insert.
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rRedlines.size());
+}
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/qa/core/doc/data/ins-then-format-self.docx 
b/sw/qa/core/doc/data/ins-then-format-self.docx
new file mode 100644
index 000000000000..55e90fbae7ac
Binary files /dev/null and b/sw/qa/core/doc/data/ins-then-format-self.docx 
differ
diff --git a/sw/source/core/doc/DocumentRedlineManager.cxx 
b/sw/source/core/doc/DocumentRedlineManager.cxx
index f19d352e4888..0eb97aeb3339 100644
--- a/sw/source/core/doc/DocumentRedlineManager.cxx
+++ b/sw/source/core/doc/DocumentRedlineManager.cxx
@@ -1918,7 +1918,14 @@ void 
DocumentRedlineManager::PreAppendInsertRedline(AppendRedlineContext& rCtx)
 
 void DocumentRedlineManager::PreAppendDeleteRedline(AppendRedlineContext& rCtx)
 {
-    switch( rCtx.pRedl->GetType() )
+    RedlineType eRedlType = rCtx.pRedl->GetType();
+    bool bHierarchicalFormat = rCtx.pRedl->GetType() == RedlineType::Format && 
rCtx.pRedl->GetStackCount() > 1;
+    if (bHierarchicalFormat && rCtx.pRedl->GetType(1) == RedlineType::Insert)
+    {
+        eRedlType = rCtx.pRedl->GetType(1);
+    }
+
+    switch (eRedlType)
     {
     case RedlineType::Delete:
         switch( rCtx.eCmpPos )

Reply via email to