summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/test/xmltesttools.hxx4
-rw-r--r--sw/qa/extras/ooxmlexport/data/tdf152200-field+textbox.docxbin0 -> 15009 bytes
-rw-r--r--sw/qa/extras/ooxmlexport/ooxmlexport18.cxx25
-rw-r--r--sw/source/filter/ww8/wrtw8nds.cxx8
-rw-r--r--test/source/xmltesttools.cxx12
5 files changed, 46 insertions, 3 deletions
diff --git a/include/test/xmltesttools.hxx b/include/test/xmltesttools.hxx
index f408273b802e..a9f30f7d227d 100644
--- a/include/test/xmltesttools.hxx
+++ b/include/test/xmltesttools.hxx
@@ -62,6 +62,10 @@ protected:
*/
int getXPathPosition(const xmlDocUniquePtr& pXmlDoc, const OString& rXPath, std::string_view rChildName);
/**
+ * Get the number of the nodes returned by the rXPath.
+ */
+ int countXPathNodes(const xmlDocUniquePtr& pXmlDoc, const OString& rXPath);
+ /**
* Assert that rXPath exists, and returns exactly one node.
*/
void assertXPath(const xmlDocUniquePtr& pXmlDoc, const OString& rXPath);
diff --git a/sw/qa/extras/ooxmlexport/data/tdf152200-field+textbox.docx b/sw/qa/extras/ooxmlexport/data/tdf152200-field+textbox.docx
new file mode 100644
index 000000000000..606d1346a27a
--- /dev/null
+++ b/sw/qa/extras/ooxmlexport/data/tdf152200-field+textbox.docx
Binary files differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport18.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport18.cxx
index 04c775fa8fcb..8e2732faead8 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport18.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport18.cxx
@@ -187,6 +187,31 @@ CPPUNIT_TEST_FIXTURE(Test, testImageCropping)
CPPUNIT_ASSERT_EQUAL(sal_Int32(0), aGraphicCropStruct.Bottom);
}
+CPPUNIT_TEST_FIXTURE(Test, testTdf152200)
+{
+ // Given a document with a fly anchored after a FORMTEXT in the end of the paragraph:
+ createSwDoc("tdf152200-field+textbox.docx");
+
+ // When exporting that back to DOCX:
+ save("Office Open XML Text");
+
+ // Then make sure that fldChar with type 'end' goes prior to the at-char anchored fly.
+ xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
+ const int nRunsBeforeFldCharEnd = countXPathNodes(pXmlDoc, "//w:fldChar[@w:fldCharType='end']/preceding::w:r");
+ CPPUNIT_ASSERT(nRunsBeforeFldCharEnd);
+ const int nRunsBeforeAlternateContent = countXPathNodes(pXmlDoc, "//mc:AlternateContent/preceding::w:r");
+ CPPUNIT_ASSERT(nRunsBeforeAlternateContent);
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected greater than: 6
+ // - Actual : 5
+ CPPUNIT_ASSERT_GREATER(nRunsBeforeFldCharEnd, nRunsBeforeAlternateContent);
+ // Make sure we only have one paragraph in body, and only three field characters overal,
+ // located directly in runs of this paragraph
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p");
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:r/w:fldChar", 3);
+ assertXPath(pXmlDoc, "//w:fldChar", 3); // no field characters elsewhere
+}
+
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/filter/ww8/wrtw8nds.cxx b/sw/source/filter/ww8/wrtw8nds.cxx
index a173a2014c4b..115a009bde79 100644
--- a/sw/source/filter/ww8/wrtw8nds.cxx
+++ b/sw/source/filter/ww8/wrtw8nds.cxx
@@ -2640,6 +2640,14 @@ void MSWordExportBase::OutputTextNode( SwTextNode& rNode )
bPostponeWritingText = false ;
AttrOutput().RunText( aSnippet, eChrSet );
}
+
+ if (ofs == 1 && nNextAttr == nEnd)
+ {
+ // tdf#152200: There could be flys anchored after the last position; make sure
+ // to provide a separate run after field character to write them
+ AttrOutput().EndRun(&rNode, nCurrentPos, -1, nNextAttr == nEnd);
+ AttrOutput().StartRun(pRedlineData, nCurrentPos, bSingleEmptyRun);
+ }
}
if ( aAttrIter.IsDropCap( nNextAttr ) )
diff --git a/test/source/xmltesttools.cxx b/test/source/xmltesttools.cxx
index a79b039332dd..26973b440c61 100644
--- a/test/source/xmltesttools.cxx
+++ b/test/source/xmltesttools.cxx
@@ -183,13 +183,19 @@ void XmlTestTools::assertXPathAttrs(const xmlDocUniquePtr& pXmlDoc, const OStrin
}
}
-void XmlTestTools::assertXPath(const xmlDocUniquePtr& pXmlDoc, const OString& rXPath, int nNumberOfNodes)
+int XmlTestTools::countXPathNodes(const xmlDocUniquePtr& pXmlDoc, const OString& rXPath)
{
xmlXPathObjectPtr pXmlObj = getXPathNode(pXmlDoc, rXPath);
xmlNodeSetPtr pXmlNodes = pXmlObj->nodesetval;
- CPPUNIT_ASSERT_EQUAL_MESSAGE(OString(OString::Concat("In <") + pXmlDoc->name + ">, XPath '" + rXPath + "' number of nodes is incorrect").getStr(),
- nNumberOfNodes, xmlXPathNodeSetGetLength(pXmlNodes));
+ const int n = xmlXPathNodeSetGetLength(pXmlNodes);
xmlXPathFreeObject(pXmlObj);
+ return n;
+}
+
+void XmlTestTools::assertXPath(const xmlDocUniquePtr& pXmlDoc, const OString& rXPath, int nNumberOfNodes)
+{
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(OString(OString::Concat("In <") + pXmlDoc->name + ">, XPath '" + rXPath + "' number of nodes is incorrect").getStr(),
+ nNumberOfNodes, countXPathNodes(pXmlDoc, rXPath));
}
void XmlTestTools::assertXPathContent(const xmlDocUniquePtr& pXmlDoc, const OString& rXPath, const OUString& rContent)