tdf#137684 sw ChangesInMargin: fix Undo of characters

Undo of tracked deletions in the same position was reversed
to avoid changing the ranges of the remaining hidden redlines.
Now the ranges are corrected after the Undo (at least for the
multiple characters deleted by pressing Delete).

Clean-up of commit fe1fc9615511994ac128e52f9ad1cda4e86188f5
(tdf#137684 sw ChangesInMargin: fix crash on Undo of characters).

Change-Id: If10bba5232d7b5084a2770efd9df229ae7509eb3
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/106266
Tested-by: Jenkins
Reviewed-by: László Németh <nemeth@numbertext.org>
diff --git a/sw/qa/extras/uiwriter/uiwriter2.cxx b/sw/qa/extras/uiwriter/uiwriter2.cxx
index a14a16a..48a6aa3 100644
--- a/sw/qa/extras/uiwriter/uiwriter2.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter2.cxx
@@ -1917,8 +1917,7 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf137684)
    {
        dispatchCommand(mxComponent, ".uno:Undo", {});
    }
    // TODO: fix order of the characters after Undo
    CPPUNIT_ASSERT(getParagraph(1)->getString().startsWith(" noitpyrcnE"));
    CPPUNIT_ASSERT(getParagraph(1)->getString().startsWith("Encryption "));

    // switch off "Show changes in margin" mode
    dispatchCommand(mxComponent, ".uno:ShowChangesInMargin", {});
diff --git a/sw/source/core/undo/unredln.cxx b/sw/source/core/undo/unredln.cxx
index 1d48861..564eb78 100644
--- a/sw/source/core/undo/unredln.cxx
+++ b/sw/source/core/undo/unredln.cxx
@@ -93,23 +93,35 @@ void SwUndoRedline::UndoImpl(::sw::UndoRedoContext & rContext)
    // fix PaM for deletions shown in margin
    SwRedlineTable::size_type nCurRedlinePos;
    const SwRangeRedline * pRedline =
            rDoc.getIDocumentRedlineAccess().GetRedline( *rPam.End(), &nCurRedlinePos );
            rDoc.getIDocumentRedlineAccess().GetRedline( *rPam.GetPoint(), &nCurRedlinePos );
    if ( pRedline && !pRedline->IsVisible() )
    {
        const SwRedlineTable& rTable = rDoc.getIDocumentRedlineAccess().GetRedlineTable();
        // skip older redlines in the same position
        while ( nCurRedlinePos + 1 < rTable.size() &&
            *pRedline->GetPoint() == *rTable[nCurRedlinePos + 1]->GetPoint() )
        // count invisible (DELETE) redlines in the same position
        SwRedlineTable::size_type nPos = nCurRedlinePos + 1;
        while ( nPos < rTable.size() && !rTable[nPos]->IsVisible() &&
            *pRedline->GetPoint() == *rTable[nPos]->GetPoint() )
        {
            ++nCurRedlinePos;
            ++nPos;
        }
        SwRangeRedline * pHiddenRedline( rTable[nCurRedlinePos] );
        pHiddenRedline->Show(0, rTable.GetPos(pHiddenRedline), /*bForced=*/true);
        pHiddenRedline->Show(1, rTable.GetPos(pHiddenRedline), /*bForced=*/true);
        rPam = *pHiddenRedline;
    }

    UndoRedlineImpl(rDoc, rPam);
        SwContentNode *pNd = rPam.GetContentNode();
        const sal_Int32 nStart = rPam.Start()->nContent.GetIndex();
        UndoRedlineImpl(rDoc, rPam);

        // restore redline ranges to the start of the hidden deletion
        // TODO fix the other cases
        for (SwRedlineTable::size_type nIdx = nCurRedlinePos; nIdx + 1 < nPos; ++nIdx) {
            SwRangeRedline * pHiddenRedline2( rTable[nIdx] );
            pHiddenRedline2->GetPoint()->nContent.Assign(pNd, nStart);
        }
    }
    else
        UndoRedlineImpl(rDoc, rPam);

    if( mpRedlSaveData )
    {