From 685442bf71440e56fa8ae5a572d62f0a1e2c3200 Mon Sep 17 00:00:00 2001 From: Michael Stahl Date: Fri, 18 Aug 2017 23:05:53 +0200 Subject: tdf#111524 sw: delete annotation marks when creating delete redline Range annotations are represented by a SwPostItField at the end of the annotated range, and a AnnotationMark that covers the range (including the field). During a normal delete, SwUndoDelete calls SwUndoSaveContent::DelContentIndex(), which has a special case to remove the AnnotationMark if the field is deleted. The problem is that when change tracking is enabled, the AnnotationMark survives, but the field is moved out of the paragraph when the redlines are hidden (as happens during ODF export), hence lcl_FillAnnotationStartArray() doesn't find its field. There doesn't appear to be a good solution to this, because in ODF it's also not possible to represent this, because the deleted content is outside the text:p element. It doesn't work to delete the annotation mark in DelBookmarks(), when hiding the redline, because then no Undo is created to restore the mark, and DelBookmarks() is also called from Undo code from SwUndoDelete, which breaks with this change. So delete the annotation mark when creating the redline in DocumentContentOperationsManager::DeleteAndJoinWithRedlineImpl(). Fixes the assert and the subsequent crash, which is a regression from 31c54fa7bb03768b425ae019096e0a0e26e9c736. Change-Id: I361ffee8e6ab86de499c25f34a96ceeaf83d9e0b --- .../core/doc/DocumentContentOperationsManager.cxx | 37 +++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/sw/source/core/doc/DocumentContentOperationsManager.cxx b/sw/source/core/doc/DocumentContentOperationsManager.cxx index 42572905e79c..45d192443d66 100644 --- a/sw/source/core/doc/DocumentContentOperationsManager.cxx +++ b/sw/source/core/doc/DocumentContentOperationsManager.cxx @@ -52,6 +52,7 @@ #include #include #include +#include #include #include #include @@ -73,6 +74,7 @@ #include #include #include +#include #include #include @@ -3556,6 +3558,36 @@ bool DocumentContentOperationsManager::DeleteAndJoinWithRedlineImpl( SwPaM & rPa SwUndoRedlineDelete* pUndo = nullptr; RedlineFlags eOld = m_rDoc.getIDocumentRedlineAccess().GetRedlineFlags(); m_rDoc.GetDocumentRedlineManager().checkRedlining( eOld ); + + auto & rDMA(*m_rDoc.getIDocumentMarkAccess()); + std::vector> MarkUndos; + for (auto iter = rDMA.getAnnotationMarksBegin(); + iter != rDMA.getAnnotationMarksEnd(); ) + { + // tdf#111524 remove annotation marks that have their field + // characters deleted + SwPosition const& rEndPos((**iter).GetMarkEnd()); + if (*rPam.Start() < rEndPos && rEndPos <= *rPam.End()) + { + if (m_rDoc.GetIDocumentUndoRedo().DoesUndo()) + { + MarkUndos.emplace_back(o3tl::make_unique(**iter)); + } + // iter is into annotation mark vector so must be dereferenced! + rDMA.deleteMark(&**iter); + // this invalidates iter, have to start over... + iter = rDMA.getAnnotationMarksBegin(); + } + else + { // marks are sorted by start + if (*rPam.End() < (**iter).GetMarkStart()) + { + break; + } + ++iter; + } + } + if (m_rDoc.GetIDocumentUndoRedo().DoesUndo()) { @@ -3564,10 +3596,13 @@ bool DocumentContentOperationsManager::DeleteAndJoinWithRedlineImpl( SwPaM & rPa //JP 06.01.98: MUSS noch optimiert werden!!! m_rDoc.getIDocumentRedlineAccess().SetRedlineFlags( RedlineFlags::On | RedlineFlags::ShowInsert | RedlineFlags::ShowDelete ); - pUndo = new SwUndoRedlineDelete( rPam, SwUndoId::DELETE ); const SwRewriter aRewriter = pUndo->GetRewriter(); m_rDoc.GetIDocumentUndoRedo().StartUndo( SwUndoId::DELETE, &aRewriter ); + for (auto& it : MarkUndos) + { + m_rDoc.GetIDocumentUndoRedo().AppendUndo(it.release()); + } m_rDoc.GetIDocumentUndoRedo().AppendUndo( pUndo ); } -- cgit