1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
10 #include <swmodeltestbase.hxx>
12 #include <com/sun/star/beans/XPropertySet.hpp>
13 #include <IDocumentSettingAccess.hxx>
17 #include <tools/lineend.hxx>
18 #include <com/sun/star/table/ShadowFormat.hpp>
19 #include <com/sun/star/text/TableColumnSeparator.hpp>
20 #include <com/sun/star/text/XDocumentIndex.hpp>
21 #include <com/sun/star/text/RelOrientation.hpp>
23 class Test
: public SwModelTestBase
26 Test() : SwModelTestBase("/sw/qa/extras/ooxmlexport/data/", "Office Open XML Text") {}
32 bool mustTestImportOf(const char* filename
) const override
{
33 // If the testcase is stored in some other format, it's pointless to test.
34 return OString(filename
).endsWith(".docx");
38 DECLARE_OOXMLEXPORT_TEST(testTdf87569v
, "tdf87569_vml.docx")
40 //the original tdf87569 sample has vml shapes...
41 uno::Reference
<beans::XPropertySet
> xShapeProperties(getShape(1), uno::UNO_QUERY
);
43 xShapeProperties
->getPropertyValue("HoriOrientRelation") >>= nValue
;
44 CPPUNIT_ASSERT_EQUAL_MESSAGE("tdf87569_vml: The Shape is not in the table!",
45 text::RelOrientation::FRAME
, nValue
);
48 DECLARE_OOXMLEXPORT_TEST(testTdf87569d
, "tdf87569_drawingml.docx")
50 //if the original tdf87569 sample is upgraded it will have drawingml shapes...
51 uno::Reference
<beans::XPropertySet
> xShapeProperties(getShape(1), uno::UNO_QUERY
);
53 xShapeProperties
->getPropertyValue("HoriOrientRelation") >>= nValue
;
54 CPPUNIT_ASSERT_EQUAL_MESSAGE("tdf87569_drawingml: The Shape is not in the table!",
55 text::RelOrientation::FRAME
, nValue
);
58 DECLARE_OOXMLEXPORT_TEST(testTdf120315
, "tdf120315.docx")
60 // tdf#120315 cells of the second column weren't vertically merged
61 // because their horizontal positions are different a little bit
62 uno::Reference
<text::XTextTablesSupplier
> xTablesSupplier(mxComponent
, uno::UNO_QUERY
);
63 uno::Reference
<container::XIndexAccess
> xTables(xTablesSupplier
->getTextTables(),
65 uno::Reference
<text::XTextTable
> xTextTable(xTables
->getByIndex(0), uno::UNO_QUERY
);
66 uno::Reference
<table::XTableRows
> xTableRows
= xTextTable
->getRows();
67 CPPUNIT_ASSERT_EQUAL(getProperty
<uno::Sequence
<text::TableColumnSeparator
>>(
68 xTableRows
->getByIndex(0), "TableColumnSeparators")[0]
70 getProperty
<uno::Sequence
<text::TableColumnSeparator
>>(
71 xTableRows
->getByIndex(1), "TableColumnSeparators")[2]
75 DECLARE_OOXMLEXPORT_TEST(testTdf108350_noFontdefaults
, "tdf108350_noFontdefaults.docx")
77 uno::Reference
< container::XNameAccess
> paragraphStyles
= getStyles("ParagraphStyles");
78 uno::Reference
< beans::XPropertySet
> xStyleProps(paragraphStyles
->getByName("NoParent"), uno::UNO_QUERY
);
79 CPPUNIT_ASSERT_EQUAL(OUString("Times New Roman"), getProperty
<OUString
>(xStyleProps
, "CharFontName"));
80 //CPPUNIT_ASSERT_EQUAL_MESSAGE("Font size", 10.f, getProperty<float>(xStyleProps, "CharHeight"));
83 DECLARE_OOXMLEXPORT_TEST(testTdf129522_removeShadowStyle
, "tdf129522_removeShadowStyle.odt")
85 uno::Reference
< container::XNameAccess
> paragraphStyles
= getStyles("ParagraphStyles");
86 uno::Reference
< beans::XPropertySet
> xStyleProps(paragraphStyles
->getByName("Shadow"), uno::UNO_QUERY_THROW
);
87 table::ShadowFormat aShadow
= getProperty
<table::ShadowFormat
>(xStyleProps
, "ParaShadowFormat");
88 CPPUNIT_ASSERT_EQUAL(table::ShadowLocation_BOTTOM_RIGHT
, aShadow
.Location
);
90 // Shadows were inherited regardless of whether the style disabled them.
91 xStyleProps
.set(paragraphStyles
->getByName("Shadow-removed"), uno::UNO_QUERY_THROW
);
92 aShadow
= getProperty
<table::ShadowFormat
>(xStyleProps
, "ParaShadowFormat");
93 CPPUNIT_ASSERT_EQUAL(table::ShadowLocation_NONE
, aShadow
.Location
);
95 uno::Reference
< container::XNameAccess
> characterStyles
= getStyles("CharacterStyles");
96 xStyleProps
.set(characterStyles
->getByName("CharShadow"), uno::UNO_QUERY_THROW
);
97 aShadow
= getProperty
<table::ShadowFormat
>(xStyleProps
, "CharShadowFormat");
98 CPPUNIT_ASSERT_EQUAL(table::ShadowLocation_BOTTOM_RIGHT
, aShadow
.Location
);
100 xStyleProps
.set(characterStyles
->getByName("CharShadow-removed"), uno::UNO_QUERY_THROW
);
101 aShadow
= getProperty
<table::ShadowFormat
>(xStyleProps
, "CharShadowFormat");
102 CPPUNIT_ASSERT_EQUAL(table::ShadowLocation_NONE
, aShadow
.Location
);
105 DECLARE_OOXMLIMPORT_TEST(testTdf125038
, "tdf125038.docx")
107 OUString aActual
= getParagraph(1)->getString();
108 // Without the accompanying fix in place, this test would have failed with:
109 // - Expected: phone:...
110 // - Actual : result1result2phone:...
111 // i.e. the result if the inner MERGEFIELD fields ended up in the body text.
112 CPPUNIT_ASSERT_EQUAL(OUString("phone: \t1234567890"), aActual
);
115 DECLARE_OOXMLIMPORT_TEST(testTdf124986
, "tdf124986.docx")
117 // Load a document with SET fields, where the SET fields contain leading/trailing quotation marks and spaces.
118 uno::Reference
<text::XTextDocument
> xTextDocument(mxComponent
, uno::UNO_QUERY
);
119 uno::Reference
<text::XTextFieldsSupplier
> xTextFieldsSupplier(mxComponent
, uno::UNO_QUERY
);
120 uno::Reference
<container::XEnumerationAccess
> xFieldsAccess(xTextFieldsSupplier
->getTextFields());
121 uno::Reference
<container::XEnumeration
> xFields(xFieldsAccess
->createEnumeration());
123 while (xFields
->hasMoreElements())
125 uno::Reference
<lang::XServiceInfo
> xServiceInfo(xFields
->nextElement(), uno::UNO_QUERY
);
126 uno::Reference
<beans::XPropertySet
> xPropertySet(xServiceInfo
, uno::UNO_QUERY
);
128 if (xServiceInfo
->supportsService("com.sun.star.text.TextField.SetExpression"))
130 xPropertySet
->getPropertyValue("Content") >>= aValue
;
131 CPPUNIT_ASSERT_EQUAL(OUString("demo"), aValue
);
136 DECLARE_OOXMLIMPORT_TEST(testTdf125038b
, "tdf125038b.docx")
138 // Load a document with an IF field, where the IF field command contains a paragraph break.
139 uno::Reference
<text::XTextDocument
> xTextDocument(mxComponent
, uno::UNO_QUERY
);
140 uno::Reference
<container::XEnumerationAccess
> xParagraphAccess(xTextDocument
->getText(), uno::UNO_QUERY
);
141 uno::Reference
<container::XEnumeration
> xParagraphs
= xParagraphAccess
->createEnumeration();
142 CPPUNIT_ASSERT(xParagraphs
->hasMoreElements());
143 uno::Reference
<text::XTextRange
> xParagraph(xParagraphs
->nextElement(), uno::UNO_QUERY
);
145 // Without the accompanying fix in place, this test would have failed with:
146 // - Expected: phone: 1234
148 // i.e. the first paragraph was empty and the second paragraph had the content.
149 CPPUNIT_ASSERT_EQUAL(OUString("phone: 1234"), xParagraph
->getString());
150 CPPUNIT_ASSERT(xParagraphs
->hasMoreElements());
151 xParagraphs
->nextElement();
153 // Without the accompanying fix in place, this test would have failed with:
154 // - Expression: !xParagraphs->hasMoreElements()
155 // i.e. the document had 3 paragraphs, while only 2 was expected.
156 CPPUNIT_ASSERT(!xParagraphs
->hasMoreElements());
159 DECLARE_OOXMLIMPORT_TEST(testTdf125038c
, "tdf125038c.docx")
161 OUString aActual
= getParagraph(1)->getString();
162 // Without the accompanying fix in place, this test would have failed with:
163 // - Expected: email: test@test.test
165 // I.e. the result of the MERGEFIELD field inside an IF field was lost.
166 CPPUNIT_ASSERT_EQUAL(OUString("email: test@test.test"), aActual
);
169 DECLARE_OOXMLEXPORT_TEST(testTdf121661
, "tdf121661.docx")
171 xmlDocPtr pXmlSettings
= parseExport("word/settings.xml");
174 assertXPath(pXmlSettings
, "/w:settings/w:hyphenationZone", "val", "851");
177 DECLARE_OOXMLEXPORT_TEST(testTdf121658
, "tdf121658.docx")
179 xmlDocPtr pXmlSettings
= parseExport("word/settings.xml");
182 assertXPath(pXmlSettings
, "/w:settings/w:doNotHyphenateCaps");
185 DECLARE_OOXMLEXPORT_TEST(testTdf124367
, "tdf124367.docx")
187 uno::Reference
<text::XTextTablesSupplier
> xTablesSupplier(mxComponent
, uno::UNO_QUERY
);
188 uno::Reference
<container::XIndexAccess
> xTables(xTablesSupplier
->getTextTables(),
190 uno::Reference
<text::XTextTable
> xTextTable(xTables
->getByIndex(0), uno::UNO_QUERY
);
191 uno::Reference
<table::XTableRows
> xTableRows
= xTextTable
->getRows();
192 // it was 2761 at the first import, and 2760 at the second import, due to incorrect rounding
193 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16
>(2762),
194 getProperty
<uno::Sequence
<text::TableColumnSeparator
>>(
195 xTableRows
->getByIndex(2), "TableColumnSeparators")[0]
199 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf128820
, "tdf128820.fodt")
201 // Import of exported DOCX failed because of wrong namespace used for wsp element
202 // Now test the exported XML, in case we stop failing opening invalid files
203 xmlDocPtr pXml
= parseExport("word/document.xml");
204 CPPUNIT_ASSERT(pXml
);
205 // The parent wpg:wgp element has three children: wpg:cNvGrpSpPr, wpg:grpSpPr, and wpg:wsp
206 // (if we start legitimately exporting additional children, this needs to be adjusted to check
207 // all those, to make sure we don't export wrong elements).
208 assertXPathChildren(pXml
,
209 "/w:document/w:body/w:p/w:r/mc:AlternateContent/mc:Choice/w:drawing/"
210 "wp:inline/a:graphic/a:graphicData/wpg:wgp",
213 "/w:document/w:body/w:p/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:inline/"
214 "a:graphic/a:graphicData/wpg:wgp/wpg:cNvGrpSpPr");
216 "/w:document/w:body/w:p/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:inline/"
217 "a:graphic/a:graphicData/wpg:wgp/wpg:grpSpPr");
218 // This one was pic:wsp instead of wps:wsp
220 "/w:document/w:body/w:p/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:inline/"
221 "a:graphic/a:graphicData/wpg:wgp/wps:wsp");
224 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf128889
, "tdf128889.fodt")
226 xmlDocPtr pXml
= parseExport("word/document.xml");
227 CPPUNIT_ASSERT(pXml
);
228 // There was an w:r (with w:br) as an invalid child of first paragraph's w:pPr
229 assertXPath(pXml
, "/w:document/w:body/w:p[1]/w:pPr/w:r", 0);
230 assertXPath(pXml
, "/w:document/w:body/w:p[1]/w:r", 2);
231 // Check that the break is in proper - last - position
232 assertXPath(pXml
, "/w:document/w:body/w:p[1]/w:r[2]/w:br", "type", "page");
235 DECLARE_OOXMLEXPORT_TEST(testTdf129353
, "tdf129353.docx")
237 CPPUNIT_ASSERT_EQUAL(8, getParagraphs());
238 getParagraph(1, "(Verne, 1870)");
239 getParagraph(2, "Bibliography");
240 getParagraph(4, "Christie, A. (1922). The Secret Adversary. ");
241 CPPUNIT_ASSERT_EQUAL(OUString(), getParagraph(8)->getString());
243 uno::Reference
<text::XDocumentIndexesSupplier
> xIndexSupplier(mxComponent
, uno::UNO_QUERY
);
244 uno::Reference
<container::XIndexAccess
> xIndexes
= xIndexSupplier
->getDocumentIndexes();
245 uno::Reference
<text::XDocumentIndex
> xIndex(xIndexes
->getByIndex(0), uno::UNO_QUERY
);
246 uno::Reference
<text::XTextRange
> xTextRange
= xIndex
->getAnchor();
247 uno::Reference
<text::XText
> xText
= xTextRange
->getText();
248 uno::Reference
<text::XTextCursor
> xTextCursor
= xText
->createTextCursor();
249 xTextCursor
->gotoRange(xTextRange
->getStart(), false);
250 xTextCursor
->gotoRange(xTextRange
->getEnd(), true);
251 OUString
aIndexString(convertLineEnd(xTextCursor
->getString(), LineEnd::LINEEND_LF
));
253 // Check that all the pre-rendered entries are correct, including trailing spaces
254 CPPUNIT_ASSERT_EQUAL(OUString("\n" // starting with an empty paragraph
255 "Christie, A. (1922). The Secret Adversary. \n"
257 "Verne, J. G. (1870). Twenty Thousand Leagues Under the Sea. \n"
258 ""), // ending with an empty paragraph
262 DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf77796
, "tdf77796.docx")
264 xmlDocPtr pXml
= parseExport("word/document.xml");
265 CPPUNIT_ASSERT(pXml
);
266 // cell paddings from table style
267 assertXPath(pXml
, "/w:document/w:body/w:tbl/w:tblPr/w:tblCellMar/w:start", "w", "5");
268 assertXPath(pXml
, "/w:document/w:body/w:tbl/w:tblPr/w:tblCellMar/w:top", "w", "240");
269 assertXPath(pXml
, "/w:document/w:body/w:tbl/w:tblPr/w:tblCellMar/w:bottom", "w", "480");
271 assertXPath(pXml
, "/w:document/w:body/w:tbl/w:tblPr/w:tblCellMar/w:end", "w", "108");
274 CPPUNIT_PLUGIN_IMPLEMENT();
276 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */