[Libreoffice-commits] core.git: Branch 'libreoffice-6-4' - sw/source

Michael Stahl (via logerrit) logerrit at kemper.freedesktop.org
Wed Jun 17 22:48:22 UTC 2020


 sw/source/core/doc/DocumentRedlineManager.cxx |   22 ++++++++++++++++++++++
 sw/source/core/inc/UndoDelete.hxx             |    3 +++
 sw/source/core/undo/undel.cxx                 |   26 +++++++++++++++++++++++---
 3 files changed, 48 insertions(+), 3 deletions(-)

New commits:
commit 1e04dd3bca5b3bd3ea94af3304bdce87b705451b
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Fri Jun 12 19:08:19 2020 +0200
Commit:     Thorsten Behrens <Thorsten.Behrens at CIB.de>
CommitDate: Thu Jun 18 00:47:51 2020 +0200

    tdf#132944 sw_redlinehide: delete of insert redline
    
    Because of an existing insert redline with SwComparePosition::Equal
    this hits the DeleteAndJoin() call in AppendRedline() and so what
    happens on Undo is that the SwUndoDelete first creates all the layout
    frames and then the SwUndoRedlineDelete creates the frames a 2nd time.
    
    Because this can happen not only for Equal but also Inside case, it
    appears best to prevent the "inner" Undo from recreating the frames;
    it's always SwUndoDelete.
    
    This is quite hacky...
    
    Change-Id: I4438dd09bb6c2edf8154d333de403483768755fd
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/96233
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.stahl at cib.de>
    (cherry picked from commit ad0351b84926075297fb74abbe9b31a0455782af)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/96517
    Reviewed-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>

diff --git a/sw/source/core/doc/DocumentRedlineManager.cxx b/sw/source/core/doc/DocumentRedlineManager.cxx
index fb6a54d5cec2..d23a69717f66 100644
--- a/sw/source/core/doc/DocumentRedlineManager.cxx
+++ b/sw/source/core/doc/DocumentRedlineManager.cxx
@@ -25,6 +25,8 @@
 #include <fmtfld.hxx>
 #include <frmtool.hxx>
 #include <IDocumentUndoRedo.hxx>
+#include <UndoManager.hxx>
+#include <UndoDelete.hxx>
 #include <IDocumentFieldsAccess.hxx>
 #include <IDocumentLayoutAccess.hxx>
 #include <IDocumentState.hxx>
@@ -887,6 +889,21 @@ namespace
             static_cast<SwPaM&>(m_rRedline) = *m_pCursor;
         }
     };
+
+    auto UndoDeleteDisableFrames(SwDoc & rDoc) -> void
+    {
+        // inside AppendRedline(), a SwUndoDelete was created;
+        // prevent it from creating duplicate layout frames on Undo
+        auto & rUndo(rDoc.GetUndoManager());
+        if (rUndo.DoesUndo())
+        {
+            SwUndo *const pUndo(rUndo.GetLastUndo());
+            assert(pUndo);
+            SwUndoDelete *const pUndoDel(dynamic_cast<SwUndoDelete*>(pUndo));
+            assert(pUndoDel);
+            pUndoDel->DisableMakeFrames(); // tdf#132944
+        }
+    }
 }
 
 namespace sw
@@ -1556,12 +1573,14 @@ DocumentRedlineManager::AppendRedline(SwRangeRedline* pNewRedl, bool const bCall
                                 }
                                 else
                                     m_rDoc.getIDocumentContentOperations().DeleteAndJoin( *pNewRedl );
+                                UndoDeleteDisableFrames(m_rDoc); // tdf#132944
 
                                 bCompress = true;
                             }
                             if( !bCallDelete && !bDec && *pEnd == *pREnd )
                             {
                                 m_rDoc.getIDocumentContentOperations().DeleteAndJoin( *pNewRedl );
+                                UndoDeleteDisableFrames(m_rDoc);
                                 bCompress = true;
                             }
                             else if ( bCallDelete || !bDec )
