tdf#138135: sw ChangesInMargin: join characters at backspace

Words deleted by pressing multiple backspaces weren't shown
on margin, only their first letter.

Change-Id: I2f5d0bb057250d3bfd788e1007f1ad24f8c3c2fd
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/105807
Tested-by: Jenkins
Reviewed-by: László Németh <nemeth@numbertext.org>
diff --git a/sw/inc/docary.hxx b/sw/inc/docary.hxx
index 9b4a6e8..4a3e203 100644
--- a/sw/inc/docary.hxx
+++ b/sw/inc/docary.hxx
@@ -259,8 +259,11 @@ public:
     @param tableIndex position in SwRedlineTable to start searching at, will be updated with the index of the returned
                       redline (or the next redline after the given position if not found)
     @param next true: redline starts at position and ends after, false: redline starts before position and ends at or after
     @param visible    true: redline must be visible false: redline must be not visible
    */
    const SwRangeRedline* FindAtPosition( const SwPosition& startPosition, size_type& tableIndex, bool next = true ) const;
    const SwRangeRedline* FindAtPosition( const SwPosition& startPosition,
                                          size_type& tableIndex,
                                          bool next = true, bool visible = true ) const;

    bool                        empty() const { return maVector.empty(); }
    size_type                   size() const { return maVector.size(); }
diff --git a/sw/qa/extras/uiwriter/uiwriter2.cxx b/sw/qa/extras/uiwriter/uiwriter2.cxx
index 31ce73f..dccf9de 100644
--- a/sw/qa/extras/uiwriter/uiwriter2.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter2.cxx
@@ -1925,6 +1925,41 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf137684)
    CPPUNIT_ASSERT(!pWrtShell->GetViewOptions()->IsShowChangesInMargin());
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf138135)
{
    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 letter by letter by using backspace
    dispatchCommand(mxComponent, ".uno:GoToNextWord", {});

    for (int i = 0; i <= 10; ++i)
    {
        dispatchCommand(mxComponent, ".uno:SwBackspace", {});
    }
    CPPUNIT_ASSERT(getParagraph(1)->getString().startsWith("support"));

    // single Undo undoes the deletion of the whole word
    //
    // This was only a 1-character Undo because of missing
    // joining of the deleted characters
    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 2e018b7..1460953 100644
--- a/sw/source/core/doc/DocumentContentOperationsManager.cxx
+++ b/sw/source/core/doc/DocumentContentOperationsManager.cxx
@@ -3992,6 +3992,15 @@ bool DocumentContentOperationsManager::DeleteAndJoinWithRedlineImpl( SwPaM & rPa
                    // within a paragraph TODO: fix also for paragraph join
                    pRedline->GetPoint()->nNode == pRedline->GetMark()->nNode)
            {
                // show hidden previous deletion for joining
                SwRedlineTable::size_type index = 0;
                const SwRangeRedline* pPrevRedline = rTable.FindAtPosition(
                                *pRedline->End(), index, /*bNext=*/false, /*bGetVisible=*/false );
                if ( pPrevRedline && RedlineType::Delete == pPrevRedline->GetType() )
                {
                    SwRangeRedline* pPrevRed = rTable[ index ];
                    pPrevRed->Show(1, index, /*bForced=*/true);
                }
                pRedline->Show(0, rTable.GetPos(pRedline), /*bForced=*/false);
                pRedline->Show(1, rTable.GetPos(pRedline), /*bForced=*/false);
            }
diff --git a/sw/source/core/doc/docredln.cxx b/sw/source/core/doc/docredln.cxx
index a413480..ab57f1b 100644
--- a/sw/source/core/doc/docredln.cxx
+++ b/sw/source/core/doc/docredln.cxx
@@ -702,13 +702,14 @@ SwRedlineTable::size_type SwRedlineTable::FindPrevSeqNo( sal_uInt16 nSeqNo, size

const SwRangeRedline* SwRedlineTable::FindAtPosition( const SwPosition& rSttPos,
                                        size_type& rPos,
                                        bool bNext ) const
                                        bool bNext, bool bGetVisible ) const
{
    const SwRangeRedline* pFnd = nullptr;
    for( ; rPos < maVector.size() ; ++rPos )
    {
        const SwRangeRedline* pTmp = (*this)[ rPos ];
        if( pTmp->HasMark() && pTmp->IsVisible() )
        bool bIsVisible(pTmp->IsVisible());
        if( (pTmp->HasMark()) && bIsVisible && bGetVisible )
        {
            const SwPosition* pRStt = pTmp->Start(),
                      * pREnd = pRStt == pTmp->GetPoint() ? pTmp->GetMark()
@@ -724,6 +725,11 @@ const SwRangeRedline* SwRedlineTable::FindAtPosition( const SwPosition& rSttPos,
            else
                break;
        }
        else if ( !bIsVisible && !bGetVisible && *pTmp->Start() == rSttPos )
        {
            pFnd = pTmp;
            break;
        }
    }
    return pFnd;
}