sw/inc/docary.hxx                             |    2 +-
 sw/qa/core/doc/doc.cxx                        |   23 +++++++++++++++++++++++
 sw/source/core/doc/DocumentRedlineManager.cxx |   13 ++++++++++++-
 3 files changed, 36 insertions(+), 2 deletions(-)

New commits:
commit 8cabdef0b34210d026ea7a8229f321e272a49109
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Thu May 22 08:43:06 2025 +0200
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Thu May 22 14:52:23 2025 +0200

    tdf#166319 sw interdependent redlines: handle accept of ins-then-fmt's fmt
    
    The bugdoc has <ins>AA<format>BB</format>CC</ins> in it, accepting the
    "BB" part resulted in a fully accepted portion, while the expected
    result is to accept the underlying insert, like in Word.
    
    The problem is that the accept code is not aware that the format has an
    underlying insert, so the format gets accepted and as a side effect the
    insert redline is gone, too.
    
    Fix this by extending DocumentRedlineManager::AcceptRedlineRange() to
    just get rid of the inner redline in the insert-then-format case, which
    results in a plain format redline, as wanted. lcl_DeleteInnerRedline()
    can do exactly this, added already in commit
    f468d61755fad1e38e481f8f439bbce9161a3aa7 (tdf#166319 sw interdependent
    redlines: handle reject of delete under format, 2025-05-16).
    
    Connecting this (effectively) insert redline (insert-then-format, to be
    precise) with the surrounding plain insert redlines is not done yet,
    though.
    
    Change-Id: I64e2ab1f6a6ce7872c3e4ea7b0bfb0c542c611ed
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/185653
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Tested-by: Jenkins

diff --git a/sw/inc/docary.hxx b/sw/inc/docary.hxx
index 248c7bfb510b..a05a8cba2fe3 100644
--- a/sw/inc/docary.hxx
+++ b/sw/inc/docary.hxx
@@ -213,7 +213,7 @@ struct CompareSwRedlineTable
 // Notification type for notifying about redlines to LOK clients
 enum class RedlineNotification { Add, Remove, Modify };
 
-class SwRedlineTable
+class SW_DLLPUBLIC SwRedlineTable
 {
 public:
     typedef o3tl::sorted_vector<SwRangeRedline*, CompareSwRedlineTable,
diff --git a/sw/qa/core/doc/doc.cxx b/sw/qa/core/doc/doc.cxx
index 62ddfb9bab26..f708bbf23827 100644
--- a/sw/qa/core/doc/doc.cxx
+++ b/sw/qa/core/doc/doc.cxx
@@ -790,6 +790,29 @@ CPPUNIT_TEST_FIXTURE(SwCoreDocTest, testInsThenFormat)
     CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0), rRedlines.size());
     // Also make sure the text of the format-on-insert redline is removed.
     CPPUNIT_ASSERT(pTextNode->GetText().isEmpty());
+
+    // And when accepting the format-on-insert:
+    pWrtShell->Undo();
+    CPPUNIT_ASSERT_EQUAL(u"AAABBBCCC"_ustr, pTextNode->GetText());
+    SwPaM* pCursor = pWrtShell->GetCursor();
+    pCursor->DeleteMark();
+    pWrtShell->SttEndDoc(/*bStt=*/true);
+    // Move inside "BBB".
+    pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/false, 4, 
/*bBasicCall=*/false);
+    SwRedlineTable::size_type nRedline{};
+    rRedlines.FindAtPosition(*pCursor->Start(), nRedline);
+    pWrtShell->AcceptRedline(nRedline);
+
+    // Then make sure the format is kept and the insert is accepted:
+    pWrtShell->SttEndDoc(/*bStt=*/true);
+    // Move inside "BBB".
+    pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/false, 4, 
/*bBasicCall=*/false);
+    const SwRangeRedline* pRedline = 
rRedlines.FindAtPosition(*pCursor->Start(), nRedline);
+    // Without the accompanying fix in place, this test would have failed, 
there was no redline for
+    // "BBB".
+    CPPUNIT_ASSERT(pRedline);
+    CPPUNIT_ASSERT_EQUAL(RedlineType::Format, pRedline->GetType());
+    CPPUNIT_ASSERT(!pRedline->GetRedlineData().Next());
 }
 
 CPPUNIT_TEST_FIXTURE(SwCoreDocTest, testDelThenFormat)
diff --git a/sw/source/core/doc/DocumentRedlineManager.cxx 
b/sw/source/core/doc/DocumentRedlineManager.cxx
index 7cbb483fb0a1..0c16551b65c2 100644
--- a/sw/source/core/doc/DocumentRedlineManager.cxx
+++ b/sw/source/core/doc/DocumentRedlineManager.cxx
@@ -3290,7 +3290,18 @@ bool 
DocumentRedlineManager::AcceptRedlineRange(SwRedlineTable::size_type nPosOr
             }
             nPamEndtNI = pTmp->Start()->GetNodeIndex();
             nPamEndCI = pTmp->Start()->GetContentIndex();
-            bRet |= lcl_AcceptRedline(maRedlineTable, nRdlIdx, bCallDelete);
+
+            if (pTmp->GetType() == RedlineType::Format && 
pTmp->GetStackCount() > 1
+                && pTmp->GetType(1) == RedlineType::Insert)
+            {
+                // This combination of 2 redline types prefers accepting the 
inner one first.
+                bRet |= lcl_DeleteInnerRedline(maRedlineTable, nRdlIdx, 1);
+            }
+            else
+            {
+                bRet |= lcl_AcceptRedline(maRedlineTable, nRdlIdx, 
bCallDelete);
+            }
+
             nRdlIdx++; //we will decrease it in the loop anyway.
         }
         else if (CanCombineTypesForAcceptReject(aOrigData, *pTmp)

Reply via email to