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

Reply via email to