1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  */
9 
10 #include <swmodeltestbase.hxx>
11 
12 #include <config_features.h>
13 
14 #include <com/sun/star/awt/Size.hpp>
15 #include <com/sun/star/beans/XPropertySet.hpp>
16 #include <com/sun/star/text/XFootnote.hpp>
17 #include <com/sun/star/text/XPageCursor.hpp>
18 #include <com/sun/star/text/XTextColumns.hpp>
19 #include <com/sun/star/text/XTextFramesSupplier.hpp>
20 #include <com/sun/star/text/XTextViewCursorSupplier.hpp>
21 #include <com/sun/star/graphic/XGraphic.hpp>
22 #include <com/sun/star/style/BreakType.hpp>
23 #include <com/sun/star/style/PageStyleLayout.hpp>
24 #include <com/sun/star/text/HoriOrientation.hpp>
25 #include <com/sun/star/text/RelOrientation.hpp>
26 #include <com/sun/star/text/VertOrientation.hpp>
27 #include <com/sun/star/text/WrapTextMode.hpp>
28 #include <com/sun/star/view/XFormLayerAccess.hpp>
29 #include <com/sun/star/view/XViewSettingsSupplier.hpp>
30 #include <com/sun/star/view/XSelectionSupplier.hpp>
31 #include <com/sun/star/style/LineSpacing.hpp>
32 #include <com/sun/star/style/LineSpacingMode.hpp>
33 #include <com/sun/star/style/ParagraphAdjust.hpp>
34 #include <com/sun/star/drawing/XControlShape.hpp>
35 #include <com/sun/star/text/TextContentAnchorType.hpp>
36 #include <com/sun/star/packages/zip/ZipFileAccess.hpp>
37 #include <com/sun/star/text/XTextTable.hpp>
38 
39 #include <sfx2/docfile.hxx>
40 #include <sfx2/docfilt.hxx>
41 #include <comphelper/processfactory.hxx>
42 #include <tools/UnitConversion.hxx>
43 
44 #include <docsh.hxx>
45 #include <ftninfo.hxx>
46 #include <unotxdoc.hxx>
47 
48 class Test : public SwModelTestBase
49 {
50 public:
Test()51     Test() : SwModelTestBase("/sw/qa/extras/ooxmlexport/data/", "Office Open XML Text") {}
52 
53 protected:
54     /**
55      * Denylist handling
56      */
mustTestImportOf(const char * filename) const57     bool mustTestImportOf(const char* filename) const override {
58         // If the testcase is stored in some other format, it's pointless to test.
59         return OString(filename).endsWith(".docx");
60     }
61 };
62 
63 class DocmTest : public SwModelTestBase
64 {
65 public:
DocmTest()66     DocmTest()
67         : SwModelTestBase("/sw/qa/extras/ooxmlexport/data/", "MS Word 2007 XML VBA")
68     {
69     }
70 };
71 
72 DECLARE_OOXMLEXPORT_TEST(testFdo55381, "fdo55381.docx")
73 {
74     CPPUNIT_ASSERT_EQUAL(4, getPages());
75     //TODO: frames not located on the correct pages
76 }
77 
78 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testDocm, "hello.docm")
79 {
80     // Make sure that we check the name of the export filter.
81     // This was application/vnd.ms-word.document.macroEnabled.main+xml when the
82     // name of the import filter was checked.
83     xmlDocUniquePtr pXmlDoc = parseExport("[Content_Types].xml");
84     assertXPath(pXmlDoc,
85                 "/ContentType:Types/ContentType:Override[@PartName='/word/document.xml']",
86                 "ContentType",
87                 "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml");
88 }
89 
90 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testDefaultContentTypes, "fdo55381.docx")
91 {
92     xmlDocUniquePtr pXmlDoc = parseExport("[Content_Types].xml");
93     assertXPath(pXmlDoc,
94                 "/ContentType:Types/ContentType:Default[@Extension='xml']",
95                 "ContentType",
96                 "application/xml");
97 
98     assertXPath(pXmlDoc,
99                 "/ContentType:Types/ContentType:Default[@Extension='rels']",
100                 "ContentType",
101                 "application/vnd.openxmlformats-package.relationships+xml");
102 
103     assertXPath(pXmlDoc,
104                 "/ContentType:Types/ContentType:Default[@Extension='png']",
105                 "ContentType",
106                 "image/png");
107 
108     assertXPath(pXmlDoc,
109                 "/ContentType:Types/ContentType:Default[@Extension='jpeg']",
110                 "ContentType",
111                 "image/jpeg");
112 }
113 
114 DECLARE_SW_ROUNDTRIP_TEST(testDocmSave, "hello.docm", nullptr, DocmTest)
115 {
116     // This was
117     // application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml,
118     // we used the wrong content type for .docm files.
119     if (xmlDocUniquePtr pXmlDoc = parseExport("[Content_Types].xml"))
120         assertXPath(pXmlDoc,
121                     "/ContentType:Types/ContentType:Override[@PartName='/word/document.xml']",
122                     "ContentType",
123                     "application/vnd.ms-word.document.macroEnabled.main+xml");
124 }
125 
126 DECLARE_SW_ROUNDTRIP_TEST(testBadDocm, "bad.docm", nullptr, DocmTest)
127 {
128     SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument *>(mxComponent.get());
129     CPPUNIT_ASSERT(pTextDoc);
130     // This was 'MS Word 2007 XML', broken docm files were not recognized.
131     CPPUNIT_ASSERT_EQUAL(OUString("MS Word 2007 XML VBA"), pTextDoc->GetDocShell()->GetMedium()->GetFilter()->GetName());
132 }
133 
134 DECLARE_OOXMLEXPORT_TEST(testTdf109063, "tdf109063.docx")
135 {
136     // This was 1, near-page-width table was imported as a TextFrame.
137     CPPUNIT_ASSERT_EQUAL(0, getShapes());
138 }
139 
140 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf108269, "tdf108269.docm")
141 {
142     uno::Reference<packages::zip::XZipFileAccess2> xNameAccess = packages::zip::ZipFileAccess::createWithURL(comphelper::getComponentContext(m_xSFactory), maTempFile.GetURL());
143     // This failed: VBA streams were not roundtripped via the doc-level
144     // grab-bag.
145     CPPUNIT_ASSERT(xNameAccess->hasByName("word/vbaProject.bin"));
146     CPPUNIT_ASSERT(xNameAccess->hasByName("word/vbaData.xml"));
147 }
148 
149 DECLARE_OOXMLEXPORT_TEST(testTdf92045, "tdf92045.docx")
150 {
151     // This was true, <w:effect w:val="none"/> resulted in setting the blinking font effect.
152     CPPUNIT_ASSERT_EQUAL(false, getProperty<bool>(getRun(getParagraph(1), 1), "CharFlash"));
153 }
154 
155 DECLARE_OOXMLEXPORT_TEST(testTdf95031, "tdf95031.docx")
156 {
157     // This was 494, in-numbering paragraph's automating spacing was handled as visible spacing, while it should not.
158     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), getProperty<sal_Int32>(getParagraph(2), "ParaBottomMargin"));
159     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), getProperty<sal_Int32>(getParagraph(3), "ParaTopMargin"));
160 }
161 
162 DECLARE_OOXMLEXPORT_TEST(testTdf106690, "tdf106690.docx")
163 {
164     // This was 0, numbering rules with automatic spacing meant 0
165     // before/autospacing for all text nodes, even for ones at the start/end of
166     // a numbered text node block.
167     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(494), getProperty<sal_Int32>(getParagraph(2), "ParaBottomMargin"));
168     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(494), getProperty<sal_Int32>(getParagraph(2), "ParaTopMargin"));
169 }
170 
171 DECLARE_OOXMLEXPORT_TEST(testTdf106690Cell, "tdf106690-cell.docx")
172 {
173     uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
174     uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY);
175     uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY);
176     uno::Reference<text::XTextRange> xCell(xTable->getCellByName("A1"), uno::UNO_QUERY);
177     // This was 0, bottom margin of the second paragraph in the A1 table cell
178     // had a reduced auto-space, just because of a next paragraph in the A2
179     // cell.
180     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(494), getProperty<sal_Int32>(getParagraphOfText(2, xCell->getText()), "ParaBottomMargin"));
181 }
182 
183 DECLARE_OOXMLEXPORT_TEST(testTdf122342, "tdf122342.docx")
184 {
185     // These were 494, style based numbering rules with automatic spacing meant 0
186     // before/autospacing for all text nodes, even for ones at the start/end of
187     // a numbered text node block.
188     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), getProperty<sal_Int32>(getParagraph(1), "ParaBottomMargin"));
189     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), getProperty<sal_Int32>(getParagraph(2), "ParaBottomMargin"));
190     // last list item
191     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(494), getProperty<sal_Int32>(getParagraph(3), "ParaBottomMargin"));
192 }
193 
194 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf132802, "tdf132802.docx")
195 {
196     xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
197     assertXPath(pXmlDoc, "/w:document/w:body/w:p[1]/w:pPr/w:spacing", "after", "0");
198     assertXPath(pXmlDoc, "/w:document/w:body/w:p[2]/w:pPr/w:spacing", "after", "0");
199     // This was 0 (list auto spacing is not zero before tables)
200     assertXPath(pXmlDoc, "/w:document/w:body/w:p[3]/w:pPr/w:spacing", "after", "280");
201     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[1]/w:tc/w:p[1]/w:pPr/w:spacing", "after", "0");
202     // This was 0 (list auto spacing is not zero at the end of table cells)
203     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[1]/w:tc/w:p[2]/w:pPr/w:spacing", "after", "280");
204     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[2]/w:tc/w:p[1]/w:pPr/w:spacing", "after", "280");
205     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[3]/w:tc/w:p[1]/w:pPr/w:spacing", "after", "280");
206     // This was 0 (list auto spacing is not zero at list end)
207     assertXPath(pXmlDoc, "/w:document/w:body/w:p[4]/w:pPr/w:spacing", "after", "280");
208 }
209 
210 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf132807, "tdf132807.docx")
211 {
212     xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
213     assertXPath(pXmlDoc, "/w:document/w:body/w:p[2]/w:pPr/w:spacing", "before", "280");
214     // This was 240 (list auto spacing is zero in lists)
215     assertXPath(pXmlDoc, "/w:document/w:body/w:p[3]/w:pPr/w:spacing", "before", "0");
216     assertXPath(pXmlDoc, "/w:document/w:body/w:p[4]/w:pPr/w:spacing", "before", "0");
217 
218     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[1]/w:tc/w:p[1]/w:pPr/w:spacing", "before", "0");
219     // This was 240 (list auto spacing is zero in lists)
220     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[1]/w:tc/w:p[2]/w:pPr/w:spacing", "before", "0");
221 
222     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[2]/w:tc/w:p[1]/w:pPr/w:spacing", "before", "0");
223     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[2]/w:tc/w:p[2]/w:pPr/w:spacing", "before", "280");
224     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[3]/w:tc/w:p[1]/w:pPr/w:spacing", "before", "0");
225     assertXPath(pXmlDoc, "/w:document/w:body/w:p[5]/w:pPr/w:spacing", "before", "280");
226 }
227 
228 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf133052, "tdf133052.docx")
229 {
230     xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
231     // These were 240 (top auto spacing of list subitems are zero)
232     assertXPath(pXmlDoc, "/w:document/w:body/w:p[4]/w:pPr/w:spacing", "before", "0");
233     assertXPath(pXmlDoc, "/w:document/w:body/w:p[5]/w:pPr/w:spacing", "before", "0");
234     // in tables, too
235     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[1]/w:tc/w:p[2]/w:pPr/w:spacing", "before", "0");
236     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[1]/w:tc/w:p[3]/w:pPr/w:spacing", "before", "0");
237     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[1]/w:tc/w:p[4]/w:pPr/w:spacing", "before", "0");
238     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[1]/w:tc/w:p[5]/w:pPr/w:spacing", "before", "0");
239 }
240 
241 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf134648, "tdf134648.docx")
242 {
243     xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
244 
245     // list item with direct top auto spacing
246     assertXPath(pXmlDoc, "/w:document/w:body/w:p[1]/w:pPr/w:spacing", "after", "240");
247     assertXPath(pXmlDoc, "/w:document/w:body/w:p[1]/w:pPr/w:spacing", "beforeAutospacing", "1");
248 
249     // This was spacing w:after=200, but bottom auto spacing of first list subitem is zero
250     assertXPath(pXmlDoc, "/w:document/w:body/w:p[2]/w:pPr/w:spacing", 0);
251 }
252 
253 DECLARE_OOXMLEXPORT_TEST(testTdf129575_directBefore, "tdf129575-directBefore.docx")
254 {
255     uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
256     uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY);
257     uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY);
258     uno::Reference<text::XTextRange> xCell(xTable->getCellByName("A1"), uno::UNO_QUERY);
259     // direct paragraph formatting
260     // This was 212 twips from the table style, but always direct paragraph formatting wins, in the case of the default 0 margin, too
261     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), getProperty<sal_Int32>(getParagraphOfText(1, xCell->getText()), "ParaTopMargin"));
262     // default margin
263     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), getProperty<sal_Int32>(getParagraphOfText(1, xCell->getText()), "ParaBottomMargin"));
264 }
265 
266 DECLARE_OOXMLEXPORT_TEST(testTdf129575_directAfter, "tdf129575-directAfter.docx")
267 {
268     uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
269     uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY);
270     uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY);
271     uno::Reference<text::XTextRange> xCell(xTable->getCellByName("A1"), uno::UNO_QUERY);
272     // from table style
273     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(212), getProperty<sal_Int32>(getParagraphOfText(1, xCell->getText()), "ParaTopMargin"));
274     // direct paragraph formatting
275     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), getProperty<sal_Int32>(getParagraphOfText(1, xCell->getText()), "ParaBottomMargin"));
276 }
277 
278 DECLARE_OOXMLEXPORT_TEST(testTdf129575_styleAfter, "tdf129575-styleAfter.docx")
279 {
280     uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
281     uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY);
282     uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY);
283     uno::Reference<text::XTextRange> xCell(xTable->getCellByName("A1"), uno::UNO_QUERY);
284     // direct paragraph formatting
285     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), getProperty<sal_Int32>(getParagraphOfText(1, xCell->getText()), "ParaTopMargin"));
286     // from table style
287     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(212), getProperty<sal_Int32>(getParagraphOfText(1, xCell->getText()), "ParaBottomMargin"));
288 }
289 
290 DECLARE_OOXMLEXPORT_TEST(testTdf129575_docDefault, "tdf129575-docDefault.docx")
291 {
292     uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
293     uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY);
294     uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY);
295     uno::Reference<text::XTextRange> xCell(xTable->getCellByName("A1"), uno::UNO_QUERY);
296     // docDefault defines both bottom margin and line spacing, but
297     // applied bottom margin values are based on non-docDefault paragraph styles, line spacing is based on table style
298 
299     // docDefault: <w:spacing w:after="160" w:line="320" w:lineRule="auto"/>
300     // table style: <w:spacing w:after="0" w:line="240" w:lineRule="auto"/> (single line space, overwriting bigger docDefault)
301 
302     // Paragraph style Normal: <w:spacing w:after="160"/> (same as docDefault),
303     // table style based single line spacing
304     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(282), getProperty<sal_Int32>(getParagraphOfText(1, xCell->getText()), "ParaBottomMargin"));
305     style::LineSpacing aLineSpacing = getProperty<style::LineSpacing>(getParagraphOfText(1, xCell->getText()), "ParaLineSpacing");
306     CPPUNIT_ASSERT_EQUAL(sal_Int16(style::LineSpacingMode::PROP), aLineSpacing.Mode);
307     CPPUNIT_ASSERT_EQUAL(sal_Int16(100), aLineSpacing.Height);
308     // Heading 2: <w:spacing w:after="360"/> (different from docDefault),
309     // table style based single line spacing
310     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(635), getProperty<sal_Int32>(getParagraphOfText(2, xCell->getText()), "ParaBottomMargin"));
311     aLineSpacing = getProperty<style::LineSpacing>(getParagraphOfText(1, xCell->getText()), "ParaLineSpacing");
312     CPPUNIT_ASSERT_EQUAL(sal_Int16(style::LineSpacingMode::PROP), aLineSpacing.Mode);
313     CPPUNIT_ASSERT_EQUAL(sal_Int16(100), aLineSpacing.Height);
314 
315 }
316 
317 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf118812, "tdf118812_tableStyles-comprehensive.docx")
318 {
319     xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
320     // cell A1
321     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[1]/w:tc/w:p/w:pPr/w:pStyle", "val", "Normal");
322     assertXPathNoAttribute(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[1]/w:tc/w:p/w:pPr/w:spacing", "lineRule");
323     assertXPathNoAttribute(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[1]/w:tc/w:p/w:pPr/w:spacing", "line");
324     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[1]/w:tc/w:p/w:pPr/w:spacing", "before", "480");
325     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[1]/w:tc/w:p/w:pPr/w:spacing", "after", "20");
326     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[1]/w:tc/w:p/w:r[1]/w:rPr/w:color", 0);
327     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[1]/w:tc/w:p/w:r[1]/w:rPr/w:sz", "val", "16");
328     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[1]/w:tc/w:p/w:r[2]/w:rPr/w:rStyle", "val", "CharSubStyleDefaults");
329     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[1]/w:tc/w:p/w:r[2]/w:rPr/w:color", 0);
330     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[1]/w:tc/w:p/w:r[2]/w:rPr/w:sz", "val", "16");
331     // cell A2
332     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[2]/w:tc/w:p/w:pPr/w:pStyle", "val", "Normal");
333     assertXPathNoAttribute(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[2]/w:tc/w:p/w:pPr/w:spacing", "lineRule");
334     assertXPathNoAttribute(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[2]/w:tc/w:p/w:pPr/w:spacing", "line");
335     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[2]/w:tc/w:p/w:pPr/w:spacing", "before", "480");
336     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[2]/w:tc/w:p/w:pPr/w:spacing", "after", "20");
337     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[2]/w:tc/w:p/w:r[1]/w:rPr/w:color", 0);
338     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[2]/w:tc/w:p/w:r[1]/w:rPr/w:sz", "val", "16");
339     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[2]/w:tc/w:p/w:r[2]/w:rPr/w:rStyle", "val", "ParaSubStyleDefaultsChar");
340     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[2]/w:tc/w:p/w:r[2]/w:rPr/w:color", 0);
341     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[2]/w:tc/w:p/w:r[2]/w:rPr/w:sz", "val", "16");
342     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[2]/w:tc/w:p/w:r[3]/w:rPr/w:rStyle", "val", "CharSubStyleNormal");
343     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[2]/w:tc/w:p/w:r[3]/w:rPr/w:color", 0);
344     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[2]/w:tc/w:p/w:r[3]/w:rPr/w:sz", "val", "16");
345     // cell A3
346     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[3]/w:tc/w:p/w:pPr/w:pStyle", "val", "ParaSubStyleNormal");
347     assertXPathNoAttribute(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[3]/w:tc/w:p/w:pPr/w:spacing", "lineRule");
348     assertXPathNoAttribute(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[3]/w:tc/w:p/w:pPr/w:spacing", "line");
349     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[3]/w:tc/w:p/w:pPr/w:spacing", "before", "480");
350     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[3]/w:tc/w:p/w:pPr/w:spacing", "after", "280");
351     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[3]/w:tc/w:p/w:r[1]/w:rPr/w:color", 0);
352     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[3]/w:tc/w:p/w:r[1]/w:rPr/w:sz", 0);
353     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[3]/w:tc/w:p/w:r[2]/w:rPr/w:rStyle", "val", "CharSubStyleNormal");
354     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[3]/w:tc/w:p/w:r[2]/w:rPr/w:color", 0);
355     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[3]/w:tc/w:p/w:r[2]/w:rPr/w:sz", 0);
356     // cell A4
357     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[4]/w:tc/w:p/w:pPr/w:pStyle", "val", "ParaSubStyleDefaults");
358     assertXPathNoAttribute(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[4]/w:tc/w:p/w:pPr/w:spacing", "lineRule");
359     assertXPathNoAttribute(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[4]/w:tc/w:p/w:pPr/w:spacing", "line");
360     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[4]/w:tc/w:p/w:pPr/w:spacing", "before", "480");
361     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[4]/w:tc/w:p/w:pPr/w:spacing", "after", "200");
362     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[4]/w:tc/w:p/w:r[1]/w:rPr/w:color", 0);
363     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[4]/w:tc/w:p/w:r[1]/w:rPr/w:sz", 0);
364     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[4]/w:tc/w:p/w:r[2]/w:rPr/w:rStyle", "val", "CharSubStyleDefaults");
365     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[4]/w:tc/w:p/w:r[2]/w:rPr/w:color", 0);
366     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[4]/w:tc/w:p/w:r[2]/w:rPr/w:sz", 0);
367     // cell A5
368     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[5]/w:tc/w:p/w:pPr/w:pStyle", "val", "Normal");
369     assertXPathNoAttribute(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[5]/w:tc/w:p/w:pPr/w:spacing", "lineRule");
370     assertXPathNoAttribute(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[5]/w:tc/w:p/w:pPr/w:spacing", "line");
371     assertXPathNoAttribute(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[5]/w:tc/w:p/w:pPr/w:rPr", "color");
372     assertXPathNoAttribute(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[5]/w:tc/w:p/w:pPr/w:rPr", "sz");
373     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[5]/w:tc/w:p/w:pPr/w:spacing", "before", "480");
374     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[5]/w:tc/w:p/w:pPr/w:spacing", "after", "20");
375     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[5]/w:tc/w:p/w:r[1]/w:rPr/w:color", 1);
376     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[5]/w:tc/w:p/w:r[1]/w:rPr/w:color", "val", "AAAA00"); // all text in color
377     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[5]/w:tc/w:p/w:r[1]/w:rPr/w:sz", "val", "16");
378     // cell A6
379     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[6]/w:tc/w:p/w:pPr/w:pStyle", "val", "Normal");
380     assertXPathNoAttribute(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[6]/w:tc/w:p/w:pPr/w:spacing", "lineRule");
381     assertXPathNoAttribute(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[6]/w:tc/w:p/w:pPr/w:spacing", "line");
382     assertXPathNoAttribute(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[6]/w:tc/w:p/w:pPr/w:rPr", "color");
383     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[6]/w:tc/w:p/w:pPr/w:rPr/w:sz", "val", "16");
384     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[6]/w:tc/w:p/w:pPr/w:spacing", "before", "480");
385     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[6]/w:tc/w:p/w:pPr/w:spacing", "after", "20");
386     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[6]/w:tc/w:p/w:r[1]/w:rPr/w:color", 0);
387     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[6]/w:tc/w:p/w:r[1]/w:rPr/w:sz", "val", "16");
388     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[6]/w:tc/w:p/w:r[2]/w:rPr/w:color", 1);
389     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[6]/w:tc/w:p/w:r[2]/w:rPr/w:color", "val", "AAAA00");
390     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[6]/w:tc/w:p/w:r[2]/w:rPr/w:sz", "val", "16");
391 
392     // tdf#131070 keep paragraph style based right indentation with indentation of direct numbering
393     // cell A7 - This was <w:ind w:start="1440" w:hanging="0"/>
394     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[7]/w:tc/w:p/w:pPr/w:ind", 0);
395     // cell A8
396     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[8]/w:tc/w:p/w:pPr/w:ind", "start", "714");
397     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[8]/w:tc/w:p/w:pPr/w:ind", "end", "1701");
398     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[8]/w:tc/w:p/w:pPr/w:ind", "hanging", "357");
399     // cell A9
400     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[9]/w:tc/w:p/w:pPr/w:ind", "end", "1440");
401     // This was 1440
402     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[9]/w:tc/w:p/w:pPr/w:ind", "start", "720");
403     // This was 0
404     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[9]/w:tc/w:p/w:pPr/w:ind", "hanging", "360");
405 }
406 
407 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf107626, "tdf107626.odt")
408 {
409     CPPUNIT_ASSERT_EQUAL(1, getPages());
410     xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
411     // This was 2 (missing trailing cell in merged cell range)
412     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[3]/w:tc", 3);
413 }
414 
415 DECLARE_OOXMLEXPORT_TEST(testTdf106970, "tdf106970.docx")
416 {
417     // The second paragraph (first numbered one) had 0 bottom margin:
418     // autospacing was even collapsed between different numbering styles.
419     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(494), getProperty<sal_Int32>(getParagraph(2), "ParaBottomMargin"));
420     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), getProperty<sal_Int32>(getParagraph(3), "ParaBottomMargin"));
421     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(494), getProperty<sal_Int32>(getParagraph(4), "ParaBottomMargin"));
422 }
423 
424 DECLARE_OOXMLEXPORT_TEST(testTdf79272_strictDxa, "tdf79272_strictDxa.docx")
425 {
426     uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
427     uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY);
428     CPPUNIT_ASSERT_EQUAL(sal_Int32(4318), getProperty<sal_Int32>(xTables->getByIndex(0), "Width"));
429 
430     xmlDocUniquePtr pXmlDoc = parseExport("word/styles.xml");
431     if (!pXmlDoc)
432          return;
433     // Validation test: order of elements was wrong. Order was: insideH, end, insideV.
434     int nEnd = getXPathPosition(pXmlDoc, "/w:styles/w:style[@w:styleId='TableGrid']/w:tblPr/w:tblBorders", "end");
435     int nInsideH = getXPathPosition(pXmlDoc, "/w:styles/w:style[@w:styleId='TableGrid']/w:tblPr/w:tblBorders", "insideH");
436     int nInsideV = getXPathPosition(pXmlDoc, "/w:styles/w:style[@w:styleId='TableGrid']/w:tblPr/w:tblBorders", "insideV");
437     CPPUNIT_ASSERT(nEnd < nInsideH);
438     CPPUNIT_ASSERT(nInsideH < nInsideV);
439 }
440 
441 DECLARE_OOXMLEXPORT_TEST(testTdf109306, "tdf109306.docx")
442 {
443     uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
444     uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY);
445     // Both types of relative width specification (pct): simple integers (in fiftieths of percent)
446     // and floats with "%" unit specification must be treated correctly
447     CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xTables->getByIndex(0), "IsWidthRelative"));
448     CPPUNIT_ASSERT_EQUAL(sal_Int16(9), getProperty<sal_Int16>(xTables->getByIndex(0), "RelativeWidth"));
449 
450     CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xTables->getByIndex(1), "IsWidthRelative"));
451     CPPUNIT_ASSERT_EQUAL(sal_Int16(80), getProperty<sal_Int16>(xTables->getByIndex(1), "RelativeWidth"));
452 }
453 
454 DECLARE_OOXMLEXPORT_TEST(testKern, "kern.docx")
455 {
456     CPPUNIT_ASSERT(getProperty<bool>(getRun(getParagraph(1), 1), "CharAutoKerning"));
457     // This failed: kerning was also enabled for the second paragraph.
458     CPPUNIT_ASSERT(!getProperty<bool>(getRun(getParagraph(2), 1), "CharAutoKerning"));
459 
460     uno::Reference<beans::XPropertySet> xStyle(getStyles("ParagraphStyles")->getByName("Default Paragraph Style"), uno::UNO_QUERY);
461     //tdf107801: kerning normally isn't enabled by default for .docx
462     CPPUNIT_ASSERT_EQUAL_MESSAGE("AutoKern should be false", false, getProperty<bool>(xStyle, "CharAutoKerning"));
463 }
464 
465 DECLARE_OOXMLEXPORT_TEST(testTdf89377, "tdf89377_tableWithBreakBeforeParaStyle.docx")
466 {
467     // the paragraph style should set table's text-flow break-before-page
468     CPPUNIT_ASSERT_EQUAL( 3, getPages() );
469 
470     uno::Reference<beans::XPropertySet> xStyle(getStyles("ParagraphStyles")->getByName("Default Paragraph Style"), uno::UNO_QUERY);
471     //tdf107801: kerning info wasn't exported previously.
472     CPPUNIT_ASSERT_EQUAL_MESSAGE("AutoKern should be true", true, getProperty<bool>(xStyle, "CharAutoKerning"));
473 }
474 
475 DECLARE_OOXMLEXPORT_TEST(testTdf104420, "tdf104420_lostParagraph.docx")
476 {
477     // the add/remove dummy paragraph was losing an entire header and paragraph
478     CPPUNIT_ASSERT_EQUAL( 2, getPages() );
479 }
480 
481 DECLARE_OOXMLEXPORT_TEST(testTdf41542_borderlessPadding, "tdf41542_borderlessPadding.odt")
482 {
483     // the page style's borderless padding should force this to 3 pages, not 1
484     CPPUNIT_ASSERT_EQUAL( 3, getPages() );
485 }
486 
487 #if HAVE_MORE_FONTS
488 DECLARE_OOXMLEXPORT_TEST(tdf105490_negativeMargins, "tdf105490_negativeMargins.docx")
489 {
490     // negative margins should change to minimal margins, not default margins.
491     CPPUNIT_ASSERT_EQUAL( 1, getPages() );
492 }
493 #endif
494 
495 DECLARE_OOXMLEXPORT_TEST(testTdf97648_relativeWidth,"tdf97648_relativeWidth.docx")
496 {
497     CPPUNIT_ASSERT_DOUBLES_EQUAL( sal_Int32(7616), getShape(1)->getSize().Width, 10);
498     CPPUNIT_ASSERT_DOUBLES_EQUAL( sal_Int32(8001), getShape(2)->getSize().Width, 10);
499     CPPUNIT_ASSERT_DOUBLES_EQUAL( sal_Int32(4001), getShape(3)->getSize().Width, 10);
500     CPPUNIT_ASSERT_EQUAL( style::ParagraphAdjust_LEFT, static_cast<style::ParagraphAdjust>(getProperty<sal_Int16>(getParagraph(6), "ParaAdjust")) );
501     CPPUNIT_ASSERT_DOUBLES_EQUAL( sal_Int32(1600), getShape(4)->getSize().Width, 10);
502     CPPUNIT_ASSERT_EQUAL( style::ParagraphAdjust_RIGHT, static_cast<style::ParagraphAdjust>(getProperty<sal_Int16>(getParagraph(8), "ParaAdjust")) );
503 
504 
505     CPPUNIT_ASSERT_EQUAL( sal_Int32(0), getProperty<sal_Int32>(getShape(1), "LeftMargin") );
506     if (!mbExported)
507     {
508         CPPUNIT_ASSERT_EQUAL_MESSAGE("Text should wrap above/below the line", text::WrapTextMode_NONE, getProperty<text::WrapTextMode>(getShape(1), "Surround"));
509         CPPUNIT_ASSERT_EQUAL(text::HoriOrientation::CENTER, getProperty<sal_Int16>(getShape(2), "HoriOrient"));
510         CPPUNIT_ASSERT_EQUAL(text::HoriOrientation::RIGHT, getProperty<sal_Int16>(getShape(3), "HoriOrient"));
511         CPPUNIT_ASSERT_EQUAL(text::HoriOrientation::LEFT, getProperty<sal_Int16>(getShape(4), "HoriOrient"));
512     }
513 }
514 
515 DECLARE_OOXMLEXPORT_TEST(testTdf104061_tableSectionColumns,"tdf104061_tableSectionColumns.docx")
516 {
517     CPPUNIT_ASSERT_MESSAGE("There should be two or three pages", getPages() <= 3 );
518 
519     //tdf#95114 - follow style is Text Body - DOCX test
520     uno::Reference< beans::XPropertySet > properties(getStyles("ParagraphStyles")->getByName("annotation subject"), uno::UNO_QUERY);
521     CPPUNIT_ASSERT_EQUAL(OUString("annotation text"), getProperty<OUString>(properties, "FollowStyle"));
522 }
523 
524 DECLARE_OOXMLEXPORT_TEST(testTdf46940_dontEquallyDistributeColumns, "tdf46940_dontEquallyDistributeColumns.docx")
525 {
526     uno::Reference<text::XTextSectionsSupplier> xTextSectionsSupplier(mxComponent, uno::UNO_QUERY);
527     uno::Reference<container::XIndexAccess> xTextSections(xTextSectionsSupplier->getTextSections(), uno::UNO_QUERY);
528     CPPUNIT_ASSERT_EQUAL(false, getProperty<bool>(xTextSections->getByIndex(0), "DontBalanceTextColumns"));
529     // This was false, columns before a section-page-break were balanced.
530     CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xTextSections->getByIndex(2), "DontBalanceTextColumns"));
531     CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xTextSections->getByIndex(3), "DontBalanceTextColumns"));
532 }
533 
534 DECLARE_OOXMLEXPORT_TEST(testTdf98700_keepWithNext, "tdf98700_keepWithNext.odt")
535 {
536     CPPUNIT_ASSERT_EQUAL(2, getPages());
537     CPPUNIT_ASSERT_EQUAL_MESSAGE("Heading style keeps with next", true, getProperty<bool>(getParagraph(1), "ParaKeepTogether"));
538     CPPUNIT_ASSERT_EQUAL_MESSAGE("Default style doesn't keep with next", false, getProperty<bool>(getParagraph(2), "ParaKeepTogether"));
539     CPPUNIT_ASSERT_EQUAL_MESSAGE("Heading 1 style inherits keeps with next", true, getProperty<bool>(getParagraph(3), "ParaKeepTogether"));
540     CPPUNIT_ASSERT_EQUAL_MESSAGE("Heading 2 style disabled keep with next", false, getProperty<bool>(getParagraph(4), "ParaKeepTogether"));
541     CPPUNIT_ASSERT_EQUAL_MESSAGE("Text Body style toggled off keep with next", false, getProperty<bool>(getParagraph(5), "ParaKeepTogether"));
542 
543     //tdf#95114 - follow style is Text Body - ODT test
544     uno::Reference< beans::XPropertySet > properties(getStyles("ParagraphStyles")->getByName("Heading 1"), uno::UNO_QUERY);
545     CPPUNIT_ASSERT_EQUAL(OUString("Text body"), getProperty<OUString>(properties, "FollowStyle"));
546 }
547 
548 // base class to supply a helper method for testHFLinkToPrev
549 class testHFBase : public Test
550 {
551 protected:
552     OUString
getHFText(const uno::Reference<style::XStyle> & xPageStyle,const OUString & sPropName)553     getHFText(const uno::Reference<style::XStyle>& xPageStyle,
554               const OUString &sPropName)
555     {
556         auto xTextRange = getProperty< uno::Reference<text::XTextRange> >(
557             xPageStyle, sPropName);
558         return xTextRange->getString();
559     }
560 };
561 
562 DECLARE_SW_EXPORT_TEST(testHFLinkToPrev, "headerfooter-link-to-prev.docx", nullptr, testHFBase)
563 {
564     uno::Reference<container::XNameAccess> xPageStyles = getStyles("PageStyles");
565 
566     // get a page cursor
567     uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
568     uno::Reference<text::XTextViewCursorSupplier> xTextViewCursorSupplier(
569         xModel->getCurrentController(), uno::UNO_QUERY);
570     uno::Reference<text::XPageCursor> xCursor(
571         xTextViewCursorSupplier->getViewCursor(), uno::UNO_QUERY);
572 
573     // get LO page style for page 1, corresponding to docx section 1 first page
574     xCursor->jumpToFirstPage();
575     OUString pageStyleName = getProperty<OUString>(xCursor, "PageStyleName");
576     uno::Reference<style::XStyle> xPageStyle(
577         xPageStyles->getByName(pageStyleName), uno::UNO_QUERY);
578     // check page 1 header & footer text
579     CPPUNIT_ASSERT_EQUAL(OUString("First page header for all sections"),
580         getHFText(xPageStyle, "HeaderText"));
581     CPPUNIT_ASSERT_EQUAL(OUString("First page footer for section 1 only"),
582         getHFText(xPageStyle, "FooterText"));
583 
584     // get LO page style for page 2, corresponding to docx section 1
585     xCursor->jumpToPage(2);
586     pageStyleName = getProperty<OUString>(xCursor, "PageStyleName");
587     xPageStyle.set( xPageStyles->getByName(pageStyleName), uno::UNO_QUERY );
588     // check header & footer text
589     CPPUNIT_ASSERT_EQUAL(OUString("Even page header for section 1 only"),
590         getHFText(xPageStyle, "HeaderTextLeft"));
591     CPPUNIT_ASSERT_EQUAL(OUString("Even page footer for all sections"),
592         getHFText(xPageStyle, "FooterTextLeft"));
593     CPPUNIT_ASSERT_EQUAL(OUString("Odd page header for all sections"),
594         getHFText(xPageStyle, "HeaderText"));
595     CPPUNIT_ASSERT_EQUAL(OUString("Odd page footer for section 1 only"),
596         getHFText(xPageStyle, "FooterText"));
597 
598     // get LO page style for page 4, corresponding to docx section 2 first page
599     xCursor->jumpToPage(4);
600     pageStyleName = getProperty<OUString>(xCursor, "PageStyleName");
601     xPageStyle.set( xPageStyles->getByName(pageStyleName), uno::UNO_QUERY );
602     // check header & footer text
603     CPPUNIT_ASSERT_EQUAL(OUString("First page header for all sections"),
604         getHFText(xPageStyle, "HeaderText"));
605     CPPUNIT_ASSERT_EQUAL(OUString("First page footer for sections 2 and 3 only"),
606         getHFText(xPageStyle, "FooterText"));
607 
608     // get LO page style for page 5, corresponding to docx section 2
609     xCursor->jumpToPage(5);
610     pageStyleName = getProperty<OUString>(xCursor, "PageStyleName");
611     xPageStyle.set( xPageStyles->getByName(pageStyleName), uno::UNO_QUERY );
612     // check header & footer text
613     CPPUNIT_ASSERT_EQUAL(OUString("Even page header for sections 2 and 3 only"),
614         getHFText(xPageStyle, "HeaderTextLeft"));
615     CPPUNIT_ASSERT_EQUAL(OUString("Even page footer for all sections"),
616         getHFText(xPageStyle, "FooterTextLeft"));
617     CPPUNIT_ASSERT_EQUAL(OUString("Odd page header for all sections"),
618         getHFText(xPageStyle, "HeaderText"));
619     CPPUNIT_ASSERT_EQUAL(OUString("Odd page footer for sections 2 and 3 only"),
620         getHFText(xPageStyle, "FooterText"));
621 
622     // get LO page style for page 7, corresponding to docx section 3 first page
623     xCursor->jumpToPage(7);
624     pageStyleName = getProperty<OUString>(xCursor, "PageStyleName");
625     xPageStyle.set( xPageStyles->getByName(pageStyleName), uno::UNO_QUERY );
626     // check header & footer text
627     CPPUNIT_ASSERT_EQUAL(OUString("First page header for all sections"),
628         getHFText(xPageStyle, "HeaderText"));
629     CPPUNIT_ASSERT_EQUAL(OUString("First page footer for sections 2 and 3 only"),
630         getHFText(xPageStyle, "FooterText"));
631 
632     // get LO page style for page 8, corresponding to docx section 3
633     xCursor->jumpToPage(8);
634     pageStyleName = getProperty<OUString>(xCursor, "PageStyleName");
635     xPageStyle.set( xPageStyles->getByName(pageStyleName), uno::UNO_QUERY );
636     // check header & footer text
637     CPPUNIT_ASSERT_EQUAL(OUString("Even page header for sections 2 and 3 only"),
638         getHFText(xPageStyle, "HeaderTextLeft"));
639     CPPUNIT_ASSERT_EQUAL(OUString("Even page footer for all sections"),
640         getHFText(xPageStyle, "FooterTextLeft"));
641     CPPUNIT_ASSERT_EQUAL(OUString("Odd page header for all sections"),
642         getHFText(xPageStyle, "HeaderText"));
643     CPPUNIT_ASSERT_EQUAL(OUString("Odd page footer for sections 2 and 3 only"),
644         getHFText(xPageStyle, "FooterText"));
645 }
646 
647 DECLARE_OOXMLEXPORT_TEST(testRhbz988516, "rhbz988516.docx")
648 {
649     // The problem was that the list properties of the footer leaked into body
650     CPPUNIT_ASSERT_EQUAL(OUString(), getProperty<OUString>(getParagraph(1), "NumberingStyleName"));
651     CPPUNIT_ASSERT_EQUAL(OUString("Enclosure 3"), getParagraph(2)->getString());
652     CPPUNIT_ASSERT_EQUAL(OUString(), getProperty<OUString>(getParagraph(2), "NumberingStyleName"));
653     CPPUNIT_ASSERT_EQUAL(OUString(), getProperty<OUString>(getParagraph(3), "NumberingStyleName"));
654     CPPUNIT_ASSERT_EQUAL(OUString(), getProperty<OUString>(getParagraph(4), "NumberingStyleName"));
655 
656     // tdf#103975 The problem was that an empty paragraph with page break info was removed.
657     CPPUNIT_ASSERT_EQUAL( 2, getPages() );
658 }
659 
660 DECLARE_OOXMLEXPORT_TEST(testTdf103975_notPageBreakB, "tdf103975_notPageBreakB.docx")
661 {
662     // turn on View Formatting Marks to see these documents.
663     uno::Reference<beans::XPropertySet> xTextSection = getProperty< uno::Reference<beans::XPropertySet> >(getParagraph(1), "TextSection");
664     CPPUNIT_ASSERT(xTextSection.is());
665     uno::Reference<text::XTextColumns> xTextColumns = getProperty< uno::Reference<text::XTextColumns> >(xTextSection, "TextColumns");
666     CPPUNIT_ASSERT_EQUAL(sal_Int16(2), xTextColumns->getColumnCount());
667 
668     xTextSection = getProperty< uno::Reference<beans::XPropertySet> >(getParagraph(2), "TextSection");
669     CPPUNIT_ASSERT(xTextSection.is());
670     xTextColumns = getProperty< uno::Reference<text::XTextColumns> >(xTextSection, "TextColumns");
671     CPPUNIT_ASSERT_EQUAL(sal_Int16(2), xTextColumns->getColumnCount());
672 
673     xTextSection = getProperty< uno::Reference<beans::XPropertySet> >(getParagraph(3), "TextSection");
674     CPPUNIT_ASSERT(xTextSection.is());
675     xTextColumns = getProperty< uno::Reference<text::XTextColumns> >(xTextSection, "TextColumns");
676     CPPUNIT_ASSERT_EQUAL(sal_Int16(0), xTextColumns->getColumnCount());
677 
678     xTextSection = getProperty< uno::Reference<beans::XPropertySet> >(getParagraph(4), "TextSection");
679     CPPUNIT_ASSERT(xTextSection.is());
680     xTextColumns = getProperty< uno::Reference<text::XTextColumns> >(xTextSection, "TextColumns");
681     CPPUNIT_ASSERT_EQUAL(sal_Int16(0), xTextColumns->getColumnCount());
682 
683     CPPUNIT_ASSERT_EQUAL(style::BreakType_COLUMN_BEFORE, getProperty<style::BreakType>(getParagraph(2), "BreakType"));
684     CPPUNIT_ASSERT_EQUAL( 4, getParagraphs() );
685     CPPUNIT_ASSERT_EQUAL( 1, getPages() );
686 }
687 
688 DECLARE_OOXMLEXPORT_TEST(testTdf103975_notPageBreakC, "tdf103975_notPageBreakC.docx")
689 {
690     // turn on View Formatting Marks to see these documents.
691     uno::Reference<beans::XPropertySet> xTextSection = getProperty< uno::Reference<beans::XPropertySet> >(getParagraph(1), "TextSection");
692     CPPUNIT_ASSERT(xTextSection.is());
693     uno::Reference<text::XTextColumns> xTextColumns = getProperty< uno::Reference<text::XTextColumns> >(xTextSection, "TextColumns");
694     CPPUNIT_ASSERT_EQUAL(sal_Int16(2), xTextColumns->getColumnCount());
695 
696     xTextSection = getProperty< uno::Reference<beans::XPropertySet> >(getParagraph(2), "TextSection");
697     CPPUNIT_ASSERT(xTextSection.is());
698     xTextColumns = getProperty< uno::Reference<text::XTextColumns> >(xTextSection, "TextColumns");
699     CPPUNIT_ASSERT_EQUAL(sal_Int16(2), xTextColumns->getColumnCount());
700 
701     xTextSection = getProperty< uno::Reference<beans::XPropertySet> >(getParagraph(3), "TextSection");
702     CPPUNIT_ASSERT(xTextSection.is());
703     xTextColumns = getProperty< uno::Reference<text::XTextColumns> >(xTextSection, "TextColumns");
704     CPPUNIT_ASSERT_EQUAL(sal_Int16(0), xTextColumns->getColumnCount());
705 
706     xTextSection = getProperty< uno::Reference<beans::XPropertySet> >(getParagraph(4), "TextSection");
707     CPPUNIT_ASSERT(xTextSection.is());
708     xTextColumns = getProperty< uno::Reference<text::XTextColumns> >(xTextSection, "TextColumns");
709     CPPUNIT_ASSERT_EQUAL(sal_Int16(0), xTextColumns->getColumnCount());
710 
711     CPPUNIT_ASSERT_EQUAL(style::BreakType_COLUMN_BEFORE, getProperty<style::BreakType>(getParagraph(2), "BreakType"));
712     CPPUNIT_ASSERT_EQUAL( 4, getParagraphs() );
713     CPPUNIT_ASSERT_EQUAL( 1, getPages() );
714 }
715 
716 DECLARE_OOXMLEXPORT_TEST(testTdf103975_notPageBreakD, "tdf103975_notPageBreakD.docx")
717 {
718     // The problem was that the column break was moving outside of the columns, making a page break.
719     CPPUNIT_ASSERT_EQUAL(style::BreakType_COLUMN_BEFORE, getProperty<style::BreakType>(getParagraph(2), "BreakType"));
720     CPPUNIT_ASSERT_EQUAL( 1, getPages() );
721 }
722 
723 DECLARE_OOXMLEXPORT_TEST(testTdf103975_notPageBreakE, "tdf103975_notPageBreakE.docx")
724 {
725     // The problem was that the column break was getting lost.
726     CPPUNIT_ASSERT_EQUAL(style::BreakType_COLUMN_BEFORE, getProperty<style::BreakType>(getParagraph(2), "BreakType"));
727 }
728 
729 DECLARE_OOXMLEXPORT_TEST(testTdf112352_nextPageColumns, "tdf112352_nextPageColumns.docx")
730 {
731     uno::Reference<beans::XPropertySet> xTextSection = getProperty< uno::Reference<beans::XPropertySet> >(getParagraph(2), "TextSection");
732     uno::Reference<text::XTextColumns> xTextColumns = getProperty< uno::Reference<text::XTextColumns> >(xTextSection, "TextColumns");
733     CPPUNIT_ASSERT_EQUAL(sal_Int16(2), xTextColumns->getColumnCount());
734 
735     xTextSection = getProperty< uno::Reference<beans::XPropertySet> >(getParagraph(3), "TextSection");
736     xTextColumns = getProperty< uno::Reference<text::XTextColumns> >(xTextSection, "TextColumns");
737     CPPUNIT_ASSERT_EQUAL(sal_Int16(0), xTextColumns->getColumnCount());
738 }
739 
740 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf109310_endnoteStyleForMSO, "tdf109310_endnoteStyleForMSO.docx")
741 {
742     xmlDocUniquePtr pXmlDoc = parseExport("word/endnotes.xml");
743     // Check w:rStyle element has w:val attribute - note that w: is not specified for attribute
744     assertXPath(pXmlDoc, "/w:endnotes/w:endnote[@w:id='2']/w:p/w:r[1]/w:rPr/w:rStyle", "val",
745                 "EndnoteCharacters");
746 }
747 
748 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf103389, "tdf103389.docx")
749 {
750     xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
751     // No geometry was exported for the second canvas
752     // Check both canvases' geometry
753     assertXPath(pXmlDoc, "/w:document/w:body/w:p[1]/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:inline/a:graphic/a:graphicData/wpg:wgp/wps:wsp/wps:spPr/a:prstGeom", "prst", "rect");
754     assertXPath(pXmlDoc, "/w:document/w:body/w:p[2]/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:inline/a:graphic/a:graphicData/wpg:wgp/wps:wsp/wps:spPr/a:prstGeom", "prst", "rect");
755 }
756 
757 DECLARE_OOXMLEXPORT_TEST(testTdf84678, "tdf84678.docx")
758 {
759     // This was 0, left margin inside a shape+text wasn't imported from DOCX.
760     // 360000 EMU, but layout uses twips.
761     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(567), parseDump("/root/page/body/txt/anchored/fly/infos/prtBounds", "left").toInt32());
762 
763 }
764 
765 DECLARE_OOXMLEXPORT_TEST(testTdf103544, "tdf103544.docx")
766 {
767     // We have two shapes: a frame and an image
768     CPPUNIT_ASSERT_EQUAL(2, getShapes());
769 
770     // Image was lost because of the frame export
771     uno::Reference<beans::XPropertySet> xImage(getShape(1), uno::UNO_QUERY);
772     auto xGraphic = getProperty<uno::Reference<graphic::XGraphic> >(xImage, "Graphic");
773     CPPUNIT_ASSERT(xGraphic.is());
774 }
775 
776 DECLARE_OOXMLEXPORT_TEST(testTdf103573, "tdf103573.docx")
777 {
778     // Relative positions to the left or right margin (MS Word naming) was not handled.
779     uno::Reference<beans::XPropertySet> xShapeProperties( getShape(1), uno::UNO_QUERY );
780     sal_Int16 nValue;
781     xShapeProperties->getPropertyValue("HoriOrient") >>= nValue;
782     CPPUNIT_ASSERT_EQUAL_MESSAGE("Not centered horizontally", text::HoriOrientation::CENTER, nValue);
783     xShapeProperties->getPropertyValue("HoriOrientRelation") >>= nValue;
784     CPPUNIT_ASSERT_EQUAL_MESSAGE("Not centered horizontally relatively to left page border", text::RelOrientation::PAGE_LEFT, nValue);
785 
786     xShapeProperties.set( getShape(2), uno::UNO_QUERY );
787     xShapeProperties->getPropertyValue("HoriOrient") >>= nValue;
788     CPPUNIT_ASSERT_EQUAL_MESSAGE("Not centered horizontally", text::HoriOrientation::CENTER, nValue);
789     xShapeProperties->getPropertyValue("HoriOrientRelation") >>= nValue;
790     CPPUNIT_ASSERT_EQUAL_MESSAGE("Not centered horizontally relatively to right page border", text::RelOrientation::PAGE_RIGHT, nValue);
791 }
792 
793 DECLARE_OOXMLEXPORT_TEST(testTdf106132, "tdf106132.docx")
794 {
795     uno::Reference<beans::XPropertySet> xShape(getShapeByName(u"Frame1"), uno::UNO_QUERY);
796     // This was 250, <wps:bodyPr ... rIns="0" ...> was ignored for an outer shape.
797     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), getProperty<sal_Int32>(xShape, "TextRightDistance"));
798 }
799 
800 DECLARE_OOXMLEXPORT_TEST(testBnc519228OddBreaks, "bnc519228_odd-breaksB.docx")
801 {
802     // Check that all the normal styles are not set as right-only, those should be only those used after odd page breaks.
803     uno::Reference<beans::XPropertySet> defaultStyle(getStyles("PageStyles")->getByName("Standard"), uno::UNO_QUERY);
804     CPPUNIT_ASSERT_EQUAL(uno::makeAny(style::PageStyleLayout_ALL), defaultStyle->getPropertyValue("PageStyleLayout"));
805     uno::Reference<beans::XPropertySet> firstPage( getStyles("PageStyles")->getByName("First Page"), uno::UNO_QUERY );
806     CPPUNIT_ASSERT_EQUAL(uno::makeAny(style::PageStyleLayout_ALL), firstPage->getPropertyValue("PageStyleLayout"));
807 
808     OUString page1StyleName = getProperty<OUString>( getParagraph( 1, "This is the first page." ), "PageDescName");
809     uno::Reference<beans::XPropertySet> page1Style(getStyles("PageStyles")->getByName(page1StyleName), uno::UNO_QUERY);
810     CPPUNIT_ASSERT_EQUAL(uno::makeAny(style::PageStyleLayout_RIGHT), page1Style->getPropertyValue("PageStyleLayout"));
811     getParagraphOfText( 1, getProperty< uno::Reference<text::XText> >(page1Style, "HeaderText"), "This is the header for odd pages");
812 
813     // Page2 comes from follow of style for page 1 and should be a normal page. Also check the two page style have the same properties,
814     // since page style for page1 was created from page style for page 2.
815     OUString page2StyleName = getProperty<OUString>( page1Style, "FollowStyle" );
816     uno::Reference<beans::XPropertySet> page2Style(getStyles("PageStyles")->getByName(page2StyleName), uno::UNO_QUERY);
817     CPPUNIT_ASSERT_EQUAL(uno::makeAny(style::PageStyleLayout_ALL), page2Style->getPropertyValue("PageStyleLayout"));
818     getParagraphOfText( 1, getProperty< uno::Reference<text::XText> >(page2Style, "HeaderTextLeft"), "This is the even header");
819     getParagraphOfText( 1, getProperty< uno::Reference<text::XText> >(page2Style, "HeaderTextRight"), "This is the header for odd pages");
820     CPPUNIT_ASSERT_EQUAL(getProperty<sal_Int32>(page1Style, "TopMargin"), getProperty<sal_Int32>(page2Style, "TopMargin"));
821 
822     OUString page5StyleName = getProperty<OUString>( getParagraph( 4, "Then an odd break after an odd page, should lead us to page #5." ), "PageDescName");
823     uno::Reference<beans::XPropertySet> page5Style(getStyles("PageStyles")->getByName(page5StyleName), uno::UNO_QUERY);
824     CPPUNIT_ASSERT_EQUAL(uno::makeAny(style::PageStyleLayout_RIGHT), page5Style->getPropertyValue("PageStyleLayout"));
825     getParagraphOfText( 1, getProperty< uno::Reference<text::XText> >(page5Style, "HeaderText"), "This is the header for odd pages");
826 }
827 
828 DECLARE_OOXMLEXPORT_TEST(testTdf79329, "tdf79329.docx")
829 {
830     uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
831     uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY);
832     // This was 1: only the inner, not the outer table was created.
833     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2), xTables->getCount());
834 }
835 
836 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf103982, "tdf103982.docx")
837 {
838     xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
839     sal_Int32 nDistB = getXPath(pXmlDoc, "//wp:anchor", "distB").toInt32();
840     // This was -260350, which is not a valid value for an unsigned type.
841     CPPUNIT_ASSERT(nDistB >= 0);
842 
843     // tdf#115670 the shadow should not be enabled (no on="t")
844     uno::Reference<beans::XPropertySet> xPropertySet(getShape(1), uno::UNO_QUERY);
845     CPPUNIT_ASSERT(!getProperty<bool>(xPropertySet, "Shadow"));
846 }
847 
848 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf104115, "tdf104115.docx")
849 {
850     xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
851     // This found 0 nodes: the custom geometry was not written for the Bezier
852     // curve -> Word refused to open the document.
853     assertXPath(pXmlDoc, "//a:custGeom", 1);
854 }
855 
856 DECLARE_OOXMLEXPORT_TEST(testTdf103651, "tdf103651.docx")
857 {
858     uno::Reference<beans::XPropertySet> xTextField = getProperty< uno::Reference<beans::XPropertySet> >(getRun(getParagraph(1), 1), "TextField");
859     OUString sContent;
860     xTextField->getPropertyValue("Content") >>= sContent;
861     // Comment in the first paragraph should not have smiley ( 0xf04a ).
862     CPPUNIT_ASSERT_EQUAL( sal_Int32( -1 ) , sContent.indexOf( u'\xf04a' ));
863 
864     // this document has a w:kern setting in the DocDefault character properties.  Ensure it applies.
865     CPPUNIT_ASSERT(getProperty<bool>(getRun(getParagraph(1), 1), "CharAutoKerning"));
866 }
867 
868 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf99227, "tdf99227.docx")
869 {
870     // A drawing anchored as character to a footnote caused write past end of document.xml at export to docx.
871     // After that, importing after export failed with
872     // SAXParseException: '[word/document.xml line 2]: Extra content at the end of the document', Stream 'word / document.xml',
873     // and before commit ebf767eeb2a169ba533e1b2ffccf16f41d95df35, the drawing was silently lost.
874     xmlDocUniquePtr pXmlDoc = parseExport("word/footnotes.xml");
875 
876     assertXPath(pXmlDoc, "//w:footnote/w:p/w:r/w:drawing", 1);
877 }
878 
879 DECLARE_OOXMLEXPORT_TEST(testTdf37153, "tdf37153_considerWrapOnObjPos.docx")
880 {
881     CPPUNIT_ASSERT_EQUAL(text::WrapTextMode_THROUGH, getProperty<text::WrapTextMode>(getShape(1), "Surround"));
882 
883     uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
884     uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY);
885     uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY);
886     CPPUNIT_ASSERT_EQUAL(text::VertOrientation::BOTTOM, getProperty<sal_Int16>(xTable->getCellByName("A1"), "VertOrient"));
887 
888     //For MSO compatibility, the textbox should be at the top of the cell, not at the bottom - despite VertOrientation::BOTTOM
889     xmlDocUniquePtr pXmlDoc = parseLayoutDump();
890     sal_Int32 nFlyTop  = getXPath(pXmlDoc, "/root/page/body/tab/row/cell[1]/txt/anchored/fly/infos/bounds", "top").toInt32();
891     CPPUNIT_ASSERT_MESSAGE("FlyTop should be 2865, not 5649", nFlyTop < sal_Int32(3000));
892     sal_Int32 nTextTop  = getXPath(pXmlDoc, "/root/page/body/tab/row/cell[2]/txt[1]/infos/bounds", "top").toInt32();
893     CPPUNIT_ASSERT_MESSAGE("TextTop should be 3856", nTextTop > 3000);
894 }
895 
896 DECLARE_OOXMLEXPORT_TEST(testTdf112446_frameStyle, "tdf112446_frameStyle.docx")
897 {
898     CPPUNIT_ASSERT_EQUAL(text::HoriOrientation::NONE, getProperty<sal_Int16>(getShape(1), "HoriOrient"));
899 }
900 
901 DECLARE_OOXMLEXPORT_TEST(testTdf82173_footnoteStyle, "tdf82173_footnoteStyle.docx")
902 {
903     uno::Reference<text::XFootnotesSupplier> xFootnotesSupplier(mxComponent, uno::UNO_QUERY);
904     uno::Reference<container::XIndexAccess> xFootnotes = xFootnotesSupplier->getFootnotes();
905 
906     uno::Reference<text::XText> xFootnoteText;
907     xFootnotes->getByIndex(0) >>= xFootnoteText;
908     // This was footnote text, which didn't match with newly created footnotes
909     CPPUNIT_ASSERT_EQUAL(OUString("Footnote"), getProperty<OUString>(getParagraphOfText(1, xFootnoteText), "ParaStyleName"));
910 
911     uno::Reference<beans::XPropertySet> xPageStyle(getStyles("CharacterStyles")->getByName("Footnote Characters"), uno::UNO_QUERY);
912     CPPUNIT_ASSERT_EQUAL( sal_Int32(58),       getProperty< sal_Int32 >(xPageStyle, "CharEscapementHeight") );
913     CPPUNIT_ASSERT_EQUAL( sal_Int32(0x00FF00), getProperty< sal_Int32 >(xPageStyle, "CharColor") );
914 
915     xPageStyle.set(getStyles("CharacterStyles")->getByName("Footnote anchor"), uno::UNO_QUERY);
916     CPPUNIT_ASSERT_EQUAL( sal_Int32(58),       getProperty< sal_Int32 >(xPageStyle, "CharEscapementHeight") );
917     CPPUNIT_ASSERT_EQUAL( sal_Int32(0x00FF00), getProperty< sal_Int32 >(xPageStyle, "CharColor") );
918 
919     //tdf#118361 - in RTL locales, the footnote separator should still be left aligned.
920     uno::Any aPageStyle = getStyles("PageStyles")->getByName("Standard");
921     CPPUNIT_ASSERT_EQUAL_MESSAGE("Footnote separator LTR", sal_Int16(0), getProperty<sal_Int16>(aPageStyle, "FootnoteLineAdjust"));
922 }
923 
924 DECLARE_OOXMLEXPORT_TEST(testTdf82173_endnoteStyle, "tdf82173_endnoteStyle.docx")
925 {
926     uno::Reference<text::XEndnotesSupplier> xEndnotesSupplier(mxComponent, uno::UNO_QUERY);
927     uno::Reference<container::XIndexAccess> xEndnotes = xEndnotesSupplier->getEndnotes();
928     uno::Reference<text::XFootnote> xEndnote;
929     xEndnotes->getByIndex(0) >>= xEndnote;
930     // character properties were previously not assigned to the footnote/endnote in-text anchor.
931     CPPUNIT_ASSERT_EQUAL( 24.0f, getProperty< float >(xEndnote->getAnchor(), "CharHeight") );
932     CPPUNIT_ASSERT_EQUAL( sal_Int32(0xFF0000), getProperty< sal_Int32 >(xEndnote->getAnchor(), "CharColor") );
933 
934     uno::Reference<text::XText> xEndnoteText;
935     xEndnotes->getByIndex(0) >>= xEndnoteText;
936     // This was Endnote Symbol
937     CPPUNIT_ASSERT_EQUAL(OUString("Endnote"), getProperty<OUString>(getParagraphOfText(1, xEndnoteText), "ParaStyleName"));
938     CPPUNIT_ASSERT_EQUAL(sal_Int32(0x993300), getProperty<sal_Int32>(getParagraphOfText(1, xEndnoteText), "CharColor"));
939 
940     uno::Reference<beans::XPropertySet> xPageStyle(getStyles("CharacterStyles")->getByName("Endnote Characters"), uno::UNO_QUERY);
941     CPPUNIT_ASSERT_EQUAL( sal_Int32(58),       getProperty< sal_Int32 >(xPageStyle, "CharEscapementHeight") );
942     CPPUNIT_ASSERT_EQUAL( sal_Int32(0xFF00FF), getProperty< sal_Int32 >(xPageStyle, "CharColor") );
943 
944     xPageStyle.set(getStyles("CharacterStyles")->getByName("Endnote anchor"), uno::UNO_QUERY);
945     CPPUNIT_ASSERT_EQUAL( sal_Int32(58),       getProperty< sal_Int32 >(xPageStyle, "CharEscapementHeight") );
946     CPPUNIT_ASSERT_EQUAL( sal_Int32(0xFF00FF), getProperty< sal_Int32 >(xPageStyle, "CharColor") );
947 }
948 
949 DECLARE_OOXMLEXPORT_TEST(testTdf55427_footnote2endnote, "tdf55427_footnote2endnote.odt")
950 {
951     CPPUNIT_ASSERT_EQUAL(4, getPages());
952     uno::Reference<beans::XPropertySet> xPageStyle(getStyles("ParagraphStyles")->getByName("Footnote"), uno::UNO_QUERY);
953     CPPUNIT_ASSERT_EQUAL_MESSAGE( "Footnote style is rose color", sal_Int32(0xFF007F), getProperty< sal_Int32 >(xPageStyle, "CharColor") );
954     xPageStyle.set(getStyles("ParagraphStyles")->getByName("Endnote"), uno::UNO_QUERY);
955     CPPUNIT_ASSERT_EQUAL_MESSAGE( "Endnote style is cyan3 color", sal_Int32(0x2BD0D2), getProperty< sal_Int32 >(xPageStyle, "CharColor") );
956 
957     SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
958     CPPUNIT_ASSERT(pTextDoc);
959     SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc();
960     // The footnote numbering type of ARABIC will not transfer over when those footnotes are converted to endnotes.
961     CPPUNIT_ASSERT_EQUAL_MESSAGE( "Footnote numbering type", SVX_NUM_ARABIC, pDoc->GetFootnoteInfo().m_aFormat.GetNumberingType() );
962     // The original document has a real endnote using ROMAN_LOWER numbering, so that setting MUST remain unchanged.
963     CPPUNIT_ASSERT_EQUAL_MESSAGE( "Endnote numbering type", SVX_NUM_ROMAN_LOWER, pDoc->GetEndNoteInfo().m_aFormat.GetNumberingType() );
964 
965     uno::Reference<text::XFootnotesSupplier> xFootnotesSupplier(mxComponent, uno::UNO_QUERY);
966     uno::Reference<container::XIndexAccess> xFootnotes = xFootnotesSupplier->getFootnotes();
967 
968     uno::Reference<text::XEndnotesSupplier> xEndnotesSupplier(mxComponent, uno::UNO_QUERY);
969     uno::Reference<container::XIndexAccess> xEndnotes = xEndnotesSupplier->getEndnotes();
970     uno::Reference<text::XFootnote> xEndnote;
971     xEndnotes->getByIndex(0) >>= xEndnote;
972     uno::Reference<text::XText> xEndnoteText;
973     xEndnotes->getByIndex(0) >>= xEndnoteText;
974 
975     // ODT footnote-at-document-end's closest DOCX match is an endnote, so the two imports will not exactly match by design.
976     if (!mbExported)
977     {
978         CPPUNIT_ASSERT_EQUAL_MESSAGE( "original footnote count", sal_Int32(5), xFootnotes->getCount() );
979         CPPUNIT_ASSERT_EQUAL_MESSAGE( "original endnote count", sal_Int32(1), xEndnotes->getCount() );
980 
981         uno::Reference<text::XFootnote> xFootnote;
982         xFootnotes->getByIndex(0) >>= xFootnote;
983         CPPUNIT_ASSERT_EQUAL_MESSAGE( "original footnote's number", OUString("1"), xFootnote->getAnchor()->getString() );
984         CPPUNIT_ASSERT_EQUAL_MESSAGE( "original endnote's number", OUString("i"), xEndnote->getAnchor()->getString() );
985 
986         uno::Reference<text::XText> xFootnoteText;
987         xFootnotes->getByIndex(0) >>= xFootnoteText;
988         CPPUNIT_ASSERT_EQUAL_MESSAGE( "original footnote style", OUString("Footnote"), getProperty<OUString>(getParagraphOfText(1, xFootnoteText), "ParaStyleName") );
989         CPPUNIT_ASSERT_EQUAL_MESSAGE( "original endnote style", OUString("Endnote"), getProperty<OUString>(getParagraphOfText(1, xEndnoteText), "ParaStyleName") );
990     }
991     else
992     {
993         // These asserted items are major differences in the conversion from footnote to endnote, NOT necessary conditions for a proper functioning document.
994         CPPUNIT_ASSERT_EQUAL_MESSAGE( "At-Document-End footnotes were converted into endnotes", sal_Int32(0), xFootnotes->getCount() );
995         CPPUNIT_ASSERT_EQUAL_MESSAGE( "At-Document-End footnotes became endnotes", sal_Int32(6), xEndnotes->getCount() );
996 
997         CPPUNIT_ASSERT_EQUAL_MESSAGE( "converted footnote's number", OUString("i"), xEndnote->getAnchor()->getString() );
998         xEndnotes->getByIndex(4) >>= xEndnote;
999         CPPUNIT_ASSERT_EQUAL_MESSAGE( "original endnote's new number", OUString("v"), xEndnote->getAnchor()->getString() );
1000 
1001         CPPUNIT_ASSERT_EQUAL_MESSAGE( "retained footnote style", OUString("Footnote"), getProperty<OUString>(getParagraphOfText(1, xEndnoteText), "ParaStyleName") );
1002         xEndnotes->getByIndex(4) >>= xEndnoteText;
1003         CPPUNIT_ASSERT_EQUAL_MESSAGE( "original endnote style", OUString("Endnote"), getProperty<OUString>(getParagraphOfText(1, xEndnoteText), "ParaStyleName") );
1004     }
1005 }
1006 
1007 DECLARE_OOXMLEXPORT_TEST(testTdf104162, "tdf104162.docx")
1008 {
1009     // This crashed: the comment field contained a table with a <w:hideMark/>.
1010     uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
1011     uno::Reference<container::XElementAccess> xTextFields(xTextFieldsSupplier->getTextFields());
1012     CPPUNIT_ASSERT(xTextFields->hasElements());
1013 }
1014 
1015 DECLARE_OOXMLEXPORT_TEST(testTdf104150, "tdf104150.docx")
1016 {
1017     uno::Reference<beans::XPropertySet> xPageStyle(getStyles("PageStyles")->getByName("Standard"), uno::UNO_QUERY);
1018     // This was 0xff0000, i.e. red: background shape wasn't ignored.
1019     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(-1), getProperty<sal_Int32>(xPageStyle, "BackColor"));
1020 }
1021 
1022 DECLARE_OOXMLEXPORT_TEST(testTdf103976, "tdf103976.docx")
1023 {
1024     uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
1025     uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY);
1026     uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY);
1027     uno::Reference<text::XTextRange> xCell(xTable->getCellByName("A1"), uno::UNO_QUERY);
1028     // This was 0, table style inheritance went wrong and w:afterLines had priority over w:after.
1029     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(convertTwipToMm100(60)), getProperty<sal_Int32>(getParagraphOfText(1, xCell->getText()), "ParaBottomMargin"));
1030 
1031     // tdf#116549: heading 2 style should not have a bottom border.
1032     uno::Reference<beans::XPropertySet> xStyle(getStyles("ParagraphStyles")->getByName("Heading 2"), uno::UNO_QUERY);
1033     table::BorderLine2 aBottomBorder = getProperty<table::BorderLine2>(xStyle, "BottomBorder");
1034     CPPUNIT_ASSERT_EQUAL(sal_uInt32(0), aBottomBorder.LineWidth);
1035 }
1036 
1037 DECLARE_OOXMLEXPORT_TEST(testTdf106001, "tdf106001.docx")
1038 {
1039     // This was 0 (1 on UI), while Word treats outliers as 100 (outlier = not in [1..600])
1040     CPPUNIT_ASSERT_EQUAL( static_cast<sal_Int16>( 100 ), getProperty<sal_Int16>(getRun(getParagraph(1), 1), "CharScaleWidth" ));
1041 }
1042 
1043 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf106001_2, "tdf106001-2.odt")
1044 {
1045     CPPUNIT_ASSERT_EQUAL(1, getPages());
1046     // In test ODT CharScaleWidth = 900, this was not changed upon OOXML export to stay in [1..600], now it's clamped to 600
1047     // Note: we disregard what's set in pPr / rPr and only care about r / rPr
1048     xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
1049     assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:r/w:rPr/w:w","val","600");
1050 }
1051 
1052 DECLARE_OOXMLEXPORT_TEST(testTdf99074, "tdf99074.docx")
1053 {
1054     uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
1055     uno::Reference<view::XViewSettingsSupplier> const xController(
1056         xModel->getCurrentController(), uno::UNO_QUERY);
1057     uno::Reference<beans::XPropertySet> const xViewSettings(
1058         xController->getViewSettings());
1059 
1060     // The behavior changed - Word 2013 and 2016 ignore this setting on
1061     // import, and instead honor the user's setting.
1062     // Let's ignore the <w:view w:val="web"/> too.
1063     CPPUNIT_ASSERT(!getProperty<bool>(xViewSettings, "ShowOnlineLayout"));
1064 }
1065 
1066 DECLARE_OOXMLEXPORT_TEST(testDefaultSectBreakCols, "default-sect-break-cols.docx")
1067 {
1068     // First problem: the first two paragraphs did not have their own text section, so the whole document had two columns.
1069     uno::Reference<beans::XPropertySet> xTextSection = getProperty< uno::Reference<beans::XPropertySet> >(getParagraph(1, "First."), "TextSection");
1070     CPPUNIT_ASSERT(xTextSection.is());
1071     uno::Reference<text::XTextColumns> xTextColumns = getProperty< uno::Reference<text::XTextColumns> >(xTextSection, "TextColumns");
1072     CPPUNIT_ASSERT_EQUAL(sal_Int16(2), xTextColumns->getColumnCount());
1073 
1074     // Second problem: the page style had two columns, while it shouldn't have any.
1075     uno::Reference<beans::XPropertySet> xPageStyle(getStyles("PageStyles")->getByName("Standard"), uno::UNO_QUERY);
1076     xTextColumns = getProperty< uno::Reference<text::XTextColumns> >(xPageStyle, "TextColumns");
1077     CPPUNIT_ASSERT_EQUAL(sal_Int16(0), xTextColumns->getColumnCount());
1078     // Check for the Column Separator value.It should be FALSE as the document does not contain separator line.
1079     bool bValue = getProperty< bool >(xTextColumns, "SeparatorLineIsOn");
1080     CPPUNIT_ASSERT(!bValue) ;
1081 }
1082 
1083 DECLARE_OOXMLEXPORT_TEST(testMultiColumnSeparator, "multi-column-separator-with-line.docx")
1084 {
1085     uno::Reference<beans::XPropertySet> xTextSection = getProperty< uno::Reference<beans::XPropertySet> >(getParagraph(1, "First data."), "TextSection");
1086     CPPUNIT_ASSERT(xTextSection.is());
1087     uno::Reference<text::XTextColumns> xTextColumns = getProperty< uno::Reference<text::XTextColumns> >(xTextSection, "TextColumns");
1088     CPPUNIT_ASSERT_EQUAL(sal_Int16(2), xTextColumns->getColumnCount());
1089     // Check for the Column Separator value.It should be TRUE as the document contains separator line.
1090     bool  bValue = getProperty< bool >(xTextColumns, "SeparatorLineIsOn");
1091     CPPUNIT_ASSERT(bValue);
1092 }
1093 
1094 DECLARE_OOXMLEXPORT_TEST(testUnbalancedColumns, "unbalanced-columns.docx")
1095 {
1096     uno::Reference<text::XTextSectionsSupplier> xTextSectionsSupplier(mxComponent, uno::UNO_QUERY);
1097     uno::Reference<container::XIndexAccess> xTextSections(xTextSectionsSupplier->getTextSections(), uno::UNO_QUERY);
1098     // This was false, last section was balanced, but it's unbalanced in Word.
1099     CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xTextSections->getByIndex(2), "DontBalanceTextColumns"));
1100 }
1101 
1102 DECLARE_OOXMLEXPORT_TEST(testTdf121670_columnsInSectionsOnly, "tdf121670_columnsInSectionsOnly.docx")
1103 {
1104     uno::Reference<text::XTextSectionsSupplier> xTextSectionsSupplier(mxComponent, uno::UNO_QUERY);
1105     uno::Reference<container::XIndexAccess> xTextSections(xTextSectionsSupplier->getTextSections(), uno::UNO_QUERY);
1106     CPPUNIT_ASSERT_EQUAL_MESSAGE("DontBalanceTextColumns?", true, getProperty<bool>(xTextSections->getByIndex(0), "DontBalanceTextColumns"));
1107 
1108     uno::Reference<beans::XPropertySet> xTextSection = getProperty< uno::Reference<beans::XPropertySet> >(getParagraph(2), "TextSection");
1109     CPPUNIT_ASSERT(xTextSection.is());
1110     uno::Reference<text::XTextColumns> xTextColumns = getProperty< uno::Reference<text::XTextColumns> >(xTextSection, "TextColumns");
1111     CPPUNIT_ASSERT_EQUAL_MESSAGE("# of columns", sal_Int16(3), xTextColumns->getColumnCount());
1112 
1113     xTextSection.set( getProperty< uno::Reference<beans::XPropertySet> >(getParagraph(3), "TextSection") );
1114     CPPUNIT_ASSERT(xTextSection.is());
1115     xTextColumns.set( getProperty< uno::Reference<text::XTextColumns> >(xTextSection, "TextColumns") );
1116     CPPUNIT_ASSERT_EQUAL_MESSAGE("# of columns", sal_Int16(0), xTextColumns->getColumnCount());
1117 }
1118 
1119 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf106492, "tdf106492.docx")
1120 {
1121     xmlDocUniquePtr pXmlDoc = parseExport();
1122     // This was 4: an additional sectPr was added to the document.
1123     assertXPath(pXmlDoc, "//w:sectPr", 3);
1124 }
1125 
1126 DECLARE_OOXMLEXPORT_TEST(testTdf107104, "tdf107104.docx")
1127 {
1128     CPPUNIT_ASSERT(getShape(1)->getSize().Width > 0);
1129     // This failed: the second arrow was invisible because it had zero width.
1130     CPPUNIT_ASSERT(getShape(2)->getSize().Width > 0);
1131 }
1132 
1133 DECLARE_OOXMLEXPORT_TEST(testTdf107033, "tdf107033.docx")
1134 {
1135     uno::Reference<beans::XPropertySet> xPageStyle(getStyles("PageStyles")->getByName("Standard"), uno::UNO_QUERY);
1136     // This was 0: footnote separator was disabled even in case the document
1137     // had no footnotes.
1138     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(25), getProperty<sal_Int32>(xPageStyle, "FootnoteLineRelativeWidth"));
1139 }
1140 
1141 #if HAVE_MORE_FONTS
1142 DECLARE_OOXMLEXPORT_TEST(testTdf107889, "tdf107889.docx")
1143 {
1144     // This was 1, multi-page table was imported as a floating one.
1145     CPPUNIT_ASSERT_EQUAL(0, getShapes());
1146 }
1147 #endif
1148 
1149 DECLARE_OOXMLEXPORT_TEST(testTdf107837, "tdf107837.odt")
1150 {
1151     CPPUNIT_ASSERT_EQUAL(1, getPages());
1152     uno::Reference<text::XTextSectionsSupplier> xTextSectionsSupplier(mxComponent, uno::UNO_QUERY);
1153     uno::Reference<container::XIndexAccess> xTextSections(xTextSectionsSupplier->getTextSections(), uno::UNO_QUERY);
1154     // This was true, a balanced section from ODF turned into a non-balanced one after OOXML roundtrip.
1155     CPPUNIT_ASSERT_EQUAL(false, getProperty<bool>(xTextSections->getByIndex(0), "DontBalanceTextColumns"));
1156 }
1157 
1158 DECLARE_OOXMLEXPORT_TEST(testTdf107684, "tdf107684.odt")
1159 {
1160     CPPUNIT_ASSERT_EQUAL(1, getPages());
1161     if (xmlDocUniquePtr pXmlDoc = parseExport("word/styles.xml"))
1162         // This was 1, <w:outlineLvl> was duplicated for Heading1.
1163         assertXPath(pXmlDoc, "//w:style[@w:styleId='Heading1']/w:pPr/w:outlineLvl", 1);
1164 }
1165 
1166 DECLARE_OOXMLEXPORT_TEST(testTdf107618, "tdf107618.doc")
1167 {
1168     // This was false, header was lost on export.
1169     uno::Reference<beans::XPropertySet> xPageStyle(getStyles("PageStyles")->getByName("Standard"), uno::UNO_QUERY);
1170     CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xPageStyle, "HeaderIsOn"));
1171 }
1172 
1173 DECLARE_OOXMLEXPORT_TEST(testTdf108682, "tdf108682.docx")
1174 {
1175     auto aLineSpacing = getProperty<style::LineSpacing>(getParagraph(1), "ParaLineSpacing");
1176     // This was style::LineSpacingMode::PROP.
1177     CPPUNIT_ASSERT_EQUAL(style::LineSpacingMode::FIX, aLineSpacing.Mode);
1178     // 260 twips in mm100, this was a negative value.
1179     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(459), aLineSpacing.Height);
1180 }
1181 
1182 DECLARE_OOXMLEXPORT_TEST(testTdf100075, "tdf100075.docx")
1183 {
1184     uno::Reference<text::XTextFramesSupplier> xTextFramesSupplier(mxComponent, uno::UNO_QUERY);
1185     uno::Reference<container::XIndexAccess> xIndexAccess(xTextFramesSupplier->getTextFrames(), uno::UNO_QUERY);
1186 
1187     // There are two frames in document
1188     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2), xIndexAccess->getCount());
1189 
1190     uno::Reference<beans::XPropertySet> xFrame1(xIndexAccess->getByIndex(0), uno::UNO_QUERY);
1191     uno::Reference<beans::XPropertySet> xFrame2(xIndexAccess->getByIndex(1), uno::UNO_QUERY);
1192 
1193     // Ensure that frame#1 height is more that frame#2: if no hRul attribute
1194     // defined, MS Word will use hRul=auto if height is not defined,
1195     // and hRul=atLeast if height is provided. So frame#1 should be higher
1196     CPPUNIT_ASSERT(getProperty<sal_Int32>(xFrame1, "Height") > getProperty<sal_Int32>(xFrame2, "Height"));
1197 }
1198 
1199 DECLARE_OOXMLEXPORT_TEST(testTdf105095, "tdf105095.docx")
1200 {
1201     uno::Reference<text::XFootnotesSupplier> xFootnotesSupplier(mxComponent, uno::UNO_QUERY);
1202     uno::Reference<container::XIndexAccess> xFootnotes = xFootnotesSupplier->getFootnotes();
1203     uno::Reference<text::XTextRange> xTextRange(xFootnotes->getByIndex(0), uno::UNO_QUERY);
1204     // This failed, tab between the footnote number and the footnote content
1205     // was lost on import.
1206     CPPUNIT_ASSERT_EQUAL( OUString("\tfootnote"), xTextRange->getString() );
1207 }
1208 
1209 DECLARE_OOXMLEXPORT_TEST(testTdf106062_nonHangingFootnote, "tdf106062_nonHangingFootnote.odt")
1210 {
1211     CPPUNIT_ASSERT_EQUAL(1, getPages());
1212     uno::Reference<text::XFootnotesSupplier> xFootnotesSupplier(mxComponent, uno::UNO_QUERY);
1213     uno::Reference<container::XIndexAccess> xFootnotes = xFootnotesSupplier->getFootnotes();
1214     uno::Reference<text::XTextRange> xTextRange(xFootnotes->getByIndex(0), uno::UNO_QUERY);
1215     // This failed, tab between the footnote number and the footnote content was lost on import.
1216     CPPUNIT_ASSERT_MESSAGE( "Footnote starts with a tab", xTextRange->getString().startsWith("\t") );
1217 }
1218 
1219 DECLARE_OOXMLEXPORT_TEST( testActiveXTextfield, "activex_textbox.docx" )
1220 {
1221     uno::Reference<drawing::XControlShape> xControlShape( getShape(1), uno::UNO_QUERY );
1222     CPPUNIT_ASSERT( xControlShape.is() );
1223 
1224     // Check control type
1225     uno::Reference<beans::XPropertySet> xPropertySet( xControlShape->getControl(), uno::UNO_QUERY );
1226     uno::Reference<lang::XServiceInfo> xServiceInfo( xPropertySet, uno::UNO_QUERY );
1227     CPPUNIT_ASSERT_EQUAL( true, bool( xServiceInfo->supportsService ( "com.sun.star.form.component.TextField" ) ) );
1228 
1229     // Check textfield is multi-line
1230     CPPUNIT_ASSERT_EQUAL( true, getProperty<bool>(xPropertySet, "MultiLine") );
1231 
1232     uno::Reference<drawing::XControlShape> xControlShape2( getShape(2), uno::UNO_QUERY );
1233     CPPUNIT_ASSERT( xControlShape2.is() );
1234 
1235     // Check control type
1236     uno::Reference<beans::XPropertySet> xPropertySet2( xControlShape2->getControl(), uno::UNO_QUERY );
1237     uno::Reference<lang::XServiceInfo> xServiceInfo2( xPropertySet2, uno::UNO_QUERY );
1238     CPPUNIT_ASSERT_EQUAL( true, bool( xServiceInfo2->supportsService ( "com.sun.star.form.component.TextField" ) ) );
1239 
1240     // Check textfield is single-line
1241     CPPUNIT_ASSERT_EQUAL( false, getProperty<bool>(xPropertySet2, "MultiLine") );
1242 
1243     // Don't open in design mode when form controls exist
1244     uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
1245     uno::Reference<view::XFormLayerAccess> xFormLayerAccess(xModel->getCurrentController(), uno::UNO_QUERY);
1246     CPPUNIT_ASSERT( !xFormLayerAccess->isFormDesignMode() );
1247 }
1248 
1249 DECLARE_OOXMLEXPORT_TEST( testActiveXCheckbox, "activex_checkbox.docx" )
1250 {
1251     uno::Reference<drawing::XControlShape> xControlShape( getShape(1), uno::UNO_QUERY );
1252     CPPUNIT_ASSERT( xControlShape.is() );
1253 
1254     // Check control type
1255     uno::Reference<beans::XPropertySet> xPropertySet( xControlShape->getControl(), uno::UNO_QUERY );
1256     uno::Reference<lang::XServiceInfo> xServiceInfo( xPropertySet, uno::UNO_QUERY );
1257     CPPUNIT_ASSERT_EQUAL( true, bool( xServiceInfo->supportsService( "com.sun.star.form.component.CheckBox" ) ) );
1258 
1259     // Check custom label
1260     CPPUNIT_ASSERT_EQUAL( OUString( "Custom Caption" ), getProperty<OUString>(xPropertySet, "Label") );
1261 
1262     // Check background color (highlight system color)
1263     CPPUNIT_ASSERT_EQUAL( sal_Int32( 0x316AC5 ), getProperty<sal_Int32>(xPropertySet, "BackgroundColor") );
1264 
1265     // Check Text color (active border system color)
1266     CPPUNIT_ASSERT_EQUAL(sal_Int32(0xD4D0C8), getProperty<sal_Int32>(xPropertySet, "TextColor"));
1267 
1268     // Check state of the checkbox
1269     CPPUNIT_ASSERT_EQUAL(sal_Int16(1), getProperty<sal_Int16>(xPropertySet, "State"));
1270 
1271     // Check anchor type
1272     uno::Reference<beans::XPropertySet> xPropertySet2(xControlShape, uno::UNO_QUERY);
1273     CPPUNIT_ASSERT_EQUAL(text::TextContentAnchorType_AT_CHARACTER,getProperty<text::TextContentAnchorType>(xPropertySet2,"AnchorType"));
1274 }
1275 
1276 DECLARE_OOXMLEXPORT_TEST(testActiveXControlAlign, "activex_control_align.odt")
1277 {
1278     CPPUNIT_ASSERT_EQUAL(2, getShapes());
1279     CPPUNIT_ASSERT_EQUAL(1, getPages());
1280     // First check box aligned as a floating object
1281     uno::Reference<drawing::XControlShape> xControlShape(getShape(1), uno::UNO_QUERY);
1282     CPPUNIT_ASSERT(xControlShape.is());
1283 
1284     // Check whether we have the right control
1285     uno::Reference<beans::XPropertySet> xPropertySet(xControlShape->getControl(), uno::UNO_QUERY);
1286     uno::Reference<lang::XServiceInfo> xServiceInfo(xPropertySet, uno::UNO_QUERY);
1287     CPPUNIT_ASSERT_EQUAL(true, bool(xServiceInfo->supportsService( "com.sun.star.form.component.CheckBox")));
1288     CPPUNIT_ASSERT_EQUAL(OUString("Floating Check Box"), getProperty<OUString>(xPropertySet, "Label"));
1289 
1290     // Check anchor type
1291     uno::Reference<beans::XPropertySet> xPropertySet2(xControlShape, uno::UNO_QUERY);
1292     CPPUNIT_ASSERT_EQUAL(text::TextContentAnchorType_AT_CHARACTER,getProperty<text::TextContentAnchorType>(xPropertySet2,"AnchorType"));
1293 
1294     // Also check position and size
1295     uno::Reference<drawing::XShape> xShape(xControlShape, uno::UNO_QUERY);
1296     CPPUNIT_ASSERT(xShape.is());
1297     CPPUNIT_ASSERT_EQUAL(sal_Int32(4470), xShape->getSize().Width);
1298     CPPUNIT_ASSERT_EQUAL(sal_Int32(1427), xShape->getSize().Height);
1299     CPPUNIT_ASSERT_EQUAL(sal_Int32(5126), xShape->getPosition().X);
1300     CPPUNIT_ASSERT_EQUAL(sal_Int32(2341), xShape->getPosition().Y);
1301 
1302     // Second check box aligned inline / as character
1303     xControlShape.set(getShape(2), uno::UNO_QUERY);
1304 
1305     // Check whether we have the right control
1306     xPropertySet.set(xControlShape->getControl(), uno::UNO_QUERY);
1307     xServiceInfo.set(xPropertySet, uno::UNO_QUERY);
1308     CPPUNIT_ASSERT_EQUAL(true, bool(xServiceInfo->supportsService("com.sun.star.form.component.CheckBox")));
1309     CPPUNIT_ASSERT_EQUAL(OUString("Inline Check Box"), getProperty<OUString>(xPropertySet, "Label"));
1310 
1311     // Check anchor type
1312     xPropertySet2.set(xControlShape, uno::UNO_QUERY);
1313     CPPUNIT_ASSERT_EQUAL(text::TextContentAnchorType_AS_CHARACTER,getProperty<text::TextContentAnchorType>(xPropertySet2,"AnchorType"));
1314     CPPUNIT_ASSERT_EQUAL(sal_Int32(text::VertOrientation::TOP),getProperty<sal_Int32>(xPropertySet2,"VertOrient"));
1315 
1316     // Also check position and size
1317     xShape.set(xControlShape, uno::UNO_QUERY);
1318     CPPUNIT_ASSERT(xShape.is());
1319     CPPUNIT_ASSERT_EQUAL(sal_Int32(4410), xShape->getSize().Width);
1320     CPPUNIT_ASSERT_EQUAL(sal_Int32(1083), xShape->getSize().Height);
1321     CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xShape->getPosition().X);
1322     CPPUNIT_ASSERT_EQUAL(sal_Int32(-1085), xShape->getPosition().Y);
1323 
1324     // Also check the specific OOXML elements
1325     xmlDocUniquePtr pXmlDoc = parseExport();
1326     CPPUNIT_ASSERT(pXmlDoc);
1327     // For inline controls use w:object as parent element and pictureFrame shapetype
1328     assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:r/w:object", 1);
1329     assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:r/w:object/v:shapetype", "spt", "75");
1330     // For floating controls use w:pict as parent element and hostControl shapetype
1331     assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:r[1]/w:pict", 1);
1332     assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:r[1]/w:pict/v:shapetype", "spt", "201");
1333 
1334      // Have different shape ids
1335     CPPUNIT_ASSERT(getXPath(pXmlDoc, "/w:document/w:body/w:p/w:r/w:object/v:shape", "id") !=
1336         getXPath(pXmlDoc, "/w:document/w:body/w:p/w:r[1]/w:pict/v:shape", "id"));
1337 }
1338 
1339 DECLARE_OOXMLEXPORT_TEST(testTdf109184, "tdf109184.docx")
1340 {
1341     uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
1342     uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY);
1343     uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY);
1344 
1345     // Before table background color was white, should be transparent (auto).
1346     uno::Reference<text::XTextRange> xCell1(xTable->getCellByName("A1"), uno::UNO_QUERY);
1347     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(-1), getProperty<sal_Int32>(xCell1, "BackColor"));
1348 
1349     // Cell with auto color but with 15% fill, shouldn't be transparent.
1350     uno::Reference<text::XTextRange> xCell2(xTable->getCellByName("B1"), uno::UNO_QUERY);
1351     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0xd8d8d8), getProperty<sal_Int32>(xCell2, "BackColor"));
1352 
1353     // Cell with color defined (red).
1354     uno::Reference<text::XTextRange> xCell3(xTable->getCellByName("A2"), uno::UNO_QUERY);
1355     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0xff0000), getProperty<sal_Int32>(xCell3, "BackColor"));
1356 }
1357 
1358 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf111964, "tdf111964.docx")
1359 {
1360     xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
1361     // Unicode spaces that are not XML whitespace must not be trimmed
1362     static constexpr OUStringLiteral sWSReference = u"\u2002\u2002\u2002\u2002\u2002";
1363     assertXPathContent(pXmlDoc, "/w:document/w:body/w:p/w:r[6]/w:t", sWSReference);
1364 }
1365 
1366 DECLARE_OOXMLEXPORT_TEST(testWatermark, "watermark-shapetype.docx")
1367 {
1368     uno::Reference<drawing::XShape> xShape1(getShape(1), uno::UNO_QUERY);
1369     CPPUNIT_ASSERT(xShape1.is());
1370     uno::Reference<beans::XPropertySet> xPropertySet1(xShape1, uno::UNO_QUERY);
1371 
1372     uno::Reference<drawing::XShape> xShape2(getShape(2), uno::UNO_QUERY);
1373     CPPUNIT_ASSERT(xShape2.is());
1374     uno::Reference<beans::XPropertySet> xPropertySet2(xShape2, uno::UNO_QUERY);
1375 
1376     CPPUNIT_ASSERT_EQUAL(xPropertySet1->getPropertyValue("TextAutoGrowHeight"), xPropertySet2->getPropertyValue("TextAutoGrowHeight"));
1377 }
1378 
1379 DECLARE_OOXMLEXPORT_TEST(testActiveXControlAtRunEnd, "activex_control_at_run_end.odt")
1380 {
1381     CPPUNIT_ASSERT_EQUAL(2, getShapes());
1382     CPPUNIT_ASSERT_EQUAL(1, getPages());
1383     // Two issues were here:
1384     //  1) second shape was not export (it is anchored to the end of the run)
1385     //  2) inline property was inherited to the second shape by mistake
1386 
1387     // First checkbox is the inlined one
1388     uno::Reference<drawing::XControlShape> xControlShape(getShape(1), uno::UNO_QUERY);
1389     CPPUNIT_ASSERT(xControlShape.is());
1390 
1391     // Check whether we have the right control
1392     uno::Reference<beans::XPropertySet> xPropertySet(xControlShape->getControl(), uno::UNO_QUERY);
1393     uno::Reference<lang::XServiceInfo> xServiceInfo(xPropertySet, uno::UNO_QUERY);
1394     CPPUNIT_ASSERT_EQUAL(true, bool(xServiceInfo->supportsService( "com.sun.star.form.component.CheckBox")));
1395     CPPUNIT_ASSERT_EQUAL(OUString("Inline Checkbox"), getProperty<OUString>(xPropertySet, "Label"));
1396 
1397     // Check anchor type
1398     uno::Reference<beans::XPropertySet> xPropertySet2(xControlShape, uno::UNO_QUERY);
1399     CPPUNIT_ASSERT_EQUAL(text::TextContentAnchorType_AS_CHARACTER,getProperty<text::TextContentAnchorType>(xPropertySet2,"AnchorType"));
1400 
1401     // Second check box anchored to character
1402     xControlShape.set(getShape(2), uno::UNO_QUERY);
1403 
1404     // Check whether we have the right control
1405     xPropertySet.set(xControlShape->getControl(), uno::UNO_QUERY);
1406     xServiceInfo.set(xPropertySet, uno::UNO_QUERY);
1407     CPPUNIT_ASSERT_EQUAL(true, bool(xServiceInfo->supportsService("com.sun.star.form.component.CheckBox")));
1408     CPPUNIT_ASSERT_EQUAL(OUString("Floating Checkbox"), getProperty<OUString>(xPropertySet, "Label"));
1409 
1410     // Check anchor type
1411     xPropertySet2.set(xControlShape, uno::UNO_QUERY);
1412     CPPUNIT_ASSERT_EQUAL(text::TextContentAnchorType_AT_CHARACTER,getProperty<text::TextContentAnchorType>(xPropertySet2,"AnchorType"));
1413 }
1414 
1415 DECLARE_OOXMLEXPORT_TEST(testActiveXOptionButtonGroup, "activex_option_button_group.docx")
1416 {
1417     // Optionbutton groups were not handled
1418     // The two optionbutton should have the same group name
1419     const OUString sGroupName = "GroupX";
1420 
1421     uno::Reference<drawing::XControlShape> xControlShape(getShape(1), uno::UNO_QUERY);
1422     CPPUNIT_ASSERT(xControlShape.is());
1423     uno::Reference<beans::XPropertySet> xPropertySet(xControlShape->getControl(), uno::UNO_QUERY);
1424     CPPUNIT_ASSERT_EQUAL(sGroupName, getProperty<OUString>(xPropertySet, "GroupName"));
1425 
1426     xControlShape.set(getShape(2), uno::UNO_QUERY);
1427     CPPUNIT_ASSERT(xControlShape.is());
1428     xPropertySet.set(xControlShape->getControl(), uno::UNO_QUERY);
1429     CPPUNIT_ASSERT_EQUAL(sGroupName, getProperty<OUString>(xPropertySet, "GroupName"));
1430 }
1431 
1432 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(tdf112169, "tdf112169.odt")
1433 {
1434     CPPUNIT_ASSERT_EQUAL(1, getShapes());
1435     CPPUNIT_ASSERT_EQUAL(6, getPages());
1436     // LO crashed while export because of character background color handling
1437 
1438     //tdf76683 - Cannot be negative number - use firstLine instead of hanging
1439     xmlDocUniquePtr pXmlDoc = parseExport("word/numbering.xml");
1440     assertXPathNoAttribute(pXmlDoc, "/w:numbering/w:abstractNum[1]/w:lvl[1]/w:pPr/w:ind", "hanging");
1441     assertXPath(pXmlDoc, "/w:numbering/w:abstractNum[1]/w:lvl[1]/w:pPr/w:ind", "firstLine","360");
1442 }
1443 
1444 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf103090, "tdf103090.odt")
1445 {
1446     CPPUNIT_ASSERT_EQUAL(1, getPages());
1447     xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
1448 
1449     // Get bookmark name
1450     OUString bookmarkName = getXPath(pXmlDoc, "/w:document/w:body/w:p/w:bookmarkStart", "name");
1451 
1452     // Ensure that name has no spaces
1453     CPPUNIT_ASSERT(bookmarkName.indexOf(" ") < 0);
1454 
1455     // Get PAGEREF field
1456     OUString fieldName = getXPathContent(pXmlDoc, "/w:document/w:body/w:p/w:r[2]/w:instrText");
1457 
1458     // Ensure that PAGEREF field refers exactly our bookmark
1459     OUString expectedFieldName = " PAGEREF " + bookmarkName + " \\h ";
1460     CPPUNIT_ASSERT_EQUAL(expectedFieldName, fieldName);
1461 }
1462 
1463 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf107111, "tdf107111.docx")
1464 {
1465     xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
1466 
1467     // Ensure that hyperlink and its properties are in place.
1468     assertXPath(pXmlDoc, "/w:document/w:body/w:p[5]/w:hyperlink/w:r/w:rPr", 1);
1469 
1470     // Ensure that hyperlink properties do not contain <w:webHidden/>.
1471     assertXPath(pXmlDoc, "/w:document/w:body/w:p[5]/w:hyperlink/w:r/w:rPr/w:webHidden", 0);
1472 }
1473 
1474 DECLARE_OOXMLEXPORT_TEST(testTdf90789, "tdf90789.docx")
1475 {
1476     uno::Reference<text::XTextContent> xShape(getShape(1), uno::UNO_QUERY_THROW);
1477     CPPUNIT_ASSERT(xShape->getAnchor() != nullptr);
1478 
1479     uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY_THROW);
1480     uno::Reference<view::XSelectionSupplier> xCtrl(xModel->getCurrentController(), uno::UNO_QUERY_THROW);
1481     xCtrl->select(uno::makeAny(xShape->getAnchor()));
1482 
1483     uno::Reference<text::XTextViewCursorSupplier> xTextViewCursorSupplier(xCtrl, uno::UNO_QUERY_THROW);
1484     uno::Reference<text::XTextViewCursor> xTextCursor(xTextViewCursorSupplier->getViewCursor(), uno::UNO_SET_THROW);
1485     uno::Reference<text::XPageCursor> xPageCursor(xTextCursor, uno::UNO_QUERY_THROW);
1486     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(1), xPageCursor->getPage());
1487 }
1488 
1489 DECLARE_OOXMLEXPORT_TEST(testTdf90789_2, "tdf90789-2.docx")
1490 {
1491     // Section break before frame and shape was ignored
1492     CPPUNIT_ASSERT_EQUAL( 3, getPages() );
1493 }
1494 
1495 DECLARE_OOXMLEXPORT_TEST(testTdf104354_2, "tdf104354-2.docx")
1496 {
1497     uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
1498     uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY);
1499     uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY);
1500     uno::Reference<text::XTextRange> xCell(xTable->getCellByName("A1"), uno::UNO_QUERY);
1501 
1502     // top margin of the first paragraph and bottom margin of the last paragraph
1503     // is zero, when auto spacing is used.
1504 
1505     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), getProperty<sal_Int32>(getParagraphOfText(1, xCell->getText()), "ParaTopMargin"));
1506     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(494), getProperty<sal_Int32>(getParagraphOfText(1, xCell->getText()), "ParaBottomMargin"));
1507     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(494), getProperty<sal_Int32>(getParagraphOfText(2, xCell->getText()), "ParaTopMargin"));
1508     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(494), getProperty<sal_Int32>(getParagraphOfText(2, xCell->getText()), "ParaBottomMargin"));
1509     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(494), getProperty<sal_Int32>(getParagraphOfText(3, xCell->getText()), "ParaTopMargin"));
1510     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), getProperty<sal_Int32>(getParagraphOfText(3, xCell->getText()), "ParaBottomMargin"));
1511 
1512     // top margin is not auto spacing
1513     uno::Reference<text::XTextRange> xCell2(xTable->getCellByName("A2"), uno::UNO_QUERY);
1514     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(847), getProperty<sal_Int32>(getParagraphOfText(1, xCell2->getText()), "ParaTopMargin"));
1515     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), getProperty<sal_Int32>(getParagraphOfText(1, xCell2->getText()), "ParaBottomMargin"));
1516 
1517     // bottom margin is not auto spacing
1518     uno::Reference<text::XTextRange> xCell3(xTable->getCellByName("A3"), uno::UNO_QUERY);
1519     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), getProperty<sal_Int32>(getParagraphOfText(1, xCell3->getText()), "ParaTopMargin"));
1520     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(847), getProperty<sal_Int32>(getParagraphOfText(1, xCell3->getText()), "ParaBottomMargin"));
1521 
1522     // auto spacing, if the paragraph contains footnotes
1523     uno::Reference<text::XTextRange> xCell4(xTable->getCellByName("A4"), uno::UNO_QUERY);
1524     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), getProperty<sal_Int32>(getParagraphOfText(1, xCell4->getText()), "ParaTopMargin"));
1525     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), getProperty<sal_Int32>(getParagraphOfText(1, xCell4->getText()), "ParaBottomMargin"));
1526 
1527     // auto spacing is explicitly disabled, and no margins are defined.
1528     xCell.set(xTable->getCellByName("A5"), uno::UNO_QUERY);
1529     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), getProperty<sal_Int32>(getParagraphOfText(1, xCell->getText()), "ParaTopMargin"));
1530     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), getProperty<sal_Int32>(getParagraphOfText(1, xCell->getText()), "ParaBottomMargin"));
1531     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), getProperty<sal_Int32>(getParagraphOfText(2, xCell->getText()), "ParaTopMargin"));
1532     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), getProperty<sal_Int32>(getParagraphOfText(2, xCell->getText()), "ParaBottomMargin"));
1533     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), getProperty<sal_Int32>(getParagraphOfText(3, xCell->getText()), "ParaTopMargin"));
1534     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), getProperty<sal_Int32>(getParagraphOfText(3, xCell->getText()), "ParaBottomMargin"));
1535 
1536     // auto spacing on a paragraph
1537     uno::Reference<text::XTextTable> xTable2(xTables->getByIndex(1), uno::UNO_QUERY);
1538     uno::Reference<text::XTextRange> xCell5(xTable2->getCellByName("A1"), uno::UNO_QUERY);
1539     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), getProperty<sal_Int32>(getParagraphOfText(1, xCell5->getText()), "ParaTopMargin"));
1540     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), getProperty<sal_Int32>(getParagraphOfText(1, xCell5->getText()), "ParaBottomMargin"));
1541 }
1542 
1543 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf137593, "tdf137593.docx")
1544 {
1545     xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
1546 
1547     // zero auto spacing, if the first paragraph contains text boxes
1548     // This was 280.
1549     assertXPath(pXmlDoc, "/w:document/w:body/w:tbl[1]/w:tr/w:tc/w:p[1]/w:pPr/w:spacing", "before", "0");
1550 }
1551 
1552 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf115557, "tdf115557.docx")
1553 {
1554     // A chart anchored to a footnote multiplied during import
1555     xmlDocUniquePtr pXmlDoc = parseExport("word/footnotes.xml");
1556 
1557     assertXPath(pXmlDoc, "//w:footnote/w:p/w:r/w:drawing", 1);
1558 }
1559 
1560 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testAlignmentRelativeFromTopMarginDML, "tdf137641_RelativeFromTopMargin.docx")
1561 {
1562     // Import as DML.
1563     xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
1564 
1565     assertXPath(pXmlDoc,
1566                 "/w:document/w:body/w:p[2]/w:r/mc:AlternateContent[1]/mc:Choice/w:drawing/"
1567                 "wp:anchor/wp:positionV",
1568                 "relativeFrom", "topMargin");
1569     assertXPathContent(pXmlDoc,
1570                        "/w:document/w:body/w:p[2]/w:r/mc:AlternateContent[1]/mc:Choice/w:drawing/"
1571                        "wp:anchor/wp:positionV/wp:align",
1572                        "top");
1573     assertXPath(pXmlDoc,
1574         "/w:document/w:body/w:p[2]/w:r/mc:AlternateContent[2]/mc:Choice/w:drawing/"
1575         "wp:anchor/wp:positionV",
1576         "relativeFrom", "topMargin");
1577     assertXPathContent(pXmlDoc,
1578                        "/w:document/w:body/w:p[2]/w:r/mc:AlternateContent[2]/mc:Choice/w:drawing/"
1579                        "wp:anchor/wp:positionV/wp:align",
1580                        "bottom");
1581     assertXPath(pXmlDoc,
1582         "/w:document/w:body/w:p[2]/w:r/mc:AlternateContent[3]/mc:Choice/w:drawing/"
1583         "wp:anchor/wp:positionV",
1584         "relativeFrom", "topMargin");
1585     assertXPathContent(pXmlDoc,
1586                        "/w:document/w:body/w:p[2]/w:r/mc:AlternateContent[3]/mc:Choice/w:drawing/"
1587                        "wp:anchor/wp:positionV/wp:align",
1588                        "center");
1589 }
1590 
1591 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testAlignmentRelativeFromTopMarginVML, "tdf137642_Vertical_Alignment_toppage.docx")
1592 {
1593     // Import as VML.
1594     xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
1595 
1596     assertXPath(pXmlDoc,
1597                 "/w:document/w:body/w:p/w:r/mc:AlternateContent[1]/mc:Choice/w:drawing/"
1598                 "wp:anchor/wp:positionV",
1599                 "relativeFrom", "topMargin");
1600     assertXPathContent(pXmlDoc,
1601                        "/w:document/w:body/w:p/w:r/mc:AlternateContent[1]/mc:Choice/w:drawing/"
1602                        "wp:anchor/wp:positionV/wp:align",
1603                        "top");
1604     assertXPath(pXmlDoc,
1605                 "/w:document/w:body/w:p/w:r/mc:AlternateContent[2]/mc:Choice/w:drawing/"
1606                 "wp:anchor/wp:positionV",
1607                 "relativeFrom", "topMargin");
1608     assertXPathContent(pXmlDoc,
1609                        "/w:document/w:body/w:p/w:r/mc:AlternateContent[2]/mc:Choice/w:drawing/"
1610                        "wp:anchor/wp:positionV/wp:align",
1611                        "bottom");
1612     assertXPath(pXmlDoc,
1613                 "/w:document/w:body/w:p/w:r/mc:AlternateContent[3]/mc:Choice/w:drawing/"
1614                 "wp:anchor/wp:positionV",
1615                 "relativeFrom", "topMargin");
1616     assertXPathContent(pXmlDoc,
1617                        "/w:document/w:body/w:p/w:r/mc:AlternateContent[3]/mc:Choice/w:drawing/"
1618                        "wp:anchor/wp:positionV/wp:align",
1619                        "center");
1620 }
1621 
1622 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testVmlShapeWithTextbox, "tdf41466_testVmlShapeWithTextbox.docx")
1623 {
1624     // Import as VML.
1625     // tdf#41466: check whether VML DOCX shape with text is imported as shape with a text frame
1626     // (text box). These kind of shapes were imported only as text frames previously, losing the
1627     // preset shape geometry, in this case "wedgeRectCallout".
1628     xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
1629 
1630     // the wrong value was "rect" instead of "wedgeRectCallout"
1631     assertXPath(pXmlDoc,
1632         "/w:document/w:body/w:p/w:r/"
1633         "mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:prstGeom",
1634         "prst", "wedgeRectCallout");
1635 }
1636 
1637 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testLayoutFlowAltAlone, "layout-flow-alt-alone.docx")
1638 {
1639     // moved from oox/qa/unit/vml.cxx
1640     // FIXME: now the DML part is checked, but we should check VML part in Fallback (too)
1641     xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
1642     assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/"
1643         "a:graphic/a:graphicData/wps:wsp/wps:bodyPr", "vert", "vert270");
1644 }
1645 
1646 CPPUNIT_PLUGIN_IMPLEMENT();
1647 
1648 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1649