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/graphic/XGraphic.hpp>
14 : #include <com/sun/star/frame/XStorable.hpp>
15 : #include <com/sun/star/drawing/FillStyle.hpp>
16 : #include <com/sun/star/drawing/LineJoint.hpp>
17 : #include <com/sun/star/drawing/LineStyle.hpp>
18 : #include <com/sun/star/drawing/XControlShape.hpp>
19 : #include <com/sun/star/awt/Gradient.hpp>
20 : #include <com/sun/star/style/TabStop.hpp>
21 : #include <com/sun/star/view/XViewSettingsSupplier.hpp>
22 : #include <com/sun/star/text/RelOrientation.hpp>
23 : #include <com/sun/star/text/XTextFrame.hpp>
24 : #include <com/sun/star/text/XTextTable.hpp>
25 : #include <com/sun/star/text/XTextFramesSupplier.hpp>
26 : #include <com/sun/star/text/XTextViewCursorSupplier.hpp>
27 : #include <com/sun/star/text/XTextSection.hpp>
28 : #include <com/sun/star/style/CaseMap.hpp>
29 : #include <com/sun/star/style/ParagraphAdjust.hpp>
30 : #include <com/sun/star/style/LineSpacing.hpp>
31 : #include <com/sun/star/style/LineSpacingMode.hpp>
32 : #include <com/sun/star/view/XSelectionSupplier.hpp>
33 : #include <com/sun/star/table/BorderLine2.hpp>
34 : #include <com/sun/star/table/ShadowFormat.hpp>
35 : #include <com/sun/star/text/GraphicCrop.hpp>
36 : #include <com/sun/star/text/XPageCursor.hpp>
37 : #include <com/sun/star/awt/FontWeight.hpp>
38 : #include <com/sun/star/awt/FontUnderline.hpp>
39 : #include <com/sun/star/awt/FontSlant.hpp>
40 : #include <com/sun/star/text/WritingMode2.hpp>
41 : #include <com/sun/star/text/WrapTextMode.hpp>
42 : #include <com/sun/star/xml/dom/XDocument.hpp>
43 : #include <com/sun/star/style/BreakType.hpp>
44 : #include <unotools/tempfile.hxx>
45 : #include <comphelper/sequenceashashmap.hxx>
46 : #include <com/sun/star/text/XDocumentIndex.hpp>
47 : #include <com/sun/star/drawing/EnhancedCustomShapeSegment.hpp>
48 : #include <com/sun/star/drawing/EnhancedCustomShapeSegmentCommand.hpp>
49 : #include <com/sun/star/drawing/EnhancedCustomShapeParameterPair.hpp>
50 : #include <com/sun/star/drawing/TextVerticalAdjust.hpp>
51 : #include <com/sun/star/drawing/Hatch.hpp>
52 :
53 : #include <string>
54 :
55 264 : class Test : public SwModelTestBase
56 : {
57 : public:
58 264 : Test() : SwModelTestBase("/sw/qa/extras/ooxmlexport/data/", "Office Open XML Text") {}
59 :
60 : protected:
61 : /**
62 : * Blacklist handling
63 : */
64 132 : bool mustTestImportOf(const char* filename) const SAL_OVERRIDE {
65 : const char* aBlacklist[] = {
66 : "math-escape.docx",
67 : "math-mso2k7.docx",
68 : "ImageCrop.docx",
69 : "test_GIF_ImageCrop.docx",
70 : "test_PNG_ImageCrop.docx"
71 132 : };
72 132 : std::vector<const char*> vBlacklist(aBlacklist, aBlacklist + SAL_N_ELEMENTS(aBlacklist));
73 :
74 : // If the testcase is stored in some other format, it's pointless to test.
75 132 : return (OString(filename).endsWith(".docx") && std::find(vBlacklist.begin(), vBlacklist.end(), filename) == vBlacklist.end());
76 : }
77 :
78 : /**
79 : * Validation handling
80 : */
81 132 : bool mustValidate(const char* filename) const SAL_OVERRIDE
82 : {
83 : const char* aWhitelist[] = {
84 : "page-graphic-background.odt",
85 : "zoom.docx",
86 : "empty.odt",
87 : "fdo38244.docx",
88 : "comments-nested.odt"
89 132 : };
90 132 : std::vector<const char*> vWhitelist(aWhitelist, aWhitelist + SAL_N_ELEMENTS(aWhitelist));
91 :
92 132 : return std::find(vWhitelist.begin(), vWhitelist.end(), filename) != vWhitelist.end();
93 : }
94 : };
95 :
96 : #if !defined(WNT)
97 :
98 26 : DECLARE_OOXMLEXPORT_TEST(testPageGraphicBackground, "page-graphic-background.odt")
99 : {
100 : // No idea how the graphic background should be exported (seems there is no
101 : // way to do a non-tiling export to OOXML), but at least the background
102 : // color shouldn't be black.
103 2 : uno::Reference<beans::XPropertySet> xPageStyle(getStyles("PageStyles")->getByName(DEFAULT_STYLE), uno::UNO_QUERY);
104 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(-1), getProperty<sal_Int32>(xPageStyle, "BackColor"));
105 2 : }
106 :
107 28 : DECLARE_OOXMLEXPORT_TEST(testZoom, "zoom.docx")
108 : {
109 4 : uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
110 6 : uno::Reference<view::XViewSettingsSupplier> xViewSettingsSupplier(xModel->getCurrentController(), uno::UNO_QUERY);
111 6 : uno::Reference<beans::XPropertySet> xPropertySet(xViewSettingsSupplier->getViewSettings());
112 4 : sal_Int16 nValue = 0;
113 4 : xPropertySet->getPropertyValue("ZoomValue") >>= nValue;
114 4 : CPPUNIT_ASSERT_EQUAL(sal_Int16(42), nValue);
115 :
116 : // Validation test: order of elements were wrong.
117 4 : xmlDocPtr pXmlDoc = parseExport("word/styles.xml");
118 4 : if (!pXmlDoc)
119 6 : return;
120 : // Order was: rsid, next.
121 2 : int nNext = getXPathPosition(pXmlDoc, "/w:styles/w:style[3]", "next");
122 2 : int nRsid = getXPathPosition(pXmlDoc, "/w:styles/w:style[3]", "rsid");
123 2 : CPPUNIT_ASSERT(nNext < nRsid);
124 :
125 2 : pXmlDoc = parseExport("docProps/app.xml");
126 : // One paragraph in the document.
127 2 : assertXPathContent(pXmlDoc, "/extended-properties:Properties/extended-properties:Paragraphs", "1");
128 4 : assertXPathContent(pXmlDoc, "/extended-properties:Properties/extended-properties:Company", "Example Ltd");
129 : }
130 :
131 26 : DECLARE_OOXMLEXPORT_TEST(defaultTabStopNotInStyles, "empty.odt")
132 : {
133 : // The default tab stop was mistakenly exported to a style.
134 : // xray ThisComponent.StyleFamilies(1)(0).ParaTabStop
135 2 : uno::Reference< container::XNameAccess > paragraphStyles = getStyles( "ParagraphStyles" );
136 4 : uno::Reference< beans::XPropertySet > properties( paragraphStyles->getByName( "Standard" ), uno::UNO_QUERY );
137 : uno::Sequence< style::TabStop > stops = getProperty< uno::Sequence< style::TabStop > >(
138 4 : paragraphStyles->getByName( "Standard" ), "ParaTabStops" );
139 : // There actually be be one tab stop, but it will be the default.
140 2 : CPPUNIT_ASSERT_EQUAL( static_cast<sal_Int32>(1), stops.getLength());
141 4 : CPPUNIT_ASSERT_EQUAL( style::TabAlign_DEFAULT, stops[ 0 ].Alignment );
142 2 : }
143 :
144 28 : DECLARE_OOXMLEXPORT_TEST(testFdo38244, "fdo38244.docx")
145 : {
146 : /*
147 : * Comments attached to a range was imported without the range, check for the annotation mark start/end positions.
148 : *
149 : * oParas = ThisComponent.Text.createEnumeration
150 : * oPara = oParas.nextElement
151 : * oRuns = oPara.createEnumeration
152 : * oRun = oRuns.nextElement
153 : * oRun = oRuns.nextElement 'Annotation
154 : * oRun = oRuns.nextElement
155 : * oRun = oRuns.nextElement 'AnnotationEnd
156 : * xray oRun.TextPortionType
157 : */
158 4 : uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
159 8 : uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextDocument->getText(), uno::UNO_QUERY);
160 8 : uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
161 8 : uno::Reference<container::XEnumerationAccess> xRunEnumAccess(xParaEnum->nextElement(), uno::UNO_QUERY);
162 8 : uno::Reference<container::XEnumeration> xRunEnum = xRunEnumAccess->createEnumeration();
163 4 : xRunEnum->nextElement();
164 8 : uno::Reference<beans::XPropertySet> xPropertySet(xRunEnum->nextElement(), uno::UNO_QUERY);
165 4 : CPPUNIT_ASSERT_EQUAL(OUString("Annotation"), getProperty<OUString>(xPropertySet, "TextPortionType"));
166 4 : xRunEnum->nextElement();
167 4 : xPropertySet.set(xRunEnum->nextElement(), uno::UNO_QUERY);
168 4 : CPPUNIT_ASSERT_EQUAL(OUString("AnnotationEnd"), getProperty<OUString>(xPropertySet, "TextPortionType"));
169 :
170 : /*
171 : * Initials were not imported.
172 : *
173 : * oFields = ThisComponent.TextFields.createEnumeration
174 : * oField = oFields.nextElement
175 : * xray oField.Initials
176 : */
177 8 : uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
178 8 : uno::Reference<container::XEnumerationAccess> xFieldsAccess(xTextFieldsSupplier->getTextFields());
179 8 : uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration());
180 4 : xPropertySet.set(xFields->nextElement(), uno::UNO_QUERY);
181 4 : CPPUNIT_ASSERT_EQUAL(OUString("M"), getProperty<OUString>(xPropertySet, "Initials"));
182 :
183 : /*
184 : * There was a fake empty paragraph at the end of the comment text.
185 : *
186 : * oFields = ThisComponent.TextFields.createEnumeration
187 : * oField = oFields.nextElement
188 : * oParas = oField.TextRange.createEnumeration
189 : * oPara = oParas.nextElement
190 : * oPara = oParas.nextElement
191 : */
192 :
193 4 : xParaEnumAccess.set(getProperty< uno::Reference<container::XEnumerationAccess> >(xPropertySet, "TextRange"), uno::UNO_QUERY);
194 4 : xParaEnum = xParaEnumAccess->createEnumeration();
195 4 : xParaEnum->nextElement();
196 4 : bool bCaught = false;
197 : try
198 : {
199 4 : xParaEnum->nextElement();
200 : }
201 8 : catch (container::NoSuchElementException&)
202 : {
203 4 : bCaught = true;
204 : }
205 8 : CPPUNIT_ASSERT_EQUAL(true, bCaught);
206 4 : }
207 :
208 26 : DECLARE_OOXMLEXPORT_TEST(testCommentsNested, "comments-nested.odt")
209 : {
210 2 : uno::Reference<beans::XPropertySet> xOuter(getProperty< uno::Reference<beans::XPropertySet> >(getRun(getParagraph(1), 2), "TextField"), uno::UNO_QUERY);
211 2 : CPPUNIT_ASSERT_EQUAL(OUString("Outer"), getProperty<OUString>(xOuter, "Content"));
212 :
213 4 : uno::Reference<beans::XPropertySet> xInner(getProperty< uno::Reference<beans::XPropertySet> >(getRun(getParagraph(1), 4), "TextField"), uno::UNO_QUERY);
214 4 : CPPUNIT_ASSERT_EQUAL(OUString("Inner"), getProperty<OUString>(xInner, "Content"));
215 2 : }
216 :
217 26 : DECLARE_OOXMLEXPORT_TEST(testMathEscape, "math-escape.docx")
218 : {
219 2 : CPPUNIT_ASSERT_EQUAL(OUString("\\{ left [ right ] left ( right ) \\}"), getFormula(getRun(getParagraph(1), 1)));
220 2 : }
221 :
222 26 : DECLARE_OOXMLEXPORT_TEST(testFdo51034, "fdo51034.odt")
223 : {
224 : // The problem was that the 'l' param of the HYPERLINK field was parsed with = "#", not += "#".
225 2 : CPPUNIT_ASSERT_EQUAL(OUString("http://Www.google.com/#a"), getProperty<OUString>(getRun(getParagraph(1), 1), "HyperLinkURL"));
226 2 : }
227 :
228 : // Construct the expected formula from UTF8, as there may be such characters.
229 : // Remove all spaces, as LO export/import may change that.
230 : // Replace symbol - (i.e. U+2212) with ASCII - , LO does this change and it shouldn't matter.
231 : #define CHECK_FORMULA( expected, actual ) \
232 : CPPUNIT_ASSERT_EQUAL( \
233 : OUString( expected, strlen( expected ), RTL_TEXTENCODING_UTF8 ) \
234 : .replaceAll( " ", "" ).replaceAll( OUString( "\xe2\x88\x92", strlen( "\xe2\x88\x92" ), RTL_TEXTENCODING_UTF8 ), "-" ), \
235 : OUString( actual ).replaceAll( " ", "" ).replaceAll( OUString( "\xe2\x88\x92", strlen( "\xe2\x88\x92" ), RTL_TEXTENCODING_UTF8 ), "-" ))
236 :
237 28 : DECLARE_OOXMLEXPORT_TEST(testMathAccents, "math-accents.docx")
238 : {
239 8 : CHECK_FORMULA(
240 : "acute {a} grave {a} check {a} breve {a} circle {a} widevec {a} widetilde {a}"
241 : " widehat {a} dot {a} widevec {a} widevec {a} widetilde {a} underline {a}",
242 4 : getFormula( getRun( getParagraph( 1 ), 1 )));
243 4 : }
244 :
245 28 : DECLARE_OOXMLEXPORT_TEST(testMathD, "math-d.docx")
246 : {
247 4 : CHECK_FORMULA( "left (x mline y mline z right )", getFormula( getRun( getParagraph( 1 ), 1 )));
248 4 : CHECK_FORMULA( "left (1 right )", getFormula( getRun( getParagraph( 1 ), 2 )));
249 4 : CHECK_FORMULA( "left [2 right ]", getFormula( getRun( getParagraph( 1 ), 3 )));
250 4 : CHECK_FORMULA( "left ldbracket 3 right rdbracket", getFormula( getRun( getParagraph( 1 ), 4 )));
251 4 : CHECK_FORMULA( "left lline 4 right rline", getFormula( getRun( getParagraph( 1 ), 5 )));
252 4 : CHECK_FORMULA( "left ldline 5 right rdline", getFormula( getRun( getParagraph( 1 ), 6 )));
253 4 : CHECK_FORMULA( "left langle 6 right rangle", getFormula( getRun( getParagraph( 1 ), 7 )));
254 4 : CHECK_FORMULA( "left langle a mline b right rangle", getFormula( getRun( getParagraph( 1 ), 8 )));
255 4 : CHECK_FORMULA( "left ({x} over {y} right )", getFormula( getRun( getParagraph( 1 ), 9 )));
256 4 : }
257 :
258 28 : DECLARE_OOXMLEXPORT_TEST(testMathEscaping, "math-escaping.docx")
259 : {
260 4 : CHECK_FORMULA( "\xe2\x88\x92 \xe2\x88\x9e < x < \xe2\x88\x9e", getFormula( getRun( getParagraph( 1 ), 1 )));
261 4 : }
262 :
263 28 : DECLARE_OOXMLEXPORT_TEST(testMathLim, "math-lim.docx")
264 : {
265 4 : CHECK_FORMULA( "lim from {x \xe2\x86\x92 1} {x}", getFormula( getRun( getParagraph( 1 ), 1 )));
266 4 : }
267 :
268 28 : DECLARE_OOXMLEXPORT_TEST(testMathMalformedXml, "math-malformed_xml.docx")
269 : {
270 4 : CPPUNIT_ASSERT_EQUAL( 0, getLength());
271 4 : }
272 :
273 28 : DECLARE_OOXMLEXPORT_TEST(testMathMatrix, "math-matrix.docx")
274 : {
275 4 : CHECK_FORMULA( "left [matrix {1 # 2 ## 3 # 4} right ]", getFormula( getRun( getParagraph( 1 ), 1 )));
276 4 : }
277 :
278 26 : DECLARE_OOXMLEXPORT_TEST(testMathMso2k7, "math-mso2k7.docx")
279 : {
280 2 : CHECK_FORMULA( "A = \xcf\x80 {r} ^ {2}", getFormula( getRun( getParagraph( 1 ), 1 )));
281 : // TODO check the stack/binom difference
282 : // CHECK_FORMULA( "{left (x+a right )} ^ {n} = sum from {k=0} to {n} {left (binom {n} {k} right ) {x} ^ {k} {a} ^ {n-k}}",
283 4 : CHECK_FORMULA( "{left (x+a right )} ^ {n} = sum from {k=0} to {n} {left (stack {n # k} right ) {x} ^ {k} {a} ^ {n-k}}",
284 2 : getFormula( getRun( getParagraph( 2 ), 1 )));
285 4 : CHECK_FORMULA( "{left (1+x right )} ^ {n} =1+ {nx} over {1!} + {n left (n-1 right ) {x} ^ {2}} over {2!} +\xe2\x80\xa6",
286 2 : getFormula( getRun( getParagraph( 3 ), 1 )));
287 : // TODO check (cos/sin miss {})
288 : // CHECK_FORMULA( "f left (x right ) = {a} rsub {0} + sum from {n=1} to {\xe2\x88\x9e} {left ({a} rsub {n} cos {{n\xcf\x80x} over {L}} + {b} rsub {n} sin {{n\xcf\x80x} over {L}} right )}",
289 4 : CHECK_FORMULA( "f left (x right ) = {a} rsub {0} + sum from {n=1} to {\xe2\x88\x9e} {left ({a} rsub {n} cos {n\xcf\x80x} over {L} + {b} rsub {n} sin {n\xcf\x80x} over {L} right )}",
290 2 : getFormula( getRun( getParagraph( 4 ), 1 )));
291 2 : CHECK_FORMULA( "{a} ^ {2} + {b} ^ {2} = {c} ^ {2}", getFormula( getRun( getParagraph( 5 ), 1 )));
292 4 : CHECK_FORMULA( "x = {- b \xc2\xb1 sqrt {{b} ^ {2} -4 ac}} over {2 a}",
293 2 : getFormula( getRun( getParagraph( 6 ), 1 )));
294 4 : CHECK_FORMULA(
295 : "{e} ^ {x} =1+ {x} over {1!} + {{x} ^ {2}} over {2!} + {{x} ^ {3}} over {3!} +\xe2\x80\xa6, -\xe2\x88\x9e<x<\xe2\x88\x9e",
296 2 : getFormula( getRun( getParagraph( 7 ), 1 )));
297 4 : CHECK_FORMULA(
298 : // "sin {\xce\xb1} \xc2\xb1 sin {\xce\xb2} =2 sin {{1} over {2} left (\xce\xb1\xc2\xb1\xce\xb2 right )} cos {{1} over {2} left (\xce\xb1\xe2\x88\x93\xce\xb2 right )}",
299 : // TODO check (cos/in miss {})
300 : "sin \xce\xb1 \xc2\xb1 sin \xce\xb2 =2 sin {1} over {2} left (\xce\xb1\xc2\xb1\xce\xb2 right ) cos {1} over {2} left (\xce\xb1\xe2\x88\x93\xce\xb2 right )",
301 2 : getFormula( getRun( getParagraph( 8 ), 1 )));
302 4 : CHECK_FORMULA(
303 : // "cos {\xce\xb1} + cos {\xce\xb2} =2 cos {{1} over {2} left (\xce\xb1+\xce\xb2 right )} cos {{1} over {2} left (\xce\xb1-\xce\xb2 right )}",
304 : // TODO check (cos/sin miss {})
305 : "cos \xce\xb1 + cos \xce\xb2 =2 cos {1} over {2} left (\xce\xb1+\xce\xb2 right ) cos {1} over {2} left (\xce\xb1-\xce\xb2 right )",
306 2 : getFormula( getRun( getParagraph( 9 ), 1 )));
307 2 : }
308 :
309 28 : DECLARE_OOXMLEXPORT_TEST(testMathNary, "math-nary.docx")
310 : {
311 4 : CHECK_FORMULA( "lllint from {1} to {2} {x + 1}", getFormula( getRun( getParagraph( 1 ), 1 )));
312 4 : CHECK_FORMULA( "prod from {a} {b}", getFormula( getRun( getParagraph( 1 ), 2 )));
313 4 : CHECK_FORMULA( "sum to {2} {x}", getFormula( getRun( getParagraph( 1 ), 3 )));
314 4 : }
315 :
316 28 : DECLARE_OOXMLEXPORT_TEST(testMathOverbraceUnderbrace, "math-overbrace_underbrace.docx")
317 : {
318 4 : CHECK_FORMULA( "{abcd} overbrace {4}", getFormula( getRun( getParagraph( 1 ), 1 )));
319 4 : CHECK_FORMULA( "{xyz} underbrace {3}", getFormula( getRun( getParagraph( 2 ), 1 )));
320 4 : }
321 :
322 28 : DECLARE_OOXMLEXPORT_TEST(testMathOverstrike, "math-overstrike.docx")
323 : {
324 4 : CHECK_FORMULA( "overstrike {abc}", getFormula( getRun( getParagraph( 1 ), 1 )));
325 4 : }
326 :
327 28 : DECLARE_OOXMLEXPORT_TEST(testMathPlaceholders, "math-placeholders.docx")
328 : {
329 4 : CHECK_FORMULA( "sum from <?> to <?> <?>", getFormula( getRun( getParagraph( 1 ), 1 )));
330 4 : }
331 :
332 28 : DECLARE_OOXMLEXPORT_TEST(testMathRad, "math-rad.docx")
333 : {
334 4 : CHECK_FORMULA( "sqrt {4}", getFormula( getRun( getParagraph( 1 ), 1 )));
335 4 : CHECK_FORMULA( "nroot {3} {x + 1}", getFormula( getRun( getParagraph( 1 ), 2 )));
336 4 : }
337 :
338 28 : DECLARE_OOXMLEXPORT_TEST(testMathSubscripts, "math-subscripts.docx")
339 : {
340 4 : CHECK_FORMULA( "{x} ^ {y} + {e} ^ {x}", getFormula( getRun( getParagraph( 1 ), 1 )));
341 4 : CHECK_FORMULA( "{x} ^ {b}", getFormula( getRun( getParagraph( 1 ), 2 )));
342 4 : CHECK_FORMULA( "{x} rsub {b}", getFormula( getRun( getParagraph( 1 ), 3 )));
343 4 : CHECK_FORMULA( "{a} rsub {c} rsup {b}", getFormula( getRun( getParagraph( 1 ), 4 )));
344 4 : CHECK_FORMULA( "{x} lsub {2} lsup {1}", getFormula( getRun( getParagraph( 1 ), 5 )));
345 8 : CHECK_FORMULA( "{{x csup {6} csub {3}} lsub {4} lsup {5}} rsub {2} rsup {1}",
346 4 : getFormula( getRun( getParagraph( 1 ), 6 )));
347 4 : }
348 :
349 28 : DECLARE_OOXMLEXPORT_TEST(testMathVerticalStacks, "math-vertical_stacks.docx")
350 : {
351 4 : CHECK_FORMULA( "{a} over {b}", getFormula( getRun( getParagraph( 1 ), 1 )));
352 4 : CHECK_FORMULA( "{a} / {b}", getFormula( getRun( getParagraph( 2 ), 1 )));
353 : // TODO check these
354 : // CHECK_FORMULA( "binom {a} {b}", getFormula( getRun( getParagraph( 3 ), 1 )));
355 : // CHECK_FORMULA( "binom {a} {binom {b} {c}}", getFormula( getRun( getParagraph( 4 ), 1 )));
356 4 : }
357 :
358 26 : DECLARE_OOXMLEXPORT_TEST(testTable, "table.odt")
359 : {
360 : // Validation test: order of elements were wrong.
361 2 : xmlDocPtr pXmlDoc = parseExport("word/document.xml");
362 2 : if (!pXmlDoc)
363 2 : return;
364 : // Order was: insideH, end, insideV.
365 2 : int nEnd = getXPathPosition(pXmlDoc, "/w:document/w:body/w:tbl/w:tblPr/w:tblBorders", "end");
366 2 : int nInsideH = getXPathPosition(pXmlDoc, "/w:document/w:body/w:tbl/w:tblPr/w:tblBorders", "insideH");
367 2 : int nInsideV = getXPathPosition(pXmlDoc, "/w:document/w:body/w:tbl/w:tblPr/w:tblBorders", "insideV");
368 2 : CPPUNIT_ASSERT(nEnd < nInsideH);
369 2 : CPPUNIT_ASSERT(nInsideH < nInsideV);
370 :
371 : // Make sure we write qFormat for well-known style names.
372 2 : assertXPath(parseExport("word/styles.xml"), "//w:style[@w:styleId='Normal']/w:qFormat", 1);
373 : }
374 :
375 28 : DECLARE_OOXMLEXPORT_TEST(testTablePosition, "table-position.docx")
376 : {
377 4 : sal_Int32 xCoordsFromOffice[] = { 2500, -1000, 0, 0 };
378 4 : sal_Int32 cellLeftMarginFromOffice[] = { 250, 100, 0, 0 };
379 :
380 4 : uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
381 8 : uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
382 8 : uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables( ), uno::UNO_QUERY);
383 :
384 20 : for (int i=0; i<4; i++) {
385 16 : uno::Reference<text::XTextTable> xTable1 (xTables->getByIndex(i), uno::UNO_QUERY);
386 : // Verify X coord
387 32 : uno::Reference<view::XSelectionSupplier> xCtrl(xModel->getCurrentController(), uno::UNO_QUERY);
388 16 : xCtrl->select(uno::makeAny(xTable1));
389 32 : uno::Reference<text::XTextViewCursorSupplier> xTextViewCursorSupplier(xCtrl, uno::UNO_QUERY);
390 32 : uno::Reference<text::XTextViewCursor> xCursor(xTextViewCursorSupplier->getViewCursor(), uno::UNO_QUERY);
391 16 : awt::Point pos = xCursor->getPosition();
392 32 : CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Incorrect X coord computed from docx",
393 16 : xCoordsFromOffice[i], pos.X, 1);
394 :
395 : // Verify left margin of 1st cell :
396 : // * Office left margins are measured relative to the right of the border
397 : // * LO left spacing is measured from the center of the border
398 32 : uno::Reference<table::XCell> xCell = xTable1->getCellByName("A1");
399 32 : uno::Reference< beans::XPropertySet > xPropSet(xCell, uno::UNO_QUERY_THROW);
400 16 : sal_Int32 aLeftMargin = -1;
401 16 : xPropSet->getPropertyValue("LeftBorderDistance") >>= aLeftMargin;
402 32 : uno::Any aLeftBorder = xPropSet->getPropertyValue("LeftBorder");
403 16 : table::BorderLine2 aLeftBorderLine;
404 16 : aLeftBorder >>= aLeftBorderLine;
405 32 : CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Incorrect left spacing computed from docx cell margin",
406 16 : cellLeftMarginFromOffice[i], aLeftMargin - 0.5 * aLeftBorderLine.LineWidth, 1);
407 20 : }
408 4 : }
409 :
410 : struct SingleLineBorders {
411 : sal_Int16 top, bottom, left, right;
412 96 : SingleLineBorders(int t=0, int b=0, int l=0, int r=0)
413 96 : : top(t), bottom(b), left(l), right(r) {}
414 192 : sal_Int16 getBorder(int i) const
415 : {
416 192 : switch (i) {
417 48 : case 0: return top;
418 48 : case 1: return bottom;
419 48 : case 2: return left;
420 48 : case 3: return right;
421 0 : default: assert(false); return 0;
422 : }
423 : }
424 : };
425 :
426 28 : DECLARE_OOXMLEXPORT_TEST(testTableBorders, "table-borders.docx")
427 : {
428 4 : uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
429 8 : uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
430 8 : uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables( ), uno::UNO_QUERY);
431 4 : CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount());
432 8 : uno::Reference<text::XTextTable> xTextTable (xTables->getByIndex(0), uno::UNO_QUERY);
433 :
434 8 : std::map<OUString, SingleLineBorders> cellBorders;
435 4 : cellBorders[OUString("A1")] = SingleLineBorders(106, 106, 106, 106);
436 4 : cellBorders[OUString("B1")] = SingleLineBorders(106, 0, 106, 35);
437 4 : cellBorders[OUString("C1")] = SingleLineBorders(106, 106, 35, 106);
438 4 : cellBorders[OUString("A2")] = SingleLineBorders(106, 35, 106, 0);
439 4 : cellBorders[OUString("B2")] = SingleLineBorders(0, 0, 0, 0);
440 4 : cellBorders[OUString("C2")] = SingleLineBorders(106, 106, 0, 106);
441 4 : cellBorders[OUString("A3")] = SingleLineBorders(35, 35, 106, 106);
442 4 : cellBorders[OUString("B3")] = SingleLineBorders(0, 106, 106, 106);
443 4 : cellBorders[OUString("C3")] = SingleLineBorders(106, 106, 106, 106);
444 4 : cellBorders[OUString("A4")] = SingleLineBorders(35, 106, 106, 35);
445 4 : cellBorders[OUString("B4")] = SingleLineBorders(106, 106, 35, 106);
446 4 : cellBorders[OUString("C4")] = SingleLineBorders(106, 106, 106, 106);
447 :
448 : const OUString borderNames[] = {
449 : OUString("TopBorder"),
450 : OUString("BottomBorder"),
451 : OUString("LeftBorder"),
452 : OUString("RightBorder"),
453 8 : };
454 :
455 8 : uno::Sequence<OUString> const cells = xTextTable->getCellNames();
456 4 : sal_Int32 nLength = cells.getLength();
457 4 : CPPUNIT_ASSERT_EQUAL((sal_Int32)cellBorders.size(), nLength);
458 :
459 52 : for (sal_Int32 i = 0; i < nLength; ++i)
460 : {
461 48 : uno::Reference<table::XCell> xCell = xTextTable->getCellByName(cells[i]);
462 96 : uno::Reference< beans::XPropertySet > xPropSet(xCell, uno::UNO_QUERY_THROW);
463 48 : const SingleLineBorders& borders = cellBorders[cells[i]];
464 :
465 240 : for (sal_Int32 j = 0; j < 4; ++j)
466 : {
467 192 : uno::Any aBorder = xPropSet->getPropertyValue(borderNames[j]);
468 192 : table::BorderLine aBorderLine;
469 192 : if (aBorder >>= aBorderLine)
470 : {
471 192 : std::stringstream message;
472 192 : message << cells[i] << "'s " << borderNames[j] << " is incorrect";
473 384 : CPPUNIT_ASSERT_EQUAL_MESSAGE(message.str(),
474 384 : borders.getBorder(j), aBorderLine.OuterLineWidth);
475 : }
476 192 : }
477 52 : }
478 4 : }
479 :
480 26 : DECLARE_OOXMLEXPORT_TEST(testFdo51550, "fdo51550.odt")
481 : {
482 : // The problem was that we lacked the fallback to export the replacement graphic for OLE objects.
483 2 : uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY);
484 4 : uno::Reference<container::XIndexAccess> xDraws(xDrawPageSupplier->getDrawPage(), uno::UNO_QUERY);
485 4 : CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xDraws->getCount());
486 2 : }
487 :
488 : /*
489 : * doesn't work on openSUSE12.2 at least
490 : DECLARE_OOXMLEXPORT_TEST(test1Table1Page, "1-table-1-page.docx")
491 : {
492 : // 2 problem for this document after export:
493 : // - invalid sectPr inserted at the beginning of the page
494 : // - font of empty cell is not preserved, leading to change in rows height
495 : uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
496 : uno::Reference<text::XTextViewCursorSupplier> xTextViewCursorSupplier(xModel->getCurrentController(), uno::UNO_QUERY);
497 : uno::Reference<text::XPageCursor> xCursor(xTextViewCursorSupplier->getViewCursor(), uno::UNO_QUERY);
498 : xCursor->jumpToLastPage();
499 : CPPUNIT_ASSERT_EQUAL(sal_Int16(1), xCursor->getPage());
500 : }
501 : */
502 :
503 26 : DECLARE_OOXMLEXPORT_TEST(testTextFrames, "textframes.odt")
504 : {
505 : // The frames were simply missing, so let's check if all 3 frames were imported back.
506 2 : uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY);
507 4 : uno::Reference<container::XIndexAccess> xIndexAccess(xDrawPageSupplier->getDrawPage(), uno::UNO_QUERY);
508 4 : CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xIndexAccess->getCount());
509 2 : }
510 :
511 28 : DECLARE_OOXMLEXPORT_TEST(testTextFrameBorders, "textframe-borders.docx")
512 : {
513 4 : uno::Reference<text::XTextFramesSupplier> xTextFramesSupplier(mxComponent, uno::UNO_QUERY);
514 8 : uno::Reference<container::XIndexAccess> xIndexAccess(xTextFramesSupplier->getTextFrames(), uno::UNO_QUERY);
515 4 : if (xIndexAccess->getCount())
516 : {
517 : // After import, a TextFrame is created by the VML import.
518 2 : uno::Reference<beans::XPropertySet> xFrame(xIndexAccess->getByIndex(0), uno::UNO_QUERY);
519 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(0xD99594), getProperty<sal_Int32>(xFrame, "BackColor"));
520 :
521 2 : table::BorderLine2 aBorder = getProperty<table::BorderLine2>(xFrame, "TopBorder");
522 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(0xC0504D), aBorder.Color);
523 2 : CPPUNIT_ASSERT_EQUAL(sal_uInt32(35), aBorder.LineWidth);
524 :
525 2 : table::ShadowFormat aShadowFormat = getProperty<table::ShadowFormat>(xFrame, "ShadowFormat");
526 2 : CPPUNIT_ASSERT_EQUAL(table::ShadowLocation_BOTTOM_RIGHT, aShadowFormat.Location);
527 2 : CPPUNIT_ASSERT_EQUAL(sal_Int16(48), aShadowFormat.ShadowWidth);
528 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(0x622423), aShadowFormat.Color);
529 : }
530 : else
531 : {
532 : // After export and import, the result is a shape.
533 2 : uno::Reference<beans::XPropertySet> xShape(getShape(1), uno::UNO_QUERY);
534 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(0xD99594), getProperty<sal_Int32>(xShape, "FillColor"));
535 :
536 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(0xC0504D), getProperty<sal_Int32>(xShape, "LineColor"));
537 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(35), getProperty<sal_Int32>(xShape, "LineWidth"));
538 :
539 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(48), getProperty<sal_Int32>(xShape, "ShadowXDistance"));
540 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(48), getProperty<sal_Int32>(xShape, "ShadowYDistance"));
541 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(0x622423), getProperty<sal_Int32>(xShape, "ShadowColor"));
542 4 : }
543 4 : }
544 :
545 28 : DECLARE_OOXMLEXPORT_TEST(testTextframeGradient, "textframe-gradient.docx")
546 : {
547 4 : uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY);
548 8 : uno::Reference<container::XIndexAccess> xIndexAccess(xDrawPageSupplier->getDrawPage(), uno::UNO_QUERY);
549 4 : CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xIndexAccess->getCount());
550 :
551 8 : uno::Reference<beans::XPropertySet> xFrame(xIndexAccess->getByIndex(0), uno::UNO_QUERY);
552 4 : CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_GRADIENT, getProperty<drawing::FillStyle>(xFrame, "FillStyle"));
553 4 : awt::Gradient aGradient = getProperty<awt::Gradient>(xFrame, "FillGradient");
554 4 : CPPUNIT_ASSERT_EQUAL(sal_Int32(0xC0504D), aGradient.StartColor);
555 4 : CPPUNIT_ASSERT_EQUAL(sal_Int32(0xD99594), aGradient.EndColor);
556 4 : CPPUNIT_ASSERT_EQUAL(awt::GradientStyle_AXIAL, aGradient.Style);
557 :
558 4 : xFrame.set(xIndexAccess->getByIndex(1), uno::UNO_QUERY);
559 4 : CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_GRADIENT, getProperty<drawing::FillStyle>(xFrame, "FillStyle"));
560 4 : aGradient = getProperty<awt::Gradient>(xFrame, "FillGradient");
561 4 : CPPUNIT_ASSERT_EQUAL(sal_Int32(0x000000), aGradient.StartColor);
562 4 : CPPUNIT_ASSERT_EQUAL(sal_Int32(0x666666), aGradient.EndColor);
563 4 : CPPUNIT_ASSERT_EQUAL(awt::GradientStyle_AXIAL, aGradient.Style);
564 :
565 : // Left / right margin was incorrect: the attribute was missing and we
566 : // didn't have the right default (had 0 instead of the below one).
567 4 : CPPUNIT_ASSERT_EQUAL(sal_Int32(318), getProperty<sal_Int32>(xFrame, "LeftMargin"));
568 8 : CPPUNIT_ASSERT_EQUAL(sal_Int32(318), getProperty<sal_Int32>(xFrame, "RightMargin"));
569 4 : }
570 :
571 28 : DECLARE_OOXMLEXPORT_TEST(testCellBtlr, "cell-btlr.docx")
572 : {
573 : /*
574 : * The problem was that the exporter didn't mirror the workaround of the
575 : * importer, regarding the btLr text direction: the <w:textDirection
576 : * w:val="btLr"/> token was completely missing in the output.
577 : */
578 :
579 4 : xmlDocPtr pXmlDoc = parseExport();
580 4 : if (!pXmlDoc)
581 6 : return;
582 2 : assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr/w:tc/w:tcPr/w:textDirection", "val", "btLr");
583 : }
584 :
585 28 : DECLARE_OOXMLEXPORT_TEST(testTableStylerPrSz, "table-style-rPr-sz.docx")
586 : {
587 : // Verify that font size inside the table is 20pt, despite the sz attribute in the table size.
588 : // Also check that other rPr attribute are used: italic, bold, underline
589 : // Office has the same behavior
590 4 : uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY);
591 8 : uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(), uno::UNO_QUERY);
592 8 : uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY);
593 8 : uno::Reference<text::XTextRange> xCell(xTable->getCellByName("A1"), uno::UNO_QUERY);
594 8 : uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xCell->getText(), uno::UNO_QUERY);
595 8 : uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
596 8 : uno::Reference<text::XTextRange> xPara(xParaEnum->nextElement(), uno::UNO_QUERY);
597 :
598 8 : CPPUNIT_ASSERT_EQUAL(20.f, getProperty<float>(getRun(xPara, 1), "CharHeight"));
599 : // CPPUNIT_ASSERT_EQUAL(awt::FontUnderline::SINGLE, getProperty<short>(getRun(xPara, 1), "CharUnderline"));
600 : // CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD, getProperty<float>(getRun(xPara, 1), "CharWeight"));
601 : // CPPUNIT_ASSERT_EQUAL(awt::FontSlant_ITALIC, getProperty<awt::FontSlant>(getRun(xPara, 1), "CharPosture"));
602 4 : }
603 :
604 28 : DECLARE_OOXMLEXPORT_TEST(testMathLiteral, "math-literal.docx")
605 : {
606 8 : CHECK_FORMULA( "iiint from {V} to <?> {\"div\" \"F\"} dV= llint from {S} to <?> {\"F\" \xe2\x88\x99 \"n \" dS}",
607 4 : getFormula( getRun( getParagraph( 1 ), 1 )));
608 4 : }
609 :
610 26 : DECLARE_OOXMLEXPORT_TEST(testFdo48557, "fdo48557.odt")
611 : {
612 : // Inner margins of the textframe wasn't exported.
613 2 : uno::Reference<text::XTextFramesSupplier> xTextFramesSupplier(mxComponent, uno::UNO_QUERY);
614 4 : uno::Reference<container::XIndexAccess> xIndexAccess(xTextFramesSupplier->getTextFrames(), uno::UNO_QUERY);
615 4 : uno::Reference<beans::XPropertySet> xFrame(getShape(1), uno::UNO_QUERY);
616 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(150), getProperty<sal_Int32>(xFrame, "TextLeftDistance"));
617 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(150), getProperty<sal_Int32>(xFrame, "TextRightDistance"));
618 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(150), getProperty<sal_Int32>(xFrame, "TextUpperDistance"));
619 4 : CPPUNIT_ASSERT_EQUAL(sal_Int32(150), getProperty<sal_Int32>(xFrame, "TextLowerDistance"));
620 2 : }
621 :
622 28 : DECLARE_OOXMLEXPORT_TEST(testI120928, "i120928.docx")
623 : {
624 : // w:numPicBullet was ignored, leading to missing graphic bullet in numbering.
625 4 : uno::Reference<beans::XPropertySet> xPropertySet(getStyles("NumberingStyles")->getByName("WWNum1"), uno::UNO_QUERY);
626 8 : uno::Reference<container::XIndexAccess> xLevels(xPropertySet->getPropertyValue("NumberingRules"), uno::UNO_QUERY);
627 8 : uno::Sequence<beans::PropertyValue> aProps;
628 4 : xLevels->getByIndex(0) >>= aProps; // 1st level
629 :
630 4 : bool bIsGraphic = false;
631 64 : for (int i = 0; i < aProps.getLength(); ++i)
632 : {
633 60 : const beans::PropertyValue& rProp = aProps[i];
634 :
635 60 : if (rProp.Name == "NumberingType")
636 4 : CPPUNIT_ASSERT_EQUAL(style::NumberingType::BITMAP, rProp.Value.get<sal_Int16>());
637 56 : else if (rProp.Name == "GraphicURL")
638 4 : bIsGraphic = true;
639 : }
640 8 : CPPUNIT_ASSERT_EQUAL(true, bIsGraphic);
641 4 : }
642 :
643 28 : DECLARE_OOXMLEXPORT_TEST(testFdo64826, "fdo64826.docx")
644 : {
645 : // 'Track-Changes' (Track Revisions) wasn't exported.
646 4 : CPPUNIT_ASSERT_EQUAL(true, bool(getProperty<sal_Bool>(mxComponent, "RecordChanges")));
647 4 : }
648 :
649 28 : DECLARE_OOXMLEXPORT_TEST(testPageBackground, "page-background.docx")
650 : {
651 : // 'Document Background' wasn't exported.
652 4 : uno::Reference<beans::XPropertySet> xPageStyle(getStyles("PageStyles")->getByName(DEFAULT_STYLE), uno::UNO_QUERY);
653 4 : CPPUNIT_ASSERT_EQUAL(sal_Int32(0x92D050), getProperty<sal_Int32>(xPageStyle, "BackColor"));
654 4 : }
655 :
656 28 : DECLARE_OOXMLEXPORT_TEST(testFdo65265, "fdo65265.docx")
657 : {
658 : // Redline (tracked changes) of text formatting were not exported
659 4 : uno::Reference<text::XTextRange> xParagraph1 = getParagraph(1);
660 8 : uno::Reference<text::XTextRange> xParagraph2 = getParagraph(2);
661 :
662 4 : CPPUNIT_ASSERT_EQUAL(OUString("Format"), getProperty<OUString>(getRun(xParagraph1, 3), "RedlineType"));
663 8 : CPPUNIT_ASSERT_EQUAL(OUString("Format"), getProperty<OUString>(getRun(xParagraph2, 2), "RedlineType"));
664 4 : }
665 :
666 28 : DECLARE_OOXMLEXPORT_TEST(testFdo65655, "fdo65655.docx")
667 : {
668 : // The problem was that the DOCX had a non-blank odd footer and a blank even footer
669 : // The 'Different Odd & Even Pages' was turned on
670 : // However - LO assumed that because the 'even' footer is blank - it should ignore the 'Different Odd & Even Pages' flag
671 : // So it did not import it and did not export it
672 4 : uno::Reference<beans::XPropertySet> xPropertySet(getStyles("PageStyles")->getByName(DEFAULT_STYLE), uno::UNO_QUERY);
673 4 : bool bValue = false;
674 4 : xPropertySet->getPropertyValue("HeaderIsShared") >>= bValue;
675 4 : CPPUNIT_ASSERT_EQUAL(false, bool(bValue));
676 4 : xPropertySet->getPropertyValue("FooterIsShared") >>= bValue;
677 4 : CPPUNIT_ASSERT_EQUAL(false, bool(bValue));
678 4 : }
679 :
680 28 : DECLARE_OOXMLEXPORT_TEST(testFDO63053, "fdo63053.docx")
681 : {
682 4 : uno::Reference<document::XDocumentPropertiesSupplier> xDocumentPropertiesSupplier(mxComponent, uno::UNO_QUERY);
683 8 : uno::Reference<document::XDocumentProperties> xDocumentProperties = xDocumentPropertiesSupplier->getDocumentProperties();
684 4 : CPPUNIT_ASSERT_EQUAL(OUString("test1&test2"), xDocumentProperties->getTitle());
685 8 : CPPUNIT_ASSERT_EQUAL(OUString("test1&test2"), xDocumentProperties->getSubject());
686 4 : }
687 :
688 28 : DECLARE_OOXMLEXPORT_TEST(testWatermark, "watermark.docx")
689 : {
690 4 : uno::Reference<text::XTextRange> xShape(getShape(1), uno::UNO_QUERY);
691 : // 1st problem: last character was missing
692 4 : CPPUNIT_ASSERT_EQUAL(OUString("SAMPLE"), xShape->getString());
693 :
694 8 : uno::Reference<beans::XPropertySet> xPropertySet(xShape, uno::UNO_QUERY);
695 8 : uno::Sequence<beans::PropertyValue> aProps = getProperty< uno::Sequence<beans::PropertyValue> >(xShape, "CustomShapeGeometry");
696 4 : bool bFound = false;
697 32 : for (int i = 0; i < aProps.getLength(); ++i)
698 28 : if (aProps[i].Name == "TextPath")
699 4 : bFound = true;
700 : // 2nd problem: v:textpath wasn't imported
701 4 : CPPUNIT_ASSERT_EQUAL(true, bFound);
702 :
703 : // 3rd problem: rotation angle was 315, not 45.
704 4 : CPPUNIT_ASSERT_EQUAL(sal_Int32(45 * 100), getProperty<sal_Int32>(xShape, "RotateAngle"));
705 :
706 : // 4th problem: mso-position-vertical-relative:margin was ignored, VertOrientRelation was text::RelOrientation::FRAME.
707 4 : CPPUNIT_ASSERT_EQUAL(text::RelOrientation::PAGE_PRINT_AREA, getProperty<sal_Int16>(xShape, "VertOrientRelation"));
708 :
709 : // These problems were in the exporter
710 : // The textpath wasn't semi-transparent.
711 4 : CPPUNIT_ASSERT_EQUAL(sal_Int16(50), getProperty<sal_Int16>(xShape, "FillTransparence"));
712 : // The textpath had a stroke.
713 8 : CPPUNIT_ASSERT_EQUAL(drawing::LineStyle_NONE, getProperty<drawing::LineStyle>(xShape, "LineStyle"));
714 4 : }
715 :
716 28 : DECLARE_OOXMLEXPORT_TEST(testFdo43093, "fdo43093.docx")
717 : {
718 : // The problem was that the alignment are not exchange when the paragraph are RTL.
719 4 : uno::Reference<uno::XInterface> xParaRtlLeft(getParagraph( 1, "RTL Left"));
720 4 : sal_Int32 nRtlLeft = getProperty< sal_Int32 >( xParaRtlLeft, "ParaAdjust" );
721 : // test the text Direction value for the pragraph
722 4 : sal_Int16 nRLDir = getProperty< sal_Int32 >( xParaRtlLeft, "WritingMode" );
723 :
724 8 : uno::Reference<uno::XInterface> xParaRtlRight(getParagraph( 3, "RTL Right"));
725 4 : sal_Int32 nRtlRight = getProperty< sal_Int32 >( xParaRtlRight, "ParaAdjust" );
726 4 : sal_Int16 nRRDir = getProperty< sal_Int32 >( xParaRtlRight, "WritingMode" );
727 :
728 8 : uno::Reference<uno::XInterface> xParaLtrLeft(getParagraph( 5, "LTR Left"));
729 4 : sal_Int32 nLtrLeft = getProperty< sal_Int32 >( xParaLtrLeft, "ParaAdjust" );
730 4 : sal_Int16 nLLDir = getProperty< sal_Int32 >( xParaLtrLeft, "WritingMode" );
731 :
732 8 : uno::Reference<uno::XInterface> xParaLtrRight(getParagraph( 7, "LTR Right"));
733 4 : sal_Int32 nLtrRight = getProperty< sal_Int32 >( xParaLtrRight, "ParaAdjust" );
734 4 : sal_Int16 nLRDir = getProperty< sal_Int32 >( xParaLtrRight, "WritingMode" );
735 :
736 : // this will test the both the text direction and alignment for each paragraph
737 4 : CPPUNIT_ASSERT_EQUAL( sal_Int32 (style::ParagraphAdjust_LEFT), nRtlLeft);
738 4 : CPPUNIT_ASSERT_EQUAL(text::WritingMode2::RL_TB, nRLDir);
739 :
740 4 : CPPUNIT_ASSERT_EQUAL( sal_Int32 (style::ParagraphAdjust_RIGHT), nRtlRight);
741 4 : CPPUNIT_ASSERT_EQUAL(text::WritingMode2::RL_TB, nRRDir);
742 :
743 4 : CPPUNIT_ASSERT_EQUAL( sal_Int32 (style::ParagraphAdjust_LEFT), nLtrLeft);
744 4 : CPPUNIT_ASSERT_EQUAL(text::WritingMode2::LR_TB, nLLDir);
745 :
746 4 : CPPUNIT_ASSERT_EQUAL( sal_Int32 (style::ParagraphAdjust_RIGHT), nLtrRight);
747 8 : CPPUNIT_ASSERT_EQUAL(text::WritingMode2::LR_TB, nLRDir);
748 4 : }
749 :
750 28 : DECLARE_OOXMLEXPORT_TEST(testFdo64238_a, "fdo64238_a.docx")
751 : {
752 : // The problem was that when 'Show Only Odd Footer' was marked in Word and the Even footer *was filled*
753 : // then LO would still import the Even footer and concatenate it to to the odd footer.
754 : // This case specifically is for :
755 : // 'Blank Odd Footer' with 'Non-Blank Even Footer' when 'Show Only Odd Footer' is marked in Word
756 : // In this case the imported footer in LO was supposed to be blank, but instead was the 'even' footer
757 4 : uno::Reference<text::XText> xFooterText = getProperty< uno::Reference<text::XText> >(getStyles("PageStyles")->getByName(DEFAULT_STYLE), "FooterText");
758 8 : uno::Reference< text::XTextRange > xFooterParagraph = getParagraphOfText( 1, xFooterText );
759 8 : uno::Reference<container::XEnumerationAccess> xRunEnumAccess(xFooterParagraph, uno::UNO_QUERY);
760 8 : uno::Reference<container::XEnumeration> xRunEnum = xRunEnumAccess->createEnumeration();
761 4 : sal_Int32 numOfRuns = 0;
762 16 : while (xRunEnum->hasMoreElements())
763 : {
764 8 : uno::Reference<text::XTextRange> xRun(xRunEnum->nextElement(), uno::UNO_QUERY);
765 8 : numOfRuns++;
766 8 : }
767 8 : CPPUNIT_ASSERT_EQUAL(sal_Int32(2), numOfRuns);
768 4 : }
769 :
770 28 : DECLARE_OOXMLEXPORT_TEST(testFdo64238_b, "fdo64238_b.docx")
771 : {
772 : // The problem was that when 'Show Only Odd Footer' was marked in Word and the Even footer *was filled*
773 : // then LO would still import the Even footer and concatenate it to to the odd footer.
774 : // This case specifically is for :
775 : // 'Non-Blank Odd Footer' with 'Non-Blank Even Footer' when 'Show Only Odd Footer' is marked in Word
776 : // In this case the imported footer in LO was supposed to be just the odd footer, but instead was the 'odd' and 'even' footers concatenated
777 4 : uno::Reference<text::XText> xFooterText = getProperty< uno::Reference<text::XText> >(getStyles("PageStyles")->getByName(DEFAULT_STYLE), "FooterText");
778 8 : uno::Reference< text::XTextRange > xFooterParagraph = getParagraphOfText( 1, xFooterText );
779 8 : uno::Reference<container::XEnumerationAccess> xRunEnumAccess(xFooterParagraph, uno::UNO_QUERY);
780 8 : uno::Reference<container::XEnumeration> xRunEnum = xRunEnumAccess->createEnumeration();
781 4 : sal_Int32 numOfRuns = 0;
782 28 : while (xRunEnum->hasMoreElements())
783 : {
784 20 : uno::Reference<text::XTextRange> xRun(xRunEnum->nextElement(), uno::UNO_QUERY);
785 20 : numOfRuns++;
786 20 : }
787 8 : CPPUNIT_ASSERT_EQUAL(sal_Int32(5), numOfRuns);
788 4 : }
789 :
790 28 : DECLARE_OOXMLEXPORT_TEST(testFdo56679, "fdo56679.docx")
791 : {
792 : // The problem was that the DOCX importer and exporter did not handle the 'color' of an underline
793 : // (not the color of the text, the color of the underline itself)
794 4 : uno::Reference< text::XTextRange > xParagraph = getParagraph( 1 );
795 8 : uno::Reference< text::XTextRange > xText = getRun( xParagraph, 2, "This is a simple sentence.");
796 :
797 4 : CPPUNIT_ASSERT_EQUAL(true, bool(getProperty<sal_Bool>(xText, "CharUnderlineHasColor")));
798 8 : CPPUNIT_ASSERT_EQUAL(sal_Int32(0xFF0000), getProperty<sal_Int32>(xText, "CharUnderlineColor"));
799 4 : }
800 :
801 28 : DECLARE_OOXMLEXPORT_TEST(testFdo65400, "fdo65400.docx")
802 : {
803 : // The problem was that if in Word you choose 'Character Shading' - then the text portion
804 : // is marked with 'w:shd val=pct15'. LO did not store this value and so when importing and exporting
805 : // this value was lost (and so Word did not show 'Character Shading' was on)
806 4 : uno::Reference< text::XTextRange > paragraph1 = getParagraph( 1 );
807 8 : uno::Reference< text::XTextRange > shaded = getRun( paragraph1, 2, "normal" );
808 4 : CPPUNIT_ASSERT_EQUAL( sal_Int32( 0x0026 ), getProperty< sal_Int32 >( shaded, "CharShadingValue" ));
809 8 : CPPUNIT_ASSERT_EQUAL( sal_Int32( 0xd8d8d8 ), getProperty< sal_Int32 >( shaded, "CharBackColor" ));
810 4 : }
811 :
812 28 : DECLARE_OOXMLEXPORT_TEST(testFdo66543, "fdo66543.docx")
813 : {
814 : // The problem was that when importing DOCX with 'line numbers' - the 'start value' was imported
815 : // but nothing was done with it.
816 :
817 4 : uno::Reference< text::XTextRange > paragraph1 = getParagraph( 1 );
818 4 : CPPUNIT_ASSERT_EQUAL( sal_Int32( 1 ), getProperty< sal_Int32 >( paragraph1, "ParaLineNumberStartValue" ));
819 4 : }
820 :
821 26 : DECLARE_OOXMLEXPORT_TEST(testN822175, "n822175.odt")
822 : {
823 2 : uno::Reference<beans::XPropertySet> xFrame(getShape(1), uno::UNO_QUERY);
824 : // Was text::WrapTextMode_THROUGH, due to missing Surround handling in the exporter.
825 2 : CPPUNIT_ASSERT_EQUAL(text::WrapTextMode_PARALLEL, getProperty<text::WrapTextMode>(xFrame, "Surround"));
826 2 : }
827 :
828 28 : DECLARE_OOXMLEXPORT_TEST(testFdo66688, "fdo66688.docx")
829 : {
830 : // The problem was that TextFrame imported and exported the wrong value for transparency
831 : // (was stored as 'FillTransparence' instead of 'BackColorTransparency'
832 4 : uno::Reference<beans::XPropertySet> xFrame(getShape(2), uno::UNO_QUERY);
833 4 : CPPUNIT_ASSERT_EQUAL( sal_Int32( 80 ), getProperty< sal_Int32 >( xFrame, "FillTransparence" ) );
834 4 : }
835 :
836 28 : DECLARE_OOXMLEXPORT_TEST(testFdo66773, "fdo66773.docx")
837 : {
838 : // The problem was the line spacing was interpreted by Word as 'Multiple 1.08' if no default settings were written.
839 : // Now after the 'docDefaults' section is written in <styles.xml> - there is no more problem.
840 : // (Word does not try to calculate some arbitrary value for line spacing).
841 4 : uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
842 8 : uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextDocument->getText(), uno::UNO_QUERY);
843 8 : uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
844 4 : CPPUNIT_ASSERT(xParaEnum->hasMoreElements());
845 :
846 4 : style::LineSpacing alineSpacing = getProperty<style::LineSpacing>(xParaEnum->nextElement(), "ParaLineSpacing");
847 4 : CPPUNIT_ASSERT_EQUAL(style::LineSpacingMode::PROP, alineSpacing.Mode);
848 8 : CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(100), static_cast<sal_Int32>(alineSpacing.Height));
849 4 : }
850 :
851 26 : DECLARE_OOXMLEXPORT_TEST(testFdo58577, "fdo58577.odt")
852 : {
853 : // The second frame was simply missing, so let's check if both frames were imported back.
854 2 : uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY);
855 4 : uno::Reference<container::XIndexAccess> xIndexAccess(xDrawPageSupplier->getDrawPage(), uno::UNO_QUERY);
856 4 : CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xIndexAccess->getCount());
857 2 : }
858 :
859 26 : DECLARE_OOXMLEXPORT_TEST(testBnc581614, "bnc581614.doc")
860 : {
861 2 : uno::Reference<beans::XPropertySet> xFrame(getShape(1), uno::UNO_QUERY);
862 2 : CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_NONE, getProperty<drawing::FillStyle>(xFrame, "FillStyle"));
863 2 : }
864 :
865 28 : DECLARE_OOXMLEXPORT_TEST(testFdo66929, "fdo66929.docx")
866 : {
867 : // The problem was that the default 'inset' attribute of the 'textbox' node was exported incorrectly.
868 : // A node like '<v:textbox inset="0">' was exported back as '<v:textbox inset="0pt,0pt,0pt,0pt">'
869 : // This is wrong because the original node denotes a specific 'left' inset, and a default 'top','right','bottom' inset
870 4 : uno::Reference<text::XTextFramesSupplier> xTextFramesSupplier(mxComponent, uno::UNO_QUERY);
871 8 : uno::Reference<container::XIndexAccess> xIndexAccess(xTextFramesSupplier->getTextFrames(), uno::UNO_QUERY);
872 4 : if (xIndexAccess->getCount())
873 : {
874 : // VML import -> TextFrame
875 0 : uno::Reference<beans::XPropertySet> xFrame(xIndexAccess->getByIndex(0), uno::UNO_QUERY);
876 0 : CPPUNIT_ASSERT_EQUAL( sal_Int32( 0 ) , getProperty< sal_Int32 >( xFrame, "LeftBorderDistance" ) );
877 0 : CPPUNIT_ASSERT_EQUAL( sal_Int32( 127 ), getProperty< sal_Int32 >( xFrame, "TopBorderDistance" ) );
878 0 : CPPUNIT_ASSERT_EQUAL( sal_Int32( 254 ), getProperty< sal_Int32 >( xFrame, "RightBorderDistance" ) );
879 0 : CPPUNIT_ASSERT_EQUAL( sal_Int32( 127 ), getProperty< sal_Int32 >( xFrame, "BottomBorderDistance" ) );
880 : }
881 : else
882 : {
883 : // drawingML import -> shape with TextBox
884 4 : uno::Reference<beans::XPropertySet> xShape(getShape(1), uno::UNO_QUERY);
885 4 : CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xShape, "TextLeftDistance"));
886 4 : CPPUNIT_ASSERT_EQUAL(sal_Int32(127), getProperty<sal_Int32>(xShape, "TextUpperDistance"));
887 4 : CPPUNIT_ASSERT_EQUAL(sal_Int32(254), getProperty<sal_Int32>(xShape, "TextRightDistance"));
888 4 : CPPUNIT_ASSERT_EQUAL(sal_Int32(127), getProperty<sal_Int32>(xShape, "TextLowerDistance"));
889 4 : }
890 4 : }
891 :
892 28 : DECLARE_OOXMLEXPORT_TEST(testPageBorderSpacingExportCase2, "page-borders-export-case-2.docx")
893 : {
894 : // The problem was that the exporter didn't mirror the workaround of the
895 : // importer, regarding the page border's spacing : the <w:pgBorders w:offsetFrom="page">
896 : // and the inner nodes like <w:top w:space="24" .... />
897 : //
898 : // The exporter ALWAYS exported 'w:offsetFrom="text"' even when the spacing values where too large
899 : // for Word to handle (larger than 31 points)
900 :
901 4 : xmlDocPtr pXmlDoc = parseExport();
902 4 : if (!pXmlDoc)
903 6 : return;
904 :
905 : // Assert the XPath expression - page borders
906 2 : assertXPath(pXmlDoc, "/w:document/w:body/w:sectPr/w:pgBorders", "offsetFrom", "page");
907 :
908 : // Assert the XPath expression - 'left' border
909 2 : assertXPath(pXmlDoc, "/w:document/w:body/w:sectPr/w:pgBorders/w:left", "space", "24");
910 :
911 : // Assert the XPath expression - 'right' border
912 2 : assertXPath(pXmlDoc, "/w:document/w:body/w:sectPr/w:pgBorders/w:right", "space", "24");
913 : }
914 :
915 28 : DECLARE_OOXMLEXPORT_TEST(testFdo66145, "fdo66145.docx")
916 : {
917 : // The Writer ignored the 'First Is Shared' flag
918 8 : CPPUNIT_ASSERT_EQUAL(OUString("This is the FIRST page header."),
919 4 : parseDump("/root/page[1]/header/txt/text()"));
920 8 : CPPUNIT_ASSERT_EQUAL(
921 : OUString("This is the header for the REST OF THE FILE."),
922 4 : parseDump("/root/page[2]/header/txt/text()"));
923 8 : CPPUNIT_ASSERT_EQUAL(
924 : OUString("This is the header for the REST OF THE FILE."),
925 4 : parseDump("/root/page[3]/header/txt/text()"));
926 4 : }
927 :
928 28 : DECLARE_OOXMLEXPORT_TEST(testGrabBag, "grabbag.docx")
929 : {
930 : // w:mirrorIndents was lost on roundtrip, now should be handled as a grab bag property
931 4 : xmlDocPtr pXmlDoc = parseExport();
932 4 : if (!pXmlDoc)
933 6 : return;
934 2 : assertXPath(pXmlDoc, "/w:document/w:body/w:p/w:pPr/w:mirrorIndents");
935 : }
936 :
937 28 : DECLARE_OOXMLEXPORT_TEST(testFdo66781, "fdo66781.docx")
938 : {
939 : // The problem was that bullets with level=0 were shown in LO as normal bullets,
940 : // and when saved back to DOCX were saved with level=1 (so hidden bullets became visible)
941 4 : uno::Reference<beans::XPropertySet> xPropertySet(getStyles("NumberingStyles")->getByName("WWNum1"), uno::UNO_QUERY);
942 4 : uno::Reference<container::XIndexAccess> xLevels(xPropertySet->getPropertyValue("NumberingRules"), uno::UNO_QUERY);
943 4 : uno::Sequence<beans::PropertyValue> aProps;
944 4 : xLevels->getByIndex(0) >>= aProps; // 1st level
945 :
946 56 : for (int i = 0; i < aProps.getLength(); ++i)
947 : {
948 56 : const beans::PropertyValue& rProp = aProps[i];
949 56 : if (rProp.Name == "BulletChar")
950 : {
951 4 : CPPUNIT_ASSERT_EQUAL(OUString("\x0", 1, RTL_TEXTENCODING_UTF8), rProp.Value.get<OUString>());
952 8 : return;
953 : }
954 : }
955 :
956 : // Shouldn't reach here
957 0 : CPPUNIT_FAIL("Did not find bullet with level 0");
958 : }
959 :
960 26 : DECLARE_OOXMLEXPORT_TEST(testFdo60990, "fdo60990.odt")
961 : {
962 : // The shape had no background, no paragraph adjust and no font color.
963 2 : uno::Reference<beans::XPropertySet> xShape(getShape(1), uno::UNO_QUERY);
964 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(0x00CFE7F5), getProperty<sal_Int32>(xShape, "FillColor"));
965 4 : uno::Reference<text::XText> xText = uno::Reference<text::XTextRange>(xShape, uno::UNO_QUERY)->getText();
966 4 : uno::Reference<text::XTextRange> xParagraph = getParagraphOfText(1, xText);
967 2 : CPPUNIT_ASSERT_EQUAL(style::ParagraphAdjust_CENTER, static_cast<style::ParagraphAdjust>(getProperty<sal_Int16>(xParagraph, "ParaAdjust")));
968 4 : CPPUNIT_ASSERT_EQUAL(sal_Int32(0x00FF00), getProperty<sal_Int32>(getRun(xParagraph, 1), "CharColor"));
969 2 : }
970 :
971 28 : DECLARE_OOXMLEXPORT_TEST(testFdo65718, "fdo65718.docx")
972 : {
973 : // The problem was that the exporter always exported values of "0" for an images distance from text.
974 : // the actual attributes where 'distT', 'distB', 'distL', 'distR'
975 4 : uno::Reference<beans::XPropertySet> xPropertySet(getShape(1), uno::UNO_QUERY);
976 :
977 4 : CPPUNIT_ASSERT_EQUAL(sal_Int32( EMU_TO_MM100(0) ), getProperty<sal_Int32>(xPropertySet, "TopMargin") );
978 4 : CPPUNIT_ASSERT_EQUAL(sal_Int32( EMU_TO_MM100(0) ), getProperty<sal_Int32>(xPropertySet, "BottomMargin") );
979 :
980 : // Going to do '+1' because the 'getProperty' return 318 (instead of 317.5)
981 : // I think this is because it returns an integer, instead of a float.
982 : // The actual exporting to DOCX exports the correct value (114300 = 317.5 * 360)
983 : // The exporting to DOCX uses the 'SvxLRSpacing' that stores the value in TWIPS (180 TWIPS)
984 : // However, the 'LeftMargin' property is an integer property that holds that value in 'MM100' (should hold 317.5, but it is 318)
985 : // So I had to add the hack of the '+1' to make the test-case pass
986 4 : CPPUNIT_ASSERT_EQUAL(sal_Int32( EMU_TO_MM100(114300) + 1 ), getProperty<sal_Int32>(xPropertySet, "LeftMargin") );
987 4 : CPPUNIT_ASSERT_EQUAL(sal_Int32( EMU_TO_MM100(114300) + 1), getProperty<sal_Int32>(xPropertySet, "RightMargin") );
988 4 : }
989 :
990 28 : DECLARE_OOXMLEXPORT_TEST(testFdo64350, "fdo64350.docx")
991 : {
992 : // The problem was that page border shadows were not exported
993 4 : table::ShadowFormat aShadow = getProperty<table::ShadowFormat>(getStyles("PageStyles")->getByName(DEFAULT_STYLE), "ShadowFormat");
994 4 : CPPUNIT_ASSERT_EQUAL(table::ShadowLocation_BOTTOM_RIGHT, aShadow.Location);
995 4 : }
996 :
997 28 : DECLARE_OOXMLEXPORT_TEST(testFdo67013, "fdo67013.docx")
998 : {
999 : /*
1000 : * The problem was that borders inside headers \ footers were not exported
1001 : * This was checked in xray using these commands:
1002 : *
1003 : * xHeaderText = ThisComponent.getStyleFamilies().getByName("PageStyles").getByName("Standard").HeaderText
1004 : * xHeaderEnum = xHeaderText.createEnumeration()
1005 : * xHeaderFirstParagraph = xHeaderEnum.nextElement()
1006 : * xHeaderBottomBorder = xHeaderFirstParagraph.BottomBorder
1007 : *
1008 : * xFooterText = ThisComponent.getStyleFamilies().getByName("PageStyles").getByName("Standard").FooterText
1009 : * xFooterEnum = xFooterText.createEnumeration()
1010 : * xFooterFirstParagraph = xFooterEnum.nextElement()
1011 : * xFooterTopBorder = xFooterFirstParagraph.TopBorder
1012 : */
1013 4 : uno::Reference<text::XText> xHeaderText = getProperty< uno::Reference<text::XText> >(getStyles("PageStyles")->getByName(DEFAULT_STYLE), "HeaderText");
1014 8 : uno::Reference< text::XTextRange > xHeaderParagraph = getParagraphOfText( 1, xHeaderText );
1015 4 : table::BorderLine2 aHeaderBottomBorder = getProperty<table::BorderLine2>(xHeaderParagraph, "BottomBorder");
1016 4 : CPPUNIT_ASSERT_EQUAL(sal_Int32(0x622423), aHeaderBottomBorder.Color);
1017 4 : CPPUNIT_ASSERT_EQUAL(sal_Int16(106), aHeaderBottomBorder.InnerLineWidth);
1018 4 : CPPUNIT_ASSERT_EQUAL(sal_Int16(26), aHeaderBottomBorder.LineDistance);
1019 4 : CPPUNIT_ASSERT_EQUAL(sal_Int16(7), aHeaderBottomBorder.LineStyle);
1020 4 : CPPUNIT_ASSERT_EQUAL(sal_uInt32(159), aHeaderBottomBorder.LineWidth);
1021 4 : CPPUNIT_ASSERT_EQUAL(sal_Int16(26), aHeaderBottomBorder.OuterLineWidth);
1022 :
1023 8 : uno::Reference<text::XText> xFooterText = getProperty< uno::Reference<text::XText> >(getStyles("PageStyles")->getByName(DEFAULT_STYLE), "FooterText");
1024 8 : uno::Reference< text::XTextRange > xFooterParagraph = getParagraphOfText( 1, xFooterText );
1025 4 : table::BorderLine2 aFooterTopBorder = getProperty<table::BorderLine2>(xFooterParagraph, "TopBorder");
1026 4 : CPPUNIT_ASSERT_EQUAL(sal_Int32(0x622423), aFooterTopBorder.Color);
1027 4 : CPPUNIT_ASSERT_EQUAL(sal_Int16(26), aFooterTopBorder.InnerLineWidth);
1028 4 : CPPUNIT_ASSERT_EQUAL(sal_Int16(26), aFooterTopBorder.LineDistance);
1029 4 : CPPUNIT_ASSERT_EQUAL(sal_Int16(4), aFooterTopBorder.LineStyle);
1030 4 : CPPUNIT_ASSERT_EQUAL(sal_uInt32(159), aFooterTopBorder.LineWidth);
1031 8 : CPPUNIT_ASSERT_EQUAL(sal_Int16(106), aFooterTopBorder.OuterLineWidth);
1032 4 : }
1033 :
1034 28 : DECLARE_OOXMLEXPORT_TEST(testParaShadow, "para-shadow.docx")
1035 : {
1036 : // The problem was that in w:pBdr, child elements had a w:shadow attribute, but that was ignored.
1037 4 : table::ShadowFormat aShadow = getProperty<table::ShadowFormat>(getParagraph(2), "ParaShadowFormat");
1038 4 : CPPUNIT_ASSERT_EQUAL(COL_BLACK, sal_uInt32(aShadow.Color));
1039 4 : CPPUNIT_ASSERT_EQUAL(table::ShadowLocation_BOTTOM_RIGHT, aShadow.Location);
1040 : // w:sz="48" is in eights of a point, 1 pt is 20 twips.
1041 4 : CPPUNIT_ASSERT_EQUAL(sal_Int16(convertTwipToMm100(24/8*20)), aShadow.ShadowWidth);
1042 4 : }
1043 :
1044 28 : DECLARE_OOXMLEXPORT_TEST(testTableFloating, "table-floating.docx")
1045 : {
1046 : // Both the size and the position of the table was incorrect.
1047 4 : uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
1048 8 : uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY);
1049 : // Second table was too wide: 16249, i.e. as wide as the first table.
1050 4 : CPPUNIT_ASSERT_EQUAL(sal_Int32(11248), getProperty<sal_Int32>(xTables->getByIndex(1), "Width"));
1051 :
1052 8 : uno::Reference<text::XTextFramesSupplier> xTextFramesSupplier(mxComponent, uno::UNO_QUERY);
1053 8 : uno::Reference<container::XIndexAccess> xIndexAccess(xTextFramesSupplier->getTextFrames(), uno::UNO_QUERY);
1054 4 : if (xIndexAccess->getCount())
1055 : {
1056 : // After import, table is inside a TextFrame.
1057 2 : uno::Reference<beans::XPropertySet> xFrame(xIndexAccess->getByIndex(0), uno::UNO_QUERY);
1058 : // This was 0, should be the the opposite of (left margin + half of the border width).
1059 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(-199), getProperty<sal_Int32>(xFrame, "HoriOrientPosition"));
1060 : // Was 0 as well, should be the right margin.
1061 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(250), getProperty<sal_Int32>(xFrame, "RightMargin"));
1062 : }
1063 : else
1064 : {
1065 : // After import, table is inside a TextFrame.
1066 2 : uno::Reference<beans::XPropertySet> xShape(getShape(1), uno::UNO_QUERY);
1067 : // This was 0, should be the the opposite of (left margin + half of the border width).
1068 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(-199), getProperty<sal_Int32>(xShape, "HoriOrientPosition"));
1069 : // Was 0 as well, should be the right margin.
1070 2 : CPPUNIT_ASSERT_EQUAL(sal_Int32(250), getProperty<sal_Int32>(xShape, "RightMargin"));
1071 4 : }
1072 4 : }
1073 :
1074 28 : DECLARE_OOXMLEXPORT_TEST(testFdo44689_start_page_0, "fdo44689_start_page_0.docx")
1075 : {
1076 : // The problem was that the import & export process did not analyze the 'start from page' attribute of a section
1077 4 : uno::Reference<beans::XPropertySet> xPara(getParagraph(0), uno::UNO_QUERY);
1078 4 : CPPUNIT_ASSERT_EQUAL(sal_Int16(0), getProperty<sal_Int16>(xPara, "PageNumberOffset"));
1079 4 : }
1080 :
1081 28 : DECLARE_OOXMLEXPORT_TEST(testFdo44689_start_page_7, "fdo44689_start_page_7.docx")
1082 : {
1083 : // The problem was that the import & export process did not analyze the 'start from page' attribute of a section
1084 4 : uno::Reference<beans::XPropertySet> xPara(getParagraph(0), uno::UNO_QUERY);
1085 4 : CPPUNIT_ASSERT_EQUAL(sal_Int16(7), getProperty<sal_Int16>(xPara, "PageNumberOffset"));
1086 4 : }
1087 :
1088 28 : DECLARE_OOXMLEXPORT_TEST(testFdo67737, "fdo67737.docx")
1089 : {
1090 : // The problem was that imported shapes did not import and render the 'flip:x' and 'flip:y' attributes
1091 4 : uno::Reference<drawing::XShape> xArrow = getShape(1);
1092 4 : uno::Sequence<beans::PropertyValue> aProps = getProperty< uno::Sequence<beans::PropertyValue> >(xArrow, "CustomShapeGeometry");
1093 8 : for (int i = 0; i < aProps.getLength(); ++i)
1094 : {
1095 8 : const beans::PropertyValue& rProp = aProps[i];
1096 8 : if (rProp.Name == "MirroredY")
1097 : {
1098 4 : CPPUNIT_ASSERT_EQUAL( true, bool(rProp.Value.get<sal_Bool>()) );
1099 8 : return;
1100 : }
1101 : }
1102 :
1103 : // Shouldn't reach here
1104 0 : CPPUNIT_FAIL("Did not find MirroredY=true property");
1105 : }
1106 :
1107 28 : DECLARE_OOXMLEXPORT_TEST(testTransparentShadow, "transparent-shadow.docx")
1108 : {
1109 4 : uno::Reference<drawing::XShape> xPicture = getShape(1);
1110 4 : sal_Int32 nShadowColor = getProperty<sal_Int32>(xPicture, "ShadowColor");
1111 4 : sal_Int16 nShadowTransparence = getProperty<sal_Int16>(xPicture, "ShadowTransparence");
1112 4 : CPPUNIT_ASSERT_EQUAL(sal_Int32(0x808080), nShadowColor);
1113 4 : CPPUNIT_ASSERT_EQUAL(sal_Int16(50), nShadowTransparence);
1114 4 : }
1115 :
1116 28 : DECLARE_OOXMLEXPORT_TEST(testBnc837302, "bnc837302.docx")
1117 : {
1118 : // The problem was that text with empty author was not inserted as a redline
1119 4 : uno::Reference<text::XTextRange> xParagraph = getParagraph(1);
1120 :
1121 : // previously 'AAA' was not an own run
1122 4 : getRun(xParagraph, 3, "AAA");
1123 : // interestingly the 'Insert' is set on the _previous_ run
1124 4 : CPPUNIT_ASSERT_EQUAL(OUString("Insert"), getProperty<OUString>(getRun(xParagraph, 2), "RedlineType"));
1125 :
1126 : // make sure we don't introduce a redlined delete in the 2nd paragraph
1127 4 : xParagraph = getParagraph(2);
1128 4 : CPPUNIT_ASSERT_EQUAL(false, hasProperty(getRun(xParagraph, 1), "RedlineType"));
1129 4 : }
1130 :
1131 : #endif
1132 :
1133 8 : CPPUNIT_PLUGIN_IMPLEMENT();
1134 :
1135 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|