summaryrefslogtreecommitdiffstats
path: root/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--sw/qa/extras/ooxmlexport/ooxmlexport14.cxx1591
1 files changed, 1591 insertions, 0 deletions
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
new file mode 100644
index 000000000..d96bd7087
--- /dev/null
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
@@ -0,0 +1,1591 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <swmodeltestbase.hxx>
+
+#include <com/sun/star/awt/FontUnderline.hpp>
+#include <com/sun/star/awt/FontWeight.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/style/LineSpacing.hpp>
+#include <com/sun/star/style/LineSpacingMode.hpp>
+#include <com/sun/star/table/ShadowFormat.hpp>
+#include <com/sun/star/text/RelOrientation.hpp>
+#include <com/sun/star/text/TableColumnSeparator.hpp>
+#include <com/sun/star/text/XDependentTextField.hpp>
+#include <com/sun/star/text/XDocumentIndex.hpp>
+#include <com/sun/star/text/XDocumentIndexesSupplier.hpp>
+#include <com/sun/star/text/XFootnotesSupplier.hpp>
+#include <com/sun/star/text/XFootnote.hpp>
+#include <com/sun/star/text/XTextContentAppend.hpp>
+#include <com/sun/star/text/XTextDocument.hpp>
+#include <com/sun/star/text/XTextFieldsSupplier.hpp>
+#include <com/sun/star/text/XTextGraphicObjectsSupplier.hpp>
+#include <com/sun/star/text/XTextTable.hpp>
+#include <com/sun/star/text/XTextTablesSupplier.hpp>
+
+#include <comphelper/sequenceashashmap.hxx>
+#include <oox/drawingml/drawingmltypes.hxx>
+#include <unotools/fltrcfg.hxx>
+#include <o3tl/string_view.hxx>
+
+using namespace com::sun::star;
+
+constexpr OUStringLiteral DATA_DIRECTORY = u"/sw/qa/extras/ooxmlexport/data/";
+
+class Test : public SwModelTestBase
+{
+public:
+ Test() : SwModelTestBase(DATA_DIRECTORY, "Office Open XML Text") {}
+};
+
+DECLARE_OOXMLEXPORT_TEST(Tdf130907, "tdf130907.docx")
+{
+ uno::Reference<text::XTextRange> xPara1 = getParagraph(2);
+ CPPUNIT_ASSERT(xPara1.is());
+ uno::Reference<beans::XPropertySet> xFormula1Props(xPara1, uno::UNO_QUERY);
+ CPPUNIT_ASSERT(xFormula1Props.is());
+ sal_Int16 nHOri1;
+ xFormula1Props->getPropertyValue("ParaAdjust") >>= nHOri1;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("The alignment of the equation is not left!",
+ sal_Int16(style::ParagraphAdjust::ParagraphAdjust_LEFT), nHOri1);
+
+ uno::Reference<text::XTextRange> xPara2 = getParagraph(3);
+ CPPUNIT_ASSERT(xPara2.is());
+ uno::Reference<beans::XPropertySet> xFormula2Props(xPara2, uno::UNO_QUERY);
+ CPPUNIT_ASSERT(xFormula2Props.is());
+ sal_Int16 nHOri2;
+ xFormula2Props->getPropertyValue("ParaAdjust") >>= nHOri2;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("The alignment of the equation is not center!",
+ sal_Int16(style::ParagraphAdjust::ParagraphAdjust_CENTER), nHOri2);
+
+ uno::Reference<text::XTextRange> xPara3 = getParagraph(5);
+ CPPUNIT_ASSERT(xPara3.is());
+ uno::Reference<beans::XPropertySet> xFormula3Props(xPara3, uno::UNO_QUERY);
+ CPPUNIT_ASSERT(xFormula3Props.is());
+ sal_Int16 nHOri3;
+ xFormula3Props->getPropertyValue("ParaAdjust") >>= nHOri3;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("The alignment of the equation is not right!",
+ sal_Int16(style::ParagraphAdjust::ParagraphAdjust_RIGHT), nHOri3);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf128197)
+{
+ load(mpTestDocumentPath, "128197_compat14.docx");
+ xmlDocUniquePtr pLayout14 = parseLayoutDump();
+ sal_Int32 nHeight14 = getXPath(pLayout14, "//page[1]/body/txt[1]/infos/bounds", "height").toInt32();
+
+ load(mpTestDocumentPath, "128197_compat15.docx");
+ xmlDocUniquePtr pLayout15 = parseLayoutDump();
+ sal_Int32 nHeight15 = getXPath(pLayout15, "//page[1]/body/txt[1]/infos/bounds", "height").toInt32();
+
+ // In compat mode=14 second line has size of the shape thus entire paragraph height is smaller
+ // So nHeight14 < nHeight15
+ CPPUNIT_ASSERT_LESS(nHeight15, nHeight14);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf135595_HFtableWrap)
+{
+ loadAndReload("tdf135595_HFtableWrap.odt");
+ xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+ sal_Int32 nRowHeight = getXPath(pXmlDoc, "//page[1]/header/tab/row/infos/bounds", "height").toInt32();
+ // tdf#77794: always force bLayoutInCell from false to true for MSO2013+
+ // The fly is supposed to be inside the cell. Before, height was 998. Now it is 2839.
+ CPPUNIT_ASSERT_MESSAGE("Image must be contained inside the table cell", nRowHeight > 2000);
+}
+
+DECLARE_OOXMLEXPORT_TEST(testTdf135943_shapeWithText_L0c15,
+ "tdf135943_shapeWithText_LayoutInCell0_compat15.docx")
+{
+ // With compat15, layoutinCell ought to be ignored/forced to true.
+ // HOWEVER, currently only the shape is correctly placed, while its text is un-synced separately.
+ // So to prevent this ugly mess, just leave everything together in the historical (wrong) spot.
+ xmlDocUniquePtr pDump = parseLayoutDump();
+ sal_Int32 nFrameLeft = getXPath(pDump, "//anchored/SwAnchoredDrawObject/bounds", "left").toInt32();
+ sal_Int32 nFrameRight = getXPath(pDump, "//anchored/SwAnchoredDrawObject/bounds", "right").toInt32();
+ sal_Int32 nTextLeft = getXPath(pDump, "//anchored/fly/infos/bounds", "left").toInt32();
+ sal_Int32 nTextRight = getXPath(pDump, "//anchored/fly/infos/bounds", "right").toInt32();
+ // The text must be inside of its frame boundaries
+ CPPUNIT_ASSERT(nFrameRight >= nTextRight);
+ CPPUNIT_ASSERT(nFrameLeft <= nTextLeft);
+ // LayoutInCell: The text must fit inside cell A1 //cell[1]/info/bounds/right = 4703
+ //CPPUNIT_ASSERT(nTextRight < 4704);
+
+ uno::Reference<beans::XPropertySet> xShapeProperties(getShape(1), uno::UNO_QUERY);
+ bool bValue;
+ xShapeProperties->getPropertyValue("IsFollowingTextFlow") >>= bValue;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("YOU FIXED ME? LayoutInCell ought to be true", false, bValue);
+}
+
+DECLARE_OOXMLEXPORT_TEST(testTdf135595_HFtableWrap_c12, "tdf135595_HFtableWrap_c12.docx")
+{
+ xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+ // tdf#104596: ignore wrap exception apparently does not apply if it is not "layout in table cell".
+ // Should be only one page. Row height should be two lines at 722, not wrapped to three lines at 998.
+ sal_Int32 nRowHeight = getXPath(pXmlDoc, "//header/tab/row/infos/bounds", "height").toInt32();
+ CPPUNIT_ASSERT_MESSAGE("Text must not wrap around header image", nRowHeight < 800);
+}
+
+DECLARE_OOXMLEXPORT_TEST(testTdf123622, "tdf123622.docx")
+{
+ uno::Reference<beans::XPropertySet> XPropsRight(getShape(1),uno::UNO_QUERY);
+ sal_Int16 nRelativePosR = 0;
+ XPropsRight->getPropertyValue("HoriOrientRelation")>>=nRelativePosR;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Shape inside the margin", sal_Int16(4), nRelativePosR);
+
+ uno::Reference<beans::XPropertySet> XPropsLeft(getShape(2), uno::UNO_QUERY);
+ sal_Int16 nRelativePosL = 0;
+ XPropsLeft->getPropertyValue("HoriOrientRelation") >>= nRelativePosL;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Shape inside the margin", sal_Int16(3), nRelativePosL);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf78749)
+{
+ loadAndReload("tdf78749.docx");
+ //Shape lost the background image before, now check if it still has...
+ auto xShape = getShape(1);
+ uno::Reference<beans::XPropertySet> xShpProps(xShape, uno::UNO_QUERY);
+ OUString aPropertyVal;
+ xShpProps->getPropertyValue("FillBitmapName") >>= aPropertyVal;
+ CPPUNIT_ASSERT(!aPropertyVal.isEmpty());
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf128207)
+{
+ loadAndSave("tdf128207.docx");
+ //There was the charts on each other, because their horizontal and vertical position was 0!
+ xmlDocUniquePtr p_XmlDoc = parseExport("word/document.xml");
+ CPPUNIT_ASSERT(p_XmlDoc);
+ assertXPathContent(p_XmlDoc, "/w:document/w:body/w:p[1]/w:r[1]/w:drawing/wp:anchor/wp:positionH/wp:posOffset", "4445");
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf123873)
+{
+ loadAndSave("tdf123873.docx");
+ //OLE Object were overlapped due to missing wrap import
+ xmlDocUniquePtr p_XmlDoc = parseExport("word/document.xml");
+ CPPUNIT_ASSERT(p_XmlDoc);
+ assertXPath(
+ p_XmlDoc, "/w:document/w:body/w:p[2]/w:r[2]/w:drawing/wp:anchor/wp:wrapTopAndBottom");
+}
+
+CPPUNIT_TEST_FIXTURE(Test, Tdf133065)
+{
+ loadAndSave("tdf133065.odt");
+ CPPUNIT_ASSERT_EQUAL(7, getShapes());
+ CPPUNIT_ASSERT_EQUAL(3, getPages());
+ auto pxmldoc = parseExport("word/document.xml");
+ CPPUNIT_ASSERT(pxmldoc);
+ OUString aVal;
+
+ aVal = getXPath(pxmldoc, "/w:document/w:body/w:p[3]/w:r[2]/w:object/v:shape/w10:wrap", "type");
+ CPPUNIT_ASSERT(aVal.indexOf("square") > -1);
+ aVal = getXPath(pxmldoc, "/w:document/w:body/w:p[3]/w:r[2]/w:object/v:shape/w10:wrap", "side");
+ CPPUNIT_ASSERT(aVal.indexOf("left") > -1);
+
+ aVal = getXPath(pxmldoc, "/w:document/w:body/w:p[8]/w:r[2]/w:object/v:shape/w10:wrap", "type");
+ CPPUNIT_ASSERT(aVal.indexOf("square") > -1);
+ aVal = getXPath(pxmldoc, "/w:document/w:body/w:p[8]/w:r[2]/w:object/v:shape/w10:wrap", "side");
+ CPPUNIT_ASSERT(aVal.indexOf("right") > -1);
+
+ aVal = getXPath(pxmldoc, "/w:document/w:body/w:p[12]/w:r[2]/w:object/v:shape/w10:wrap", "type");
+ CPPUNIT_ASSERT(aVal.indexOf("square") > -1);
+ aVal = getXPath(pxmldoc, "/w:document/w:body/w:p[12]/w:r[2]/w:object/v:shape/w10:wrap", "side");
+ CPPUNIT_ASSERT(aVal.indexOf("largest") > -1);
+
+ aVal = getXPath(pxmldoc, "/w:document/w:body/w:p[20]/w:r[2]/w:object/v:shape/w10:wrap", "type");
+ CPPUNIT_ASSERT(aVal.indexOf("topAndBottom") > -1);
+
+ aVal = getXPath(pxmldoc, "/w:document/w:body/w:p[24]/w:r[2]/w:object/v:shape/w10:wrap", "type");
+ CPPUNIT_ASSERT(aVal.indexOf("square") > -1);
+}
+
+DECLARE_OOXMLEXPORT_TEST(testTdf130814model, "tdf130814.docx")
+{
+ CPPUNIT_ASSERT_EQUAL(Color(0x1F497D), getProperty<Color>(getRun(getParagraph(2), 1), "CharColor"));
+ CPPUNIT_ASSERT_EQUAL(double(16), getProperty<double>(getRun(getParagraph(2), 1), "CharHeight"));
+ CPPUNIT_ASSERT_EQUAL(awt::FontUnderline::SINGLE, getProperty<sal_Int16>(getRun(getParagraph(2), 1), "CharUnderline"));
+ CPPUNIT_ASSERT_EQUAL(OUString("Candara"), getProperty<OUString>(getRun(getParagraph(2), 1), "CharFontName"));
+ CPPUNIT_ASSERT_EQUAL(OUString("Arial Unicode MS"), getProperty<OUString>(getRun(getParagraph(2), 1), "CharFontNameAsian"));
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf107020)
+{
+ loadAndSave("tdf107020.docx");
+ if (!IsDefaultDPI())
+ return;
+ xmlDocUniquePtr p_XmlDoc = parseExport("word/document.xml");
+ CPPUNIT_ASSERT(p_XmlDoc);
+ assertXPath(
+ p_XmlDoc, "/w:document/w:body/w:p/w:r/w:drawing/wp:inline/a:graphic/a:graphicData/pic:pic/pic:blipFill/a:srcRect", "l", "4910");
+ assertXPath(
+ p_XmlDoc, "/w:document/w:body/w:p/w:r/w:drawing/wp:inline/a:graphic/a:graphicData/pic:pic/pic:blipFill/a:srcRect", "t", "27183");
+ assertXPath(
+ p_XmlDoc, "/w:document/w:body/w:p/w:r/w:drawing/wp:inline/a:graphic/a:graphicData/pic:pic/pic:blipFill/a:srcRect", "r", "57638");
+ assertXPath(
+ p_XmlDoc, "/w:document/w:body/w:p/w:r/w:drawing/wp:inline/a:graphic/a:graphicData/pic:pic/pic:blipFill/a:srcRect", "b", "48360");
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf130814ooxml)
+{
+ loadAndSave("tdf130814.docx");
+ xmlDocUniquePtr p_XmlDoc = parseExport("word/document.xml");
+ CPPUNIT_ASSERT(p_XmlDoc);
+ assertXPath(
+ p_XmlDoc, "/w:document/w:body/w:p[2]/w:r[1]/w:rPr/w:rFonts", "eastAsia", "Arial Unicode MS");
+ assertXPath(
+ p_XmlDoc, "/w:document/w:body/w:p[2]/w:r[1]/w:rPr/w:rFonts", "ascii", "Candara");
+ assertXPath(
+ p_XmlDoc, "/w:document/w:body/w:p[2]/w:r[1]/w:rPr/w:rFonts", "hAnsi", "Candara");
+ assertXPath(
+ p_XmlDoc, "/w:document/w:body/w:p[2]/w:r[1]/w:rPr/w:color", "val", "1F497D");
+ assertXPath(
+ p_XmlDoc, "/w:document/w:body/w:p[2]/w:r[1]/w:rPr/w:sz", "val", "32");
+ assertXPath(
+ p_XmlDoc, "/w:document/w:body/w:p[2]/w:r[1]/w:rPr/w:szCs", "val", "32");
+ assertXPath(
+ p_XmlDoc, "/w:document/w:body/w:p[2]/w:r[1]/w:rPr/w:u", "val", "single");
+}
+
+DECLARE_OOXMLEXPORT_TEST(testTdf129888vml, "tdf129888vml.docx")
+{
+ //the line shape has anchor in the first cell however it has to
+ //be positioned to an another cell. To reach this we must handle
+ //the o:allowincell attribute of the shape, and its position has
+ //to be calculated from the page frame instead of the table:
+
+ uno::Reference<beans::XPropertySet> xShapeProperties(getShape(1), uno::UNO_QUERY);
+ bool bValue;
+ xShapeProperties->getPropertyValue("IsFollowingTextFlow") >>= bValue;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("tdf129888vml The line shape has bad place!",
+ false, bValue);
+}
+
+DECLARE_OOXMLEXPORT_TEST(testTdf129888dml, "tdf129888dml.docx")
+{
+ //the shape has anchor in the first cell however it has to
+ //be positioned to the right side of the page. To reach this we must handle
+ //the layoutInCell attribute of the shape, and its position has
+ //to be calculated from the page frame instead of the table:
+
+ uno::Reference<beans::XPropertySet> xShapeProperties(getShape(1), uno::UNO_QUERY);
+ bool bValue;
+ xShapeProperties->getPropertyValue("IsFollowingTextFlow") >>= bValue;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("tdf129888dml The shape has bad place!",
+ false, bValue);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf130120)
+{
+ loadAndSave("tdf130120.docx");
+ //Text for exporting the allowincell attribute:
+ xmlDocUniquePtr p_XmlDoc = parseExport("word/document.xml");
+ assertXPath(p_XmlDoc, "/w:document/w:body/w:tbl/w:tr/w:tc/w:p/w:r/mc:AlternateContent/"
+ "mc:Choice/w:drawing/wp:anchor", "layoutInCell", "0");
+}
+
+CPPUNIT_TEST_FIXTURE(Test, Tdf133030)
+{
+ loadAndSave("tdf133030.docx");
+ auto pExport = parseExport("word/document.xml");
+ CPPUNIT_ASSERT(pExport);
+
+ assertXPath(pExport, "/w:document/w:body/w:p[3]/m:oMathPara/m:oMathParaPr/m:jc", "val", "center");
+ assertXPath(pExport, "/w:document/w:body/w:p[5]/m:oMathPara/m:oMathParaPr/m:jc", "val", "left");
+ assertXPath(pExport, "/w:document/w:body/w:p[7]/m:oMathPara/m:oMathParaPr/m:jc", "val", "right");
+}
+
+DECLARE_OOXMLEXPORT_TEST(testTdf87569v, "tdf87569_vml.docx")
+{
+ //the original tdf87569 sample has vml shapes...
+ uno::Reference<beans::XPropertySet> xShapeProperties(getShape(1), uno::UNO_QUERY);
+ bool bValue;
+ xShapeProperties->getPropertyValue("IsFollowingTextFlow") >>= bValue;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("tdf87569_vml: The Shape is not in the table!",
+ true, bValue);
+}
+
+DECLARE_OOXMLEXPORT_TEST(testTdf133000_numStyleFormatting, "tdf133000_numStyleFormatting.docx")
+{
+ // Paragraph style's LeftMargin should not override numbering's Left Margin
+ xmlDocUniquePtr pDump = parseLayoutDump();
+ assertXPathContent(pDump, "/root/page[1]/body/txt[2]", "First line");
+ const sal_Int32 nLevel1Margin = getXPath(pDump, "//page[1]/body/txt[2]/infos/prtBounds", "left").toInt32();
+ assertXPathContent(pDump, "/root/page[1]/body/txt[4]", "One sublevel");
+ const sal_Int32 nLevel2Margin = getXPath(pDump, "//page[1]/body/txt[4]/infos/prtBounds", "left").toInt32();
+ CPPUNIT_ASSERT( nLevel1Margin < nLevel2Margin );
+}
+
+DECLARE_OOXMLEXPORT_TEST(testTdf134260, "tdf134260.docx")
+{
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 0
+ // - Actual : 1270
+
+ auto xNum1Levels
+ = getProperty<uno::Reference<container::XIndexAccess>>(getParagraph(1), "NumberingRules");
+
+ CPPUNIT_ASSERT_EQUAL(
+ sal_Int32(0),
+ comphelper::SequenceAsHashMap(xNum1Levels->getByIndex(0))["ListtabStopPosition"]
+ .get<sal_Int32>());
+
+ auto xNum2Levels
+ = getProperty<uno::Reference<container::XIndexAccess>>(getParagraph(2), "NumberingRules");
+
+ CPPUNIT_ASSERT_EQUAL(
+ sal_Int32(0),
+ comphelper::SequenceAsHashMap(xNum2Levels->getByIndex(0))["ListtabStopPosition"]
+ .get<sal_Int32>());
+
+ auto xNum3Levels
+ = getProperty<uno::Reference<container::XIndexAccess>>(getParagraph(3), "NumberingRules");
+
+ CPPUNIT_ASSERT_EQUAL(
+ sal_Int32(0),
+ comphelper::SequenceAsHashMap(xNum3Levels->getByIndex(0))["ListtabStopPosition"]
+ .get<sal_Int32>());
+}
+
+DECLARE_ODFEXPORT_TEST(testArabicZeroNumbering, "arabic-zero-numbering.docx")
+{
+ auto xNumberingRules
+ = getProperty<uno::Reference<container::XIndexAccess>>(getParagraph(1), "NumberingRules");
+ comphelper::SequenceAsHashMap aMap(xNumberingRules->getByIndex(0));
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 64
+ // - Actual : 4
+ // i.e. numbering type was ARABIC, not ARABIC_ZERO.
+ CPPUNIT_ASSERT_EQUAL(o3tl::narrowing<sal_uInt16>(style::NumberingType::ARABIC_ZERO),
+ aMap["NumberingType"].get<sal_uInt16>());
+}
+
+DECLARE_ODFEXPORT_TEST(testArabicZero3Numbering, "arabic-zero3-numbering.docx")
+{
+ auto xNumberingRules
+ = getProperty<uno::Reference<container::XIndexAccess>>(getParagraph(1), "NumberingRules");
+ comphelper::SequenceAsHashMap aMap(xNumberingRules->getByIndex(0));
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 65
+ // - Actual : 4
+ // i.e. numbering type was ARABIC, not ARABIC_ZERO3.
+ CPPUNIT_ASSERT_EQUAL(o3tl::narrowing<sal_uInt16>(style::NumberingType::ARABIC_ZERO3),
+ aMap["NumberingType"].get<sal_uInt16>());
+}
+
+DECLARE_ODFEXPORT_TEST(testArabicZero4Numbering, "arabic-zero4-numbering.docx")
+{
+ auto xNumberingRules
+ = getProperty<uno::Reference<container::XIndexAccess>>(getParagraph(1), "NumberingRules");
+ comphelper::SequenceAsHashMap aMap(xNumberingRules->getByIndex(0));
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 66
+ // - Actual : 4
+ // i.e. numbering type was ARABIC, not ARABIC_ZERO4.
+ CPPUNIT_ASSERT_EQUAL(o3tl::narrowing<sal_uInt16>(style::NumberingType::ARABIC_ZERO4),
+ aMap["NumberingType"].get<sal_uInt16>());
+}
+
+DECLARE_ODFEXPORT_TEST(testArabicZero5Numbering, "arabic-zero5-numbering.docx")
+{
+ auto xNumberingRules
+ = getProperty<uno::Reference<container::XIndexAccess>>(getParagraph(1), "NumberingRules");
+ comphelper::SequenceAsHashMap aMap(xNumberingRules->getByIndex(0));
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 67
+ // - Actual : 4
+ // i.e. numbering type was ARABIC, not ARABIC_ZERO5.
+ CPPUNIT_ASSERT_EQUAL(o3tl::narrowing<sal_uInt16>(style::NumberingType::ARABIC_ZERO5),
+ aMap["NumberingType"].get<sal_uInt16>());
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testArabicZeroNumberingFootnote)
+{
+ // Create a document, set footnote numbering type to ARABIC_ZERO.
+ loadURL("private:factory/swriter", nullptr);
+ uno::Reference<text::XFootnotesSupplier> xFootnotesSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xFootnoteSettings
+ = xFootnotesSupplier->getFootnoteSettings();
+ sal_uInt16 nNumberingType = style::NumberingType::ARABIC_ZERO;
+ xFootnoteSettings->setPropertyValue("NumberingType", uno::Any(nNumberingType));
+
+ // Insert a footnote.
+ uno::Reference<lang::XMultiServiceFactory> xFactory(mxComponent, uno::UNO_QUERY);
+ uno::Reference<text::XTextContent> xFootnote(
+ xFactory->createInstance("com.sun.star.text.Footnote"), uno::UNO_QUERY);
+ uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
+ uno::Reference<text::XTextContentAppend> xTextContentAppend(xTextDocument->getText(),
+ uno::UNO_QUERY);
+ xTextContentAppend->appendTextContent(xFootnote, {});
+
+ reload("Office Open XML Text", "");
+
+ xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
+ // Without the accompanying fix in place, this test would have failed with:
+ // XPath '/w:document/w:body/w:sectPr/w:footnotePr/w:numFmt' number of nodes is incorrect
+ // because the exporter had no idea what markup to use for ARABIC_ZERO.
+ assertXPath(pXmlDoc, "/w:document/w:body/w:sectPr/w:footnotePr/w:numFmt", "val", "decimalZero");
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testChicagoNumberingFootnote)
+{
+ // Create a document, set footnote numbering type to SYMBOL_CHICAGO.
+ loadURL("private:factory/swriter", nullptr);
+ uno::Reference<text::XFootnotesSupplier> xFootnotesSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xFootnoteSettings
+ = xFootnotesSupplier->getFootnoteSettings();
+ sal_uInt16 nNumberingType = style::NumberingType::SYMBOL_CHICAGO;
+ xFootnoteSettings->setPropertyValue("NumberingType", uno::Any(nNumberingType));
+
+ // Insert a footnote.
+ uno::Reference<lang::XMultiServiceFactory> xFactory(mxComponent, uno::UNO_QUERY);
+ uno::Reference<text::XTextContent> xFootnote(
+ xFactory->createInstance("com.sun.star.text.Footnote"), uno::UNO_QUERY);
+ uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
+ uno::Reference<text::XTextContentAppend> xTextContentAppend(xTextDocument->getText(),
+ uno::UNO_QUERY);
+ xTextContentAppend->appendTextContent(xFootnote, {});
+
+ reload("Office Open XML Text", "");
+
+ xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
+ // Without the accompanying fix in place, this test would have failed with:
+ // XPath '/w:document/w:body/w:sectPr/w:footnotePr/w:numFmt' number of nodes is incorrect
+ // because the exporter had no idea what markup to use for SYMBOL_CHICAGO.
+ assertXPath(pXmlDoc, "/w:document/w:body/w:sectPr/w:footnotePr/w:numFmt", "val", "chicago");
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testListNotCountedIndent)
+{
+ loadAndReload("list_notcounted_indent.fodt");
+ xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p[1]/w:pPr/w:numPr/w:numId", "val", "0");
+ // wrong: 720
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p[1]/w:pPr/w:ind", "start", "0");
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p[1]/w:pPr/w:ind", "end", "0");
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p[1]/w:pPr/w:ind", "hanging", "0");
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p[2]/w:pPr/w:numPr/w:numId", "val", "2");
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p[2]/w:pPr/w:ind", 0);
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p[3]/w:pPr/w:numPr/w:numId", "val", "0");
+ // wrong: 180
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p[3]/w:pPr/w:ind", "start", "720");
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p[3]/w:pPr/w:ind", "hanging", "0");
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p[4]/w:pPr/w:numPr/w:numId", "val", "0");
+ // wrong: 720
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p[4]/w:pPr/w:ind", "start", "0");
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p[4]/w:pPr/w:ind", "end", "0");
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p[4]/w:pPr/w:ind", "hanging", "0");
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p[5]/w:pPr/w:numPr/w:numId", "val", "0");
+ // wrong: 720
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p[5]/w:pPr/w:ind", "start", "0");
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p[5]/w:pPr/w:ind", "end", "0");
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p[5]/w:pPr/w:ind", "hanging", "0");
+}
+
+DECLARE_OOXMLEXPORT_TEST(testTdf87569d, "tdf87569_drawingml.docx")
+{
+ //if the original tdf87569 sample is upgraded it will have drawingml shapes...
+ uno::Reference<beans::XPropertySet> xShapeProperties(getShape(1), uno::UNO_QUERY);
+ bool bValue;
+ xShapeProperties->getPropertyValue("IsFollowingTextFlow") >>= bValue;
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("tdf87569_drawingml: The Shape is not in the table!",
+ true, bValue);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf130610)
+{
+ loadAndReload("tdf130610_bold_in_2_styles.ott");
+ CPPUNIT_ASSERT_EQUAL(1, getPages());
+ // check character properties
+ {
+ uno::Reference<beans::XPropertySet> xStyle(
+ getStyles("CharacterStyles")->getByName("WollMuxRoemischeZiffer"),
+ uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Bold", awt::FontWeight::BOLD, getProperty<float>(xStyle, "CharWeight"));
+ }
+
+ // check paragraph properties
+ {
+ uno::Reference<beans::XPropertySet> xStyle(
+ getStyles("ParagraphStyles")->getByName("WollMuxVerfuegungspunkt"),
+ uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Bold", awt::FontWeight::BOLD, getProperty<float>(xStyle, "CharWeight"));
+ }
+
+ // check inline text properties
+ {
+ xmlDocUniquePtr pXmlDoc =parseExport("word/document.xml");
+ if (pXmlDoc)
+ {
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p[2]/w:r/w:rPr/w:b");
+ }
+ }
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf121045)
+{
+ loadAndSave("tdf121045.docx");
+ xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
+ CPPUNIT_ASSERT(pXmlDoc);
+ assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr/w:tc[1]/w:p/w:pPr/w:rPr/w:sz", "val", "20");
+ assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr/w:tc[1]/w:p/w:pPr/w:rPr/w:szCs", "val", "20");
+ assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr/w:tc[1]/w:p/w:r[1]/w:fldChar", "fldCharType", "begin");
+ assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr/w:tc[1]/w:p/w:r[2]/w:instrText", 1);
+ assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr/w:tc[1]/w:p/w:r[3]/w:fldChar", "fldCharType", "separate");
+ assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr/w:tc[1]/w:p/w:r[5]/w:fldChar", "fldCharType", "end");
+ // form control keeps its direct formatted font size
+ assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr/w:tc[1]/w:p/w:r[2]/w:rPr/w:sz", "val", "20");
+ assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr/w:tc[1]/w:p/w:r[2]/w:rPr/w:szCs", "val", "20");
+ assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr/w:tc[1]/w:p/w:r[3]/w:rPr/w:sz", "val", "20");
+ assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr/w:tc[1]/w:p/w:r[3]/w:rPr/w:szCs", "val", "20");
+ assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr/w:tc[1]/w:p/w:r[4]/w:rPr/w:sz", "val", "20");
+ assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr/w:tc[1]/w:p/w:r[4]/w:rPr/w:szCs", "val", "20");
+ assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr/w:tc[1]/w:p/w:r[5]/w:rPr/w:sz", "val", "20");
+ assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr/w:tc[1]/w:p/w:r[5]/w:rPr/w:szCs", "val", "20");
+}
+
+DECLARE_OOXMLEXPORT_TEST(testTdf78352, "tdf78352.docx")
+{
+ CPPUNIT_ASSERT_EQUAL(1, getPages());
+
+ // Ensure that width of first tab is close to zero (previous value was ~1000 twips)
+ int nWidth = parseDump("/root/page/body/txt[1]/Text[@nType='PortionType::TabLeft']", "nWidth").toInt32();
+ CPPUNIT_ASSERT_LESS(150, nWidth);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf81567)
+{
+ loadAndReload("tdf81567.odt");
+ CPPUNIT_ASSERT_EQUAL(1, getPages());
+ CPPUNIT_ASSERT_EQUAL(2, getShapes());
+
+ int nFrameWidth = parseDump("/root/page/body/txt/anchored/fly/infos/bounds", "width").toInt32();
+ CPPUNIT_ASSERT_EQUAL(2371, nFrameWidth);
+
+ int nFrameHeight = parseDump("/root/page/body/txt/anchored/fly/infos/bounds", "height").toInt32();
+ CPPUNIT_ASSERT_EQUAL(3520, nFrameHeight);
+
+ int nFrameTop = parseDump("/root/page/body/txt/anchored/fly/infos/bounds", "top").toInt32();
+ CPPUNIT_ASSERT_EQUAL(1518, nFrameTop);
+
+ int nImageWidth = parseDump("/root/page/body/txt/anchored/fly/txt/anchored/fly/infos/bounds", "width").toInt32();
+ CPPUNIT_ASSERT_EQUAL(2370, nImageWidth);
+
+ int nImageHeight = parseDump("/root/page/body/txt/anchored/fly/txt/anchored/fly/infos/bounds", "height").toInt32();
+ CPPUNIT_ASSERT_EQUAL(1605, nImageHeight);
+
+ // Check the image is at the top of the frame
+ // Without the fix in place, this test would have failed with:
+ // - Expected: 1638
+ // - Actual : 2236
+ int nImageTop = parseDump("/root/page/body/txt/anchored/fly/txt/anchored/fly/infos/bounds", "top").toInt32();
+ CPPUNIT_ASSERT_EQUAL(1638, nImageTop);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf92472)
+{
+ loadAndSave("tdf92472.docx");
+ xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
+ CPPUNIT_ASSERT(pXmlDoc);
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p[2]/w:pPr/w:rPr/w:sz", "val", "20");
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p[2]/w:pPr/w:rPr/w:szCs", "val", "20");
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p[2]/w:r[1]/w:fldChar", "fldCharType", "begin");
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p[2]/w:r[2]/w:instrText", 1);
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p[2]/w:r[3]/w:fldChar", "fldCharType", "separate");
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p[2]/w:r[5]/w:fldChar", "fldCharType", "end");
+ // form control keeps its direct formatted font size
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p[2]/w:r[2]/w:rPr/w:sz", "val", "20");
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p[2]/w:r[2]/w:rPr/w:szCs", "val", "20");
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p[2]/w:r[3]/w:rPr/w:sz", "val", "20");
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p[2]/w:r[3]/w:rPr/w:szCs", "val", "20");
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p[2]/w:r[4]/w:rPr/w:sz", "val", "20");
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p[2]/w:r[4]/w:rPr/w:szCs", "val", "20");
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p[2]/w:r[5]/w:rPr/w:sz", "val", "20");
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p[2]/w:r[5]/w:rPr/w:szCs", "val", "20");
+}
+
+CPPUNIT_TEST_FIXTURE(Test, Tdf133035)
+{
+ loadAndSave("tdf133035.docx");
+ auto pxml = parseExport("word/document.xml");
+ CPPUNIT_ASSERT(pxml);
+ OUString aXmlVal = getXPath(pxml, "/w:document/w:body/w:p[1]/w:r[1]/w:object/v:shape", "style");
+ CPPUNIT_ASSERT(aXmlVal.indexOf("margin-left:186.6pt") > -1);
+}
+
+DECLARE_OOXMLEXPORT_TEST(testTdf131260, "tdf131260.docx")
+{
+ uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(),
+ uno::UNO_QUERY);
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 3
+ // - Actual : 2
+ CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xTables->getCount());
+}
+DECLARE_OOXMLEXPORT_TEST(testTdf120315, "tdf120315.docx")
+{
+ // tdf#120315 cells of the second column weren't vertically merged
+ // because their horizontal positions are different a little bit
+ uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(),
+ uno::UNO_QUERY);
+ uno::Reference<text::XTextTable> xTextTable(xTables->getByIndex(0), uno::UNO_QUERY);
+ uno::Reference<table::XTableRows> xTableRows = xTextTable->getRows();
+ CPPUNIT_ASSERT_EQUAL(getProperty<uno::Sequence<text::TableColumnSeparator>>(
+ xTableRows->getByIndex(0), "TableColumnSeparators")[0]
+ .Position,
+ getProperty<uno::Sequence<text::TableColumnSeparator>>(
+ xTableRows->getByIndex(1), "TableColumnSeparators")[2]
+ .Position);
+}
+
+DECLARE_OOXMLEXPORT_TEST(testTdf108350_noFontdefaults, "tdf108350_noFontdefaults.docx")
+{
+ uno::Reference< container::XNameAccess > paragraphStyles = getStyles("ParagraphStyles");
+ uno::Reference< beans::XPropertySet > xStyleProps(paragraphStyles->getByName("NoParent"), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("Times New Roman"), getProperty<OUString>(xStyleProps, "CharFontName"));
+ //CPPUNIT_ASSERT_EQUAL_MESSAGE("Font size", 10.f, getProperty<float>(xStyleProps, "CharHeight"));
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf123116_oversizedRowSplit)
+{
+ loadAndReload("tdf123116_oversizedRowSplit.odt");
+ // Intentionally require a very non-backward-compatible, natural continuation of the table
+ // instead of an ugly "page break" like MS Word does (and LO used to do).
+ CPPUNIT_ASSERT_EQUAL_MESSAGE("Row splits over 4 pages", 4, getPages());
+}
+
+DECLARE_OOXMLEXPORT_TEST(testPageContentBottom, "page-content-bottom.docx")
+{
+ uno::Reference<beans::XPropertySet> xShape(getShape(1), uno::UNO_QUERY);
+ sal_Int16 nExpected = text::RelOrientation::PAGE_PRINT_AREA_BOTTOM;
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 10 (PAGE_PRINT_AREA_BOTTOM)
+ // - Actual : 0 (FRAME)
+ // i.e. the bottom-of-body relation was lost.
+ CPPUNIT_ASSERT_EQUAL(nExpected, getProperty<sal_Int16>(xShape, "VertOrientRelation"));
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf129522_removeShadowStyle)
+{
+ loadAndReload("tdf129522_removeShadowStyle.odt");
+ CPPUNIT_ASSERT_EQUAL(1, getPages());
+ uno::Reference< container::XNameAccess > paragraphStyles = getStyles("ParagraphStyles");
+ uno::Reference< beans::XPropertySet > xStyleProps(paragraphStyles->getByName("Shadow"), uno::UNO_QUERY_THROW);
+ table::ShadowFormat aShadow = getProperty<table::ShadowFormat>(xStyleProps, "ParaShadowFormat");
+ CPPUNIT_ASSERT_EQUAL(table::ShadowLocation_BOTTOM_RIGHT, aShadow.Location);
+
+ // Shadows were inherited regardless of whether the style disabled them.
+ xStyleProps.set(paragraphStyles->getByName("Shadow-removed"), uno::UNO_QUERY_THROW);
+ aShadow = getProperty<table::ShadowFormat>(xStyleProps, "ParaShadowFormat");
+ CPPUNIT_ASSERT_EQUAL(table::ShadowLocation_NONE, aShadow.Location);
+
+ uno::Reference< container::XNameAccess > characterStyles = getStyles("CharacterStyles");
+ xStyleProps.set(characterStyles->getByName("CharShadow"), uno::UNO_QUERY_THROW);
+ aShadow = getProperty<table::ShadowFormat>(xStyleProps, "CharShadowFormat");
+ CPPUNIT_ASSERT_EQUAL(table::ShadowLocation_BOTTOM_RIGHT, aShadow.Location);
+
+ xStyleProps.set(characterStyles->getByName("CharShadow-removed"), uno::UNO_QUERY_THROW);
+ aShadow = getProperty<table::ShadowFormat>(xStyleProps, "CharShadowFormat");
+ CPPUNIT_ASSERT_EQUAL(table::ShadowLocation_NONE, aShadow.Location);
+}
+
+DECLARE_OOXMLEXPORT_TEST(testTdf130167_spilloverHeaderShape, "testTdf130167_spilloverHeader.docx")
+{
+ uno::Reference<text::XTextGraphicObjectsSupplier> xTextGraphicObjectsSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XIndexAccess> xNameAccess(
+ xTextGraphicObjectsSupplier->getGraphicObjects(), uno::UNO_QUERY);
+ // graphics from discarded headers were being added to the text body. Reduced from 5 to 2 shapes overall.
+ // CPPUNIT_ASSERT(xNameAccess->getCount() <= 4); -> What about hidden headers?
+ CPPUNIT_ASSERT_LESS(sal_Int32(9), xNameAccess->getCount());
+}
+
+DECLARE_OOXMLEXPORT_TEST(testTdf124986, "tdf124986.docx")
+{
+ // Load a document with SET fields, where the SET fields contain leading/trailing quotation marks and spaces.
+ uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XEnumerationAccess> xFieldsAccess(xTextFieldsSupplier->getTextFields());
+ uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration());
+
+ while (xFields->hasMoreElements())
+ {
+ uno::Reference<lang::XServiceInfo> xServiceInfo(xFields->nextElement(), uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xPropertySet(xServiceInfo, uno::UNO_QUERY);
+ if (xServiceInfo->supportsService("com.sun.star.text.TextField.SetExpression"))
+ {
+ OUString aValue;
+ xPropertySet->getPropertyValue("Content") >>= aValue;
+ CPPUNIT_ASSERT_EQUAL(OUString("demo"), aValue);
+ }
+ }
+}
+
+DECLARE_OOXMLEXPORT_TEST(testTdf83309, "tdf83309.docx")
+{
+ // Important: bug case had 4 pages
+ CPPUNIT_ASSERT_EQUAL(2, getPages());
+
+ // First paragraph does not have tab before
+ // (same applies to all paragraphs in doc, but lets assume they are
+ // behave same way)
+ OUString sNodeType = parseDump("/root/page[1]/body/txt[1]/Text[1]", "nType");
+ CPPUNIT_ASSERT_EQUAL(OUString("PortionType::Text"), sNodeType);
+
+ // tdf148380: creation-date field in header.xml was unsupported on export
+ uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
+ auto xFieldsAccess(xTextFieldsSupplier->getTextFields());
+ uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration());
+ uno::Reference<text::XTextField> xField(xFields->nextElement(), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("8/31/14 10:26 AM"), xField->getPresentation(false));
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf121661)
+{
+ loadAndSave("tdf121661.docx");
+ xmlDocUniquePtr pXmlSettings = parseExport("word/settings.xml");
+ assertXPath(pXmlSettings, "/w:settings/w:hyphenationZone", "val", "851");
+
+ // tdf#149421
+ uno::Reference<beans::XPropertySet> xStyle(getStyles("ParagraphStyles")->getByName("Standard"), uno::UNO_QUERY);
+ // This was false
+ CPPUNIT_ASSERT_GREATER( static_cast<sal_Int16>(0), getProperty<sal_Int16>(xStyle, "ParaHyphenationZone"));
+}
+
+DECLARE_OOXMLEXPORT_TEST(testTdf149421, "tdf121661.docx")
+{
+ uno::Reference<beans::XPropertySet> xStyle(getStyles("ParagraphStyles")->getByName("Standard"), uno::UNO_QUERY);
+ // This was false
+ CPPUNIT_ASSERT_GREATER( static_cast<sal_Int16>(0), getProperty<sal_Int16>(xStyle, "ParaHyphenationZone"));
+
+ if (!mbExported)
+ {
+ CPPUNIT_ASSERT_EQUAL( static_cast<sal_Int16>(851), getProperty<sal_Int16>(xStyle, "ParaHyphenationZone"));
+ // modify hyphenation zone (note: only hyphenation zone set in Standard paragraph style
+ // is exported, according to the document-level hyphenation settings of OOXML)
+ xStyle->setPropertyValue("ParaHyphenationZone", uno::Any(static_cast<sal_Int16>(2000)));
+ }
+ else
+ {
+ // check the export of the modified hyphenation zone
+ CPPUNIT_ASSERT_EQUAL( static_cast<sal_Int16>(2000), getProperty<sal_Int16>(xStyle, "ParaHyphenationZone"));
+ }
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf121658)
+{
+ loadAndSave("tdf121658.docx");
+ xmlDocUniquePtr pXmlSettings = parseExport("word/settings.xml");
+ assertXPath(pXmlSettings, "/w:settings/w:doNotHyphenateCaps");
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTableStyleConfNested)
+{
+ loadAndSave("table-style-conf-nested.docx");
+ xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
+ CPPUNIT_ASSERT(pXmlDoc);
+ // Without the accompanying fix in place, this test would have failed, as the custom table cell
+ // border properties were lost, so the outer A2 cell started to have borders, not present in the
+ // doc model.
+ assertXPath(pXmlDoc, "//w:body/w:tbl/w:tr/w:tc[2]/w:tcPr/w:tcBorders/w:top", "val", "nil");
+}
+
+CPPUNIT_TEST_FIXTURE(SwModelTestBase, testTdf133771)
+{
+ // Create the doc model.
+ OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "tdf133771.odt";
+ loadURL(aURL, nullptr, /*pPassword*/ "test");
+
+ CPPUNIT_ASSERT_EQUAL(OUString("Password Protected"), getParagraph(1)->getString());
+
+ // Without the fix in place, this test would have failed with
+ // "An uncaught exception of type com.sun.star.io.IOException"
+ // exporting to docx
+ save("Office Open XML Text", maTempFile);
+ mbExported = true;
+ xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
+ CPPUNIT_ASSERT(pXmlDoc);
+ assertXPathContent(pXmlDoc, "//w:body/w:p/w:r/w:t", "Password Protected");
+}
+
+CPPUNIT_TEST_FIXTURE(SwModelTestBase, testZeroLineSpacing)
+{
+ // Create the doc model.
+ loadURL("private:factory/swriter", nullptr);
+ uno::Reference<beans::XPropertySet> xParagraph(getParagraph(1), uno::UNO_QUERY);
+ style::LineSpacing aSpacing;
+ aSpacing.Mode = style::LineSpacingMode::MINIMUM;
+ aSpacing.Height = 0;
+ xParagraph->setPropertyValue("ParaLineSpacing", uno::Any(aSpacing));
+
+ // Export to docx.
+ save("Office Open XML Text", maTempFile);
+ mbExported = true;
+ xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
+ CPPUNIT_ASSERT(pXmlDoc);
+
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: atLeast
+ // - Actual : auto
+ // i.e. the minimal linespacing was lost on export.
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:pPr/w:spacing", "lineRule", "atLeast");
+ assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:pPr/w:spacing", "line", "0");
+}
+
+CPPUNIT_TEST_FIXTURE(SwModelTestBase, testSemiTransparentText)
+{
+ // Create an in-memory empty document.
+ loadURL("private:factory/swriter", nullptr);
+
+ // Set text to half-transparent and type a character.
+ uno::Reference<beans::XPropertySet> xParagraph(getParagraph(1), uno::UNO_QUERY);
+ CPPUNIT_ASSERT(xParagraph.is());
+ sal_Int16 nTransparence = 75;
+ xParagraph->setPropertyValue("CharTransparence", uno::Any(nTransparence));
+ uno::Reference<text::XTextRange> xTextRange(xParagraph, uno::UNO_QUERY);
+ CPPUNIT_ASSERT(xTextRange.is());
+ xTextRange->setString("x");
+
+ // Export to docx.
+ save("Office Open XML Text", maTempFile);
+ mbExported = true;
+ xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
+ CPPUNIT_ASSERT(pXmlDoc);
+ double fValue = getXPath(
+ pXmlDoc,
+ "/w:document/w:body/w:p/w:r/w:rPr/w14:textFill/w14:solidFill/w14:srgbClr/w14:alpha",
+ "val")
+ .toDouble();
+ sal_Int16 nActual = basegfx::fround(fValue / oox::drawingml::PER_PERCENT);
+
+ // Without the accompanying fix in place, this test would have failed, as the w14:textFill
+ // element was missing.
+ CPPUNIT_ASSERT_EQUAL(nTransparence, nActual);
+}
+
+CPPUNIT_TEST_FIXTURE(SwModelTestBase, testTdf147485)
+{
+ // Before the fix this was impossible.
+ load(DATA_DIRECTORY, "Tdf147485.docx");
+}
+
+CPPUNIT_TEST_FIXTURE(SwModelTestBase, testTdf149546)
+{
+ // Before the fix this was impossible.
+ load(DATA_DIRECTORY, "tdf149546.docx");
+}
+
+CPPUNIT_TEST_FIXTURE(SwModelTestBase, testUserField)
+{
+ // Create an in-memory empty document with a user field.
+ loadURL("private:factory/swriter", nullptr);
+ uno::Reference<lang::XMultiServiceFactory> xFactory(mxComponent, uno::UNO_QUERY);
+ uno::Reference<text::XDependentTextField> xField(
+ xFactory->createInstance("com.sun.star.text.TextField.User"), uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xMaster(
+ xFactory->createInstance("com.sun.star.text.FieldMaster.User"), uno::UNO_QUERY);
+ xMaster->setPropertyValue("Name", uno::Any(OUString("foo")));
+ xField->attachTextFieldMaster(xMaster);
+ xField->getTextFieldMaster()->setPropertyValue("Content", uno::Any(OUString("bar")));
+ uno::Reference<text::XTextDocument> xDocument(mxComponent, uno::UNO_QUERY);
+ uno::Reference<text::XText> xText = xDocument->getText();
+ xText->insertTextContent(xText->createTextCursor(), xField, /*bAbsorb=*/false);
+
+ // Export to docx.
+ save("Office Open XML Text", maTempFile);
+ mbExported = true;
+ xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
+ CPPUNIT_ASSERT(pXmlDoc);
+
+ // Without the accompanying fix in place, this test would have failed, the user field was
+ // exported as <w:t>User Field foo = bar</w:t>.
+ assertXPathContent(pXmlDoc, "//w:p/w:r[2]/w:instrText", " DOCVARIABLE foo ");
+ assertXPathContent(pXmlDoc, "//w:p/w:r[4]/w:t", "bar");
+
+ // Make sure that not only the variables, but also their values are written.
+ pXmlDoc = parseExport("word/settings.xml");
+ CPPUNIT_ASSERT(pXmlDoc);
+ assertXPath(pXmlDoc, "//w:docVars/w:docVar", "name", "foo");
+ assertXPath(pXmlDoc, "//w:docVars/w:docVar", "val", "bar");
+}
+
+CPPUNIT_TEST_FIXTURE(SwModelTestBase, testHighlightEdit_numbering)
+{
+ // Create the doc model.
+ OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "tdf135774_numberingCRProps.docx";
+ loadURL(aURL, nullptr);
+
+ // This only affects when saving as w:highlight - which is not the default since 7.0.
+ SvtFilterOptions& rOpt = SvtFilterOptions::Get();
+ bool bWasExportToShade = rOpt.IsCharBackground2Shading();
+ rOpt.SetCharBackground2Highlighting();
+
+ //Simulate a user editing the char background color of the paragraph 2 marker (CR)
+ uno::Reference<beans::XPropertySet> properties(getParagraph(2), uno::UNO_QUERY);
+ uno::Sequence<beans::NamedValue> aListAutoFormat;
+ CPPUNIT_ASSERT(properties->getPropertyValue("ListAutoFormat") >>= aListAutoFormat);
+ comphelper::SequenceAsHashMap aMap(properties->getPropertyValue("ListAutoFormat"));
+ // change the background color to RES_CHRATR_BACKGROUND.
+ aMap["CharBackColor"] <<= static_cast<sal_Int32>(0xff00ff);
+ // Two attributes can affect character background. Highlight has priority, and is only there for MS compatibility,
+ // so clear any potential highlight set earlier, or override any coming via a style.
+ aMap["CharHighlight"] <<= static_cast<sal_Int32>(COL_TRANSPARENT);
+
+ uno::Sequence<beans::PropertyValue> aGrabBag;
+ aMap["CharInteropGrabBag"] >>= aGrabBag;
+ for (beans::PropertyValue& rProp : asNonConstRange(aGrabBag))
+ {
+ // The shading is no longer defined from import, so clear that flag.
+ // BackColor 0xff00ff will now attempt to export as highlight, since we set that in SvtFilterOptions.
+ if (rProp.Name == "CharShadingMarker")
+ rProp.Value <<= false;
+ }
+ aMap["CharInteropGrabBag"] <<= aGrabBag;
+
+ aMap >> aListAutoFormat;
+ properties->setPropertyValue("ListAutoFormat", uno::Any(aListAutoFormat));
+
+ // Export to docx.
+ save("Office Open XML Text", maTempFile);
+ mbExported = true;
+
+ // Paragraph 2 should have only one w:highlight written per w:rPr. Without the fix, there were two.
+ xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
+ assertXPath(pXmlDoc, "//w:body/w:p[2]/w:pPr/w:rPr/w:highlight", "val", "none");
+ // Visually, the "none" highlight means the bullet point should not have a character background.
+
+ if (bWasExportToShade)
+ rOpt.SetCharBackground2Shading();
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf132766)
+{
+ loadAndSave("tdf132766.docx");
+ xmlDocUniquePtr pXmlDoc = parseExport("word/numbering.xml");
+ CPPUNIT_ASSERT(pXmlDoc);
+
+ // Ensure that for list=1 and level=0 we wrote correct bullet char and correct font
+ assertXPath(pXmlDoc, "//w:numbering/w:abstractNum[@w:abstractNumId='1']/w:lvl[@w:ilvl='0']/w:lvlText",
+ "val", u"\uF0B7");
+ assertXPath(pXmlDoc, "//w:numbering/w:abstractNum[@w:abstractNumId='1']/w:lvl[@w:ilvl='0']/w:rPr/w:rFonts",
+ "ascii", "Symbol");
+ assertXPath(pXmlDoc, "//w:numbering/w:abstractNum[@w:abstractNumId='1']/w:lvl[@w:ilvl='0']/w:rPr/w:rFonts",
+ "hAnsi", "Symbol");
+ assertXPath(pXmlDoc, "//w:numbering/w:abstractNum[@w:abstractNumId='1']/w:lvl[@w:ilvl='0']/w:rPr/w:rFonts",
+ "cs", "Symbol");
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf128245)
+{
+ loadAndSave("tdf128245.docx");
+ xmlDocUniquePtr pXmlDoc = parseExport("word/numbering.xml");
+ CPPUNIT_ASSERT(pXmlDoc);
+
+ assertXPath(pXmlDoc, "//w:num[@w:numId='1']/w:abstractNumId", "val", "1");
+ assertXPath(pXmlDoc, "//w:num[@w:numId='2']/w:abstractNumId", "val", "2");
+ assertXPath(pXmlDoc, "//w:num[@w:numId='3']/w:abstractNumId", "val", "3");
+ assertXPath(pXmlDoc, "//w:num[@w:numId='4']/w:abstractNumId", "val", "1");
+ assertXPath(pXmlDoc, "//w:num[@w:numId='4']/w:lvlOverride[@w:ilvl='0']", "ilvl", "0");
+ assertXPath(pXmlDoc, "//w:num[@w:numId='4']/w:lvlOverride/w:startOverride", "val", "1");
+ assertXPath(pXmlDoc, "//w:num[@w:numId='4']/w:lvlOverride[@w:ilvl='1']", 0);
+}
+
+DECLARE_OOXMLEXPORT_TEST(testTdf124367, "tdf124367.docx")
+{
+ uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(),
+ uno::UNO_QUERY);
+ uno::Reference<text::XTextTable> xTextTable(xTables->getByIndex(0), uno::UNO_QUERY);
+ uno::Reference<table::XTableRows> xTableRows = xTextTable->getRows();
+ // it was 2761 at the first import, and 2760 at the second import, due to incorrect rounding
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(2762),
+ getProperty<uno::Sequence<text::TableColumnSeparator>>(
+ xTableRows->getByIndex(2), "TableColumnSeparators")[0]
+ .Position);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf95189)
+{
+ loadAndReload("tdf95189.docx");
+ {
+ uno::Reference<beans::XPropertySet> xPara(getParagraph(1), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("1"), getProperty<OUString>(xPara, "ListLabelString"));
+ }
+ {
+ uno::Reference<beans::XPropertySet> xPara(getParagraph(2), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("2"), getProperty<OUString>(xPara, "ListLabelString"));
+ }
+ {
+ uno::Reference<beans::XPropertySet> xPara(getParagraph(3), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("1"), getProperty<OUString>(xPara, "ListLabelString"));
+ }
+ {
+ uno::Reference<beans::XPropertySet> xPara(getParagraph(4), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("2"), getProperty<OUString>(xPara, "ListLabelString"));
+ }
+ {
+ uno::Reference<beans::XPropertySet> xPara(getParagraph(5), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("3"), getProperty<OUString>(xPara, "ListLabelString"));
+ }
+ {
+ uno::Reference<beans::XPropertySet> xPara(getParagraph(6), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("1"), getProperty<OUString>(xPara, "ListLabelString"));
+ }
+ {
+ uno::Reference<beans::XPropertySet> xPara(getParagraph(7), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("2"), getProperty<OUString>(xPara, "ListLabelString"));
+ }
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf128820)
+{
+ loadAndSave("tdf128820.fodt");
+ // Import of exported DOCX failed because of wrong namespace used for wsp element
+ // Now test the exported XML, in case we stop failing opening invalid files
+ xmlDocUniquePtr pXml = parseExport("word/document.xml");
+ CPPUNIT_ASSERT(pXml);
+ // The parent wpg:wgp element has three children: wpg:cNvGrpSpPr, wpg:grpSpPr, and wpg:wsp
+ // (if we start legitimately exporting additional children, this needs to be adjusted to check
+ // all those, to make sure we don't export wrong elements).
+ assertXPathChildren(pXml,
+ "/w:document/w:body/w:p/w:r/mc:AlternateContent/mc:Choice/w:drawing/"
+ "wp:inline/a:graphic/a:graphicData/wpg:wgp",
+ 3);
+ assertXPath(pXml,
+ "/w:document/w:body/w:p/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:inline/"
+ "a:graphic/a:graphicData/wpg:wgp/wpg:cNvGrpSpPr");
+ assertXPath(pXml,
+ "/w:document/w:body/w:p/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:inline/"
+ "a:graphic/a:graphicData/wpg:wgp/wpg:grpSpPr");
+ // This one was pic:wsp instead of wps:wsp
+ assertXPath(pXml,
+ "/w:document/w:body/w:p/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:inline/"
+ "a:graphic/a:graphicData/wpg:wgp/wps:wsp");
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf128889)
+{
+ loadAndSave("tdf128889.fodt");
+ xmlDocUniquePtr pXml = parseExport("word/document.xml");
+ CPPUNIT_ASSERT(pXml);
+ // There was an w:r (with w:br) as an invalid child of first paragraph's w:pPr
+ assertXPath(pXml, "/w:document/w:body/w:p[1]/w:pPr/w:r", 0);
+ assertXPath(pXml, "/w:document/w:body/w:p[1]/w:r", 2);
+ // Check that the break is in proper - last - position
+ assertXPath(pXml, "/w:document/w:body/w:p[1]/w:r[2]/w:br", "type", "page");
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf132754)
+{
+ loadAndReload("tdf132754.docx");
+ {
+ uno::Reference<beans::XPropertySet> xPara(getParagraph(1), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("0.0.0."), getProperty<OUString>(xPara, "ListLabelString"));
+ }
+ {
+ uno::Reference<beans::XPropertySet> xPara(getParagraph(2), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("0.0.1."), getProperty<OUString>(xPara, "ListLabelString"));
+ }
+ {
+ uno::Reference<beans::XPropertySet> xPara(getParagraph(3), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(OUString("0.0.2."), getProperty<OUString>(xPara, "ListLabelString"));
+ }
+}
+
+DECLARE_OOXMLEXPORT_TEST(testTdf129353, "tdf129353.docx")
+{
+ CPPUNIT_ASSERT_EQUAL(8, getParagraphs());
+ getParagraph(1, "(Verne, 1870)");
+ getParagraph(2, "Bibliography");
+ getParagraph(4, "Christie, A. (1922). The Secret Adversary. ");
+ CPPUNIT_ASSERT_EQUAL(OUString(), getParagraph(8)->getString());
+
+ uno::Reference<text::XDocumentIndexesSupplier> xIndexSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XIndexAccess> xIndexes = xIndexSupplier->getDocumentIndexes();
+ uno::Reference<text::XDocumentIndex> xIndex(xIndexes->getByIndex(0), uno::UNO_QUERY);
+ uno::Reference<text::XTextRange> xTextRange = xIndex->getAnchor();
+ uno::Reference<text::XText> xText = xTextRange->getText();
+ uno::Reference<text::XTextCursor> xTextCursor = xText->createTextCursor();
+ xTextCursor->gotoRange(xTextRange->getStart(), false);
+ xTextCursor->gotoRange(xTextRange->getEnd(), true);
+ OUString aIndexString(convertLineEnd(xTextCursor->getString(), LineEnd::LINEEND_LF));
+
+ // Check that all the pre-rendered entries are correct, including trailing spaces
+ CPPUNIT_ASSERT_EQUAL(OUString("\n" // starting with an empty paragraph
+ "Christie, A. (1922). The Secret Adversary. \n"
+ "\n"
+ "Verne, J. G. (1870). Twenty Thousand Leagues Under the Sea. \n"
+ ""), // ending with an empty paragraph
+ aIndexString);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf77796)
+{
+ loadAndSave("tdf77796.docx");
+ xmlDocUniquePtr pXml = parseExport("word/document.xml");
+ CPPUNIT_ASSERT(pXml);
+ // cell paddings from table style
+ assertXPath(pXml, "/w:document/w:body/w:tbl/w:tblPr/w:tblCellMar/w:start", "w", "5");
+ assertXPath(pXml, "/w:document/w:body/w:tbl/w:tblPr/w:tblCellMar/w:top", "w", "240");
+ assertXPath(pXml, "/w:document/w:body/w:tbl/w:tblPr/w:tblCellMar/w:bottom", "w", "480");
+ // not modified
+ assertXPath(pXml, "/w:document/w:body/w:tbl/w:tblPr/w:tblCellMar/w:end", "w", "108");
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf128290)
+{
+ loadAndSave("tdf128290.odt");
+ CPPUNIT_ASSERT_EQUAL(1, getPages());
+ xmlDocUniquePtr pXml = parseExport("word/document.xml");
+ CPPUNIT_ASSERT(pXml);
+ assertXPath(pXml, "/w:document/w:body/w:tbl/w:tblPr/w:tblLayout", "type", "fixed");
+}
+
+DECLARE_OOXMLEXPORT_TEST(testTdf120394, "tdf120394.docx")
+{
+ CPPUNIT_ASSERT_EQUAL(1, getPages());
+ {
+ uno::Reference<beans::XPropertySet> xPara(getParagraph(1), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(0), getProperty<sal_Int16>(xPara, "NumberingLevel"));
+ CPPUNIT_ASSERT_EQUAL(OUString("1"), getProperty<OUString>(xPara, "ListLabelString"));
+ }
+ {
+ uno::Reference<beans::XPropertySet> xPara(getParagraph(2), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(1), getProperty<sal_Int16>(xPara, "NumberingLevel"));
+ CPPUNIT_ASSERT_EQUAL(OUString(), getProperty<OUString>(xPara, "ListLabelString"));
+ }
+ {
+ uno::Reference<beans::XPropertySet> xPara(getParagraph(3), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(1), getProperty<sal_Int16>(xPara, "NumberingLevel"));
+ CPPUNIT_ASSERT_EQUAL(OUString(), getProperty<OUString>(xPara, "ListLabelString"));
+ }
+ {
+ uno::Reference<beans::XPropertySet> xPara(getParagraph(5), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(2), getProperty<sal_Int16>(xPara, "NumberingLevel"));
+ CPPUNIT_ASSERT_EQUAL(OUString("1.2.1"), getProperty<OUString>(xPara, "ListLabelString"));
+ }
+}
+
+DECLARE_OOXMLEXPORT_TEST(testTdf133605, "tdf133605.docx")
+{
+ CPPUNIT_ASSERT_EQUAL(1, getPages());
+ {
+ uno::Reference<beans::XPropertySet> xPara(getParagraph(3), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(0), getProperty<sal_Int16>(xPara, "NumberingLevel"));
+ CPPUNIT_ASSERT_EQUAL(OUString(), getProperty<OUString>(xPara, "ListLabelString"));
+ }
+ {
+ uno::Reference<beans::XPropertySet> xPara(getParagraph(4), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(1), getProperty<sal_Int16>(xPara, "NumberingLevel"));
+ CPPUNIT_ASSERT_EQUAL(OUString("1."), getProperty<OUString>(xPara, "ListLabelString"));
+ }
+ {
+ uno::Reference<beans::XPropertySet> xPara(getParagraph(5), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(2), getProperty<sal_Int16>(xPara, "NumberingLevel"));
+ CPPUNIT_ASSERT_EQUAL(OUString("1.1"), getProperty<OUString>(xPara, "ListLabelString"));
+ }
+ {
+ uno::Reference<beans::XPropertySet> xPara(getParagraph(6), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(3), getProperty<sal_Int16>(xPara, "NumberingLevel"));
+ CPPUNIT_ASSERT_EQUAL(OUString("(a)"), getProperty<OUString>(xPara, "ListLabelString"));
+ }
+}
+
+DECLARE_OOXMLEXPORT_TEST(testTdf133605_2, "tdf133605_2.docx")
+{
+ // About the same document as tdf133605.docx, but number definition has level definitions in random order
+ CPPUNIT_ASSERT_EQUAL(1, getPages());
+ {
+ uno::Reference<beans::XPropertySet> xPara(getParagraph(3), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(0), getProperty<sal_Int16>(xPara, "NumberingLevel"));
+ CPPUNIT_ASSERT_EQUAL(OUString(), getProperty<OUString>(xPara, "ListLabelString"));
+ }
+ {
+ uno::Reference<beans::XPropertySet> xPara(getParagraph(4), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(1), getProperty<sal_Int16>(xPara, "NumberingLevel"));
+ CPPUNIT_ASSERT_EQUAL(OUString("1."), getProperty<OUString>(xPara, "ListLabelString"));
+ }
+ {
+ uno::Reference<beans::XPropertySet> xPara(getParagraph(5), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(2), getProperty<sal_Int16>(xPara, "NumberingLevel"));
+ CPPUNIT_ASSERT_EQUAL(OUString("1.1"), getProperty<OUString>(xPara, "ListLabelString"));
+ }
+ {
+ uno::Reference<beans::XPropertySet> xPara(getParagraph(6), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(3), getProperty<sal_Int16>(xPara, "NumberingLevel"));
+ CPPUNIT_ASSERT_EQUAL(OUString("(a)"), getProperty<OUString>(xPara, "ListLabelString"));
+ }
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf123757)
+{
+ loadAndSave("tdf123757.docx");
+ xmlDocUniquePtr pXml = parseExport("word/document.xml");
+ CPPUNIT_ASSERT(pXml);
+ assertXPath(pXml, "/w:document/w:body/w:tbl", 2);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf141172)
+{
+ loadAndSave("tdf141172.docx");
+ xmlDocUniquePtr pXml = parseExport("word/endnotes.xml");
+ CPPUNIT_ASSERT(pXml);
+ // This was 1 (lost table during copying endnote content)
+ assertXPath(pXml, "/w:endnotes/w:endnote/w:tbl", 2);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf141548)
+{
+ loadAndSave("tdf141548.docx");
+ xmlDocUniquePtr pXml = parseExport("word/endnotes.xml");
+ CPPUNIT_ASSERT(pXml);
+ // This was 0 (lost text content of the run with endnoteRef)
+ assertXPath(pXml, "/w:endnotes/w:endnote[4]/w:p/w:r[2]/w:t", 2);
+ assertXPathContent(pXml, "/w:endnotes/w:endnote[4]/w:p/w:r[2]/w:t[1]", "another endnote");
+ assertXPathContent(pXml, "/w:endnotes/w:endnote[4]/w:p/w:r[2]/w:t[2]", "new line");
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf143399)
+{
+ loadAndSave("tdf143399.docx");
+ xmlDocUniquePtr pXml = parseExport("word/footnotes.xml");
+ CPPUNIT_ASSERT(pXml);
+ // These were 0 (lost text content of documents both with footnotes and endnotes)
+ assertXPath(pXml, "/w:footnotes/w:footnote[3]/w:p/w:r[3]/w:t", 1);
+ assertXPathContent(pXml, "/w:footnotes/w:footnote[3]/w:p/w:r[3]/w:t", "Footnotes_graphic2");
+ assertXPath(pXml, "/w:footnotes/w:footnote[4]/w:p/w:r[3]/w:t", 1);
+ assertXPathContent(pXml, "/w:footnotes/w:footnote[4]/w:p/w:r[3]/w:t", "Footnotes_graphic");
+
+ xmlDocUniquePtr pXml2 = parseExport("word/endnotes.xml");
+ CPPUNIT_ASSERT(pXml);
+ // This was 0 (lost text content of the run with endnoteRef)
+ assertXPath(pXml2, "/w:endnotes/w:endnote[3]/w:p/w:r[3]/w:t", 1);
+ assertXPathContent(pXml2, "/w:endnotes/w:endnote[3]/w:p/w:r[3]/w:t[1]", "Endnotes");
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf143583)
+{
+ loadAndSave("tdf143583_emptyParaAtEndOfFootnote.docx");
+ xmlDocUniquePtr pXml = parseExport("word/footnotes.xml");
+ CPPUNIT_ASSERT(pXml);
+ assertXPath(pXml, "/w:footnotes/w:footnote[3]/w:p", 2);
+ // This was 1
+ assertXPath(pXml, "/w:footnotes/w:footnote[4]/w:p", 2);
+ // This was 2
+ assertXPath(pXml, "/w:footnotes/w:footnote[5]/w:p", 3);
+ // This was 2
+ assertXPath(pXml, "/w:footnotes/w:footnote[6]/w:p", 3);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf152203)
+{
+ loadAndSave("tdf152203.docx");
+ xmlDocUniquePtr pXml = parseExport("word/footnotes.xml");
+ CPPUNIT_ASSERT(pXml);
+
+ uno::Reference<text::XFootnotesSupplier> xFootnotesSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XIndexAccess> xFootnotes = xFootnotesSupplier->getFootnotes();
+ uno::Reference<text::XTextRange> xLastFootnote(xFootnotes->getByIndex(5), uno::UNO_QUERY);
+ // This was "Footnote for pg5" (replaced footnotes)
+ CPPUNIT_ASSERT_EQUAL( OUString("Footnote for pg 6"), xLastFootnote->getString().trim() );
+
+ uno::Reference<text::XTextRange> xLastButOne(xFootnotes->getByIndex(4), uno::UNO_QUERY);
+ // This was "Footnote for pg 6" (replaced footnotes)
+ CPPUNIT_ASSERT_EQUAL( OUString("Footnote for pg5"), xLastButOne->getString().trim() );
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf152206)
+{
+ loadAndSave("tdf152206.docx");
+ xmlDocUniquePtr pXml = parseExport("word/footnotes.xml");
+ CPPUNIT_ASSERT(pXml);
+
+ uno::Reference<text::XFootnotesSupplier> xFootnotesSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XIndexAccess> xFootnotes = xFootnotesSupplier->getFootnotes();
+ uno::Reference<text::XTextRange> xLastFootnote(xFootnotes->getByIndex(1), uno::UNO_QUERY);
+ // This was "Footnote for pg5" (replaced footnotes)
+ CPPUNIT_ASSERT_EQUAL( OUString("Footnote for pg 6"), xLastFootnote->getString().trim() );
+
+ uno::Reference<text::XTextRange> xLastButOne(xFootnotes->getByIndex(0), uno::UNO_QUERY);
+ // This was "Footnote for pg 6" (replaced footnotes)
+ CPPUNIT_ASSERT_EQUAL( OUString("Footnote for pg5"), xLastButOne->getString().trim() );
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf153255)
+{
+ loadAndSave("tdf153255.docx");
+ xmlDocUniquePtr pXml = parseExport("word/footnotes.xml");
+ CPPUNIT_ASSERT(pXml);
+
+ uno::Reference<text::XFootnotesSupplier> xFootnotesSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XIndexAccess> xFootnotes = xFootnotesSupplier->getFootnotes();
+ uno::Reference<text::XTextRange> xLastFootnote(xFootnotes->getByIndex(5), uno::UNO_QUERY);
+ // This was "Footnote for pg2" (replaced footnotes)
+ CPPUNIT_ASSERT_EQUAL( OUString("Footnote for pg 6"), xLastFootnote->getString().trim() );
+
+ uno::Reference<text::XTextRange> xLastButOne(xFootnotes->getByIndex(4), uno::UNO_QUERY);
+ // This was "Footnote for pg 6" (replaced footnotes)
+ CPPUNIT_ASSERT_EQUAL( OUString("Footnote for pg5"), xLastButOne->getString().trim() );
+
+ // check all the remaining footnotes
+
+ uno::Reference<text::XTextRange> xFootnote1(xFootnotes->getByIndex(0), uno::UNO_QUERY);
+ // This was "Footnote for pg3" (replaced footnotes)
+ CPPUNIT_ASSERT_EQUAL( OUString("Footnote for pg1"), xFootnote1->getString().trim() );
+
+ uno::Reference<text::XTextRange> xFootnote2(xFootnotes->getByIndex(1), uno::UNO_QUERY);
+ // This was "Footnote for pg5" (replaced footnotes)
+ CPPUNIT_ASSERT_EQUAL( OUString("Footnote for pg2"), xFootnote2->getString().trim() );
+
+ uno::Reference<text::XTextRange> xFootnote3(xFootnotes->getByIndex(2), uno::UNO_QUERY);
+ // This was "Footnote for pg4." (replaced footnotes)
+ CPPUNIT_ASSERT_EQUAL( OUString("Footnote for pg3"), xFootnote3->getString().trim() );
+
+ uno::Reference<text::XTextRange> xFootnote4(xFootnotes->getByIndex(3), uno::UNO_QUERY);
+ // This was "Footnote for pg1" (replaced footnotes)
+ CPPUNIT_ASSERT_EQUAL( OUString("Footnote for pg4."), xFootnote4->getString().trim() );
+}
+
+// skip test for macOS (missing fonts?)
+#if !defined(MACOSX)
+DECLARE_OOXMLEXPORT_TEST(testTdf146346, "tdf146346.docx")
+{
+ // This was 2 (by bad docDefault vertical margins around tables in footnotes)
+ CPPUNIT_ASSERT_EQUAL(1, getPages());
+}
+#endif
+
+DECLARE_OOXMLEXPORT_TEST(testContSectBreakHeaderFooter, "cont-sect-break-header-footer.docx")
+{
+ // Load a document with a continuous section break on page 2.
+ CPPUNIT_ASSERT_EQUAL(OUString("First page header, section 1"),
+ parseDump("/root/page[1]/header/txt/text()"));
+ CPPUNIT_ASSERT_EQUAL(OUString("First page footer, section 1"),
+ parseDump("/root/page[1]/footer/txt/text()"));
+ // Make sure the header stays like this; if we naively just update the page style name of the
+ // first para on page 2, then this would be 'Header, section 2', which is incorrect.
+ CPPUNIT_ASSERT_EQUAL(OUString("First page header, section 2"),
+ parseDump("/root/page[2]/header/txt/text()"));
+ CPPUNIT_ASSERT_EQUAL(OUString("First page footer, section 2"),
+ parseDump("/root/page[2]/footer/txt/text()"));
+ // This is inherited from page 2.
+ CPPUNIT_ASSERT_EQUAL(OUString("Header, section 2"),
+ parseDump("/root/page[3]/header/txt/text()"));
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 1
+ // - Actual : 0
+ // - xpath should match exactly 1 node
+ // i.e. the footer had no text (inherited from page 2), while the correct behavior is to provide
+ // the own footer text.
+ CPPUNIT_ASSERT_EQUAL(OUString("Footer, section 3"),
+ parseDump("/root/page[3]/footer/txt/text()"));
+
+ // Without the export fix in place, the import-export-import test would have failed with:
+ // - Expected: Header, section 2
+ // - Actual : First page header, section 2
+ // i.e. both the header and the footer on page 3 was wrong.
+
+ // Additional problem: top margin on page 3 was wrong.
+ if (mbExported)
+ {
+ xmlDocUniquePtr pXml = parseExport("word/document.xml");
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 2200
+ // - Actual : 2574
+ // i.e. the top margin on page 3 was too large and now matches the value from the input
+ // document.
+ assertXPath(pXml, "/w:document/w:body/w:sectPr/w:pgMar", "top", "2200");
+ }
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testHyphenationAuto)
+{
+ loadAndReload("hyphenation.odt");
+ CPPUNIT_ASSERT_EQUAL(1, getPages());
+ // Explicitly set hyphenation=auto on document level
+ xmlDocUniquePtr pXmlSettings = parseExport("word/settings.xml");
+ CPPUNIT_ASSERT(pXmlSettings);
+ assertXPath(pXmlSettings, "/w:settings/w:autoHyphenation", "val", "true");
+
+ // Second paragraph has explicitly enabled hyphenation
+ xmlDocUniquePtr pXml = parseExport("word/document.xml");
+ CPPUNIT_ASSERT(pXml);
+ assertXPath(pXml, "/w:document/w:body/w:p[2]/w:pPr/w:suppressAutoHyphens", "val", "false");
+
+ // Default paragraph style explicitly disables hyphens
+ xmlDocUniquePtr pXmlStyles = parseExport("word/styles.xml");
+ CPPUNIT_ASSERT(pXmlStyles);
+ assertXPath(pXmlStyles, "/w:styles/w:docDefaults/w:pPrDefault/w:pPr/w:suppressAutoHyphens", "val", "true");
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testStrikeoutGroupShapeText)
+{
+ loadAndSave("tdf131776_StrikeoutGroupShapeText.docx");
+ // tdf#131776: Check if strikeout is used in shape group texts
+ xmlDocUniquePtr pXml = parseExport("word/document.xml");
+
+ // double strike (dstrike)
+ // no "val" attribute
+ assertXPath(pXml, "/w:document/w:body/w:p/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wpg:wgp/"
+ "wps:wsp[1]/wps:txbx/w:txbxContent/w:p/w:r/w:rPr/w:dstrike");
+ assertXPathNoAttribute(pXml, "/w:document/w:body/w:p/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wpg:wgp/"
+ "wps:wsp[1]/wps:txbx/w:txbxContent/w:p/w:r/w:rPr/w:dstrike", "val");
+ // "val" attribute is true, this is used in this test file. However, LO is going to export this element without the "val" attribute
+ // because if the element appears, but without an attribute its "val" true by default.
+ assertXPath(pXml, "/w:document/w:body/w:p/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wpg:wgp/"
+ "wps:wsp[2]/wps:txbx/w:txbxContent/w:p/w:r/w:rPr/w:dstrike");
+ assertXPathNoAttribute(pXml, "/w:document/w:body/w:p/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wpg:wgp/"
+ "wps:wsp[2]/wps:txbx/w:txbxContent/w:p/w:r/w:rPr/w:dstrike", "val");
+ // "val" attribute is false (this was missing, resulting the regression)
+ assertXPath(pXml, "/w:document/w:body/w:p/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wpg:wgp/"
+ "wps:wsp[3]/wps:txbx/w:txbxContent/w:p/w:r/w:rPr/w:dstrike", "val", "false");
+
+ // simple strike (strike)
+ // no "val" attribute
+ assertXPath(pXml, "/w:document/w:body/w:p/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wpg:wgp/"
+ "wps:wsp[4]/wps:txbx/w:txbxContent/w:p/w:r/w:rPr/w:strike");
+ assertXPathNoAttribute(pXml, "/w:document/w:body/w:p/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wpg:wgp/"
+ "wps:wsp[4]/wps:txbx/w:txbxContent/w:p/w:r/w:rPr/w:strike", "val");
+ // "val" attribute is true, this is used in this test file. However, LO is going to export this element without the "val" attribute
+ // because if the element appears, but without an attribute its "val" true by default.
+ assertXPath(pXml, "/w:document/w:body/w:p/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wpg:wgp/"
+ "wps:wsp[5]/wps:txbx/w:txbxContent/w:p/w:r/w:rPr/w:strike");
+ assertXPathNoAttribute(pXml, "/w:document/w:body/w:p/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wpg:wgp/"
+ "wps:wsp[5]/wps:txbx/w:txbxContent/w:p/w:r/w:rPr/w:strike", "val");
+ // "val" attribute is false
+ assertXPath(pXml, "/w:document/w:body/w:p/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wpg:wgp/"
+ "wps:wsp[6]/wps:txbx/w:txbxContent/w:p/w:r/w:rPr/w:strike", "val", "false");
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf131539)
+{
+ loadAndSave("tdf131539.odt");
+ CPPUNIT_ASSERT_EQUAL(2, getShapes());
+ CPPUNIT_ASSERT_EQUAL(1, getPages());
+ //The positions of OLE objects were not exported, check if now it is exported correctly
+ xmlDocUniquePtr p_XmlDoc = parseExport("word/document.xml");
+ CPPUNIT_ASSERT(p_XmlDoc);
+ OUString aXmlVal = getXPath(p_XmlDoc, "/w:document/w:body/w:p[4]/w:r[1]/w:object/v:shape", "style");
+ // This data was missing
+ CPPUNIT_ASSERT(aXmlVal.indexOf("margin-left:139.95")>-1);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testLineWidthRounding)
+{
+ loadAndSave("tdf126363_LineWidthRounding.docx");
+ // tdf#126363: check if line with stays the same after export
+ xmlDocUniquePtr pXml = parseExport("word/document.xml");
+ // this was 57240 (it differs from the original 57150, losing the preset line width)
+ assertXPath(pXml, "/w:document/w:body/w:p/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:ln", "w", "57150");
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf108505)
+{
+ loadAndReload("tdf108505.docx");
+ uno::Reference<text::XTextRange> xParagraph = getParagraph(3);
+ uno::Reference<text::XTextRange> xText
+ = getRun(xParagraph, 1, "Wrong font when alone on the line");
+
+ // Without the fix in place this would have become Times New Roman
+ CPPUNIT_ASSERT_EQUAL(
+ OUString("Trebuchet MS"),
+ getProperty<OUString>(xText, "CharFontName"));
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testRelativeAnchorHeightFromTopMarginHasHeader)
+{
+ loadAndReload("tdf123324_testRelativeAnchorHeightFromTopMarginHasHeader.docx");
+ // tdf#123324 The height was set relative to page print area top,
+ // but this was handled relative to page height.
+ // Note: page print area top = margin + header height.
+ // In this case the header exists.
+ xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+ assertXPath(pXmlDoc, "//anchored/SwAnchoredDrawObject/bounds", "height", "2551");
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testRelativeAnchorHeightFromTopMarginNoHeader)
+{
+ loadAndReload("tdf123324_testRelativeAnchorHeightFromTopMarginNoHeader.docx");
+ // tdf#123324 The height was set relative from top margin, but this was handled relative from page height.
+ // Note: the MSO Word margin = LO margin + LO header height.
+ // In this case the header does not exist, so MSO Word margin and LO Writer margin are the same.
+
+ // tdf#123324 The height was set relative to page print area top,
+ // but this was handled relative to page height.
+ // Note: page print area top = margin + header height.
+ // In this case the header does not exist, so OpenDocument and OOXML margins are the same.
+ xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+ assertXPath(pXmlDoc, "//anchored/SwAnchoredDrawObject/bounds", "height", "2551");
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testTdf64531)
+{
+ loadAndReload("tdf64531.docx");
+ xmlDocUniquePtr pXmlDoc= parseExport("word/document.xml");
+ OString sPathToTabs= "/w:document/w:body/w:sdt/w:sdtContent/w:p[2]/w:pPr/w:tabs/";
+ assertXPath(pXmlDoc, sPathToTabs+"w:tab[1]", "pos","720");
+ assertXPath(pXmlDoc, sPathToTabs+"w:tab[2]", "pos","12950");
+}
+
+DECLARE_OOXMLEXPORT_TEST(testVmlShapeTextWordWrap, "tdf97618_testVmlShapeTextWordWrap.docx")
+{
+ // tdf#97618 The text wrapping of a shape was not handled in a canvas.
+ // TODO: fix export too
+ if (mbExported)
+ return;
+ xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+ if (!pXmlDoc)
+ return;
+ // The bound rect of shape will be wider if wrap does not work (the wrong value is 3167).
+ assertXPath(pXmlDoc, "//anchored/SwAnchoredDrawObject/bounds", "width", "2500");
+}
+
+DECLARE_OOXMLEXPORT_TEST(testVmlLineShapeMirroredX, "tdf97517_testVmlLineShapeMirroredX.docx")
+{
+ // tdf#97517 The "flip:x" was not handled for VML line shapes.
+ xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
+ if (!pXmlDoc)
+ return;
+ OUString sStyle = getXPath(pXmlDoc,
+ "/w:document/w:body/w:p[3]/w:r/mc:AlternateContent/mc:Fallback/w:pict/v:line",
+ "style");
+ CPPUNIT_ASSERT(sStyle.indexOf("flip:x") > 0);
+}
+
+DECLARE_OOXMLEXPORT_TEST(testVmlLineShapeMirroredY, "tdf137678_testVmlLineShapeMirroredY.docx")
+{
+ // tdf#137678 The "flip:y" was not handled for VML line shapes.
+ xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
+ if (!pXmlDoc)
+ return;
+ OUString sStyle = getXPath(pXmlDoc,
+ "/w:document/w:body/w:p[3]/w:r/mc:AlternateContent/mc:Fallback/w:pict/v:line",
+ "style");
+ CPPUNIT_ASSERT(sStyle.indexOf("flip:y") > 0);
+}
+
+CPPUNIT_TEST_FIXTURE(Test, testVmlLineShapeRotated)
+{
+ loadAndSave("tdf137765_testVmlLineShapeRotated.docx");
+ // tdf#137765 The "rotation" (in style attribute) was not handled correctly for VML line shapes.
+ xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
+ // it was 1.55pt,279.5pt
+ assertXPath(pXmlDoc,
+ "/w:document/w:body/w:p[3]/w:r/mc:AlternateContent/mc:Fallback/w:pict/v:line",
+ "from",
+ "-9pt,296.75pt");
+ // it was 25.5pt,317.8pt
+ assertXPath(pXmlDoc,
+ "/w:document/w:body/w:p[3]/w:r/mc:AlternateContent/mc:Fallback/w:pict/v:line",
+ "to",
+ "36.05pt,300.55pt");
+}
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */