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