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

Michael Stahl (via logerrit) logerrit at kemper.freedesktop.org
Wed Jun 17 08:30:40 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 ad0351b84926075297fb74abbe9b31a0455782af
Author:     Michael Stahl <Michael.Stahl at cib.de>
AuthorDate: Fri Jun 12 19:08:19 2020 +0200
Commit:     Michael Stahl <michael.stahl at cib.de>
CommitDate: Wed Jun 17 10:30:00 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>

diff --git a/sw/source/core/doc/DocumentRedlineManager.cxx b/sw/source/core/doc/DocumentRedlineManager.cxx
index b8b85c984546..6bce5c1d9364 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>
@@ -889,6 +891,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
@@ -1558,12 +1575,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 )
@@ -1583,6 +1602,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;
@@ -1607,6 +1627,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;
@@ -1629,6 +1650,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 c99939a5d0ec..ce38a4d99e03 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 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 f285e8852f5b..739597cf6fce 100644
--- a/sw/source/core/undo/undel.cxx
+++ b/sw/source/core/undo/undel.cxx
@@ -186,6 +186,7 @@ SwUndoDelete::SwUndoDelete(
     m_bResetPgDesc( false ),
     m_bResetPgBrk( false ),
     m_bFromTableCopy( bCalledByTableCpy )
+    , m_bDisableMakeFrames(false)
 {
 
     m_bCacheComment = false;
@@ -1047,7 +1048,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,
@@ -1094,7 +1114,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
@@ -1110,7 +1130,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