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/drawing/FillStyle.hpp>
13 #include <com/sun/star/awt/Gradient.hpp>
14 #include <com/sun/star/text/XTextTable.hpp>
15 #include <com/sun/star/style/CaseMap.hpp>
16 #include <com/sun/star/style/ParagraphAdjust.hpp>
17 #include <com/sun/star/table/ShadowFormat.hpp>
18 #include <com/sun/star/text/GraphicCrop.hpp>
19 #include <com/sun/star/text/WritingMode2.hpp>
20 #include <com/sun/star/xml/dom/XDocument.hpp>
21 #include <com/sun/star/style/BreakType.hpp>
23 #include <ftninfo.hxx>
25 #include <unotxdoc.hxx>
27 class Test
: public SwModelTestBase
30 Test() : SwModelTestBase("/sw/qa/extras/ooxmlexport/data/", "Office Open XML Text") {}
33 DECLARE_OOXMLEXPORT_TEST(testFdo68418
, "fdo68418.docx")
35 // The problem was that in 'MSWordExportBase::SectionProperties' function in 'wrt8sty.cxx'
36 // it checked if it 'IsPlausableSingleWordSection'.
37 // The 'IsPlausableSingleWordSection' compared different aspects of 2 'SwFrameFormat' objects.
38 // One of the checks was 'do both formats have the same distance from the top and bottom ?'
39 // This check is correct if both have headers or both don't have headers.
40 // However - if one has a header, and the other one has an empty header (no header) - it is not correct to compare
41 // between them (same goes for 'footer').
42 uno::Reference
<text::XText
> xFooterText
= getProperty
< uno::Reference
<text::XText
> >(getStyles("PageStyles")->getByName("Standard"), "FooterText");
43 uno::Reference
< text::XTextRange
> xFooterParagraph
= getParagraphOfText( 1, xFooterText
);
45 // First page footer is empty, second page footer is 'aaaa'
46 CPPUNIT_ASSERT_EQUAL(OUString("aaaa"), xFooterParagraph
->getString()); // I get an error that it expects ''
49 DECLARE_OOXMLEXPORT_TEST(testA4AndBorders
, "a4andborders.docx")
52 * The problem was that in case of a document with borders, the pgSz attribute
53 * was exported as a child of pgBorders, thus being ignored on reload.
54 * We assert dimension against A4 size in mm (to avoid minor rounding errors)
56 uno::Reference
<beans::XPropertySet
> xPageStyle(getStyles("PageStyles")->getByName("Standard"), uno::UNO_QUERY
);
57 CPPUNIT_ASSERT_EQUAL_MESSAGE("Incorrect Page Width (mm)", sal_Int32(210), getProperty
<sal_Int32
>(xPageStyle
, "Width") / 100);
58 CPPUNIT_ASSERT_EQUAL_MESSAGE("Incorrect Page Height (mm)", sal_Int32(297), getProperty
<sal_Int32
>(xPageStyle
, "Height") / 100);
61 DECLARE_OOXMLEXPORT_TEST(testFdo68787
, "fdo68787.docx")
63 uno::Reference
<beans::XPropertySet
> xPageStyle(getStyles("PageStyles")->getByName("Standard"), uno::UNO_QUERY
);
64 // This was 25, the 'lack of w:separator' <-> '0 line width' mapping was missing.
65 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty
<sal_Int32
>(xPageStyle
, "FootnoteLineRelativeWidth"));
68 DECLARE_OOXMLEXPORT_TEST(testTdf92470_footnoteRestart
, "tdf92470_footnoteRestart.docx")
70 SwXTextDocument
* pTextDoc
= dynamic_cast<SwXTextDocument
*>(mxComponent
.get());
71 CPPUNIT_ASSERT( pTextDoc
);
72 SwDoc
* pDoc
= pTextDoc
->GetDocShell()->GetDoc();
73 CPPUNIT_ASSERT( pDoc
);
74 CPPUNIT_ASSERT_EQUAL_MESSAGE( "Footnote doesn't restart every Page", FTNNUM_PAGE
, pDoc
->GetFootnoteInfo().m_eNum
);
76 uno::Reference
<beans::XPropertySet
> xPageStyle(getStyles("PageStyles")->getByName("Standard"), uno::UNO_QUERY
);
77 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>(25), getProperty
<sal_Int32
>(xPageStyle
, "FootnoteLineRelativeWidth"));
80 CPPUNIT_TEST_FIXTURE(Test
, testTdf108944_footnoteSeparator2
)
82 loadAndReload("tdf108944_footnoteSeparator2.odt");
83 CPPUNIT_ASSERT_EQUAL(1, getPages());
84 uno::Reference
<beans::XPropertySet
> xPageStyle(getStyles("PageStyles")->getByName("Standard"), uno::UNO_QUERY
);
85 //This was zero. The comment was causing the bHasFtnSep flag to be reset to false, so the separator was missing.
86 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32
>(25), getProperty
<sal_Int32
>(xPageStyle
, "FootnoteLineRelativeWidth"));
89 CPPUNIT_TEST_FIXTURE(Test
, testCharacterBorder
)
91 loadAndReload("charborder.odt");
92 CPPUNIT_ASSERT_EQUAL(1, getPages());
93 uno::Reference
<beans::XPropertySet
> xRun(getRun(getParagraph(1),1), uno::UNO_QUERY
);
94 // OOXML has just one border attribute (<w:bdr>) for text border so all side has
95 // the same border with the same padding
98 const table::BorderLine2 aTopBorder
= getProperty
<table::BorderLine2
>(xRun
,"CharTopBorder");
99 CPPUNIT_ASSERT_BORDER_EQUAL(table::BorderLine2(0xFF6600,0,318,0,0,318), aTopBorder
);
100 CPPUNIT_ASSERT_BORDER_EQUAL(aTopBorder
, getProperty
<table::BorderLine2
>(xRun
,"CharLeftBorder"));
101 CPPUNIT_ASSERT_BORDER_EQUAL(aTopBorder
, getProperty
<table::BorderLine2
>(xRun
,"CharBottomBorder"));
102 CPPUNIT_ASSERT_BORDER_EQUAL(aTopBorder
, getProperty
<table::BorderLine2
>(xRun
,"CharRightBorder"));
107 const sal_Int32 nTopPadding
= getProperty
<sal_Int32
>(xRun
,"CharTopBorderDistance");
108 // In the original ODT the padding is 150, but the unit conversion round it down.
109 CPPUNIT_ASSERT_EQUAL(sal_Int32(141), nTopPadding
);
110 CPPUNIT_ASSERT_EQUAL(nTopPadding
, getProperty
<sal_Int32
>(xRun
,"CharLeftBorderDistance"));
111 CPPUNIT_ASSERT_EQUAL(nTopPadding
, getProperty
<sal_Int32
>(xRun
,"CharBottomBorderDistance"));
112 CPPUNIT_ASSERT_EQUAL(nTopPadding
, getProperty
<sal_Int32
>(xRun
,"CharRightBorderDistance"));
116 /* OOXML use just one bool value for shadow so the next conversions
117 are made during an export-import round
119 location: any -> bottom-right
120 width: any -> border width */
122 const table::ShadowFormat aShadow
= getProperty
<table::ShadowFormat
>(xRun
, "CharShadowFormat");
123 CPPUNIT_ASSERT_EQUAL(COL_BLACK
, Color(ColorTransparency
, aShadow
.Color
));
124 CPPUNIT_ASSERT_EQUAL(table::ShadowLocation_BOTTOM_RIGHT
, aShadow
.Location
);
125 CPPUNIT_ASSERT_EQUAL(sal_Int16(318), aShadow
.ShadowWidth
);
128 // Also check shadow when it is in middle of the paragraph
129 // (problem can be during export with SwWW8AttrIter::HasTextItem())
131 uno::Reference
<beans::XPropertySet
> xMiddleRun(getRun(getParagraph(2),2), uno::UNO_QUERY
);
132 const table::ShadowFormat aShadow
= getProperty
<table::ShadowFormat
>(xMiddleRun
, "CharShadowFormat");
133 CPPUNIT_ASSERT_EQUAL(COL_BLACK
, Color(ColorTransparency
, aShadow
.Color
));
134 CPPUNIT_ASSERT_EQUAL(table::ShadowLocation_BOTTOM_RIGHT
, aShadow
.Location
);
135 CPPUNIT_ASSERT_EQUAL(sal_Int16(318), aShadow
.ShadowWidth
);
138 xmlDocUniquePtr pXmlStyles
= parseExport("word/styles.xml");
139 // Make sure we write qFormat for custom style names.
140 assertXPath(pXmlStyles
, "//w:style[@w:styleId='Heading']/w:qFormat", 1);
143 CPPUNIT_TEST_FIXTURE(Test
, testStyleInheritance
)
145 loadAndSave("style-inheritance.docx");
147 // Check that now styleId's are more like what MSO produces
148 xmlDocUniquePtr pXmlStyles
= parseExport("word/styles.xml");
149 // the 1st style always must be Normal
150 assertXPath(pXmlStyles
, "/w:styles/w:style[1]", "styleId", "Normal");
151 // some random style later
152 assertXPath(pXmlStyles
, "/w:styles/w:style[4]", "styleId", "Heading3");
154 // Check that we do _not_ export w:next for styles that point to themselves.
155 assertXPath(pXmlStyles
, "/w:styles/w:style[1]/w:next", 0);
157 // Check that we roundtrip <w:next> correctly - on XML level
158 assertXPath(pXmlStyles
, "/w:styles/w:style[2]/w:next", "val", "Normal");
159 // And to be REALLY sure, check it on the API level too ;-)
160 uno::Reference
< container::XNameAccess
> paragraphStyles
= getStyles("ParagraphStyles");
161 uno::Reference
< beans::XPropertySet
> properties(paragraphStyles
->getByName("Heading 1"), uno::UNO_QUERY
);
162 CPPUNIT_ASSERT_EQUAL(OUString("Standard"), getProperty
<OUString
>(properties
, "FollowStyle"));
164 // This was 0, as export of w:outlineLvl was missing.
165 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), getProperty
<sal_Int32
>(properties
, "OutlineLevel"));
167 properties
.set(paragraphStyles
->getByName("Heading 11"), uno::UNO_QUERY
);
168 CPPUNIT_ASSERT_EQUAL(OUString("Heading 1"), getProperty
<OUString
>(properties
, "FollowStyle"));
170 // Make sure style #2 is Heading 1.
171 assertXPath(pXmlStyles
, "/w:styles/w:style[2]", "styleId", "Heading1");
172 // w:ind was copied from the parent (Normal) style without a good reason.
173 assertXPath(pXmlStyles
, "/w:styles/w:style[2]/w:pPr/w:ind", 0);
175 // We output exactly 2 properties in rPrDefault, nothing else was
176 // introduced as an additional default
177 assertXPath(pXmlStyles
, "/w:styles/w:docDefaults/w:rPrDefault/w:rPr/*", 2);
178 // Check that we output real content of rPrDefault
179 assertXPath(pXmlStyles
, "/w:styles/w:docDefaults/w:rPrDefault/w:rPr/w:rFonts", "ascii", "Times New Roman");
180 assertXPath(pXmlStyles
, "/w:styles/w:docDefaults/w:rPrDefault/w:rPr/w:lang", "bidi", "ar-SA");
181 // pPrDefault contains only one hyphenation property
182 assertXPath(pXmlStyles
, "/w:styles/w:docDefaults/w:pPrDefault/w:pPr/*", 1);
184 // Check latent styles
185 uno::Sequence
<beans::PropertyValue
> aGrabBag
= getProperty
< uno::Sequence
<beans::PropertyValue
> >(mxComponent
, "InteropGrabBag");
186 uno::Sequence
<beans::PropertyValue
> aLatentStyles
;
187 for (beans::PropertyValue
const & prop
: std::as_const(aGrabBag
))
188 if (prop
.Name
== "latentStyles")
189 prop
.Value
>>= aLatentStyles
;
190 CPPUNIT_ASSERT(aLatentStyles
.getLength()); // document should have latent styles
192 // Check latent style default attributes
194 uno::Sequence
<beans::PropertyValue
> aLatentStyleExceptions
;
195 for (beans::PropertyValue
const & prop
: std::as_const(aLatentStyles
))
197 if (prop
.Name
== "count")
198 aCount
= prop
.Value
.get
<OUString
>();
199 else if (prop
.Name
== "lsdExceptions")
200 prop
.Value
>>= aLatentStyleExceptions
;
202 CPPUNIT_ASSERT_EQUAL(OUString("371"), aCount
); // This check the "count" attribute.
204 // Check exceptions to the latent style defaults.
205 uno::Sequence
<beans::PropertyValue
> aLatentStyleException
;
206 aLatentStyleExceptions
[0].Value
>>= aLatentStyleException
;
208 for (beans::PropertyValue
const & prop
: std::as_const(aLatentStyleException
))
209 if (prop
.Name
== "name")
210 aName
= prop
.Value
.get
<OUString
>();
211 CPPUNIT_ASSERT_EQUAL(OUString("Normal"), aName
); // This checks the "name" attribute of the first exception.
213 // This numbering style wasn't roundtripped.
214 assertXPath(pXmlStyles
, "/w:styles/w:style[@w:styleId='NoList']/w:name", "val", "No List");
216 // Table style wasn't roundtripped.
217 assertXPath(pXmlStyles
, "/w:styles/w:style[@w:styleId='TableNormal']/w:tblPr/w:tblCellMar/w:left", "w", "108");
218 assertXPath(pXmlStyles
, "/w:styles/w:style[@w:styleId='TableNormal']/w:semiHidden", 1);
219 assertXPath(pXmlStyles
, "/w:styles/w:style[@w:styleId='TableNormal']/w:unhideWhenUsed", 1);
221 // Additional para style properties should be also roundtripped.
222 assertXPath(pXmlStyles
, "/w:styles/w:style[@w:styleId='ListParagraph']/w:uiPriority", "val", "34");
223 assertXPath(pXmlStyles
, "/w:styles/w:style[@w:styleId='Normal']/w:qFormat", 1);
224 assertXPath(pXmlStyles
, "/w:styles/w:style[@w:styleId='Normal']/w:rsid", "val", "00780346");
225 assertXPath(pXmlStyles
, "/w:styles/w:style[@w:styleId='Normal']", "default", "1");
227 assertXPath(pXmlStyles
, "/w:styles/w:style[@w:styleId='Heading1']/w:link", "val", "Heading1Char");
228 assertXPath(pXmlStyles
, "/w:styles/w:style[@w:styleId='Heading1']/w:locked", 1);
230 assertXPath(pXmlStyles
, "/w:styles/w:style[@w:styleId='Heading11']", "customStyle", "1");
231 assertXPath(pXmlStyles
, "/w:styles/w:style[@w:styleId='Heading11']/w:autoRedefine", 1);
233 // Additional char style properties should be also roundtripped.
234 assertXPath(pXmlStyles
, "/w:styles/w:style[@w:styleId='DefaultParagraphFont']", "default", "1");
236 // Finally check the same for numbering styles.
237 assertXPath(pXmlStyles
, "/w:styles/w:style[@w:styleId='NoList']", "default", "1");
239 // This was 1, the default style had <w:suppressAutoHyphens w:val="true"/> even for a default style having no RES_PARATR_HYPHENZONE set.
240 assertXPath(pXmlStyles
, "/w:styles/w:style[@w:styleId='Normal']/w:pPr/w:suppressAutoHyphens", 0);
243 CPPUNIT_TEST_FIXTURE(Test
, testCalendar1
)
245 loadAndSave("calendar1.docx");
246 // Document has a non-trivial table style, test the roundtrip of it.
247 xmlDocUniquePtr pXmlStyles
= parseExport("word/styles.xml");
248 assertXPath(pXmlStyles
, "/w:styles/w:style[@w:styleId='Calendar1']/w:basedOn", "val", "TableNormal");
249 assertXPath(pXmlStyles
, "/w:styles/w:style[@w:styleId='Calendar1']/w:rsid", "val", "00903003");
250 assertXPath(pXmlStyles
, "/w:styles/w:style[@w:styleId='Calendar1']/w:tblPr/w:tblStyleColBandSize", "val", "1");
251 assertXPath(pXmlStyles
, "/w:styles/w:style[@w:styleId='Calendar1']/w:tcPr/w:shd", "val", "clear");
253 // Table style lost its paragraph / run properties.
254 assertXPath(pXmlStyles
, "/w:styles/w:style[@w:styleId='Calendar1']/w:pPr/w:spacing", "lineRule", "auto");
255 assertXPath(pXmlStyles
, "/w:styles/w:style[@w:styleId='Calendar1']/w:rPr/w:lang", "eastAsia", "ja-JP");
257 // Table style lost its conditional table formatting properties.
258 assertXPath(pXmlStyles
, "/w:styles/w:style[@w:styleId='Calendar1']/w:tblStylePr[@w:type='firstRow']/w:pPr/w:wordWrap", 1);
259 assertXPath(pXmlStyles
, "/w:styles/w:style[@w:styleId='Calendar1']/w:tblStylePr[@w:type='firstRow']/w:rPr/w:rFonts", "hAnsiTheme", "minorHAnsi");
260 assertXPath(pXmlStyles
, "/w:styles/w:style[@w:styleId='Calendar1']/w:tblStylePr[@w:type='firstRow']/w:tblPr", 1);
261 assertXPath(pXmlStyles
, "/w:styles/w:style[@w:styleId='Calendar1']/w:tblStylePr[@w:type='firstRow']/w:tcPr/w:vAlign", "val", "bottom");
262 assertXPath(pXmlStyles
, "/w:styles/w:style[@w:styleId='Calendar1']/w:tblStylePr[@w:type='lastRow']/w:tcPr/w:tcBorders/w:tr2bl", "val", "nil");
263 assertXPath(pXmlStyles
, "/w:styles/w:style[@w:styleId='Calendar1']/w:tblStylePr[@w:type='band2Horz']/w:tcPr/w:tcBorders/w:top", "themeColor", "text1");
265 // w:tblLook element and its attributes were missing.
266 xmlDocUniquePtr pXmlDoc
= parseExport("word/document.xml");
267 assertXPath(pXmlDoc
, "/w:document/w:body/w:tbl/w:tblPr/w:tblLook", "firstRow", "1");
268 assertXPath(pXmlDoc
, "/w:document/w:body/w:tbl/w:tblPr/w:tblLook", "lastRow", "0");
269 assertXPath(pXmlDoc
, "/w:document/w:body/w:tbl/w:tblPr/w:tblLook", "lastColumn", "0");
270 assertXPath(pXmlDoc
, "/w:document/w:body/w:tbl/w:tblPr/w:tblLook", "firstColumn", "1");
271 assertXPath(pXmlDoc
, "/w:document/w:body/w:tbl/w:tblPr/w:tblLook", "noHBand", "0");
272 assertXPath(pXmlDoc
, "/w:document/w:body/w:tbl/w:tblPr/w:tblLook", "noVBand", "1");
273 assertXPath(pXmlDoc
, "/w:document/w:body/w:tbl/w:tblPr/w:tblLook", "val", "04a0");
276 DECLARE_OOXMLEXPORT_TEST(testCalendar2
, "calendar2.docx")
278 // Problem was that CharCaseMap was style::CaseMap::NONE.
279 uno::Reference
<text::XTextTable
> xTable(getParagraphOrTable(1), uno::UNO_QUERY
);
280 uno::Reference
<text::XTextRange
> xCell(xTable
->getCellByName("A1"), uno::UNO_QUERY
);
281 CPPUNIT_ASSERT_EQUAL(style::CaseMap::UPPERCASE
, getProperty
<sal_Int16
>(getRun(getParagraphOfText(1, xCell
->getText()), 1), "CharCaseMap"));
282 // Font size in the second row was 11.
283 xCell
.set(xTable
->getCellByName("A2"), uno::UNO_QUERY
);
284 CPPUNIT_ASSERT_EQUAL(16.f
, getProperty
<float>(getRun(getParagraphOfText(1, xCell
->getText()), 1), "CharHeight"));
285 // Font size in the third row was 11 as well.
286 xCell
.set(xTable
->getCellByName("B3"), uno::UNO_QUERY
);
287 CPPUNIT_ASSERT_EQUAL(14.f
, getProperty
<float>(getRun(getParagraphOfText(1, xCell
->getText()), 1), "CharHeight"));
289 // This paragraph property was missing in table style.
292 xmlDocUniquePtr pXmlStyles
= parseExport("word/styles.xml");
293 assertXPath(pXmlStyles
, "/w:styles/w:style[@w:styleId='Calendar2']/w:pPr/w:jc", "val", "center");
295 // These run properties were missing
296 assertXPath(pXmlStyles
, "/w:styles/w:style[@w:styleId='Calendar2']/w:rPr/w:lang", "val", "en-US");
297 assertXPath(pXmlStyles
, "/w:styles/w:style[@w:styleId='Calendar2']/w:rPr/w:lang", "bidi", "ar-SA");
298 assertXPath(pXmlStyles
, "/w:styles/w:style[@w:styleId='Calendar2']/w:tblStylePr[@w:type='firstRow']/w:rPr/w:caps", 1);
299 assertXPath(pXmlStyles
, "/w:styles/w:style[@w:styleId='Calendar2']/w:tblStylePr[@w:type='firstRow']/w:rPr/w:smallCaps", "val", "0");
300 assertXPath(pXmlStyles
, "/w:styles/w:style[@w:styleId='Calendar2']/w:tblStylePr[@w:type='firstRow']/w:rPr/w:color", "themeColor", "accent1");
301 assertXPath(pXmlStyles
, "/w:styles/w:style[@w:styleId='Calendar2']/w:tblStylePr[@w:type='firstRow']/w:rPr/w:spacing", "val", "20");
303 // Table borders were also missing
304 assertXPath(pXmlStyles
, "/w:styles/w:style[@w:styleId='Calendar2']/w:tblPr/w:tblBorders/w:insideV", "themeTint", "99");
307 DECLARE_OOXMLEXPORT_TEST(testCalendar3
, "calendar3.docx")
309 // TableStyle:firstRow (for header rows 1 and 2) color and size overrides document rPrDefault
310 uno::Reference
<text::XTextTable
> xTable(getParagraphOrTable(1), uno::UNO_QUERY
);
311 uno::Reference
<text::XTextRange
> xCell(xTable
->getCellByName("A2"), uno::UNO_QUERY
);
312 CPPUNIT_ASSERT_EQUAL(Color(0x5B9BD5), getProperty
<Color
>(getRun(getParagraphOfText(1, xCell
->getText()), 1), "CharColor"));
313 CPPUNIT_ASSERT_EQUAL(16.f
, getProperty
<float>(getRun(getParagraphOfText(1, xCell
->getText()),1), "CharHeight"));
314 // direct formatting in A1
315 uno::Reference
<text::XTextRange
> xCell2(xTable
->getCellByName("A1"), uno::UNO_QUERY
);
316 CPPUNIT_ASSERT_EQUAL(Color(0x2E74B5), getProperty
<Color
>(getRun(getParagraphOfText(1, xCell2
->getText()), 1), "CharColor"));
317 CPPUNIT_ASSERT_EQUAL(20.f
, getProperty
<float>(getRun(getParagraphOfText(1, xCell2
->getText()),1), "CharHeight"));
319 // tdf#132149 Despite specifying portrait, the page size's specified width is greater than its height.
320 // Both Word and LO display it as landscape, so ensure that it round-trips with landscape dimensions.
321 uno::Reference
<beans::XPropertySet
> xPageStyle(getStyles("PageStyles")->getByName("Standard"), uno::UNO_QUERY
);
322 CPPUNIT_ASSERT_EQUAL_MESSAGE("Page Width (mm) ", sal_Int32(148), getProperty
<sal_Int32
>(xPageStyle
, "Width") / 100);
323 CPPUNIT_ASSERT_EQUAL_MESSAGE("Page Height (mm)", sal_Int32(104), getProperty
<sal_Int32
>(xPageStyle
, "Height") / 100);
326 DECLARE_OOXMLEXPORT_TEST(testCalendar4
, "calendar4.docx")
328 // TableStyle:fontsize - overrides DocDefaults, but not Style.
329 // In this case the style does not define anything (but does copy-inherit the DocDefaults size 36)
330 uno::Reference
<text::XTextTable
> xTable(getParagraphOrTable(1), uno::UNO_QUERY
);
331 uno::Reference
<text::XTextRange
> xCell(xTable
->getCellByName("A3"), uno::UNO_QUERY
);
332 CPPUNIT_ASSERT_EQUAL(14.f
, getProperty
<float>(getRun(xCell
,1), "CharHeight"));
335 DECLARE_OOXMLEXPORT_TEST(testCalendar5
, "calendar5.docx")
337 // check text portions with and without direct formatting
338 uno::Reference
<text::XTextTable
> xTable(getParagraphOrTable(1), uno::UNO_QUERY
);
339 uno::Reference
<text::XTextRange
> xCell(xTable
->getCellByName("A1"), uno::UNO_QUERY
);
340 // text portions with direct formatting
341 CPPUNIT_ASSERT_EQUAL(Color(0x2E74B5), getProperty
<Color
>(getRun(getParagraphOfText(1, xCell
->getText()), 1), "CharColor"));
342 CPPUNIT_ASSERT_EQUAL(Color(0xFF0000), getProperty
<Color
>(getRun(getParagraphOfText(1, xCell
->getText()), 2), "CharColor"));
343 // default paragraph text color
344 CPPUNIT_ASSERT_EQUAL(Color(0x5B9BD5), getProperty
<Color
>(getRun(getParagraphOfText(1, xCell
->getText()), 3), "CharColor"));
345 // text portions with direct formatting
346 CPPUNIT_ASSERT_EQUAL(20.f
, getProperty
<float>(getRun(getParagraphOfText(1, xCell
->getText()),1), "CharHeight"));
347 CPPUNIT_ASSERT_EQUAL(10.f
, getProperty
<float>(getRun(getParagraphOfText(1, xCell
->getText()),2), "CharHeight"));
348 // default paragraph text size
349 CPPUNIT_ASSERT_EQUAL(16.f
, getProperty
<float>(getRun(getParagraphOfText(1, xCell
->getText()),3), "CharHeight"));
352 CPPUNIT_TEST_FIXTURE(Test
, testTcBorders
)
354 loadAndSave("testTcBorders.docx");
355 //fdo#76635 : Table borders are not getting preserved.
357 xmlDocUniquePtr pXmlDocument
= parseExport("word/document.xml");
359 assertXPath(pXmlDocument
, "/w:document[1]/w:body[1]/w:tbl[1]/w:tr[1]/w:tc[1]/w:tcPr[1]/w:tcBorders[1]/w:bottom[1][@w:val = 'single']",1);
360 assertXPath(pXmlDocument
, "/w:document[1]/w:body[1]/w:tbl[1]/w:tr[1]/w:tc[1]/w:tcPr[1]/w:tcBorders[1]/w:bottom[1][@w:sz = 4]", 1);
361 assertXPath(pXmlDocument
, "/w:document[1]/w:body[1]/w:tbl[1]/w:tr[1]/w:tc[1]/w:tcPr[1]/w:tcBorders[1]/w:bottom[1][@w:space = 0]", 1);
362 assertXPath(pXmlDocument
, "/w:document[1]/w:body[1]/w:tbl[1]/w:tr[1]/w:tc[1]/w:tcPr[1]/w:tcBorders[1]/w:bottom[1][@w:color = 808080]", 1);
364 uno::Reference
<beans::XPropertySet
> xStyle(
365 getStyles("CharacterStyles")->getByName("Code Featured Element"),
367 CPPUNIT_ASSERT_EQUAL_MESSAGE("Bold", float(150), getProperty
<float>(xStyle
, "CharWeight"));
370 CPPUNIT_TEST_FIXTURE(Test
, testQuicktables
)
372 loadAndSave("quicktables.docx");
373 xmlDocUniquePtr pXmlStyles
= parseExport("word/styles.xml");
375 // These were missing in the Calendar3 table style.
376 assertXPath(pXmlStyles
, "/w:styles/w:style[@w:styleId='Calendar3']/w:rPr/w:rFonts", "cstheme", "majorBidi");
377 assertXPath(pXmlStyles
, "/w:styles/w:style[@w:styleId='Calendar3']/w:rPr/w:color", "themeTint", "80");
378 CPPUNIT_ASSERT(getXPath(pXmlStyles
, "/w:styles/w:style[@w:styleId='Calendar3']/w:tblStylePr[@w:type='firstRow']/w:rPr/w:color", "themeShade").equalsIgnoreAsciiCase("BF"));
381 assertXPath(pXmlStyles
, "/w:styles/w:style[@w:styleId='Calendar4']/w:pPr/w:snapToGrid", "val", "0");
382 assertXPath(pXmlStyles
, "/w:styles/w:style[@w:styleId='Calendar4']/w:rPr/w:bCs", 1);
383 assertXPath(pXmlStyles
, "/w:styles/w:style[@w:styleId='Calendar4']/w:tcPr/w:shd", "themeFill", "accent1");
384 assertXPath(pXmlStyles
, "/w:styles/w:style[@w:styleId='Calendar4']/w:tcPr/w:shd", "themeFillShade", "80");
385 assertXPath(pXmlStyles
, "/w:styles/w:style[@w:styleId='Calendar4']/w:tblStylePr[@w:type='firstCol']/w:pPr/w:ind", "rightChars", "0");
386 assertXPath(pXmlStyles
, "/w:styles/w:style[@w:styleId='Calendar4']/w:tblStylePr[@w:type='firstCol']/w:pPr/w:ind", "right", "144");
387 assertXPath(pXmlStyles
, "/w:styles/w:style[@w:styleId='Calendar4']/w:tblStylePr[@w:type='band2Horz']/w:tcPr/w:tcMar/w:bottom", "w", "86");
390 assertXPath(pXmlStyles
, "/w:styles/w:style[@w:styleId='LightList']/w:tblStylePr[@w:type='firstRow']/w:pPr/w:spacing", "before", "0");
392 // MediumList2-Accent1.
393 CPPUNIT_ASSERT(getXPath(pXmlStyles
, "/w:styles/w:style[@w:styleId='MediumList2-Accent1']/w:tblStylePr[@w:type='band1Vert']/w:tcPr/w:shd", "themeFillTint").equalsIgnoreAsciiCase("3F"));
395 // MediumShading2-Accent5.
396 assertXPath(pXmlStyles
, "/w:styles/w:style[@w:styleId='MediumShading2-Accent5']/w:tblStylePr[@w:type='firstRow']/w:tcPr/w:tcBorders/w:top", "color", "auto");
399 CPPUNIT_TEST_FIXTURE(Test
, testFdo71302
)
401 loadAndSave("fdo71302.docx");
402 xmlDocUniquePtr pXmlStyles
= parseExport("word/styles.xml");
404 // This got renamed to "Strong Emphasis" without a good reason.
405 assertXPath(pXmlStyles
, "/w:styles/w:style[@w:styleId='Strong']", 1);
409 DECLARE_OOXMLEXPORT_TEST(testSmartart
, "smartart.docx")
411 uno::Reference
<text::XTextDocument
> xTextDocument(mxComponent
, uno::UNO_QUERY
);
412 uno::Reference
<beans::XPropertySet
> xTextDocumentPropertySet(xTextDocument
, uno::UNO_QUERY
);
413 uno::Sequence
<beans::PropertyValue
> aGrabBag(0);
414 xTextDocumentPropertySet
->getPropertyValue("InteropGrabBag") >>= aGrabBag
;
415 CPPUNIT_ASSERT(aGrabBag
.hasElements()); // Grab Bag not empty
418 for(beans::PropertyValue
const & prop
: std::as_const(aGrabBag
))
420 if (prop
.Name
== "OOXTheme")
423 uno::Reference
<xml::dom::XDocument
> aThemeDom
;
424 CPPUNIT_ASSERT(prop
.Value
>>= aThemeDom
); // PropertyValue of proper type
425 CPPUNIT_ASSERT(aThemeDom
); // Reference not empty
428 CPPUNIT_ASSERT(bTheme
); // Grab Bag has all the expected elements
430 CPPUNIT_ASSERT_EQUAL(1, getShapes()); // One groupshape in the doc
432 uno::Reference
<container::XIndexAccess
> xGroup(getShape(1), uno::UNO_QUERY
);
433 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xGroup
->getCount()); // 1 rendered bitmap from the original shapes
435 uno::Reference
<beans::XPropertySet
> xGroupPropertySet(getShape(1), uno::UNO_QUERY
);
436 xGroupPropertySet
->getPropertyValue("InteropGrabBag") >>= aGrabBag
;
437 CPPUNIT_ASSERT(aGrabBag
.hasElements()); // Grab Bag not empty
439 bool bData
= false, bLayout
= false, bQStyle
= false, bColor
= false, bDrawing
= false;
440 for(beans::PropertyValue
const & prop
: std::as_const(aGrabBag
))
442 if (prop
.Name
== "OOXData")
445 uno::Reference
<xml::dom::XDocument
> aDataDom
;
446 CPPUNIT_ASSERT(prop
.Value
>>= aDataDom
); // PropertyValue of proper type
447 CPPUNIT_ASSERT(aDataDom
); // Reference not empty
449 else if (prop
.Name
== "OOXLayout")
452 uno::Reference
<xml::dom::XDocument
> aLayoutDom
;
453 CPPUNIT_ASSERT(prop
.Value
>>= aLayoutDom
); // PropertyValue of proper type
454 CPPUNIT_ASSERT(aLayoutDom
); // Reference not empty
456 else if (prop
.Name
== "OOXStyle")
459 uno::Reference
<xml::dom::XDocument
> aStyleDom
;
460 CPPUNIT_ASSERT(prop
.Value
>>= aStyleDom
); // PropertyValue of proper type
461 CPPUNIT_ASSERT(aStyleDom
); // Reference not empty
463 else if (prop
.Name
== "OOXColor")
466 uno::Reference
<xml::dom::XDocument
> aColorDom
;
467 CPPUNIT_ASSERT(prop
.Value
>>= aColorDom
); // PropertyValue of proper type
468 CPPUNIT_ASSERT(aColorDom
); // Reference not empty
470 else if (prop
.Name
== "OOXDrawing")
473 uno::Sequence
< uno::Any
> diagramDrawing
;
474 uno::Reference
<xml::dom::XDocument
> aDrawingDom
;
475 CPPUNIT_ASSERT(prop
.Value
>>= diagramDrawing
);
476 CPPUNIT_ASSERT(diagramDrawing
[0] >>= aDrawingDom
); // PropertyValue of proper type
477 CPPUNIT_ASSERT(aDrawingDom
); // Reference not empty
480 // Grab Bag has all the expected elements:
481 CPPUNIT_ASSERT(bData
);
482 CPPUNIT_ASSERT(bLayout
);
483 CPPUNIT_ASSERT(bQStyle
);
484 CPPUNIT_ASSERT(bColor
);
485 CPPUNIT_ASSERT(bDrawing
);
487 uno::Reference
<beans::XPropertySet
> xPropertySet(xGroup
->getByIndex(0), uno::UNO_QUERY
);
489 xPropertySet
->getPropertyValue("Name") >>= nValue
;
490 CPPUNIT_ASSERT_EQUAL(OUString("RenderedShapes"), nValue
); // Rendered bitmap has the proper name
493 CPPUNIT_TEST_FIXTURE(Test
, testFontNameIsEmpty
)
495 loadAndSave("font-name-is-empty.docx");
496 // Check no empty font name is exported
497 // This test does not fail, if the document contains a font with empty name.
499 xmlDocUniquePtr pXmlFontTable
= parseExport("word/fontTable.xml");
500 xmlXPathObjectPtr pXmlObj
= getXPathNode(pXmlFontTable
, "/w:fonts/w:font");
501 xmlNodeSetPtr pXmlNodes
= pXmlObj
->nodesetval
;
502 sal_Int32 length
= xmlXPathNodeSetGetLength(pXmlNodes
);
503 for(sal_Int32 index
= 0; index
< length
; index
++){
504 xmlNodePtr pXmlNode
= pXmlNodes
->nodeTab
[index
];
505 OUString attrVal
= OUString::createFromAscii(reinterpret_cast<char*>(xmlGetProp(pXmlNode
, BAD_CAST("name"))));
506 if (attrVal
.isEmpty()){
507 CPPUNIT_FAIL("Font name is empty.");
510 xmlXPathFreeObject(pXmlObj
);
513 CPPUNIT_TEST_FIXTURE(Test
, testMultiColumnLineSeparator
)
515 loadAndSave("multi-column-line-separator-SAVED.docx");
516 // Check for the Column Separator value.It should be FALSE as the document does not contain separator line.
517 xmlDocUniquePtr pXmlDoc
= parseExport("word/document.xml");
518 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[3]/w:pPr/w:sectPr/w:cols","sep","false");
521 DECLARE_OOXMLEXPORT_TEST(testCustomXmlGrabBag
, "customxml.docx")
523 // The problem was that item[n].xml and itemProps[n].xml and .rels files for item[n].xml
524 // files were missing from docx file after saving file.
525 // This test case tests whether customxml files grabbagged properly in correct object.
527 uno::Reference
<text::XTextDocument
> xTextDocument(mxComponent
, uno::UNO_QUERY
);
528 uno::Reference
<beans::XPropertySet
> xTextDocumentPropertySet(xTextDocument
, uno::UNO_QUERY
);
529 uno::Sequence
<beans::PropertyValue
> aGrabBag(0);
530 xTextDocumentPropertySet
->getPropertyValue("InteropGrabBag") >>= aGrabBag
;
531 CPPUNIT_ASSERT(aGrabBag
.hasElements()); // Grab Bag not empty
532 bool CustomXml
= false;
533 for(beans::PropertyValue
const & prop
: std::as_const(aGrabBag
))
535 if (prop
.Name
== "OOXCustomXml" || prop
.Name
== "OOXCustomXmlProps")
538 uno::Reference
<xml::dom::XDocument
> aCustomXmlDom
;
539 uno::Sequence
<uno::Reference
<xml::dom::XDocument
> > aCustomXmlDomList
;
540 CPPUNIT_ASSERT(prop
.Value
>>= aCustomXmlDomList
); // PropertyValue of proper type
541 sal_Int32 length
= aCustomXmlDomList
.getLength();
542 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), length
);
543 aCustomXmlDom
= aCustomXmlDomList
[0];
544 CPPUNIT_ASSERT(aCustomXmlDom
); // Reference not empty
547 CPPUNIT_ASSERT(CustomXml
); // Grab Bag has all the expected elements
550 CPPUNIT_TEST_FIXTURE(Test
, testCustomXmlRelationships
)
552 loadAndSave("customxml.docx");
553 xmlDocUniquePtr pXmlDoc
= parseExport("customXml/_rels/item1.xml.rels");
555 // Check there is a relation to itemProps1.xml.
556 assertXPath(pXmlDoc
, "/rels:Relationships/rels:Relationship", 1);
557 assertXPath(pXmlDoc
, "/rels:Relationships/rels:Relationship[@Id='rId1']", "Target", "itemProps1.xml");
560 CPPUNIT_TEST_FIXTURE(Test
, testFdo69644
)
562 loadAndSave("fdo69644.docx");
563 // The problem was that the exporter exported the table definition
564 // with only 3 columns, instead of 5 columns.
565 // Check that the table grid is exported with 5 columns
566 xmlDocUniquePtr pXmlDoc
= parseExport("word/document.xml");
567 assertXPath(pXmlDoc
, "/w:document/w:body/w:tbl/w:tblGrid/w:gridCol", 5);
570 DECLARE_OOXMLEXPORT_TEST(testFdo70812
, "fdo70812.docx")
572 // Import just crashed.
573 getParagraph(1, "Sample pages document.");
576 CPPUNIT_TEST_FIXTURE(Test
, testPgMargin
)
578 loadAndSave("testPgMargin.docx");
579 xmlDocUniquePtr pXmlDoc
= parseExport("word/document.xml");
580 assertXPath(pXmlDoc
, "/w:document/w:body/w:sectPr/w:pgMar", "left", "1440");
583 DECLARE_OOXMLEXPORT_TEST(testImageCrop
, "ImageCrop.docx")
585 uno::Reference
<drawing::XShape
> image
= getShape(1);
586 uno::Reference
<beans::XPropertySet
> imageProperties(image
, uno::UNO_QUERY
);
587 css::text::GraphicCrop aGraphicCropStruct
;
589 imageProperties
->getPropertyValue( "GraphicCrop" ) >>= aGraphicCropStruct
;
591 CPPUNIT_ASSERT_EQUAL( sal_Int32( 2955 ), aGraphicCropStruct
.Left
);
592 CPPUNIT_ASSERT_EQUAL( sal_Int32( 5477 ), aGraphicCropStruct
.Right
);
593 CPPUNIT_ASSERT_EQUAL( sal_Int32( 2856 ), aGraphicCropStruct
.Top
);
594 CPPUNIT_ASSERT_EQUAL( sal_Int32( 2291 ), aGraphicCropStruct
.Bottom
);
597 DECLARE_OOXMLEXPORT_TEST(testTdf106974_int32Crop
, "tdf106974_int32Crop.docx")
599 uno::Reference
<drawing::XShape
> image
= getShape(1);
600 uno::Reference
<beans::XPropertySet
> imageProperties(image
, uno::UNO_QUERY
);
601 css::text::GraphicCrop aGraphicCropStruct
;
603 imageProperties
->getPropertyValue( "GraphicCrop" ) >>= aGraphicCropStruct
;
605 // The crop is constructed in GraphicProperties::pushToPropMap, where
606 // GraphicHelper::getOriginalSize tries to get graphic size in mm, then falls back to pixels,
607 // which are then converted to mm taking screen DPI scaling into account. Thus, the resulting
608 // values are DPI-dependent.
609 const double fXScaleFactor
= 96.0 / Application::GetDefaultDevice()->GetDPIX();
611 CPPUNIT_ASSERT_MESSAGE(
612 OString::number(aGraphicCropStruct
.Right
).getStr(),
613 40470 * fXScaleFactor
< aGraphicCropStruct
.Right
);
616 DECLARE_OOXMLEXPORT_TEST(testLineSpacingexport
, "test_line_spacing.docx")
618 // The Problem was that the w:line attribute value in w:spacing tag was incorrect
619 uno::Reference
<text::XTextDocument
> xTextDocument(mxComponent
, uno::UNO_QUERY
);
620 uno::Reference
<container::XEnumerationAccess
> xParaEnumAccess(xTextDocument
->getText(), uno::UNO_QUERY
);
621 uno::Reference
<container::XEnumeration
> xParaEnum
= xParaEnumAccess
->createEnumeration();
622 CPPUNIT_ASSERT(xParaEnum
->hasMoreElements());
624 // FIXME The test passes on most machines (including Linux x86_64 with gcc-4.7), but fails on various configs:
625 // Linux arm, Linux x86_64 with gcc-4.8 and Mac. Need to figure out what goes wrong and fix that.
627 style::LineSpacing alineSpacing
= getProperty
<style::LineSpacing
>(xParaEnum
->nextElement(), "ParaLineSpacing");
628 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16
>(13200), static_cast<sal_Int16
>(alineSpacing
.Height
));
629 xmlDocPtr pXmlDoc
= parseExport("word/document.xml");
632 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[1]/w:pPr/w:spacing", "line", "31680");
636 DECLARE_OOXMLEXPORT_TEST(testTextBoxGradientAngle
, "fdo65295.docx")
638 CPPUNIT_ASSERT_EQUAL(8, getShapes());
640 // Angle of frame#1 is 135 degrees, but 'aGradient.Angle' holds value in 1/10 of a degree
641 uno::Reference
<beans::XPropertySet
> xFrame1(getShape(1), uno::UNO_QUERY
);
642 CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_GRADIENT
, getProperty
<drawing::FillStyle
>(xFrame1
, "FillStyle"));
643 awt::Gradient aGradient1
= getProperty
<awt::Gradient
>(xFrame1
, "FillGradient");
644 CPPUNIT_ASSERT_EQUAL(sal_Int16(135 * 10), aGradient1
.Angle
);
646 // Angle of frame#2 is 180 degrees, but 'aGradient.Angle' holds value in 1/10 of a degree
647 uno::Reference
<beans::XPropertySet
> xFrame2(getShape(2), uno::UNO_QUERY
);
648 CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_GRADIENT
, getProperty
<drawing::FillStyle
>(xFrame2
, "FillStyle"));
649 awt::Gradient aGradient2
= getProperty
<awt::Gradient
>(xFrame2
, "FillGradient");
650 CPPUNIT_ASSERT_EQUAL(sal_Int16(180 * 10), aGradient2
.Angle
);
652 // Angle of frame#3 is 90 degrees, but 'aGradient.Angle' holds value in 1/10 of a degree
653 uno::Reference
<beans::XPropertySet
> xFrame3(getShape(3), uno::UNO_QUERY
);
654 CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_GRADIENT
, getProperty
<drawing::FillStyle
>(xFrame3
, "FillStyle"));
655 awt::Gradient aGradient3
= getProperty
<awt::Gradient
>(xFrame3
, "FillGradient");
656 CPPUNIT_ASSERT_EQUAL(sal_Int16( 90 * 10), aGradient3
.Angle
);
658 // Angle of frame#4 is 225 degrees, but 'aGradient.Angle' holds value in 1/10 of a degree
659 uno::Reference
<beans::XPropertySet
> xFrame4(getShape(4), uno::UNO_QUERY
);
660 CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_GRADIENT
, getProperty
<drawing::FillStyle
>(xFrame4
, "FillStyle"));
661 awt::Gradient aGradient4
= getProperty
<awt::Gradient
>(xFrame4
, "FillGradient");
662 CPPUNIT_ASSERT_EQUAL(sal_Int16(225 * 10), aGradient4
.Angle
);
664 // Angle of frame#5 is 270 degrees, but 'aGradient.Angle' holds value in 1/10 of a degree
665 uno::Reference
<beans::XPropertySet
> xFrame5(getShape(5), uno::UNO_QUERY
);
666 CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_GRADIENT
, getProperty
<drawing::FillStyle
>(xFrame5
, "FillStyle"));
667 awt::Gradient aGradient5
= getProperty
<awt::Gradient
>(xFrame5
, "FillGradient");
668 CPPUNIT_ASSERT_EQUAL(sal_Int16(270 * 10), aGradient5
.Angle
);
670 // Angle of frame#6 is 315 degrees, but 'aGradient.Angle' holds value in 1/10 of a degree
671 uno::Reference
<beans::XPropertySet
> xFrame6(getShape(6), uno::UNO_QUERY
);
672 CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_GRADIENT
, getProperty
<drawing::FillStyle
>(xFrame6
, "FillStyle"));
673 awt::Gradient aGradient6
= getProperty
<awt::Gradient
>(xFrame6
, "FillGradient");
674 CPPUNIT_ASSERT_EQUAL(sal_Int16(315 * 10), aGradient6
.Angle
);
676 // Angle of frame#7 is 0 degrees, but 'aGradient.Angle' holds value in 1/10 of a degree
677 uno::Reference
<beans::XPropertySet
> xFrame7(getShape(7), uno::UNO_QUERY
);
678 CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_GRADIENT
, getProperty
<drawing::FillStyle
>(xFrame7
, "FillStyle"));
679 awt::Gradient aGradient7
= getProperty
<awt::Gradient
>(xFrame7
, "FillGradient");
680 CPPUNIT_ASSERT_EQUAL(sal_Int16( 0 * 10), aGradient7
.Angle
);
682 // Angle of frame#8 is 45 degrees, but 'aGradient.Angle' holds value in 1/10 of a degree
683 uno::Reference
<beans::XPropertySet
> xFrame8(getShape(8), uno::UNO_QUERY
);
684 CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_GRADIENT
, getProperty
<drawing::FillStyle
>(xFrame8
, "FillStyle"));
685 awt::Gradient aGradient8
= getProperty
<awt::Gradient
>(xFrame8
, "FillGradient");
686 CPPUNIT_ASSERT_EQUAL(sal_Int16( 45 * 10), aGradient8
.Angle
);
689 CPPUNIT_TEST_FIXTURE(Test
, testCellGridSpan
)
691 loadAndSave("cell-grid-span.docx");
692 // The problem was during export gridSpan value for 1st & 2nd cells for test document
693 // used to get set wrongly to 5 and 65532 respectively which was the reason for crash during save operation
694 // Verifying gridSpan element is not present in RoundTripped Document (As it's Default value is 1).
695 xmlDocUniquePtr pXmlDoc
= parseExport("word/document.xml");
696 assertXPath(pXmlDoc
, "/w:document/w:body/w:tbl/w:tr/w:tc[1]/w:tcPr/w:gridSpan",0);
697 assertXPath(pXmlDoc
, "/w:document/w:body/w:tbl/w:tr/w:tc[2]/w:tcPr/w:gridSpan",0);
699 DECLARE_OOXMLEXPORT_TEST(testFdo71646
, "fdo71646.docx")
701 // The problem was after save file created by MS the direction changed to RTL.
702 uno::Reference
<uno::XInterface
> xParaLTRLeft(getParagraph( 1, "LTR LEFT"));
703 sal_Int32 nLTRLeft
= getProperty
< sal_Int32
>( xParaLTRLeft
, "ParaAdjust" );
704 // test the text Direction value for the paragraph
705 sal_Int16 nLRDir
= getProperty
< sal_Int32
>( xParaLTRLeft
, "WritingMode" );
707 // this will test the both the text direction and alignment for paragraph
708 CPPUNIT_ASSERT_EQUAL( sal_Int32 (style::ParagraphAdjust_LEFT
), nLTRLeft
);
709 CPPUNIT_ASSERT_EQUAL(text::WritingMode2::LR_TB
, nLRDir
);
712 CPPUNIT_TEST_FIXTURE(Test
, testParaAutoSpacing
)
714 loadAndSave("para-auto-spacing.docx");
715 xmlDocUniquePtr pXmlDoc
= parseExport("word/document.xml");
716 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[1]/w:pPr/w:spacing", "beforeAutospacing","1");
717 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[1]/w:pPr/w:spacing", "afterAutospacing","1");
719 assertXPathNoAttribute(pXmlDoc
, "/w:document/w:body/w:p[2]/w:pPr/w:spacing",
720 "beforeAutospacing");
721 assertXPathNoAttribute(pXmlDoc
, "/w:document/w:body/w:p[2]/w:pPr/w:spacing",
723 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[2]/w:pPr/w:spacing", "before","400");
724 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[2]/w:pPr/w:spacing", "after","400");
727 DECLARE_OOXMLEXPORT_TEST(testGIFImageCrop
, "test_GIF_ImageCrop.docx")
729 uno::Reference
<drawing::XShape
> image
= getShape(1);
730 uno::Reference
<beans::XPropertySet
> imageProperties(image
, uno::UNO_QUERY
);
731 css::text::GraphicCrop aGraphicCropStruct
;
733 imageProperties
->getPropertyValue( "GraphicCrop" ) >>= aGraphicCropStruct
;
735 // The crop is constructed in GraphicProperties::pushToPropMap, where
736 // GraphicHelper::getOriginalSize tries to get graphic size in mm, then falls back to pixels,
737 // which are then converted to mm taking screen DPI scaling into account. Thus, the resulting
738 // values are DPI-dependent.
739 const double fXScaleFactor
= 96.0 / Application::GetDefaultDevice()->GetDPIX();
740 const double fYScaleFactor
= 96.0 / Application::GetDefaultDevice()->GetDPIY();
742 CPPUNIT_ASSERT_DOUBLES_EQUAL(1085 * fXScaleFactor
, aGraphicCropStruct
.Left
, 1);
743 CPPUNIT_ASSERT_DOUBLES_EQUAL(3651 * fXScaleFactor
, aGraphicCropStruct
.Right
, 1);
744 CPPUNIT_ASSERT_DOUBLES_EQUAL(953 * fYScaleFactor
, aGraphicCropStruct
.Top
, 1);
745 CPPUNIT_ASSERT_DOUBLES_EQUAL(1244 * fYScaleFactor
, aGraphicCropStruct
.Bottom
, 1);
748 DECLARE_OOXMLEXPORT_TEST(testPNGImageCrop
, "test_PNG_ImageCrop.docx")
750 /* The problem was image cropping information was not getting saved
752 * Check for presence of cropping parameters in exported file.
754 uno::Reference
<drawing::XShape
> image
= getShape(1);
755 uno::Reference
<beans::XPropertySet
> imageProperties(image
, uno::UNO_QUERY
);
756 css::text::GraphicCrop aGraphicCropStruct
;
758 imageProperties
->getPropertyValue( "GraphicCrop" ) >>= aGraphicCropStruct
;
760 // The crop is constructed in GraphicProperties::pushToPropMap, where
761 // GraphicHelper::getOriginalSize tries to get graphic size in mm, then falls back to pixels,
762 // which are then converted to mm taking screen DPI scaling into account. Thus, the resulting
763 // values are DPI-dependent.
764 const double fXScaleFactor
= 96.0 / Application::GetDefaultDevice()->GetDPIX();
765 const double fYScaleFactor
= 96.0 / Application::GetDefaultDevice()->GetDPIY();
767 CPPUNIT_ASSERT_DOUBLES_EQUAL(1058 * fXScaleFactor
, aGraphicCropStruct
.Left
, 1);
768 CPPUNIT_ASSERT_DOUBLES_EQUAL(1111 * fXScaleFactor
, aGraphicCropStruct
.Right
, 1);
769 CPPUNIT_ASSERT_DOUBLES_EQUAL(1164 * fYScaleFactor
, aGraphicCropStruct
.Top
, 1);
770 CPPUNIT_ASSERT_DOUBLES_EQUAL(635 * fYScaleFactor
, aGraphicCropStruct
.Bottom
, 1);
773 CPPUNIT_TEST_FIXTURE(Test
, testTdf41542_imagePadding
)
775 loadAndReload("tdf41542_imagePadding.odt");
776 CPPUNIT_ASSERT_EQUAL(3, getShapes());
777 CPPUNIT_ASSERT_EQUAL(1, getPages());
778 // borderlessImage - image WITHOUT BORDERS : simulate padding with -crop
779 text::GraphicCrop crop
= getProperty
<text::GraphicCrop
>(getShape(2), "GraphicCrop");
780 CPPUNIT_ASSERT( crop
.Left
!= 0 );
781 CPPUNIT_ASSERT( crop
.Right
!= 0 );
782 CPPUNIT_ASSERT_EQUAL( crop
.Left
, crop
.Top
);
783 CPPUNIT_ASSERT_EQUAL( crop
.Right
, crop
.Bottom
);
784 CPPUNIT_ASSERT_EQUAL( crop
.Left
, crop
.Right
);
786 // borderedImage - image WITH BORDERS : simulate padding with -crop
787 crop
= getProperty
<text::GraphicCrop
>(getShape(3), "GraphicCrop");
788 CPPUNIT_ASSERT( crop
.Left
!= 0 );
789 CPPUNIT_ASSERT( crop
.Right
!= 0 );
790 CPPUNIT_ASSERT_EQUAL( crop
.Left
, crop
.Top
);
791 CPPUNIT_ASSERT_EQUAL( crop
.Right
, crop
.Bottom
);
792 CPPUNIT_ASSERT_EQUAL( crop
.Left
, crop
.Right
);
795 CPPUNIT_TEST_FIXTURE(Test
, testFootnoteParagraphTag
)
797 loadAndSave("testFootnote.docx");
798 /* In footnotes.xml, the paragraph tag inside <w:footnote w:id="2"> was getting written into document.xml.
799 * Check for, paragraph tag is correctly written into footnotes.xml.
801 xmlDocUniquePtr pXmlFootnotes
= parseExport("word/footnotes.xml");
802 assertXPath(pXmlFootnotes
, "/w:footnotes/w:footnote[3]","id","2");
803 assertXPath(pXmlFootnotes
, "/w:footnotes/w:footnote[3]/w:p/w:r/w:footnoteRef", 1);
806 CPPUNIT_TEST_FIXTURE(Test
, testSpacingLineRule
)
808 loadAndReload("table_lineRule.docx");
809 xmlDocUniquePtr pXmlDoc
= parseExport("word/document.xml");
810 assertXPath(pXmlDoc
, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:p/w:pPr/w:spacing", "lineRule", "auto");
813 CPPUNIT_TEST_FIXTURE(Test
, testTableLineSpacing
)
815 loadAndSave("table_atleast.docx");
816 xmlDocUniquePtr pXmlDoc
= parseExport("word/document.xml");
817 assertXPath(pXmlDoc
, "/w:document/w:body/w:tbl/w:tr/w:tc/w:p/w:pPr/w:spacing", "line", "320");
820 DECLARE_OOXMLEXPORT_TEST(testOoxmlTriangle
, "ooxml-triangle.docx")
822 // The problem was that ooxml-triangle shape type wasn't handled by VML
823 // export (only isosceles-triangle), leading to a missing shape.
827 DECLARE_OOXMLEXPORT_TEST(testMce
, "mce.docx")
829 // The shape is red in Word2007, green in Word2010. Check that our import follows the later.
830 CPPUNIT_ASSERT_EQUAL(Color(0x9bbb59), getProperty
<Color
>(getShape(1), "FillColor"));
833 CPPUNIT_TEST_FIXTURE(Test
, testThemePreservation
)
835 loadAndSave("theme-preservation.docx");
836 // check default font theme values have been preserved
837 xmlDocUniquePtr pXmlStyles
= parseExport("word/styles.xml");
838 assertXPath(pXmlStyles
, "/w:styles/w:docDefaults/w:rPrDefault/w:rPr/w:rFonts", "asciiTheme", "minorHAnsi");
839 assertXPath(pXmlStyles
, "/w:styles/w:docDefaults/w:rPrDefault/w:rPr/w:rFonts", "cstheme", "minorBidi");
841 // check the font theme values in style definitions
842 assertXPath(pXmlStyles
, "/w:styles/w:style[1]/w:rPr/w:rFonts", "eastAsiaTheme", "minorEastAsia");
844 // check the color theme values in style definitions
845 assertXPath(pXmlStyles
, "/w:styles/w:style[@w:styleId='Custom1']/w:rPr/w:color", "themeColor", "accent1");
846 assertXPath(pXmlStyles
, "/w:styles/w:style[@w:styleId='Custom1']/w:rPr/w:color", "themeTint", "99");
848 // check direct format font theme values have been preserved
849 xmlDocUniquePtr pXmlDocument
= parseExport("word/document.xml");
850 assertXPath(pXmlDocument
, "/w:document/w:body/w:p[5]/w:r[1]/w:rPr/w:rFonts", "hAnsiTheme", "majorHAnsi");
851 assertXPath(pXmlDocument
, "/w:document/w:body/w:p[5]/w:r[1]/w:rPr/w:rFonts", "asciiTheme", "majorHAnsi");
853 // check theme font color value has been preserved
854 assertXPath(pXmlDocument
, "/w:document/w:body/w:p[4]/w:r[1]/w:rPr/w:color", "themeColor", "accent3");
855 OUString sThemeShade
= getXPath(pXmlDocument
, "/w:document/w:body/w:p[4]/w:r[1]/w:rPr/w:color", "themeShade");
856 CPPUNIT_ASSERT_EQUAL(sal_Int32(0xbf), sThemeShade
.toInt32(16));
858 // check the themeFontLang values in settings file
859 xmlDocUniquePtr pXmlSettings
= parseExport("word/settings.xml");
860 assertXPath(pXmlSettings
, "/w:settings/w:themeFontLang", "val", "en-US");
861 assertXPath(pXmlSettings
, "/w:settings/w:themeFontLang", "eastAsia", "zh-CN");
862 assertXPath(pXmlSettings
, "/w:settings/w:themeFontLang", "bidi", "he-IL");
864 // check fonts have been applied properly
865 sal_Unicode fontName
[2]; //represents the string "宋体"
866 fontName
[0] = 0x5b8b;
867 fontName
[1] = 0x4f53;
868 CPPUNIT_ASSERT_EQUAL(OUString(fontName
, 2), getProperty
<OUString
>(getParagraph(1), "CharFontNameAsian"));
869 CPPUNIT_ASSERT_EQUAL(OUString("Arial"),
870 getProperty
<OUString
>(getParagraph(2), "CharFontNameComplex"));
871 CPPUNIT_ASSERT_EQUAL(OUString("Trebuchet MS"),
872 getProperty
<OUString
>(getParagraph(3, "Default style theme font"), "CharFontName"));
873 CPPUNIT_ASSERT_EQUAL(OUString("Arial Black"),
874 getProperty
<OUString
>(getRun(getParagraph(4, "Direct format font"), 1), "CharFontName"));
875 CPPUNIT_ASSERT_EQUAL(OUString("Trebuchet MS"),
876 getProperty
<OUString
>(getParagraph(5, "Major theme font"), "CharFontName"));
878 // check the paragraph background pattern has been preserved including theme colors
879 assertXPath(pXmlDocument
, "/w:document/w:body/w:p[6]/w:pPr/w:shd", "val", "thinHorzStripe");
880 assertXPath(pXmlDocument
, "/w:document/w:body/w:p[6]/w:pPr/w:shd", "themeFill", "text2");
881 assertXPath(pXmlDocument
, "/w:document/w:body/w:p[6]/w:pPr/w:shd", "themeFillTint", "33");
882 assertXPath(pXmlDocument
, "/w:document/w:body/w:p[6]/w:pPr/w:shd", "themeColor", "accent1");
883 assertXPath(pXmlDocument
, "/w:document/w:body/w:p[6]/w:pPr/w:shd", "themeShade", "80");
886 CPPUNIT_TEST_FIXTURE(Test
, testTableThemePreservation
)
888 loadAndSave("table-theme-preservation.docx");
889 xmlDocUniquePtr pXmlDocument
= parseExport("word/document.xml");
891 // check cell theme colors have been preserved
892 assertXPath(pXmlDocument
, "/w:document/w:body/w:tbl/w:tr[2]/w:tc[1]/w:tcPr/w:shd", "themeFill", "accent6");
893 assertXPathNoAttribute(pXmlDocument
, "/w:document/w:body/w:tbl/w:tr[2]/w:tc[1]/w:tcPr/w:shd",
895 assertXPath(pXmlDocument
, "/w:document/w:body/w:tbl/w:tr[2]/w:tc[1]/w:tcPr/w:shd", "themeFillTint", "33");
896 assertXPath(pXmlDocument
, "/w:document/w:body/w:tbl/w:tr[2]/w:tc[2]/w:tcPr/w:shd", "themeFill", "accent6");
897 assertXPathNoAttribute(pXmlDocument
, "/w:document/w:body/w:tbl/w:tr[2]/w:tc[2]/w:tcPr/w:shd",
899 assertXPathNoAttribute(pXmlDocument
, "/w:document/w:body/w:tbl/w:tr[2]/w:tc[2]/w:tcPr/w:shd",
901 assertXPath(pXmlDocument
, "/w:document/w:body/w:tbl/w:tr[2]/w:tc[3]/w:tcPr/w:shd", "themeFill", "accent6");
902 assertXPath(pXmlDocument
, "/w:document/w:body/w:tbl/w:tr[2]/w:tc[3]/w:tcPr/w:shd", "themeFillShade", "80");
903 assertXPathNoAttribute(pXmlDocument
, "/w:document/w:body/w:tbl/w:tr[2]/w:tc[3]/w:tcPr/w:shd",
905 assertXPath(pXmlDocument
, "/w:document/w:body/w:tbl/w:tr[2]/w:tc[3]/w:tcPr/w:shd", "val", "horzStripe");
906 assertXPath(pXmlDocument
, "/w:document/w:body/w:tbl/w:tr[2]/w:tc[3]/w:tcPr/w:shd", "themeColor", "accent3");
907 assertXPath(pXmlDocument
, "/w:document/w:body/w:tbl/w:tr[2]/w:tc[3]/w:tcPr/w:shd", "themeTint", "33");
908 assertXPath(pXmlDocument
, "/w:document/w:body/w:tbl/w:tr[2]/w:tc[3]/w:tcPr/w:shd", "color", "E7EEEE");
910 // check table style has been preserved
911 assertXPath(pXmlDocument
, "/w:document/w:body/w:tbl/w:tblPr/w:tblStyle", "val", "Sombreadoclaro-nfasis1");
912 // check table style is not overwritten by other properties
913 assertXPath(pXmlDocument
, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[2]/w:tcPr/w:tcBorders/*", 0);
914 assertXPath(pXmlDocument
, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[3]/w:tcPr/w:tcBorders/*", 0);
915 // check that one cell attribute present in the original document has been preserved
916 assertXPath(pXmlDocument
, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:tcPr/w:tcBorders/*", 1);
918 // Check that w:cnfStyle row, cell and paragraph property is preserved.
919 assertXPath(pXmlDocument
, "//w:tbl/w:tr[1]/w:trPr/w:cnfStyle", "val", "100000000000");
920 assertXPath(pXmlDocument
, "//w:tbl/w:tr[1]/w:trPr/w:cnfStyle", "firstRow", "1");
921 assertXPath(pXmlDocument
, "//w:tbl/w:tr[1]/w:trPr/w:cnfStyle", "lastRow", "0");
922 assertXPath(pXmlDocument
, "//w:tbl/w:tr[1]/w:trPr/w:cnfStyle", "firstColumn", "0");
923 assertXPath(pXmlDocument
, "//w:tbl/w:tr[1]/w:trPr/w:cnfStyle", "lastColumn", "0");
925 assertXPath(pXmlDocument
, "//w:tbl/w:tr[1]/w:tc/w:tcPr/w:cnfStyle", "val", "001000000000");
926 assertXPath(pXmlDocument
, "//w:tbl/w:tr[1]/w:tc/w:tcPr/w:cnfStyle", "oddVBand", "0");
927 assertXPath(pXmlDocument
, "//w:tbl/w:tr[1]/w:tc/w:tcPr/w:cnfStyle", "evenVBand", "0");
928 assertXPath(pXmlDocument
, "//w:tbl/w:tr[1]/w:tc/w:tcPr/w:cnfStyle", "oddHBand", "0");
929 assertXPath(pXmlDocument
, "//w:tbl/w:tr[1]/w:tc/w:tcPr/w:cnfStyle", "evenHBand", "0");
931 assertXPath(pXmlDocument
, "//w:tbl/w:tr[1]/w:tc[2]/w:p/w:pPr/w:cnfStyle", "val", "100000000000");
932 assertXPath(pXmlDocument
, "//w:tbl/w:tr[1]/w:tc[2]/w:p/w:pPr/w:cnfStyle", "firstRowFirstColumn", "0");
933 assertXPath(pXmlDocument
, "//w:tbl/w:tr[1]/w:tc[2]/w:p/w:pPr/w:cnfStyle", "firstRowLastColumn", "0");
934 assertXPath(pXmlDocument
, "//w:tbl/w:tr[1]/w:tc[2]/w:p/w:pPr/w:cnfStyle", "lastRowFirstColumn", "0");
935 assertXPath(pXmlDocument
, "//w:tbl/w:tr[1]/w:tc[2]/w:p/w:pPr/w:cnfStyle", "lastRowLastColumn", "0");
939 CPPUNIT_TEST_FIXTURE(Test
, testcantSplit
)
941 loadAndSave("2_table_doc.docx");
942 // if Split table value is true for a table then during export do not write <w:cantSplit w:val="false"/>
943 // in table row property,As default row prop is allow row to break across page.
944 // writing <w:cantSplit w:val="false"/> during export was causing problem that all the cell data used to come on same page
945 xmlDocUniquePtr pXmlDoc
= parseExport("word/document.xml");
946 assertXPath(pXmlDoc
, "/w:document/w:body/w:tbl[1]/w:tr/w:trPr/w:cantSplit",0);
947 assertXPath(pXmlDoc
, "/w:document/w:body/w:tbl[2]/w:tr/w:trPr/w:cantSplit","val","true");
950 CPPUNIT_TEST_FIXTURE(Test
, testDontSplitTable
)
952 loadAndReload("tdf101589_dontSplitTable.odt");
953 CPPUNIT_ASSERT_EQUAL(2, getPages());
954 //single row tables need to prevent split by setting row to no split
955 CPPUNIT_ASSERT_EQUAL( OUString("Row 1"), parseDump("/root/page[2]/body/tab[1]/row[1]/cell[1]/txt[1]") );
957 uno::Reference
<text::XTextTablesSupplier
> xTablesSupplier(mxComponent
, uno::UNO_QUERY
);
958 uno::Reference
<container::XIndexAccess
> xTables(xTablesSupplier
->getTextTables(), uno::UNO_QUERY
);
959 uno::Reference
<text::XTextTable
> xTable (xTables
->getByIndex(0), uno::UNO_QUERY
);
960 CPPUNIT_ASSERT_EQUAL(false, getProperty
<bool>(xTable
, "Split"));
962 uno::Reference
<table::XTableRows
> xTableRows
= xTable
->getRows();
963 CPPUNIT_ASSERT_EQUAL(false, getProperty
<bool>(xTableRows
->getByIndex(0), "IsSplitAllowed"));
966 DECLARE_OOXMLEXPORT_TEST(testExtraSectionBreak
, "1_page.docx")
968 // There was a problem for some documents during export.Invalid sectPr getting added
969 // because of faulty calculation of PageDesc value
970 // This was the reason for increasing number of pages after RT
971 CPPUNIT_ASSERT_EQUAL(1, getPages());
973 // tdf126544 Styles were being added before their base/parent/inherited-from style existed, and so were using default settings.
974 uno::Reference
<container::XNameAccess
> xParaStyles(getStyles("ParagraphStyles"));
975 uno::Reference
<style::XStyle
> xStyle(xParaStyles
->getByName("Heading 1"), uno::UNO_QUERY
);
976 CPPUNIT_ASSERT_EQUAL( OUString("Heading Base"), xStyle
->getParentStyle() );
979 CPPUNIT_TEST_FIXTURE(Test
, testcolumnbreak
)
981 loadAndSave("columnbreak.docx");
982 CPPUNIT_ASSERT_EQUAL(style::BreakType_COLUMN_BEFORE
, getProperty
<style::BreakType
>(getParagraph(5, "This is first line after col brk."), "BreakType"));
983 xmlDocUniquePtr pXmlDoc
= parseExport("word/document.xml");
984 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[5]/w:r[1]/w:br", "type", "column");
987 CPPUNIT_TEST_FIXTURE(Test
, testGlossary
)
989 loadAndSave("testGlossary.docx");
990 xmlDocUniquePtr pXmlDoc
= parseExport("word/glossary/document.xml");
991 assertXPath(pXmlDoc
, "/w:glossaryDocument", "Ignorable", "w14 wp14");
994 CPPUNIT_TEST_FIXTURE(Test
, testGlossaryWithEmail
)
997 loadAndSave("glossaryWithEmail.docx");
998 xmlDocUniquePtr pXmlDoc
= parseExport("word/glossary/_rels/document.xml.rels");
999 assertXPath(pXmlDoc
, "/rels:Relationships/rels:Relationship[@Id='rId4' "
1000 "and @Type='http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink' "
1001 "and @Target='mailto:emailgoeshere@example.com' "
1002 "and @TargetMode='External']");
1004 // preserve the ShowingPlaceholder setting on both block SDTs.
1005 pXmlDoc
= parseExport("word/document.xml");
1006 assertXPath(pXmlDoc
,"/w:document/w:body/w:p/w:sdt/w:sdtPr/w:showingPlcHdr", 2);
1009 DECLARE_OOXMLEXPORT_TEST(testFdo71785
, "fdo71785.docx")
1014 CPPUNIT_TEST_FIXTURE(Test
, testCrashWhileSave
)
1016 loadAndSave("testCrashWhileSave.docx");
1017 xmlDocUniquePtr pXmlDoc
= parseExport("word/footer1.xml");
1018 CPPUNIT_ASSERT(getXPath(pXmlDoc
, "/w:ftr/w:tbl/w:tr/w:tc[1]/w:p[1]/w:pPr/w:pStyle", "val").match("Normal"));
1021 CPPUNIT_TEST_FIXTURE(Test
, testFileOpenInputOutputError
)
1023 loadAndReload("floatingtbl_with_formula.docx");
1024 // Docx containing Floating table with formula was giving "General input/output error" while opening in LibreOffice
1025 xmlDocUniquePtr pXmlDoc
= parseExport("word/document.xml");
1026 assertXPath(pXmlDoc
, "/w:document/w:body/w:p[1]/w:pPr/w:pStyle", "val", "Normal");
1028 // let's also assert that the formula was exported properly
1029 assertXPathContent(pXmlDoc
, "//w:tbl/w:tr/w:tc[2]/w:p/m:oMathPara/m:oMath/m:sSubSup/m:e/m:r/m:t", u
"\u03C3");
1032 CPPUNIT_TEST_FIXTURE(Test
, testSingleCellTableBorders
)
1034 loadAndSave("tdf124399_SingleCellTableBorders.docx");
1035 // tdf#124399: Extra borders on single cell tables fixed.
1037 xmlDocUniquePtr pXmlDocument
= parseExport("word/document.xml");
1038 assertXPath(pXmlDocument
, "/w:document/w:body/w:tbl/w:tr/w:tc/w:tcPr/w:tcBorders/w:top [@w:val = 'nil']", 1);
1039 assertXPath(pXmlDocument
, "/w:document/w:body/w:tbl/w:tr/w:tc/w:tcPr/w:tcBorders/w:bottom [@w:val = 'nil']", 1);
1042 CPPUNIT_TEST_FIXTURE(Test
, testInsideBorders
)
1044 loadAndSave("tdf129242_InsideBorders.docx");
1045 // tdf#129242: Don't remove inside borders if the table has more than one cells.
1047 xmlDocUniquePtr pXmlDocument
= parseExport("word/document.xml");
1049 // If this is not 0, then inside borders are removed.
1050 assertXPathChildren(pXmlDocument
, "/w:document/w:body/w:tbl/w:tr/w:tc[2]/w:tcPr/w:tcBorders", 0);
1053 CPPUNIT_TEST_FIXTURE(Test
, testRightBorder
)
1055 loadAndSave("tdf129442_RightBorder.docx");
1056 // tdf#129442: Right border of a one column table was missing.
1058 xmlDocUniquePtr pXmlDocument
= parseExport("word/document.xml");
1060 // If the right border is missing like in the bug, then there is a <w:right w:val="nil" /> tag in tcBorders.
1061 assertXPath(pXmlDocument
, "/w:document/w:body/w:tbl/w:tr[1]/w:tc/w:tcPr/w:tcBorders/w:end [@w:val = 'nil']", 0);
1064 CPPUNIT_TEST_FIXTURE(Test
, testBottomBorder
)
1066 loadAndSave("tdf129450_BottomBorder.docx");
1067 // tdf#129450: Missing bottom border in one row table.
1069 xmlDocUniquePtr pXmlDocument
= parseExport("word/document.xml");
1071 // If there is no bottom border, it is shown in tcBorders.
1072 assertXPath(pXmlDocument
, "/w:document/w:body/w:tbl/w:tr/w:tc[1]/w:tcPr/w:tcBorders/w:bottom [@w:val = 'nil']", 0);
1075 CPPUNIT_TEST_FIXTURE(Test
, testBottomBorders
)
1077 loadAndSave("tdf129452_BottomBorders.docx");
1078 // tdf#129452: Do not omit bottom borders when a column in a table is vertically merged and
1079 // the inside borders are turned off.
1081 xmlDocUniquePtr pXmlDocument
= parseExport("word/document.xml");
1083 assertXPath(pXmlDocument
, "/w:document/w:body/w:tbl/w:tr[4]/w:tc[1]/w:tcPr/w:tcBorders/w:bottom [@w:val = 'nil']", 0);
1084 assertXPath(pXmlDocument
, "/w:document/w:body/w:tbl/w:tr[4]/w:tc[2]/w:tcPr/w:tcBorders/w:bottom [@w:val = 'nil']", 0);
1086 // But also don't treat separately merged cells as one - the topmost merged cell shouldn't gain a border.
1087 assertXPath(pXmlDocument
, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[4]/w:tcPr/w:tcBorders/w:bottom", 0);
1090 CPPUNIT_TEST_FIXTURE(Test
, testFontTypes
)
1092 loadAndSave("tdf120344_FontTypes.docx");
1093 // tdf#120344: Font type of numbering symbols can be different than the font type of the text.
1095 // Check the font type of the text, should be Consolas.
1096 xmlDocUniquePtr pXmlDocument
= parseExport("word/document.xml");
1097 assertXPath(pXmlDocument
, "/w:document/w:body/w:p[1]/w:r/w:rPr/w:rFonts [@w:ascii='Consolas']", 1);
1099 // Now the font type of the numbering symbols, should be Arial Black.
1100 xmlDocUniquePtr qXmlDocument
= parseExport("word/numbering.xml");
1101 assertXPath(qXmlDocument
, "/w:numbering/w:abstractNum[1]/w:lvl[1]/w:rPr/w:rFonts [@w:ascii='Arial Black']", 1);
1104 CPPUNIT_TEST_FIXTURE(Test
, testNumberingLevels
)
1106 loadAndSave("tdf95495.docx");
1107 xmlDocUniquePtr pXmlDocument
= parseExport("word/document.xml");
1109 // tdf#95495: set list level of the custom style based on the setting of the parent style
1110 // [this assertXPath is not a very good test, since the numbering definition is not set on the paragraph itself,
1111 // but in a style. This just tests the current copy-to-paragraph implementation. But leaving it for now,
1112 // since this example is very much a corner case, so anyone trespassing here should double-check everything...]
1113 assertXPath(pXmlDocument
, "/w:document/w:body/w:p[2]/w:pPr/w:numPr/w:ilvl [@w:val = '1']", 1);
1115 xmlDocUniquePtr pXmlDoc
= parseLayoutDump();
1116 // Note: _Toc and _Ref hidden bookmarks are imported from OOXML as normal bookmarks.
1117 // Without hiding them from visible bookmarks (SwBookmarkPortion), this line would be
1118 // shown as "A.2.1 [[[[[.DESCRIPTION]]]] with XML layout dump "A.2.1 #_Ref... Bookmark Start..."
1119 assertXPath(pXmlDoc
, "//body/txt[5]/SwParaPortion/SwLineLayout/child::*[1]", "expand", "A.2.1 ");
1120 assertXPath(pXmlDoc
, "//body/txt[5]/SwParaPortion/SwLineLayout/child::*[2]", "portion", ".DESCRIPTION");
1123 CPPUNIT_TEST_FIXTURE(Test
, testVerticalBorders
)
1125 loadAndSave("calendar3.docx");
1126 // tdf#130799: Inside vertical borders of a table should not be missing.
1128 xmlDocUniquePtr pXmlDocument
= parseExport("word/document.xml");
1129 // Left and right borders.
1130 assertXPathChildren(pXmlDocument
, "/w:document/w:body/w:tbl/w:tr[3]/w:tc[3]/w:tcPr/w:tcBorders", 2);
1133 CPPUNIT_TEST_FIXTURE(Test
, testArrowFlipXY
)
1135 loadAndSave("tdf100751_arrowBothFlip.docx");
1136 // tdf#100751: Both x and y flip should happen.
1138 xmlDocUniquePtr pXmlDocument
= parseExport("word/document.xml");
1140 OUString arrowStyle
= getXPath(pXmlDocument
, "/w:document/w:body/w:p/w:r/mc:AlternateContent/mc:Fallback/w:pict/v:group/v:shape[2]", "style");
1141 CPPUNIT_ASSERT(arrowStyle
.indexOf(u
"flip:xy") != sal_Int32(-1));
1144 CPPUNIT_TEST_FIXTURE(Test
, testArrowPosition
)
1146 loadAndSave("tdf104565_ArrowPosition.docx");
1147 // tdf#104565: Test correct position.
1148 xmlDocUniquePtr pXmlDocument
= parseExport("word/document.xml");
1150 // This is the correct Y coordinate, the incorrect was 817880.
1151 assertXPathContent(pXmlDocument
, "/w:document/w:body/w:p/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor"
1152 "/wp:positionV/wp:posOffset", "516255");
1155 CPPUNIT_TEST_FIXTURE(Test
, testArrowMarker
)
1157 loadAndSave("tdf123346_ArrowMarker.docx");
1158 // tdf#123346: Check arrow marker.
1160 xmlDocUniquePtr pXmlDocument
= parseExport("word/document.xml");
1162 assertXPath(pXmlDocument
, "/w:document/w:body/w:p/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor"
1163 "/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:ln/a:tailEnd", "type", "arrow");
1166 CPPUNIT_TEST_FIXTURE(Test
, testShapeLineWidth
)
1168 loadAndSave("tdf92526_ShapeLineWidth.odt");
1169 CPPUNIT_ASSERT_EQUAL(1, getShapes());
1170 CPPUNIT_ASSERT_EQUAL(1, getPages());
1171 // tdf#92526: Make sure that line with stays 0.
1172 xmlDocUniquePtr pXml
= parseExport("word/document.xml");
1174 // "w" attribute was not exported.
1175 assertXPath(pXml
, "/w:document/w:body/w:p/w:r/mc:AlternateContent/mc:Choice/w:drawing"
1176 "/wp:anchor/a:graphic/a:graphicData/wps:wsp/wps:spPr/a:ln", "w", "0");
1179 CPPUNIT_TEST_FIXTURE(Test
, testRelativeAnchorWidthFromLeftMargin
)
1181 loadAndSave("tdf132976_testRelativeAnchorWidthFromLeftMargin.docx");
1182 // tdf#132976 The size of the width of this shape should come from the size of the left margin.
1183 // It was set to the size of the width of the entire page before.
1184 xmlDocUniquePtr pXmlDoc
= parseLayoutDump();
1185 assertXPath(pXmlDoc
, "//anchored/SwAnchoredDrawObject/bounds", "width", "1133");
1188 CPPUNIT_TEST_FIXTURE(Test
, testRelativeAnchorWidthFromInsideOutsideMargin
)
1190 loadAndSave("tdf133861_RelativeAnchorWidthFromInsideOutsideMargin.docx");
1191 // tdf#133863 tdf#133864 The sizes of the width of these shapes depend on the sizes of the inside and outside margins.
1192 // The open book: outside --text-- inside | inside --text-- outside
1193 xmlDocUniquePtr pXmlDoc
= parseLayoutDump();
1195 assertXPath(pXmlDoc
, "(//anchored/SwAnchoredDrawObject)[1]/bounds", "width", "1440");
1197 assertXPath(pXmlDoc
, "(//anchored/SwAnchoredDrawObject)[2]/bounds", "width", "2552");
1199 assertXPath(pXmlDoc
, "(//anchored/SwAnchoredDrawObject)[3]/bounds", "width", "2552");
1201 assertXPath(pXmlDoc
, "(//anchored/SwAnchoredDrawObject)[4]/bounds", "width", "1440");
1204 CPPUNIT_TEST_FIXTURE(Test
, testBodyPrUpright
)
1206 loadAndSave("tdf123610_handle_upright.docx");
1207 // tdf#123610: Check grab-bag attribute upright to keep text upright regardless of shape rotation.
1209 xmlDocUniquePtr pXmlDocument
= parseExport("word/document.xml");
1211 assertXPath(pXmlDocument
, "/w:document/w:body/w:p/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor"
1212 "/a:graphic/a:graphicData/wps:wsp/wps:bodyPr", "upright", "1");
1215 CPPUNIT_TEST_FIXTURE(Test
, testLostArrow
)
1217 loadAndReload("tdf99810-lost-arrow.odt");
1218 CPPUNIT_ASSERT_EQUAL(1, getShapes());
1219 CPPUNIT_ASSERT_EQUAL(1, getPages());
1220 // tdf#99810: check whether we use normal shape instead of connector shape if the XML namespace
1221 // is wps, because wps:
1222 xmlDocUniquePtr pDoc
= parseExport("word/document.xml");
1224 assertXPath(pDoc
, "/w:document/w:body/w:p/w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor"
1225 "/a:graphic/a:graphicData/wps:wsp");
1228 CPPUNIT_PLUGIN_IMPLEMENT();
1230 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */