sw/inc/IDocumentState.hxx | 2 +- sw/source/core/doc/DocumentStateManager.cxx | 20 ++++++++++++++------ sw/source/core/inc/DocumentStateManager.hxx | 2 +- sw/source/uibase/docvw/PostItMgr.cxx | 4 ++-- sw/source/uibase/fldui/fldmgr.cxx | 2 +- 5 files changed, 19 insertions(+), 11 deletions(-)
New commits: commit 5f0f477f7aecb59d378497094a3535f1b7bd40bf Author: Michael Stahl <michael.st...@allotropia.de> AuthorDate: Fri May 16 15:52:35 2025 +0200 Commit: Michael Stahl <michael.st...@allotropia.de> CommitDate: Fri May 16 20:34:34 2025 +0200 LOCRDT sw: fix crash on deleting comment in hidden text CppunitTest_sw_mailmerge CPPUNIT_TEST_NAME="testMissingDefaultLineColor" calls RemoveInvisibleContent() which deletes a comment and there are 2 problems: 1) the comment doesn't have an SwAnnotationWin because it's in hidden text - so YrsRemoveComment needs to be able to find it with only the anchor position, as the comment id is only available from EE 2) the comment wasn't even inserted via YrsAddComment; not sure why, presumably because it was inserted via insert file? Ignore this for now, just avoid crashing... Change-Id: Id1e925911ef35d230ad5e35df3ebfdcfbb734558 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/185421 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.st...@allotropia.de> diff --git a/sw/inc/IDocumentState.hxx b/sw/inc/IDocumentState.hxx index 8684b16d28aa..c05d895f11b1 100644 --- a/sw/inc/IDocumentState.hxx +++ b/sw/inc/IDocumentState.hxx @@ -69,7 +69,7 @@ public: SwPostItField const& rField, bool isInsert) = 0; virtual void YrsRemoveCommentImpl(rtl::OString const& rCommentId) = 0; - virtual void YrsRemoveComment(SwPosition const& rPos, rtl::OString const& rCommentId) = 0; + virtual void YrsRemoveComment(SwPosition const& rPos) = 0; virtual void YrsNotifyCursorUpdate() = 0; #endif diff --git a/sw/source/core/doc/DocumentStateManager.cxx b/sw/source/core/doc/DocumentStateManager.cxx index 91ca61bb3991..4d40d0eacf24 100644 --- a/sw/source/core/doc/DocumentStateManager.cxx +++ b/sw/source/core/doc/DocumentStateManager.cxx @@ -1197,17 +1197,25 @@ void DocumentStateManager::YrsRemoveCommentImpl(OString const& rCommentId) m_pYrsSupplier->m_Comments.erase(rCommentId); } -void DocumentStateManager::YrsRemoveComment(SwPosition const& rPos, OString const& rCommentId) +void DocumentStateManager::YrsRemoveComment(SwPosition const& rPos) { SAL_INFO("sw.yrs", "YRS RemoveComment"); - YrsRemoveCommentImpl(rCommentId); + auto const it2{::std::find_if(m_pYrsSupplier->m_Comments.begin(), m_pYrsSupplier->m_Comments.end(), + [&rPos](auto const& it){ return it.second.front()->GetAnchorPosition() == rPos; })}; + if (it2 == m_pYrsSupplier->m_Comments.end()) + { + SAL_INFO("sw.yrs", "YRS RemoveComment anchor does not exist"); + return; // TODO this may happen on mail merge or presumably insert file + } + OString const commentId{it2->first}; + YrsRemoveCommentImpl(commentId); YTransaction *const pTxn{m_pYrsSupplier->GetWriteTransaction()}; if (!pTxn) { return; } - ymap_remove(m_pYrsSupplier->m_pComments, pTxn, rCommentId.getStr()); + ymap_remove(m_pYrsSupplier->m_pComments, pTxn, commentId.getStr()); // first, adjust position of all other comments in the paragraph for (auto const& it : m_pYrsSupplier->m_Comments) @@ -1237,7 +1245,7 @@ void DocumentStateManager::YrsRemoveComment(SwPosition const& rPos, OString cons pItem->GetFormatField().GetTextField())}; ::sw::mark::AnnotationMark const*const pMark{rHint.GetAnnotationMark()}; if (pMark != nullptr - && it.first != rCommentId + && it.first != commentId && rPos.nNode == pMark->GetMarkStart().nNode && rPos.nContent <= pMark->GetMarkStart().nContent) { diff --git a/sw/source/core/inc/DocumentStateManager.hxx b/sw/source/core/inc/DocumentStateManager.hxx index 8c4a0ce9e041..8245796bac95 100644 --- a/sw/source/core/inc/DocumentStateManager.hxx +++ b/sw/source/core/inc/DocumentStateManager.hxx @@ -86,7 +86,7 @@ public: void YrsAddComment(SwPosition const& rPos, ::std::optional<SwPosition> oAnchorStart, SwPostItField const& rField, bool isInsert) override; void YrsRemoveCommentImpl(OString const& rCommentId) override; - void YrsRemoveComment(SwPosition const& rPos, OString const& rCommentId) override; + void YrsRemoveComment(SwPosition const& rPos) override; void YrsNotifyCursorUpdate() override; #endif }; diff --git a/sw/source/uibase/docvw/PostItMgr.cxx b/sw/source/uibase/docvw/PostItMgr.cxx index 7a3f1edde247..41cdeb207a85 100644 --- a/sw/source/uibase/docvw/PostItMgr.cxx +++ b/sw/source/uibase/docvw/PostItMgr.cxx @@ -521,9 +521,9 @@ void SwPostItMgr::RemoveItem( SfxBroadcaster* pBroadcast ) if (i != mvPostItFields.end()) { #if ENABLE_YRS + // note: (*i)->mpPostIt may be null here, if it's in hidden text - see testMissingDefaultLineColor mpView->GetDocShell()->GetDoc()->getIDocumentState().YrsRemoveComment( - (*i)->GetAnchorPosition(), - (*i)->mpPostIt->GetOutlinerView()->GetEditView().GetYrsCommentId()); + (*i)->GetAnchorPosition()); #endif std::unique_ptr<SwAnnotationItem> p = std::move(*i); // tdf#120487 remove from list before dispose, so comment window commit 4ec57814fae16d16f9c87178402d52ba3a3c8eb1 Author: Michael Stahl <michael.st...@allotropia.de> AuthorDate: Fri May 16 12:31:40 2025 +0200 Commit: Michael Stahl <michael.st...@allotropia.de> CommitDate: Fri May 16 20:34:23 2025 +0200 LOCRDT sw: more test failures * CppunitTest_sw_a11y CPPUNIT_TEST_NAME="TestMenuInsertPageBreak" missing type check in SwFieldMgr::InsertField() * CppunitTest_sw_odfexport4 CPPUNIT_TEST_NAME="testTdf160877" inserts stuff from SwEditShell ctor so there's a shell calling YrsNotifyCursorUpdate() which isn't a SwWrtShell yet... * CppunitTest_sw_uiwriter5 CPPUNIT_TEST_NAME="testImageCommentAtChar" triggers assert in YrsAddComment() by intentionally adding annotation mark with start == end Change-Id: Ic619b7188c63d30b63916976870c74da10e8c4cd Reviewed-on: https://gerrit.libreoffice.org/c/core/+/185418 Reviewed-by: Michael Stahl <michael.st...@allotropia.de> Tested-by: Jenkins diff --git a/sw/source/core/doc/DocumentStateManager.cxx b/sw/source/core/doc/DocumentStateManager.cxx index dbee6e5f0f30..91ca61bb3991 100644 --- a/sw/source/core/doc/DocumentStateManager.cxx +++ b/sw/source/core/doc/DocumentStateManager.cxx @@ -1129,10 +1129,10 @@ void DocumentStateManager::YrsAddComment(SwPosition const& rPos, pItem->GetFormatField().GetTextField())}; ::sw::mark::AnnotationMark const*const pMark{rHint.GetAnnotationMark()}; if (pMark != nullptr + && it.first != commentId // see testImageCommentAtChar with start == field pos && rPos.nNode == pMark->GetMarkStart().nNode && rPos.nContent <= pMark->GetMarkStart().nContent) { - assert(it.first != commentId); // start always before inserted char ::std::unique_ptr<YOutput, YOutputDeleter> const pComment{ ymap_get(m_pYrsSupplier->m_pComments, pTxn, it.first.getStr())}; assert(pComment); @@ -1237,10 +1237,10 @@ void DocumentStateManager::YrsRemoveComment(SwPosition const& rPos, OString cons pItem->GetFormatField().GetTextField())}; ::sw::mark::AnnotationMark const*const pMark{rHint.GetAnnotationMark()}; if (pMark != nullptr + && it.first != rCommentId && rPos.nNode == pMark->GetMarkStart().nNode && rPos.nContent <= pMark->GetMarkStart().nContent) { - assert(it.first != rCommentId); // start always before inserted char ::std::unique_ptr<YOutput, YOutputDeleter> const pComment{ ymap_get(m_pYrsSupplier->m_pComments, pTxn, it.first.getStr())}; assert(pComment); @@ -1266,7 +1266,7 @@ void DocumentStateManager::YrsNotifyCursorUpdate() { SwWrtShell *const pShell{dynamic_cast<SwWrtShell*>(m_rDoc.getIDocumentLayoutAccess().GetCurrentViewShell())}; YTransaction *const pTxn{m_pYrsSupplier ? m_pYrsSupplier->GetWriteTransaction() : nullptr}; - if (!pTxn || !pShell->GetView().GetPostItMgr()) + if (!pTxn || !pShell || !pShell->GetView().GetPostItMgr()) { return; } diff --git a/sw/source/uibase/fldui/fldmgr.cxx b/sw/source/uibase/fldui/fldmgr.cxx index 385c950171bc..beb8cf522854 100644 --- a/sw/source/uibase/fldui/fldmgr.cxx +++ b/sw/source/uibase/fldui/fldmgr.cxx @@ -1573,7 +1573,7 @@ bool SwFieldMgr::InsertField( pCurShell->EndAllAction(); #if ENABLE_YRS - if (isSuccess) + if (isSuccess && rData.m_nTypeId == SwFieldTypesEnum::Postit) { // now the SwAnnotationWin are created // shell cursor is behind field