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 62f094380dcc7f23be32f600d86df9063fc9bb0d
Author:     Miklos Vajna <[email protected]>
AuthorDate: Thu May 22 08:43:06 2025 +0200
Commit:     Caolán McNamara <[email protected]>
CommitDate: Thu May 22 10:30:30 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/+/185640
    Tested-by: Jenkins CollaboraOffice <[email protected]>
    Reviewed-by: Caolán McNamara <[email protected]>

diff --git a/sw/inc/docary.hxx b/sw/inc/docary.hxx
index dc8d0941dc04..48b77d7e34de 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 3aaad36d2b7d..dfe5bd2c830f 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 5318a6a67ff0..33a6881e1785 100644
--- a/sw/source/core/doc/DocumentRedlineManager.cxx
+++ b/sw/source/core/doc/DocumentRedlineManager.cxx
@@ -3291,7 +3291,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