sw/qa/extras/ooxmlexport/data/comment_with_children.odt |binary
 sw/qa/extras/ooxmlexport/ooxmlexport21.cxx              |   29 ++++++++++++++++
 sw/source/filter/ww8/docxattributeoutput.cxx            |   11 +++---
 3 files changed, 36 insertions(+), 4 deletions(-)

New commits:
commit 34d242f5099fdb9234ac047e5712aea6df113e4c
Author:     Jaume Pujantell <jaume.pujant...@collabora.com>
AuthorDate: Thu Sep 19 19:22:21 2024 +0200
Commit:     Jaume Pujantell <jaume.pujant...@collabora.com>
CommitDate: Wed Sep 25 15:44:06 2024 +0200

    tdf#163092 sw: fix broken anotations on save to docx
    
    Opening an odt file and saving it as docx would break the comment
    threads into unconnected comments.
    
    This also fixes a regression from commit
    3bb2668f5e753e9fa6aa7eea74454bf11cdfc853 where creating a commet
    thread with multiple children and saving to docx would break it
    into separate threads.
    
    Change-Id: I76a0ec49bd69b953d816b3b5d3cc6d14065d5846
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/173681
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/173872
    Tested-by: Jenkins
    Reviewed-by: Jaume Pujantell <jaume.pujant...@collabora.com>

diff --git a/sw/qa/extras/ooxmlexport/data/comment_with_children.odt 
b/sw/qa/extras/ooxmlexport/data/comment_with_children.odt
new file mode 100644
index 000000000000..83ff88c69595
Binary files /dev/null and 
b/sw/qa/extras/ooxmlexport/data/comment_with_children.odt differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx
index deea3789c446..924f8b970856 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport21.cxx
@@ -1187,6 +1187,35 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf61000)
         "pos"_ostr, u"0"_ustr);
 }
 
+CPPUNIT_TEST_FIXTURE(Test, testCommentWithChildrenTdf163092)
+{
+    loadAndSave("comment_with_children.odt");
+    // commentsExtended should exist
+    xmlDocUniquePtr pXmlCommExt = parseExport("word/commentsExtended.xml");
+    CPPUNIT_ASSERT(pXmlCommExt);
+    // And it should contain the same parent-child relations
+    OUString sExChild1
+        = getXPath(pXmlCommExt, "/w15:commentsEx/w15:commentEx[1]"_ostr, 
"paraId"_ostr);
+    OUString sExParent1
+        = getXPath(pXmlCommExt, "/w15:commentsEx/w15:commentEx[1]"_ostr, 
"paraIdParent"_ostr);
+    OUString sExChild2
+        = getXPath(pXmlCommExt, "/w15:commentsEx/w15:commentEx[2]"_ostr, 
"paraId"_ostr);
+    OUString sExParent2
+        = getXPath(pXmlCommExt, "/w15:commentsEx/w15:commentEx[2]"_ostr, 
"paraIdParent"_ostr);
+    std::map<OUString, OUString> parents;
+    parents[sExChild1] = sExParent1;
+    parents[sExChild2] = sExParent2;
+    xmlDocUniquePtr pXmlComments = parseExport("word/comments.xml");
+    OUString sComment1Id
+        = getXPath(pXmlComments, "/w:comments/w:comment[1]/w:p[1]"_ostr, 
"paraId"_ostr);
+    OUString sComment2Id
+        = getXPath(pXmlComments, "/w:comments/w:comment[2]/w:p[1]"_ostr, 
"paraId"_ostr);
+    OUString sComment3Id
+        = getXPath(pXmlComments, "/w:comments/w:comment[3]/w:p[1]"_ostr, 
"paraId"_ostr);
+    CPPUNIT_ASSERT_EQUAL(parents[sComment2Id], sComment1Id);
+    CPPUNIT_ASSERT_EQUAL(parents[sComment3Id], sComment2Id);
+}
+
 } // end of anonymous namespace
 CPPUNIT_PLUGIN_IMPLEMENT();
 
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx 
b/sw/source/filter/ww8/docxattributeoutput.cxx
index 6b38d40f1ad5..295c043e3cb9 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -8355,14 +8355,17 @@ DocxAttributeOutput::hasProperties 
DocxAttributeOutput::WritePostitFields()
     hasProperties eResult = hasProperties::no;
     for (auto& [f1, data1] : m_postitFields)
     {
-        if (f1->GetParentId() != 0)
+        if (f1->GetParentId() != 0 || f1->GetParentPostItId() != 0)
         {
             for (size_t i = 0; i < m_postitFields.size(); i++)
             {
                 auto& [f2, data2] = m_postitFields[i];
-                if (f2->GetParaId() == f1->GetParentId())
+                if ((f1->GetParentId() != 0 && f2->GetParaId() == 
f1->GetParentId())
+                    || (f1->GetParentPostItId() != 0
+                        && f2->GetPostItId() == f1->GetParentPostItId()))
                 {
-                    data2.parentStatus = ParentStatus::IsParent;
+                    if (data2.parentStatus == ParentStatus::None)
+                        data2.parentStatus = ParentStatus::IsParent;
                     data1.parentStatus = ParentStatus::HasParent;
                     data1.parentIndex = i;
                     break;
@@ -8431,7 +8434,7 @@ void DocxAttributeOutput::WritePostItFieldsResolved()
             continue;
         OUString idstr = NumberToHexBinary(data.lastParaId);
         std::optional<OUString> sDone, sParentId;
-        if (f->GetParentId() != 0)
+        if (f->GetParentId() != 0 || f->GetParentPostItId() != 0)
         {
             if (data.parentStatus == ParentStatus::HasParent)
             {

Reply via email to