[Libreoffice-commits] core.git: sw/source

Noel Grandin (via logerrit) logerrit at kemper.freedesktop.org
Mon Aug 30 07:37:39 UTC 2021


 sw/source/core/doc/DocumentRedlineManager.cxx | 1709 +++++++++++++-------------
 1 file changed, 856 insertions(+), 853 deletions(-)

New commits:
commit 8a4df9024faf07d97185b5d609f961a381232348
Author:     Noel Grandin <noelgrandin at gmail.com>
AuthorDate: Sun Aug 29 18:41:44 2021 +0200
Commit:     Noel Grandin <noel.grandin at collabora.co.uk>
CommitDate: Mon Aug 30 09:37:06 2021 +0200

    flatten DocumentRedlineManager::AppendRedline a little
    
    Change-Id: I2801aad45f11bd9b8a97fc63c2f005f946a02bf6
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/121233
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <noel.grandin at collabora.co.uk>

diff --git a/sw/source/core/doc/DocumentRedlineManager.cxx b/sw/source/core/doc/DocumentRedlineManager.cxx
index 4573959af9f6..aaf24054db5e 100644
--- a/sw/source/core/doc/DocumentRedlineManager.cxx
+++ b/sw/source/core/doc/DocumentRedlineManager.cxx
@@ -1219,1040 +1219,1043 @@ Behaviour of Delete-Redline:
 IDocumentRedlineAccess::AppendResult
 DocumentRedlineManager::AppendRedline(SwRangeRedline* pNewRedl, bool const bCallDelete)
 {
-    bool bMerged = false;
     CHECK_REDLINE( *this )
 
-    if (IsRedlineOn() && !IsShowOriginal(meRedlineFlags))
+    if (!IsRedlineOn() || IsShowOriginal(meRedlineFlags))
     {
-        pNewRedl->InvalidateRange(SwRangeRedline::Invalidation::Add);
+        if( bCallDelete && RedlineType::Delete == pNewRedl->GetType() )
+        {
+            RedlineFlags eOld = meRedlineFlags;
+            // Set to NONE, so that the Delete::Redo merges the Redline data correctly!
+            // The ShowMode needs to be retained!
+            meRedlineFlags = eOld & ~RedlineFlags(RedlineFlags::On | RedlineFlags::Ignore);
+            m_rDoc.getIDocumentContentOperations().DeleteAndJoin( *pNewRedl );
+            meRedlineFlags = eOld;
+        }
+        delete pNewRedl;
+        pNewRedl = nullptr;
+        CHECK_REDLINE( *this )
+        return AppendResult::IGNORED;
+    }
+
 
-        if( m_rDoc.IsAutoFormatRedline() )
+    bool bMerged = false;
+
+    pNewRedl->InvalidateRange(SwRangeRedline::Invalidation::Add);
+
+    if( m_rDoc.IsAutoFormatRedline() )
+    {
+        pNewRedl->SetAutoFormat();
+        if( mpAutoFormatRedlnComment && !mpAutoFormatRedlnComment->isEmpty() )
         {
-            pNewRedl->SetAutoFormat();
-            if( mpAutoFormatRedlnComment && !mpAutoFormatRedlnComment->isEmpty() )
-            {
-                pNewRedl->SetComment( *mpAutoFormatRedlnComment );
-                pNewRedl->SetSeqNo( mnAutoFormatRedlnCommentNo );
-            }
+            pNewRedl->SetComment( *mpAutoFormatRedlnComment );
+            pNewRedl->SetSeqNo( mnAutoFormatRedlnCommentNo );
         }
+    }
 
-        SwPosition* pStt = pNewRedl->Start(),
-                  * pEnd = pStt == pNewRedl->GetPoint() ? pNewRedl->GetMark()
-                                                        : pNewRedl->GetPoint();
+    SwPosition* pStt = pNewRedl->Start(),
+              * pEnd = pStt == pNewRedl->GetPoint() ? pNewRedl->GetMark()
+                                                    : pNewRedl->GetPoint();
+    {
+        SwTextNode* pTextNode = pStt->nNode.GetNode().GetTextNode();
+        if( pTextNode == nullptr )
         {
-            SwTextNode* pTextNode = pStt->nNode.GetNode().GetTextNode();
-            if( pTextNode == nullptr )
+            if( pStt->nContent > 0 )
             {
-                if( pStt->nContent > 0 )
-                {
-                    OSL_ENSURE( false, "Redline start: non-text-node with content" );
-                    pStt->nContent = 0;
-                }
+                OSL_ENSURE( false, "Redline start: non-text-node with content" );
+                pStt->nContent = 0;
             }
-            else
+        }
+        else
+        {
+            if( pStt->nContent > pTextNode->Len() )
             {
-                if( pStt->nContent > pTextNode->Len() )
-                {
-                    OSL_ENSURE( false, "Redline start: index after text" );
-                    pStt->nContent = pTextNode->Len();
-                }
+                OSL_ENSURE( false, "Redline start: index after text" );
+                pStt->nContent = pTextNode->Len();
             }
-            pTextNode = pEnd->nNode.GetNode().GetTextNode();
-            if( pTextNode == nullptr )
+        }
+        pTextNode = pEnd->nNode.GetNode().GetTextNode();
+        if( pTextNode == nullptr )
+        {
+            if( pEnd->nContent > 0 )
             {
-                if( pEnd->nContent > 0 )
-                {
-                    OSL_ENSURE( false, "Redline end: non-text-node with content" );
-                    pEnd->nContent = 0;
-                }
+                OSL_ENSURE( false, "Redline end: non-text-node with content" );
+                pEnd->nContent = 0;
             }
-            else
+        }
+        else
+        {
+            if( pEnd->nContent > pTextNode->Len() )
             {
-                if( pEnd->nContent > pTextNode->Len() )
-                {
-                    OSL_ENSURE( false, "Redline end: index after text" );
-                    pEnd->nContent = pTextNode->Len();
-                }
+                OSL_ENSURE( false, "Redline end: index after text" );
+                pEnd->nContent = pTextNode->Len();
             }
         }
-        if( ( *pStt == *pEnd ) &&
-            ( pNewRedl->GetContentIdx() == nullptr ) )
-        {   // Do not insert empty redlines
-            delete pNewRedl;
-            return AppendResult::IGNORED;
-        }
-        bool bCompress = false;
-        SwRedlineTable::size_type n = 0;
-        // look up the first Redline for the starting position
-        if( !GetRedline( *pStt, &n ) && n )
-            --n;
-        bool bDec = false;
+    }
+    if( ( *pStt == *pEnd ) &&
+        ( pNewRedl->GetContentIdx() == nullptr ) )
+    {   // Do not insert empty redlines
+        delete pNewRedl;
+        return AppendResult::IGNORED;
+    }
+    bool bCompress = false;
+    SwRedlineTable::size_type n = 0;
+    // look up the first Redline for the starting position
+    if( !GetRedline( *pStt, &n ) && n )
+        --n;
+    bool bDec = false;
 
-        for( ; pNewRedl && n < mpRedlineTable->size(); bDec ? n : ++n )
-        {
-            bDec = false;
+    for( ; pNewRedl && n < mpRedlineTable->size(); bDec ? n : ++n )
+    {
+        bDec = false;
 
-            SwRangeRedline* pRedl = (*mpRedlineTable)[ n ];
-            SwPosition* pRStt = pRedl->Start(),
-                      * pREnd = pRStt == pRedl->GetPoint() ? pRedl->GetMark()
-                                                           : pRedl->GetPoint();
+        SwRangeRedline* pRedl = (*mpRedlineTable)[ n ];
+        SwPosition* pRStt = pRedl->Start(),
+                  * pREnd = pRStt == pRedl->GetPoint() ? pRedl->GetMark()
+                                                       : pRedl->GetPoint();
 
-            // #i8518# remove empty redlines while we're at it
-            if( ( *pRStt == *pREnd ) &&
-                ( pRedl->GetContentIdx() == nullptr ) )
-            {
-                mpRedlineTable->DeleteAndDestroy(n);
-                continue;
-            }
+        // #i8518# remove empty redlines while we're at it
+        if( ( *pRStt == *pREnd ) &&
+            ( pRedl->GetContentIdx() == nullptr ) )
+        {
+            mpRedlineTable->DeleteAndDestroy(n);
+            continue;
+        }
 
-            SwComparePosition eCmpPos = ComparePosition( *pStt, *pEnd, *pRStt, *pREnd );
+        SwComparePosition eCmpPos = ComparePosition( *pStt, *pEnd, *pRStt, *pREnd );
 
-            switch( pNewRedl->GetType() )
+        switch( pNewRedl->GetType() )
+        {
+        case RedlineType::Insert:
+            switch( pRedl->GetType() )
             {
             case RedlineType::Insert:
-                switch( pRedl->GetType() )
+                if( pRedl->IsOwnRedline( *pNewRedl ) )
                 {
-                case RedlineType::Insert:
-                    if( pRedl->IsOwnRedline( *pNewRedl ) )
-                    {
-                        bool bDelete = false;
-
-                        // Merge if applicable?
-                        if( (( SwComparePosition::Behind == eCmpPos &&
-                               IsPrevPos( *pREnd, *pStt ) ) ||
-                             ( SwComparePosition::CollideStart == eCmpPos ) ||
-                             ( SwComparePosition::OverlapBehind == eCmpPos ) ) &&
-                            pRedl->CanCombine( *pNewRedl ) &&
-                            ( n+1 >= mpRedlineTable->size() ||
-                             ( *(*mpRedlineTable)[ n+1 ]->Start() >= *pEnd &&
-                             *(*mpRedlineTable)[ n+1 ]->Start() != *pREnd ) ) )
-                        {
-                            pRedl->SetEnd( *pEnd, pREnd );
-                            if( !pRedl->HasValidRange() )
-                            {
-                                // re-insert
-                                mpRedlineTable->Remove( n );
-                                mpRedlineTable->Insert( pRedl );
-                            }
-
-                            bMerged = true;
-                            bDelete = true;
-                        }
-                        else if( (( SwComparePosition::Before == eCmpPos &&
-                                    IsPrevPos( *pEnd, *pRStt ) ) ||
-                                   ( SwComparePosition::CollideEnd == eCmpPos ) ||
-                                  ( SwComparePosition::OverlapBefore == eCmpPos ) ) &&
-                            pRedl->CanCombine( *pNewRedl ) &&
-                            ( !n ||
-                             *(*mpRedlineTable)[ n-1 ]->End() != *pRStt ))
+                    bool bDelete = false;
+
+                    // Merge if applicable?
+                    if( (( SwComparePosition::Behind == eCmpPos &&
+                           IsPrevPos( *pREnd, *pStt ) ) ||
+                         ( SwComparePosition::CollideStart == eCmpPos ) ||
+                         ( SwComparePosition::OverlapBehind == eCmpPos ) ) &&
+                        pRedl->CanCombine( *pNewRedl ) &&
+                        ( n+1 >= mpRedlineTable->size() ||
+                         ( *(*mpRedlineTable)[ n+1 ]->Start() >= *pEnd &&
+                         *(*mpRedlineTable)[ n+1 ]->Start() != *pREnd ) ) )
+                    {
+                        pRedl->SetEnd( *pEnd, pREnd );
+                        if( !pRedl->HasValidRange() )
                         {
-                            pRedl->SetStart( *pStt, pRStt );
                             // re-insert
                             mpRedlineTable->Remove( n );
                             mpRedlineTable->Insert( pRedl );
-
-                            bMerged = true;
-                            bDelete = true;
                         }
-                        else if ( SwComparePosition::Outside == eCmpPos )
-                        {
-                            // own insert-over-insert redlines:
-                            // just scrap the inside ones
-                            mpRedlineTable->DeleteAndDestroy( n );
-                            bDec = true;
-                        }
-                        else if( SwComparePosition::OverlapBehind == eCmpPos )
-                        {
-                            *pStt = *pREnd;
-                            if( ( *pStt == *pEnd ) &&
-                                ( pNewRedl->GetContentIdx() == nullptr ) )
-                                bDelete = true;
-                        }
-                        else if( SwComparePosition::OverlapBefore == eCmpPos )
-                        {
-                            *pEnd = *pRStt;
-                            if( ( *pStt == *pEnd ) &&
-                                ( pNewRedl->GetContentIdx() == nullptr ) )
-                                bDelete = true;
-                        }
-                        else if( SwComparePosition::Inside == eCmpPos )
-                        {
-                            bDelete = true;
-                            bMerged = true;
-                        }
-                        else if( SwComparePosition::Equal == eCmpPos )
-                            bDelete = true;
 
-                        if( bDelete )
-                        {
-                            delete pNewRedl;
-                            pNewRedl = nullptr;
-                            bCompress = true;
-                        }
+                        bMerged = true;
+                        bDelete = true;
                     }
-                    else if( SwComparePosition::Inside == eCmpPos )
+                    else if( (( SwComparePosition::Before == eCmpPos &&
+                                IsPrevPos( *pEnd, *pRStt ) ) ||
+                               ( SwComparePosition::CollideEnd == eCmpPos ) ||
+                              ( SwComparePosition::OverlapBefore == eCmpPos ) ) &&
+                        pRedl->CanCombine( *pNewRedl ) &&
+                        ( !n ||
+                         *(*mpRedlineTable)[ n-1 ]->End() != *pRStt ))
                     {
-                        // split up
-                        if( *pEnd != *pREnd )
-                        {
-                            SwRangeRedline* pCpy = new SwRangeRedline( *pRedl );
-                            pCpy->SetStart( *pEnd );
-                            mpRedlineTable->Insert( pCpy );
-                        }
-                        pRedl->SetEnd( *pStt, pREnd );
-                        if( ( *pStt == *pRStt ) &&
-                            ( pRedl->GetContentIdx() == nullptr ) )
-                        {
-                            mpRedlineTable->DeleteAndDestroy( n );
-                            bDec = true;
-                        }
-                        else if( !pRedl->HasValidRange() )
-                        {
-                            // re-insert
-                            mpRedlineTable->Remove( n );
-                            mpRedlineTable->Insert( pRedl );
-                        }
+                        pRedl->SetStart( *pStt, pRStt );
+                        // re-insert
+                        mpRedlineTable->Remove( n );
+                        mpRedlineTable->Insert( pRedl );
+
+                        bMerged = true;
+                        bDelete = true;
                     }
                     else if ( SwComparePosition::Outside == eCmpPos )
                     {
-                        // handle overlapping redlines in broken documents
-
-                        // split up the new redline, since it covers the
-                        // existing redline. Insert the first part, and
-                        // progress with the remainder as usual
-                        SwRangeRedline* pSplit = new SwRangeRedline( *pNewRedl );
-                        pSplit->SetEnd( *pRStt );
-                        pNewRedl->SetStart( *pREnd );
-                        mpRedlineTable->Insert( pSplit );
-                        if( *pStt == *pEnd && pNewRedl->GetContentIdx() == nullptr )
-                        {
-                            delete pNewRedl;
-                            pNewRedl = nullptr;
-                            bCompress = true;
-                        }
+                        // own insert-over-insert redlines:
+                        // just scrap the inside ones
+                        mpRedlineTable->DeleteAndDestroy( n );
+                        bDec = true;
                     }
-                    else if ( SwComparePosition::OverlapBehind == eCmpPos )
+                    else if( SwComparePosition::OverlapBehind == eCmpPos )
                     {
-                        // handle overlapping redlines in broken documents
-                        pNewRedl->SetStart( *pREnd );
+                        *pStt = *pREnd;
+                        if( ( *pStt == *pEnd ) &&
+                            ( pNewRedl->GetContentIdx() == nullptr ) )
+                            bDelete = true;
                     }
-                    else if ( SwComparePosition::OverlapBefore == eCmpPos )
+                    else if( SwComparePosition::OverlapBefore == eCmpPos )
                     {
-                        // handle overlapping redlines in broken documents
                         *pEnd = *pRStt;
                         if( ( *pStt == *pEnd ) &&
                             ( pNewRedl->GetContentIdx() == nullptr ) )
-                        {
-                            delete pNewRedl;
-                            pNewRedl = nullptr;
-                            bCompress = true;
-                        }
+                            bDelete = true;
                     }
-                    break;
-                case RedlineType::Delete:
-                    if( SwComparePosition::Inside == eCmpPos )
+                    else if( SwComparePosition::Inside == eCmpPos )
                     {
-                        // split up
-                        if( *pEnd != *pREnd )
-                        {
-                            SwRangeRedline* pCpy = new SwRangeRedline( *pRedl );
-                            pCpy->SetStart( *pEnd );
-                            mpRedlineTable->Insert( pCpy );
-                        }
-                        pRedl->SetEnd( *pStt, pREnd );
-                        if( ( *pStt == *pRStt ) &&
-                            ( pRedl->GetContentIdx() == nullptr ) )
-                        {
-                            mpRedlineTable->DeleteAndDestroy( n );
-                            bDec = true;
-                        }
-                        else if( !pRedl->HasValidRange() )
-                        {
-                            // re-insert
-                            mpRedlineTable->Remove( n );
-                            mpRedlineTable->Insert( pRedl, n );
-                        }
+                        bDelete = true;
+                        bMerged = true;
                     }
-                    else if ( SwComparePosition::Outside == eCmpPos )
-                    {
-                        // handle overlapping redlines in broken documents
+                    else if( SwComparePosition::Equal == eCmpPos )
+                        bDelete = true;
 
-                        // split up the new redline, since it covers the
-                        // existing redline. Insert the first part, and
-                        // progress with the remainder as usual
-                        SwRangeRedline* pSplit = new SwRangeRedline( *pNewRedl );
-                        pSplit->SetEnd( *pRStt );
-                        pNewRedl->SetStart( *pREnd );
-                        mpRedlineTable->Insert( pSplit );
-                        if( *pStt == *pEnd && pNewRedl->GetContentIdx() == nullptr )
-                        {
-                            delete pNewRedl;
-                            pNewRedl = nullptr;
-                            bCompress = true;
-                        }
+                    if( bDelete )
+                    {
+                        delete pNewRedl;
+                        pNewRedl = nullptr;
+                        bCompress = true;
                     }
-                    else if ( SwComparePosition::Equal == eCmpPos )
+                }
+                else if( SwComparePosition::Inside == eCmpPos )
+                {
+                    // split up
+                    if( *pEnd != *pREnd )
+                    {
+                        SwRangeRedline* pCpy = new SwRangeRedline( *pRedl );
+                        pCpy->SetStart( *pEnd );
+                        mpRedlineTable->Insert( pCpy );
+                    }
+                    pRedl->SetEnd( *pStt, pREnd );
+                    if( ( *pStt == *pRStt ) &&
+                        ( pRedl->GetContentIdx() == nullptr ) )
                     {
-                        // handle identical redlines in broken documents
-                        // delete old (delete) redline
                         mpRedlineTable->DeleteAndDestroy( n );
                         bDec = true;
                     }
-                    else if ( SwComparePosition::OverlapBehind == eCmpPos )
-                    {   // Another workaround for broken redlines
-                        pNewRedl->SetStart( *pREnd );
-                    }
-                    break;
-                case RedlineType::Format:
-                    switch( eCmpPos )
+                    else if( !pRedl->HasValidRange() )
                     {
-                    case SwComparePosition::OverlapBefore:
-                        pRedl->SetStart( *pEnd, pRStt );
                         // re-insert
                         mpRedlineTable->Remove( n );
-                        mpRedlineTable->Insert( pRedl, n );
-                        bDec = true;
-                        break;
-
-                    case SwComparePosition::OverlapBehind:
-                        pRedl->SetEnd( *pStt, pREnd );
-                        if( *pStt == *pRStt && pRedl->GetContentIdx() == nullptr )
-                        {
-                            mpRedlineTable->DeleteAndDestroy( n );
-                            bDec = true;
-                        }
-                        break;
-
-                    case SwComparePosition::Equal:
-                    case SwComparePosition::Outside:
-                        // Overlaps the current one completely or has the
-                        // same dimension, delete the old one
-                        mpRedlineTable->DeleteAndDestroy( n );
-                        bDec = true;
-                        break;
-
-                    case SwComparePosition::Inside:
-                        // Overlaps the current one completely,
-                        // split or shorten the new one
-                        if( *pEnd != *pREnd )
-                        {
-                            if( *pEnd != *pRStt )
-                            {
-                                SwRangeRedline* pNew = new SwRangeRedline( *pRedl );
-                                pNew->SetStart( *pEnd );
-                                pRedl->SetEnd( *pStt, pREnd );
-                                if( *pStt == *pRStt && pRedl->GetContentIdx() == nullptr )
-                                    mpRedlineTable->DeleteAndDestroy( n );
-                                AppendRedline( pNew, bCallDelete );
-                                n = 0;      // re-initialize
-                                bDec = true;
-                            }
-                        }
-                        else
-                            pRedl->SetEnd( *pStt, pREnd );
-                        break;
-                    default:
-                        break;
+                        mpRedlineTable->Insert( pRedl );
                     }
-                    break;
-                default:
-                    break;
                 }
-                break;
-
-            case RedlineType::Delete:
-                switch( pRedl->GetType() )
+                else if ( SwComparePosition::Outside == eCmpPos )
                 {
-                case RedlineType::Delete:
-                    switch( eCmpPos )
+                    // handle overlapping redlines in broken documents
+
+                    // split up the new redline, since it covers the
+                    // existing redline. Insert the first part, and
+                    // progress with the remainder as usual
+                    SwRangeRedline* pSplit = new SwRangeRedline( *pNewRedl );
+                    pSplit->SetEnd( *pRStt );
+                    pNewRedl->SetStart( *pREnd );
+                    mpRedlineTable->Insert( pSplit );
+                    if( *pStt == *pEnd && pNewRedl->GetContentIdx() == nullptr )
                     {
-                    case SwComparePosition::Outside:
-                        {
-                            // Overlaps the current one completely,
-                            // split the new one
-                            if (*pEnd == *pREnd)
-                            {
-                                pNewRedl->SetEnd(*pRStt, pEnd);
-                            }
-                            else if (*pStt == *pRStt)
-                            {
-                                pNewRedl->SetStart(*pREnd, pStt);
-                            }
-                            else
-                            {
-                                SwRangeRedline* pNew = new SwRangeRedline( *pNewRedl );
-                                pNew->SetStart( *pREnd );
-                                pNewRedl->SetEnd( *pRStt, pEnd );
-                                AppendRedline( pNew, bCallDelete );
-                                n = 0;      // re-initialize
-                                bDec = true;
-                            }
-                        }
-                        break;
-
-                    case SwComparePosition::Inside:
-                    case SwComparePosition::Equal:
                         delete pNewRedl;
                         pNewRedl = nullptr;
                         bCompress = true;
-                        break;
-
-                    case SwComparePosition::OverlapBefore:
-                    case SwComparePosition::OverlapBehind:
-                        if( pRedl->IsOwnRedline( *pNewRedl ) &&
-                            pRedl->CanCombine( *pNewRedl ))
-                        {
-                            // If that's the case we can merge it, meaning
-                            // the new one covers this well
-                            if( SwComparePosition::OverlapBehind == eCmpPos )
-                                pNewRedl->SetStart( *pRStt, pStt );
-                            else
-                                pNewRedl->SetEnd( *pREnd, pEnd );
-                            mpRedlineTable->DeleteAndDestroy( n );
-                            bDec = true;
-                        }
-                        else if( SwComparePosition::OverlapBehind == eCmpPos )
-                            pNewRedl->SetStart( *pREnd, pStt );
-                        else
-                            pNewRedl->SetEnd( *pRStt, pEnd );
-                        break;
-
-                    case SwComparePosition::CollideStart:
-                    case SwComparePosition::CollideEnd:
-                        if( pRedl->IsOwnRedline( *pNewRedl ) &&
-                            pRedl->CanCombine( *pNewRedl ) )
-                        {
-                            if( IsHideChanges( meRedlineFlags ))
-                            {
-                                // Before we can merge, we make it visible!
-                                // We insert temporarily so that pNew is
-                                // also dealt with when moving the indices.
-                                mpRedlineTable->Insert(pNewRedl);
-                                pRedl->Show(0, mpRedlineTable->GetPos(pRedl));
-                                mpRedlineTable->Remove( pNewRedl );
-                                pRStt = pRedl->Start();
-                                pREnd = pRedl->End();
-                            }
-
-                            // If that's the case we can merge it, meaning
-                            // the new one covers this well
-                            if( SwComparePosition::CollideStart == eCmpPos )
-                                pNewRedl->SetStart( *pRStt, pStt );
-                            else
-                                pNewRedl->SetEnd( *pREnd, pEnd );
-
-                            // delete current (below), and restart process with
-                            // previous
-                            SwRedlineTable::size_type nToBeDeleted = n;
-                            bDec = true;
-
-                            if( *(pNewRedl->Start()) <= *pREnd )
-                            {
-                                // Whoooah, we just extended the new 'redline'
-                                // beyond previous redlines, so better start
-                                // again. Of course this is not supposed to
-                                // happen, and in an ideal world it doesn't,
-                                // but unfortunately this code is buggy and
-                                // totally rotten so it does happen and we
-                                // better fix it.
-                                n = 0;
-                                bDec = true;
-                            }
-
-                            mpRedlineTable->DeleteAndDestroy( nToBeDeleted );
-                        }
-                        break;
-                    default:
-                        break;
                     }
-                    break;
-
-                case RedlineType::Insert:
+                }
+                else if ( SwComparePosition::OverlapBehind == eCmpPos )
                 {
-                    // b62341295: Do not throw away redlines
-                    // even if they are not allowed to be combined
-                    RedlineFlags eOld = meRedlineFlags;
-                    if( !( eOld & RedlineFlags::DontCombineRedlines ) &&
-                        pRedl->IsOwnRedline( *pNewRedl ) )
+                    // handle overlapping redlines in broken documents
+                    pNewRedl->SetStart( *pREnd );
+                }
+                else if ( SwComparePosition::OverlapBefore == eCmpPos )
+                {
+                    // handle overlapping redlines in broken documents
+                    *pEnd = *pRStt;
+                    if( ( *pStt == *pEnd ) &&
+                        ( pNewRedl->GetContentIdx() == nullptr ) )
+                    {
+                        delete pNewRedl;
+                        pNewRedl = nullptr;
+                        bCompress = true;
+                    }
+                }
+                break;
+            case RedlineType::Delete:
+                if( SwComparePosition::Inside == eCmpPos )
+                {
+                    // split up
+                    if( *pEnd != *pREnd )
+                    {
+                        SwRangeRedline* pCpy = new SwRangeRedline( *pRedl );
+                        pCpy->SetStart( *pEnd );
+                        mpRedlineTable->Insert( pCpy );
+                    }
+                    pRedl->SetEnd( *pStt, pREnd );
+                    if( ( *pStt == *pRStt ) &&
+                        ( pRedl->GetContentIdx() == nullptr ) )
+                    {
+                        mpRedlineTable->DeleteAndDestroy( n );
+                        bDec = true;
+                    }
+                    else if( !pRedl->HasValidRange() )
+                    {
+                        // re-insert
+                        mpRedlineTable->Remove( n );
+                        mpRedlineTable->Insert( pRedl, n );
+                    }
+                }
+                else if ( SwComparePosition::Outside == eCmpPos )
+                {
+                    // handle overlapping redlines in broken documents
+
+                    // split up the new redline, since it covers the
+                    // existing redline. Insert the first part, and
+                    // progress with the remainder as usual
+                    SwRangeRedline* pSplit = new SwRangeRedline( *pNewRedl );
+                    pSplit->SetEnd( *pRStt );
+                    pNewRedl->SetStart( *pREnd );
+                    mpRedlineTable->Insert( pSplit );
+                    if( *pStt == *pEnd && pNewRedl->GetContentIdx() == nullptr )
+                    {
+                        delete pNewRedl;
+                        pNewRedl = nullptr;
+                        bCompress = true;
+                    }
+                }
+                else if ( SwComparePosition::Equal == eCmpPos )
+                {
+                    // handle identical redlines in broken documents
+                    // delete old (delete) redline
+                    mpRedlineTable->DeleteAndDestroy( n );
+                    bDec = true;
+                }
+                else if ( SwComparePosition::OverlapBehind == eCmpPos )
+                {   // Another workaround for broken redlines
+                    pNewRedl->SetStart( *pREnd );
+                }
+                break;
+            case RedlineType::Format:
+                switch( eCmpPos )
+                {
+                case SwComparePosition::OverlapBefore:
+                    pRedl->SetStart( *pEnd, pRStt );
+                    // re-insert
+                    mpRedlineTable->Remove( n );
+                    mpRedlineTable->Insert( pRedl, n );
+                    bDec = true;
+                    break;
+
+                case SwComparePosition::OverlapBehind:
+                    pRedl->SetEnd( *pStt, pREnd );
+                    if( *pStt == *pRStt && pRedl->GetContentIdx() == nullptr )
                     {
+                        mpRedlineTable->DeleteAndDestroy( n );
+                        bDec = true;
+                    }
+                    break;
 
-                        // Set to NONE, so that the Delete::Redo merges the Redline data correctly!
-                        // The ShowMode needs to be retained!
-                        meRedlineFlags = eOld & ~RedlineFlags(RedlineFlags::On | RedlineFlags::Ignore);
-                        switch( eCmpPos )
+                case SwComparePosition::Equal:
+                case SwComparePosition::Outside:
+                    // Overlaps the current one completely or has the
+                    // same dimension, delete the old one
+                    mpRedlineTable->DeleteAndDestroy( n );
+                    bDec = true;
+                    break;
+
+                case SwComparePosition::Inside:
+                    // Overlaps the current one completely,
+                    // split or shorten the new one
+                    if( *pEnd != *pREnd )
+                    {
+                        if( *pEnd != *pRStt )
                         {
-                        case SwComparePosition::Equal:
-                            bCompress = true;
-                            mpRedlineTable->DeleteAndDestroy( n );
+                            SwRangeRedline* pNew = new SwRangeRedline( *pRedl );
+                            pNew->SetStart( *pEnd );
+                            pRedl->SetEnd( *pStt, pREnd );
+                            if( *pStt == *pRStt && pRedl->GetContentIdx() == nullptr )
+                                mpRedlineTable->DeleteAndDestroy( n );
+                            AppendRedline( pNew, bCallDelete );
+                            n = 0;      // re-initialize
+                            bDec = true;
+                        }
+                    }
+                    else
+                        pRedl->SetEnd( *pStt, pREnd );
+                    break;
+                default:
+                    break;
+                }
+                break;
+            default:
+                break;
+            }
+            break;
+
+        case RedlineType::Delete:
+            switch( pRedl->GetType() )
+            {
+            case RedlineType::Delete:
+                switch( eCmpPos )
+                {
+                case SwComparePosition::Outside:
+                    {
+                        // Overlaps the current one completely,
+                        // split the new one
+                        if (*pEnd == *pREnd)
+                        {
+                            pNewRedl->SetEnd(*pRStt, pEnd);
+                        }
+                        else if (*pStt == *pRStt)
+                        {
+                            pNewRedl->SetStart(*pREnd, pStt);
+                        }
+                        else
+                        {
+                            SwRangeRedline* pNew = new SwRangeRedline( *pNewRedl );
+                            pNew->SetStart( *pREnd );
+                            pNewRedl->SetEnd( *pRStt, pEnd );
+                            AppendRedline( pNew, bCallDelete );
+                            n = 0;      // re-initialize
+                            bDec = true;
+                        }
+                    }
+                    break;
+
+                case SwComparePosition::Inside:
+                case SwComparePosition::Equal:
+                    delete pNewRedl;
+                    pNewRedl = nullptr;
+                    bCompress = true;
+                    break;
+
+                case SwComparePosition::OverlapBefore:
+                case SwComparePosition::OverlapBehind:
+                    if( pRedl->IsOwnRedline( *pNewRedl ) &&
+                        pRedl->CanCombine( *pNewRedl ))
+                    {
+                        // If that's the case we can merge it, meaning
+                        // the new one covers this well
+                        if( SwComparePosition::OverlapBehind == eCmpPos )
+                            pNewRedl->SetStart( *pRStt, pStt );
+                        else
+                            pNewRedl->SetEnd( *pREnd, pEnd );
+                        mpRedlineTable->DeleteAndDestroy( n );
+                        bDec = true;
+                    }
+                    else if( SwComparePosition::OverlapBehind == eCmpPos )
+                        pNewRedl->SetStart( *pREnd, pStt );
+                    else
+                        pNewRedl->SetEnd( *pRStt, pEnd );
+                    break;
+
+                case SwComparePosition::CollideStart:
+                case SwComparePosition::CollideEnd:
+                    if( pRedl->IsOwnRedline( *pNewRedl ) &&
+                        pRedl->CanCombine( *pNewRedl ) )
+                    {
+                        if( IsHideChanges( meRedlineFlags ))
+                        {
+                            // Before we can merge, we make it visible!
+                            // We insert temporarily so that pNew is
+                            // also dealt with when moving the indices.
+                            mpRedlineTable->Insert(pNewRedl);
+                            pRedl->Show(0, mpRedlineTable->GetPos(pRedl));
+                            mpRedlineTable->Remove( pNewRedl );
+                            pRStt = pRedl->Start();
+                            pREnd = pRedl->End();
+                        }
+
+                        // If that's the case we can merge it, meaning
+                        // the new one covers this well
+                        if( SwComparePosition::CollideStart == eCmpPos )
+                            pNewRedl->SetStart( *pRStt, pStt );
+                        else
+                            pNewRedl->SetEnd( *pREnd, pEnd );
+
+                        // delete current (below), and restart process with
+                        // previous
+                        SwRedlineTable::size_type nToBeDeleted = n;
+                        bDec = true;
+
+                        if( *(pNewRedl->Start()) <= *pREnd )
+                        {
+                            // Whoooah, we just extended the new 'redline'
+                            // beyond previous redlines, so better start
+                            // again. Of course this is not supposed to
+                            // happen, and in an ideal world it doesn't,
+                            // but unfortunately this code is buggy and
+                            // totally rotten so it does happen and we
+                            // better fix it.
+                            n = 0;
                             bDec = true;
-                            [[fallthrough]];
+                        }
+
+                        mpRedlineTable->DeleteAndDestroy( nToBeDeleted );
+                    }
+                    break;
+                default:
+                    break;
+                }
+                break;
+
+            case RedlineType::Insert:
+            {
+                // b62341295: Do not throw away redlines
+                // even if they are not allowed to be combined
+                RedlineFlags eOld = meRedlineFlags;
+                if( !( eOld & RedlineFlags::DontCombineRedlines ) &&
+                    pRedl->IsOwnRedline( *pNewRedl ) )
+                {
 
-                        case SwComparePosition::Inside:
+                    // Set to NONE, so that the Delete::Redo merges the Redline data correctly!
+                    // The ShowMode needs to be retained!
+                    meRedlineFlags = eOld & ~RedlineFlags(RedlineFlags::On | RedlineFlags::Ignore);
+                    switch( eCmpPos )
+                    {
+                    case SwComparePosition::Equal:
+                        bCompress = true;
+                        mpRedlineTable->DeleteAndDestroy( n );
+                        bDec = true;
+                        [[fallthrough]];
+
+                    case SwComparePosition::Inside:
+                        if( bCallDelete )
+                        {
+                            // DeleteAndJoin does not yield the
+                            // desired result if there is no paragraph to
+                            // join with, i.e. at the end of the document.
+                            // For this case, we completely delete the
+                            // paragraphs (if, of course, we also start on
+                            // a paragraph boundary).
+                            if( (pStt->nContent == 0) &&
+                                pEnd->nNode.GetNode().IsEndNode() )
+                            {
+                                pEnd->nNode--;
+                                pEnd->nContent.Assign(
+                                    pEnd->nNode.GetNode().GetTextNode(), 0);
+                                m_rDoc.getIDocumentContentOperations().DelFullPara( *pNewRedl );
+                            }
+                            else
+                                m_rDoc.getIDocumentContentOperations().DeleteAndJoin( *pNewRedl );
+
+                            bCompress = true;
+                        }
+                        if( !bCallDelete && !bDec && *pEnd == *pREnd )
+                        {
+                            m_rDoc.getIDocumentContentOperations().DeleteAndJoin( *pNewRedl );
+                            bCompress = true;
+                        }
+                        else if ( bCallDelete || !bDec )
+                        {
+                            // delete new redline, except in some cases of fallthrough from previous
+                            // case ::Equal (eg. same portion w:del in w:ins in OOXML import)
+                            delete pNewRedl;
+                            pNewRedl = nullptr;
+                        }
+                        break;
+
+                    case SwComparePosition::Outside:
+                        {
+                            mpRedlineTable->Remove( n );
+                            bDec = true;
                             if( bCallDelete )
                             {
-                                // DeleteAndJoin does not yield the
-                                // desired result if there is no paragraph to
-                                // join with, i.e. at the end of the document.
-                                // For this case, we completely delete the
-                                // paragraphs (if, of course, we also start on
-                                // a paragraph boundary).
-                                if( (pStt->nContent == 0) &&
-                                    pEnd->nNode.GetNode().IsEndNode() )
-                                {
-                                    pEnd->nNode--;
-                                    pEnd->nContent.Assign(
-                                        pEnd->nNode.GetNode().GetTextNode(), 0);
-                                    m_rDoc.getIDocumentContentOperations().DelFullPara( *pNewRedl );
-                                }
-                                else
-                                    m_rDoc.getIDocumentContentOperations().DeleteAndJoin( *pNewRedl );
+                                TemporaryRedlineUpdater const u(m_rDoc, *pNewRedl);
+                                m_rDoc.getIDocumentContentOperations().DeleteAndJoin( *pRedl );
+                                n = 0;      // re-initialize
+                            }
+                            delete pRedl;
+                        }
+                        break;
 
-                                bCompress = true;
+                    case SwComparePosition::OverlapBefore:
+                        {
+                            SwPaM aPam( *pRStt, *pEnd );
+
+                            if( *pEnd == *pREnd )
+                                mpRedlineTable->DeleteAndDestroy( n );
+                            else
+                            {
+                                pRedl->SetStart( *pEnd, pRStt );
+                                // re-insert
+                                mpRedlineTable->Remove( n );
+                                mpRedlineTable->Insert( pRedl, n );
                             }
-                            if( !bCallDelete && !bDec && *pEnd == *pREnd )
+
+                            if( bCallDelete )
                             {
-                                m_rDoc.getIDocumentContentOperations().DeleteAndJoin( *pNewRedl );
-                                bCompress = true;
+                                TemporaryRedlineUpdater const u(m_rDoc, *pNewRedl);
+                                m_rDoc.getIDocumentContentOperations().DeleteAndJoin( aPam );
+                                n = 0;      // re-initialize
                             }
-                            else if ( bCallDelete || !bDec )
+                            bDec = true;
+                        }
+                        break;
+
+                    case SwComparePosition::OverlapBehind:
+                        {
+                            SwPaM aPam( *pStt, *pREnd );
+
+                            if( *pStt == *pRStt )
                             {
-                                // delete new redline, except in some cases of fallthrough from previous
-                                // case ::Equal (eg. same portion w:del in w:ins in OOXML import)
-                                delete pNewRedl;
-                                pNewRedl = nullptr;
+                                mpRedlineTable->DeleteAndDestroy( n );
+                                bDec = true;
                             }
-                            break;
+                            else
+                                pRedl->SetEnd( *pStt, pREnd );
 
-                        case SwComparePosition::Outside:
+                            if( bCallDelete )
                             {
-                                mpRedlineTable->Remove( n );
+                                TemporaryRedlineUpdater const u(m_rDoc, *pNewRedl);
+                                m_rDoc.getIDocumentContentOperations().DeleteAndJoin( aPam );
+                                n = 0;      // re-initialize
                                 bDec = true;
-                                if( bCallDelete )
-                                {
-                                    TemporaryRedlineUpdater const u(m_rDoc, *pNewRedl);
-                                    m_rDoc.getIDocumentContentOperations().DeleteAndJoin( *pRedl );
-                                    n = 0;      // re-initialize
-                                }
-                                delete pRedl;
                             }
-                            break;
+                        }
+                        break;
+                    default:
+                        break;
+                    }
+
+                    meRedlineFlags = eOld;
+                }
+                else
+                {
+                    // it may be necessary to split the existing redline in
+                    // two. In this case, pRedl will be changed to cover
+                    // only part of its former range, and pNew will cover
+                    // the remainder.
+                    SwRangeRedline* pNew = nullptr;
 
-                        case SwComparePosition::OverlapBefore:
+                    switch( eCmpPos )
+                    {
+                    case SwComparePosition::Equal:
+                        {
+                            pRedl->PushData( *pNewRedl );
+                            delete pNewRedl;
+                            pNewRedl = nullptr;
+                            if( IsHideChanges( meRedlineFlags ))
                             {
-                                SwPaM aPam( *pRStt, *pEnd );
+                                pRedl->Hide(0, mpRedlineTable->GetPos(pRedl));
+                            }
+                            bCompress = true;
+                        }
+                        break;
 
-                                if( *pEnd == *pREnd )
-                                    mpRedlineTable->DeleteAndDestroy( n );
-                                else
+                    case SwComparePosition::Inside:
+                        {
+                            if( *pRStt == *pStt )
+                            {
+                                // #i97421#
+                                // redline w/out extent loops
+                                if (*pStt != *pEnd)
                                 {
+                                    pNewRedl->PushData( *pRedl, false );
                                     pRedl->SetStart( *pEnd, pRStt );
                                     // re-insert
                                     mpRedlineTable->Remove( n );
                                     mpRedlineTable->Insert( pRedl, n );
+                                    bDec = true;
                                 }
-
-                                if( bCallDelete )
-                                {
-                                    TemporaryRedlineUpdater const u(m_rDoc, *pNewRedl);
-                                    m_rDoc.getIDocumentContentOperations().DeleteAndJoin( aPam );
-                                    n = 0;      // re-initialize
-                                }
-                                bDec = true;
                             }
-                            break;
-
-                        case SwComparePosition::OverlapBehind:
+                            else
                             {
-                                SwPaM aPam( *pStt, *pREnd );
-
-                                if( *pStt == *pRStt )
+                                pNewRedl->PushData( *pRedl, false );
+                                if( *pREnd != *pEnd )
                                 {
-                                    mpRedlineTable->DeleteAndDestroy( n );
-                                    bDec = true;
+                                    pNew = new SwRangeRedline( *pRedl );
+                                    pNew->SetStart( *pEnd );
                                 }
-                                else
-                                    pRedl->SetEnd( *pStt, pREnd );
-
-                                if( bCallDelete )
+                                pRedl->SetEnd( *pStt, pREnd );
+                                if( !pRedl->HasValidRange() )
                                 {
-                                    TemporaryRedlineUpdater const u(m_rDoc, *pNewRedl);
-                                    m_rDoc.getIDocumentContentOperations().DeleteAndJoin( aPam );
-                                    n = 0;      // re-initialize
-                                    bDec = true;
+                                    // re-insert
+                                    mpRedlineTable->Remove( n );
+                                    mpRedlineTable->Insert( pRedl, n );
                                 }
                             }
-                            break;
-                        default:
-                            break;
                         }
+                        break;
 
-                        meRedlineFlags = eOld;
-                    }
-                    else
-                    {
-                        // it may be necessary to split the existing redline in
-                        // two. In this case, pRedl will be changed to cover
-                        // only part of its former range, and pNew will cover
-                        // the remainder.
-                        SwRangeRedline* pNew = nullptr;
+                    case SwComparePosition::Outside:
+                        {
+                            pRedl->PushData( *pNewRedl );
+                            if( *pEnd == *pREnd )
+                            {
+                                pNewRedl->SetEnd( *pRStt, pEnd );
+                            }
+                            else if (*pStt == *pRStt)
+                            {
+                                pNewRedl->SetStart(*pREnd, pStt);
+                            }
+                            else
+                            {
+                                pNew = new SwRangeRedline( *pNewRedl );
+                                pNew->SetEnd( *pRStt );
+                                pNewRedl->SetStart( *pREnd, pStt );
+                            }
+                            bCompress = true;
+                        }
+                        break;
 
-                        switch( eCmpPos )
+                    case SwComparePosition::OverlapBefore:
                         {
-                        case SwComparePosition::Equal:
+                            if( *pEnd == *pREnd )
                             {
                                 pRedl->PushData( *pNewRedl );
-                                delete pNewRedl;
-                                pNewRedl = nullptr;
+                                pNewRedl->SetEnd( *pRStt, pEnd );
                                 if( IsHideChanges( meRedlineFlags ))
                                 {
+                                    mpRedlineTable->Insert(pNewRedl);
                                     pRedl->Hide(0, mpRedlineTable->GetPos(pRedl));
+                                    mpRedlineTable->Remove( pNewRedl );
                                 }
-                                bCompress = true;
                             }
-                            break;
-
-                        case SwComparePosition::Inside:
+                            else
                             {
-                                if( *pRStt == *pStt )
-                                {
-                                    // #i97421#
-                                    // redline w/out extent loops
-                                    if (*pStt != *pEnd)
-                                    {
-                                        pNewRedl->PushData( *pRedl, false );
-                                        pRedl->SetStart( *pEnd, pRStt );
-                                        // re-insert
-                                        mpRedlineTable->Remove( n );
-                                        mpRedlineTable->Insert( pRedl, n );
-                                        bDec = true;
-                                    }
-                                }
-                                else
-                                {
-                                    pNewRedl->PushData( *pRedl, false );
-                                    if( *pREnd != *pEnd )
-                                    {
-                                        pNew = new SwRangeRedline( *pRedl );
-                                        pNew->SetStart( *pEnd );
-                                    }
-                                    pRedl->SetEnd( *pStt, pREnd );
-                                    if( !pRedl->HasValidRange() )
-                                    {
-                                        // re-insert
-                                        mpRedlineTable->Remove( n );
-                                        mpRedlineTable->Insert( pRedl, n );
-                                    }
-                                }
+                                pNew = new SwRangeRedline( *pRedl );
+                                pNew->PushData( *pNewRedl );
+                                pNew->SetEnd( *pEnd );
+                                pNewRedl->SetEnd( *pRStt, pEnd );
+                                pRedl->SetStart( *pNew->End(), pRStt ) ;
+                                // re-insert
+                                mpRedlineTable->Remove( n );
+                                mpRedlineTable->Insert( pRedl );
+                                bDec = true;
                             }
-                            break;
+                        }
+                        break;
 
-                        case SwComparePosition::Outside:
+                    case SwComparePosition::OverlapBehind:
+                        {
+                            if( *pStt == *pRStt )
                             {
                                 pRedl->PushData( *pNewRedl );
-                                if( *pEnd == *pREnd )
-                                {
-                                    pNewRedl->SetEnd( *pRStt, pEnd );
-                                }
-                                else if (*pStt == *pRStt)
-                                {
-                                    pNewRedl->SetStart(*pREnd, pStt);
-                                }
-                                else
+                                pNewRedl->SetStart( *pREnd, pStt );
+                                if( IsHideChanges( meRedlineFlags ))
                                 {
-                                    pNew = new SwRangeRedline( *pNewRedl );
-                                    pNew->SetEnd( *pRStt );
-                                    pNewRedl->SetStart( *pREnd, pStt );
+                                    mpRedlineTable->Insert( pNewRedl );
+                                    pRedl->Hide(0, mpRedlineTable->GetPos(pRedl));
+                                    mpRedlineTable->Remove( pNewRedl );
                                 }
-                                bCompress = true;
                             }
-                            break;
-
-                        case SwComparePosition::OverlapBefore:
+                            else
                             {
-                                if( *pEnd == *pREnd )
+                                pNew = new SwRangeRedline( *pRedl );
+                                pNew->PushData( *pNewRedl );
+                                pNew->SetStart( *pStt );
+                                pNewRedl->SetStart( *pREnd, pStt );
+                                pRedl->SetEnd( *pNew->Start(), pREnd );
+                                if( !pRedl->HasValidRange() )
                                 {
-                                    pRedl->PushData( *pNewRedl );
-                                    pNewRedl->SetEnd( *pRStt, pEnd );
-                                    if( IsHideChanges( meRedlineFlags ))
-                                    {
-                                        mpRedlineTable->Insert(pNewRedl);
-                                        pRedl->Hide(0, mpRedlineTable->GetPos(pRedl));
-                                        mpRedlineTable->Remove( pNewRedl );
-                                    }
-                                }
-                                else
-                                {
-                                    pNew = new SwRangeRedline( *pRedl );
-                                    pNew->PushData( *pNewRedl );
-                                    pNew->SetEnd( *pEnd );
-                                    pNewRedl->SetEnd( *pRStt, pEnd );
-                                    pRedl->SetStart( *pNew->End(), pRStt ) ;
                                     // re-insert
                                     mpRedlineTable->Remove( n );
                                     mpRedlineTable->Insert( pRedl );
-                                    bDec = true;
                                 }
                             }
-                            break;
-
-                        case SwComparePosition::OverlapBehind:
-                            {
-                                if( *pStt == *pRStt )
-                                {
-                                    pRedl->PushData( *pNewRedl );
-                                    pNewRedl->SetStart( *pREnd, pStt );
-                                    if( IsHideChanges( meRedlineFlags ))
-                                    {
-                                        mpRedlineTable->Insert( pNewRedl );
-                                        pRedl->Hide(0, mpRedlineTable->GetPos(pRedl));
-                                        mpRedlineTable->Remove( pNewRedl );
-                                    }
-                                }
-                                else
-                                {
-                                    pNew = new SwRangeRedline( *pRedl );
-                                    pNew->PushData( *pNewRedl );
-                                    pNew->SetStart( *pStt );
-                                    pNewRedl->SetStart( *pREnd, pStt );
-                                    pRedl->SetEnd( *pNew->Start(), pREnd );
-                                    if( !pRedl->HasValidRange() )
-                                    {
-                                        // re-insert
-                                        mpRedlineTable->Remove( n );
-                                        mpRedlineTable->Insert( pRedl );
-                                    }
-                                }
-                            }
-                            break;
-                        default:
-                            break;
                         }
+                        break;
+                    default:
+                        break;
+                    }
+
+                    // insert the pNew part (if it exists)
+                    if( pNew )
+                    {
+                        mpRedlineTable->Insert( pNew );
+
+                        // pNew must be deleted if Insert() wasn't
+                        // successful. But that can't happen, since pNew is
+                        // part of the original pRedl redline.
+                        // OSL_ENSURE( bRet, "Can't insert existing redline?" );
+
+                        // restart (now with pRedl being split up)
+                        n = 0;
+                        bDec = true;
+                    }
+                }
+            }
+            break;
+
+            case RedlineType::Format:
+                switch( eCmpPos )
+                {
+                case SwComparePosition::OverlapBefore:
+                    pRedl->SetStart( *pEnd, pRStt );
+                    // re-insert
+                    mpRedlineTable->Remove( n );
+                    mpRedlineTable->Insert( pRedl, n );
+                    bDec = true;
+                    break;
 
-                        // insert the pNew part (if it exists)
-                        if( pNew )
-                        {
-                            mpRedlineTable->Insert( pNew );
+                case SwComparePosition::OverlapBehind:
+                    pRedl->SetEnd( *pStt, pREnd );
+                    break;
 
-                            // pNew must be deleted if Insert() wasn't
-                            // successful. But that can't happen, since pNew is
-                            // part of the original pRedl redline.
-                            // OSL_ENSURE( bRet, "Can't insert existing redline?" );
+                case SwComparePosition::Equal:
+                case SwComparePosition::Outside:
+                    // Overlaps the current one completely or has the
+                    // same dimension, delete the old one
+                    mpRedlineTable->DeleteAndDestroy( n );
+                    bDec = true;
+                    break;
 
-                            // restart (now with pRedl being split up)
-                            n = 0;
+                case SwComparePosition::Inside:
+                    // Overlaps the current one completely,
+                    // split or shorten the new one
+                    if( *pEnd != *pREnd )
+                    {
+                        if( *pEnd != *pRStt )
+                        {
+                            SwRangeRedline* pNew = new SwRangeRedline( *pRedl );
+                            pNew->SetStart( *pEnd );
+                            pRedl->SetEnd( *pStt, pREnd );
+                            if( ( *pStt == *pRStt ) &&
+                                ( pRedl->GetContentIdx() == nullptr ) )
+                                mpRedlineTable->DeleteAndDestroy( n );
+                            AppendRedline( pNew, bCallDelete );
+                            n = 0;      // re-initialize
                             bDec = true;
                         }
                     }
+                    else
+                        pRedl->SetEnd( *pStt, pREnd );
+                    break;
+                default:
+                    break;
                 }
                 break;
+            default:
+                break;
+            }
+            break;
 
-                case RedlineType::Format:
-                    switch( eCmpPos )
-                    {
-                    case SwComparePosition::OverlapBefore:
-                        pRedl->SetStart( *pEnd, pRStt );
-                        // re-insert
-                        mpRedlineTable->Remove( n );
-                        mpRedlineTable->Insert( pRedl, n );
-                        bDec = true;
-                        break;
+        case RedlineType::Format:
+            switch( pRedl->GetType() )
+            {
+            case RedlineType::Insert:
+            case RedlineType::Delete:
+                switch( eCmpPos )
+                {
+                case SwComparePosition::OverlapBefore:
+                    pNewRedl->SetEnd( *pRStt, pEnd );
+                    break;
 
-                    case SwComparePosition::OverlapBehind:
-                        pRedl->SetEnd( *pStt, pREnd );
-                        break;
+                case SwComparePosition::OverlapBehind:
+                    pNewRedl->SetStart( *pREnd, pStt );
+                    break;
 
-                    case SwComparePosition::Equal:
-                    case SwComparePosition::Outside:
-                        // Overlaps the current one completely or has the
-                        // same dimension, delete the old one
-                        mpRedlineTable->DeleteAndDestroy( n );
-                        bDec = true;
-                        break;
+                case SwComparePosition::Equal:
+                case SwComparePosition::Inside:
+                    delete pNewRedl;
+                    pNewRedl = nullptr;
+                    break;
 
-                    case SwComparePosition::Inside:
-                        // Overlaps the current one completely,
-                        // split or shorten the new one
-                        if( *pEnd != *pREnd )
-                        {
-                            if( *pEnd != *pRStt )
-                            {
-                                SwRangeRedline* pNew = new SwRangeRedline( *pRedl );
-                                pNew->SetStart( *pEnd );
-                                pRedl->SetEnd( *pStt, pREnd );
-                                if( ( *pStt == *pRStt ) &&
-                                    ( pRedl->GetContentIdx() == nullptr ) )
-                                    mpRedlineTable->DeleteAndDestroy( n );
-                                AppendRedline( pNew, bCallDelete );
-                                n = 0;      // re-initialize
-                                bDec = true;
-                            }
-                        }
-                        else
-                            pRedl->SetEnd( *pStt, pREnd );
-                        break;
-                    default:
-                        break;
+                case SwComparePosition::Outside:
+                    // Overlaps the current one completely,
+                    // split or shorten the new one
+                    if (*pEnd == *pREnd)
+                    {
+                        pNewRedl->SetEnd(*pRStt, pEnd);
+                    }
+                    else if (*pStt == *pRStt)
+                    {
+                        pNewRedl->SetStart(*pREnd, pStt);
+                    }
+                    else
+                    {
+                        SwRangeRedline* pNew = new SwRangeRedline( *pNewRedl );
+                        pNew->SetStart( *pREnd );
+                        pNewRedl->SetEnd( *pRStt, pEnd );
+                        AppendRedline( pNew, bCallDelete );
+                        n = 0;      // re-initialize
+                        bDec = true;
                     }
                     break;
                 default:
                     break;
                 }
                 break;
-
             case RedlineType::Format:
-                switch( pRedl->GetType() )
+                switch( eCmpPos )
                 {
-                case RedlineType::Insert:
-                case RedlineType::Delete:
-                    switch( eCmpPos )
+                case SwComparePosition::Outside:
+                case SwComparePosition::Equal:
                     {
-                    case SwComparePosition::OverlapBefore:
-                        pNewRedl->SetEnd( *pRStt, pEnd );
-                        break;
-
-                    case SwComparePosition::OverlapBehind:
-                        pNewRedl->SetStart( *pREnd, pStt );
-                        break;
+                        // Overlaps the current one completely or has the
+                        // same dimension, delete the old one
+                        mpRedlineTable->DeleteAndDestroy( n );
+                        bDec = true;
+                    }
+                    break;
 
-                    case SwComparePosition::Equal:
-                    case SwComparePosition::Inside:
+                case SwComparePosition::Inside:
+                    if( pRedl->IsOwnRedline( *pNewRedl ) &&
+                        pRedl->CanCombine( *pNewRedl ))
+                    {
+                        // own one can be ignored completely
                         delete pNewRedl;
                         pNewRedl = nullptr;
-                        break;
-
-                    case SwComparePosition::Outside:
-                        // Overlaps the current one completely,
-                        // split or shorten the new one
-                        if (*pEnd == *pREnd)
-                        {
-                            pNewRedl->SetEnd(*pRStt, pEnd);
-                        }
-                        else if (*pStt == *pRStt)
-                        {
-                            pNewRedl->SetStart(*pREnd, pStt);
-                        }
-                        else
-                        {
-                            SwRangeRedline* pNew = new SwRangeRedline( *pNewRedl );
-                            pNew->SetStart( *pREnd );
-                            pNewRedl->SetEnd( *pRStt, pEnd );
-                            AppendRedline( pNew, bCallDelete );
-                            n = 0;      // re-initialize
-                            bDec = true;
-                        }
-                        break;
-                    default:
-                        break;
                     }
-                    break;
-                case RedlineType::Format:
-                    switch( eCmpPos )
+                    else if( *pREnd == *pEnd )
+                        // or else only shorten the current one
+                        pRedl->SetEnd( *pStt, pREnd );
+                    else if( *pRStt == *pStt )
                     {
-                    case SwComparePosition::Outside:
-                    case SwComparePosition::Equal:
-                        {
-                            // Overlaps the current one completely or has the
-                            // same dimension, delete the old one
-                            mpRedlineTable->DeleteAndDestroy( n );
-                            bDec = true;
-                        }
-                        break;
-
-                    case SwComparePosition::Inside:
-                        if( pRedl->IsOwnRedline( *pNewRedl ) &&
-                            pRedl->CanCombine( *pNewRedl ))
-                        {
-                            // own one can be ignored completely
-                            delete pNewRedl;
-                            pNewRedl = nullptr;
-                        }
-                        else if( *pREnd == *pEnd )
-                            // or else only shorten the current one
-                            pRedl->SetEnd( *pStt, pREnd );
-                        else if( *pRStt == *pStt )
-                        {
-                            // or else only shorten the current one
-                            pRedl->SetStart( *pEnd, pRStt );
-                            // re-insert
-                            mpRedlineTable->Remove( n );
-                            mpRedlineTable->Insert( pRedl, n );
-                            bDec = true;
-                        }
-                        else
-                        {
-                            // If it lies completely within the current one
-                            // we need to split it
-                            SwRangeRedline* pNew = new SwRangeRedline( *pRedl );
-                            pNew->SetStart( *pEnd );
-                            pRedl->SetEnd( *pStt, pREnd );
-                            AppendRedline( pNew, bCallDelete );
-                            n = 0;      // re-initialize
-                            bDec = true;
-                        }
-                        break;
+                        // or else only shorten the current one
+                        pRedl->SetStart( *pEnd, pRStt );
+                        // re-insert
+                        mpRedlineTable->Remove( n );
+                        mpRedlineTable->Insert( pRedl, n );
+                        bDec = true;
+                    }
+                    else
+                    {
+                        // If it lies completely within the current one
+                        // we need to split it
+                        SwRangeRedline* pNew = new SwRangeRedline( *pRedl );
+                        pNew->SetStart( *pEnd );
+                        pRedl->SetEnd( *pStt, pREnd );
+                        AppendRedline( pNew, bCallDelete );
+                        n = 0;      // re-initialize
+                        bDec = true;
+                    }
+                    break;
 
-                    case SwComparePosition::OverlapBefore:
-                    case SwComparePosition::OverlapBehind:
-                        if( pRedl->IsOwnRedline( *pNewRedl ) &&
-                            pRedl->CanCombine( *pNewRedl ))
-                        {
-                            // If that's the case we can merge it, meaning
-                            // the new one covers this well
-                            if( SwComparePosition::OverlapBehind == eCmpPos )
-                                pNewRedl->SetStart( *pRStt, pStt );
-                            else
-                                pNewRedl->SetEnd( *pREnd, pEnd );
-                            mpRedlineTable->DeleteAndDestroy( n );
-                            bDec = false;
-                        }
-                        else if( SwComparePosition::OverlapBehind == eCmpPos )
-                            pNewRedl->SetStart( *pREnd, pStt );
+                case SwComparePosition::OverlapBefore:
+                case SwComparePosition::OverlapBehind:
+                    if( pRedl->IsOwnRedline( *pNewRedl ) &&
+                        pRedl->CanCombine( *pNewRedl ))
+                    {
+                        // If that's the case we can merge it, meaning
+                        // the new one covers this well
+                        if( SwComparePosition::OverlapBehind == eCmpPos )
+                            pNewRedl->SetStart( *pRStt, pStt );
                         else
-                            pNewRedl->SetEnd( *pRStt, pEnd );
-                        break;
-
-                    case SwComparePosition::CollideEnd:
-                        if( pRedl->IsOwnRedline( *pNewRedl ) &&
-                            pRedl->CanCombine( *pNewRedl ) && n &&
-                            *(*mpRedlineTable)[ n-1 ]->End() < *pStt )
-                        {
-                            // If that's the case we can merge it, meaning
-                            // the new one covers this well
                             pNewRedl->SetEnd( *pREnd, pEnd );
-                            mpRedlineTable->DeleteAndDestroy( n );
-                            bDec = true;
-                        }
-                        break;
-                    case SwComparePosition::CollideStart:
-                        if( pRedl->IsOwnRedline( *pNewRedl ) &&
-                            pRedl->CanCombine( *pNewRedl ) &&
-                            n+1 < mpRedlineTable->size() &&
-                            *(*mpRedlineTable)[ n+1 ]->Start() < *pEnd )
-                        {
-                            // If that's the case we can merge it, meaning
-                            // the new one covers this well
-                            pNewRedl->SetStart( *pRStt, pStt );
-                            mpRedlineTable->DeleteAndDestroy( n );
-                            bDec = true;
-                        }
-                        break;
-                    default:
-                        break;
+                        mpRedlineTable->DeleteAndDestroy( n );
+                        bDec = false;
+                    }
+                    else if( SwComparePosition::OverlapBehind == eCmpPos )
+                        pNewRedl->SetStart( *pREnd, pStt );
+                    else
+                        pNewRedl->SetEnd( *pRStt, pEnd );
+                    break;
+
+                case SwComparePosition::CollideEnd:
+                    if( pRedl->IsOwnRedline( *pNewRedl ) &&
+                        pRedl->CanCombine( *pNewRedl ) && n &&
+                        *(*mpRedlineTable)[ n-1 ]->End() < *pStt )
+                    {
+                        // If that's the case we can merge it, meaning
+                        // the new one covers this well
+                        pNewRedl->SetEnd( *pREnd, pEnd );
+                        mpRedlineTable->DeleteAndDestroy( n );
+                        bDec = true;
+                    }
+                    break;
+                case SwComparePosition::CollideStart:
+                    if( pRedl->IsOwnRedline( *pNewRedl ) &&
+                        pRedl->CanCombine( *pNewRedl ) &&
+                        n+1 < mpRedlineTable->size() &&
+                        *(*mpRedlineTable)[ n+1 ]->Start() < *pEnd )
+                    {
+                        // If that's the case we can merge it, meaning
+                        // the new one covers this well
+                        pNewRedl->SetStart( *pRStt, pStt );
+                        mpRedlineTable->DeleteAndDestroy( n );
+                        bDec = true;
                     }
                     break;
                 default:
                     break;
                 }
                 break;
-
-            case RedlineType::FmtColl:
-                // How should we behave here?
-                // insert as is
-                break;
             default:
                 break;
             }
+            break;
+
+        case RedlineType::FmtColl:
+            // How should we behave here?
+            // insert as is
+            break;
+        default:
+            break;
         }
+    }
 
-        if( pNewRedl )
+    if( pNewRedl )
+    {
+        if( ( *pStt == *pEnd ) &&
+            ( pNewRedl->GetContentIdx() == nullptr ) )
+        {   // Do not insert empty redlines
+            delete pNewRedl;
+            pNewRedl = nullptr;
+        }
+        else
         {
-            if( ( *pStt == *pEnd ) &&
-                ( pNewRedl->GetContentIdx() == nullptr ) )
-            {   // Do not insert empty redlines
-                delete pNewRedl;
-                pNewRedl = nullptr;
-            }
-            else
+            if ( bCallDelete && RedlineType::Delete == pNewRedl->GetType() )
             {
-                if ( bCallDelete && RedlineType::Delete == pNewRedl->GetType() )
+                if ( pStt->nContent != 0 )
                 {
-                    if ( pStt->nContent != 0 )
-                    {
-                        // tdf#119571 update the style of the joined paragraph
-                        // after a partially deleted paragraph to show its correct style
-                        // in "Show changes" mode, too. All removed paragraphs
-                        // get the style of the first (partially deleted) paragraph
-                        // to avoid text insertion with bad style in the deleted
-                        // area later.
-
-                        SwContentNode* pDelNd = pStt->nNode.GetNode().GetContentNode();
-                        SwContentNode* pTextNd = pEnd->nNode.GetNode().GetContentNode();
-                        SwTextNode* pDelNode = pStt->nNode.GetNode().GetTextNode();
-                        SwTextNode* pTextNode;
-                        SwNodeIndex aIdx( pEnd->nNode.GetNode() );
-                        bool bFirst = true;
-
-                        while (pDelNode != nullptr && pTextNd != nullptr && pDelNd->GetIndex() < pTextNd->GetIndex())
+                    // tdf#119571 update the style of the joined paragraph
+                    // after a partially deleted paragraph to show its correct style
+                    // in "Show changes" mode, too. All removed paragraphs
+                    // get the style of the first (partially deleted) paragraph
+                    // to avoid text insertion with bad style in the deleted
+                    // area later.
+
+                    SwContentNode* pDelNd = pStt->nNode.GetNode().GetContentNode();
+                    SwContentNode* pTextNd = pEnd->nNode.GetNode().GetContentNode();
+                    SwTextNode* pDelNode = pStt->nNode.GetNode().GetTextNode();
+                    SwTextNode* pTextNode;
+                    SwNodeIndex aIdx( pEnd->nNode.GetNode() );
+                    bool bFirst = true;
+
+                    while (pDelNode != nullptr && pTextNd != nullptr && pDelNd->GetIndex() < pTextNd->GetIndex())
+                    {
+                        pTextNode = pTextNd->GetTextNode();
+                        if (pTextNode && pDelNode != pTextNode )
                         {
-                            pTextNode = pTextNd->GetTextNode();
-                            if (pTextNode && pDelNode != pTextNode )
+                            SwPosition aPos(aIdx);
+
+                            if (m_rDoc.GetIDocumentUndoRedo().DoesUndo())
                             {
-                                SwPosition aPos(aIdx);
+                                bCompress = true;
 
-                                if (m_rDoc.GetIDocumentUndoRedo().DoesUndo())
+                                // split redline to store ExtraData per paragraphs
+                                SwRangeRedline* pPar = new SwRangeRedline( *pNewRedl );
+                                pPar->SetStart( aPos );
+                                pNewRedl->SetEnd( aPos );
+
+                                // get extradata for reset formatting of the modified paragraph
+                                SwRedlineExtraData_FormatColl* pExtraData = lcl_CopyStyle(aPos, *pStt, false);
+                                if (pExtraData)
                                 {
-                                    bCompress = true;
-
-                                    // split redline to store ExtraData per paragraphs
-                                    SwRangeRedline* pPar = new SwRangeRedline( *pNewRedl );
-                                    pPar->SetStart( aPos );
-                                    pNewRedl->SetEnd( aPos );
-
-                                    // get extradata for reset formatting of the modified paragraph
-                                    SwRedlineExtraData_FormatColl* pExtraData = lcl_CopyStyle(aPos, *pStt, false);
-                                    if (pExtraData)
-                                    {
-                                        std::unique_ptr<SwRedlineExtraData_FormatColl> xRedlineExtraData;
-                                        if (!bFirst)
-                                            pExtraData->SetFormatAll(false);
-                                        xRedlineExtraData.reset(pExtraData);
-                                        pPar->SetExtraData( xRedlineExtraData.get() );
-                                    }
-
-                                    // skip empty redlines without ExtraData
-                                    // FIXME: maybe checking pExtraData is redundant here
-                                    if ( pExtraData || *pPar->Start() != *pPar->End() )
-                                        mpRedlineTable->Insert( pPar );
-                                    else
-                                        delete pPar;
+                                    std::unique_ptr<SwRedlineExtraData_FormatColl> xRedlineExtraData;
+                                    if (!bFirst)
+                                        pExtraData->SetFormatAll(false);
+                                    xRedlineExtraData.reset(pExtraData);
+                                    pPar->SetExtraData( xRedlineExtraData.get() );
                                 }
 
-                                // modify paragraph formatting
-                                lcl_CopyStyle(*pStt, aPos);
+                                // skip empty redlines without ExtraData
+                                // FIXME: maybe checking pExtraData is redundant here
+                                if ( pExtraData || *pPar->Start() != *pPar->End() )
+                                    mpRedlineTable->Insert( pPar );
+                                else
+                                    delete pPar;
                             }
-                            pTextNd = SwNodes::GoPrevious( &aIdx );
 
-                            if (bFirst)
-                                bFirst = false;
+                            // modify paragraph formatting
+                            lcl_CopyStyle(*pStt, aPos);
                         }
+                        pTextNd = SwNodes::GoPrevious( &aIdx );
+
+                        if (bFirst)
+                            bFirst = false;
                     }
                 }
-                bool const ret = mpRedlineTable->Insert( pNewRedl );
-                assert(ret || !pNewRedl);
-                if (ret && !pNewRedl)
-                {
-                    bMerged = true; // treat InsertWithValidRanges as "merge"
-                }
+            }
+            bool const ret = mpRedlineTable->Insert( pNewRedl );
+            assert(ret || !pNewRedl);
+            if (ret && !pNewRedl)
+            {
+                bMerged = true; // treat InsertWithValidRanges as "merge"
             }
         }
-
-        if( bCompress )
-            CompressRedlines();
-    }
-    else
-    {
-        if( bCallDelete && RedlineType::Delete == pNewRedl->GetType() )
-        {
-            RedlineFlags eOld = meRedlineFlags;
-            // Set to NONE, so that the Delete::Redo merges the Redline data correctly!
-            // The ShowMode needs to be retained!
-            meRedlineFlags = eOld & ~RedlineFlags(RedlineFlags::On | RedlineFlags::Ignore);
-            m_rDoc.getIDocumentContentOperations().DeleteAndJoin( *pNewRedl );
-            meRedlineFlags = eOld;
-        }
-        delete pNewRedl;
-        pNewRedl = nullptr;
     }
+
+    if( bCompress )
+        CompressRedlines();
+
     CHECK_REDLINE( *this )
 
     return (nullptr != pNewRedl)


More information about the Libreoffice-commits mailing list