@@ -1581,6 +1600,7 @@ DocumentRedlineManager::AppendRedline(SwRangeRedline* pNewRedl, bool const bCall
                                 {
                                     TemporaryRedlineUpdater const u(m_rDoc, *pNewRedl);
                                     m_rDoc.getIDocumentContentOperations().DeleteAndJoin( *pRedl );
+                                    UndoDeleteDisableFrames(m_rDoc);
                                     n = 0;      // re-initialize
                                 }
                                 delete pRedl;
@@ -1605,6 +1625,7 @@ DocumentRedlineManager::AppendRedline(SwRangeRedline* pNewRedl, bool const bCall
                                 {
                                     TemporaryRedlineUpdater const u(m_rDoc, *pNewRedl);
                                     m_rDoc.getIDocumentContentOperations().DeleteAndJoin( aPam );
+                                    UndoDeleteDisableFrames(m_rDoc);
                                     n = 0;      // re-initialize
                                 }
                                 bDec = true;
@@ -1627,6 +1648,7 @@ DocumentRedlineManager::AppendRedline(SwRangeRedline* pNewRedl, bool const bCall
                                 {
                                     TemporaryRedlineUpdater const u(m_rDoc, *pNewRedl);
                                     m_rDoc.getIDocumentContentOperations().DeleteAndJoin( aPam );
+                                    UndoDeleteDisableFrames(m_rDoc);
                                     n = 0;      // re-initialize
                                     bDec = true;
                                 }
diff --git a/sw/source/core/inc/UndoDelete.hxx b/sw/source/core/inc/UndoDelete.hxx
index b9b52583971e..a0ff970661f0 100644
--- a/sw/source/core/inc/UndoDelete.hxx
+++ b/sw/source/core/inc/UndoDelete.hxx
@@ -59,6 +59,7 @@ class SwUndoDelete
     bool m_bResetPgDesc : 1;   // TRUE: reset PgDsc on following node
     bool m_bResetPgBrk : 1;    // TRUE: reset PgBreak on following node
     bool const m_bFromTableCopy : 1; // TRUE: called by SwUndoTableCpyTable
+    bool m_bDisableMakeFrames : 1;
 
     bool SaveContent( const SwPosition* pStt, const SwPosition* pEnd,
                     SwTextNode* pSttTextNd, SwTextNode* pEndTextNd );
@@ -98,6 +99,8 @@ public:
 
     // SwUndoTableCpyTable needs this information:
     bool IsDelFullPara() const { return m_bDelFullPara; }
+
+    void DisableMakeFrames() { m_bDisableMakeFrames = true; };
 };
 
 #endif // INCLUDED_SW_SOURCE_CORE_INC_UNDODELETE_HXX
diff --git a/sw/source/core/undo/undel.cxx b/sw/source/core/undo/undel.cxx
index 30298fe1e761..0510ea64dc37 100644
--- a/sw/source/core/undo/undel.cxx
+++ b/sw/source/core/undo/undel.cxx
@@ -190,6 +190,7 @@ SwUndoDelete::SwUndoDelete(
     m_bResetPgDesc( false ),
     m_bResetPgBrk( false ),
     m_bFromTableCopy( bCalledByTableCpy )
+    , m_bDisableMakeFrames(false)
 {
 
     m_bCacheComment = false;
@@ -1051,7 +1052,26 @@ void SwUndoDelete::UndoImpl(::sw::UndoRedoContext & rContext)
         SetSaveData(rDoc, *m_pRedlSaveData);
 
     sal_uLong delFullParaEndNode(m_nEndNode);
-    if (m_bDelFullPara && m_pRedlSaveData)
+    if (m_bDisableMakeFrames) // tdf#132944
+    {
+        assert(!m_bDelFullPara);
+        SwTextNode *const pEndNode(aIdx.GetNodes()[m_nEndNode]->GetTextNode());
+        SwIterator<SwTextFrame, SwTextNode, sw::IteratorMode::UnwrapMulti> aIter(*pEndNode);
+        for (SwTextFrame* pFrame = aIter.First(); pFrame; pFrame = aIter.Next())
+        {
+            o3tl::sorted_vector<SwRootFrame *> layouts;
+            if (pFrame->getRootFrame()->IsHideRedlines())
+            {
+                assert(pFrame->GetTextNodeFirst() == pEndNode); // can't be merged with previous
+                layouts.insert(pFrame->getRootFrame());
+            }
+            for (SwRootFrame const*const pLayout : layouts)
+            {
+                pEndNode->DelFrames(pLayout); // SwUndoRedlineDelete will create it
+            }
+        }
+    }
+    else if (m_bDelFullPara && m_pRedlSaveData)
     {
         SwTextNode * pFirstMergedDeletedTextNode(nullptr);
         SwTextNode *const pNextNode = FindFirstAndNextNode(rDoc, *this,
@@ -1098,7 +1118,7 @@ void SwUndoDelete::UndoImpl(::sw::UndoRedoContext & rContext)
     }
 
     // create frames after SetSaveData has recreated redlines
-    if (0 != m_nNode)
+    if (0 != m_nNode && !m_bDisableMakeFrames)
     {
         // tdf#121031 if the start node is a text node, it already has a frame;
         // if it's a table, it does not
@@ -1114,7 +1134,7 @@ void SwUndoDelete::UndoImpl(::sw::UndoRedoContext & rContext)
         ::MakeFrames(&rDoc, start, end);
     }
 
-    if (pMovedNode)
+    if (pMovedNode && !m_bDisableMakeFrames)
     {   // probably better do this after creating all frames
         lcl_MakeAutoFrames(*rDoc.GetSpzFrameFormats(), pMovedNode->GetIndex());
     }


More information about the Libreoffice-commits mailing list