tdf#157663 SW: fix redline continueing a move

Subsequent moves generated new MoveID's, like if they were separete moves.
That cause moves to forgot their other parts.

Now, if we move a redline that was moved by us it will re-use its moveID
as if it was just the continue of the previous movement.
It does not work if we move more then 1 of our own movement redlines

Note: There are complex cases what it cannot handle.. in those case it
just use the new ID, so the newly moved part, will forgot its relation
with the old move oroginal parts.
Complex case is like.. if we move 2 of our own move redlines,
that means there will be 2 MoveId we would want to continue, but only 1
insert redline to write that MoveID.
But as long as we moved only 1 of our redlines it will work, even if
there are more text redlines, even move redlines of other author.
Other move redlines will be separate move anyway.

Note2: In complex cases, we may could connect movements.
Or we could split the new inserted move part.
but those are design questions, they may be not good idea..
and the split one is probably more work to implement.

Change-Id: Icb2adf43272181c6a63a4a84750352f4b163383a
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/158473
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com>
Reviewed-by: Caolán McNamara <caolan.mcnamara@collabora.com>
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/158615
Tested-by: Jenkins
diff --git a/sw/inc/IDocumentRedlineAccess.hxx b/sw/inc/IDocumentRedlineAccess.hxx
index 6e28f13..9d97eb4 100644
--- a/sw/inc/IDocumentRedlineAccess.hxx
+++ b/sw/inc/IDocumentRedlineAccess.hxx
@@ -147,7 +147,8 @@ public:
            MERGED if pNewRedl was deleted but has been merged with existing one
            IGNORED if pNewRedl was deleted and ignored/invalid
    */
    virtual AppendResult AppendRedline(/*[in]*/SwRangeRedline* pNewRedl, /*[in]*/bool bCallDelete) = 0;
    virtual AppendResult AppendRedline(/*[in]*/ SwRangeRedline* pNewRedl, /*[in]*/ bool bCallDelete,
                                       /*[in]*/ sal_uInt32 nMoveIDToDelete = 0) = 0;

    virtual bool AppendTableRowRedline(/*[in]*/SwTableRowRedline* pPtr) = 0;
    virtual bool AppendTableCellRedline(/*[in]*/SwTableCellRedline* pPtr) = 0;
diff --git a/sw/source/core/doc/DocumentRedlineManager.cxx b/sw/source/core/doc/DocumentRedlineManager.cxx
index 468449e..8d52c81 100644
--- a/sw/source/core/doc/DocumentRedlineManager.cxx
+++ b/sw/source/core/doc/DocumentRedlineManager.cxx
@@ -1309,7 +1309,8 @@ Behaviour of Delete-Redline:
                                          the Delete
*/
IDocumentRedlineAccess::AppendResult
DocumentRedlineManager::AppendRedline(SwRangeRedline* pNewRedl, bool const bCallDelete)
DocumentRedlineManager::AppendRedline(SwRangeRedline* pNewRedl, bool const bCallDelete,
                                      sal_uInt32 nMoveIDToDelete)
{
    CHECK_REDLINE( *this )

@@ -1330,6 +1331,9 @@ DocumentRedlineManager::AppendRedline(SwRangeRedline* pNewRedl, bool const bCall
        return AppendResult::IGNORED;
    }

    // Collect MoveID's of the redlines we delete.
    // If there is only 1, then we should use its ID. (continuing the move)
    std::set<sal_uInt32> deletedMoveIDs;

    bool bMerged = false;

@@ -1807,6 +1811,16 @@ DocumentRedlineManager::AppendRedline(SwRangeRedline* pNewRedl, bool const bCall
                    // and anonymized insertion, i.e. with the same dummy timestamp
                    !pRedl->GetRedlineData(0).IsAnonymized() )
                {
                    // Collect MoveID's of the redlines we delete.
                    if (nMoveIDToDelete > 1 && maRedlineTable[n]->GetMoved() > 0
                        && (eCmpPos == SwComparePosition::Equal
                            || eCmpPos == SwComparePosition::Inside
                            || eCmpPos == SwComparePosition::Outside
                            || eCmpPos == SwComparePosition::OverlapBefore
                            || eCmpPos == SwComparePosition::OverlapBehind))
                    {
                        deletedMoveIDs.insert(maRedlineTable[n]->GetMoved());
                    }

                    // Set to NONE, so that the Delete::Redo merges the Redline data correctly!
                    // The ShowMode needs to be retained!
@@ -2421,6 +2435,23 @@ DocumentRedlineManager::AppendRedline(SwRangeRedline* pNewRedl, bool const bCall
        }
    }

    // If we deleted moved redlines, and there was only 1 MoveID, then we should use that
    // We overwrite those that was given right now, so it cannot be deeper under other redline
    if (nMoveIDToDelete > 1 && deletedMoveIDs.size() == 1)
    {
        sal_uInt32 nNewMoveID = *(deletedMoveIDs.begin());
        if (nNewMoveID > 1)     // MoveID==1 is for old, unrecognised moves, leave them alone
        {
            for (n = 0; n < maRedlineTable.size(); ++n)
            {
                if (maRedlineTable[n]->GetMoved() == nMoveIDToDelete)
                {
                    maRedlineTable[n]->SetMoved(nNewMoveID);
                }
            }
        }
    }

    if( bCompress )
        CompressRedlines(nStartPos);

diff --git a/sw/source/core/doc/docnum.cxx b/sw/source/core/doc/docnum.cxx
index 0512af4..0735380 100644
--- a/sw/source/core/doc/docnum.cxx
+++ b/sw/source/core/doc/docnum.cxx
@@ -2276,7 +2276,7 @@ bool SwDoc::MoveParagraphImpl(SwPaM& rPam, SwNodeOffset const nOffset,
            SwNodeIndex bound2(oPam->GetBound(false).GetNode());
            oPam.reset();

            getIDocumentRedlineAccess().AppendRedline( pNewRedline, true );
            getIDocumentRedlineAccess().AppendRedline( pNewRedline, true, nMovedID );

            oPam.emplace(bound1, bound2);
            sw::UpdateFramesForAddDeleteRedline(*this, *oPam);
diff --git a/sw/source/core/inc/DocumentRedlineManager.hxx b/sw/source/core/inc/DocumentRedlineManager.hxx
index 106c044..a164dbb 100644
--- a/sw/source/core/inc/DocumentRedlineManager.hxx
+++ b/sw/source/core/inc/DocumentRedlineManager.hxx
@@ -53,7 +53,10 @@ public:

    virtual bool IsInRedlines(const SwNode& rNode) const override;

    virtual AppendResult AppendRedline(/*[in]*/SwRangeRedline* pPtr, /*[in]*/bool bCallDelete) override;
    virtual AppendResult AppendRedline(
        /*[in]*/ SwRangeRedline* pPtr,
        /*[in]*/ bool bCallDelete,
        /*[in]*/ sal_uInt32 nMoveIDToDelete = 0) override;

    virtual bool AppendTableRowRedline(/*[in]*/SwTableRowRedline* pPtr) override;
    virtual bool AppendTableCellRedline(/*[in]*/SwTableCellRedline* pPtr) override;