diff options
author | Michael Stahl <Michael.Stahl@cib.de> | 2019-01-11 15:22:59 +0100 |
---|---|---|
committer | Michael Stahl <Michael.Stahl@cib.de> | 2019-01-11 18:56:05 +0100 |
commit | 484fb55168b18bbd8c6160e5a3958a5188987ab5 (patch) | |
tree | dee93b66cbb968b6d4f7124ff388c5ff6e8d62b4 /sw | |
parent | a47b8f223847ce28330244bc0eef2e6b72f7f989 (diff) |
sw_redlinehide: fix infinite loop when deleting comments
The problem is that sw::UpdateFramesForAddDeleteRedline() sends a
SwFormatFieldHintWhich::REMOVED event in order to remove any comments
that may have been deleted from the document view.
Unfortunately there's another listener in class FieldDocWatchingStack
that is used during various SwPostItMgr::Delete* functions, which will
effectively start over from scratch if it receives this event, so it
is an infinite loop.
Avoid this by simply ignoring any redline-deleted fields; deleting them
again won't provide any benefit anyway.
This can be seen with UITest
deleteAllComments.DeleteAllComments.test_comment_trackchanges.
(regression from 9b67b6a6d4b912f1e515d3884fa02c1be8aa6921)
Change-Id: Ie1d5676d1d79a51e2e4a01a3e282f8739ff08899
Reviewed-on: https://gerrit.libreoffice.org/66178
Tested-by: Jenkins
Reviewed-by: Michael Stahl <Michael.Stahl@cib.de>
Diffstat (limited to 'sw')
-rw-r--r-- | sw/source/uibase/docvw/PostItMgr.cxx | 34 |
1 files changed, 31 insertions, 3 deletions
diff --git a/sw/source/uibase/docvw/PostItMgr.cxx b/sw/source/uibase/docvw/PostItMgr.cxx index 1c6d410aac74..657d2d3b7c1d 100644 --- a/sw/source/uibase/docvw/PostItMgr.cxx +++ b/sw/source/uibase/docvw/PostItMgr.cxx @@ -1381,6 +1381,28 @@ public: } }; +class IsFieldNotDeleted : public FilterFunctor +{ +private: + IDocumentRedlineAccess const& m_rIDRA; + FilterFunctor const& m_rNext; + +public: + IsFieldNotDeleted(IDocumentRedlineAccess const& rIDRA, + FilterFunctor & rNext) + : m_rIDRA(rIDRA) + , m_rNext(rNext) + { + } + bool operator()(const SwFormatField* pField) const override + { + if (!m_rNext(pField)) + return false; + if (!pField->GetTextField()) + return false; + return !sw::IsFieldDeletedInModel(m_rIDRA, *pField->GetTextField()); + } +}; //Manages the passed in vector by automatically removing entries if they are deleted //and automatically adding entries if they appear in the document and match the @@ -1491,7 +1513,9 @@ void SwPostItMgr::Delete(const OUString& rAuthor) mpWrtShell->StartUndo( SwUndoId::DELETE, &aRewriter ); IsPostitFieldWithAuthorOf aFilter(rAuthor); - FieldDocWatchingStack aStack(mvPostItFields, *mpView->GetDocShell(), aFilter); + IDocumentRedlineAccess const& rIDRA(mpWrtShell->getIDocumentRedlineAccess()); + IsFieldNotDeleted aFilter2(rIDRA, aFilter); + FieldDocWatchingStack aStack(mvPostItFields, *mpView->GetDocShell(), aFilter2); while (const SwFormatField* pField = aStack.pop()) { if (mpWrtShell->GotoField(*pField)) @@ -1518,7 +1542,9 @@ void SwPostItMgr::Delete(sal_uInt32 nPostItId) mpWrtShell->StartUndo( SwUndoId::DELETE, &aRewriter ); IsPostitFieldWithPostitId aFilter(nPostItId); - FieldDocWatchingStack aStack(mvPostItFields, *mpView->GetDocShell(), aFilter); + IDocumentRedlineAccess const& rIDRA(mpWrtShell->getIDocumentRedlineAccess()); + IsFieldNotDeleted aFilter2(rIDRA, aFilter); + FieldDocWatchingStack aStack(mvPostItFields, *mpView->GetDocShell(), aFilter2); const SwFormatField* pField = aStack.pop(); if (pField && mpWrtShell->GotoField(*pField)) mpWrtShell->DelRight(); @@ -1539,8 +1565,10 @@ void SwPostItMgr::Delete() mpWrtShell->StartUndo( SwUndoId::DELETE, &aRewriter ); IsPostitField aFilter; + IDocumentRedlineAccess const& rIDRA(mpWrtShell->getIDocumentRedlineAccess()); + IsFieldNotDeleted aFilter2(rIDRA, aFilter); FieldDocWatchingStack aStack(mvPostItFields, *mpView->GetDocShell(), - aFilter); + aFilter2); while (const SwFormatField* pField = aStack.pop()) { if (mpWrtShell->GotoField(*pField)) |