tdf#137526 sw ChangesInMargin: fix Undo of deleted words

Follow-up of commit 1e383097aa929176bac33f46787e16d945a0a98b
(tdf#34355 sw,offapi,officecfg: show track changes in margin).

Change-Id: I81dd310b2664d19de272f7c61ba5ac142592f9f0
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/104557
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 8e7a9ad..b597085 100644
--- a/sw/qa/extras/uiwriter/uiwriter2.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter2.cxx
@@ -1865,6 +1865,33 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf132160)
    dispatchCommand(mxComponent, ".uno:Undo", {});
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf137526)
{
    load(DATA_DIRECTORY, "tdf132160.odt");

    SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
    CPPUNIT_ASSERT(pTextDoc);

    // switch on "Show changes in margin" mode
    dispatchCommand(mxComponent, ".uno:ShowChangesInMargin", {});

    SwWrtShell* const pWrtShell = pTextDoc->GetDocShell()->GetWrtShell();
    CPPUNIT_ASSERT(pWrtShell->GetViewOptions()->IsShowChangesInMargin());

    // select and delete a word
    dispatchCommand(mxComponent, ".uno:WordRightSel", {});
    dispatchCommand(mxComponent, ".uno:Delete", {});
    CPPUNIT_ASSERT(getParagraph(1)->getString().startsWith("support"));

    // this would crash due to bad redline range
    dispatchCommand(mxComponent, ".uno:Undo", {});
    CPPUNIT_ASSERT(getParagraph(1)->getString().startsWith("Encryption"));

    // switch off "Show changes in margin" mode
    dispatchCommand(mxComponent, ".uno:ShowChangesInMargin", {});
    CPPUNIT_ASSERT(!pWrtShell->GetViewOptions()->IsShowChangesInMargin());
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf52391)
{
    load(DATA_DIRECTORY, "tdf52391.fodt");
diff --git a/sw/source/core/doc/DocumentContentOperationsManager.cxx b/sw/source/core/doc/DocumentContentOperationsManager.cxx
index 473e0db..48d258c 100644
--- a/sw/source/core/doc/DocumentContentOperationsManager.cxx
+++ b/sw/source/core/doc/DocumentContentOperationsManager.cxx
@@ -3979,9 +3979,22 @@ bool DocumentContentOperationsManager::DeleteAndJoinWithRedlineImpl( SwPaM & rPa
                "sw.core", "redlines will be moved in DeleteAndJoin");
        m_rDoc.getIDocumentRedlineAccess().SetRedlineFlags(
            RedlineFlags::On | RedlineFlags::ShowInsert | RedlineFlags::ShowDelete);

        SwViewShell *pSh = m_rDoc.getIDocumentLayoutAccess().GetCurrentViewShell();
        bool bShowChangesInMargin = pSh && pSh->GetViewOptions()->IsShowChangesInMargin();
        const SwRedlineTable& rTable = m_rDoc.getIDocumentRedlineAccess().GetRedlineTable();
        for (SwRangeRedline * pRedline : redlines)
        {
            assert(pRedline->HasValidRange());

            // deletions shown in margin
            if (bShowChangesInMargin &&
                    // within a paragraph TODO: fix also for paragraph join
                    pRedline->GetPoint()->nNode == pRedline->GetMark()->nNode)
            {
                pRedline->Show(0, rTable.GetPos(pRedline), /*bForced=*/false);
                pRedline->Show(1, rTable.GetPos(pRedline), /*bForced=*/false);
            }
            undos.emplace_back(std::make_unique<SwUndoRedlineDelete>(
                        *pRedline, SwUndoId::DELETE));
        }
diff --git a/sw/source/core/undo/unredln.cxx b/sw/source/core/undo/unredln.cxx
index 92da377..d2d60b6 100644
--- a/sw/source/core/undo/unredln.cxx
+++ b/sw/source/core/undo/unredln.cxx
@@ -90,6 +90,19 @@ void SwUndoRedline::UndoImpl(::sw::UndoRedoContext & rContext)
    SwDoc& rDoc = rContext.GetDoc();
    SwPaM& rPam(AddUndoRedoPaM(rContext));

    // fix PaM for deletions shown in margin
    SwRedlineTable::size_type nCurRedlinePos;
    const SwRangeRedline * pRedline =
            rDoc.getIDocumentRedlineAccess().GetRedline( *rPam.End(), &nCurRedlinePos );
    if ( pRedline && !pRedline->IsVisible() )
    {
        const SwRedlineTable& rTable = rDoc.getIDocumentRedlineAccess().GetRedlineTable();
        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);

    if( mpRedlSaveData )