Kaydet (Commit) 484fb551 authored tarafından Michael Stahl's avatar Michael Stahl

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 9b67b6a6)

Change-Id: Ie1d5676d1d79a51e2e4a01a3e282f8739ff08899
Reviewed-on: https://gerrit.libreoffice.org/66178
Tested-by: Jenkins
Reviewed-by: 's avatarMichael Stahl <Michael.Stahl@cib.de>
üst a47b8f22
......@@ -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))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment