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 <memory>
11 #include <swmodeltestbase.hxx>
12 #include <config_features.h>
13 
14 #include <com/sun/star/awt/FontSlant.hpp>
15 #include <com/sun/star/awt/Gradient.hpp>
16 #include <com/sun/star/container/XIndexReplace.hpp>
17 #include <com/sun/star/drawing/FillStyle.hpp>
18 #include <com/sun/star/drawing/PointSequenceSequence.hpp>
19 #include <com/sun/star/drawing/GraphicExportFilter.hpp>
20 #include <com/sun/star/drawing/XGraphicExportFilter.hpp>
21 #include <com/sun/star/drawing/QRCode.hpp>
22 #include <com/sun/star/drawing/QRCodeErrorCorrection.hpp>
23 #include <com/sun/star/table/ShadowFormat.hpp>
24 #include <com/sun/star/table/XCellRange.hpp>
25 #include <com/sun/star/text/RelOrientation.hpp>
26 #include <com/sun/star/text/XDocumentIndex.hpp>
27 #include <com/sun/star/drawing/TextVerticalAdjust.hpp>
28 #include <com/sun/star/graphic/XGraphic.hpp>
29 #include <officecfg/Office/Common.hxx>
30 #include <com/sun/star/document/XEmbeddedObjectSupplier.hpp>
31 #include <com/sun/star/text/XTextEmbeddedObjectsSupplier.hpp>
32 #include <com/sun/star/text/XTextField.hpp>
33 #include <com/sun/star/text/WritingMode2.hpp>
34 #include <comphelper/storagehelper.hxx>
35 #include <comphelper/fileformat.h>
36 #include <comphelper/propertysequence.hxx>
37 #include <unotools/streamwrap.hxx>
38 #include <svl/PasswordHelper.hxx>
39 #include <docufld.hxx> // for SwHiddenTextField::ParseIfFieldDefinition() method call
40 #include <unoprnms.hxx>
41 #include <sortedobjs.hxx>
42 #include <flyfrm.hxx>
43 #include <ftnidx.hxx>
44 #include <txtftn.hxx>
45 
46 class Test : public SwModelTestBase
47 {
48 public:
Test()49     Test() : SwModelTestBase("/sw/qa/extras/odfexport/data/", "writer8") {}
50 
51     /**
52      * Blacklist handling
53      */
mustTestImportOf(const char * filename) const54     bool mustTestImportOf(const char* filename) const override {
55         // Only test import of .odt document
56         return OString(filename).endsWith(".odt");
57     }
58 
mustValidate(const char *) const59     bool mustValidate(const char* /*filename*/) const override
60     {
61         return true;
62     }
63 
preTest(const char * pFilename)64     virtual std::unique_ptr<Resetter> preTest(const char* pFilename) override
65     {
66         if (OString(pFilename) == "fdo58949.docx")
67         {
68             std::unique_ptr<Resetter> pResetter(new Resetter(
69                 [] () {
70                     std::shared_ptr<comphelper::ConfigurationChanges> pBatch(
71                             comphelper::ConfigurationChanges::create());
72                     officecfg::Office::Common::Filter::Microsoft::Import::MathTypeToMath::set(true, pBatch);
73                     return pBatch->commit();
74                 }));
75 
76             std::shared_ptr<comphelper::ConfigurationChanges> pBatch(comphelper::ConfigurationChanges::create());
77             officecfg::Office::Common::Filter::Microsoft::Import::MathTypeToMath::set(false, pBatch);
78             pBatch->commit();
79             return pResetter;
80         }
81         if (OString(pFilename) == "2_MathType3.docx")
82         {
83             std::unique_ptr<Resetter> pResetter(new Resetter(
84                 [this] () {
85                     mpFilter = "writer8";
86                     std::shared_ptr<comphelper::ConfigurationChanges> pBatch(
87                             comphelper::ConfigurationChanges::create());
88                     officecfg::Office::Common::Cache::Writer::OLE_Objects::set(20, pBatch);
89                     return pBatch->commit();
90                 }));
91             mpFilter = "OpenDocument Text Flat XML"; // doesn't happen with ODF package
92             std::shared_ptr<comphelper::ConfigurationChanges> pBatch(
93                     comphelper::ConfigurationChanges::create());
94             officecfg::Office::Common::Cache::Writer::OLE_Objects::set(1, pBatch);
95             pBatch->commit();
96             return pResetter;
97         }
98         return nullptr;
99     }
100 };
101 
102 DECLARE_ODFEXPORT_TEST(testMathObjectFlatExport, "2_MathType3.docx")
103 {
104     uno::Reference<util::XModifiable> xModifiable(mxComponent, uno::UNO_QUERY);
105     CPPUNIT_ASSERT(!xModifiable->isModified());
106     // see preTest(), set the OLE cache to 1 for this test
107     // and the problem was that the formulas that were in the cache
108     // (the second one) were lost
109     OUString formula1(getFormula(getRun(getParagraph(1), 1)));
110     CPPUNIT_ASSERT_EQUAL(OUString(" size 12{1+1=2} {}"), formula1);
111     OUString formula2(getFormula(getRun(getParagraph(2), 1)));
112     CPPUNIT_ASSERT_EQUAL(OUString(" size 12{2+2=4} {}"), formula2);
113 }
114 
testTdf43569_CheckIfFieldParse()115 static void testTdf43569_CheckIfFieldParse()
116 {
117     {
118         const OUString fieldDefinition("IF A B C");
119 
120         OUString paramCondition;
121         OUString paramTrue;
122         OUString paramFalse;
123 
124         SwHiddenTextField::ParseIfFieldDefinition(fieldDefinition, paramCondition, paramTrue, paramFalse);
125 
126         CPPUNIT_ASSERT_EQUAL(OUString("A"), paramCondition);
127         CPPUNIT_ASSERT_EQUAL(OUString("B"), paramTrue);
128         CPPUNIT_ASSERT_EQUAL(OUString("C"), paramFalse);
129     }
130 
131     {
132         const OUString fieldDefinition("  IF AAA BBB CCC  ");
133 
134         OUString paramCondition;
135         OUString paramTrue;
136         OUString paramFalse;
137 
138         SwHiddenTextField::ParseIfFieldDefinition(fieldDefinition, paramCondition, paramTrue, paramFalse);
139 
140         CPPUNIT_ASSERT_EQUAL(OUString("AAA"), paramCondition);
141         CPPUNIT_ASSERT_EQUAL(OUString("BBB"), paramTrue);
142         CPPUNIT_ASSERT_EQUAL(OUString("CCC"), paramFalse);
143     }
144 
145     {
146         const OUString fieldDefinition("  IF AAA \"BBB\" \"CCC\"  ");
147 
148         OUString paramCondition;
149         OUString paramTrue;
150         OUString paramFalse;
151 
152         SwHiddenTextField::ParseIfFieldDefinition(fieldDefinition, paramCondition, paramTrue, paramFalse);
153 
154         CPPUNIT_ASSERT_EQUAL(OUString("AAA"), paramCondition);
155         CPPUNIT_ASSERT_EQUAL(OUString("BBB"), paramTrue);
156         CPPUNIT_ASSERT_EQUAL(OUString("CCC"), paramFalse);
157     }
158 
159     // true-case and false-case have spaces inside
160     {
161         const OUString fieldDefinition("  IF A A A \"B B B\" \"C C C\"  ");
162 
163         OUString paramCondition;
164         OUString paramTrue;
165         OUString paramFalse;
166 
167         SwHiddenTextField::ParseIfFieldDefinition(fieldDefinition, paramCondition, paramTrue, paramFalse);
168 
169         CPPUNIT_ASSERT_EQUAL(OUString("A A A"), paramCondition);
170         CPPUNIT_ASSERT_EQUAL(OUString("B B B"), paramTrue);
171         CPPUNIT_ASSERT_EQUAL(OUString("C C C"), paramFalse);
172     }
173 
174     // true-case and false-case have leading/trailing space
175     {
176         const OUString fieldDefinition("IF A1 A2 A3 \"B1 B2 \" \" C1 C2\"  ");
177 
178         OUString paramCondition;
179         OUString paramTrue;
180         OUString paramFalse;
181 
182         SwHiddenTextField::ParseIfFieldDefinition(fieldDefinition, paramCondition, paramTrue, paramFalse);
183 
184         CPPUNIT_ASSERT_EQUAL(OUString("A1 A2 A3"), paramCondition);
185         CPPUNIT_ASSERT_EQUAL(OUString("B1 B2 "), paramTrue);
186         CPPUNIT_ASSERT_EQUAL(OUString(" C1 C2"), paramFalse);
187     }
188 
189     // true-case and false-case are empty
190     {
191         const OUString fieldDefinition("IF condition \"\" \"\"  ");
192 
193         OUString paramCondition;
194         OUString paramTrue;
195         OUString paramFalse;
196 
197         SwHiddenTextField::ParseIfFieldDefinition(fieldDefinition, paramCondition, paramTrue, paramFalse);
198 
199         CPPUNIT_ASSERT_EQUAL(OUString("condition"), paramCondition);
200         CPPUNIT_ASSERT_EQUAL(OUString(""), paramTrue);
201         CPPUNIT_ASSERT_EQUAL(OUString(""), paramFalse);
202     }
203 }
204 
205 // Input document contains only one IF-field,
206 // and it should be imported as com.sun.star.text.TextField.ConditionalText in any case,
207 // instead of insertion of the pair of two field-marks: <field:fieldmark-start> + <field:fieldmark-end>.
208 DECLARE_ODFEXPORT_TEST(testTdf43569, "tdf43569_conditionalfield.doc")
209 {
210     // check if our parser is valid
211     testTdf43569_CheckIfFieldParse();
212 
213     // now check field creation during import
214     uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
215     uno::Reference<container::XEnumerationAccess> xFieldsAccess(xTextFieldsSupplier->getTextFields());
216     uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration());
217 
218     // at least one field should be detected
219     CPPUNIT_ASSERT(xFields->hasMoreElements());
220 }
221 
222 DECLARE_ODFEXPORT_TEST(testTdf103567, "tdf103567.odt")
223 {
224     uno::Reference<drawing::XShape> const xShape(getShape(1));
225 
226     // contour wrap polygon
227     css::drawing::PointSequenceSequence const pointss(
228         getProperty<css::drawing::PointSequenceSequence>(xShape, "ContourPolyPolygon"));
229     CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pointss.getLength());
230     // for some reason this property exists with 199 points if it wasn't
231     // imported, that would be a fail
232     CPPUNIT_ASSERT_EQUAL(sal_Int32(5), pointss[0].getLength());
233     CPPUNIT_ASSERT_EQUAL(sal_Int32(   0), pointss[0][0].X);
234     CPPUNIT_ASSERT_EQUAL(sal_Int32(2672), pointss[0][0].Y);
235     CPPUNIT_ASSERT_EQUAL(sal_Int32(   0), pointss[0][1].X);
236     CPPUNIT_ASSERT_EQUAL(sal_Int32(1111), pointss[0][1].Y);
237     CPPUNIT_ASSERT_EQUAL(sal_Int32(2672), pointss[0][2].X);
238     CPPUNIT_ASSERT_EQUAL(sal_Int32(1111), pointss[0][2].Y);
239     CPPUNIT_ASSERT_EQUAL(sal_Int32(2672), pointss[0][3].X);
240     CPPUNIT_ASSERT_EQUAL(sal_Int32(2672), pointss[0][3].Y);
241     CPPUNIT_ASSERT_EQUAL(sal_Int32(   0), pointss[0][4].X);
242     CPPUNIT_ASSERT_EQUAL(sal_Int32(2672), pointss[0][4].Y);
243 
244     // image map, one rectangle
245     uno::Reference<container::XIndexContainer> const xImageMap(
246         getProperty<uno::Reference<container::XIndexContainer>>(xShape, "ImageMap"));
247 
248     uno::Reference<beans::XPropertySet> const xEntry(xImageMap->getByIndex(0), uno::UNO_QUERY);
249     CPPUNIT_ASSERT_EQUAL(OUString("http://example.com/"), getProperty<OUString>(xEntry, "URL"));
250     awt::Rectangle const rect(getProperty<awt::Rectangle>(xEntry, "Boundary"));
251     CPPUNIT_ASSERT_EQUAL(sal_Int32( 726), rect.X);
252     CPPUNIT_ASSERT_EQUAL(sal_Int32(1718), rect.Y);
253     CPPUNIT_ASSERT_EQUAL(sal_Int32(1347), rect.Width);
254     CPPUNIT_ASSERT_EQUAL(sal_Int32( 408), rect.Height);
255 }
256 
257 DECLARE_ODFEXPORT_TEST(testUserFieldDecl, "user-field-decl.odt")
258 {
259     if (xmlDocPtr pXmlDoc = parseExport("styles.xml"))
260         // Without the accompanying fix in place, this test would have failed with 'Expected: 2;
261         // Actual: 1', i.e. the in-table field had no declaration (in the header), while the
262         // outside-table one had the declaration.
263         assertXPath(pXmlDoc, "//style:header/text:user-field-decls/text:user-field-decl", 2);
264 }
265 
266 DECLARE_ODFEXPORT_TEST(testUserFieldDeclFly, "user-field-decl-fly.odt")
267 {
268     if (xmlDocPtr pXmlDoc = parseExport("styles.xml"))
269         // Without the accompanying fix in place, this test would have failed with 'Expected: 2;
270         // Actual: 1', i.e. the in-textframe field had no declaration (in the header), while the
271         // outside-textframe one had the declaration.
272         assertXPath(pXmlDoc, "//style:header/text:user-field-decls/text:user-field-decl", 2);
273 }
274 
275 DECLARE_ODFEXPORT_TEST(testFramebackgrounds, "framebackgrounds.odt")
276 {
277    //Counting the Number of Frames and checking with the expected count
278     uno::Reference<text::XTextFramesSupplier> xTextFramesSupplier(mxComponent, uno::UNO_QUERY);
279     uno::Reference<container::XIndexAccess> xIndexAccess(xTextFramesSupplier->getTextFrames(), uno::UNO_QUERY);
280     CPPUNIT_ASSERT_EQUAL(sal_Int32(16), xIndexAccess->getCount());
281     uno::Reference<drawing::XShape> xTextFrame;
282     awt::Gradient aGradientxTextFrame;
283     //Frame 1
284     xTextFrame = getShape(1);
285     CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_NONE, getProperty<drawing::FillStyle>(xTextFrame, "FillStyle"));
286     CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xTextFrame, "FillTransparence"));
287     //Frame 2
288     xTextFrame = getShape(2);
289     CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_SOLID, getProperty<drawing::FillStyle>(xTextFrame, "FillStyle"));
290     CPPUNIT_ASSERT_EQUAL(sal_Int32(0x006600), getProperty<util::Color>(xTextFrame, "FillColor"));
291     CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xTextFrame, "FillTransparence"));
292     //Frame 3
293     xTextFrame = getShape(3);
294     CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_SOLID, getProperty<drawing::FillStyle>(xTextFrame, "FillStyle"));
295     CPPUNIT_ASSERT_EQUAL(sal_Int32(0x006600), getProperty<util::Color>(xTextFrame, "FillColor"));
296     CPPUNIT_ASSERT_EQUAL(sal_Int32(45), getProperty<sal_Int32>(xTextFrame, "FillTransparence"));
297     //Frame 4
298     xTextFrame = getShape(4);
299     CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_SOLID, getProperty<drawing::FillStyle>(xTextFrame, "FillStyle"));
300     CPPUNIT_ASSERT_EQUAL(sal_Int32(0x579D1C), getProperty<util::Color>(xTextFrame, "FillColor"));
301     aGradientxTextFrame = getProperty<awt::Gradient>(xTextFrame, "FillTransparenceGradient");
302     CPPUNIT_ASSERT_EQUAL(css::awt::GradientStyle_LINEAR, aGradientxTextFrame.Style);
303     //Frame 5
304     xTextFrame = getShape(5);
305     CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_GRADIENT, getProperty<drawing::FillStyle>(xTextFrame, "FillStyle"));
306     CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xTextFrame, "FillTransparence"));
307     CPPUNIT_ASSERT_EQUAL(OUString("Subtle Tango Green"), getProperty<OUString>(xTextFrame, "FillGradientName"));
308     //Frame 6
309     xTextFrame = getShape(6);
310     CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_GRADIENT, getProperty<drawing::FillStyle>(xTextFrame, "FillStyle"));
311     CPPUNIT_ASSERT_EQUAL(OUString("Subtle Tango Green"), getProperty<OUString>(xTextFrame, "FillGradientName"));
312     CPPUNIT_ASSERT_EQUAL(sal_Int32(45), getProperty<sal_Int32>(xTextFrame, "FillTransparence"));
313     //Frame 7
314     xTextFrame = getShape(7);
315     CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_GRADIENT, getProperty<drawing::FillStyle>(xTextFrame, "FillStyle"));
316     CPPUNIT_ASSERT_EQUAL(OUString("Subtle Tango Green"), getProperty<OUString>(xTextFrame, "FillGradientName"));
317     aGradientxTextFrame = getProperty<awt::Gradient>(xTextFrame, "FillTransparenceGradient");
318     CPPUNIT_ASSERT_EQUAL(css::awt::GradientStyle_LINEAR, aGradientxTextFrame.Style);
319     //Frame 8
320     xTextFrame = getShape(8);
321     CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_HATCH, getProperty<drawing::FillStyle>(xTextFrame, "FillStyle"));
322     CPPUNIT_ASSERT_EQUAL(OUString("Black 0 Degrees"), getProperty<OUString>(xTextFrame, "FillHatchName"));
323     CPPUNIT_ASSERT_EQUAL(false, getProperty<bool>(xTextFrame, "FillBackground"));
324     CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xTextFrame, "FillTransparence"));
325     //Frame 9
326     xTextFrame = getShape(9);
327     CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_HATCH, getProperty<drawing::FillStyle>(xTextFrame, "FillStyle"));
328     CPPUNIT_ASSERT_EQUAL(OUString("Black 0 Degrees"), getProperty<OUString>(xTextFrame, "FillHatchName"));
329     CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xTextFrame, "FillBackground"));
330     CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xTextFrame, "FillTransparence"));
331     //Frame 10
332     xTextFrame = getShape(10);
333     CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_HATCH, getProperty<drawing::FillStyle>(xTextFrame, "FillStyle"));
334     CPPUNIT_ASSERT_EQUAL(OUString("Black 0 Degrees"), getProperty<OUString>(xTextFrame, "FillHatchName"));
335     CPPUNIT_ASSERT_EQUAL(false, getProperty<bool>(xTextFrame, "FillBackground"));
336     CPPUNIT_ASSERT_EQUAL(sal_Int32(45), getProperty<sal_Int32>(xTextFrame, "FillTransparence"));
337     //Frame 11
338     xTextFrame = getShape(11);
339     CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_HATCH, getProperty<drawing::FillStyle>(xTextFrame, "FillStyle"));
340     CPPUNIT_ASSERT_EQUAL(OUString("Black 0 Degrees"), getProperty<OUString>(xTextFrame, "FillHatchName"));
341     CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xTextFrame, "FillBackground"));
342     CPPUNIT_ASSERT_EQUAL(sal_Int32(45), getProperty<sal_Int32>(xTextFrame, "FillTransparence"));
343     //Frame 12
344     xTextFrame = getShape(12);
345     CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_HATCH, getProperty<drawing::FillStyle>(xTextFrame, "FillStyle"));
346     CPPUNIT_ASSERT_EQUAL(OUString("Black 0 Degrees"), getProperty<OUString>(xTextFrame, "FillHatchName"));
347     CPPUNIT_ASSERT_EQUAL(false, getProperty<bool>(xTextFrame, "FillBackground"));
348     aGradientxTextFrame = getProperty<awt::Gradient>(xTextFrame, "FillTransparenceGradient");
349     CPPUNIT_ASSERT_EQUAL(css::awt::GradientStyle_LINEAR, aGradientxTextFrame.Style);
350     //Frame 13
351     xTextFrame = getShape(13);
352     CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_HATCH, getProperty<drawing::FillStyle>(xTextFrame, "FillStyle"));
353     CPPUNIT_ASSERT_EQUAL(OUString("Black 0 Degrees"), getProperty<OUString>(xTextFrame, "FillHatchName"));
354     CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xTextFrame, "FillBackground"));
355     aGradientxTextFrame = getProperty<awt::Gradient>(xTextFrame, "FillTransparenceGradient");
356     CPPUNIT_ASSERT_EQUAL(css::awt::GradientStyle_LINEAR, aGradientxTextFrame.Style);
357     //Frame 14
358     xTextFrame = getShape(14);
359     CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_BITMAP, getProperty<drawing::FillStyle>(xTextFrame, "FillStyle"));
360     CPPUNIT_ASSERT_EQUAL(OUString("Sky"), getProperty<OUString>(xTextFrame, "FillBitmapName"));
361     CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xTextFrame, "FillTransparence"));
362     CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xTextFrame, "FillBitmapPositionOffsetX"));
363     CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xTextFrame, "FillBitmapPositionOffsetY"));
364     CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xTextFrame, "FillBitmapOffsetX"));
365     CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xTextFrame, "FillBitmapOffsetY"));
366     CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xTextFrame, "FillBitmapTile"));
367     //Frame 15
368     xTextFrame = getShape(15);
369     CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_BITMAP, getProperty<drawing::FillStyle>(xTextFrame, "FillStyle"));
370     CPPUNIT_ASSERT_EQUAL(OUString("Sky"), getProperty<OUString>(xTextFrame, "FillBitmapName"));
371     CPPUNIT_ASSERT_EQUAL(sal_Int32(45), getProperty<sal_Int32>(xTextFrame, "FillTransparence"));
372     CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xTextFrame, "FillBitmapPositionOffsetX"));
373     CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xTextFrame, "FillBitmapPositionOffsetY"));
374     CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xTextFrame, "FillBitmapOffsetX"));
375     CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xTextFrame, "FillBitmapOffsetY"));
376     CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xTextFrame, "FillBitmapTile"));
377     //Frame 16
378     xTextFrame = getShape(16);
379     CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_BITMAP, getProperty<drawing::FillStyle>(xTextFrame, "FillStyle"));
380     CPPUNIT_ASSERT_EQUAL(OUString("Sky"), getProperty<OUString>(xTextFrame, "FillBitmapName"));
381     CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xTextFrame, "FillBitmapPositionOffsetX"));
382     CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xTextFrame, "FillBitmapPositionOffsetY"));
383     CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xTextFrame, "FillBitmapOffsetX"));
384     CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xTextFrame, "FillBitmapOffsetY"));
385     CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xTextFrame, "FillBitmapTile"));
386     aGradientxTextFrame = getProperty<awt::Gradient>(xTextFrame, "FillTransparenceGradient");
387     CPPUNIT_ASSERT_EQUAL(css::awt::GradientStyle_LINEAR, aGradientxTextFrame.Style);
388 
389     if (xmlDocPtr pXmlDoc = parseExport("content.xml"))
390     {
391         // check that there are 3 background-image elements
392         assertXPath(pXmlDoc, "//style:style[@style:parent-style-name='Frame' and @style:family='graphic']/style:graphic-properties[@draw:fill='bitmap']/style:background-image[@style:repeat='stretch']", 3);
393         // tdf#90640: check that one of them is 55% opaque
394         assertXPath(pXmlDoc, "//style:style[@style:parent-style-name='Frame' and @style:family='graphic']/style:graphic-properties[@draw:fill='bitmap' and @fo:background-color='transparent' and @draw:opacity='55%']/style:background-image[@style:repeat='stretch' and @draw:opacity='55%']", 1);
395         // tdf#90640: check that one of them is 43% opaque
396         // (emulated - hopefully not with rounding errors)
397         assertXPath(pXmlDoc, "//style:style[@style:parent-style-name='Frame' and @style:family='graphic']/style:graphic-properties[@draw:fill='bitmap' and @fo:background-color='transparent' and @draw:opacity-name='Transparency_20_1']/style:background-image[@style:repeat='stretch' and @draw:opacity='43%']", 1);
398     }
399 }
400 
401 DECLARE_SW_ROUNDTRIP_TEST(testSHA1Correct, "sha1_correct.odt", "1012345678901234567890123456789012345678901234567890", Test)
402 {   // tdf#114939 this has both an affected password as well as content.xml
403     getParagraph(1, "012");
404 }
405 
406 DECLARE_SW_ROUNDTRIP_TEST(testSHA1Wrong, "sha1_wrong.odt", "1012345678901234567890123456789012345678901234567890", Test)
407 {   // tdf#114939 this has both an affected password as well as content.xml
408     getParagraph(1, "012");
409 }
410 
411 DECLARE_ODFEXPORT_TEST(testOOoxmlEmbedded, "oooxml_embedded.sxw")
412 {
413     uno::Reference<text::XTextEmbeddedObjectsSupplier> xTEOSupplier(mxComponent, uno::UNO_QUERY);
414     uno::Reference<container::XNameAccess> xAccess(xTEOSupplier->getEmbeddedObjects());
415     uno::Sequence<OUString> aSeq(xAccess->getElementNames());
416     CPPUNIT_ASSERT_EQUAL(sal_Int32(4), aSeq.getLength());
417     uno::Reference<document::XEmbeddedObjectSupplier> xEOSupplier1(xAccess->getByName("Object1"), uno::UNO_QUERY);
418     uno::Reference<lang::XComponent> xObj1(xEOSupplier1->getEmbeddedObject());
419     uno::Reference<document::XEmbeddedObjectSupplier> xEOSupplier2(xAccess->getByName("Object2"), uno::UNO_QUERY);
420     uno::Reference<lang::XComponent> xObj2(xEOSupplier2->getEmbeddedObject());
421     uno::Reference<document::XEmbeddedObjectSupplier> xEOSupplier3(xAccess->getByName("Object3"), uno::UNO_QUERY);
422     uno::Reference<lang::XComponent> xObj3(xEOSupplier3->getEmbeddedObject());
423     uno::Reference<document::XEmbeddedObjectSupplier> xEOSupplier4(xAccess->getByName("Object4"), uno::UNO_QUERY);
424     uno::Reference<lang::XComponent> xObj4(xEOSupplier4->getEmbeddedObject());
425     //checking first object
426     uno::Reference<document::XStorageBasedDocument> xSBDoc1(xObj1, uno::UNO_QUERY);
427     uno::Reference<embed::XStorage> xStorage1(xSBDoc1->getDocumentStorage());
428     CPPUNIT_ASSERT_EQUAL(sal_Int32(SOFFICE_FILEFORMAT_8), comphelper::OStorageHelper::GetXStorageFormat(xStorage1));
429     //checking second object
430     uno::Reference<document::XStorageBasedDocument> xSBDoc2(xObj2, uno::UNO_QUERY);
431     uno::Reference<embed::XStorage> xStorage2(xSBDoc2->getDocumentStorage());
432     CPPUNIT_ASSERT_EQUAL(sal_Int32(SOFFICE_FILEFORMAT_8), comphelper::OStorageHelper::GetXStorageFormat(xStorage2));
433     //checking third object
434     uno::Reference<document::XStorageBasedDocument> xSBDoc3(xObj3, uno::UNO_QUERY);
435     uno::Reference<embed::XStorage> xStorage3(xSBDoc3->getDocumentStorage());
436     CPPUNIT_ASSERT_EQUAL(sal_Int32(SOFFICE_FILEFORMAT_8), comphelper::OStorageHelper::GetXStorageFormat(xStorage3));
437     //checking fourth object
438     uno::Reference<document::XStorageBasedDocument> xSBDoc4(xObj4, uno::UNO_QUERY);
439     uno::Reference<embed::XStorage> xStorage4(xSBDoc4->getDocumentStorage());
440     CPPUNIT_ASSERT_EQUAL(sal_Int32(SOFFICE_FILEFORMAT_8), comphelper::OStorageHelper::GetXStorageFormat(xStorage4));
441 }
442 
443 DECLARE_ODFEXPORT_TEST(testredlineTextFrame, "redlineTextFrame.odt")
444 {
445     //Note this is for a crash test
446     //Counting the Number of Frames and checking with the expected count
447     uno::Reference<text::XTextFramesSupplier> xTextFramesSupplier(mxComponent, uno::UNO_QUERY);
448     uno::Reference<container::XIndexAccess> xIndexAccess(xTextFramesSupplier->getTextFrames(), uno::UNO_QUERY);
449     CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());
450 }
451 
452 DECLARE_ODFEXPORT_TEST(testFdo38244, "fdo38244.odt")
453 {
454     // See ooxmlexport's testFdo38244().
455 
456     // Test comment range feature.
457     uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
458     uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextDocument->getText(), uno::UNO_QUERY);
459     uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
460     uno::Reference<container::XEnumerationAccess> xRunEnumAccess(xParaEnum->nextElement(), uno::UNO_QUERY);
461     uno::Reference<container::XEnumeration> xRunEnum = xRunEnumAccess->createEnumeration();
462     xRunEnum->nextElement();
463     uno::Reference<beans::XPropertySet> xPropertySet(xRunEnum->nextElement(), uno::UNO_QUERY);
464     CPPUNIT_ASSERT_EQUAL(OUString("Annotation"), getProperty<OUString>(xPropertySet, "TextPortionType"));
465     xRunEnum->nextElement();
466     xPropertySet.set(xRunEnum->nextElement(), uno::UNO_QUERY);
467     CPPUNIT_ASSERT_EQUAL(OUString("AnnotationEnd"), getProperty<OUString>(xPropertySet, "TextPortionType"));
468 
469     // Test properties
470     uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
471     uno::Reference<container::XEnumerationAccess> xFieldsAccess(xTextFieldsSupplier->getTextFields());
472     uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration());
473     xPropertySet.set(xFields->nextElement(), uno::UNO_QUERY);
474     CPPUNIT_ASSERT_EQUAL(OUString("__Fieldmark__4_1833023242"), getProperty<OUString>(xPropertySet, "Name"));
475     CPPUNIT_ASSERT_EQUAL(OUString("M"), getProperty<OUString>(xPropertySet, "Initials"));
476 }
477 
478 DECLARE_ODFEXPORT_TEST(testSenderInitials, "sender-initials.fodt")
479 {
480     // Test sender-initial properties (both annotation metadata and text field)
481     uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
482     uno::Reference<container::XEnumerationAccess> xFieldsAccess(xTextFieldsSupplier->getTextFields());
483     uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration());
484     // first 3 are annotations, last 2 are text fields
485     for (unsigned i = 0; i < 3; ++i)
486     {
487         uno::Reference<beans::XPropertySet> xPropertySet(xFields->nextElement(), uno::UNO_QUERY);
488         CPPUNIT_ASSERT_EQUAL(OUString("I"), getProperty<OUString>(xPropertySet, "Initials"));
489     }
490     for (unsigned i = 0; i < 2; ++i)
491     {
492         uno::Reference<beans::XPropertySet> xPropertySet(xFields->nextElement(), uno::UNO_QUERY);
493         CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xPropertySet, "IsFixed"));
494         CPPUNIT_ASSERT_EQUAL(OUString("I"), getProperty<OUString>(xPropertySet, "Content"));
495     }
496 }
497 
498 #ifndef WNT
499 DECLARE_ODFEXPORT_TEST(testResolvedComment, "resolved-comment.odt")
500 {
501     // TODO find out why does this break testFdo58949 on Windows.
502     uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
503     uno::Reference<container::XEnumerationAccess> xFieldsAccess(xTextFieldsSupplier->getTextFields());
504     uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration());
505     uno::Reference<beans::XPropertySet> xPropertySet(xFields->nextElement(), uno::UNO_QUERY);
506     CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xPropertySet, "Resolved"));
507     xPropertySet.set(xFields->nextElement(), uno::UNO_QUERY);
508     CPPUNIT_ASSERT_EQUAL(false, getProperty<bool>(xPropertySet, "Resolved"));
509 }
510 #endif
511 
512 DECLARE_ODFEXPORT_TEST(testTdf92379, "tdf92379.fodt")
513 {
514     // frame style fo:background-color was not imported
515     uno::Reference<container::XNameAccess> xStyles(getStyles("FrameStyles"));
516     uno::Reference<beans::XPropertySet> xStyle(xStyles->getByName("encarts"),
517             uno::UNO_QUERY);
518     CPPUNIT_ASSERT_EQUAL(sal_Int32(0xffcc99), getProperty<sal_Int32>(xStyle, "BackColorRGB"));
519     CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xStyle, "BackColorTransparency"));
520     CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_SOLID, getProperty<drawing::FillStyle>(xStyle, "FillStyle"));
521     CPPUNIT_ASSERT_EQUAL(sal_Int32(0xffcc99), getProperty<sal_Int32>(xStyle, "FillColor"));
522     CPPUNIT_ASSERT_EQUAL(sal_Int16(0), getProperty<sal_Int16>(xStyle, "FillTransparence"));
523 
524     uno::Reference<beans::XPropertySet> xFrameStyle2(xStyles->getByName("Untitled1"),
525             uno::UNO_QUERY);
526     CPPUNIT_ASSERT_EQUAL(sal_Int32(0xffffff), getProperty<sal_Int32>(xFrameStyle2, "BackColorRGB"));
527     CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xFrameStyle2, "BackTransparent"));
528     CPPUNIT_ASSERT_EQUAL(sal_Int32(100), getProperty<sal_Int32>(xFrameStyle2, "BackColorTransparency"));
529     CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_NONE, getProperty<drawing::FillStyle>(xFrameStyle2, "FillStyle"));
530 // unfortunately this is actually the pool default value, which would be hard to fix - but it isn't a problem because style is NONE
531 //    CPPUNIT_ASSERT_EQUAL(sal_Int32(0xffffff), getProperty<sal_Int32>(xFrameStyle2, "FillColor"));
532 //    CPPUNIT_ASSERT_EQUAL(sal_Int16(100), getProperty<sal_Int16>(xFrameStyle2, "FillTransparence"));
533 
534     if (xmlDocPtr pXmlDoc = parseExport("styles.xml"))
535     {
536         // check that fo:background-color attribute is exported properly
537         assertXPath(pXmlDoc, "//style:style[@style:family='graphic' and @style:name='encarts']/style:graphic-properties[@fo:background-color='#ffcc99']", 1);
538         assertXPath(pXmlDoc, "//style:style[@style:family='graphic' and @style:name='Untitled1']/style:graphic-properties[@fo:background-color='transparent']", 1);
539     }
540 
541     // paragraph style fo:background-color was wrongly inherited despite being
542     // overridden in derived style
543     uno::Reference<container::XNameAccess> xParaStyles(getStyles("ParagraphStyles"));
544     uno::Reference<beans::XPropertySet> xStyle1(xParaStyles->getByName(
545             "Titre Avis expert"), uno::UNO_QUERY);
546     CPPUNIT_ASSERT_EQUAL(sal_Int32(0x661900), getProperty<sal_Int32>(xStyle1, "ParaBackColor"));
547     CPPUNIT_ASSERT_EQUAL(false, getProperty<bool>(xStyle1, "ParaBackTransparent"));
548     CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_SOLID, getProperty<drawing::FillStyle>(xStyle1, "FillStyle"));
549     CPPUNIT_ASSERT_EQUAL(sal_Int32(0x661900), getProperty<sal_Int32>(xStyle1, "FillColor"));
550     CPPUNIT_ASSERT_EQUAL(sal_Int16(0), getProperty<sal_Int16>(xStyle1, "FillTransparence"));
551     CPPUNIT_ASSERT_EQUAL(sal_Int32(0xffffff), getProperty<sal_Int32>(xStyle1, "CharColor"));
552 
553     uno::Reference<beans::XPropertySet> xStyle2(xParaStyles->getByName(
554             "Avis expert questions"), uno::UNO_QUERY);
555     CPPUNIT_ASSERT_EQUAL(sal_Int32(COL_TRANSPARENT), getProperty<sal_Int32>(xStyle2, "ParaBackColor"));
556     CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xStyle2, "ParaBackTransparent"));
557     CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_NONE, getProperty<drawing::FillStyle>(xStyle2, "FillStyle"));
558 // unfortunately this is actually the pool default value, which would be hard to fix - but it isn't a problem because style is NONE
559 //    CPPUNIT_ASSERT_EQUAL(sal_Int32(0xffffff), getProperty<sal_Int32>(xStyle2, "FillColor"));
560 //    CPPUNIT_ASSERT_EQUAL(sal_Int16(100), getProperty<sal_Int16>(xStyle2, "FillTransparence"));
561     CPPUNIT_ASSERT_EQUAL(sal_Int32(0x661900), getProperty<sal_Int32>(xStyle2, "CharColor"));
562 
563     uno::Reference<beans::XPropertySet> xStyle31(xParaStyles->getByName(
564             "avis expert questions non cadres"), uno::UNO_QUERY);
565     CPPUNIT_ASSERT_EQUAL(sal_Int32(0x801900), getProperty<sal_Int32>(xStyle31, "ParaBackColor"));
566     CPPUNIT_ASSERT_EQUAL(false, getProperty<bool>(xStyle31, "ParaBackTransparent"));
567     CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_SOLID, getProperty<drawing::FillStyle>(xStyle31, "FillStyle"));
568     CPPUNIT_ASSERT_EQUAL(sal_Int32(0x801900), getProperty<sal_Int32>(xStyle31, "FillColor"));
569     CPPUNIT_ASSERT_EQUAL(sal_Int16(0), getProperty<sal_Int16>(xStyle31, "FillTransparence"));
570     CPPUNIT_ASSERT_EQUAL(sal_Int32(0x661900), getProperty<sal_Int32>(xStyle31, "CharColor"));
571 
572     uno::Reference<beans::XPropertySet> xStyle32(xParaStyles->getByName(
573             "Avis expert rXponses"), uno::UNO_QUERY);
574     CPPUNIT_ASSERT_EQUAL(sal_Int32(COL_TRANSPARENT), getProperty<sal_Int32>(xStyle32, "ParaBackColor"));
575     CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xStyle32, "ParaBackTransparent"));
576     CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_NONE, getProperty<drawing::FillStyle>(xStyle32, "FillStyle"));
577 // unfortunately this is actually the pool default value, which would be hard to fix - but it isn't a problem because style is NONE
578 //    CPPUNIT_ASSERT_EQUAL(sal_Int32(0xffffff), getProperty<sal_Int32>(xStyle32, "FillColor"));
579 //    CPPUNIT_ASSERT_EQUAL(sal_Int16(100), getProperty<sal_Int16>(xStyle32, "FillTransparence"));
580     CPPUNIT_ASSERT_EQUAL(sal_Int32(0x461900), getProperty<sal_Int32>(xStyle32, "CharColor"));
581 
582     if (xmlDocPtr pXmlDoc = parseExport("styles.xml"))
583     {
584         // check that fo:background-color attribute is exported properly
585         assertXPath(pXmlDoc, "//style:style[@style:family='paragraph' and @style:display-name='Titre Avis expert']/style:paragraph-properties[@fo:background-color='#661900']", 1);
586         assertXPath(pXmlDoc, "//style:style[@style:family='paragraph' and @style:display-name='Avis expert questions']/style:paragraph-properties[@fo:background-color='transparent']", 1);
587         assertXPath(pXmlDoc, "//style:style[@style:family='paragraph' and @style:display-name='avis expert questions non cadres']/style:paragraph-properties[@fo:background-color='#801900']", 1);
588         assertXPath(pXmlDoc, "//style:style[@style:family='paragraph' and @style:display-name='Avis expert rXponses']/style:paragraph-properties[@fo:background-color='transparent']", 1);
589     }
590 }
591 
592 DECLARE_ODFEXPORT_TEST(testFdo79358, "fdo79358.odt")
593 {
594     // the boolean properties of the index were not exported properly
595     uno::Reference<text::XDocumentIndexesSupplier> xIndexSupplier(mxComponent, uno::UNO_QUERY);
596     uno::Reference<container::XIndexAccess> xIndexes = xIndexSupplier->getDocumentIndexes();
597     uno::Reference<text::XDocumentIndex> xTOCIndex(xIndexes->getByIndex(0), uno::UNO_QUERY);
598     uno::Reference<beans::XPropertySet> xTOCProps(xTOCIndex, uno::UNO_QUERY);
599     CPPUNIT_ASSERT_EQUAL(false, getProperty<bool>(xTOCProps, "CreateFromOutline"));
600     CPPUNIT_ASSERT_EQUAL(false, getProperty<bool>(xTOCProps, "CreateFromMarks"));
601     CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xTOCProps, "CreateFromLevelParagraphStyles"));
602     // check that the source styles are preserved too while at it
603     uno::Reference<container::XIndexReplace> xLevels(
604         getProperty< uno::Reference<container::XIndexReplace> >(xTOCProps,
605             "LevelParagraphStyles"));
606     uno::Sequence<OUString> seq { "Heading" };
607     CPPUNIT_ASSERT_EQUAL(uno::makeAny(seq), xLevels->getByIndex(1));
608     CPPUNIT_ASSERT_EQUAL(uno::makeAny(uno::Sequence<OUString>()), xLevels->getByIndex(2));
609 }
610 
611 DECLARE_ODFEXPORT_TEST(testFirstHeaderFooter, "first-header-footer.odt")
612 {
613     // Test import and export of the header-first token.
614 
615     // The document has 6 pages, two page styles for the first and second half of pages.
616     CPPUNIT_ASSERT_EQUAL(OUString("First header"),  parseDump("/root/page[1]/header/txt/text()"));
617     CPPUNIT_ASSERT_EQUAL(OUString("First footer"),  parseDump("/root/page[1]/footer/txt/text()"));
618     CPPUNIT_ASSERT_EQUAL(OUString("Left header"),   parseDump("/root/page[2]/header/txt/text()"));
619     CPPUNIT_ASSERT_EQUAL(OUString("Left footer"),   parseDump("/root/page[2]/footer/txt/text()"));
620     CPPUNIT_ASSERT_EQUAL(OUString("Right header"),  parseDump("/root/page[3]/header/txt/text()"));
621     CPPUNIT_ASSERT_EQUAL(OUString("Right footer"),  parseDump("/root/page[3]/footer/txt/text()"));
622     CPPUNIT_ASSERT_EQUAL(OUString("First header2"), parseDump("/root/page[4]/header/txt/text()"));
623     CPPUNIT_ASSERT_EQUAL(OUString("First footer2"), parseDump("/root/page[4]/footer/txt/text()"));
624     CPPUNIT_ASSERT_EQUAL(OUString("Right header2"), parseDump("/root/page[5]/header/txt/text()"));
625     CPPUNIT_ASSERT_EQUAL(OUString("Right footer2"), parseDump("/root/page[5]/footer/txt/text()"));
626     CPPUNIT_ASSERT_EQUAL(OUString("Left header2"),  parseDump("/root/page[6]/header/txt/text()"));
627     CPPUNIT_ASSERT_EQUAL(OUString("Left footer2"),  parseDump("/root/page[6]/footer/txt/text()"));
628 }
629 
630 DECLARE_ODFEXPORT_TEST(testTextframeGradient, "textframe-gradient.odt")
631 {
632     uno::Reference<text::XTextFramesSupplier> xTextFramesSupplier(mxComponent, uno::UNO_QUERY);
633     uno::Reference<container::XIndexAccess> xIndexAccess(xTextFramesSupplier->getTextFrames(), uno::UNO_QUERY);
634     CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xIndexAccess->getCount());
635 
636     uno::Reference<beans::XPropertySet> xFrame(xIndexAccess->getByIndex(0), uno::UNO_QUERY);
637     CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_GRADIENT, getProperty<drawing::FillStyle>(xFrame, "FillStyle"));
638     awt::Gradient aGradient = getProperty<awt::Gradient>(xFrame, "FillGradient");
639     CPPUNIT_ASSERT_EQUAL(sal_Int32(0xC0504D), aGradient.StartColor);
640     CPPUNIT_ASSERT_EQUAL(sal_Int32(0xD99594), aGradient.EndColor);
641     CPPUNIT_ASSERT_EQUAL(awt::GradientStyle_AXIAL, aGradient.Style);
642 
643     xFrame.set(xIndexAccess->getByIndex(1), uno::UNO_QUERY);
644     CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_GRADIENT, getProperty<drawing::FillStyle>(xFrame, "FillStyle"));
645     aGradient = getProperty<awt::Gradient>(xFrame, "FillGradient");
646     CPPUNIT_ASSERT_EQUAL(sal_Int32(0x000000), aGradient.StartColor);
647     CPPUNIT_ASSERT_EQUAL(sal_Int32(0x666666), aGradient.EndColor);
648     CPPUNIT_ASSERT_EQUAL(awt::GradientStyle_AXIAL, aGradient.Style);
649 }
650 
651 DECLARE_ODFEXPORT_TEST(testDuplicateCrossRefHeadingBookmark, "CrossRefHeadingBookmark.fodt")
652 {
653     // the file contains invalid duplicate heading cross reference bookmarks
654     // but we have to round trip them, tdf#94804
655 
656     uno::Reference<text::XBookmarksSupplier> xBookmarksSupplier(mxComponent,
657         uno::UNO_QUERY);
658     uno::Reference<container::XNameAccess> xBookmarks =
659         xBookmarksSupplier->getBookmarks();
660     uno::Reference<text::XTextContent> xBookmark1(
661         xBookmarks->getByName("__RefHeading__8284_1826734303"), uno::UNO_QUERY);
662     CPPUNIT_ASSERT(xBookmark1.is());
663     CPPUNIT_ASSERT_THROW(xBookmarks->getByName("__RefHeading__1673_25705824"), container::NoSuchElementException);
664 
665     uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
666     uno::Reference<util::XRefreshable>(xTextFieldsSupplier->getTextFields(), uno::UNO_QUERY_THROW)->refresh();
667 
668     uno::Reference<container::XEnumerationAccess> xFieldsAccess(xTextFieldsSupplier->getTextFields());
669     uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration());
670     uno::Any aField1 = xFields->nextElement();
671     uno::Reference<text::XTextField> xField1(aField1, uno::UNO_QUERY);
672     CPPUNIT_ASSERT_EQUAL(OUString("1.1"), xField1->getPresentation(false));
673     uno::Any aField2 = xFields->nextElement();
674     uno::Reference<text::XTextField> xField2(aField2, uno::UNO_QUERY);
675     CPPUNIT_ASSERT_EQUAL(OUString("1.1"), xField2->getPresentation(false));
676 }
677 
678 DECLARE_ODFEXPORT_TEST(testFdo60769, "fdo60769.odt")
679 {
680     // Test multi-paragraph comment range feature.
681     uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
682     uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextDocument->getText(), uno::UNO_QUERY);
683     uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
684     uno::Reference<container::XEnumerationAccess> xRunEnumAccess(xParaEnum->nextElement(), uno::UNO_QUERY);
685     uno::Reference<container::XEnumeration> xRunEnum = xRunEnumAccess->createEnumeration();
686     while (xRunEnum->hasMoreElements())
687     {
688         uno::Reference<beans::XPropertySet> xPropertySet(xRunEnum->nextElement(), uno::UNO_QUERY);
689         OUString aType =  getProperty<OUString>(xPropertySet, "TextPortionType");
690         // First paragraph: no field end, no anchor
691         CPPUNIT_ASSERT(aType == "Text" || aType == "Annotation");
692     }
693 
694     xRunEnumAccess.set(xParaEnum->nextElement(), uno::UNO_QUERY);
695     while (xRunEnum->hasMoreElements())
696     {
697         uno::Reference<beans::XPropertySet> xPropertySet(xRunEnum->nextElement(), uno::UNO_QUERY);
698         OUString aType =  getProperty<OUString>(xPropertySet, "TextPortionType");
699         // Second paragraph: no field start
700         CPPUNIT_ASSERT(aType == "Text" || aType == "AnnotationEnd");
701     }
702 }
703 
704 DECLARE_ODFEXPORT_TEST(testFdo58949, "fdo58949.docx")
705 {
706     /*
707      * The problem was that the exporter didn't insert "Obj102" to the
708      * resulting zip file. No idea how to check for "broken" (missing OLE data
709      * and replacement image) OLE objects using UNO, so we'll check the zip file directly.
710      */
711 
712     utl::TempFile aTempFile;
713     save("writer8", aTempFile);
714 
715     uno::Sequence<uno::Any> aArgs(1);
716     aArgs[0] <<= aTempFile.GetURL();
717     uno::Reference<container::XNameAccess> xNameAccess(m_xSFactory->createInstanceWithArguments("com.sun.star.packages.zip.ZipFileAccess", aArgs), uno::UNO_QUERY);
718     CPPUNIT_ASSERT_EQUAL(true, bool(xNameAccess->hasByName("Obj102")));
719 }
720 
721 DECLARE_ODFEXPORT_TEST(testStylePageNumber, "ooo321_stylepagenumber.odt")
722 {
723     uno::Reference<text::XTextContent> xTable1(getParagraphOrTable(1));
724 // actually no break attribute is written in this case
725 //    CPPUNIT_ASSERT_EQUAL(style::BreakType_PAGE_BEFORE, getProperty<style::BreakType>(xTable1, "BreakType"));
726     CPPUNIT_ASSERT_EQUAL(OUString("Left Page"), getProperty<OUString>(xTable1, "PageDescName"));
727     CPPUNIT_ASSERT_EQUAL(sal_Int16(1), getProperty<sal_Int16>(xTable1, "PageNumberOffset"));
728 
729     uno::Reference<text::XTextContent> xPara1(getParagraphOrTable(2));
730     CPPUNIT_ASSERT_EQUAL(OUString("Right Page"), getProperty<OUString>(xPara1, "PageDescName"));
731     CPPUNIT_ASSERT_EQUAL(sal_Int16(1), getProperty<sal_Int16>(xPara1, "PageNumberOffset"));
732 
733     // i#114163 tdf#77111: OOo < 3.3 bug, it wrote "auto" as "0" for tables
734     uno::Reference<beans::XPropertySet> xTable0(getParagraphOrTable(3), uno::UNO_QUERY);
735     CPPUNIT_ASSERT_EQUAL(OUString("Left Page"), getProperty<OUString>(xTable0, "PageDescName"));
736     CPPUNIT_ASSERT_EQUAL(uno::Any(), xTable0->getPropertyValue("PageNumberOffset"));
737 
738     uno::Reference<beans::XPropertySet> xPara0(getParagraphOrTable(4), uno::UNO_QUERY);
739     CPPUNIT_ASSERT_EQUAL(OUString("Right Page"), getProperty<OUString>(xPara0, "PageDescName"));
740     CPPUNIT_ASSERT_EQUAL(uno::Any(), xPara0->getPropertyValue("PageNumberOffset"));
741 
742     uno::Reference<container::XNameAccess> xParaStyles = getStyles("ParagraphStyles");
743     uno::Reference<beans::XPropertySet> xStyle1(xParaStyles->getByName("stylewithbreak1"), uno::UNO_QUERY);
744     CPPUNIT_ASSERT_EQUAL(OUString("Right Page"), getProperty<OUString>(xStyle1, "PageDescName"));
745     CPPUNIT_ASSERT_EQUAL(sal_Int16(1), getProperty<sal_Int16>(xStyle1, "PageNumberOffset"));
746 
747     uno::Reference<beans::XPropertySet> xStyle0(xParaStyles->getByName("stylewithbreak0"), uno::UNO_QUERY);
748     CPPUNIT_ASSERT_EQUAL(OUString("First Page"), getProperty<OUString>(xStyle0, "PageDescName"));
749     CPPUNIT_ASSERT_EQUAL(uno::Any(), xStyle0->getPropertyValue("PageNumberOffset"));
750 }
751 
752 DECLARE_ODFEXPORT_TEST(testCharacterBorder, "charborder.odt")
753 {
754     // Make sure paragraph and character attributes don't interfere
755     // First paragraph has a paragraph border and a character border included by the paragraph style
756 
757     // Paragraph border of first paragraph
758     {
759         const table::BorderLine2 aFirstParTopBorder(0x6666FF,2,26,26,7,55);
760         const sal_Int32 aFirstParTopPadding(150);
761         uno::Reference<beans::XPropertySet> xSet(getParagraph(1), uno::UNO_QUERY);
762 
763         // Top border
764         CPPUNIT_ASSERT_BORDER_EQUAL(aFirstParTopBorder, getProperty<table::BorderLine2>(xSet,"TopBorder"));
765         CPPUNIT_ASSERT_EQUAL(aFirstParTopPadding, getProperty<sal_Int32>(xSet,"TopBorderDistance"));
766 
767         // Bottom border (same as top border)
768         CPPUNIT_ASSERT_BORDER_EQUAL(aFirstParTopBorder, getProperty<table::BorderLine2>(xSet,"BottomBorder"));
769         CPPUNIT_ASSERT_EQUAL(aFirstParTopPadding, getProperty<sal_Int32>(xSet,"BottomBorderDistance"));
770 
771         // Left border (same as top border)
772         CPPUNIT_ASSERT_BORDER_EQUAL(aFirstParTopBorder, getProperty<table::BorderLine2>(xSet,"LeftBorder"));
773         CPPUNIT_ASSERT_EQUAL(aFirstParTopPadding, getProperty<sal_Int32>(xSet,"LeftBorderDistance"));
774 
775         // Right border (same as top border)
776         CPPUNIT_ASSERT_BORDER_EQUAL(aFirstParTopBorder, getProperty<table::BorderLine2>(xSet,"RightBorder"));
777         CPPUNIT_ASSERT_EQUAL(aFirstParTopPadding, getProperty<sal_Int32>(xSet,"RightBorderDistance"));
778 
779         // Shadow
780         const table::ShadowFormat aShadow = getProperty<table::ShadowFormat>(xSet,"ParaShadowFormat");
781         CPPUNIT_ASSERT_EQUAL(sal_Int32(0), aShadow.Color);
782         CPPUNIT_ASSERT_EQUAL(false, static_cast<bool>(aShadow.IsTransparent));
783         CPPUNIT_ASSERT_EQUAL(table::ShadowLocation(0), aShadow.Location);
784         CPPUNIT_ASSERT_EQUAL(sal_Int16(0), aShadow.ShadowWidth);
785     }
786 
787     // Character border for first paragraph
788     {
789         const table::BorderLine2 aFirstParCharTopBorder(0xFF3333,0,37,0,2,37);
790         const sal_Int32 aFirstParCharTopPadding(450);
791         uno::Reference<beans::XPropertySet> xSet(getParagraph(1), uno::UNO_QUERY);
792 
793         // Top border
794         CPPUNIT_ASSERT_BORDER_EQUAL(aFirstParCharTopBorder, getProperty<table::BorderLine2>(xSet,"CharTopBorder"));
795         CPPUNIT_ASSERT_EQUAL(aFirstParCharTopPadding, getProperty<sal_Int32>(xSet,"CharTopBorderDistance"));
796 
797         // Bottom border (same as top border)
798         CPPUNIT_ASSERT_BORDER_EQUAL(aFirstParCharTopBorder, getProperty<table::BorderLine2>(xSet,"CharBottomBorder"));
799         CPPUNIT_ASSERT_EQUAL(aFirstParCharTopPadding, getProperty<sal_Int32>(xSet,"CharBottomBorderDistance"));
800 
801         // Left border (same as top border)
802         CPPUNIT_ASSERT_BORDER_EQUAL(aFirstParCharTopBorder, getProperty<table::BorderLine2>(xSet,"CharLeftBorder"));
803         CPPUNIT_ASSERT_EQUAL(aFirstParCharTopPadding, getProperty<sal_Int32>(xSet,"CharLeftBorderDistance"));
804 
805         // Right border (same as top border)
806         CPPUNIT_ASSERT_BORDER_EQUAL(aFirstParCharTopBorder, getProperty<table::BorderLine2>(xSet,"CharRightBorder"));
807         CPPUNIT_ASSERT_EQUAL(aFirstParCharTopPadding, getProperty<sal_Int32>(xSet,"CharRightBorderDistance"));
808 
809         // Shadow
810         const table::ShadowFormat aShadow = getProperty<table::ShadowFormat>(xSet,"CharShadowFormat");
811         CPPUNIT_ASSERT_EQUAL(sal_Int32(0xFF3333), aShadow.Color);
812         CPPUNIT_ASSERT_EQUAL(false, static_cast<bool>(aShadow.IsTransparent));
813         CPPUNIT_ASSERT_EQUAL(table::ShadowLocation(2), aShadow.Location);
814         CPPUNIT_ASSERT_EQUAL(sal_Int16(280), aShadow.ShadowWidth);
815 
816         // Check autostyle
817         {
818             uno::Reference< style::XAutoStyleFamily > xAutoStyleFamily(getAutoStyles("ParagraphStyles"));
819             uno::Reference < container::XEnumeration > xAutoStylesEnum( xAutoStyleFamily->createEnumeration() );
820             CPPUNIT_ASSERT_EQUAL(true, static_cast<bool>(xAutoStylesEnum->hasMoreElements()));
821 
822             // First paragraph autostyle
823             uno::Reference < beans::XPropertySet > xPSet( xAutoStylesEnum->nextElement(), uno::UNO_QUERY );
824 
825             // Top border
826             CPPUNIT_ASSERT_BORDER_EQUAL(aFirstParCharTopBorder, getProperty<table::BorderLine2>(xSet,"CharTopBorder"));
827             CPPUNIT_ASSERT_EQUAL(aFirstParCharTopPadding, getProperty<sal_Int32>(xSet,"CharTopBorderDistance"));
828 
829             // Bottom border
830             CPPUNIT_ASSERT_BORDER_EQUAL(aFirstParCharTopBorder, getProperty<table::BorderLine2>(xSet,"CharBottomBorder"));
831             CPPUNIT_ASSERT_EQUAL(aFirstParCharTopPadding, getProperty<sal_Int32>(xSet,"CharBottomBorderDistance"));
832 
833             // Left border
834             CPPUNIT_ASSERT_BORDER_EQUAL(aFirstParCharTopBorder, getProperty<table::BorderLine2>(xSet,"CharLeftBorder"));
835             CPPUNIT_ASSERT_EQUAL(aFirstParCharTopPadding, getProperty<sal_Int32>(xSet,"CharLeftBorderDistance"));
836 
837             // Right border
838             CPPUNIT_ASSERT_BORDER_EQUAL(aFirstParCharTopBorder, getProperty<table::BorderLine2>(xSet,"CharRightBorder"));
839             CPPUNIT_ASSERT_EQUAL(aFirstParCharTopPadding, getProperty<sal_Int32>(xSet,"CharRightBorderDistance"));
840         }
841     }
842 
843     // Second paragraph's second text portion has a character style named CharDiffBor
844     // This style includes border with different sides
845     {
846 
847         table::BorderLine2 aBorderArray[4] =
848         {
849             table::BorderLine2(0xFF3333,0,37,0,14,37),     // Top (fine dashed line)
850             table::BorderLine2(0x99FF66,26,26,53,11,106),  // Bottom
851             table::BorderLine2(0x6666FF,9,26,9,12,71),     // Left
852             table::BorderLine2(0,0,0,0,0,0)                // Right
853         };
854 
855         sal_Int32 aDistances[4] = { 400 /*Top*/, 300 /*Bottom*/, 250 /*Left*/, 0 /*Right*/ };
856 
857         // Get second text portion of second paragraph
858         uno::Reference < beans::XPropertySet > xSet( getRun(getParagraph(2),2), uno::UNO_QUERY );
859 
860         // Top border
861         CPPUNIT_ASSERT_BORDER_EQUAL(aBorderArray[0], getProperty<table::BorderLine2>(xSet,"CharTopBorder"));
862         CPPUNIT_ASSERT_EQUAL(aDistances[0], getProperty<sal_Int32>(xSet,"CharTopBorderDistance"));
863 
864         // Bottom border
865         CPPUNIT_ASSERT_BORDER_EQUAL(aBorderArray[1], getProperty<table::BorderLine2>(xSet,"CharBottomBorder"));
866         CPPUNIT_ASSERT_EQUAL(aDistances[1], getProperty<sal_Int32>(xSet,"CharBottomBorderDistance"));
867 
868         // Left border
869         CPPUNIT_ASSERT_BORDER_EQUAL(aBorderArray[2], getProperty<table::BorderLine2>(xSet,"CharLeftBorder"));
870         CPPUNIT_ASSERT_EQUAL(aDistances[2], getProperty<sal_Int32>(xSet,"CharLeftBorderDistance"));
871 
872         // Right border
873         CPPUNIT_ASSERT_BORDER_EQUAL(aBorderArray[3], getProperty<table::BorderLine2>(xSet,"CharRightBorder"));
874         CPPUNIT_ASSERT_EQUAL(aDistances[3], getProperty<sal_Int32>(xSet,"CharRightBorderDistance"));
875 
876         // Shadow
877         const table::ShadowFormat aShadow = getProperty<table::ShadowFormat>(xSet,"CharShadowFormat");
878         CPPUNIT_ASSERT_EQUAL(sal_Int32(0), aShadow.Color);
879         CPPUNIT_ASSERT_EQUAL(false, static_cast<bool>(aShadow.IsTransparent));
880         CPPUNIT_ASSERT_EQUAL(table::ShadowLocation(3), aShadow.Location);
881         CPPUNIT_ASSERT_EQUAL(sal_Int16(79), aShadow.ShadowWidth);
882 
883         // Check character style
884         {
885             uno::Reference< container::XNameAccess > xStyleFamily = getStyles("CharacterStyles");
886             uno::Reference < beans::XPropertySet > xStyleSet(xStyleFamily->getByName("CharDiffBor"), uno::UNO_QUERY);
887 
888             // Top border
889             CPPUNIT_ASSERT_BORDER_EQUAL(aBorderArray[0], getProperty<table::BorderLine2>(xSet,"CharTopBorder"));
890             CPPUNIT_ASSERT_EQUAL(aDistances[0], getProperty<sal_Int32>(xSet,"CharTopBorderDistance"));
891 
892             // Bottom border
893             CPPUNIT_ASSERT_BORDER_EQUAL(aBorderArray[1], getProperty<table::BorderLine2>(xSet,"CharBottomBorder"));
894             CPPUNIT_ASSERT_EQUAL(aDistances[1], getProperty<sal_Int32>(xSet,"CharBottomBorderDistance"));
895 
896             // Left border
897             CPPUNIT_ASSERT_BORDER_EQUAL(aBorderArray[2], getProperty<table::BorderLine2>(xSet,"CharLeftBorder"));
898             CPPUNIT_ASSERT_EQUAL(aDistances[2], getProperty<sal_Int32>(xSet,"CharLeftBorderDistance"));
899 
900             // Right border
901             CPPUNIT_ASSERT_BORDER_EQUAL(aBorderArray[3], getProperty<table::BorderLine2>(xSet,"CharRightBorder"));
902             CPPUNIT_ASSERT_EQUAL(aDistances[3], getProperty<sal_Int32>(xSet,"CharRightBorderDistance"));
903         }
904     }
905 }
906 
907 DECLARE_ODFEXPORT_TEST(testProtectionKey, "protection-key.fodt")
908 {
909     OUString const password("1012345678901234567890123456789012345678901234567890");
910 
911     // check 1 invalid OOo legacy password and 3 valid ODF 1.2 passwords
912     uno::Reference<text::XTextSectionsSupplier> xTextSectionsSupplier(mxComponent, uno::UNO_QUERY);
913     uno::Reference<container::XIndexAccess> xSections(xTextSectionsSupplier->getTextSections(), uno::UNO_QUERY);
914     uno::Reference<beans::XPropertySet> xSect0(xSections->getByIndex(0), uno::UNO_QUERY);
915     uno::Sequence<sal_Int8> const key0(getProperty<uno::Sequence<sal_Int8>>(xSect0, "ProtectionKey"));
916     CPPUNIT_ASSERT(SvPasswordHelper::CompareHashPassword(key0, password));
917     uno::Reference<beans::XPropertySet> xSect1(xSections->getByIndex(1), uno::UNO_QUERY);
918     uno::Sequence<sal_Int8> const key1(getProperty<uno::Sequence<sal_Int8>>(xSect1, "ProtectionKey"));
919     CPPUNIT_ASSERT(SvPasswordHelper::CompareHashPassword(key1, password));
920     uno::Reference<beans::XPropertySet> xSect2(xSections->getByIndex(2), uno::UNO_QUERY);
921     uno::Sequence<sal_Int8> const key2(getProperty<uno::Sequence<sal_Int8>>(xSect1, "ProtectionKey"));
922     CPPUNIT_ASSERT(SvPasswordHelper::CompareHashPassword(key2, password));
923     uno::Reference<beans::XPropertySet> xSect3(xSections->getByIndex(3), uno::UNO_QUERY);
924     uno::Sequence<sal_Int8> const key3(getProperty<uno::Sequence<sal_Int8>>(xSect1, "ProtectionKey"));
925     CPPUNIT_ASSERT(SvPasswordHelper::CompareHashPassword(key3, password));
926 
927     // we can't assume that the user entered the password; check that we
928     // round-trip the password as-is
929     if (xmlDocPtr pXmlDoc = parseExport("content.xml"))
930     {
931         assertXPath(pXmlDoc, "//text:section[@text:name='Section0' and @text:protected='true' and @text:protection-key='vbnhxyBKtPHCA1wB21zG1Oha8ZA=']");
932         assertXPath(pXmlDoc, "//text:section[@text:name='Section1' and @text:protected='true' and @text:protection-key='nLHas0RIwepGDaH4c2hpyIUvIS8=']");
933         assertXPath(pXmlDoc, "//text:section[@text:name='Section2' and @text:protected='true' and @text:protection-key-digest-algorithm='http://www.w3.org/2000/09/xmldsig#sha256' and @text:protection-key='1tnJohagR2T0yF/v69hLPuumSTsj32CumW97nkKGuSQ=']");
934         assertXPath(pXmlDoc, "//text:section[@text:name='Section3' and @text:protected='true' and @text:protection-key-digest-algorithm='http://www.w3.org/2000/09/xmldsig#sha256' and @text:protection-key='1tnJohagR2T0yF/v69hLPuumSTsj32CumW97nkKGuSQ=']");
935     }
936 }
937 
938 DECLARE_ODFEXPORT_TEST(testTdf128188, "footnote-collect-at-end-of-section.fodt")
939 {
940     SwDoc *const pDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get())->GetDocShell()->GetDoc();
941     CPPUNIT_ASSERT(pDoc);
942     SwFootnoteIdxs const& rFootnotes(pDoc->GetFootnoteIdxs());
943     // Section1
944     CPPUNIT_ASSERT_EQUAL(sal_uInt16(1), rFootnotes[0]->GetFootnote().GetNumber());
945     CPPUNIT_ASSERT_EQUAL(sal_uInt16(1), rFootnotes[0]->GetFootnote().GetNumberRLHidden());
946     CPPUNIT_ASSERT_EQUAL(sal_uInt16(2), rFootnotes[1]->GetFootnote().GetNumber());
947     CPPUNIT_ASSERT_EQUAL(sal_uInt16(2), rFootnotes[1]->GetFootnote().GetNumberRLHidden());
948     // Section2
949     CPPUNIT_ASSERT_EQUAL(sal_uInt16(1), rFootnotes[2]->GetFootnote().GetNumber());
950     CPPUNIT_ASSERT_EQUAL(sal_uInt16(1), rFootnotes[2]->GetFootnote().GetNumberRLHidden());
951     // deleted
952     CPPUNIT_ASSERT_EQUAL(sal_uInt16(2), rFootnotes[3]->GetFootnote().GetNumber());
953     CPPUNIT_ASSERT_EQUAL(sal_uInt16(1), rFootnotes[3]->GetFootnote().GetNumberRLHidden());
954     // deleted
955     CPPUNIT_ASSERT_EQUAL(sal_uInt16(3), rFootnotes[4]->GetFootnote().GetNumber());
956     CPPUNIT_ASSERT_EQUAL(sal_uInt16(1), rFootnotes[4]->GetFootnote().GetNumberRLHidden());
957     CPPUNIT_ASSERT_EQUAL(sal_uInt16(4), rFootnotes[5]->GetFootnote().GetNumber());
958     CPPUNIT_ASSERT_EQUAL(sal_uInt16(2), rFootnotes[5]->GetFootnote().GetNumberRLHidden());
959 }
960 
961 DECLARE_ODFEXPORT_TEST(testFdo43807, "fdo43807.odt")
962 {
963     uno::Reference<beans::XPropertySet> xSet(getParagraph(1), uno::UNO_QUERY);
964     CPPUNIT_ASSERT_EQUAL(OUString("Drop Caps"),getProperty<OUString>(xSet,"DropCapCharStyleName"));
965 
966     xSet.set(getParagraph(2), uno::UNO_QUERY);
967     CPPUNIT_ASSERT_EQUAL(OUString("User Defined Drop Caps"),getProperty<OUString>(xSet,"DropCapCharStyleName"));
968 }
969 
970 DECLARE_ODFEXPORT_TEST(testTdf103091, "tdf103091.fodt")
971 {
972     // check that all conditional paragraph style conditions are imported
973     uno::Reference<container::XNameAccess> xParaStyles(getStyles("ParagraphStyles"));
974     uno::Reference<beans::XPropertySet> xStyle1(xParaStyles->getByName(
975             "Conditional"), uno::UNO_QUERY);
976     auto conditions(getProperty<uno::Sequence<beans::NamedValue>>(xStyle1, "ParaStyleConditions"));
977 
978     CPPUNIT_ASSERT_EQUAL(sal_Int32(28), conditions.getLength());
979     CPPUNIT_ASSERT_EQUAL(OUString("TableHeader"), conditions[0].Name);
980     CPPUNIT_ASSERT_EQUAL(uno::makeAny(OUString("Addressee")), conditions[0].Value);
981     CPPUNIT_ASSERT_EQUAL(OUString("Table"), conditions[1].Name);
982     CPPUNIT_ASSERT_EQUAL(uno::makeAny(OUString("Bibliography 1")), conditions[1].Value);
983     CPPUNIT_ASSERT_EQUAL(OUString("Frame"), conditions[2].Name);
984     CPPUNIT_ASSERT_EQUAL(uno::makeAny(OUString("Bibliography Heading")), conditions[2].Value);
985     CPPUNIT_ASSERT_EQUAL(OUString("Section"), conditions[3].Name);
986     CPPUNIT_ASSERT_EQUAL(uno::makeAny(OUString("Caption")), conditions[3].Value);
987     CPPUNIT_ASSERT_EQUAL(OUString("Footnote"), conditions[4].Name);
988     CPPUNIT_ASSERT_EQUAL(uno::makeAny(OUString("Salutation")), conditions[4].Value);
989     CPPUNIT_ASSERT_EQUAL(OUString("Endnote"), conditions[5].Name);
990     CPPUNIT_ASSERT_EQUAL(uno::makeAny(OUString("Contents 1")), conditions[5].Value);
991     CPPUNIT_ASSERT_EQUAL(OUString("Header"), conditions[6].Name);
992     CPPUNIT_ASSERT_EQUAL(uno::makeAny(OUString("Contents 2")), conditions[6].Value);
993     CPPUNIT_ASSERT_EQUAL(OUString("Footer"), conditions[7].Name);
994     CPPUNIT_ASSERT_EQUAL(uno::makeAny(OUString("Contents 3")), conditions[7].Value);
995     CPPUNIT_ASSERT_EQUAL(OUString("OutlineLevel1"), conditions[8].Name);
996     CPPUNIT_ASSERT_EQUAL(uno::makeAny(OUString("Contents 4")), conditions[8].Value);
997     CPPUNIT_ASSERT_EQUAL(OUString("OutlineLevel2"), conditions[9].Name);
998     CPPUNIT_ASSERT_EQUAL(uno::makeAny(OUString("Contents 5")), conditions[9].Value);
999     CPPUNIT_ASSERT_EQUAL(OUString("OutlineLevel3"), conditions[10].Name);
1000     CPPUNIT_ASSERT_EQUAL(uno::makeAny(OUString("Contents 6")), conditions[10].Value);
1001     CPPUNIT_ASSERT_EQUAL(OUString("OutlineLevel4"), conditions[11].Name);
1002     CPPUNIT_ASSERT_EQUAL(uno::makeAny(OUString("Contents 7")), conditions[11].Value);
1003     CPPUNIT_ASSERT_EQUAL(OUString("OutlineLevel5"), conditions[12].Name);
1004     CPPUNIT_ASSERT_EQUAL(uno::makeAny(OUString("Contents 8")), conditions[12].Value);
1005     CPPUNIT_ASSERT_EQUAL(OUString("OutlineLevel6"), conditions[13].Name);
1006     CPPUNIT_ASSERT_EQUAL(uno::makeAny(OUString("Contents 9")), conditions[13].Value);
1007     CPPUNIT_ASSERT_EQUAL(OUString("OutlineLevel7"), conditions[14].Name);
1008     CPPUNIT_ASSERT_EQUAL(uno::makeAny(OUString("Contents 10")), conditions[14].Value);
1009     CPPUNIT_ASSERT_EQUAL(OUString("OutlineLevel8"), conditions[15].Name);
1010     CPPUNIT_ASSERT_EQUAL(uno::makeAny(OUString("Contents Heading")), conditions[15].Value);
1011     CPPUNIT_ASSERT_EQUAL(OUString("OutlineLevel9"), conditions[16].Name);
1012     CPPUNIT_ASSERT_EQUAL(uno::makeAny(OUString("Standard")), conditions[16].Value);
1013     CPPUNIT_ASSERT_EQUAL(OUString("OutlineLevel10"), conditions[17].Name);
1014     CPPUNIT_ASSERT_EQUAL(uno::makeAny(OUString("Drawing")), conditions[17].Value);
1015     CPPUNIT_ASSERT_EQUAL(OUString("NumberingLevel1"), conditions[18].Name);
1016     CPPUNIT_ASSERT_EQUAL(uno::makeAny(OUString("Endnote")), conditions[18].Value);
1017     CPPUNIT_ASSERT_EQUAL(OUString("NumberingLevel2"), conditions[19].Name);
1018     CPPUNIT_ASSERT_EQUAL(uno::makeAny(OUString("First line indent")), conditions[19].Value);
1019     CPPUNIT_ASSERT_EQUAL(OUString("NumberingLevel3"), conditions[20].Name);
1020     CPPUNIT_ASSERT_EQUAL(uno::makeAny(OUString("Footer")), conditions[20].Value);
1021     CPPUNIT_ASSERT_EQUAL(OUString("NumberingLevel4"), conditions[21].Name);
1022     CPPUNIT_ASSERT_EQUAL(uno::makeAny(OUString("Footer left")), conditions[21].Value);
1023     CPPUNIT_ASSERT_EQUAL(OUString("NumberingLevel5"), conditions[22].Name);
1024     CPPUNIT_ASSERT_EQUAL(uno::makeAny(OUString("Footer right")), conditions[22].Value);
1025     CPPUNIT_ASSERT_EQUAL(OUString("NumberingLevel6"), conditions[23].Name);
1026     CPPUNIT_ASSERT_EQUAL(uno::makeAny(OUString("Footnote")), conditions[23].Value);
1027     CPPUNIT_ASSERT_EQUAL(OUString("NumberingLevel7"), conditions[24].Name);
1028     CPPUNIT_ASSERT_EQUAL(uno::makeAny(OUString("Frame contents")), conditions[24].Value);
1029     CPPUNIT_ASSERT_EQUAL(OUString("NumberingLevel8"), conditions[25].Name);
1030     CPPUNIT_ASSERT_EQUAL(uno::makeAny(OUString("Hanging indent")), conditions[25].Value);
1031     CPPUNIT_ASSERT_EQUAL(OUString("NumberingLevel9"), conditions[26].Name);
1032     CPPUNIT_ASSERT_EQUAL(uno::makeAny(OUString("Header")), conditions[26].Value);
1033     CPPUNIT_ASSERT_EQUAL(OUString("NumberingLevel10"), conditions[27].Name);
1034     CPPUNIT_ASSERT_EQUAL(uno::makeAny(OUString("Header left")), conditions[27].Value);
1035 }
1036 
1037 DECLARE_ODFEXPORT_TEST(testTextframeTransparentShadow, "textframe-transparent-shadow.odt")
1038 {
1039     uno::Reference<drawing::XShape> xPicture = getShape(1);
1040     // ODF stores opacity of 75%, that means 25% transparency.
1041     CPPUNIT_ASSERT_EQUAL(sal_Int32(25), getProperty<sal_Int32>(xPicture, "ShadowTransparence"));
1042 }
1043 
1044 DECLARE_ODFEXPORT_TEST(testRelhPage, "relh-page.odt")
1045 {
1046     uno::Reference<drawing::XShape> xTextFrame = getShape(1);
1047     // This was text::RelOrientation::FRAME (the default), RelativeHeightRelation was not handled in xmloff.
1048     CPPUNIT_ASSERT_EQUAL(text::RelOrientation::PAGE_FRAME, getProperty<sal_Int16>(xTextFrame, "RelativeHeightRelation"));
1049     // Make sure rel-height-rel doesn't affect width.
1050     CPPUNIT_ASSERT_EQUAL(text::RelOrientation::FRAME, getProperty<sal_Int16>(xTextFrame, "RelativeWidthRelation"));
1051 
1052     // This was 2601, 20% height was relative from margin, not page.
1053     CPPUNIT_ASSERT_EQUAL(sal_Int32(3168), parseDump("/root/page/body/txt/anchored/fly/infos/bounds", "height").toInt32());
1054 }
1055 
1056 DECLARE_ODFEXPORT_TEST(testRelhPageTdf80282, "relh-page-tdf80282.odt")
1057 {
1058     uno::Reference<drawing::XShape> xTextFrame = getShape(1);
1059     CPPUNIT_ASSERT_EQUAL_MESSAGE("Height", sal_Int32(8391), parseDump("//anchored/fly/infos/bounds", "height").toInt32());
1060     CPPUNIT_ASSERT_EQUAL_MESSAGE("Width",  sal_Int32(5953), parseDump("//anchored/fly/infos/bounds", "width").toInt32());
1061 }
1062 
1063 DECLARE_ODFEXPORT_TEST(testRelwPage, "relw-page.odt")
1064 {
1065     uno::Reference<drawing::XShape> xTextFrame = getShape(1);
1066     // This was text::RelOrientation::FRAME (the default), RelativeWidthRelation was not handled in xmloff.
1067     CPPUNIT_ASSERT_EQUAL(text::RelOrientation::PAGE_FRAME, getProperty<sal_Int16>(xTextFrame, "RelativeWidthRelation"));
1068     // Make sure rel-width-rel doesn't affect height.
1069     CPPUNIT_ASSERT_EQUAL(text::RelOrientation::FRAME, getProperty<sal_Int16>(xTextFrame, "RelativeHeightRelation"));
1070 
1071     // This was 3762, 40% width was relative from margin, not page.
1072     CPPUNIT_ASSERT_EQUAL(sal_Int32(4896), parseDump("/root/page/body/txt/anchored/fly/infos/bounds", "width").toInt32());
1073 }
1074 
1075 DECLARE_ODFEXPORT_TEST(testTextFrameVertAdjust, "textframe-vertadjust.odt")
1076 {
1077     // Test import/export of new frame attribute called TextVerticalAdjust
1078 
1079     // 1st frame's context is adjusted to the top
1080     uno::Reference<beans::XPropertySet> xFrame(getTextFrameByName("Rectangle 1"), uno::UNO_QUERY);
1081     CPPUNIT_ASSERT_EQUAL(drawing::TextVerticalAdjust_TOP, getProperty<drawing::TextVerticalAdjust>(xFrame, "TextVerticalAdjust"));
1082     // 2nd frame's context is adjusted to the center
1083     xFrame.set(getTextFrameByName("Rectangle 2"), uno::UNO_QUERY);
1084     CPPUNIT_ASSERT_EQUAL(drawing::TextVerticalAdjust_CENTER, getProperty<drawing::TextVerticalAdjust>(xFrame, "TextVerticalAdjust"));
1085     // 3rd frame's context is adjusted to the bottom
1086     xFrame.set(getTextFrameByName("Rectangle 3"), uno::UNO_QUERY);
1087     CPPUNIT_ASSERT_EQUAL(drawing::TextVerticalAdjust_BOTTOM, getProperty<drawing::TextVerticalAdjust>(xFrame, "TextVerticalAdjust"));
1088 }
1089 
1090 DECLARE_ODFEXPORT_TEST(testTdf111891_frameVertStyle, "tdf111891_frameVertStyle.odt")
1091 {
1092     uno::Reference<beans::XPropertySet> xFrame(getShape(1), uno::UNO_QUERY);
1093     CPPUNIT_ASSERT_EQUAL(drawing::TextVerticalAdjust_BOTTOM, getProperty<drawing::TextVerticalAdjust>(xFrame, "TextVerticalAdjust"));
1094 }
1095 
1096 DECLARE_ODFEXPORT_TEST(testShapeRelsize, "shape-relsize.odt")
1097 {
1098     uno::Reference<drawing::XShape> xShape = getShape(1);
1099     // These were all 0, as style:rel-width/height was ignored on import for shapes.
1100     CPPUNIT_ASSERT_EQUAL(sal_Int16(40), getProperty<sal_Int16>(xShape, "RelativeWidth"));
1101     CPPUNIT_ASSERT_EQUAL(sal_Int16(20), getProperty<sal_Int16>(xShape, "RelativeHeight"));
1102 
1103     // Relation was "page" for both width and height, should be "paragraph" for width.
1104     CPPUNIT_ASSERT_EQUAL(text::RelOrientation::FRAME, getProperty<sal_Int16>(xShape, "RelativeWidthRelation"));
1105     // And make sure that height stays "page".
1106     CPPUNIT_ASSERT_EQUAL(text::RelOrientation::PAGE_FRAME, getProperty<sal_Int16>(xShape, "RelativeHeightRelation"));
1107 }
1108 
1109 DECLARE_ODFEXPORT_TEST(testTextboxRoundedCorners, "textbox-rounded-corners.odt")
1110 {
1111     uno::Reference<drawing::XShape> xShape = getShape(1);
1112     comphelper::SequenceAsHashMap aCustomShapeGeometry(getProperty< uno::Sequence<beans::PropertyValue> >(xShape, "CustomShapeGeometry"));
1113 
1114     // Test that the shape is a rounded rectangle.
1115     CPPUNIT_ASSERT_EQUAL(OUString("round-rectangle"), aCustomShapeGeometry["Type"].get<OUString>());
1116 
1117     // The shape text should start with a table, with "a" in its A1 cell.
1118     uno::Reference<text::XText> xText = uno::Reference<text::XTextRange>(xShape, uno::UNO_QUERY_THROW)->getText();
1119     uno::Reference<text::XTextTable> xTable(getParagraphOrTable(1, xText), uno::UNO_QUERY);
1120     uno::Reference<text::XTextRange> xCell(xTable->getCellByName("A1"), uno::UNO_QUERY);
1121     CPPUNIT_ASSERT_EQUAL(OUString("a"), xCell->getString());
1122 
1123     // Table inside a textbox should be in the extension namespace.
1124     if (xmlDocPtr pXmlDoc = parseExport("content.xml"))
1125         // This failed, as draw:custom-shape had a table:table child.
1126         assertXPath(pXmlDoc, "//draw:custom-shape/loext:table", "name", "Table1");
1127 }
1128 
1129 // test that import whitespace collapsing is compatible with old docs
1130 DECLARE_ODFEXPORT_TEST(testWhitespace, "whitespace.odt")
1131 {
1132     uno::Reference<container::XEnumerationAccess> xPara;
1133     uno::Reference<container::XEnumeration> xPortions;
1134     uno::Reference<text::XTextRange> xPortion;
1135     xPara.set(getParagraphOrTable(1), uno::UNO_QUERY);
1136     xPortions.set(xPara->createEnumeration());
1137     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1138     CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty<OUString>(xPortion, "TextPortionType"));
1139     CPPUNIT_ASSERT_EQUAL(OUString("X "), xPortion->getString());
1140     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1141     CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty<OUString>(xPortion, "TextPortionType"));
1142     CPPUNIT_ASSERT_EQUAL(OUString(" "), xPortion->getString());
1143     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1144     CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty<OUString>(xPortion, "TextPortionType"));
1145     CPPUNIT_ASSERT_EQUAL(OUString(" X"), xPortion->getString());
1146     CPPUNIT_ASSERT(!xPortions->hasMoreElements());
1147 
1148     xPara.set(getParagraphOrTable(2), uno::UNO_QUERY);
1149     xPortions.set(xPara->createEnumeration());
1150     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1151     CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty<OUString>(xPortion, "TextPortionType"));
1152     CPPUNIT_ASSERT_EQUAL(OUString("X "), xPortion->getString());
1153     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1154     CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty<OUString>(xPortion, "TextPortionType"));
1155     CPPUNIT_ASSERT_EQUAL(OUString(" "), xPortion->getString());
1156     CPPUNIT_ASSERT_EQUAL(OUString("http://example.com/"), getProperty<OUString>(xPortion, "HyperLinkURL"));
1157     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1158     CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty<OUString>(xPortion, "TextPortionType"));
1159     CPPUNIT_ASSERT_EQUAL(OUString(" X"), xPortion->getString());
1160     CPPUNIT_ASSERT(!xPortions->hasMoreElements());
1161 
1162     xPara.set(getParagraphOrTable(3), uno::UNO_QUERY);
1163     xPortions.set(xPara->createEnumeration());
1164     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1165     CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty<OUString>(xPortion, "TextPortionType"));
1166     CPPUNIT_ASSERT_EQUAL(OUString("X "), xPortion->getString());
1167     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1168     CPPUNIT_ASSERT_EQUAL(OUString("Ruby"), getProperty<OUString>(xPortion, "TextPortionType"));
1169     CPPUNIT_ASSERT_EQUAL(OUString(), xPortion->getString());
1170     CPPUNIT_ASSERT_EQUAL(OUString("foo"), getProperty<OUString>(xPortion, "RubyText"));
1171     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1172     CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty<OUString>(xPortion, "TextPortionType"));
1173     CPPUNIT_ASSERT_EQUAL(OUString(" "), xPortion->getString());
1174     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1175     CPPUNIT_ASSERT_EQUAL(OUString("Ruby"), getProperty<OUString>(xPortion, "TextPortionType"));
1176     CPPUNIT_ASSERT_EQUAL(OUString(), xPortion->getString());
1177     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1178     CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty<OUString>(xPortion, "TextPortionType"));
1179     CPPUNIT_ASSERT_EQUAL(OUString(" X"), xPortion->getString());
1180     CPPUNIT_ASSERT(!xPortions->hasMoreElements());
1181 
1182     xPara.set(getParagraphOrTable(4), uno::UNO_QUERY);
1183     xPortions.set(xPara->createEnumeration());
1184     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1185     CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty<OUString>(xPortion, "TextPortionType"));
1186     CPPUNIT_ASSERT_EQUAL(OUString("X "), xPortion->getString());
1187     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1188     CPPUNIT_ASSERT_EQUAL(OUString("InContentMetadata"), getProperty<OUString>(xPortion, "TextPortionType"));
1189     {
1190         // what a stupid idea to require recursively enumerating this
1191         uno::Reference<container::XEnumerationAccess> xMeta(
1192             getProperty<uno::Reference<text::XTextContent>>(xPortion, "InContentMetadata"), uno::UNO_QUERY);
1193         uno::Reference<container::XEnumeration> xMetaPortions =
1194             xMeta->createEnumeration();
1195         uno::Reference<text::XTextRange> xMP(xMetaPortions->nextElement(), uno::UNO_QUERY);
1196         CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty<OUString>(xMP, "TextPortionType"));
1197         CPPUNIT_ASSERT_EQUAL(OUString(" "), xMP->getString());
1198         CPPUNIT_ASSERT(!xMetaPortions->hasMoreElements());
1199     }
1200     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1201     CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty<OUString>(xPortion, "TextPortionType"));
1202     CPPUNIT_ASSERT_EQUAL(OUString(" X"), xPortion->getString());
1203     CPPUNIT_ASSERT(!xPortions->hasMoreElements());
1204 
1205     xPara.set(getParagraphOrTable(5), uno::UNO_QUERY);
1206     xPortions.set(xPara->createEnumeration());
1207     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1208     CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty<OUString>(xPortion, "TextPortionType"));
1209     CPPUNIT_ASSERT_EQUAL(OUString("X "), xPortion->getString());
1210     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1211     CPPUNIT_ASSERT_EQUAL(OUString("TextField"), getProperty<OUString>(xPortion, "TextPortionType"));
1212     {
1213         // what a stupid idea to require recursively enumerating this
1214         uno::Reference<container::XEnumerationAccess> xMeta(
1215             getProperty<uno::Reference<text::XTextContent>>(xPortion, "TextField"), uno::UNO_QUERY);
1216         uno::Reference<container::XEnumeration> xMetaPortions =
1217             xMeta->createEnumeration();
1218         uno::Reference<text::XTextRange> xMP(xMetaPortions->nextElement(), uno::UNO_QUERY);
1219         CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty<OUString>(xMP, "TextPortionType"));
1220         CPPUNIT_ASSERT_EQUAL(OUString(" "), xMP->getString());
1221         CPPUNIT_ASSERT(!xMetaPortions->hasMoreElements());
1222     }
1223     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1224     CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty<OUString>(xPortion, "TextPortionType"));
1225     CPPUNIT_ASSERT_EQUAL(OUString(" X"), xPortion->getString());
1226     CPPUNIT_ASSERT(!xPortions->hasMoreElements());
1227 
1228     xPara.set(getParagraphOrTable(7), uno::UNO_QUERY);
1229     xPortions.set(xPara->createEnumeration());
1230     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1231     CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty<OUString>(xPortion, "TextPortionType"));
1232     CPPUNIT_ASSERT_EQUAL(OUString("X "), xPortion->getString());
1233     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1234     CPPUNIT_ASSERT_EQUAL(OUString("Frame"), getProperty<OUString>(xPortion, "TextPortionType"));
1235     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1236     CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty<OUString>(xPortion, "TextPortionType"));
1237     CPPUNIT_ASSERT_EQUAL(OUString(" X"), xPortion->getString());
1238     CPPUNIT_ASSERT(!xPortions->hasMoreElements());
1239 
1240     xPara.set(getParagraphOrTable(8), uno::UNO_QUERY);
1241     xPortions.set(xPara->createEnumeration());
1242     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1243     CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty<OUString>(xPortion, "TextPortionType"));
1244     CPPUNIT_ASSERT_EQUAL(OUString("X "), xPortion->getString());
1245     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1246     CPPUNIT_ASSERT_EQUAL(OUString("Frame"), getProperty<OUString>(xPortion, "TextPortionType"));
1247     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1248     CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty<OUString>(xPortion, "TextPortionType"));
1249     CPPUNIT_ASSERT_EQUAL(OUString(" X"), xPortion->getString());
1250     CPPUNIT_ASSERT(!xPortions->hasMoreElements());
1251 
1252     xPara.set(getParagraphOrTable(9), uno::UNO_QUERY);
1253     xPortions.set(xPara->createEnumeration());
1254     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1255     CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty<OUString>(xPortion, "TextPortionType"));
1256     CPPUNIT_ASSERT_EQUAL(OUString("X "), xPortion->getString());
1257     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1258     CPPUNIT_ASSERT_EQUAL(OUString("Frame"), getProperty<OUString>(xPortion, "TextPortionType"));
1259     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1260     CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty<OUString>(xPortion, "TextPortionType"));
1261     CPPUNIT_ASSERT_EQUAL(OUString(" X"), xPortion->getString());
1262     CPPUNIT_ASSERT(!xPortions->hasMoreElements());
1263 
1264     xPara.set(getParagraphOrTable(10), uno::UNO_QUERY);
1265     uno::Reference<container::XContentEnumerationAccess> xCEA(xPara, uno::UNO_QUERY);
1266     uno::Reference<container::XEnumeration> xFrames(
1267             xCEA->createContentEnumeration("com.sun.star.text.TextContent"));
1268     xFrames->nextElement(); // one at-paragraph frame
1269     CPPUNIT_ASSERT(!xFrames->hasMoreElements());
1270     xPortions.set(xPara->createEnumeration());
1271     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1272     CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty<OUString>(xPortion, "TextPortionType"));
1273     CPPUNIT_ASSERT_EQUAL(OUString(" X"), xPortion->getString());
1274     CPPUNIT_ASSERT(!xPortions->hasMoreElements());
1275 
1276     xPara.set(getParagraphOrTable(11), uno::UNO_QUERY);
1277     xPortions.set(xPara->createEnumeration());
1278     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1279     CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty<OUString>(xPortion, "TextPortionType"));
1280     CPPUNIT_ASSERT_EQUAL(OUString("X "), xPortion->getString());
1281     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1282     CPPUNIT_ASSERT_EQUAL(OUString("Footnote"), getProperty<OUString>(xPortion, "TextPortionType"));
1283     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1284     CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty<OUString>(xPortion, "TextPortionType"));
1285     CPPUNIT_ASSERT_EQUAL(OUString(" X"), xPortion->getString());
1286     CPPUNIT_ASSERT(!xPortions->hasMoreElements());
1287 
1288     xPara.set(getParagraphOrTable(12), uno::UNO_QUERY);
1289     xPortions.set(xPara->createEnumeration());
1290     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1291     CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty<OUString>(xPortion, "TextPortionType"));
1292     CPPUNIT_ASSERT_EQUAL(OUString("X "), xPortion->getString());
1293     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1294     CPPUNIT_ASSERT_EQUAL(OUString("TextField"), getProperty<OUString>(xPortion, "TextPortionType"));
1295     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1296     CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty<OUString>(xPortion, "TextPortionType"));
1297     CPPUNIT_ASSERT_EQUAL(OUString(" X"), xPortion->getString());
1298     CPPUNIT_ASSERT(!xPortions->hasMoreElements());
1299 
1300     xPara.set(getParagraphOrTable(13), uno::UNO_QUERY);
1301     xPortions.set(xPara->createEnumeration());
1302     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1303     CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty<OUString>(xPortion, "TextPortionType"));
1304     CPPUNIT_ASSERT_EQUAL(OUString("X "), xPortion->getString());
1305     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1306     CPPUNIT_ASSERT_EQUAL(OUString("Annotation"), getProperty<OUString>(xPortion, "TextPortionType"));
1307     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1308     CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty<OUString>(xPortion, "TextPortionType"));
1309     CPPUNIT_ASSERT_EQUAL(OUString(" "), xPortion->getString());
1310     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1311     CPPUNIT_ASSERT_EQUAL(OUString("AnnotationEnd"), getProperty<OUString>(xPortion, "TextPortionType"));
1312     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1313     CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty<OUString>(xPortion, "TextPortionType"));
1314     CPPUNIT_ASSERT_EQUAL(OUString(" X"), xPortion->getString());
1315     CPPUNIT_ASSERT(!xPortions->hasMoreElements());
1316 
1317     xPara.set(getParagraphOrTable(15), uno::UNO_QUERY);
1318     xPortions.set(xPara->createEnumeration());
1319     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1320     CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty<OUString>(xPortion, "TextPortionType"));
1321     CPPUNIT_ASSERT_EQUAL(OUString("X "), xPortion->getString());
1322     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1323     CPPUNIT_ASSERT_EQUAL(OUString("Bookmark"), getProperty<OUString>(xPortion, "TextPortionType"));
1324     CPPUNIT_ASSERT(getProperty<bool>(xPortion, "IsCollapsed"));
1325     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1326     CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty<OUString>(xPortion, "TextPortionType"));
1327     CPPUNIT_ASSERT_EQUAL(OUString(" X"), xPortion->getString());
1328     CPPUNIT_ASSERT(!xPortions->hasMoreElements());
1329 
1330     xPara.set(getParagraphOrTable(16), uno::UNO_QUERY);
1331     xPortions.set(xPara->createEnumeration());
1332     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1333     CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty<OUString>(xPortion, "TextPortionType"));
1334     CPPUNIT_ASSERT_EQUAL(OUString("X "), xPortion->getString());
1335     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1336     CPPUNIT_ASSERT_EQUAL(OUString("Bookmark"), getProperty<OUString>(xPortion, "TextPortionType"));
1337     CPPUNIT_ASSERT(!getProperty<bool>(xPortion, "IsCollapsed"));
1338     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1339     CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty<OUString>(xPortion, "TextPortionType"));
1340     CPPUNIT_ASSERT_EQUAL(OUString(" "), xPortion->getString());
1341     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1342     CPPUNIT_ASSERT_EQUAL(OUString("Bookmark"), getProperty<OUString>(xPortion, "TextPortionType"));
1343     CPPUNIT_ASSERT(!getProperty<bool>(xPortion, "IsCollapsed"));
1344     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1345     CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty<OUString>(xPortion, "TextPortionType"));
1346     CPPUNIT_ASSERT_EQUAL(OUString(" X"), xPortion->getString());
1347     CPPUNIT_ASSERT(!xPortions->hasMoreElements());
1348 
1349     xPara.set(getParagraphOrTable(17), uno::UNO_QUERY);
1350     xPortions.set(xPara->createEnumeration());
1351     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1352     CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty<OUString>(xPortion, "TextPortionType"));
1353     CPPUNIT_ASSERT_EQUAL(OUString("X "), xPortion->getString());
1354     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1355     CPPUNIT_ASSERT_EQUAL(OUString("Redline"), getProperty<OUString>(xPortion, "TextPortionType"));
1356     CPPUNIT_ASSERT(!getProperty<bool>(xPortion, "IsCollapsed"));
1357     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1358     CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty<OUString>(xPortion, "TextPortionType"));
1359     CPPUNIT_ASSERT_EQUAL(OUString(" "), xPortion->getString());
1360     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1361     CPPUNIT_ASSERT_EQUAL(OUString("Redline"), getProperty<OUString>(xPortion, "TextPortionType"));
1362     CPPUNIT_ASSERT(!getProperty<bool>(xPortion, "IsCollapsed"));
1363     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1364     CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty<OUString>(xPortion, "TextPortionType"));
1365     CPPUNIT_ASSERT_EQUAL(OUString(" X"), xPortion->getString());
1366     CPPUNIT_ASSERT(!xPortions->hasMoreElements());
1367 
1368     xPara.set(getParagraphOrTable(18), uno::UNO_QUERY);
1369     xPortions.set(xPara->createEnumeration());
1370     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1371     CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty<OUString>(xPortion, "TextPortionType"));
1372     CPPUNIT_ASSERT_EQUAL(OUString("X "), xPortion->getString());
1373     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1374     CPPUNIT_ASSERT_EQUAL(OUString("Redline"), getProperty<OUString>(xPortion, "TextPortionType"));
1375     CPPUNIT_ASSERT(!getProperty<bool>(xPortion, "IsCollapsed"));
1376     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1377     CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty<OUString>(xPortion, "TextPortionType"));
1378     CPPUNIT_ASSERT_EQUAL(OUString(" "), xPortion->getString());
1379     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1380     CPPUNIT_ASSERT_EQUAL(OUString("Redline"), getProperty<OUString>(xPortion, "TextPortionType"));
1381     CPPUNIT_ASSERT(!getProperty<bool>(xPortion, "IsCollapsed"));
1382     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1383     CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty<OUString>(xPortion, "TextPortionType"));
1384     CPPUNIT_ASSERT_EQUAL(OUString(" X"), xPortion->getString());
1385     CPPUNIT_ASSERT(!xPortions->hasMoreElements());
1386 
1387     xPara.set(getParagraphOrTable(19), uno::UNO_QUERY);
1388     xPortions.set(xPara->createEnumeration());
1389     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1390     CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty<OUString>(xPortion, "TextPortionType"));
1391     CPPUNIT_ASSERT_EQUAL(OUString("X "), xPortion->getString());
1392     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1393     CPPUNIT_ASSERT_EQUAL(OUString("ReferenceMark"), getProperty<OUString>(xPortion, "TextPortionType"));
1394     CPPUNIT_ASSERT(getProperty<bool>(xPortion, "IsCollapsed"));
1395     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1396     CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty<OUString>(xPortion, "TextPortionType"));
1397     CPPUNIT_ASSERT_EQUAL(OUString(" X"), xPortion->getString());
1398     CPPUNIT_ASSERT(!xPortions->hasMoreElements());
1399 
1400     xPara.set(getParagraphOrTable(20), uno::UNO_QUERY);
1401     xPortions.set(xPara->createEnumeration());
1402     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1403     CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty<OUString>(xPortion, "TextPortionType"));
1404     CPPUNIT_ASSERT_EQUAL(OUString("X "), xPortion->getString());
1405     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1406     CPPUNIT_ASSERT_EQUAL(OUString("ReferenceMark"), getProperty<OUString>(xPortion, "TextPortionType"));
1407     CPPUNIT_ASSERT(!getProperty<bool>(xPortion, "IsCollapsed"));
1408     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1409     CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty<OUString>(xPortion, "TextPortionType"));
1410     CPPUNIT_ASSERT_EQUAL(OUString(" "), xPortion->getString());
1411     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1412     CPPUNIT_ASSERT_EQUAL(OUString("ReferenceMark"), getProperty<OUString>(xPortion, "TextPortionType"));
1413     CPPUNIT_ASSERT(!getProperty<bool>(xPortion, "IsCollapsed"));
1414     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1415     CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty<OUString>(xPortion, "TextPortionType"));
1416     CPPUNIT_ASSERT_EQUAL(OUString(" X"), xPortion->getString());
1417     CPPUNIT_ASSERT(!xPortions->hasMoreElements());
1418 
1419     xPara.set(getParagraphOrTable(21), uno::UNO_QUERY);
1420     xPortions.set(xPara->createEnumeration());
1421     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1422     CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty<OUString>(xPortion, "TextPortionType"));
1423     CPPUNIT_ASSERT_EQUAL(OUString("X "), xPortion->getString());
1424     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1425     CPPUNIT_ASSERT_EQUAL(OUString("DocumentIndexMark"), getProperty<OUString>(xPortion, "TextPortionType"));
1426     CPPUNIT_ASSERT(getProperty<bool>(xPortion, "IsCollapsed"));
1427     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1428     CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty<OUString>(xPortion, "TextPortionType"));
1429     CPPUNIT_ASSERT_EQUAL(OUString(" X"), xPortion->getString());
1430     CPPUNIT_ASSERT(!xPortions->hasMoreElements());
1431 
1432     xPara.set(getParagraphOrTable(22), uno::UNO_QUERY);
1433     xPortions.set(xPara->createEnumeration());
1434     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1435     CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty<OUString>(xPortion, "TextPortionType"));
1436     CPPUNIT_ASSERT_EQUAL(OUString("X "), xPortion->getString());
1437     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1438     CPPUNIT_ASSERT_EQUAL(OUString("DocumentIndexMark"), getProperty<OUString>(xPortion, "TextPortionType"));
1439     CPPUNIT_ASSERT(!getProperty<bool>(xPortion, "IsCollapsed"));
1440     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1441     CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty<OUString>(xPortion, "TextPortionType"));
1442     CPPUNIT_ASSERT_EQUAL(OUString(" "), xPortion->getString());
1443     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1444     CPPUNIT_ASSERT_EQUAL(OUString("DocumentIndexMark"), getProperty<OUString>(xPortion, "TextPortionType"));
1445     CPPUNIT_ASSERT(!getProperty<bool>(xPortion, "IsCollapsed"));
1446     xPortion.set(xPortions->nextElement(), uno::UNO_QUERY);
1447     CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty<OUString>(xPortion, "TextPortionType"));
1448     CPPUNIT_ASSERT_EQUAL(OUString(" X"), xPortion->getString());
1449     CPPUNIT_ASSERT(!xPortions->hasMoreElements());
1450 }
1451 
1452 DECLARE_ODFEXPORT_TEST(testBtlrCell, "btlr-cell.odt")
1453 {
1454     // Without the accompanying fix in place, this test would have failed, as
1455     // the btlr text direction in the A1 cell was lost on ODF import and
1456     // export.
1457     uno::Reference<text::XTextTablesSupplier> xSupplier(mxComponent, uno::UNO_QUERY);
1458     uno::Reference<container::XNameAccess> xTables = xSupplier->getTextTables();
1459     uno::Reference<text::XTextTable> xTable(xTables->getByName("Table1"), uno::UNO_QUERY);
1460     uno::Reference<beans::XPropertySet> xA1(xTable->getCellByName("A1"), uno::UNO_QUERY);
1461     CPPUNIT_ASSERT_EQUAL(text::WritingMode2::BT_LR, getProperty<sal_Int16>(xA1, "WritingMode"));
1462 
1463     uno::Reference<beans::XPropertySet> xB1(xTable->getCellByName("B1"), uno::UNO_QUERY);
1464     auto nActual = getProperty<sal_Int16>(xB1, "WritingMode");
1465     CPPUNIT_ASSERT(nActual == text::WritingMode2::LR_TB || nActual == text::WritingMode2::CONTEXT);
1466 
1467     uno::Reference<beans::XPropertySet> xC1(xTable->getCellByName("C1"), uno::UNO_QUERY);
1468     CPPUNIT_ASSERT_EQUAL(text::WritingMode2::TB_RL, getProperty<sal_Int16>(xC1, "WritingMode"));
1469 }
1470 
1471 DECLARE_ODFEXPORT_TEST(testBtlrFrame, "btlr-frame.odt")
1472 {
1473     // Without the accompanying fix in place, this test would have failed, as
1474     // the btlr text direction in the text frame was lost on ODF import and
1475     // export.
1476     uno::Reference<beans::XPropertySet> xTextFrame(getShape(1), uno::UNO_QUERY);
1477     CPPUNIT_ASSERT(xTextFrame.is());
1478 
1479     auto nActual = getProperty<sal_Int16>(xTextFrame, "WritingMode");
1480     CPPUNIT_ASSERT_EQUAL(text::WritingMode2::BT_LR, nActual);
1481 
1482     // Without the accompanying fix in place, this test would have failed, as the fly frame had
1483     // mbVertical==true, but mbVertLRBT==false, even if the writing direction in the doc model was
1484     // btlr.
1485     SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument *>(mxComponent.get());
1486     CPPUNIT_ASSERT(pTextDoc);
1487 
1488     SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc();
1489     CPPUNIT_ASSERT(pDoc);
1490 
1491     SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
1492     CPPUNIT_ASSERT(pLayout);
1493 
1494     SwFrame* pPageFrame = pLayout->GetLower();
1495     CPPUNIT_ASSERT(pPageFrame);
1496     CPPUNIT_ASSERT(pPageFrame->IsPageFrame());
1497 
1498     SwFrame* pBodyFrame = pPageFrame->GetLower();
1499     CPPUNIT_ASSERT(pBodyFrame);
1500     CPPUNIT_ASSERT(pBodyFrame->IsBodyFrame());
1501 
1502     SwFrame* pBodyTextFrame = pBodyFrame->GetLower();
1503     CPPUNIT_ASSERT(pBodyTextFrame);
1504     CPPUNIT_ASSERT(pBodyTextFrame->IsTextFrame());
1505 
1506     CPPUNIT_ASSERT(pBodyTextFrame->GetDrawObjs());
1507     const SwSortedObjs& rAnchored = *pBodyTextFrame->GetDrawObjs();
1508     CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rAnchored.size());
1509 
1510     auto* pFlyFrame = dynamic_cast<SwFlyFrame*>(rAnchored[0]);
1511     CPPUNIT_ASSERT(pFlyFrame);
1512     CPPUNIT_ASSERT(pFlyFrame->IsVertLRBT());
1513 
1514     if (!mbExported)
1515         // Not yet exported, don't modify the doc model for test purposes.
1516         return;
1517 
1518     // Make sure that btlr -> tbrl transition clears the "BT" flag.
1519     xTextFrame->setPropertyValue("WritingMode", uno::makeAny(static_cast<sal_Int16>(text::WritingMode2::TB_LR)));
1520     pFlyFrame = dynamic_cast<SwFlyFrame*>(rAnchored[0]);
1521     CPPUNIT_ASSERT(pFlyFrame);
1522     CPPUNIT_ASSERT(!pFlyFrame->IsVertLRBT());
1523 }
1524 
1525 DECLARE_ODFEXPORT_TEST(testFdo86963, "fdo86963.odt")
1526 {
1527     // Export of this document failed with beans::UnknownPropertyException.
1528     uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY);
1529     uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage();
1530     CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xDrawPage->getCount());
1531 }
1532 
1533 // Check for correct header/footer with special first page with TOC inside:
1534 // - DECLARE_ODFEXPORT_TEST(testTdf118393, "tdf118393.odt")
1535 // - DECLARE_OOXMLEXPORT_TEST(testTdf118393, "tdf118393.odt")
1536 DECLARE_ODFEXPORT_TEST(testTdf118393, "tdf118393.odt")
1537 {
1538     CPPUNIT_ASSERT_EQUAL( 7, getPages() );
1539 
1540     // First page has no header/footer
1541     {
1542         xmlDocPtr pXmlDoc = parseLayoutDump();
1543 
1544         // check first page
1545         xmlXPathObjectPtr pXmlPage1Header = getXPathNode(pXmlDoc, "/root/page[1]/header");
1546         CPPUNIT_ASSERT_EQUAL(0, xmlXPathNodeSetGetLength(pXmlPage1Header->nodesetval));
1547 
1548         xmlXPathObjectPtr pXmlPage1Footer = getXPathNode(pXmlDoc, "/root/page[1]/footer");
1549         CPPUNIT_ASSERT_EQUAL(0, xmlXPathNodeSetGetLength(pXmlPage1Footer->nodesetval));
1550 
1551         // check second page in the same way
1552         xmlXPathObjectPtr pXmlPage2Header = getXPathNode(pXmlDoc, "/root/page[2]/header");
1553         CPPUNIT_ASSERT_EQUAL(1, xmlXPathNodeSetGetLength(pXmlPage2Header->nodesetval));
1554 
1555         xmlXPathObjectPtr pXmlPage2Footer = getXPathNode(pXmlDoc, "/root/page[2]/footer");
1556         CPPUNIT_ASSERT_EQUAL(1, xmlXPathNodeSetGetLength(pXmlPage2Footer->nodesetval));
1557    }
1558 
1559     // All other pages should have header/footer
1560 
1561     CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"),   parseDump("/root/page[2]/header/txt/text()"));
1562     CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"),   parseDump("/root/page[2]/footer/txt/text()"));
1563 
1564     CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"),   parseDump("/root/page[3]/header/txt/text()"));
1565     CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"),   parseDump("/root/page[3]/footer/txt/text()"));
1566 
1567     CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"),   parseDump("/root/page[4]/header/txt/text()"));
1568     CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"),   parseDump("/root/page[4]/footer/txt/text()"));
1569 
1570     CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"),   parseDump("/root/page[5]/header/txt/text()"));
1571     CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"),   parseDump("/root/page[5]/footer/txt/text()"));
1572 
1573     CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"),   parseDump("/root/page[6]/header/txt/text()"));
1574     CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"),   parseDump("/root/page[6]/footer/txt/text()"));
1575 
1576     CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"),   parseDump("/root/page[7]/header/txt/text()"));
1577     CPPUNIT_ASSERT_EQUAL(OUString("Seite * von *"),   parseDump("/root/page[7]/footer/txt/text()"));
1578 }
1579 
1580 DECLARE_ODFEXPORT_TEST(testGerrit13858, "gerrit13858.odt")
1581 {
1582     // Just make sure the output is valid.
1583 }
1584 DECLARE_ODFEXPORT_TEST(testOdtBorderTypes, "border_types.odt")
1585 {
1586     static const sal_Int32 lineStyles[] = { 0, 1, 2, 14, 16, 17, 3, 15 };
1587     uno::Reference<text::XTextDocument> textDocument(mxComponent, uno::UNO_QUERY);
1588     uno::Reference<container::XEnumerationAccess> xParaEnumAccess(textDocument->getText(), uno::UNO_QUERY);
1589     // list of paragraphs
1590     uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
1591     do
1592     {
1593         uno::Reference<lang::XServiceInfo> xServiceInfo;
1594         if (xParaEnum->nextElement() >>= xServiceInfo)
1595         {
1596             if (xServiceInfo->supportsService("com.sun.star.text.TextTable"))
1597             {
1598                 uno::Reference<table::XCellRange> const xCellRange(xServiceInfo, uno::UNO_QUERY_THROW);
1599 
1600                 for (sal_Int32 row = 0; row < 15; row += 2)
1601                 {
1602                     uno::Reference<table::XCell> xCell = xCellRange->getCellByPosition(1, row);
1603                     uno::Reference< beans::XPropertySet > xPropSet(xCell, uno::UNO_QUERY_THROW);
1604 
1605                     uno::Any aTopBorder = xPropSet->getPropertyValue("TopBorder");
1606                     table::BorderLine2 aTopBorderLine;
1607                     if (aTopBorder >>= aTopBorderLine)
1608                     {
1609                         sal_Int32 lineStyle = aTopBorderLine.LineStyle;
1610                         CPPUNIT_ASSERT_EQUAL(lineStyles[row / 2], lineStyle);
1611                     }
1612                 }   //end of the 'for' loop
1613             }
1614         }
1615     } while (xParaEnum->hasMoreElements());
1616 }
1617 
1618 DECLARE_ODFEXPORT_TEST(testMasterPageWithDrawingPage, "sw_hatch.odt")
1619 {
1620     uno::Reference<container::XNameAccess> xStyles(getStyles("PageStyles"));
1621     uno::Reference<beans::XPropertySet> xStyle(xStyles->getByName("Standard"), uno::UNO_QUERY);
1622     CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_HATCH, getProperty<drawing::FillStyle>(xStyle, "FillStyle"));
1623     CPPUNIT_ASSERT_EQUAL(OUString("Blue -45 Degrees"), getProperty<OUString>(xStyle, "FillHatchName"));
1624     CPPUNIT_ASSERT(!getProperty<sal_Bool>(xStyle, "FillBackground"));
1625     CPPUNIT_ASSERT_EQUAL(sal_Int16(0), getProperty<sal_Int16>(xStyle, "FillTransparence"));
1626 }
1627 
1628 DECLARE_ODFEXPORT_TEST(testCellUserDefineAttr, "userdefattr-tablecell.odt")
1629 {
1630     uno::Reference<text::XTextTable> xTable(getParagraphOrTable(1), uno::UNO_QUERY);
1631     uno::Reference<table::XCell> const xCellA1(xTable->getCellByName("A1"), uno::UNO_SET_THROW);
1632     uno::Reference<table::XCell> const xCellB1(xTable->getCellByName("B1"), uno::UNO_SET_THROW);
1633     uno::Reference<table::XCell> const xCellC1(xTable->getCellByName("C1"), uno::UNO_SET_THROW);
1634     getUserDefineAttribute(uno::makeAny(xCellA1), "proName", "v1");
1635     getUserDefineAttribute(uno::makeAny(xCellB1), "proName", "v2");
1636     getUserDefineAttribute(uno::makeAny(xCellC1), "proName", "v3");
1637 }
1638 
1639 #if HAVE_FEATURE_PDFIUM
1640 DECLARE_ODFEXPORT_TEST(testEmbeddedPdf, "embedded-pdf.odt")
1641 {
1642     uno::Reference<drawing::XShape> xShape = getShape(1);
1643     // This failed, pdf+png replacement graphics pair didn't survive an ODT roundtrip.
1644     auto xReplacementGraphic = getProperty<uno::Reference<graphic::XGraphic>>(xShape, "ReplacementGraphic");
1645     CPPUNIT_ASSERT(xReplacementGraphic.is());
1646 
1647     auto xGraphic = getProperty<uno::Reference<graphic::XGraphic>>(xShape, "Graphic");
1648     CPPUNIT_ASSERT(xGraphic.is());
1649     // This was image/x-vclgraphic, not exposing the info that the image is a PDF one.
1650     CPPUNIT_ASSERT_EQUAL(OUString("application/pdf"), getProperty<OUString>(xGraphic, "MimeType"));
1651 
1652     if (mbExported)
1653     {
1654         uno::Sequence<uno::Any> aArgs(1);
1655         aArgs[0] <<= maTempFile.GetURL();
1656         uno::Reference<container::XNameAccess> xNameAccess(m_xSFactory->createInstanceWithArguments("com.sun.star.packages.zip.ZipFileAccess", aArgs), uno::UNO_QUERY);
1657         bool bHasBitmap = false;
1658         const uno::Sequence<OUString> aNames = xNameAccess->getElementNames();
1659         for (const auto& rElementName : aNames)
1660         {
1661             if (rElementName.startsWith("Pictures") && rElementName.endsWith("png"))
1662             {
1663                 bHasBitmap = true;
1664                 break;
1665             }
1666         }
1667         // This failed, replacement was an svm file.
1668         CPPUNIT_ASSERT(bHasBitmap);
1669     }
1670 }
1671 #endif
1672 
1673 DECLARE_ODFEXPORT_TEST(testTableStyles1, "table_styles_1.odt")
1674 {
1675     // Table styles basic graphic test.
1676     // Doesn't cover all attributes.
1677     uno::Reference<style::XStyleFamiliesSupplier> XFamiliesSupplier(mxComponent, uno::UNO_QUERY);
1678     uno::Reference<container::XNameAccess> xFamilies(XFamiliesSupplier->getStyleFamilies());
1679     uno::Reference<container::XNameAccess> xCellFamily(xFamilies->getByName("CellStyles"), uno::UNO_QUERY);
1680     uno::Reference<beans::XPropertySet> xCell1Style;
1681     xCellFamily->getByName("Test style.1") >>= xCell1Style;
1682 
1683     sal_Int64 nInt64 = 0xF0F0F0;
1684     sal_Int32 nInt32 = 0xF0F0F0;
1685     table::BorderLine2 oBorder;
1686 
1687     xCell1Style->getPropertyValue("BackColor") >>= nInt64;
1688     CPPUNIT_ASSERT_EQUAL(sal_Int64(0xCC0000), nInt64);
1689     xCell1Style->getPropertyValue("WritingMode") >>= nInt32;
1690     CPPUNIT_ASSERT_EQUAL(sal_Int32(4), nInt32);
1691     xCell1Style->getPropertyValue("VertOrient") >>= nInt32;
1692     CPPUNIT_ASSERT_EQUAL(sal_Int32(0), nInt32);
1693     xCell1Style->getPropertyValue("BorderDistance") >>= nInt32;
1694     CPPUNIT_ASSERT_EQUAL(sal_Int32(97), nInt32);
1695     xCell1Style->getPropertyValue("LeftBorderDistance") >>= nInt32;
1696     CPPUNIT_ASSERT_EQUAL(sal_Int32(97), nInt32);
1697     xCell1Style->getPropertyValue("RightBorderDistance") >>= nInt32;
1698     CPPUNIT_ASSERT_EQUAL(sal_Int32(97), nInt32);
1699     xCell1Style->getPropertyValue("TopBorderDistance") >>= nInt32;
1700     CPPUNIT_ASSERT_EQUAL(sal_Int32(97), nInt32);
1701     xCell1Style->getPropertyValue("BottomBorderDistance") >>= nInt32;
1702     CPPUNIT_ASSERT_EQUAL(sal_Int32(97), nInt32);
1703     xCell1Style->getPropertyValue("RightBorder") >>= oBorder;
1704     CPPUNIT_ASSERT_EQUAL(sal_Int32(0), oBorder.Color);
1705     xCell1Style->getPropertyValue("LeftBorder") >>= oBorder;
1706     CPPUNIT_ASSERT_EQUAL(sal_Int32(0), oBorder.Color);
1707     xCell1Style->getPropertyValue("TopBorder") >>= oBorder;
1708     CPPUNIT_ASSERT_EQUAL(sal_Int32(0), oBorder.Color);
1709     xCell1Style->getPropertyValue("BottomBorder") >>= oBorder;
1710     CPPUNIT_ASSERT_EQUAL(sal_Int32(0), oBorder.Color);
1711 }
1712 
1713 DECLARE_ODFEXPORT_TEST(testTableStyles2, "table_styles_2.odt")
1714 {
1715     // Table styles paragraph and char tests
1716     // Doesn't cover all attributes.
1717     // Problem: underline for table autoformat doesn't work.
1718     uno::Reference<style::XStyleFamiliesSupplier> XFamiliesSupplier(mxComponent, uno::UNO_QUERY);
1719     uno::Reference<container::XNameAccess> xFamilies(XFamiliesSupplier->getStyleFamilies());
1720     uno::Reference<container::XNameAccess> xTableFamily(xFamilies->getByName("TableStyles"), uno::UNO_QUERY);
1721     uno::Reference<container::XNameAccess> xTableStyle(xTableFamily->getByName("Test style2"), uno::UNO_QUERY);
1722     uno::Reference<beans::XPropertySet> xCell1Style;
1723 
1724     float fFloat = 0.;
1725     bool bBool = true;
1726     sal_Int16 nInt16 = 0xF0;
1727     sal_Int32 nInt32 = 0xF0F0F0;
1728     sal_Int64 nInt64 = 0xF0F0F0;
1729     OUString sString;
1730     awt::FontSlant eCharPosture;
1731 
1732     // cell 1
1733     xTableStyle->getByName("first-row-start-column") >>= xCell1Style;
1734     xCell1Style->getPropertyValue("ParaAdjust") >>= nInt32;
1735     CPPUNIT_ASSERT_EQUAL(sal_Int32(0), nInt32);
1736     xCell1Style->getPropertyValue("CharColor") >>= nInt64;
1737     CPPUNIT_ASSERT_EQUAL(sal_Int64(0xFF6600), nInt64);
1738     xCell1Style->getPropertyValue("CharContoured") >>= bBool;
1739     CPPUNIT_ASSERT_EQUAL(false, bBool);
1740     xCell1Style->getPropertyValue("CharShadowed") >>= bBool;
1741     CPPUNIT_ASSERT_EQUAL(true, bBool);
1742     xCell1Style->getPropertyValue("CharStrikeout") >>= nInt32;
1743     CPPUNIT_ASSERT_EQUAL(sal_Int32(1), nInt32);
1744     xCell1Style->getPropertyValue("CharUnderline") >>= nInt32;
1745     CPPUNIT_ASSERT_EQUAL(sal_Int32(0), nInt32);
1746     // underline color is not working for table autoformats
1747     // xCell1Style->getPropertyValue("CharUnderlineHasColor") >>= bBool;
1748     // CPPUNIT_ASSERT_EQUAL(bool(false), bBool);
1749     // xCell1Style->getPropertyValue("CharUnderlineColor") >>= nInt64;
1750     // CPPUNIT_ASSERT_EQUAL(sal_Int64(-1), nInt64);
1751     // standard font
1752     xCell1Style->getPropertyValue("CharHeight") >>= fFloat;
1753     CPPUNIT_ASSERT_EQUAL(float(18.), fFloat);
1754     xCell1Style->getPropertyValue("CharWeight") >>= fFloat;
1755     CPPUNIT_ASSERT_EQUAL(float(100.), fFloat);
1756     xCell1Style->getPropertyValue("CharPosture") >>= eCharPosture;
1757     CPPUNIT_ASSERT_EQUAL(awt::FontSlant_NONE, eCharPosture);
1758     xCell1Style->getPropertyValue("CharFontName") >>= sString;
1759     CPPUNIT_ASSERT_EQUAL(OUString("Courier"), sString);
1760     xCell1Style->getPropertyValue("CharFontStyleName") >>= sString;
1761     CPPUNIT_ASSERT_EQUAL(OUString(), sString);
1762     xCell1Style->getPropertyValue("CharFontFamily") >>= nInt16;
1763     CPPUNIT_ASSERT_EQUAL(sal_Int16(2), nInt16);
1764     xCell1Style->getPropertyValue("CharFontPitch") >>= nInt16;
1765     CPPUNIT_ASSERT_EQUAL(sal_Int16(1), nInt16);
1766     // cjk font
1767     xCell1Style->getPropertyValue("CharHeightAsian") >>= fFloat;
1768     CPPUNIT_ASSERT_EQUAL(float(18.), fFloat);
1769     xCell1Style->getPropertyValue("CharWeightAsian") >>= fFloat;
1770     CPPUNIT_ASSERT_EQUAL(float(100.), fFloat);
1771     xCell1Style->getPropertyValue("CharPostureAsian") >>= eCharPosture;
1772     CPPUNIT_ASSERT_EQUAL(awt::FontSlant_NONE, eCharPosture);
1773     xCell1Style->getPropertyValue("CharFontNameAsian") >>= sString;
1774     CPPUNIT_ASSERT_EQUAL(OUString("Courier"), sString);
1775     xCell1Style->getPropertyValue("CharFontStyleNameAsian") >>= sString;
1776     CPPUNIT_ASSERT_EQUAL(OUString("Regularna"), sString);
1777     xCell1Style->getPropertyValue("CharFontFamilyAsian") >>= nInt16;
1778     CPPUNIT_ASSERT_EQUAL(sal_Int16(2), nInt16);
1779     xCell1Style->getPropertyValue("CharFontPitchAsian") >>= nInt16;
1780     CPPUNIT_ASSERT_EQUAL(sal_Int16(1), nInt16);
1781     // ctl font
1782     xCell1Style->getPropertyValue("CharHeightComplex") >>= fFloat;
1783     CPPUNIT_ASSERT_EQUAL(float(18.), fFloat);
1784     xCell1Style->getPropertyValue("CharWeightComplex") >>= fFloat;
1785     CPPUNIT_ASSERT_EQUAL(float(100.), fFloat);
1786     xCell1Style->getPropertyValue("CharPostureComplex") >>= eCharPosture;
1787     CPPUNIT_ASSERT_EQUAL(awt::FontSlant_NONE, eCharPosture);
1788     xCell1Style->getPropertyValue("CharFontNameComplex") >>= sString;
1789     CPPUNIT_ASSERT_EQUAL(OUString("Courier"), sString);
1790     xCell1Style->getPropertyValue("CharFontStyleNameComplex") >>= sString;
1791     CPPUNIT_ASSERT_EQUAL(OUString("Regularna"), sString);
1792     xCell1Style->getPropertyValue("CharFontFamilyComplex") >>= nInt16;
1793     CPPUNIT_ASSERT_EQUAL(sal_Int16(2), nInt16);
1794     xCell1Style->getPropertyValue("CharFontPitchComplex") >>= nInt16;
1795     CPPUNIT_ASSERT_EQUAL(sal_Int16(1), nInt16);
1796 
1797     // cell 2
1798     xTableStyle->getByName("first-row") >>= xCell1Style;
1799     xCell1Style->getPropertyValue("ParaAdjust") >>= nInt32;
1800     CPPUNIT_ASSERT_EQUAL(sal_Int32(3), nInt32);
1801     xCell1Style->getPropertyValue("CharColor") >>= nInt64;
1802     CPPUNIT_ASSERT_EQUAL(sal_Int64(0x9900FF), nInt64);
1803     xCell1Style->getPropertyValue("CharContoured") >>= bBool;
1804     CPPUNIT_ASSERT_EQUAL(true, bBool);
1805     xCell1Style->getPropertyValue("CharShadowed") >>= bBool;
1806     CPPUNIT_ASSERT_EQUAL(false, bBool);
1807     xCell1Style->getPropertyValue("CharStrikeout") >>= nInt32;
1808     CPPUNIT_ASSERT_EQUAL(sal_Int32(0), nInt32);
1809     xCell1Style->getPropertyValue("CharUnderline") >>= nInt32;
1810     CPPUNIT_ASSERT_EQUAL(sal_Int32(2), nInt32);
1811     // underline color test place
1812     // standard font
1813     xCell1Style->getPropertyValue("CharHeight") >>= fFloat;
1814     CPPUNIT_ASSERT_EQUAL(float(12.), fFloat);
1815     xCell1Style->getPropertyValue("CharWeight") >>= fFloat;
1816     CPPUNIT_ASSERT_EQUAL(float(150.), fFloat);
1817     xCell1Style->getPropertyValue("CharPosture") >>= eCharPosture;
1818     CPPUNIT_ASSERT_EQUAL(awt::FontSlant_NONE, eCharPosture);
1819     xCell1Style->getPropertyValue("CharFontName") >>= sString;
1820     CPPUNIT_ASSERT_EQUAL(OUString("Liberation Serif"), sString);
1821     xCell1Style->getPropertyValue("CharFontStyleName") >>= sString;
1822     CPPUNIT_ASSERT_EQUAL(OUString(), sString);
1823     xCell1Style->getPropertyValue("CharFontFamily") >>= nInt16;
1824     CPPUNIT_ASSERT_EQUAL(sal_Int16(3), nInt16);
1825     xCell1Style->getPropertyValue("CharFontPitch") >>= nInt16;
1826     CPPUNIT_ASSERT_EQUAL(sal_Int16(2), nInt16);
1827     // cjk font
1828     xCell1Style->getPropertyValue("CharHeightAsian") >>= fFloat;
1829     CPPUNIT_ASSERT_EQUAL(float(12.), fFloat);
1830     xCell1Style->getPropertyValue("CharWeightAsian") >>= fFloat;
1831     CPPUNIT_ASSERT_EQUAL(float(150.), fFloat);
1832     xCell1Style->getPropertyValue("CharPostureAsian") >>= eCharPosture;
1833     CPPUNIT_ASSERT_EQUAL(awt::FontSlant_NONE, eCharPosture);
1834     xCell1Style->getPropertyValue("CharFontNameAsian") >>= sString;
1835     CPPUNIT_ASSERT_EQUAL(OUString("Liberation Serif"), sString);
1836     xCell1Style->getPropertyValue("CharFontStyleNameAsian") >>= sString;
1837     CPPUNIT_ASSERT_EQUAL(OUString("Pogrubiona"), sString);
1838     xCell1Style->getPropertyValue("CharFontFamilyAsian") >>= nInt16;
1839     CPPUNIT_ASSERT_EQUAL(sal_Int16(3), nInt16);
1840     xCell1Style->getPropertyValue("CharFontPitchAsian") >>= nInt16;
1841     CPPUNIT_ASSERT_EQUAL(sal_Int16(2), nInt16);
1842     // ctl font
1843     xCell1Style->getPropertyValue("CharHeightComplex") >>= fFloat;
1844     CPPUNIT_ASSERT_EQUAL(float(12.), fFloat);
1845     xCell1Style->getPropertyValue("CharWeightComplex") >>= fFloat;
1846     CPPUNIT_ASSERT_EQUAL(float(150.), fFloat);
1847     xCell1Style->getPropertyValue("CharPostureComplex") >>= eCharPosture;
1848     CPPUNIT_ASSERT_EQUAL(awt::FontSlant_NONE, eCharPosture);
1849     xCell1Style->getPropertyValue("CharFontNameComplex") >>= sString;
1850     CPPUNIT_ASSERT_EQUAL(OUString("Liberation Serif"), sString);
1851     xCell1Style->getPropertyValue("CharFontStyleNameComplex") >>= sString;
1852     CPPUNIT_ASSERT_EQUAL(OUString("Pogrubiona"), sString);
1853     xCell1Style->getPropertyValue("CharFontFamilyComplex") >>= nInt16;
1854     CPPUNIT_ASSERT_EQUAL(sal_Int16(3), nInt16);
1855     xCell1Style->getPropertyValue("CharFontPitchComplex") >>= nInt16;
1856     CPPUNIT_ASSERT_EQUAL(sal_Int16(2), nInt16);
1857 
1858     // cell 3
1859     xTableStyle->getByName("first-row-even-column") >>= xCell1Style;
1860     xCell1Style->getPropertyValue("ParaAdjust") >>= nInt32;
1861     CPPUNIT_ASSERT_EQUAL(sal_Int32(1), nInt32);
1862     xCell1Style->getPropertyValue("CharColor") >>= nInt64;
1863     CPPUNIT_ASSERT_EQUAL(sal_Int64(0), nInt64);
1864     xCell1Style->getPropertyValue("CharContoured") >>= bBool;
1865     CPPUNIT_ASSERT_EQUAL(true, bBool);
1866     xCell1Style->getPropertyValue("CharShadowed") >>= bBool;
1867     CPPUNIT_ASSERT_EQUAL(true, bBool);
1868     xCell1Style->getPropertyValue("CharStrikeout") >>= nInt32;
1869     CPPUNIT_ASSERT_EQUAL(sal_Int32(0), nInt32);
1870     xCell1Style->getPropertyValue("CharUnderline") >>= nInt32;
1871     CPPUNIT_ASSERT_EQUAL(sal_Int32(6), nInt32);
1872     // underline color test place
1873     // standard font
1874     xCell1Style->getPropertyValue("CharHeight") >>= fFloat;
1875     CPPUNIT_ASSERT_EQUAL(float(12.), fFloat);
1876     xCell1Style->getPropertyValue("CharWeight") >>= fFloat;
1877     CPPUNIT_ASSERT_EQUAL(float(100.), fFloat);
1878     xCell1Style->getPropertyValue("CharPosture") >>= eCharPosture;
1879     CPPUNIT_ASSERT_EQUAL(awt::FontSlant_ITALIC, eCharPosture);
1880     xCell1Style->getPropertyValue("CharFontName") >>= sString;
1881     CPPUNIT_ASSERT_EQUAL(OUString("Open Sans"), sString);
1882     xCell1Style->getPropertyValue("CharFontStyleName") >>= sString;
1883     CPPUNIT_ASSERT_EQUAL(OUString(), sString);
1884     xCell1Style->getPropertyValue("CharFontFamily") >>= nInt16;
1885     CPPUNIT_ASSERT_EQUAL(sal_Int16(0), nInt16);
1886     xCell1Style->getPropertyValue("CharFontPitch") >>= nInt16;
1887     CPPUNIT_ASSERT_EQUAL(sal_Int16(2), nInt16);
1888     // cjk font
1889     xCell1Style->getPropertyValue("CharHeightAsian") >>= fFloat;
1890     CPPUNIT_ASSERT_EQUAL(float(12.), fFloat);
1891     xCell1Style->getPropertyValue("CharWeightAsian") >>= fFloat;
1892     CPPUNIT_ASSERT_EQUAL(float(100.), fFloat);
1893     xCell1Style->getPropertyValue("CharPostureAsian") >>= eCharPosture;
1894     CPPUNIT_ASSERT_EQUAL(awt::FontSlant_ITALIC, eCharPosture);
1895     xCell1Style->getPropertyValue("CharFontNameAsian") >>= sString;
1896     CPPUNIT_ASSERT_EQUAL(OUString("Open Sans"), sString);
1897     xCell1Style->getPropertyValue("CharFontStyleNameAsian") >>= sString;
1898     CPPUNIT_ASSERT_EQUAL(OUString("Kursywa"), sString);
1899     xCell1Style->getPropertyValue("CharFontFamilyAsian") >>= nInt16;
1900     CPPUNIT_ASSERT_EQUAL(sal_Int16(0), nInt16);
1901     xCell1Style->getPropertyValue("CharFontPitchAsian") >>= nInt16;
1902     CPPUNIT_ASSERT_EQUAL(sal_Int16(2), nInt16);
1903     // ctl font
1904     xCell1Style->getPropertyValue("CharHeightComplex") >>= fFloat;
1905     CPPUNIT_ASSERT_EQUAL(float(12.), fFloat);
1906     xCell1Style->getPropertyValue("CharWeightComplex") >>= fFloat;
1907     CPPUNIT_ASSERT_EQUAL(float(100.), fFloat);
1908     xCell1Style->getPropertyValue("CharPostureComplex") >>= eCharPosture;
1909     CPPUNIT_ASSERT_EQUAL(awt::FontSlant_ITALIC, eCharPosture);
1910     xCell1Style->getPropertyValue("CharFontNameComplex") >>= sString;
1911     CPPUNIT_ASSERT_EQUAL(OUString("Open Sans"), sString);
1912     xCell1Style->getPropertyValue("CharFontStyleNameComplex") >>= sString;
1913     CPPUNIT_ASSERT_EQUAL(OUString("Kursywa"), sString);
1914     xCell1Style->getPropertyValue("CharFontFamilyComplex") >>= nInt16;
1915     CPPUNIT_ASSERT_EQUAL(sal_Int16(0), nInt16);
1916     xCell1Style->getPropertyValue("CharFontPitchComplex") >>= nInt16;
1917     CPPUNIT_ASSERT_EQUAL(sal_Int16(2), nInt16);
1918 }
1919 
1920 DECLARE_ODFEXPORT_TEST(testTableStyles3, "table_styles_3.odt")
1921 {
1922     // This test checks if default valued attributes aren't exported.
1923     xmlDocPtr pXmlDoc = parseExport("styles.xml");
1924     if (!pXmlDoc)
1925         return;
1926 
1927     // <style:paragraph-properties>
1928     // For this element the only exported attributes are: "border-left", "border-bottom"
1929     assertXPathNoAttribute(pXmlDoc, "/office:document-styles/office:styles/style:style[@style:display-name='Test style3.2']/style:table-cell-properties", "background-color");
1930     // border-left place
1931     assertXPathNoAttribute(pXmlDoc, "/office:document-styles/office:styles/style:style[@style:display-name='Test style3.2']/style:table-cell-properties", "border-right");
1932     assertXPathNoAttribute(pXmlDoc, "/office:document-styles/office:styles/style:style[@style:display-name='Test style3.2']/style:table-cell-properties", "border-top");
1933     // border-bottom place
1934     assertXPathNoAttribute(pXmlDoc, "/office:document-styles/office:styles/style:style[@style:display-name='Test style3.2']/style:table-cell-properties", "padding");
1935     assertXPathNoAttribute(pXmlDoc, "/office:document-styles/office:styles/style:style[@style:display-name='Test style3.2']/style:table-cell-properties", "padding-left");
1936     assertXPathNoAttribute(pXmlDoc, "/office:document-styles/office:styles/style:style[@style:display-name='Test style3.2']/style:table-cell-properties", "padding-right");
1937     assertXPathNoAttribute(pXmlDoc, "/office:document-styles/office:styles/style:style[@style:display-name='Test style3.2']/style:table-cell-properties", "padding-top");
1938     assertXPathNoAttribute(pXmlDoc, "/office:document-styles/office:styles/style:style[@style:display-name='Test style3.2']/style:table-cell-properties", "padding-bottom");
1939     assertXPathNoAttribute(pXmlDoc, "/office:document-styles/office:styles/style:style[@style:display-name='Test style3.2']/style:table-cell-properties", "writing-mode");
1940 
1941     // <style:paragraph-properties> should be absent, because it has only "text-align" attribute, which shouldn't be exported.
1942     // Assume that style:paragraph-properties and style:text-properties exists.
1943     assertXPathChildren(pXmlDoc, "/office:document-styles/office:styles/style:style[@style:display-name='Test style3.2']", 2);
1944 
1945     // <style:text-properties>
1946     // For this element the only exported attributes are: "use-window-font-color place", "font-size-asian", "font-name-asian", "font-family-asian", "font-name-complex", "font-family-complex"
1947     // use-window-font-color place
1948     assertXPathNoAttribute(pXmlDoc, "/office:document-styles/office:styles/style:style[@style:display-name='Test style3.2']/style:text-properties", "text-shadow");
1949     assertXPathNoAttribute(pXmlDoc, "/office:document-styles/office:styles/style:style[@style:display-name='Test style3.2']/style:text-properties", "text-outline");
1950     assertXPathNoAttribute(pXmlDoc, "/office:document-styles/office:styles/style:style[@style:display-name='Test style3.2']/style:text-properties", "text-line-through-style");
1951     assertXPathNoAttribute(pXmlDoc, "/office:document-styles/office:styles/style:style[@style:display-name='Test style3.2']/style:text-properties", "text-line-through-type");
1952     assertXPathNoAttribute(pXmlDoc, "/office:document-styles/office:styles/style:style[@style:display-name='Test style3.2']/style:text-properties", "text-underline-style");
1953     assertXPathNoAttribute(pXmlDoc, "/office:document-styles/office:styles/style:style[@style:display-name='Test style3.2']/style:text-properties", "text-underline-color");
1954     assertXPathNoAttribute(pXmlDoc, "/office:document-styles/office:styles/style:style[@style:display-name='Test style3.2']/style:text-properties", "font-size");
1955     assertXPathNoAttribute(pXmlDoc, "/office:document-styles/office:styles/style:style[@style:display-name='Test style3.2']/style:text-properties", "font-weight");
1956     assertXPathNoAttribute(pXmlDoc, "/office:document-styles/office:styles/style:style[@style:display-name='Test style3.2']/style:text-properties", "font-style");
1957     assertXPathNoAttribute(pXmlDoc, "/office:document-styles/office:styles/style:style[@style:display-name='Test style3.2']/style:text-properties", "font-name");
1958     assertXPathNoAttribute(pXmlDoc, "/office:document-styles/office:styles/style:style[@style:display-name='Test style3.2']/style:text-properties", "font-family");
1959     assertXPathNoAttribute(pXmlDoc, "/office:document-styles/office:styles/style:style[@style:display-name='Test style3.2']/style:text-properties", "font-style-name");
1960     assertXPathNoAttribute(pXmlDoc, "/office:document-styles/office:styles/style:style[@style:display-name='Test style3.2']/style:text-properties", "font-family-generic");
1961     assertXPathNoAttribute(pXmlDoc, "/office:document-styles/office:styles/style:style[@style:display-name='Test style3.2']/style:text-properties", "font-pitch");
1962     // font-size-asian place
1963     assertXPathNoAttribute(pXmlDoc, "/office:document-styles/office:styles/style:style[@style:display-name='Test style3.2']/style:text-properties", "font-weight-asian");
1964     assertXPathNoAttribute(pXmlDoc, "/office:document-styles/office:styles/style:style[@style:display-name='Test style3.2']/style:text-properties", "font-style-asian");
1965     // font-name-asian place
1966     // font-family-asian place
1967     assertXPathNoAttribute(pXmlDoc, "/office:document-styles/office:styles/style:style[@style:display-name='Test style3.2']/style:text-properties", "font-style-name-asian");
1968     assertXPathNoAttribute(pXmlDoc, "/office:document-styles/office:styles/style:style[@style:display-name='Test style3.2']/style:text-properties", "font-family-generic-asian");
1969     assertXPathNoAttribute(pXmlDoc, "/office:document-styles/office:styles/style:style[@style:display-name='Test style3.2']/style:text-properties", "font-pitch-asian");
1970     assertXPathNoAttribute(pXmlDoc, "/office:document-styles/office:styles/style:style[@style:display-name='Test style3.2']/style:text-properties", "font-size-complex");
1971     assertXPathNoAttribute(pXmlDoc, "/office:document-styles/office:styles/style:style[@style:display-name='Test style3.2']/style:text-properties", "font-weight-complex");
1972     assertXPathNoAttribute(pXmlDoc, "/office:document-styles/office:styles/style:style[@style:display-name='Test style3.2']/style:text-properties", "font-style-complex");
1973     // font-name-complex place
1974     // font-family-complex place
1975     assertXPathNoAttribute(pXmlDoc, "/office:document-styles/office:styles/style:style[@style:display-name='Test style3.2']/style:text-properties", "font-style-name-complex");
1976     assertXPathNoAttribute(pXmlDoc, "/office:document-styles/office:styles/style:style[@style:display-name='Test style3.2']/style:text-properties", "font-family-generic-complex");
1977     assertXPathNoAttribute(pXmlDoc, "/office:document-styles/office:styles/style:style[@style:display-name='Test style3.2']/style:text-properties", "font-pitch-complex");
1978 
1979 }
1980 
1981 DECLARE_ODFIMPORT_TEST(testTableStyles4, "table_styles_4.odt")
1982 {
1983     // Test if loaded styles overwrite existing styles
1984     uno::Reference<style::XStyleFamiliesSupplier> XFamiliesSupplier(mxComponent, uno::UNO_QUERY);
1985     uno::Reference<container::XNameAccess> xFamilies(XFamiliesSupplier->getStyleFamilies());
1986     uno::Reference<container::XNameAccess> xTableFamily(xFamilies->getByName("TableStyles"), uno::UNO_QUERY);
1987     uno::Reference<container::XNameAccess> xTableStyle(xTableFamily->getByName("Green"), uno::UNO_QUERY);
1988     uno::Reference<beans::XPropertySet> xCell1Style;
1989 
1990     xTableStyle->getByName("first-row-start-column") >>= xCell1Style;
1991     CPPUNIT_ASSERT_EQUAL(sal_Int32(0x00ff00), getProperty<sal_Int32>(xCell1Style, "BackColor"));
1992 }
1993 
1994 DECLARE_ODFEXPORT_TEST(testTableStyles5, "table_styles_5.odt")
1995 {
1996     // Test if cell styles doesn't have a style:parent-style-name attribute.
1997     xmlDocPtr pXmlDoc = parseExport("styles.xml");
1998     if (!pXmlDoc)
1999         return;
2000 
2001     assertXPathNoAttribute(pXmlDoc, "/office:document-styles/office:styles/style:style[@style:display-name='Test style.1']", "parent-style-name");
2002     assertXPathNoAttribute(pXmlDoc, "/office:document-styles/office:styles/style:style[@style:display-name='Test style.2']", "parent-style-name");
2003     assertXPathNoAttribute(pXmlDoc, "/office:document-styles/office:styles/style:style[@style:display-name='Test style.3']", "parent-style-name");
2004     assertXPathNoAttribute(pXmlDoc, "/office:document-styles/office:styles/style:style[@style:display-name='Test style.4']", "parent-style-name");
2005     assertXPathNoAttribute(pXmlDoc, "/office:document-styles/office:styles/style:style[@style:display-name='Test style.5']", "parent-style-name");
2006     assertXPathNoAttribute(pXmlDoc, "/office:document-styles/office:styles/style:style[@style:display-name='Test style.6']", "parent-style-name");
2007     assertXPathNoAttribute(pXmlDoc, "/office:document-styles/office:styles/style:style[@style:display-name='Test style.7']", "parent-style-name");
2008     assertXPathNoAttribute(pXmlDoc, "/office:document-styles/office:styles/style:style[@style:display-name='Test style.8']", "parent-style-name");
2009     assertXPathNoAttribute(pXmlDoc, "/office:document-styles/office:styles/style:style[@style:display-name='Test style.9']", "parent-style-name");
2010     assertXPathNoAttribute(pXmlDoc, "/office:document-styles/office:styles/style:style[@style:display-name='Test style.10']", "parent-style-name");
2011     assertXPathNoAttribute(pXmlDoc, "/office:document-styles/office:styles/style:style[@style:display-name='Test style.11']", "parent-style-name");
2012     assertXPathNoAttribute(pXmlDoc, "/office:document-styles/office:styles/style:style[@style:display-name='Test style.12']", "parent-style-name");
2013     assertXPathNoAttribute(pXmlDoc, "/office:document-styles/office:styles/style:style[@style:display-name='Test style.13']", "parent-style-name");
2014     assertXPathNoAttribute(pXmlDoc, "/office:document-styles/office:styles/style:style[@style:display-name='Test style.14']", "parent-style-name");
2015     assertXPathNoAttribute(pXmlDoc, "/office:document-styles/office:styles/style:style[@style:display-name='Test style.15']", "parent-style-name");
2016     assertXPathNoAttribute(pXmlDoc, "/office:document-styles/office:styles/style:style[@style:display-name='Test style.16']", "parent-style-name");
2017 
2018 }
2019 
2020 DECLARE_ODFEXPORT_TEST(testTdf101710, "tdf101710.odt")
2021 {
2022     // Test that number format of cell styles can be imported and exported.
2023     uno::Reference<beans::XPropertySet> xStyle(getStyles("CellStyles")->getByName("Test Style.11"), uno::UNO_QUERY);
2024     CPPUNIT_ASSERT_EQUAL(sal_uInt32(10104), getProperty<sal_uInt32>(xStyle, "NumberFormat"));
2025 }
2026 
2027 DECLARE_ODFEXPORT_TEST(testImageMimetype, "image-mimetype.odt")
2028 {
2029     // Test that the loext:mimetype attribute is written for exported images, tdf#109202
2030     if (xmlDocPtr pXmlDoc = parseExport("content.xml"))
2031     {
2032         // Original image (svg)
2033         assertXPath(pXmlDoc, "/office:document-content/office:body/office:text/text:p/draw:frame/draw:image[@loext:mime-type='image/svg+xml']");
2034     }
2035 }
2036 
2037 DECLARE_ODFEXPORT_TEST(testEmbeddedFontProps, "embedded-font-props.odt")
2038 {
2039 #if !defined(MACOSX)
2040     // Test that font style/weight of embedded fonts is exposed.
2041     // Test file is a normal ODT, except EmbedFonts is set to true in settings.xml.
2042     if (xmlDocPtr pXmlDoc = parseExport("content.xml"))
2043     {
2044         // These failed, the attributes were missing.
2045         assertXPath(pXmlDoc, "//style:font-face[@style:name='Liberation Serif']/svg:font-face-src/svg:font-face-uri[1]", "font-style", "normal");
2046         assertXPath(pXmlDoc, "//style:font-face[@style:name='Liberation Serif']/svg:font-face-src/svg:font-face-uri[1]", "font-weight", "normal");
2047         assertXPath(pXmlDoc, "//style:font-face[@style:name='Liberation Serif']/svg:font-face-src/svg:font-face-uri[2]", "font-style", "normal");
2048         assertXPath(pXmlDoc, "//style:font-face[@style:name='Liberation Serif']/svg:font-face-src/svg:font-face-uri[2]", "font-weight", "bold");
2049         assertXPath(pXmlDoc, "//style:font-face[@style:name='Liberation Serif']/svg:font-face-src/svg:font-face-uri[3]", "font-style", "italic");
2050         assertXPath(pXmlDoc, "//style:font-face[@style:name='Liberation Serif']/svg:font-face-src/svg:font-face-uri[3]", "font-weight", "normal");
2051         assertXPath(pXmlDoc, "//style:font-face[@style:name='Liberation Serif']/svg:font-face-src/svg:font-face-uri[4]", "font-style", "italic");
2052         assertXPath(pXmlDoc, "//style:font-face[@style:name='Liberation Serif']/svg:font-face-src/svg:font-face-uri[4]", "font-weight", "bold");
2053     }
2054 #endif
2055 }
2056 
2057 DECLARE_ODFEXPORT_TEST(testTdf100492, "tdf100492.odt")
2058 {
2059     uno::Reference<drawing::XShape> xShape = getShape(1);
2060     CPPUNIT_ASSERT(xShape.is());
2061 
2062     // Save the first shape to a SVG
2063     uno::Reference<drawing::XGraphicExportFilter> xGraphicExporter = drawing::GraphicExportFilter::create(comphelper::getProcessComponentContext());
2064     uno::Reference<lang::XComponent> xSourceDoc(xShape, uno::UNO_QUERY);
2065     xGraphicExporter->setSourceDocument(xSourceDoc);
2066 
2067     SvMemoryStream aStream;
2068     uno::Reference<io::XOutputStream> xOutputStream(new utl::OStreamWrapper(aStream));
2069     uno::Sequence<beans::PropertyValue> aDescriptor( comphelper::InitPropertySequence({
2070             { "OutputStream", uno::Any(xOutputStream) },
2071             { "FilterName", uno::Any(OUString("SVG")) }
2072         }));
2073     xGraphicExporter->filter(aDescriptor);
2074     aStream.Seek(STREAM_SEEK_TO_BEGIN);
2075 
2076     // TODO: Disabled. Parsing of SVG gives just root node without any children.
2077     // Reason of such behavior unclear. So XPATH assert fails.
2078 
2079     // Parse resulting SVG as XML file.
2080     // xmlDocPtr pXmlDoc = parseXmlStream(&aStream);
2081 
2082     // Check amount of paths required to draw an arrow.
2083     // Since there are still some empty paths in output test can fail later. There are just two
2084     // really used and visible paths.
2085     //assertXPath(pXmlDoc, "/svg/path", 4);
2086 }
2087 
2088 DECLARE_ODFEXPORT_TEST(testTdf77961, "tdf77961.odt")
2089 {
2090     uno::Reference<container::XNameAccess> xStyles(getStyles("PageStyles"));
2091     uno::Reference<beans::XPropertySet> xStyle(xStyles->getByName("Standard"), uno::UNO_QUERY);
2092     CPPUNIT_ASSERT_EQUAL( false , getProperty<bool>(xStyle, "GridDisplay"));
2093     CPPUNIT_ASSERT_EQUAL( false , getProperty<bool>(xStyle, "GridPrint"));
2094 }
2095 
2096 DECLARE_ODFEXPORT_TEST(testReferenceLanguage, "referencelanguage.odt")
2097 {
2098     // Test loext:reference-language attribute of reference fields
2099     // (used from LibreOffice 6.1, and proposed for next ODF)
2100     const char* aFieldTexts[] = { "A 2", "Az Isten", "Az 50-esek",
2101         "A 2018-asok", "Az egyebek", "A fejezetek",
2102         reinterpret_cast<char const *>(u8"Az „Őseinket...”"), "a 2",
2103         "Az v", "az 1", "Az e", "az 1",
2104         "Az (5)", "az 1", "A 2", "az 1" };
2105     uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
2106     // update "A (4)" to "Az (5)"
2107     uno::Reference<util::XRefreshable>(xTextFieldsSupplier->getTextFields(), uno::UNO_QUERY_THROW)->refresh();
2108 
2109     uno::Reference<container::XEnumerationAccess> xFieldsAccess(xTextFieldsSupplier->getTextFields());
2110     uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration());
2111 
2112     uno::Any aHu = uno::makeAny(OUString("Hu"));
2113     uno::Any ahu = uno::makeAny(OUString("hu"));
2114     for (size_t i = 0; i < SAL_N_ELEMENTS(aFieldTexts); i++)
2115     {
2116         uno::Any aField = xFields->nextElement();
2117         uno::Reference<lang::XServiceInfo> xServiceInfo(aField, uno::UNO_QUERY);
2118         if (xServiceInfo->supportsService("com.sun.star.text.textfield.GetReference"))
2119         {
2120             uno::Reference<beans::XPropertySet> xPropertySet(aField, uno::UNO_QUERY);
2121             uno::Any aLang = xPropertySet->getPropertyValue("ReferenceFieldLanguage");
2122             CPPUNIT_ASSERT_EQUAL(true, aLang == aHu || aLang == ahu);
2123             uno::Reference<text::XTextContent> xField(aField, uno::UNO_QUERY);
2124             CPPUNIT_ASSERT_EQUAL(OUString::fromUtf8(aFieldTexts[i]), xField->getAnchor()->getString());
2125         }
2126     }
2127 }
2128 
2129 DECLARE_ODFEXPORT_TEST(testRubyPosition, "ruby-position.odt")
2130 {
2131     if (xmlDocPtr pXmlDoc = parseExport("content.xml"))
2132     {
2133         assertXPath(pXmlDoc, "//style:style[@style:family='ruby']/style:ruby-properties[@loext:ruby-position='inter-character']", 1);
2134         assertXPath(pXmlDoc, "//style:style[@style:family='ruby']/style:ruby-properties[@style:ruby-position='below']", 1);
2135     }
2136 }
2137 
2138 DECLARE_ODFEXPORT_TEST(testAllowOverlap, "allow-overlap.odt")
2139 {
2140     uno::Reference<drawing::XShape> xShape = getShape(1);
2141     // Without the accompanying fix in place, this test would have failed with:
2142     // - Expression: !getProperty<bool>(xShape, "AllowOverlap")
2143     // i.e. the custom AllowOverlap=false shape property was lost on import/export.
2144     CPPUNIT_ASSERT(!getProperty<bool>(xShape, "AllowOverlap"));
2145     xShape = getShape(2);
2146     CPPUNIT_ASSERT(!getProperty<bool>(xShape, "AllowOverlap"));
2147 }
2148 
2149 DECLARE_ODFEXPORT_TEST(testSignatureLineProperties, "signatureline-properties.fodt")
2150 {
2151     uno::Reference<drawing::XShape> xShape = getShape(1);
2152     CPPUNIT_ASSERT(xShape.is());
2153 
2154     CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xShape, "IsSignatureLine"));
2155     CPPUNIT_ASSERT_EQUAL(OUString("{3C24159B-3B98-4F60-AB52-00E7721758E9}"),
2156                          getProperty<OUString>(xShape, "SignatureLineId"));
2157     CPPUNIT_ASSERT_EQUAL(OUString("John Doe"),
2158                          getProperty<OUString>(xShape, "SignatureLineSuggestedSignerName"));
2159     CPPUNIT_ASSERT_EQUAL(OUString("Farmer"),
2160                          getProperty<OUString>(xShape, "SignatureLineSuggestedSignerTitle"));
2161     CPPUNIT_ASSERT_EQUAL(OUString("john@farmers.org"),
2162                          getProperty<OUString>(xShape, "SignatureLineSuggestedSignerEmail"));
2163     CPPUNIT_ASSERT_EQUAL(OUString("Please farm here."),
2164                          getProperty<OUString>(xShape, "SignatureLineSigningInstructions"));
2165     CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xShape, "SignatureLineCanAddComment"));
2166     CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xShape, "SignatureLineShowSignDate"));
2167 
2168     // tdf#130917 This needs to be always set when importing a doc, ooxml export expects it.
2169     uno::Reference<graphic::XGraphic> xUnsignedGraphic;
2170     uno::Reference<beans::XPropertySet> xProps(xShape, uno::UNO_QUERY);
2171     xProps->getPropertyValue("SignatureLineUnsignedImage") >>= xUnsignedGraphic;
2172     CPPUNIT_ASSERT_EQUAL(true, xUnsignedGraphic.is());
2173 }
2174 
2175 DECLARE_ODFEXPORT_TEST(testQrCodeGenProperties, "qrcode-properties.odt")
2176 {
2177     uno::Reference<drawing::XShape> xShape = getShape(1);
2178     CPPUNIT_ASSERT(xShape.is());
2179 
2180     css::drawing::QRCode aQRCode = getProperty<css::drawing::QRCode>(xShape, "QRCodeProperties");
2181 
2182     CPPUNIT_ASSERT_EQUAL(OUString("www.libreoffice.org"),
2183                          aQRCode.Payload);
2184     CPPUNIT_ASSERT_EQUAL(css::drawing::QRCodeErrorCorrection::LOW,
2185                          aQRCode.ErrorCorrection);
2186     CPPUNIT_ASSERT_EQUAL(sal_Int32(5),
2187                          aQRCode.Border);
2188 }
2189 
2190 DECLARE_ODFEXPORT_TEST(testChapterNumberingNewLine, "chapter-number-new-line.odt")
2191 {
2192     uno::Reference<text::XChapterNumberingSupplier> xNumberingSupplier(mxComponent, uno::UNO_QUERY);
2193     uno::Reference<container::XIndexAccess> xNumberingRules = xNumberingSupplier->getChapterNumberingRules();
2194     comphelper::SequenceAsHashMap hashMap(xNumberingRules->getByIndex(0));
2195 
2196     //This failed Actual Value was LISTTAB instead of NEWLINE
2197     CPPUNIT_ASSERT_EQUAL(
2198         sal_Int16(SvxNumberFormat::NEWLINE), hashMap["LabelFollowedBy"].get<sal_Int16>());
2199 }
2200 
2201 DECLARE_ODFEXPORT_TEST(testSpellOutNumberingTypes, "spellout-numberingtypes.odt")
2202 {
2203     // ordinal indicator, ordinal and cardinal number numbering styles (from LibreOffice 6.1)
2204     static const char* const aFieldTexts[] = { "1st", "Erste", "Eins",  "1.", "Premier", "Un", "1ᵉʳ", "First", "One" };
2205     // fallback for old platforms without std::codecvt and std::regex supports
2206     static const char* const aFieldTextFallbacks[] = { "Ordinal-number 1", "Ordinal 1", "1" };
2207     uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
2208     // update text field content
2209     uno::Reference<util::XRefreshable>(xTextFieldsSupplier->getTextFields(), uno::UNO_QUERY_THROW)->refresh();
2210 
2211     uno::Reference<container::XEnumerationAccess> xFieldsAccess(xTextFieldsSupplier->getTextFields());
2212     uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration());
2213 
2214     for (size_t i = 0; i < SAL_N_ELEMENTS(aFieldTexts); i++)
2215     {
2216         uno::Any aField = xFields->nextElement();
2217         uno::Reference<lang::XServiceInfo> xServiceInfo(aField, uno::UNO_QUERY);
2218         if (xServiceInfo->supportsService("com.sun.star.text.textfield.PageNumber"))
2219         {
2220             uno::Reference<text::XTextContent> xField(aField, uno::UNO_QUERY);
2221             CPPUNIT_ASSERT_EQUAL(true, OUString::fromUtf8(aFieldTexts[i]).equals(xField->getAnchor()->getString()) ||
2222                            OUString::fromUtf8(aFieldTextFallbacks[i%3]).equals(xField->getAnchor()->getString()));
2223         }
2224     }
2225 }
2226 
2227 // MAILMERGE Add conditional to expand / collapse bookmarks
2228 DECLARE_ODFEXPORT_TEST(tdf101856_overlapped, "tdf101856_overlapped.odt")
2229 {
2230     // get bookmark interface
2231     uno::Reference<text::XBookmarksSupplier> xBookmarksSupplier(mxComponent, uno::UNO_QUERY);
2232     uno::Reference<container::XIndexAccess> xBookmarksByIdx(xBookmarksSupplier->getBookmarks(), uno::UNO_QUERY);
2233     uno::Reference<container::XNameAccess> xBookmarksByName = xBookmarksSupplier->getBookmarks();
2234 
2235     // check: we have 2 bookmarks
2236     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2), xBookmarksByIdx->getCount());
2237     CPPUNIT_ASSERT(xBookmarksByName->hasByName("BookmarkNonHidden"));
2238     CPPUNIT_ASSERT(xBookmarksByName->hasByName("BookmarkHidden"));
2239 
2240     // <text:bookmark-start text:name="BookmarkNonHidden"/>
2241     uno::Reference<beans::XPropertySet> xBookmark1(xBookmarksByName->getByName("BookmarkNonHidden"), uno::UNO_QUERY);
2242     CPPUNIT_ASSERT_EQUAL(OUString(""), getProperty<OUString>(xBookmark1, UNO_NAME_BOOKMARK_CONDITION));
2243     CPPUNIT_ASSERT_EQUAL(false, getProperty<bool>(xBookmark1, UNO_NAME_BOOKMARK_HIDDEN));
2244 
2245     // <text:bookmark-start text:name="BookmarkHidden"/>
2246     uno::Reference<beans::XPropertySet> xBookmark2(xBookmarksByName->getByName("BookmarkHidden"), uno::UNO_QUERY);
2247     CPPUNIT_ASSERT_EQUAL(OUString(""), getProperty<OUString>(xBookmark2, UNO_NAME_BOOKMARK_CONDITION));
2248     CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xBookmark2, UNO_NAME_BOOKMARK_HIDDEN));
2249 }
2250 
2251 // MAILMERGE Add conditional to expand / collapse bookmarks
2252 DECLARE_ODFEXPORT_TEST(tdf101856, "tdf101856.odt")
2253 {
2254     // get bookmark interface
2255     uno::Reference<text::XBookmarksSupplier> xBookmarksSupplier(mxComponent, uno::UNO_QUERY);
2256     uno::Reference<container::XIndexAccess> xBookmarksByIdx(xBookmarksSupplier->getBookmarks(), uno::UNO_QUERY);
2257     uno::Reference<container::XNameAccess> xBookmarksByName = xBookmarksSupplier->getBookmarks();
2258 
2259     // check: we have 2 bookmarks
2260     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(5), xBookmarksByIdx->getCount());
2261     CPPUNIT_ASSERT(xBookmarksByName->hasByName("BookmarkVisible"));
2262     CPPUNIT_ASSERT(xBookmarksByName->hasByName("BookmarkHidden"));
2263     CPPUNIT_ASSERT(xBookmarksByName->hasByName("BookmarkVisibleWithCondition"));
2264     CPPUNIT_ASSERT(xBookmarksByName->hasByName("BookmarkNotHiddenWithCondition"));
2265     CPPUNIT_ASSERT(xBookmarksByName->hasByName("BookmarkHiddenWithCondition"));
2266 
2267     // <text:bookmark-start text:name="BookmarkVisible"/>
2268     uno::Reference<beans::XPropertySet> xBookmark1(xBookmarksByName->getByName("BookmarkVisible"), uno::UNO_QUERY);
2269     CPPUNIT_ASSERT_EQUAL(OUString(""), getProperty<OUString>(xBookmark1, UNO_NAME_BOOKMARK_CONDITION));
2270     CPPUNIT_ASSERT_EQUAL(false, getProperty<bool>(xBookmark1, UNO_NAME_BOOKMARK_HIDDEN));
2271 
2272     // <text:bookmark-start text:name="BookmarkHidden" loext:condition="" loext:hidden="true"/>
2273     uno::Reference<beans::XPropertySet> xBookmark2(xBookmarksByName->getByName("BookmarkHidden"), uno::UNO_QUERY);
2274     CPPUNIT_ASSERT_EQUAL(OUString(""), getProperty<OUString>(xBookmark2, UNO_NAME_BOOKMARK_CONDITION));
2275     CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xBookmark2, UNO_NAME_BOOKMARK_HIDDEN));
2276 
2277     // <text:bookmark-start text:name="BookmarkVisibleWithCondition" loext:condition="0==1" loext:hidden="true"/>
2278     uno::Reference<beans::XPropertySet> xBookmark3(xBookmarksByName->getByName("BookmarkVisibleWithCondition"), uno::UNO_QUERY);
2279     CPPUNIT_ASSERT_EQUAL(OUString("0==1"), getProperty<OUString>(xBookmark3, UNO_NAME_BOOKMARK_CONDITION));
2280     CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xBookmark3, UNO_NAME_BOOKMARK_HIDDEN));
2281 
2282     // <text:bookmark-start text:name="BookmarkNotHiddenWithCondition" loext:condition="1==1" loext:hidden="false"/>
2283     //
2284     // The following test doesn't work, while during output in the case of loext:hidden="false".
2285     // no additional parameters are written. Implementation should be reviewed.
2286     //
2287 //    uno::Reference<beans::XPropertySet> xBookmark4(xBookmarksByName->getByName("BookmarkNotHiddenWithCondition"), uno::UNO_QUERY);
2288 //    CPPUNIT_ASSERT_EQUAL(OUString("1==1"), getProperty<OUString>(xBookmark4, UNO_NAME_BOOKMARK_CONDITION));
2289 //    CPPUNIT_ASSERT_EQUAL(false, getProperty<bool>(xBookmark4, UNO_NAME_BOOKMARK_HIDDEN));
2290 
2291     // <text:bookmark-start text:name="BookmarkHiddenWithCondition" loext:condition="1==1" loext:hidden="true"/>
2292     uno::Reference<beans::XPropertySet> xBookmark5(xBookmarksByName->getByName("BookmarkHiddenWithCondition"), uno::UNO_QUERY);
2293     CPPUNIT_ASSERT_EQUAL(OUString("1==1"), getProperty<OUString>(xBookmark5, UNO_NAME_BOOKMARK_CONDITION));
2294     CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xBookmark5, UNO_NAME_BOOKMARK_HIDDEN));
2295 }
2296 
2297 DECLARE_ODFEXPORT_TEST(tdf118502, "tdf118502.odt")
2298 {
2299     uno::Reference<drawing::XShape> xShape = getShape(1);
2300     // Make sure the replacement graphic is still there
2301     // (was gone because the original graphic was not recognized during load)
2302     auto xReplacementGraphic
2303         = getProperty<uno::Reference<graphic::XGraphic>>(xShape, "ReplacementGraphic");
2304     CPPUNIT_ASSERT(xReplacementGraphic.is());
2305 }
2306 
2307 DECLARE_ODFEXPORT_TEST(tdf99631, "tdf99631.docx")
2308 {
2309     // check import of VisualArea settings of the embedded XLSX OLE objects
2310     xmlDocPtr pXmlDoc = parseExport("Object 1/settings.xml");
2311     if (!pXmlDoc)
2312         return;
2313     assertXPathContent(pXmlDoc, "//config:config-item[@config:name='VisibleAreaWidth']", "4515");
2314     assertXPathContent(pXmlDoc, "//config:config-item[@config:name='VisibleAreaHeight']", "903");
2315 
2316     xmlDocPtr pXmlDoc2 = parseExport("Object 2/settings.xml");
2317     if (!pXmlDoc2)
2318         return;
2319     assertXPathContent(pXmlDoc2, "//config:config-item[@config:name='VisibleAreaWidth']", "4515");
2320     assertXPathContent(pXmlDoc2, "//config:config-item[@config:name='VisibleAreaHeight']", "1354");
2321 }
2322 
2323 DECLARE_ODFEXPORT_TEST(tdf128504, "tdf128504.docx")
2324 {
2325     uno::Reference<text::XTextRange> xPara = getParagraph(6);
2326     uno::Reference<beans::XPropertySet> xRun(getRun(xPara,1), uno::UNO_QUERY);
2327     OUString unVisitedStyleName = getProperty<OUString>(xRun, "UnvisitedCharStyleName");
2328     CPPUNIT_ASSERT(!unVisitedStyleName.equalsIgnoreAsciiCase("Internet Link"));
2329     OUString visitedStyleName = getProperty<OUString>(xRun, "VisitedCharStyleName");
2330     CPPUNIT_ASSERT(!visitedStyleName.equalsIgnoreAsciiCase("Visited Internet Link"));
2331 }
2332 
2333 DECLARE_ODFEXPORT_TEST(tdf121658, "tdf121658.odt")
2334 {
2335     uno::Reference<container::XNameAccess> xParaStyles(getStyles("ParagraphStyles"));
2336     uno::Reference<beans::XPropertySet> xStyle1(xParaStyles->getByName(
2337             "Standard"), uno::UNO_QUERY);
2338     CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xStyle1, "ParaHyphenationNoCaps"));
2339 }
2340 
2341 DECLARE_ODFEXPORT_TEST(tdf124470, "tdf124470TableAndEmbeddedUsedFonts.odt")
2342 {
2343     // Table styles were exported out of place, inside font-face-decls.
2344     // Without the fix in place, this will fail already in ODF validation:
2345     // "content.xml[2,2150]:  Error: tag name "style:style" is not allowed. Possible tag names are: <font-face>"
2346 
2347     CPPUNIT_ASSERT_EQUAL(1, getPages());
2348 
2349     if (xmlDocPtr pXmlDoc = parseExport("content.xml"))
2350     {
2351         assertXPath(pXmlDoc, "/office:document-content/office:font-face-decls/style:style", 0);
2352         assertXPath(pXmlDoc, "/office:document-content/office:automatic-styles/style:style[@style:family='table']", 1);
2353         assertXPath(pXmlDoc, "/office:document-content/office:automatic-styles/style:style[@style:family='table-column']", 2);
2354         assertXPath(pXmlDoc, "/office:document-content/office:automatic-styles/style:style[@style:family='paragraph']", 1);
2355     }
2356 }
2357 
2358 DECLARE_ODFEXPORT_TEST(tdf135942, "nestedTableInFooter.odt")
2359 {
2360     // All table autostyles should be collected, including nested, and must not crash.
2361 
2362     CPPUNIT_ASSERT_EQUAL(1, getPages());
2363 
2364     if (xmlDocPtr pXmlDoc = parseExport("styles.xml"))
2365     {
2366         assertXPath(pXmlDoc, "/office:document-styles/office:automatic-styles/style:style[@style:family='table']", 2);
2367     }
2368 }
2369 
2370 CPPUNIT_PLUGIN_IMPLEMENT();
2371 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
2372