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.st...@cib.de> AuthorDate: Fri Jun 12 19:08:19 2020 +0200 Commit: Thorsten Behrens <thorsten.behr...@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.st...@cib.de> (cherry picked from commit ad0351b84926075297fb74abbe9b31a0455782af) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/96517 Reviewed-by: Thorsten Behrens <thorsten.behr...@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()); } _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits