Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : */
9 :
10 : #include <swmodeltestbase.hxx>
11 :
12 : #include <com/sun/star/awt/XBitmap.hpp>
13 : #include <com/sun/star/drawing/FillStyle.hpp>
14 : #include <com/sun/star/graphic/XGraphic.hpp>
15 : #include <com/sun/star/style/BreakType.hpp>
16 : #include <com/sun/star/text/FontEmphasis.hpp>
17 : #include <com/sun/star/text/HoriOrientation.hpp>
18 : #include <com/sun/star/text/XTextRangeCompare.hpp>
19 : #include <com/sun/star/text/WritingMode2.hpp>
20 : #include <oox/drawingml/drawingmltypes.hxx>
21 :
22 : #include <string>
23 :
24 122 : class Test : public SwModelTestBase
25 : {
26 : public:
27 122 : Test() : SwModelTestBase("/sw/qa/extras/ooxmlexport/data/", "Office Open XML Text") {}
28 :
29 : protected:
30 : /**
31 : * Blacklist handling
32 : */
33 61 : bool mustTestImportOf(const char* filename) const SAL_OVERRIDE {
34 : const char* aBlacklist[] = {
35 : "math-escape.docx",
36 : "math-mso2k7.docx",
37 : "ImageCrop.docx",
38 : "test_GIF_ImageCrop.docx",
39 : "test_PNG_ImageCrop.docx"
40 61 : };
41 61 : std::vector<const char*> vBlacklist(aBlacklist, aBlacklist + SAL_N_ELEMENTS(aBlacklist));
42 :
43 : // If the testcase is stored in some other format, it's pointless to test.
44 61 : return (OString(filename).endsWith(".docx") && std::find(vBlacklist.begin(), vBlacklist.end(), filename) == vBlacklist.end());
45 : }
46 :
47 : /**
48 : * Validation handling
49 : */
50 61 : bool mustValidate(const char* filename) const SAL_OVERRIDE
51 : {
52 : const char* aWhitelist[] = {
53 : "paragraph-mark-nonempty.odt"
54 61 : };
55 61 : std::vector<const char*> vWhitelist(aWhitelist, aWhitelist + SAL_N_ELEMENTS(aWhitelist));
56 :
57 61 : return std::find(vWhitelist.begin(), vWhitelist.end(), filename) != vWhitelist.end();
58 : }
59 : protected:
60 10 : bool CjkNumberedListTestHelper(sal_Int16 &nValue)
61 : {
62 10 : bool isNumber = false;
63 10 : uno::Reference<text::XTextRange> xPara(getParagraph(1));
64 20 : uno::Reference< beans::XPropertySet > properties( xPara, uno::UNO_QUERY);
65 10 : properties->getPropertyValue("NumberingIsNumber") >>= isNumber;
66 10 : if (!isNumber)
67 0 : return false;
68 20 : uno::Reference<container::XIndexAccess> xLevels( properties->getPropertyValue("NumberingRules"), uno::UNO_QUERY);
69 20 : uno::Sequence< beans::PropertyValue > aPropertyValue;
70 10 : xLevels->getByIndex(0) >>= aPropertyValue;
71 120 : for( int j = 0 ; j< aPropertyValue.getLength() ; ++j)
72 : {
73 120 : beans::PropertyValue aProp= aPropertyValue[j];
74 120 : if (aProp.Name == "NumberingType")
75 : {
76 10 : nValue = aProp.Value.get<sal_Int16>();
77 10 : return true;
78 : }
79 110 : }
80 10 : return false;
81 :
82 : }
83 : };
84 :
85 17 : DECLARE_OOXMLEXPORT_TEST(testfdo81381, "fdo81381.docx")
86 : {
87 2 : if (xmlDocPtr pXmlDoc = parseExport("word/document.xml"))
88 1 : assertXPath(pXmlDoc, "/w:document/w:body/w:p[1]/w:r[1]/w:object[1]/o:OLEObject[1]", "DrawAspect", "Icon");
89 2 : }
90 :
91 17 : DECLARE_OOXMLEXPORT_TEST(testSdtAlias, "sdt-alias.docx")
92 : {
93 2 : xmlDocPtr pXmlDoc = parseExport();
94 2 : if (!pXmlDoc)
95 3 : return;
96 :
97 : // <w:alias> was completely missing.
98 1 : assertXPath(pXmlDoc, "/w:document/w:body/w:sdt/w:sdtPr/w:alias", "val", "Subtitle");
99 : }
100 :
101 17 : DECLARE_OOXMLEXPORT_TEST(testSdtDateCharformat, "sdt-date-charformat.docx")
102 : {
103 2 : if (xmlDocPtr pXmlDoc = parseExport())
104 : {
105 : // character formatting (bold) was missing, this was 0
106 1 : assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:sdt/w:sdtContent/w:r/w:rPr/w:b", 1);
107 : // alias was also missing.
108 1 : assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:sdt/w:sdtPr/w:alias", 1);
109 : }
110 2 : }
111 :
112 17 : DECLARE_OOXMLEXPORT_TEST(testFooterBodyDistance, "footer-body-distance.docx")
113 : {
114 2 : if (xmlDocPtr pXmlDoc = parseExport())
115 : // Page break was exported as section break, this was 0
116 1 : assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:r/w:br", 1);
117 2 : }
118 :
119 17 : DECLARE_OOXMLEXPORT_TEST(testfdo81031, "fdo81031.docx")
120 : {
121 : // vml image was not rendered
122 : // As there are also numPicBullets in the file,
123 : // the fragmentPath was not changed hence relationships were not resolved.
124 :
125 2 : uno::Reference<drawing::XShape> image = getShape(1);
126 4 : uno::Reference<beans::XPropertySet> xImage(image, uno::UNO_QUERY);
127 4 : uno::Reference<graphic::XGraphic> xGraphic = getProperty<uno::Reference<graphic::XGraphic> >(xImage, "Graphic");
128 4 : uno::Reference<awt::XBitmap> xBitmap(xGraphic, uno::UNO_QUERY);
129 2 : CPPUNIT_ASSERT_EQUAL( static_cast<sal_Int32>(381), xBitmap->getSize().Width );
130 4 : CPPUNIT_ASSERT_EQUAL( static_cast<sal_Int32>(148), xBitmap->getSize().Height );
131 2 : }
132 :
133 17 : DECLARE_OOXMLEXPORT_TEST(testPlausableBorder, "plausable-border.docx")
134 : {
135 : // sw::util::IsPlausableSingleWordSection() did not merge two page styles due to borders.
136 2 : if (xmlDocPtr pXmlDoc = parseExport())
137 : // Page break was exported as section break, this was 0
138 1 : assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:r/w:br", 1);
139 2 : }
140 :
141 17 : DECLARE_OOXMLEXPORT_TEST(testUnwantedSectionBreak, "unwanted-section-break.docx")
142 : {
143 2 : if (xmlDocPtr pXmlDoc = parseExport())
144 : // This was 2: an additional sectPr was added to the document.
145 1 : assertXPath(pXmlDoc, "//w:sectPr", 1);
146 2 : }
147 :
148 17 : DECLARE_OOXMLEXPORT_TEST(testfdo80897 , "fdo80897.docx")
149 : {
150 2 : xmlDocPtr pXmlDoc = parseExport();
151 2 : if (!pXmlDoc)
152 3 : return;
153 1 : assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:bodyPr/a:prstTxWarp", "prst", "textTriangle");
154 : }
155 :
156 :
157 :
158 17 : DECLARE_OOXMLEXPORT_TEST(testFdo80997, "fdo80997.docx")
159 : {
160 : // The problem was that the DOCX exporter not able to export text behind textbox, if textbox has a wrap property.
161 2 : uno::Reference< text::XTextRange > xParagraph = getParagraph( 1 );
162 2 : uno::Reference< text::XTextRange > xText = getRun( xParagraph, 1, " text");
163 2 : }
164 :
165 17 : DECLARE_OOXMLEXPORT_TEST(testFdo80902, "fdo80902.docx")
166 : {
167 : // The problem was that the docGrid type was set as default so fix it for other grid type
168 2 : xmlDocPtr pXmlDoc = parseExport("word/document.xml");
169 2 : if (!pXmlDoc)
170 3 : return;
171 :
172 1 : assertXPath(pXmlDoc, "/w:document/w:body/w:sectPr/w:docGrid", "type", "lines");
173 : }
174 :
175 17 : DECLARE_OOXMLEXPORT_TEST(testParaShading, "para-shading.docx")
176 : {
177 : // Make sure the themeColor attribute is not written when it would be empty.
178 2 : if (xmlDocPtr pXmlDoc = parseExport("word/document.xml"))
179 1 : assertXPathNoAttribute(pXmlDoc, "/w:document/w:body/w:p/w:pPr/w:shd", "themeColor");
180 2 : }
181 :
182 17 : DECLARE_OOXMLEXPORT_TEST(testFirstHeaderFooter, "first-header-footer.docx")
183 : {
184 : // Test import and export of a section's headerf/footerf properties.
185 : // (copied from a ww8export test, with doc converted to docx using Word)
186 :
187 : // The document has 6 pages. Note that we don't test if 4 or just 2 page
188 : // styles are created, the point is that layout should be correct.
189 2 : CPPUNIT_ASSERT_EQUAL(OUString("First page header"), parseDump("/root/page[1]/header/txt/text()"));
190 2 : CPPUNIT_ASSERT_EQUAL(OUString("First page footer"), parseDump("/root/page[1]/footer/txt/text()"));
191 2 : CPPUNIT_ASSERT_EQUAL(OUString("Even page header"), parseDump("/root/page[2]/header/txt/text()"));
192 2 : CPPUNIT_ASSERT_EQUAL(OUString("Even page footer"), parseDump("/root/page[2]/footer/txt/text()"));
193 2 : CPPUNIT_ASSERT_EQUAL(OUString("Odd page header"), parseDump("/root/page[3]/header/txt/text()"));
194 2 : CPPUNIT_ASSERT_EQUAL(OUString("Odd page footer"), parseDump("/root/page[3]/footer/txt/text()"));
195 2 : CPPUNIT_ASSERT_EQUAL(OUString("First page header2"), parseDump("/root/page[4]/header/txt/text()"));
196 2 : CPPUNIT_ASSERT_EQUAL(OUString("First page footer 2"), parseDump("/root/page[4]/footer/txt/text()"));
197 2 : CPPUNIT_ASSERT_EQUAL(OUString("Odd page header 2"), parseDump("/root/page[5]/header/txt/text()"));
198 2 : CPPUNIT_ASSERT_EQUAL(OUString("Odd page footer 2"), parseDump("/root/page[5]/footer/txt/text()"));
199 2 : CPPUNIT_ASSERT_EQUAL(OUString("Even page header 2"), parseDump("/root/page[6]/header/txt/text()"));
200 2 : CPPUNIT_ASSERT_EQUAL(OUString("Even page footer 2"), parseDump("/root/page[6]/footer/txt/text()"));
201 2 : }
202 :
203 17 : DECLARE_OOXMLEXPORT_TEST(testFDO83044, "fdo83044.docx")
204 : {
205 2 : xmlDocPtr pXmlDoc = parseExport("word/document.xml");
206 :
207 2 : if (!pXmlDoc)
208 3 : return;
209 :
210 1 : assertXPath(pXmlDoc, "/w:document/w:body/w:sdt/w:sdtPr/w:text", 1);
211 : }
212 :
213 17 : DECLARE_OOXMLEXPORT_TEST(testfdo83428, "fdo83428.docx")
214 : {
215 2 : uno::Reference<document::XDocumentPropertiesSupplier> xDocumentPropertiesSupplier(mxComponent, uno::UNO_QUERY);
216 4 : uno::Reference<document::XDocumentProperties> xProps(xDocumentPropertiesSupplier->getDocumentProperties());
217 4 : uno::Reference<beans::XPropertySet> xUDProps(xProps->getUserDefinedProperties(), uno::UNO_QUERY);
218 4 : CPPUNIT_ASSERT_EQUAL(OUString("Document"), getProperty<OUString>(xUDProps, "Testing"));
219 2 : }
220 :
221 17 : DECLARE_OOXMLEXPORT_TEST(testShapeInFloattable, "shape-in-floattable.docx")
222 : {
223 2 : if (xmlDocPtr pXmlDoc = parseExport("word/document.xml"))
224 : {
225 : // No nested drawingML w:txbxContent.
226 1 : assertXPath(pXmlDoc, "//mc:Choice//w:txbxContent//w:txbxContent", 0);
227 : // Instead, make sure we have a separate shape and group shape:
228 1 : assertXPath(pXmlDoc, "//mc:AlternateContent//mc:Choice[@Requires='wps']", 1);
229 1 : assertXPath(pXmlDoc, "//mc:AlternateContent//mc:Choice[@Requires='wpg']", 1);
230 : }
231 2 : }
232 :
233 17 : DECLARE_OOXMLEXPORT_TEST(testEmptyAnnotationMark, "empty-annotation-mark.docx")
234 : {
235 2 : if (mbExported)
236 : {
237 : // Delete the word that is commented, and save again.
238 1 : uno::Reference<text::XTextRange> xRun = getRun(getParagraph(1), 3);
239 1 : CPPUNIT_ASSERT_EQUAL(OUString("with"), xRun->getString());
240 1 : xRun->setString("");
241 2 : uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY);
242 1 : xStorable->store();
243 :
244 : // Then inspect the OOXML markup of the modified document model.
245 1 : xmlDocPtr pXmlDoc = parseExport("word/document.xml");
246 : // There were two commentReference nodes.
247 1 : assertXPath(pXmlDoc, "//w:commentReference", "id", "0");
248 : // Empty comment range was not ignored on export, this was 1.
249 1 : assertXPath(pXmlDoc, "//w:commentRangeStart", 0);
250 : // Ditto.
251 2 : assertXPath(pXmlDoc, "//w:commentRangeEnd", 0);
252 : }
253 2 : }
254 :
255 17 : DECLARE_OOXMLEXPORT_TEST(testDropdownInCell, "dropdown-in-cell.docx")
256 : {
257 : // First problem: table was missing from the document, this was 0.
258 2 : uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
259 4 : uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY);
260 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount());
261 :
262 : // Second problem: dropdown shape wasn't anchored inside the B1 cell.
263 4 : uno::Reference<text::XTextContent> xShape(getShape(1), uno::UNO_QUERY);
264 4 : uno::Reference<text::XTextRange> xAnchor = xShape->getAnchor();
265 4 : uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY);
266 4 : uno::Reference<text::XTextRange> xCell(xTable->getCellByName("B1"), uno::UNO_QUERY);
267 4 : uno::Reference<text::XTextRangeCompare> xTextRangeCompare(xCell, uno::UNO_QUERY);
268 4 : CPPUNIT_ASSERT_EQUAL(sal_Int16(0), xTextRangeCompare->compareRegionStarts(xAnchor, xCell));
269 2 : }
270 :
271 17 : DECLARE_OOXMLEXPORT_TEST(testTableAlignment, "table-alignment.docx")
272 : {
273 2 : uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
274 4 : uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY);
275 4 : uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY);
276 : // This was LEFT_AND_WIDTH, i.e. table alignment wasn't imported correctly.
277 4 : CPPUNIT_ASSERT_EQUAL(text::HoriOrientation::RIGHT, getProperty<sal_Int16>(xTable, "HoriOrient"));
278 2 : }
279 :
280 17 : DECLARE_OOXMLEXPORT_TEST(testSdtIgnoredFooter, "sdt-ignored-footer.docx")
281 : {
282 2 : if (xmlDocPtr pXmlDoc = parseExport("word/document.xml"))
283 : {
284 : // This was 1, make sure no w:sdt sneaks into the main document from the footer.
285 1 : assertXPath(pXmlDoc, "//w:sdt", 0);
286 : }
287 2 : }
288 :
289 17 : DECLARE_OOXMLEXPORT_TEST(testSdtRunPicture, "sdt-run-picture.docx")
290 : {
291 : // SDT around run was exported as SDT around paragraph
292 2 : if (xmlDocPtr pXmlDoc = parseExport("word/document.xml"))
293 : {
294 : // This was 1: there was an SDT around w:p.
295 1 : assertXPath(pXmlDoc, "//w:body/w:sdt", 0);
296 : // This was 0: there were no SDT around w:r.
297 1 : assertXPath(pXmlDoc, "//w:body/w:p/w:sdt", 1);
298 : }
299 2 : }
300 :
301 17 : DECLARE_OOXMLEXPORT_TEST(testChartDupe, "chart-dupe.docx")
302 : {
303 : // Single chart was exported back as two charts.
304 2 : uno::Reference<text::XTextEmbeddedObjectsSupplier> xTextEmbeddedObjectsSupplier(mxComponent, uno::UNO_QUERY);
305 4 : uno::Reference<container::XIndexAccess> xEmbeddedObjects(xTextEmbeddedObjectsSupplier->getEmbeddedObjects(), uno::UNO_QUERY);
306 : // This was 2, on second import we got a duplicated chart copy.
307 4 : CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xEmbeddedObjects->getCount());
308 2 : }
309 :
310 17 : DECLARE_OOXMLEXPORT_TEST(testPositionAndRotation, "position-and-rotation.docx")
311 : {
312 : // The document should look like: "This line is tricky, <image> because only 'This line is tricky,' is on the left."
313 : // But the image was pushed down, so it did not break the line into two text portions.
314 2 : uno::Reference<drawing::XShape> xShape = getShape(1);
315 : // Should be 1559, was -5639
316 2 : CPPUNIT_ASSERT(xShape->getPosition().X > 1500);
317 : // Should be 88, was 473
318 2 : CPPUNIT_ASSERT(xShape->getPosition().Y < 100);
319 2 : }
320 :
321 17 : DECLARE_OOXMLEXPORT_TEST(testNumberingFont, "numbering-font.docx")
322 : {
323 2 : uno::Reference<beans::XPropertySet> xStyle(getStyles("CharacterStyles")->getByName("ListLabel 1"), uno::UNO_QUERY);
324 : // This was Calibri, i.e. custom font of the numbering itself ("1.\t") was lost on import.
325 2 : CPPUNIT_ASSERT_EQUAL(OUString("Verdana"), getProperty<OUString>(xStyle, "CharFontName"));
326 2 : }
327 :
328 17 : DECLARE_OOXMLEXPORT_TEST(testDrawingmlFlipv, "drawingml-flipv.docx")
329 : {
330 : // The problem was that the shape had vertical flip only, but then we added rotation as well on export.
331 2 : if (xmlDocPtr pXmlDoc = parseExport("word/document.xml"))
332 1 : assertXPathNoAttribute(pXmlDoc, "//a:xfrm", "rot");
333 2 : }
334 :
335 17 : DECLARE_OOXMLEXPORT_TEST(testRot90Fliph, "rot90-fliph.docx")
336 : {
337 : // The problem was that a shape rotation of 90° got turned into 270° after roundtrip.
338 2 : if (xmlDocPtr pXmlDoc = parseExport("word/document.xml"))
339 : {
340 1 : assertXPath(pXmlDoc, "//a:xfrm", "flipH", "1");
341 : // This was 16200000 (270 * 60000).
342 1 : assertXPath(pXmlDoc, "//a:xfrm", "rot", "5400000");
343 : }
344 2 : }
345 :
346 17 : DECLARE_OOXMLEXPORT_TEST(testRot180Flipv, "rot180-flipv.docx")
347 : {
348 : // 180° rotation got lost after roundtrip.
349 2 : if (xmlDocPtr pXmlDoc = parseExport("word/document.xml"))
350 : {
351 1 : assertXPath(pXmlDoc, "//a:xfrm", "flipV", "1");
352 : // This attribute was completely missing.
353 1 : assertXPath(pXmlDoc, "//a:xfrm", "rot", "10800000");
354 : }
355 2 : }
356 :
357 17 : DECLARE_OOXMLEXPORT_TEST(testRot270Flipv, "rot270-flipv.docx")
358 : {
359 : // 270° rotation got turned into 90° after roundtrip.
360 2 : if (xmlDocPtr pXmlDoc = parseExport("word/document.xml"))
361 : {
362 1 : assertXPath(pXmlDoc, "//a:xfrm", "flipV", "1");
363 : // This was 5400000.
364 1 : assertXPath(pXmlDoc, "//a:xfrm", "rot", "16200000");
365 : }
366 2 : }
367 :
368 17 : DECLARE_OOXMLEXPORT_TEST(testMsoPosition, "bnc884615-mso-position.docx")
369 : {
370 2 : if(xmlDocPtr doc = parseExport("word/footer1.xml"))
371 : {
372 : // We write the frames out in different order than they were read, so check it's the correct
373 : // textbox first by checking width. These tests may need reordering if that gets fixed.
374 1 : OUString style1 = getXPath(doc, "/w:ftr/w:p/w:r[3]/mc:AlternateContent/mc:Fallback/w:pict/v:rect", "style");
375 1 : CPPUNIT_ASSERT( style1.indexOf( ";width:531pt;" ) >= 0 );
376 1 : CPPUNIT_ASSERT( style1.indexOf( ";mso-position-vertical-relative:page" ) >= 0 );
377 1 : CPPUNIT_ASSERT( style1.indexOf( ";mso-position-horizontal-relative:page" ) >= 0 );
378 2 : OUString style2 = getXPath(doc, "/w:ftr/w:p/w:r[4]/mc:AlternateContent/mc:Fallback/w:pict/v:rect", "style");
379 1 : CPPUNIT_ASSERT( style2.indexOf( ";width:549pt;" ) >= 0 );
380 1 : CPPUNIT_ASSERT( style2.indexOf( ";mso-position-vertical-relative:text" ) >= 0 );
381 1 : CPPUNIT_ASSERT( style2.indexOf( ";mso-position-horizontal:center" ) >= 0 );
382 1 : CPPUNIT_ASSERT( style2.indexOf( ";mso-position-horizontal-relative:text" ) >= 0 );
383 2 : OUString style3 = getXPath(doc, "/w:ftr/w:p/w:r[5]/mc:AlternateContent/mc:Fallback/w:pict/v:rect", "style");
384 1 : CPPUNIT_ASSERT( style3.indexOf( ";width:36pt;" ) >= 0 );
385 1 : CPPUNIT_ASSERT( style3.indexOf( ";mso-position-horizontal-relative:text" ) >= 0 );
386 2 : CPPUNIT_ASSERT( style3.indexOf( ";mso-position-vertical-relative:text" ) >= 0 );
387 : }
388 2 : if(xmlDocPtr doc = parseExport("word/header1.xml"))
389 : {
390 1 : OUString style1 = getXPath(doc, "/w:hdr/w:p/w:r[2]/mc:AlternateContent/mc:Fallback/w:pict/v:rect", "style");
391 1 : CPPUNIT_ASSERT( style1.indexOf( ";width:335.75pt;" ) >= 0 );
392 1 : CPPUNIT_ASSERT( style1.indexOf( ";mso-position-horizontal-relative:page" ) >= 0 );
393 1 : CPPUNIT_ASSERT( style1.indexOf( ";mso-position-vertical-relative:page" ) >= 0 );
394 2 : OUString style2 = getXPath(doc, "/w:hdr/w:p/w:r[3]/mc:AlternateContent/mc:Fallback/w:pict/v:rect", "style");
395 1 : CPPUNIT_ASSERT( style2.indexOf( ";width:138.15pt;" ) >= 0 );
396 1 : CPPUNIT_ASSERT( style2.indexOf( ";mso-position-horizontal-relative:page" ) >= 0 );
397 1 : CPPUNIT_ASSERT( style2.indexOf( ";mso-position-vertical-relative:page" ) >= 0 );
398 2 : OUString style3 = getXPath(doc, "/w:hdr/w:p/w:r[4]/mc:AlternateContent/mc:Fallback/w:pict/v:rect", "style");
399 1 : CPPUNIT_ASSERT( style3.indexOf( ";width:163.8pt;" ) >= 0 );
400 1 : CPPUNIT_ASSERT( style3.indexOf( ";mso-position-horizontal-relative:page" ) >= 0 );
401 2 : CPPUNIT_ASSERT( style3.indexOf( ";mso-position-vertical-relative:page" ) >= 0 );
402 : }
403 2 : }
404 :
405 17 : DECLARE_OOXMLEXPORT_TEST(testWpsCharColor, "wps-char-color.docx")
406 : {
407 2 : uno::Reference<text::XTextRange> xShape(getShape(1), uno::UNO_QUERY);
408 : // This was -1, i.e. the character color was default (-1), not white.
409 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(0xffffff), getProperty<sal_Int32>(xShape->getStart(), "CharColor"));
410 2 : }
411 :
412 17 : DECLARE_OOXMLEXPORT_TEST(testTableStyleCellBackColor, "table-style-cell-back-color.docx")
413 : {
414 : // The problem was that cell background was white, not green.
415 2 : uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
416 4 : uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(), uno::UNO_QUERY);
417 4 : uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY);
418 4 : uno::Reference<table::XCell> xCell = xTable->getCellByName("A1");
419 : // This was 0xffffff.
420 4 : CPPUNIT_ASSERT_EQUAL(sal_Int32(0x00ff00), getProperty<sal_Int32>(xCell, "BackColor"));
421 2 : }
422 :
423 17 : DECLARE_OOXMLEXPORT_TEST(testTableStyleBorder, "table-style-border.docx")
424 : {
425 2 : uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
426 4 : uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(), uno::UNO_QUERY);
427 4 : uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY);
428 :
429 : // This was 0, the second cell was missing its right border.
430 4 : uno::Reference<table::XCell> xCell = xTable->getCellByName("A2");
431 2 : CPPUNIT_ASSERT(getProperty<table::BorderLine2>(xCell, "RightBorder").LineWidth > 0);
432 :
433 : // This was also 0 (even after fixing the previous problem), the first cell was missing its right border, too.
434 2 : xCell = xTable->getCellByName("A1");
435 4 : CPPUNIT_ASSERT(getProperty<table::BorderLine2>(xCell, "RightBorder").LineWidth > 0);
436 2 : }
437 :
438 17 : DECLARE_OOXMLEXPORT_TEST(testTableStyleBorderExport, "table-style-border-export.docx")
439 : {
440 2 : uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
441 4 : uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(), uno::UNO_QUERY);
442 4 : uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY);
443 4 : uno::Reference<table::XCell> xCell = xTable->getCellByName("A3");
444 : // Bottom border was white, so this was 0xffffff.
445 4 : CPPUNIT_ASSERT_EQUAL(sal_Int32(0x8064A2), getProperty<table::BorderLine2>(xCell, "BottomBorder").Color);
446 2 : }
447 :
448 17 : DECLARE_OOXMLEXPORT_TEST(testAnchorPosition, "anchor-position.docx")
449 : {
450 : // The problem was that the at-char anchored picture was at the end of the
451 : // paragraph, so there were only two positions: a Text, then a Frame one.
452 2 : CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty<OUString>(getRun(getParagraph(1), 1), "TextPortionType"));
453 2 : CPPUNIT_ASSERT_EQUAL(OUString("Frame"), getProperty<OUString>(getRun(getParagraph(1), 2), "TextPortionType"));
454 2 : CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty<OUString>(getRun(getParagraph(1), 3), "TextPortionType"));
455 2 : }
456 :
457 17 : DECLARE_OOXMLEXPORT_TEST(testMultiPageToc, "multi-page-toc.docx")
458 : {
459 : // Import of this document triggered an STL assertion.
460 :
461 : // Document has a ToC from its second paragraph.
462 2 : uno::Reference<container::XNamed> xTextSection = getProperty< uno::Reference<container::XNamed> >(getParagraph(2), "TextSection");
463 2 : CPPUNIT_ASSERT_EQUAL(OUString("Table of Contents1"), xTextSection->getName());
464 : // There should be a field in the header as well.
465 4 : uno::Reference<text::XText> xHeaderText = getProperty< uno::Reference<text::XText> >(getStyles("PageStyles")->getByName(DEFAULT_STYLE), "HeaderText");
466 4 : CPPUNIT_ASSERT_EQUAL(OUString("TextFieldStart"), getProperty<OUString>(getRun(getParagraphOfText(1, xHeaderText), 1), "TextPortionType"));
467 2 : }
468 :
469 17 : DECLARE_OOXMLEXPORT_TEST(testTextboxTable, "textbox-table.docx")
470 : {
471 : // We wrote not-well-formed XML during export for this one:
472 : // Shape with textbox, having a table and also anchored inside a table.
473 :
474 : // Just make sure that we have both tables.
475 2 : uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
476 4 : uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY);
477 4 : CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xTables->getCount());
478 2 : }
479 :
480 17 : DECLARE_OOXMLEXPORT_TEST(testCropPixel, "crop-pixel.docx")
481 : {
482 : // If map mode of the graphic is in pixels, then we used to handle original
483 : // size of the graphic as mm100, but it was in pixels.
484 2 : if (xmlDocPtr pXmlDoc = parseExport("word/document.xml"))
485 : {
486 : // This is 17667 in the original document, was 504666 (so the image
487 : // become invisible), now is around 19072.
488 : (void) pXmlDoc;
489 1 : CPPUNIT_ASSERT(getXPath(pXmlDoc, "//a:srcRect", "l").toInt32() <= 22452);
490 : }
491 2 : }
492 :
493 17 : DECLARE_OOXMLEXPORT_TEST(testEffectExtent, "effect-extent.docx")
494 : {
495 : // The problem was that in case there were no shadows on the picture, we
496 : // wrote a <wp:effectExtent> full or zeros.
497 2 : if (xmlDocPtr pXmlDoc = parseExport("word/document.xml"))
498 : // E.g. this was 0.
499 1 : assertXPath(pXmlDoc, "//wp:effectExtent", "l", "114300");
500 2 : }
501 :
502 17 : DECLARE_OOXMLEXPORT_TEST(testEm, "em.docx")
503 : {
504 : // Test all possible <w:em> arguments.
505 2 : CPPUNIT_ASSERT_EQUAL(text::FontEmphasis::NONE, getProperty<sal_Int16>(getRun(getParagraph(1), 1), "CharEmphasis"));
506 : // This was ACCENT_ABOVE.
507 2 : CPPUNIT_ASSERT_EQUAL(text::FontEmphasis::DOT_ABOVE, getProperty<sal_Int16>(getRun(getParagraph(1), 2), "CharEmphasis"));
508 : // This was DOT_ABOVE.
509 2 : CPPUNIT_ASSERT_EQUAL(text::FontEmphasis::ACCENT_ABOVE, getProperty<sal_Int16>(getRun(getParagraph(1), 3), "CharEmphasis"));
510 2 : CPPUNIT_ASSERT_EQUAL(text::FontEmphasis::CIRCLE_ABOVE, getProperty<sal_Int16>(getRun(getParagraph(1), 4), "CharEmphasis"));
511 2 : CPPUNIT_ASSERT_EQUAL(text::FontEmphasis::DOT_BELOW, getProperty<sal_Int16>(getRun(getParagraph(1), 5), "CharEmphasis"));
512 2 : }
513 :
514 17 : DECLARE_OOXMLEXPORT_TEST(testFdo77716, "fdo77716.docx")
515 : {
516 : // The problem was that there should be 200 twips spacing between the two paragraphs, but there wasn't any.
517 2 : uno::Reference<beans::XPropertySet> xStyle(getStyles("ParagraphStyles")->getByName("Standard"), uno::UNO_QUERY);
518 : // This was 0.
519 2 : CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(convertTwipToMm100(200)), getProperty<sal_Int32>(xStyle, "ParaBottomMargin"));
520 2 : }
521 :
522 17 : DECLARE_OOXMLEXPORT_TEST(testAfterlines, "afterlines.docx")
523 : {
524 : // This was 353, i.e. the value of <w:spacing w:after="200"> from <w:pPrDefault>, instead of <w:spacing w:afterLines="100"/> from <w:pPr>.
525 2 : CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(423), getProperty<sal_Int32>(getParagraph(1), "ParaBottomMargin"));
526 2 : }
527 :
528 17 : DECLARE_OOXMLEXPORT_TEST(testParagraphMark, "paragraph-mark.docx")
529 : {
530 : // The problem was that we didn't handle the situation when an empty paragraph's marker had both a char style and some direct formatting.
531 :
532 : // This was 11.
533 2 : CPPUNIT_ASSERT_EQUAL(12.f, getProperty<float>(getParagraph(1), "CharHeight"));
534 : // This was empty.
535 2 : CPPUNIT_ASSERT_EQUAL(OUString("Emphasis"), getProperty<OUString>(getRun(getParagraph(1), 1), "CharStyleName"));
536 2 : }
537 :
538 16 : DECLARE_OOXMLEXPORT_TEST(testParagraphMarkNonempty, "paragraph-mark-nonempty.odt")
539 : {
540 1 : if (xmlDocPtr pXmlDoc = parseExport())
541 : // There were two <w:sz> elements, make sure the 40 one is is dropped and the 20 one is kept.
542 1 : assertXPath(pXmlDoc, "//w:p/w:pPr/w:rPr/w:sz", "val", "20");
543 1 : }
544 :
545 17 : DECLARE_OOXMLEXPORT_TEST(testPageBreakBefore, "page-break-before.docx")
546 : {
547 : // This was style::BreakType_PAGE_BEFORE, i.e. page break wasn't ignored, as it should have been.
548 2 : CPPUNIT_ASSERT_EQUAL(style::BreakType_NONE, getProperty<style::BreakType>(getParagraph(2), "BreakType"));
549 2 : }
550 :
551 17 : DECLARE_OOXMLEXPORT_TEST(testTableRtl, "table-rtl.docx")
552 : {
553 2 : uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
554 4 : uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY);
555 4 : uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY);
556 : // This was text::WritingMode2::LR_TB, i.e. direction of the table was ignored.
557 4 : CPPUNIT_ASSERT_EQUAL(text::WritingMode2::RL_TB, getProperty<sal_Int16>(xTable, "WritingMode"));
558 2 : }
559 :
560 17 : DECLARE_OOXMLEXPORT_TEST(testOoxmlCjklist30, "cjklist30.docx")
561 : {
562 : sal_Int16 numFormat;
563 2 : CPPUNIT_ASSERT(CjkNumberedListTestHelper(numFormat));
564 2 : CPPUNIT_ASSERT_EQUAL(style::NumberingType::TIAN_GAN_ZH, numFormat);
565 2 : }
566 :
567 17 : DECLARE_OOXMLEXPORT_TEST(testOoxmlCjklist31, "cjklist31.docx")
568 : {
569 : sal_Int16 numFormat;
570 2 : CPPUNIT_ASSERT(CjkNumberedListTestHelper(numFormat));
571 2 : CPPUNIT_ASSERT_EQUAL(style::NumberingType::DI_ZI_ZH, numFormat);
572 2 : }
573 :
574 17 : DECLARE_OOXMLEXPORT_TEST(testOoxmlCjklist34, "cjklist34.docx")
575 : {
576 : sal_Int16 numFormat;
577 2 : CPPUNIT_ASSERT(CjkNumberedListTestHelper(numFormat));
578 2 : CPPUNIT_ASSERT_EQUAL(style::NumberingType::NUMBER_UPPER_ZH_TW, numFormat);
579 2 : }
580 :
581 17 : DECLARE_OOXMLEXPORT_TEST(testOoxmlCjklist35, "cjklist35.docx")
582 : {
583 : sal_Int16 numFormat;
584 2 : CPPUNIT_ASSERT(CjkNumberedListTestHelper(numFormat));
585 2 : CPPUNIT_ASSERT_EQUAL(style::NumberingType::NUMBER_LOWER_ZH, numFormat);
586 2 : }
587 :
588 17 : DECLARE_OOXMLEXPORT_TEST(testOoxmlCjklist44, "cjklist44.docx")
589 : {
590 : sal_Int16 numFormat;
591 2 : CPPUNIT_ASSERT(CjkNumberedListTestHelper(numFormat));
592 2 : CPPUNIT_ASSERT_EQUAL(style::NumberingType::NUMBER_HANGUL_KO, numFormat);
593 2 : }
594 :
595 16 : DECLARE_OOXMLEXPORT_TEST(testOoxmlNumListZHTW, "numlist-zhtw.odt")
596 : {
597 1 : xmlDocPtr pXmlDoc = parseExport("word/numbering.xml");
598 1 : if (!pXmlDoc)
599 1 : return;
600 :
601 1 : assertXPath ( pXmlDoc, "/w:numbering/w:abstractNum[1]/w:lvl[1]/w:numFmt","val","taiwaneseCountingThousand" );
602 : }
603 :
604 16 : DECLARE_OOXMLEXPORT_TEST(testOoxmlNumListZHCN, "numlist-zhcn.odt")
605 : {
606 1 : xmlDocPtr pXmlDoc = parseExport("word/numbering.xml");
607 1 : if (!pXmlDoc)
608 1 : return;
609 :
610 1 : assertXPath ( pXmlDoc, "/w:numbering/w:abstractNum[1]/w:lvl[1]/w:numFmt","val","chineseCountingThousand" );
611 : }
612 :
613 16 : DECLARE_OOXMLEXPORT_TEST(testOOxmlOutlineNumNone, "outline-num-none.odt")
614 : {
615 1 : if (xmlDocPtr pXmlDoc = parseExport("word/numbering.xml"))
616 1 : assertXPath(pXmlDoc, "/w:numbering/w:abstractNum[1]/w:lvl[1]/w:numFmt", "val", "none");
617 1 : }
618 :
619 17 : DECLARE_OOXMLEXPORT_TEST(testNumParentStyle, "num-parent-style.docx")
620 : {
621 : // This was "Outline", i.e. <w:numId> was not imported from the Heading 2 paragraph style.
622 2 : CPPUNIT_ASSERT(getProperty<OUString>(getParagraph(4), "NumberingStyleName").startsWith("WWNum"));
623 2 : }
624 :
625 17 : DECLARE_OOXMLEXPORT_TEST(testNumOverrideLvltext, "num-override-lvltext.docx")
626 : {
627 2 : uno::Reference<container::XIndexAccess> xRules = getProperty< uno::Reference<container::XIndexAccess> >(getStyles("NumberingStyles")->getByName("WWNum1"), "NumberingRules");
628 : // This was 1, i.e. the numbering on the second level was "1", not "1.1".
629 2 : CPPUNIT_ASSERT_EQUAL(sal_Int16(2), comphelper::SequenceAsHashMap(xRules->getByIndex(1))["ParentNumbering"].get<sal_Int16>());
630 :
631 : // The paragraph marker's red font color was inherited by the number portion, this was ff0000.
632 2 : CPPUNIT_ASSERT_EQUAL(OUString("00000a"), parseDump("//Special[@nType='POR_NUMBER']/pFont", "color"));
633 2 : }
634 :
635 17 : DECLARE_OOXMLEXPORT_TEST(testNumOverrideStart, "num-override-start.docx")
636 : {
637 2 : uno::Reference<container::XIndexAccess> xRules = getProperty< uno::Reference<container::XIndexAccess> >(getStyles("NumberingStyles")->getByName("WWNum1"), "NumberingRules");
638 : // This was 1, i.e. the numbering on the second level was "1.1", not "1.3".
639 2 : CPPUNIT_ASSERT_EQUAL(sal_Int16(3), comphelper::SequenceAsHashMap(xRules->getByIndex(1))["StartWith"].get<sal_Int16>());
640 2 : }
641 :
642 17 : DECLARE_OOXMLEXPORT_TEST(testTextboxRightEdge, "textbox-right-edge.docx")
643 : {
644 : // I'm fairly sure this is not specific to DOCX, but the doc model created
645 : // by the ODF import doesn't trigger this bug, so let's test this here
646 : // instead of uiwriter.
647 2 : int nShapeLeft = parseDump("//SwAnchoredDrawObject/bounds", "left").toInt32();
648 2 : int nShapeWidth = parseDump("//SwAnchoredDrawObject/bounds", "width").toInt32();
649 2 : int nTextboxLeft = parseDump("//fly/infos/bounds", "left").toInt32();
650 2 : int nTextboxWidth = parseDump("//fly/infos/bounds", "width").toInt32();
651 : // This is a rectangle, make sure the right edge of the textbox is still
652 : // inside the draw shape.
653 2 : CPPUNIT_ASSERT(nShapeLeft + nShapeWidth >= nTextboxLeft + nTextboxWidth);
654 2 : }
655 :
656 17 : DECLARE_OOXMLEXPORT_TEST(testEffectExtentMargin, "effectextent-margin.docx")
657 : {
658 : // This was 318, i.e. oox::drawingml::convertEmuToHmm(114300), effectExtent
659 : // wasn't part of the margin, leading to the fly not taking enough space
660 : // around itself.
661 2 : CPPUNIT_ASSERT_EQUAL(oox::drawingml::convertEmuToHmm(114300+95250), getProperty<sal_Int32>(getShape(1), "LeftMargin"));
662 2 : }
663 :
664 16 : DECLARE_OOXMLEXPORT_TEST(testTdf88583, "tdf88583.odt")
665 : {
666 1 : CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_SOLID, getProperty<drawing::FillStyle>(getParagraph(1), "FillStyle"));
667 1 : CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0x00cc00), getProperty<sal_Int32>(getParagraph(1), "FillColor"));
668 1 : }
669 :
670 17 : DECLARE_OOXMLEXPORT_TEST(testTdf89791, "tdf89791.docx")
671 : {
672 2 : if (mbExported)
673 : {
674 1 : uno::Reference<packages::zip::XZipFileAccess2> xNameAccess = packages::zip::ZipFileAccess::createWithURL(comphelper::getComponentContext(m_xSFactory), maTempFile.GetURL());
675 1 : CPPUNIT_ASSERT_EQUAL(false, bool(xNameAccess->hasByName("docProps/custom.xml")));
676 : }
677 2 : }
678 :
679 17 : DECLARE_OOXMLEXPORT_TEST(testTdf91261, "tdf91261.docx")
680 : {
681 2 : bool snapToGrid = true;
682 2 : uno::Reference< text::XTextRange > xPara = getParagraph( 2 );
683 4 : uno::Reference< beans::XPropertySet > properties( xPara, uno::UNO_QUERY);
684 2 : properties->getPropertyValue("SnapToGrid") >>= snapToGrid ;
685 2 : CPPUNIT_ASSERT_EQUAL(false, snapToGrid);
686 :
687 4 : uno::Reference< beans::XPropertySet> xStyle(getStyles("PageStyles")->getByName("Standard"), uno::UNO_QUERY);
688 : sal_Int16 nGridMode;
689 2 : xStyle->getPropertyValue("GridMode") >>= nGridMode;
690 2 : CPPUNIT_ASSERT_EQUAL( sal_Int16(2), nGridMode);
691 :
692 : bool bGridSnapToChars;
693 2 : xStyle->getPropertyValue("GridSnapToChars") >>= bGridSnapToChars;
694 4 : CPPUNIT_ASSERT_EQUAL(true, bGridSnapToChars);
695 :
696 2 : }
697 :
698 17 : DECLARE_OOXMLEXPORT_TEST(testTdf79639, "tdf79639.docx")
699 : {
700 2 : uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY);
701 4 : uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage();
702 : // This was 0, floating table in header wasn't converted to a TextFrame.
703 4 : CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), xDrawPage->getCount());
704 2 : }
705 :
706 4 : CPPUNIT_PLUGIN_IMPLEMENT();
707 :
708 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|