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 <tools/color.hxx>
11 #include <algorithm>
12 #include <memory>
13 #include <swmodeltestbase.hxx>
14
15 #include <com/sun/star/awt/Gradient2.hpp>
16 #include <com/sun/star/awt/Key.hpp>
17 #include <com/sun/star/awt/KeyModifier.hpp>
18 #include <com/sun/star/beans/NamedValue.hpp>
19 #include <com/sun/star/container/XIndexReplace.hpp>
20 #include <com/sun/star/drawing/FillStyle.hpp>
21 #include <com/sun/star/drawing/PointSequenceSequence.hpp>
22 #include <com/sun/star/table/ShadowFormat.hpp>
23 #include <com/sun/star/text/XBookmarksSupplier.hpp>
24 #include <com/sun/star/text/RelOrientation.hpp>
25 #include <com/sun/star/text/XDocumentIndex.hpp>
26 #include <com/sun/star/text/XTextSectionsSupplier.hpp>
27 #include <com/sun/star/text/XTextTablesSupplier.hpp>
28 #include <com/sun/star/drawing/TextVerticalAdjust.hpp>
29 #include <com/sun/star/graphic/XGraphic.hpp>
30 #include <officecfg/Office/Common.hxx>
31 #include <com/sun/star/document/XEmbeddedObjectSupplier.hpp>
32 #include <com/sun/star/text/XTextEmbeddedObjectsSupplier.hpp>
33 #include <com/sun/star/text/XTextField.hpp>
34 #include <com/sun/star/util/XModifiable.hpp>
35 #include <com/sun/star/text/XTextFieldsSupplier.hpp>
36 #include <com/sun/star/container/XIndexContainer.hpp>
37 #include <com/sun/star/document/XStorageBasedDocument.hpp>
38 #include <com/sun/star/text/XTextFramesSupplier.hpp>
39 #include <com/sun/star/text/XDocumentIndexesSupplier.hpp>
40 #include <com/sun/star/text/XTextDocument.hpp>
41 #include <com/sun/star/util/XRefreshable.hpp>
42 #include <com/sun/star/text/XTextTable.hpp>
43 #include <com/sun/star/ui/ImageType.hpp>
44 #include <com/sun/star/ui/XImageManager.hpp>
45 #include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
46 #include <com/sun/star/ui/XUIConfigurationManager.hpp>
47
48 #include <comphelper/storagehelper.hxx>
49 #include <comphelper/fileformat.h>
50 #include <comphelper/documentconstants.hxx>
51 #include <svl/PasswordHelper.hxx>
52 #include <comphelper/scopeguard.hxx>
53 #include <docmodel/uno/UnoGradientTools.hxx>
54 #include <vcl/image.hxx>
55
56 #include <docufld.hxx> // for SwHiddenTextField::ParseIfFieldDefinition() method call
57 #include <ftnidx.hxx>
58 #include <txtftn.hxx>
59
60 namespace
61 {
62 class Test : public SwModelTestBase
63 {
64 public:
Test()65 Test() : SwModelTestBase(u"/sw/qa/extras/odfexport/data/"_ustr, u"writer8"_ustr) {}
66 };
67
CPPUNIT_TEST_FIXTURE(Test,testMathObjectFlatExport)68 CPPUNIT_TEST_FIXTURE(Test, testMathObjectFlatExport)
69 {
70 comphelper::ScopeGuard g([this]() {
71 mpFilter = "writer8";
72 std::shared_ptr<comphelper::ConfigurationChanges> pBatch(
73 comphelper::ConfigurationChanges::create());
74 officecfg::Office::Common::Cache::Writer::OLE_Objects::set(20, pBatch);
75 return pBatch->commit();
76 });
77 mpFilter = "OpenDocument Text Flat XML"; // doesn't happen with ODF package
78 std::shared_ptr<comphelper::ConfigurationChanges> pBatch(
79 comphelper::ConfigurationChanges::create());
80 officecfg::Office::Common::Cache::Writer::OLE_Objects::set(1, pBatch);
81 pBatch->commit();
82 loadAndReload("2_MathType3.docx");
83
84 uno::Reference<util::XModifiable> xModifiable(mxComponent, uno::UNO_QUERY);
85 CPPUNIT_ASSERT(!xModifiable->isModified());
86 // see above, set the OLE cache to 1 for this test
87 // and the problem was that the formulas that were in the cache
88 // (the second one) were lost
89 OUString formula1(getFormula(getRun(getParagraph(1), 1)));
90 CPPUNIT_ASSERT_EQUAL(u" size 12{1+1=2} {}"_ustr, formula1);
91 OUString formula2(getFormula(getRun(getParagraph(2), 1)));
92 CPPUNIT_ASSERT_EQUAL(u" size 12{2+2=4} {}"_ustr, formula2);
93 }
94
95 DECLARE_ODFEXPORT_TEST(testTdf144319, "tdf144319.odt")
96 {
97 CPPUNIT_ASSERT_EQUAL(7, getShapes());
98 CPPUNIT_ASSERT_EQUAL(1, getPages());
99 OUString formula1(getFormula(getRun(getParagraph(3), 1)));
100 CPPUNIT_ASSERT_EQUAL(u"{ x = frac { { - b +- sqrt { b ^ 2 - 4 a c } } } { { 2 a } } }"_ustr, formula1);
101 OUString formula2(getFormula(getRun(getParagraph(4), 1)));
102 CPPUNIT_ASSERT_EQUAL(u"{ sum csup n csub { i = 1 } i ^ 3 = left ( frac { { n left ( { n + 1 } right ) } } { 2 } right ) ^ 2 }"_ustr, formula2);
103 OUString formula3(getFormula(getRun(getParagraph(5), 1)));
104 CPPUNIT_ASSERT_EQUAL(u"{ sum ^ n _ { i = 1 } i ^ 3 = left ( frac { { n left ( { n + 1 } right ) } } { 2 } right ) ^ 2 }"_ustr, formula3);
105 OUString formula4(getFormula(getRun(getParagraph(6), 1)));
106 CPPUNIT_ASSERT_EQUAL(u"{ sum ^ n _ { i = 1 } i ^ 3 = left ( frac { { n left ( { n + 1 } right ) } } { 2 } right ) ^ 2 }"_ustr, formula4);
107
108 // Without the fix in place, this test would have failed with
109 // - the property is of unexpected type or void: Model
110 OUString formula5(getFormula(getRun(getParagraph(7), 1)));
111 CPPUNIT_ASSERT_EQUAL(u"{ y ^ 2 { nitalic m p } = left ( { x ^ 3 + 7 } right ) { nitalic m p } }"_ustr, formula5);
112 }
113
testTdf43569_CheckIfFieldParse()114 void testTdf43569_CheckIfFieldParse()
115 {
116 {
117 OUString paramCondition;
118 OUString paramTrue;
119 OUString paramFalse;
120
121 SwHiddenTextField::ParseIfFieldDefinition(u"IF A B C", paramCondition, paramTrue, paramFalse);
122
123 CPPUNIT_ASSERT_EQUAL(u"A"_ustr, paramCondition);
124 CPPUNIT_ASSERT_EQUAL(u"B"_ustr, paramTrue);
125 CPPUNIT_ASSERT_EQUAL(u"C"_ustr, paramFalse);
126 }
127
128 {
129 OUString paramCondition;
130 OUString paramTrue;
131 OUString paramFalse;
132
133 SwHiddenTextField::ParseIfFieldDefinition(u" IF AAA BBB CCC ", paramCondition, paramTrue, paramFalse);
134
135 CPPUNIT_ASSERT_EQUAL(u"AAA"_ustr, paramCondition);
136 CPPUNIT_ASSERT_EQUAL(u"BBB"_ustr, paramTrue);
137 CPPUNIT_ASSERT_EQUAL(u"CCC"_ustr, paramFalse);
138 }
139
140 {
141 OUString paramCondition;
142 OUString paramTrue;
143 OUString paramFalse;
144
145 SwHiddenTextField::ParseIfFieldDefinition(u" IF AAA \"BBB\" \"CCC\" ", paramCondition, paramTrue, paramFalse);
146
147 CPPUNIT_ASSERT_EQUAL(u"AAA"_ustr, paramCondition);
148 CPPUNIT_ASSERT_EQUAL(u"BBB"_ustr, paramTrue);
149 CPPUNIT_ASSERT_EQUAL(u"CCC"_ustr, paramFalse);
150 }
151
152 // true-case and false-case have spaces inside
153 {
154 OUString paramCondition;
155 OUString paramTrue;
156 OUString paramFalse;
157
158 SwHiddenTextField::ParseIfFieldDefinition(u" IF A A A \"B B B\" \"C C C\" ", paramCondition, paramTrue, paramFalse);
159
160 CPPUNIT_ASSERT_EQUAL(u"A A A"_ustr, paramCondition);
161 CPPUNIT_ASSERT_EQUAL(u"B B B"_ustr, paramTrue);
162 CPPUNIT_ASSERT_EQUAL(u"C C C"_ustr, paramFalse);
163 }
164
165 // true-case and false-case have leading/trailing space
166 {
167 OUString paramCondition;
168 OUString paramTrue;
169 OUString paramFalse;
170
171 SwHiddenTextField::ParseIfFieldDefinition(u"IF A1 A2 A3 \"B1 B2 \" \" C1 C2\" ", paramCondition, paramTrue, paramFalse);
172
173 CPPUNIT_ASSERT_EQUAL(u"A1 A2 A3"_ustr, paramCondition);
174 CPPUNIT_ASSERT_EQUAL(u"B1 B2 "_ustr, paramTrue);
175 CPPUNIT_ASSERT_EQUAL(u" C1 C2"_ustr, paramFalse);
176 }
177
178 // true-case and false-case are empty
179 {
180 OUString paramCondition;
181 OUString paramTrue;
182 OUString paramFalse;
183
184 SwHiddenTextField::ParseIfFieldDefinition(u"IF condition \"\" \"\" ", paramCondition, paramTrue, paramFalse);
185
186 CPPUNIT_ASSERT_EQUAL(u"condition"_ustr, paramCondition);
187 CPPUNIT_ASSERT_EQUAL(u""_ustr, paramTrue);
188 CPPUNIT_ASSERT_EQUAL(u""_ustr, paramFalse);
189 }
190 }
191
192 // Input document contains only one IF-field,
193 // and it should be imported as com.sun.star.text.TextField.ConditionalText in any case,
194 // instead of insertion of the pair of two field-marks: <field:fieldmark-start> + <field:fieldmark-end>.
CPPUNIT_TEST_FIXTURE(Test,testTdf43569)195 CPPUNIT_TEST_FIXTURE(Test, testTdf43569)
196 {
197 loadAndReload("tdf43569_conditionalfield.doc");
198 // check if our parser is valid
199 testTdf43569_CheckIfFieldParse();
200
201 // now check field creation during import
202 uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
203 uno::Reference<container::XEnumerationAccess> xFieldsAccess(xTextFieldsSupplier->getTextFields());
204 uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration());
205
206 // at least one field should be detected
207 CPPUNIT_ASSERT(xFields->hasMoreElements());
208 }
209
CPPUNIT_TEST_FIXTURE(Test,testTdf130314)210 CPPUNIT_TEST_FIXTURE(Test, testTdf130314)
211 {
212 loadAndReload("tdf130314.docx");
213 // Without the fix in place, this test would have hung
214 CPPUNIT_ASSERT_EQUAL(2, getPages());
215 }
216
CPPUNIT_TEST_FIXTURE(Test,testTdf133487)217 CPPUNIT_TEST_FIXTURE(Test, testTdf133487)
218 {
219 loadAndReload("MadeByLO7.odt");
220 CPPUNIT_ASSERT_EQUAL(3, getShapes());
221 CPPUNIT_ASSERT_EQUAL(1, getPages());
222 xmlDocUniquePtr pXmlDoc = parseExport(u"content.xml"_ustr);
223 // shape in background has lowest index
224 assertXPath(pXmlDoc, "/office:document-content/office:body/office:text/text:p[2]/draw:custom-shape", "z-index", u"0");
225 assertXPath(pXmlDoc, "/office:document-content/office:automatic-styles/style:style[@style:name = /office:document-content/office:body/office:text/text:p[2]/draw:custom-shape[@draw:z-index = '0']/attribute::draw:style-name]/style:graphic-properties", "run-through", u"background");
226 // shape in foreground, previously index 1
227 assertXPath(pXmlDoc, "/office:document-content/office:body/office:text/text:p[1]/draw:custom-shape", "z-index", u"2");
228 assertXPath(pXmlDoc, "/office:document-content/office:automatic-styles/style:style[@style:name = /office:document-content/office:body/office:text/text:p[1]/draw:custom-shape[@draw:z-index = '2']/attribute::draw:style-name]/style:graphic-properties", "run-through", u"foreground");
229 // shape in foreground, previously index 0
230 assertXPath(pXmlDoc, "/office:document-content/office:body/office:text/text:p[3]/draw:custom-shape", "z-index", u"1");
231 assertXPath(pXmlDoc, "/office:document-content/office:automatic-styles/style:style[@style:name = /office:document-content/office:body/office:text/text:p[3]/draw:custom-shape[@draw:z-index = '1']/attribute::draw:style-name]/style:graphic-properties", "run-through", u"foreground");
232 }
233
CPPUNIT_TEST_FIXTURE(Test,testTdf141467)234 CPPUNIT_TEST_FIXTURE(Test, testTdf141467)
235 {
236 loadAndReload("Formcontrol needs high z-index.odt");
237 CPPUNIT_ASSERT_EQUAL(2, getShapes());
238 CPPUNIT_ASSERT_EQUAL(1, getPages());
239 xmlDocUniquePtr pXmlDoc = parseExport(u"content.xml"_ustr);
240 // shape in foreground has lowest index
241 assertXPath(pXmlDoc, "/office:document-content/office:body/office:text/text:p[2]/draw:custom-shape", "z-index", u"0");
242 assertXPath(pXmlDoc, "/office:document-content/office:automatic-styles/style:style[@style:name = /office:document-content/office:body/office:text/text:p[2]/draw:custom-shape[@draw:z-index = '0']/attribute::draw:style-name]/style:graphic-properties", "run-through", u"foreground");
243 // form control, previously index 0
244 assertXPath(pXmlDoc, "/office:document-content/office:body/office:text/text:p[2]/draw:control", "z-index", u"1");
245 // no run-through on form's style
246 assertXPath(pXmlDoc, "/office:document-content/office:automatic-styles/style:style[@style:name = /office:document-content/office:body/office:text/text:p[2]/draw:control[@draw:z-index = '1']/attribute::draw:style-name]/style:graphic-properties/attribute::run-through", 0);
247 }
248
249 DECLARE_ODFEXPORT_TEST(testTdf139126, "tdf139126.odt")
250 {
251 CPPUNIT_ASSERT_EQUAL(1, getPages());
252 uno::Reference<text::XTextTablesSupplier> xSupplier(mxComponent, uno::UNO_QUERY);
253 uno::Reference<container::XNameAccess> xTables = xSupplier->getTextTables();
254 uno::Reference<text::XTextTable> xTable(xTables->getByName(u"Table1"_ustr), uno::UNO_QUERY);
255
256 uno::Reference<text::XTextRange> xD2(xTable->getCellByName(u"D2"_ustr), uno::UNO_QUERY);
257 CPPUNIT_ASSERT_EQUAL(u"4.0"_ustr, xD2->getString());
258
259 // Without the fix in place, this test would have failed with
260 // - Expected: ** Expression is faulty **
261 // - Actual : 17976931348623200...
262 uno::Reference<text::XTextRange> xE2(xTable->getCellByName(u"E2"_ustr), uno::UNO_QUERY);
263 CPPUNIT_ASSERT_EQUAL(u"** Expression is faulty **"_ustr, xE2->getString());
264 }
265
CPPUNIT_TEST_FIXTURE(Test,testTdf125877)266 CPPUNIT_TEST_FIXTURE(Test, testTdf125877)
267 {
268 loadAndReload("tdf95806.docx");
269 CPPUNIT_ASSERT_EQUAL(1, getPages());
270 uno::Reference<text::XTextTablesSupplier> xSupplier(mxComponent, uno::UNO_QUERY);
271 uno::Reference<container::XIndexAccess> xTables(xSupplier->getTextTables(), uno::UNO_QUERY);
272
273 // This was 0 (lost table during ODT export in footnotes)
274 // Note: fix also tdf#95806: painting table layout is correct
275 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xTables->getCount());
276
277 // floating table: there is a frame now
278 uno::Reference<text::XTextFramesSupplier> xTextFramesSupplier(mxComponent, uno::UNO_QUERY);
279 uno::Reference<container::XIndexAccess> xIndexAccess(xTextFramesSupplier->getTextFrames(), uno::UNO_QUERY);
280 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());
281 }
282
CPPUNIT_TEST_FIXTURE(Test,testTdf150149)283 CPPUNIT_TEST_FIXTURE(Test, testTdf150149)
284 {
285 loadAndReload("tdf150149.fodt");
286 CPPUNIT_ASSERT_EQUAL(1, getPages());
287 xmlDocUniquePtr pXmlDoc = parseExport(u"content.xml"_ustr);
288 // This was 0 (lost table header in multi-column section)
289 assertXPath(pXmlDoc, "//table:table-header-rows", 1);
290 assertXPath(pXmlDoc, "//table:table-header-rows/table:table-row/table:table-cell", 3);
291 }
292
293 DECLARE_ODFEXPORT_TEST(testTdf103567, "tdf103567.odt")
294 {
295 CPPUNIT_ASSERT_EQUAL(1, getShapes());
296 CPPUNIT_ASSERT_EQUAL(1, getPages());
297 uno::Reference<drawing::XShape> const xShape(getShape(1));
298
299 // contour wrap polygon
300 css::drawing::PointSequenceSequence const pointss(
301 getProperty<css::drawing::PointSequenceSequence>(xShape, u"ContourPolyPolygon"_ustr));
302 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pointss.getLength());
303 // for some reason this property exists with 199 points if it wasn't
304 // imported, that would be a fail
305 CPPUNIT_ASSERT_EQUAL(sal_Int32(5), pointss[0].getLength());
306 CPPUNIT_ASSERT_EQUAL(sal_Int32( 0), pointss[0][0].X);
307 CPPUNIT_ASSERT_EQUAL(sal_Int32(2672), pointss[0][0].Y);
308 CPPUNIT_ASSERT_EQUAL(sal_Int32( 0), pointss[0][1].X);
309 CPPUNIT_ASSERT_EQUAL(sal_Int32(1111), pointss[0][1].Y);
310 CPPUNIT_ASSERT_EQUAL(sal_Int32(2672), pointss[0][2].X);
311 CPPUNIT_ASSERT_EQUAL(sal_Int32(1111), pointss[0][2].Y);
312 CPPUNIT_ASSERT_EQUAL(sal_Int32(2672), pointss[0][3].X);
313 CPPUNIT_ASSERT_EQUAL(sal_Int32(2672), pointss[0][3].Y);
314 CPPUNIT_ASSERT_EQUAL(sal_Int32( 0), pointss[0][4].X);
315 CPPUNIT_ASSERT_EQUAL(sal_Int32(2672), pointss[0][4].Y);
316
317 // image map, one rectangle
318 uno::Reference<container::XIndexContainer> const xImageMap(
319 getProperty<uno::Reference<container::XIndexContainer>>(xShape, u"ImageMap"_ustr));
320
321 uno::Reference<beans::XPropertySet> const xEntry(xImageMap->getByIndex(0), uno::UNO_QUERY);
322 CPPUNIT_ASSERT_EQUAL(u"http://example.com/"_ustr, getProperty<OUString>(xEntry, u"URL"_ustr));
323 awt::Rectangle const rect(getProperty<awt::Rectangle>(xEntry, u"Boundary"_ustr));
324 CPPUNIT_ASSERT_EQUAL(sal_Int32( 726), rect.X);
325 CPPUNIT_ASSERT_EQUAL(sal_Int32(1718), rect.Y);
326 CPPUNIT_ASSERT_EQUAL(sal_Int32(1347), rect.Width);
327 CPPUNIT_ASSERT_EQUAL(sal_Int32( 408), rect.Height);
328 }
329
CPPUNIT_TEST_FIXTURE(Test,testUserFieldDecl)330 CPPUNIT_TEST_FIXTURE(Test, testUserFieldDecl)
331 {
332 loadAndReload("user-field-decl.odt");
333 CPPUNIT_ASSERT_EQUAL(1, getPages());
334 xmlDocUniquePtr pXmlDoc = parseExport(u"styles.xml"_ustr);
335 // Without the accompanying fix in place, this test would have failed with 'Expected: 2;
336 // Actual: 1', i.e. the in-table field had no declaration (in the header), while the
337 // outside-table one had the declaration.
338 assertXPath(pXmlDoc, "//style:header/text:user-field-decls/text:user-field-decl", 2);
339 }
340
CPPUNIT_TEST_FIXTURE(Test,testUserFieldDeclFly)341 CPPUNIT_TEST_FIXTURE(Test, testUserFieldDeclFly)
342 {
343 loadAndReload("user-field-decl-fly.odt");
344 CPPUNIT_ASSERT_EQUAL(1, getShapes());
345 CPPUNIT_ASSERT_EQUAL(1, getPages());
346 xmlDocUniquePtr pXmlDoc = parseExport(u"styles.xml"_ustr);
347 // Without the accompanying fix in place, this test would have failed with 'Expected: 2;
348 // Actual: 1', i.e. the in-textframe field had no declaration (in the header), while the
349 // outside-textframe one had the declaration.
350 assertXPath(pXmlDoc, "//style:header/text:user-field-decls/text:user-field-decl", 2);
351 }
352
CPPUNIT_TEST_FIXTURE(Test,testFramebackgrounds)353 CPPUNIT_TEST_FIXTURE(Test, testFramebackgrounds)
354 {
355 auto verify = [this]() {
356 CPPUNIT_ASSERT_EQUAL(16, getShapes());
357 CPPUNIT_ASSERT_EQUAL(1, getPages());
358 //Counting the Number of Frames and checking with the expected count
359 uno::Reference<text::XTextFramesSupplier> xTextFramesSupplier(mxComponent, uno::UNO_QUERY);
360 uno::Reference<container::XIndexAccess> xIndexAccess(xTextFramesSupplier->getTextFrames(), uno::UNO_QUERY);
361 CPPUNIT_ASSERT_EQUAL(sal_Int32(16), xIndexAccess->getCount());
362 uno::Reference<drawing::XShape> xTextFrame;
363 awt::Gradient aGradientxTextFrame;
364 //Frame 1
365 xTextFrame = getShape(1);
366 CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_NONE, getProperty<drawing::FillStyle>(xTextFrame, u"FillStyle"_ustr));
367 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xTextFrame, u"FillTransparence"_ustr));
368 //Frame 2
369 xTextFrame = getShape(2);
370 CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_SOLID, getProperty<drawing::FillStyle>(xTextFrame, u"FillStyle"_ustr));
371 CPPUNIT_ASSERT_EQUAL(Color(0x006600), getProperty<Color>(xTextFrame, u"FillColor"_ustr));
372 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xTextFrame, u"FillTransparence"_ustr));
373 //Frame 3
374 xTextFrame = getShape(3);
375 CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_SOLID, getProperty<drawing::FillStyle>(xTextFrame, u"FillStyle"_ustr));
376 CPPUNIT_ASSERT_EQUAL(Color(0x006600), getProperty<Color>(xTextFrame, u"FillColor"_ustr));
377 CPPUNIT_ASSERT_EQUAL(sal_Int32(45), getProperty<sal_Int32>(xTextFrame, u"FillTransparence"_ustr));
378 //Frame 4
379 xTextFrame = getShape(4);
380 CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_SOLID, getProperty<drawing::FillStyle>(xTextFrame, u"FillStyle"_ustr));
381 CPPUNIT_ASSERT_EQUAL(Color(0x579D1C), getProperty<Color>(xTextFrame, u"FillColor"_ustr));
382 aGradientxTextFrame = getProperty<awt::Gradient>(xTextFrame, u"FillTransparenceGradient"_ustr);
383 CPPUNIT_ASSERT_EQUAL(css::awt::GradientStyle_LINEAR, aGradientxTextFrame.Style);
384 //Frame 5
385 xTextFrame = getShape(5);
386 CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_GRADIENT, getProperty<drawing::FillStyle>(xTextFrame, u"FillStyle"_ustr));
387 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xTextFrame, u"FillTransparence"_ustr));
388 CPPUNIT_ASSERT_EQUAL(u"Subtle Tango Green"_ustr, getProperty<OUString>(xTextFrame, u"FillGradientName"_ustr));
389 //Frame 6
390 xTextFrame = getShape(6);
391 CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_GRADIENT, getProperty<drawing::FillStyle>(xTextFrame, u"FillStyle"_ustr));
392 CPPUNIT_ASSERT_EQUAL(u"Subtle Tango Green"_ustr, getProperty<OUString>(xTextFrame, u"FillGradientName"_ustr));
393 CPPUNIT_ASSERT_EQUAL(sal_Int32(45), getProperty<sal_Int32>(xTextFrame, u"FillTransparence"_ustr));
394 //Frame 7
395 xTextFrame = getShape(7);
396 CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_GRADIENT, getProperty<drawing::FillStyle>(xTextFrame, u"FillStyle"_ustr));
397 CPPUNIT_ASSERT_EQUAL(u"Subtle Tango Green"_ustr, getProperty<OUString>(xTextFrame, u"FillGradientName"_ustr));
398 aGradientxTextFrame = getProperty<awt::Gradient>(xTextFrame, u"FillTransparenceGradient"_ustr);
399 CPPUNIT_ASSERT_EQUAL(css::awt::GradientStyle_LINEAR, aGradientxTextFrame.Style);
400 //Frame 8
401 xTextFrame = getShape(8);
402 CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_HATCH, getProperty<drawing::FillStyle>(xTextFrame, u"FillStyle"_ustr));
403 CPPUNIT_ASSERT_EQUAL(u"Black 0 Degrees"_ustr, getProperty<OUString>(xTextFrame, u"FillHatchName"_ustr));
404 CPPUNIT_ASSERT_EQUAL(false, getProperty<bool>(xTextFrame, u"FillBackground"_ustr));
405 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xTextFrame, u"FillTransparence"_ustr));
406 //Frame 9
407 xTextFrame = getShape(9);
408 CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_HATCH, getProperty<drawing::FillStyle>(xTextFrame, u"FillStyle"_ustr));
409 CPPUNIT_ASSERT_EQUAL(u"Black 0 Degrees"_ustr, getProperty<OUString>(xTextFrame, u"FillHatchName"_ustr));
410 CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xTextFrame, u"FillBackground"_ustr));
411 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xTextFrame, u"FillTransparence"_ustr));
412 //Frame 10
413 xTextFrame = getShape(10);
414 CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_HATCH, getProperty<drawing::FillStyle>(xTextFrame, u"FillStyle"_ustr));
415 CPPUNIT_ASSERT_EQUAL(u"Black 0 Degrees"_ustr, getProperty<OUString>(xTextFrame, u"FillHatchName"_ustr));
416 CPPUNIT_ASSERT_EQUAL(false, getProperty<bool>(xTextFrame, u"FillBackground"_ustr));
417 CPPUNIT_ASSERT_EQUAL(sal_Int32(45), getProperty<sal_Int32>(xTextFrame, u"FillTransparence"_ustr));
418 //Frame 11
419 xTextFrame = getShape(11);
420 CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_HATCH, getProperty<drawing::FillStyle>(xTextFrame, u"FillStyle"_ustr));
421 CPPUNIT_ASSERT_EQUAL(u"Black 0 Degrees"_ustr, getProperty<OUString>(xTextFrame, u"FillHatchName"_ustr));
422 CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xTextFrame, u"FillBackground"_ustr));
423 CPPUNIT_ASSERT_EQUAL(sal_Int32(45), getProperty<sal_Int32>(xTextFrame, u"FillTransparence"_ustr));
424 //Frame 12
425 xTextFrame = getShape(12);
426 CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_HATCH, getProperty<drawing::FillStyle>(xTextFrame, u"FillStyle"_ustr));
427 CPPUNIT_ASSERT_EQUAL(u"Black 0 Degrees"_ustr, getProperty<OUString>(xTextFrame, u"FillHatchName"_ustr));
428 CPPUNIT_ASSERT_EQUAL(false, getProperty<bool>(xTextFrame, u"FillBackground"_ustr));
429 aGradientxTextFrame = getProperty<awt::Gradient>(xTextFrame, u"FillTransparenceGradient"_ustr);
430 CPPUNIT_ASSERT_EQUAL(css::awt::GradientStyle_LINEAR, aGradientxTextFrame.Style);
431 //Frame 13
432 xTextFrame = getShape(13);
433 CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_HATCH, getProperty<drawing::FillStyle>(xTextFrame, u"FillStyle"_ustr));
434 CPPUNIT_ASSERT_EQUAL(u"Black 0 Degrees"_ustr, getProperty<OUString>(xTextFrame, u"FillHatchName"_ustr));
435 CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xTextFrame, u"FillBackground"_ustr));
436 aGradientxTextFrame = getProperty<awt::Gradient>(xTextFrame, u"FillTransparenceGradient"_ustr);
437 CPPUNIT_ASSERT_EQUAL(css::awt::GradientStyle_LINEAR, aGradientxTextFrame.Style);
438 //Frame 14
439 xTextFrame = getShape(14);
440 CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_BITMAP, getProperty<drawing::FillStyle>(xTextFrame, u"FillStyle"_ustr));
441 CPPUNIT_ASSERT_EQUAL(u"Sky"_ustr, getProperty<OUString>(xTextFrame, u"FillBitmapName"_ustr));
442 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xTextFrame, u"FillTransparence"_ustr));
443 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xTextFrame, u"FillBitmapPositionOffsetX"_ustr));
444 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xTextFrame, u"FillBitmapPositionOffsetY"_ustr));
445 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xTextFrame, u"FillBitmapOffsetX"_ustr));
446 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xTextFrame, u"FillBitmapOffsetY"_ustr));
447 CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xTextFrame, u"FillBitmapTile"_ustr));
448 //Frame 15
449 xTextFrame = getShape(15);
450 CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_BITMAP, getProperty<drawing::FillStyle>(xTextFrame, u"FillStyle"_ustr));
451 CPPUNIT_ASSERT_EQUAL(u"Sky"_ustr, getProperty<OUString>(xTextFrame, u"FillBitmapName"_ustr));
452 CPPUNIT_ASSERT_EQUAL(sal_Int32(45), getProperty<sal_Int32>(xTextFrame, u"FillTransparence"_ustr));
453 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xTextFrame, u"FillBitmapPositionOffsetX"_ustr));
454 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xTextFrame, u"FillBitmapPositionOffsetY"_ustr));
455 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xTextFrame, u"FillBitmapOffsetX"_ustr));
456 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xTextFrame, u"FillBitmapOffsetY"_ustr));
457 CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xTextFrame, u"FillBitmapTile"_ustr));
458 //Frame 16
459 xTextFrame = getShape(16);
460 CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_BITMAP, getProperty<drawing::FillStyle>(xTextFrame, u"FillStyle"_ustr));
461 CPPUNIT_ASSERT_EQUAL(u"Sky"_ustr, getProperty<OUString>(xTextFrame, u"FillBitmapName"_ustr));
462 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xTextFrame, u"FillBitmapPositionOffsetX"_ustr));
463 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xTextFrame, u"FillBitmapPositionOffsetY"_ustr));
464 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xTextFrame, u"FillBitmapOffsetX"_ustr));
465 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xTextFrame, u"FillBitmapOffsetY"_ustr));
466 CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xTextFrame, u"FillBitmapTile"_ustr));
467 aGradientxTextFrame = getProperty<awt::Gradient>(xTextFrame, u"FillTransparenceGradient"_ustr);
468 CPPUNIT_ASSERT_EQUAL(css::awt::GradientStyle_LINEAR, aGradientxTextFrame.Style);
469 };
470
471 createSwDoc("framebackgrounds.odt");
472 verify();
473 saveAndReload(mpFilter);
474 verify();
475
476 xmlDocUniquePtr pXmlDoc = parseExport(u"content.xml"_ustr);
477 // check that there are 3 background-image elements
478 assertXPath(pXmlDoc, "//style:style[@style:parent-style-name='Frame' and @style:family='graphic']/style:graphic-properties[@draw:fill='bitmap']/style:background-image[@style:repeat='stretch']", 3);
479 // tdf#90640: check that one of them is 55% opaque
480 assertXPath(pXmlDoc, "//style:style[@style:parent-style-name='Frame' and @style:family='graphic']/style:graphic-properties[@draw:fill='bitmap' and @fo:background-color='transparent' and @draw:opacity='55%']/style:background-image[@style:repeat='stretch' and @draw:opacity='55%']", 1);
481 // tdf#90640: check that one of them is 43% opaque
482 // (emulated - hopefully not with rounding errors)
483 assertXPath(pXmlDoc, "//style:style[@style:parent-style-name='Frame' and @style:family='graphic']/style:graphic-properties[@draw:fill='bitmap' and @fo:background-color='transparent' and @draw:opacity-name='Transparency_20_1']/style:background-image[@style:repeat='stretch' and @draw:opacity='43%']", 1);
484 }
485
CPPUNIT_TEST_FIXTURE(Test,testSHA1Correct)486 CPPUNIT_TEST_FIXTURE(Test, testSHA1Correct)
487 { // tdf#114939 this has both an affected password as well as content.xml
488 const char* const sPass = "1012345678901234567890123456789012345678901234567890";
489 createSwDoc("sha1_correct.odt", sPass);
490
491 CPPUNIT_ASSERT_EQUAL(1, getPages());
492 getParagraph(1, u"012"_ustr);
493
494 saveAndReload(mpFilter, sPass);
495
496 CPPUNIT_ASSERT_EQUAL(1, getPages());
497 getParagraph(1, u"012"_ustr);
498 }
499
CPPUNIT_TEST_FIXTURE(Test,testSHA1Wrong)500 CPPUNIT_TEST_FIXTURE(Test, testSHA1Wrong)
501 { // tdf#114939 this has both an affected password as well as content.xml
502 const char* const sPass = "1012345678901234567890123456789012345678901234567890";
503 createSwDoc("sha1_wrong.odt", sPass);
504
505 CPPUNIT_ASSERT_EQUAL(1, getPages());
506 getParagraph(1, u"012"_ustr);
507
508 saveAndReload(mpFilter, sPass);
509
510 CPPUNIT_ASSERT_EQUAL(1, getPages());
511 getParagraph(1, u"012"_ustr);
512 }
513
CPPUNIT_TEST_FIXTURE(Test,testOOoxmlEmbedded)514 CPPUNIT_TEST_FIXTURE(Test, testOOoxmlEmbedded)
515 {
516 loadAndReload("oooxml_embedded.sxw");
517 uno::Reference<text::XTextEmbeddedObjectsSupplier> xTEOSupplier(mxComponent, uno::UNO_QUERY);
518 uno::Reference<container::XNameAccess> xAccess(xTEOSupplier->getEmbeddedObjects());
519 uno::Sequence<OUString> aSeq(xAccess->getElementNames());
520 CPPUNIT_ASSERT_EQUAL(sal_Int32(4), aSeq.getLength());
521 uno::Reference<document::XEmbeddedObjectSupplier> xEOSupplier1(xAccess->getByName(u"Object1"_ustr), uno::UNO_QUERY);
522 uno::Reference<lang::XComponent> xObj1(xEOSupplier1->getEmbeddedObject());
523 uno::Reference<document::XEmbeddedObjectSupplier> xEOSupplier2(xAccess->getByName(u"Object2"_ustr), uno::UNO_QUERY);
524 uno::Reference<lang::XComponent> xObj2(xEOSupplier2->getEmbeddedObject());
525 uno::Reference<document::XEmbeddedObjectSupplier> xEOSupplier3(xAccess->getByName(u"Object3"_ustr), uno::UNO_QUERY);
526 uno::Reference<lang::XComponent> xObj3(xEOSupplier3->getEmbeddedObject());
527 uno::Reference<document::XEmbeddedObjectSupplier> xEOSupplier4(xAccess->getByName(u"Object4"_ustr), uno::UNO_QUERY);
528 uno::Reference<lang::XComponent> xObj4(xEOSupplier4->getEmbeddedObject());
529 //checking first object
530 uno::Reference<document::XStorageBasedDocument> xSBDoc1(xObj1, uno::UNO_QUERY);
531 uno::Reference<embed::XStorage> xStorage1(xSBDoc1->getDocumentStorage());
532 CPPUNIT_ASSERT_EQUAL(sal_Int32(SOFFICE_FILEFORMAT_8), comphelper::OStorageHelper::GetXStorageFormat(xStorage1));
533 //checking second object
534 uno::Reference<document::XStorageBasedDocument> xSBDoc2(xObj2, uno::UNO_QUERY);
535 uno::Reference<embed::XStorage> xStorage2(xSBDoc2->getDocumentStorage());
536 CPPUNIT_ASSERT_EQUAL(sal_Int32(SOFFICE_FILEFORMAT_8), comphelper::OStorageHelper::GetXStorageFormat(xStorage2));
537 //checking third object
538 uno::Reference<document::XStorageBasedDocument> xSBDoc3(xObj3, uno::UNO_QUERY);
539 uno::Reference<embed::XStorage> xStorage3(xSBDoc3->getDocumentStorage());
540 CPPUNIT_ASSERT_EQUAL(sal_Int32(SOFFICE_FILEFORMAT_8), comphelper::OStorageHelper::GetXStorageFormat(xStorage3));
541 //checking fourth object
542 uno::Reference<document::XStorageBasedDocument> xSBDoc4(xObj4, uno::UNO_QUERY);
543 uno::Reference<embed::XStorage> xStorage4(xSBDoc4->getDocumentStorage());
544 CPPUNIT_ASSERT_EQUAL(sal_Int32(SOFFICE_FILEFORMAT_8), comphelper::OStorageHelper::GetXStorageFormat(xStorage4));
545 }
546
547 DECLARE_ODFEXPORT_TEST(testTdf152710, "tdf152710.odt")
548 {
549 // Without this fix in place, this test would have crash at import time
550 CPPUNIT_ASSERT_EQUAL(2, getPages());
551 }
552
553 DECLARE_ODFEXPORT_TEST(testredlineTextFrame, "redlineTextFrame.odt")
554 {
555 CPPUNIT_ASSERT_EQUAL(2, getShapes());
556 CPPUNIT_ASSERT_EQUAL(1, getPages());
557 //Note this is for a crash test
558 //Counting the Number of Frames and checking with the expected count
559 uno::Reference<text::XTextFramesSupplier> xTextFramesSupplier(mxComponent, uno::UNO_QUERY);
560 uno::Reference<container::XIndexAccess> xIndexAccess(xTextFramesSupplier->getTextFrames(), uno::UNO_QUERY);
561 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xIndexAccess->getCount());
562 }
563
564 DECLARE_ODFEXPORT_TEST(testTdf107292, "tdf107292.odt")
565 {
566 // tracked deletions at the same position were loaded in reverse order
567 CPPUNIT_ASSERT_EQUAL(1, getPages());
568
569 // Without this fix in place, this test would have failed with
570 // - Expected: Lorem ipsum dolor sit...
571 // - Actual : dolor ipsumLorem sit...
572 CPPUNIT_ASSERT_EQUAL(u"Lorem ipsum dolor sit..."_ustr, getParagraph(1)->getString());
573 }
574
575 DECLARE_ODFEXPORT_TEST(testTdf140437, "tdf140437.odt")
576 {
577 // Without the fix in place, the document would have failed to load
578 CPPUNIT_ASSERT_EQUAL(1, getPages());
579
580 uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
581 uno::Reference<container::XEnumerationAccess> xFieldsAccess(xTextFieldsSupplier->getTextFields());
582 uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration());
583
584 // at least one field should be detected
585 CPPUNIT_ASSERT(xFields->hasMoreElements());
586 }
587
CPPUNIT_TEST_FIXTURE(Test,testTdf131621)588 CPPUNIT_TEST_FIXTURE(Test, testTdf131621)
589 {
590 loadAndReload("tdf131621.ott");
591 CPPUNIT_ASSERT_EQUAL(12, getShapes());
592 //Crash test, Check number of pages
593 CPPUNIT_ASSERT_EQUAL( 1, getPages() );
594 }
595
CPPUNIT_TEST_FIXTURE(Test,testTdf135144)596 CPPUNIT_TEST_FIXTURE(Test, testTdf135144)
597 {
598 loadAndReload("tdf135144.docx");
599 //Crashes at import time after roundtrip
600 CPPUNIT_ASSERT_EQUAL(3, getPages());
601 CPPUNIT_ASSERT_EQUAL(4, getShapes());
602 }
603
604 DECLARE_ODFEXPORT_TEST(testTdf130950, "tdf130950.odt")
605 {
606 //Crashes at import time
607 CPPUNIT_ASSERT_EQUAL(1, getPages());
608 CPPUNIT_ASSERT_EQUAL(2, getShapes());
609 }
610
611 DECLARE_ODFEXPORT_TEST(testFdo38244, "fdo38244.odt")
612 {
613 CPPUNIT_ASSERT_EQUAL(1, getPages());
614 // See ooxmlexport's testFdo38244().
615
616 // Test comment range feature.
617 uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
618 uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextDocument->getText(), uno::UNO_QUERY);
619 uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
620 uno::Reference<container::XEnumerationAccess> xRunEnumAccess(xParaEnum->nextElement(), uno::UNO_QUERY);
621 uno::Reference<container::XEnumeration> xRunEnum = xRunEnumAccess->createEnumeration();
622 xRunEnum->nextElement();
623 uno::Reference<beans::XPropertySet> xPropertySet(xRunEnum->nextElement(), uno::UNO_QUERY);
624 CPPUNIT_ASSERT_EQUAL(u"Annotation"_ustr, getProperty<OUString>(xPropertySet, u"TextPortionType"_ustr));
625 xRunEnum->nextElement();
626 xPropertySet.set(xRunEnum->nextElement(), uno::UNO_QUERY);
627 CPPUNIT_ASSERT_EQUAL(u"AnnotationEnd"_ustr, getProperty<OUString>(xPropertySet, u"TextPortionType"_ustr));
628
629 // Test properties
630 uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
631 uno::Reference<container::XEnumerationAccess> xFieldsAccess(xTextFieldsSupplier->getTextFields());
632 uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration());
633 xPropertySet.set(xFields->nextElement(), uno::UNO_QUERY);
634 CPPUNIT_ASSERT_EQUAL(u"__Fieldmark__4_1833023242"_ustr, getProperty<OUString>(xPropertySet, u"Name"_ustr));
635 CPPUNIT_ASSERT_EQUAL(u"M"_ustr, getProperty<OUString>(xPropertySet, u"Initials"_ustr));
636 }
637
CPPUNIT_TEST_FIXTURE(Test,testSenderInitials)638 CPPUNIT_TEST_FIXTURE(Test, testSenderInitials)
639 {
640 loadAndReload("sender-initials.fodt");
641 // Test sender-initial properties (both annotation metadata and text field)
642 uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
643 uno::Reference<container::XEnumerationAccess> xFieldsAccess(xTextFieldsSupplier->getTextFields());
644 uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration());
645 // first 3 are annotations, last 2 are text fields
646 for (unsigned i = 0; i < 3; ++i)
647 {
648 uno::Reference<beans::XPropertySet> xPropertySet(xFields->nextElement(), uno::UNO_QUERY);
649 CPPUNIT_ASSERT_EQUAL(u"I"_ustr, getProperty<OUString>(xPropertySet, u"Initials"_ustr));
650 }
651 for (unsigned i = 0; i < 2; ++i)
652 {
653 uno::Reference<beans::XPropertySet> xPropertySet(xFields->nextElement(), uno::UNO_QUERY);
654 CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xPropertySet, u"IsFixed"_ustr));
655 CPPUNIT_ASSERT_EQUAL(u"I"_ustr, getProperty<OUString>(xPropertySet, u"Content"_ustr));
656 }
657 }
658
659 DECLARE_ODFEXPORT_TEST(testResolvedComment, "resolved-comment.odt")
660 {
661 CPPUNIT_ASSERT_EQUAL(1, getPages());
662 uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
663 uno::Reference<container::XEnumerationAccess> xFieldsAccess(xTextFieldsSupplier->getTextFields());
664 uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration());
665 uno::Reference<beans::XPropertySet> xPropertySet(xFields->nextElement(), uno::UNO_QUERY);
666 CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xPropertySet, u"Resolved"_ustr));
667 xPropertySet.set(xFields->nextElement(), uno::UNO_QUERY);
668 CPPUNIT_ASSERT_EQUAL(false, getProperty<bool>(xPropertySet, u"Resolved"_ustr));
669 }
670
CPPUNIT_TEST_FIXTURE(Test,testTdf92379)671 CPPUNIT_TEST_FIXTURE(Test, testTdf92379)
672 {
673 auto verify = [this]() {
674 // frame style fo:background-color was not imported
675 uno::Reference<container::XNameAccess> xStyles(getStyles(u"FrameStyles"_ustr));
676 uno::Reference<beans::XPropertySet> xStyle(xStyles->getByName(u"encarts"_ustr),
677 uno::UNO_QUERY);
678 CPPUNIT_ASSERT_EQUAL(Color(0xffcc99), getProperty<Color>(xStyle, u"BackColorRGB"_ustr));
679 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), getProperty<sal_Int32>(xStyle, u"BackColorTransparency"_ustr));
680 CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_SOLID, getProperty<drawing::FillStyle>(xStyle, u"FillStyle"_ustr));
681 CPPUNIT_ASSERT_EQUAL(Color(0xffcc99), getProperty<Color>(xStyle, u"FillColor"_ustr));
682 CPPUNIT_ASSERT_EQUAL(sal_Int16(0), getProperty<sal_Int16>(xStyle, u"FillTransparence"_ustr));
683
684 uno::Reference<beans::XPropertySet> xFrameStyle2(xStyles->getByName(u"Untitled1"_ustr),
685 uno::UNO_QUERY);
686 CPPUNIT_ASSERT_EQUAL(COL_WHITE, getProperty<Color>(xFrameStyle2, u"BackColorRGB"_ustr));
687 CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xFrameStyle2, u"BackTransparent"_ustr));
688 CPPUNIT_ASSERT_EQUAL(sal_Int32(100), getProperty<sal_Int32>(xFrameStyle2, u"BackColorTransparency"_ustr));
689 CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_NONE, getProperty<drawing::FillStyle>(xFrameStyle2, u"FillStyle"_ustr));
690 // unfortunately this is actually the pool default value, which would be hard to fix - but it isn't a problem because style is NONE
691 // CPPUNIT_ASSERT_EQUAL(sal_Int32(0xffffff), getProperty<sal_Int32>(xFrameStyle2, "FillColor"));
692 // CPPUNIT_ASSERT_EQUAL(sal_Int16(100), getProperty<sal_Int16>(xFrameStyle2, "FillTransparence"));
693
694 // paragraph style fo:background-color was wrongly inherited despite being
695 // overridden in derived style
696 uno::Reference<container::XNameAccess> xParaStyles(getStyles(u"ParagraphStyles"_ustr));
697 uno::Reference<beans::XPropertySet> xStyle1(xParaStyles->getByName(
698 u"Titre Avis expert"_ustr), uno::UNO_QUERY);
699 CPPUNIT_ASSERT_EQUAL(Color(0x661900), getProperty<Color>(xStyle1, u"ParaBackColor"_ustr));
700 CPPUNIT_ASSERT_EQUAL(false, getProperty<bool>(xStyle1, u"ParaBackTransparent"_ustr));
701 CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_SOLID, getProperty<drawing::FillStyle>(xStyle1, u"FillStyle"_ustr));
702 CPPUNIT_ASSERT_EQUAL(Color(0x661900), getProperty<Color>(xStyle1, u"FillColor"_ustr));
703 CPPUNIT_ASSERT_EQUAL(sal_Int16(0), getProperty<sal_Int16>(xStyle1, u"FillTransparence"_ustr));
704 CPPUNIT_ASSERT_EQUAL(COL_WHITE, getProperty<Color>(xStyle1, u"CharColor"_ustr));
705
706 uno::Reference<beans::XPropertySet> xStyle2(xParaStyles->getByName(
707 u"Avis expert questions"_ustr), uno::UNO_QUERY);
708 CPPUNIT_ASSERT_EQUAL(COL_TRANSPARENT, getProperty<Color>(xStyle2, u"ParaBackColor"_ustr));
709 CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xStyle2, u"ParaBackTransparent"_ustr));
710 CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_NONE, getProperty<drawing::FillStyle>(xStyle2, u"FillStyle"_ustr));
711 // unfortunately this is actually the pool default value, which would be hard to fix - but it isn't a problem because style is NONE
712 // CPPUNIT_ASSERT_EQUAL(sal_Int32(0xffffff), getProperty<sal_Int32>(xStyle2, "FillColor"));
713 // CPPUNIT_ASSERT_EQUAL(sal_Int16(100), getProperty<sal_Int16>(xStyle2, "FillTransparence"));
714 CPPUNIT_ASSERT_EQUAL(Color(0x661900), getProperty<Color>(xStyle2, u"CharColor"_ustr));
715
716 uno::Reference<beans::XPropertySet> xStyle31(xParaStyles->getByName(
717 u"avis expert questions non cadres"_ustr), uno::UNO_QUERY);
718 CPPUNIT_ASSERT_EQUAL(Color(0x801900), getProperty<Color>(xStyle31, u"ParaBackColor"_ustr));
719 CPPUNIT_ASSERT_EQUAL(false, getProperty<bool>(xStyle31, u"ParaBackTransparent"_ustr));
720 CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_SOLID, getProperty<drawing::FillStyle>(xStyle31, u"FillStyle"_ustr));
721 CPPUNIT_ASSERT_EQUAL(Color(0x801900), getProperty<Color>(xStyle31, u"FillColor"_ustr));
722 CPPUNIT_ASSERT_EQUAL(sal_Int16(0), getProperty<sal_Int16>(xStyle31, u"FillTransparence"_ustr));
723 CPPUNIT_ASSERT_EQUAL(Color(0x661900), getProperty<Color>(xStyle31, u"CharColor"_ustr));
724
725 uno::Reference<beans::XPropertySet> xStyle32(xParaStyles->getByName(
726 u"Avis expert rXponses"_ustr), uno::UNO_QUERY);
727 CPPUNIT_ASSERT_EQUAL(COL_TRANSPARENT, getProperty<Color>(xStyle32, u"ParaBackColor"_ustr));
728 CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xStyle32, u"ParaBackTransparent"_ustr));
729 CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_NONE, getProperty<drawing::FillStyle>(xStyle32, u"FillStyle"_ustr));
730 // unfortunately this is actually the pool default value, which would be hard to fix - but it isn't a problem because style is NONE
731 // CPPUNIT_ASSERT_EQUAL(sal_Int32(0xffffff), getProperty<sal_Int32>(xStyle32, "FillColor"));
732 // CPPUNIT_ASSERT_EQUAL(sal_Int16(100), getProperty<sal_Int16>(xStyle32, "FillTransparence"));
733 CPPUNIT_ASSERT_EQUAL(Color(0x461900), getProperty<Color>(xStyle32, u"CharColor"_ustr));
734 };
735
736 createSwDoc("tdf92379.fodt");
737 verify();
738 saveAndReload(mpFilter);
739 verify();
740
741 xmlDocUniquePtr pXmlDoc = parseExport(u"styles.xml"_ustr);
742 // check that fo:background-color attribute is exported properly
743 assertXPath(pXmlDoc, "//style:style[@style:family='graphic' and @style:name='encarts']/style:graphic-properties[@fo:background-color='#ffcc99']", 1);
744 assertXPath(pXmlDoc, "//style:style[@style:family='graphic' and @style:name='Untitled1']/style:graphic-properties[@fo:background-color='transparent']", 1);
745
746 // check that fo:background-color attribute is exported properly
747 assertXPath(pXmlDoc, "//style:style[@style:family='paragraph' and @style:display-name='Titre Avis expert']/style:paragraph-properties[@fo:background-color='#661900']", 1);
748 assertXPath(pXmlDoc, "//style:style[@style:family='paragraph' and @style:display-name='Avis expert questions']/style:paragraph-properties[@fo:background-color='transparent']", 1);
749 assertXPath(pXmlDoc, "//style:style[@style:family='paragraph' and @style:display-name='avis expert questions non cadres']/style:paragraph-properties[@fo:background-color='#801900']", 1);
750 assertXPath(pXmlDoc, "//style:style[@style:family='paragraph' and @style:display-name='Avis expert rXponses']/style:paragraph-properties[@fo:background-color='transparent']", 1);
751 }
752
753 DECLARE_ODFEXPORT_TEST(testFdo79358, "fdo79358.odt")
754 {
755 CPPUNIT_ASSERT_EQUAL(1, getPages());
756 // the boolean properties of the index were not exported properly
757 uno::Reference<text::XDocumentIndexesSupplier> xIndexSupplier(mxComponent, uno::UNO_QUERY);
758 uno::Reference<container::XIndexAccess> xIndexes = xIndexSupplier->getDocumentIndexes();
759 uno::Reference<text::XDocumentIndex> xTOCIndex(xIndexes->getByIndex(0), uno::UNO_QUERY);
760 uno::Reference<beans::XPropertySet> xTOCProps(xTOCIndex, uno::UNO_QUERY);
761 CPPUNIT_ASSERT_EQUAL(false, getProperty<bool>(xTOCProps, u"CreateFromOutline"_ustr));
762 CPPUNIT_ASSERT_EQUAL(false, getProperty<bool>(xTOCProps, u"CreateFromMarks"_ustr));
763 CPPUNIT_ASSERT_EQUAL(true, getProperty<bool>(xTOCProps, u"CreateFromLevelParagraphStyles"_ustr));
764 // check that the source styles are preserved too while at it
765 uno::Reference<container::XIndexReplace> xLevels(
766 getProperty< uno::Reference<container::XIndexReplace> >(xTOCProps,
767 u"LevelParagraphStyles"_ustr));
768 uno::Sequence<OUString> seq { u"Heading"_ustr };
769 CPPUNIT_ASSERT_EQUAL(uno::Any(seq), xLevels->getByIndex(1));
770 CPPUNIT_ASSERT_EQUAL(uno::Any(uno::Sequence<OUString>()), xLevels->getByIndex(2));
771 }
772
773 DECLARE_ODFEXPORT_TEST(testTextframeGradient, "textframe-gradient.odt")
774 {
775 CPPUNIT_ASSERT_EQUAL(2, getShapes());
776 CPPUNIT_ASSERT_EQUAL(1, getPages());
777 uno::Reference<text::XTextFramesSupplier> xTextFramesSupplier(mxComponent, uno::UNO_QUERY);
778 uno::Reference<container::XIndexAccess> xIndexAccess(xTextFramesSupplier->getTextFrames(), uno::UNO_QUERY);
779 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xIndexAccess->getCount());
780
781 uno::Reference<beans::XPropertySet> xFrame(xIndexAccess->getByIndex(0), uno::UNO_QUERY);
782 CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_GRADIENT, getProperty<drawing::FillStyle>(xFrame, u"FillStyle"_ustr));
783 awt::Gradient2 aGradient = getProperty<awt::Gradient2>(xFrame, u"FillGradient"_ustr);
784
785 // MCGR: Use the completely imported gradient to check for correctness
786 basegfx::BColorStops aColorStops = model::gradient::getColorStopsFromUno(aGradient.ColorStops);
787
788 CPPUNIT_ASSERT_EQUAL(size_t(2), aColorStops.size());
789 CPPUNIT_ASSERT_EQUAL(0.0, aColorStops[0].getStopOffset());
790 CPPUNIT_ASSERT_EQUAL(Color(0xc0504d), Color(aColorStops[0].getStopColor()));
791 CPPUNIT_ASSERT(basegfx::fTools::equal(aColorStops[1].getStopOffset(), 1.0));
792 CPPUNIT_ASSERT_EQUAL(Color(0xd99594), Color(aColorStops[1].getStopColor()));
793 CPPUNIT_ASSERT_EQUAL(awt::GradientStyle_AXIAL, aGradient.Style);
794
795 xFrame.set(xIndexAccess->getByIndex(1), uno::UNO_QUERY);
796 CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_GRADIENT, getProperty<drawing::FillStyle>(xFrame, u"FillStyle"_ustr));
797 aGradient = getProperty<awt::Gradient2>(xFrame, u"FillGradient"_ustr);
798
799 // MCGR: Use the completely imported gradient to check for correctness
800 aColorStops = model::gradient::getColorStopsFromUno(aGradient.ColorStops);
801
802 CPPUNIT_ASSERT_EQUAL(size_t(2), aColorStops.size());
803 CPPUNIT_ASSERT_EQUAL(0.0, aColorStops[0].getStopOffset());
804 CPPUNIT_ASSERT_EQUAL(COL_BLACK, Color(aColorStops[0].getStopColor()));
805 CPPUNIT_ASSERT(basegfx::fTools::equal(aColorStops[1].getStopOffset(), 1.0));
806 CPPUNIT_ASSERT_EQUAL(COL_GRAY7, Color(aColorStops[1].getStopColor()));
807 CPPUNIT_ASSERT_EQUAL(awt::GradientStyle_AXIAL, aGradient.Style);
808 }
809
CPPUNIT_TEST_FIXTURE(Test,testDuplicateCrossRefHeadingBookmark)810 CPPUNIT_TEST_FIXTURE(Test, testDuplicateCrossRefHeadingBookmark)
811 {
812 loadAndReload("CrossRefHeadingBookmark.fodt");
813 // the file contains invalid duplicate heading cross reference bookmarks
814 // but we have to round trip them, tdf#94804
815
816 uno::Reference<text::XBookmarksSupplier> xBookmarksSupplier(mxComponent,
817 uno::UNO_QUERY);
818 uno::Reference<container::XNameAccess> xBookmarks =
819 xBookmarksSupplier->getBookmarks();
820 uno::Reference<text::XTextContent> xBookmark1(
821 xBookmarks->getByName(u"__RefHeading__8284_1826734303"_ustr), uno::UNO_QUERY);
822 CPPUNIT_ASSERT(xBookmark1.is());
823 CPPUNIT_ASSERT_THROW(xBookmarks->getByName(u"__RefHeading__1673_25705824"_ustr), container::NoSuchElementException);
824
825 uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
826 uno::Reference<util::XRefreshable>(xTextFieldsSupplier->getTextFields(), uno::UNO_QUERY_THROW)->refresh();
827
828 uno::Reference<container::XEnumerationAccess> xFieldsAccess(xTextFieldsSupplier->getTextFields());
829 uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration());
830 uno::Any aField1 = xFields->nextElement();
831 uno::Reference<text::XTextField> xField1(aField1, uno::UNO_QUERY);
832 CPPUNIT_ASSERT_EQUAL(u"1.1"_ustr, xField1->getPresentation(false));
833 uno::Any aField2 = xFields->nextElement();
834 uno::Reference<text::XTextField> xField2(aField2, uno::UNO_QUERY);
835 CPPUNIT_ASSERT_EQUAL(u"1.1"_ustr, xField2->getPresentation(false));
836 }
837
838 DECLARE_ODFEXPORT_TEST(testFdo60769, "fdo60769.odt")
839 {
840 CPPUNIT_ASSERT_EQUAL(1, getPages());
841 // Test multi-paragraph comment range feature.
842 uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
843 uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextDocument->getText(), uno::UNO_QUERY);
844 uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
845 uno::Reference<container::XEnumerationAccess> xRunEnumAccess(xParaEnum->nextElement(), uno::UNO_QUERY);
846 uno::Reference<container::XEnumeration> xRunEnum = xRunEnumAccess->createEnumeration();
847 while (xRunEnum->hasMoreElements())
848 {
849 uno::Reference<beans::XPropertySet> xPropertySet(xRunEnum->nextElement(), uno::UNO_QUERY);
850 OUString aType = getProperty<OUString>(xPropertySet, u"TextPortionType"_ustr);
851 // First paragraph: no field end, no anchor
852 CPPUNIT_ASSERT(aType == "Text" || aType == "Annotation");
853 }
854
855 xRunEnumAccess.set(xParaEnum->nextElement(), uno::UNO_QUERY);
856 while (xRunEnum->hasMoreElements())
857 {
858 uno::Reference<beans::XPropertySet> xPropertySet(xRunEnum->nextElement(), uno::UNO_QUERY);
859 OUString aType = getProperty<OUString>(xPropertySet, u"TextPortionType"_ustr);
860 // Second paragraph: no field start
861 CPPUNIT_ASSERT(aType == "Text" || aType == "AnnotationEnd");
862 }
863 }
864
865 DECLARE_ODFEXPORT_TEST(testTdf115815, "tdf115815.odt")
866 {
867 CPPUNIT_ASSERT_EQUAL(1, getPages());
868 // Test comment range feature on tracked deletion.
869 uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
870 uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xTextDocument->getText(), uno::UNO_QUERY);
871 uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
872 uno::Reference<container::XEnumerationAccess> xRunEnumAccess(xParaEnum->nextElement(), uno::UNO_QUERY);
873 uno::Reference<container::XEnumeration> xRunEnum = xRunEnumAccess->createEnumeration();
874 bool bAnnotationStart = false;
875 bool bBeforeAnnotation = true;
876 OUString sTextBeforeAnnotation;
877 while (xRunEnum->hasMoreElements())
878 {
879 uno::Reference<beans::XPropertySet> xPropertySet(xRunEnum->nextElement(), uno::UNO_QUERY);
880 OUString aType = getProperty<OUString>(xPropertySet, u"TextPortionType"_ustr);
881 // there is no AnnotationEnd with preceding AnnotationStart,
882 // i.e. annotation with lost range
883 CPPUNIT_ASSERT(aType != "AnnotationEnd" || !bAnnotationStart);
884
885 bAnnotationStart = (aType == "Annotation");
886
887 // collect paragraph text before the first annotation
888 if (bBeforeAnnotation)
889 {
890 if (bAnnotationStart)
891 bBeforeAnnotation = false;
892 else if (aType == "Text")
893 {
894 uno::Reference<text::XTextRange> xRun(xPropertySet, uno::UNO_QUERY);
895 sTextBeforeAnnotation += xRun->getString();
896 }
897 }
898 }
899
900 // This was "Lorem ipsum" (collapsed annotation range)
901 CPPUNIT_ASSERT_EQUAL(u"Lorem "_ustr, sTextBeforeAnnotation);
902 }
903
CPPUNIT_TEST_FIXTURE(Test,testFdo58949)904 CPPUNIT_TEST_FIXTURE(Test, testFdo58949)
905 {
906 comphelper::ScopeGuard g([]() {
907 std::shared_ptr<comphelper::ConfigurationChanges> pBatch(
908 comphelper::ConfigurationChanges::create());
909 officecfg::Office::Common::Filter::Microsoft::Import::MathTypeToMath::set(true, pBatch);
910 pBatch->commit();
911 });
912
913 std::shared_ptr<comphelper::ConfigurationChanges> pBatch(
914 comphelper::ConfigurationChanges::create());
915 officecfg::Office::Common::Filter::Microsoft::Import::MathTypeToMath::set(false, pBatch);
916 pBatch->commit();
917 loadAndReload("fdo58949.docx");
918
919 /*
920 * The problem was that the exporter didn't insert "Obj102" to the
921 * resulting zip file. No idea how to check for "broken" (missing OLE data
922 * and replacement image) OLE objects using UNO, so we'll check the zip file directly.
923 */
924
925 save(u"writer8"_ustr);
926
927 uno::Sequence<uno::Any> aArgs{ uno::Any(maTempFile.GetURL()) };
928 uno::Reference<container::XNameAccess> xNameAccess(m_xSFactory->createInstanceWithArguments(u"com.sun.star.packages.zip.ZipFileAccess"_ustr, aArgs), uno::UNO_QUERY);
929 const css::uno::Sequence<OUString> aNames(xNameAccess->getElementNames());
930 // The exported document must have three objects named ObjNNN. The names are assigned in
931 // OLEHandler::copyOLEOStream using a static counter, and actual numbers depend on previous
932 // tests; so just count the matching names here.
933 int nMatches = 0;
934 for (const OUString& sName : aNames)
935 {
936 OUString sRest;
937 if (sName.startsWith("Obj", &sRest))
938 {
939 // all following characters must be decimal digits; minimal value is 100
940 bool bMatch = sRest.getLength() >= 3
941 && std::all_of(sRest.getStr(), sRest.getStr() + sRest.getLength(),
942 [](sal_Unicode ch) { return ch >= '0' && ch <= '9'; });
943 if (bMatch)
944 ++nMatches;
945 }
946 }
947 CPPUNIT_ASSERT_EQUAL(3, nMatches);
948 }
949
CPPUNIT_TEST_FIXTURE(Test,testTdf134987)950 CPPUNIT_TEST_FIXTURE(Test, testTdf134987)
951 {
952 loadAndReload("tdf134987.docx");
953 uno::Reference<text::XTextEmbeddedObjectsSupplier> xTEOSupplier(mxComponent, uno::UNO_QUERY);
954 uno::Reference<container::XNameAccess> xAccess(xTEOSupplier->getEmbeddedObjects());
955 uno::Sequence<OUString> aSeq(xAccess->getElementNames());
956 CPPUNIT_ASSERT_EQUAL(sal_Int32(3), aSeq.getLength());
957
958 OUString aMediaType;
959 // checking first object (formula)
960 {
961 uno::Reference<document::XEmbeddedObjectSupplier> xEOSupplier(xAccess->getByName(u"Object1"_ustr), uno::UNO_QUERY);
962 uno::Reference<lang::XComponent> xObj(xEOSupplier->getEmbeddedObject());
963 CPPUNIT_ASSERT(xObj.is());
964
965 uno::Reference<document::XStorageBasedDocument> xSBDoc(xObj, uno::UNO_QUERY);
966 uno::Reference<embed::XStorage> xStorage(xSBDoc->getDocumentStorage());
967 CPPUNIT_ASSERT(xStorage.is());
968
969 uno::Reference< beans::XPropertySet > xStorProps(xStorage, uno::UNO_QUERY_THROW);
970 CPPUNIT_ASSERT(xStorProps->getPropertyValue(u"MediaType"_ustr) >>= aMediaType);
971 CPPUNIT_ASSERT(aMediaType.equalsIgnoreAsciiCase(MIMETYPE_OASIS_OPENDOCUMENT_FORMULA_ASCII));
972 }
973 // checking second object (chart)
974 {
975 uno::Reference<document::XEmbeddedObjectSupplier> xEOSupplier(xAccess->getByName(u"Diagram 1"_ustr), uno::UNO_QUERY);
976 uno::Reference<lang::XComponent> xObj(xEOSupplier->getEmbeddedObject());
977 CPPUNIT_ASSERT(xObj.is());
978
979 uno::Reference<document::XStorageBasedDocument> xSBDoc(xObj, uno::UNO_QUERY);
980 uno::Reference<embed::XStorage> xStorage(xSBDoc->getDocumentStorage());
981 CPPUNIT_ASSERT(xStorage.is());
982
983 uno::Reference< beans::XPropertySet > xStorProps(xStorage, uno::UNO_QUERY_THROW);
984 CPPUNIT_ASSERT(xStorProps->getPropertyValue(u"MediaType"_ustr) >>= aMediaType);
985 CPPUNIT_ASSERT(aMediaType.equalsIgnoreAsciiCase(MIMETYPE_OASIS_OPENDOCUMENT_CHART_ASCII));
986 }
987 // checking third object (chart)
988 {
989 uno::Reference<document::XEmbeddedObjectSupplier> xEOSupplier(xAccess->getByName(u"Diagram 2"_ustr), uno::UNO_QUERY);
990 uno::Reference<lang::XComponent> xObj(xEOSupplier->getEmbeddedObject());
991 CPPUNIT_ASSERT(xObj.is());
992
993 uno::Reference<document::XStorageBasedDocument> xSBDoc(xObj, uno::UNO_QUERY);
994 uno::Reference<embed::XStorage> xStorage(xSBDoc->getDocumentStorage());
995 CPPUNIT_ASSERT(xStorage.is());
996
997 uno::Reference< beans::XPropertySet > xStorProps(xStorage, uno::UNO_QUERY_THROW);
998 CPPUNIT_ASSERT(xStorProps->getPropertyValue(u"MediaType"_ustr) >>= aMediaType);
999 CPPUNIT_ASSERT(aMediaType.equalsIgnoreAsciiCase(MIMETYPE_OASIS_OPENDOCUMENT_CHART_ASCII));
1000 }
1001 }
1002
1003 DECLARE_ODFEXPORT_TEST(testStylePageNumber, "ooo321_stylepagenumber.odt")
1004 {
1005 CPPUNIT_ASSERT_EQUAL(5, getPages());
1006 uno::Reference<text::XTextContent> xTable1(getParagraphOrTable(1));
1007 // actually no break attribute is written in this case
1008 // CPPUNIT_ASSERT_EQUAL(style::BreakType_PAGE_BEFORE, getProperty<style::BreakType>(xTable1, "BreakType"));
1009 CPPUNIT_ASSERT_EQUAL(u"Left Page"_ustr, getProperty<OUString>(xTable1, u"PageDescName"_ustr));
1010 CPPUNIT_ASSERT_EQUAL(sal_Int16(1), getProperty<sal_Int16>(xTable1, u"PageNumberOffset"_ustr));
1011
1012 uno::Reference<text::XTextContent> xPara1(getParagraphOrTable(2));
1013 CPPUNIT_ASSERT_EQUAL(u"Right Page"_ustr, getProperty<OUString>(xPara1, u"PageDescName"_ustr));
1014 CPPUNIT_ASSERT_EQUAL(sal_Int16(1), getProperty<sal_Int16>(xPara1, u"PageNumberOffset"_ustr));
1015
1016 // i#114163 tdf#77111: OOo < 3.3 bug, it wrote "auto" as "0" for tables
1017 uno::Reference<beans::XPropertySet> xTable0(getParagraphOrTable(3), uno::UNO_QUERY);
1018 CPPUNIT_ASSERT_EQUAL(u"Left Page"_ustr, getProperty<OUString>(xTable0, u"PageDescName"_ustr));
1019 CPPUNIT_ASSERT_EQUAL(uno::Any(), xTable0->getPropertyValue(u"PageNumberOffset"_ustr));
1020
1021 uno::Reference<beans::XPropertySet> xPara0(getParagraphOrTable(4), uno::UNO_QUERY);
1022 CPPUNIT_ASSERT_EQUAL(u"Right Page"_ustr, getProperty<OUString>(xPara0, u"PageDescName"_ustr));
1023 CPPUNIT_ASSERT_EQUAL(uno::Any(), xPara0->getPropertyValue(u"PageNumberOffset"_ustr));
1024
1025 uno::Reference<container::XNameAccess> xParaStyles = getStyles(u"ParagraphStyles"_ustr);
1026 uno::Reference<beans::XPropertySet> xStyle1(xParaStyles->getByName(u"stylewithbreak1"_ustr), uno::UNO_QUERY);
1027 CPPUNIT_ASSERT_EQUAL(u"Right Page"_ustr, getProperty<OUString>(xStyle1, u"PageDescName"_ustr));
1028 CPPUNIT_ASSERT_EQUAL(sal_Int16(1), getProperty<sal_Int16>(xStyle1, u"PageNumberOffset"_ustr));
1029
1030 uno::Reference<beans::XPropertySet> xStyle0(xParaStyles->getByName(u"stylewithbreak0"_ustr), uno::UNO_QUERY);
1031 CPPUNIT_ASSERT_EQUAL(u"First Page"_ustr, getProperty<OUString>(xStyle0, u"PageDescName"_ustr));
1032 CPPUNIT_ASSERT_EQUAL(uno::Any(), xStyle0->getPropertyValue(u"PageNumberOffset"_ustr));
1033 }
1034
1035 DECLARE_ODFEXPORT_TEST(testCharacterBorder, "charborder.odt")
1036 {
1037 CPPUNIT_ASSERT_EQUAL(1, getPages());
1038 // Make sure paragraph and character attributes don't interfere
1039 // First paragraph has a paragraph border and a character border included by the paragraph style
1040
1041 // Paragraph border of first paragraph
1042 {
1043 const table::BorderLine2 aFirstParTopBorder(0x6666FF,2,26,26,7,55);
1044 const sal_Int32 aFirstParTopPadding(150);
1045 uno::Reference<beans::XPropertySet> xSet(getParagraph(1), uno::UNO_QUERY);
1046
1047 // Top border
1048 CPPUNIT_ASSERT_BORDER_EQUAL(aFirstParTopBorder, getProperty<table::BorderLine2>(xSet,u"TopBorder"_ustr));
1049 CPPUNIT_ASSERT_EQUAL(aFirstParTopPadding, getProperty<sal_Int32>(xSet,u"TopBorderDistance"_ustr));
1050
1051 // Bottom border (same as top border)
1052 CPPUNIT_ASSERT_BORDER_EQUAL(aFirstParTopBorder, getProperty<table::BorderLine2>(xSet,u"BottomBorder"_ustr));
1053 CPPUNIT_ASSERT_EQUAL(aFirstParTopPadding, getProperty<sal_Int32>(xSet,u"BottomBorderDistance"_ustr));
1054
1055 // Left border (same as top border)
1056 CPPUNIT_ASSERT_BORDER_EQUAL(aFirstParTopBorder, getProperty<table::BorderLine2>(xSet,u"LeftBorder"_ustr));
1057 CPPUNIT_ASSERT_EQUAL(aFirstParTopPadding, getProperty<sal_Int32>(xSet,u"LeftBorderDistance"_ustr));
1058
1059 // Right border (same as top border)
1060 CPPUNIT_ASSERT_BORDER_EQUAL(aFirstParTopBorder, getProperty<table::BorderLine2>(xSet,u"RightBorder"_ustr));
1061 CPPUNIT_ASSERT_EQUAL(aFirstParTopPadding, getProperty<sal_Int32>(xSet,u"RightBorderDistance"_ustr));
1062
1063 // Shadow
1064 const table::ShadowFormat aShadow = getProperty<table::ShadowFormat>(xSet,u"ParaShadowFormat"_ustr);
1065 CPPUNIT_ASSERT_EQUAL(COL_BLACK, Color(ColorTransparency, aShadow.Color));
1066 CPPUNIT_ASSERT_EQUAL(false, static_cast<bool>(aShadow.IsTransparent));
1067 CPPUNIT_ASSERT_EQUAL(table::ShadowLocation(0), aShadow.Location);
1068 CPPUNIT_ASSERT_EQUAL(sal_Int16(0), aShadow.ShadowWidth);
1069 }
1070
1071 // Character border for first paragraph
1072 {
1073 const table::BorderLine2 aFirstParCharTopBorder(0xFF3333,0,37,0,2,37);
1074 const sal_Int32 aFirstParCharTopPadding(450);
1075 uno::Reference<beans::XPropertySet> xSet(getParagraph(1), uno::UNO_QUERY);
1076
1077 // Top border
1078 CPPUNIT_ASSERT_BORDER_EQUAL(aFirstParCharTopBorder, getProperty<table::BorderLine2>(xSet,u"CharTopBorder"_ustr));
1079 CPPUNIT_ASSERT_EQUAL(aFirstParCharTopPadding, getProperty<sal_Int32>(xSet,u"CharTopBorderDistance"_ustr));
1080
1081 // Bottom border (same as top border)
1082 CPPUNIT_ASSERT_BORDER_EQUAL(aFirstParCharTopBorder, getProperty<table::BorderLine2>(xSet,u"CharBottomBorder"_ustr));
1083 CPPUNIT_ASSERT_EQUAL(aFirstParCharTopPadding, getProperty<sal_Int32>(xSet,u"CharBottomBorderDistance"_ustr));
1084
1085 // Left border (same as top border)
1086 CPPUNIT_ASSERT_BORDER_EQUAL(aFirstParCharTopBorder, getProperty<table::BorderLine2>(xSet,u"CharLeftBorder"_ustr));
1087 CPPUNIT_ASSERT_EQUAL(aFirstParCharTopPadding, getProperty<sal_Int32>(xSet,u"CharLeftBorderDistance"_ustr));
1088
1089 // Right border (same as top border)
1090 CPPUNIT_ASSERT_BORDER_EQUAL(aFirstParCharTopBorder, getProperty<table::BorderLine2>(xSet,u"CharRightBorder"_ustr));
1091 CPPUNIT_ASSERT_EQUAL(aFirstParCharTopPadding, getProperty<sal_Int32>(xSet,u"CharRightBorderDistance"_ustr));
1092
1093 // Shadow
1094 const table::ShadowFormat aShadow = getProperty<table::ShadowFormat>(xSet,u"CharShadowFormat"_ustr);
1095 CPPUNIT_ASSERT_EQUAL(Color(0xFF3333), Color(ColorTransparency, aShadow.Color));
1096 CPPUNIT_ASSERT_EQUAL(false, static_cast<bool>(aShadow.IsTransparent));
1097 CPPUNIT_ASSERT_EQUAL(table::ShadowLocation(2), aShadow.Location);
1098 CPPUNIT_ASSERT_EQUAL(sal_Int16(280), aShadow.ShadowWidth);
1099
1100 // Check autostyle
1101 {
1102 uno::Reference< style::XAutoStyleFamily > xAutoStyleFamily(getAutoStyles(u"ParagraphStyles"_ustr));
1103 uno::Reference < container::XEnumeration > xAutoStylesEnum( xAutoStyleFamily->createEnumeration() );
1104 CPPUNIT_ASSERT_EQUAL(true, static_cast<bool>(xAutoStylesEnum->hasMoreElements()));
1105
1106 // Top border
1107 CPPUNIT_ASSERT_BORDER_EQUAL(aFirstParCharTopBorder, getProperty<table::BorderLine2>(xSet,u"CharTopBorder"_ustr));
1108 CPPUNIT_ASSERT_EQUAL(aFirstParCharTopPadding, getProperty<sal_Int32>(xSet,u"CharTopBorderDistance"_ustr));
1109
1110 // Bottom border
1111 CPPUNIT_ASSERT_BORDER_EQUAL(aFirstParCharTopBorder, getProperty<table::BorderLine2>(xSet,u"CharBottomBorder"_ustr));
1112 CPPUNIT_ASSERT_EQUAL(aFirstParCharTopPadding, getProperty<sal_Int32>(xSet,u"CharBottomBorderDistance"_ustr));
1113
1114 // Left border
1115 CPPUNIT_ASSERT_BORDER_EQUAL(aFirstParCharTopBorder, getProperty<table::BorderLine2>(xSet,u"CharLeftBorder"_ustr));
1116 CPPUNIT_ASSERT_EQUAL(aFirstParCharTopPadding, getProperty<sal_Int32>(xSet,u"CharLeftBorderDistance"_ustr));
1117
1118 // Right border
1119 CPPUNIT_ASSERT_BORDER_EQUAL(aFirstParCharTopBorder, getProperty<table::BorderLine2>(xSet,u"CharRightBorder"_ustr));
1120 CPPUNIT_ASSERT_EQUAL(aFirstParCharTopPadding, getProperty<sal_Int32>(xSet,u"CharRightBorderDistance"_ustr));
1121 }
1122 }
1123
1124 // Second paragraph's second text portion has a character style named CharDiffBor
1125 // This style includes border with different sides
1126 {
1127
1128 table::BorderLine2 aBorderArray[4] =
1129 {
1130 table::BorderLine2(0xFF3333,0,37,0,14,37), // Top (fine dashed line)
1131 table::BorderLine2(0x99FF66,26,26,53,11,106), // Bottom
1132 table::BorderLine2(0x6666FF,9,26,9,12,71), // Left
1133 table::BorderLine2(0,0,0,0,table::BorderLineStyle::NONE,0) // Right
1134 };
1135
1136 sal_Int32 aDistances[4] = { 400 /*Top*/, 300 /*Bottom*/, 250 /*Left*/, 0 /*Right*/ };
1137
1138 // Get second text portion of second paragraph
1139 uno::Reference < beans::XPropertySet > xSet( getRun(getParagraph(2),2), uno::UNO_QUERY );
1140
1141 // Top border
1142 CPPUNIT_ASSERT_BORDER_EQUAL(aBorderArray[0], getProperty<table::BorderLine2>(xSet,u"CharTopBorder"_ustr));
1143 CPPUNIT_ASSERT_EQUAL(aDistances[0], getProperty<sal_Int32>(xSet,u"CharTopBorderDistance"_ustr));
1144
1145 // Bottom border
1146 CPPUNIT_ASSERT_BORDER_EQUAL(aBorderArray[1], getProperty<table::BorderLine2>(xSet,u"CharBottomBorder"_ustr));
1147 CPPUNIT_ASSERT_EQUAL(aDistances[1], getProperty<sal_Int32>(xSet,u"CharBottomBorderDistance"_ustr));
1148
1149 // Left border
1150 CPPUNIT_ASSERT_BORDER_EQUAL(aBorderArray[2], getProperty<table::BorderLine2>(xSet,u"CharLeftBorder"_ustr));
1151 CPPUNIT_ASSERT_EQUAL(aDistances[2], getProperty<sal_Int32>(xSet,u"CharLeftBorderDistance"_ustr));
1152
1153 // Right border
1154 CPPUNIT_ASSERT_BORDER_EQUAL(aBorderArray[3], getProperty<table::BorderLine2>(xSet,u"CharRightBorder"_ustr));
1155 CPPUNIT_ASSERT_EQUAL(aDistances[3], getProperty<sal_Int32>(xSet,u"CharRightBorderDistance"_ustr));
1156
1157 // Shadow
1158 const table::ShadowFormat aShadow = getProperty<table::ShadowFormat>(xSet,u"CharShadowFormat"_ustr);
1159 CPPUNIT_ASSERT_EQUAL(COL_BLACK, Color(ColorTransparency, aShadow.Color));
1160 CPPUNIT_ASSERT_EQUAL(false, static_cast<bool>(aShadow.IsTransparent));
1161 CPPUNIT_ASSERT_EQUAL(table::ShadowLocation(3), aShadow.Location);
1162 CPPUNIT_ASSERT_EQUAL(sal_Int16(79), aShadow.ShadowWidth);
1163
1164 // Check character style
1165 {
1166 uno::Reference< container::XNameAccess > xStyleFamily = getStyles(u"CharacterStyles"_ustr);
1167 uno::Reference < beans::XPropertySet > xStyleSet(xStyleFamily->getByName(u"CharDiffBor"_ustr), uno::UNO_QUERY);
1168
1169 // Top border
1170 CPPUNIT_ASSERT_BORDER_EQUAL(aBorderArray[0], getProperty<table::BorderLine2>(xStyleSet,u"CharTopBorder"_ustr));
1171 CPPUNIT_ASSERT_EQUAL(aDistances[0], getProperty<sal_Int32>(xStyleSet,u"CharTopBorderDistance"_ustr));
1172
1173 // Bottom border
1174 CPPUNIT_ASSERT_BORDER_EQUAL(aBorderArray[1], getProperty<table::BorderLine2>(xStyleSet,u"CharBottomBorder"_ustr));
1175 CPPUNIT_ASSERT_EQUAL(aDistances[1], getProperty<sal_Int32>(xStyleSet,u"CharBottomBorderDistance"_ustr));
1176
1177 // Left border
1178 CPPUNIT_ASSERT_BORDER_EQUAL(aBorderArray[2], getProperty<table::BorderLine2>(xStyleSet,u"CharLeftBorder"_ustr));
1179 CPPUNIT_ASSERT_EQUAL(aDistances[2], getProperty<sal_Int32>(xStyleSet,u"CharLeftBorderDistance"_ustr));
1180
1181 // Right border
1182 CPPUNIT_ASSERT_BORDER_EQUAL(aBorderArray[3], getProperty<table::BorderLine2>(xStyleSet,u"CharRightBorder"_ustr));
1183 CPPUNIT_ASSERT_EQUAL(aDistances[3], getProperty<sal_Int32>(xStyleSet,u"CharRightBorderDistance"_ustr));
1184 }
1185 }
1186 }
1187
CPPUNIT_TEST_FIXTURE(Test,testProtectionKey)1188 CPPUNIT_TEST_FIXTURE(Test, testProtectionKey)
1189 {
1190 auto verify = [this]() {
1191 static OUString constexpr password(u"1012345678901234567890123456789012345678901234567890"_ustr);
1192
1193 // check 1 invalid OOo legacy password and 3 valid ODF 1.2 passwords
1194 uno::Reference<text::XTextSectionsSupplier> xTextSectionsSupplier(mxComponent, uno::UNO_QUERY);
1195 uno::Reference<container::XIndexAccess> xSections(xTextSectionsSupplier->getTextSections(), uno::UNO_QUERY);
1196 uno::Reference<beans::XPropertySet> xSect0(xSections->getByIndex(0), uno::UNO_QUERY);
1197 uno::Sequence<sal_Int8> const key0(getProperty<uno::Sequence<sal_Int8>>(xSect0, u"ProtectionKey"_ustr));
1198 CPPUNIT_ASSERT(SvPasswordHelper::CompareHashPassword(key0, password));
1199 uno::Reference<beans::XPropertySet> xSect1(xSections->getByIndex(1), uno::UNO_QUERY);
1200 uno::Sequence<sal_Int8> const key1(getProperty<uno::Sequence<sal_Int8>>(xSect1, u"ProtectionKey"_ustr));
1201 CPPUNIT_ASSERT(SvPasswordHelper::CompareHashPassword(key1, password));
1202 uno::Reference<beans::XPropertySet> xSect2(xSections->getByIndex(2), uno::UNO_QUERY);
1203 uno::Sequence<sal_Int8> const key2(getProperty<uno::Sequence<sal_Int8>>(xSect2, u"ProtectionKey"_ustr));
1204 CPPUNIT_ASSERT(SvPasswordHelper::CompareHashPassword(key2, password));
1205 uno::Reference<beans::XPropertySet> xSect3(xSections->getByIndex(3), uno::UNO_QUERY);
1206 uno::Sequence<sal_Int8> const key3(getProperty<uno::Sequence<sal_Int8>>(xSect3, u"ProtectionKey"_ustr));
1207 CPPUNIT_ASSERT(SvPasswordHelper::CompareHashPassword(key3, password));
1208 };
1209
1210 createSwDoc("protection-key.fodt");
1211 verify();
1212 saveAndReload(mpFilter);
1213 verify();
1214
1215 // we can't assume that the user entered the password; check that we
1216 // round-trip the password as-is
1217 xmlDocUniquePtr pXmlDoc = parseExport(u"content.xml"_ustr);
1218 assertXPath(pXmlDoc, "//text:section[@text:name='Section0' and @text:protected='true' and @text:protection-key='vbnhxyBKtPHCA1wB21zG1Oha8ZA=']");
1219 assertXPath(pXmlDoc, "//text:section[@text:name='Section1' and @text:protected='true' and @text:protection-key='nLHas0RIwepGDaH4c2hpyIUvIS8=']");
1220 assertXPath(pXmlDoc, "//text:section[@text:name='Section2' and @text:protected='true' and @text:protection-key-digest-algorithm='http://www.w3.org/2000/09/xmldsig#sha256' and @text:protection-key='1tnJohagR2T0yF/v69hLPuumSTsj32CumW97nkKGuSQ=']");
1221 assertXPath(pXmlDoc, "//text:section[@text:name='Section3' and @text:protected='true' and @text:protection-key-digest-algorithm='http://www.w3.org/2000/09/xmldsig#sha256' and @text:protection-key='1tnJohagR2T0yF/v69hLPuumSTsj32CumW97nkKGuSQ=']");
1222 }
1223
CPPUNIT_TEST_FIXTURE(Test,testTdf128188)1224 CPPUNIT_TEST_FIXTURE(Test, testTdf128188)
1225 {
1226 loadAndReload("footnote-collect-at-end-of-section.fodt");
1227 SwDoc* pDoc = getSwDoc();
1228 SwFootnoteIdxs const& rFootnotes(pDoc->GetFootnoteIdxs());
1229 // Section1
1230 CPPUNIT_ASSERT_EQUAL(sal_uInt16(1), rFootnotes[0]->GetFootnote().GetNumber());
1231 CPPUNIT_ASSERT_EQUAL(sal_uInt16(1), rFootnotes[0]->GetFootnote().GetNumberRLHidden());
1232 CPPUNIT_ASSERT_EQUAL(sal_uInt16(2), rFootnotes[1]->GetFootnote().GetNumber());
1233 CPPUNIT_ASSERT_EQUAL(sal_uInt16(2), rFootnotes[1]->GetFootnote().GetNumberRLHidden());
1234 // Section2
1235 CPPUNIT_ASSERT_EQUAL(sal_uInt16(1), rFootnotes[2]->GetFootnote().GetNumber());
1236 CPPUNIT_ASSERT_EQUAL(sal_uInt16(1), rFootnotes[2]->GetFootnote().GetNumberRLHidden());
1237 // deleted
1238 CPPUNIT_ASSERT_EQUAL(sal_uInt16(2), rFootnotes[3]->GetFootnote().GetNumber());
1239 CPPUNIT_ASSERT_EQUAL(sal_uInt16(1), rFootnotes[3]->GetFootnote().GetNumberRLHidden());
1240 // deleted
1241 CPPUNIT_ASSERT_EQUAL(sal_uInt16(3), rFootnotes[4]->GetFootnote().GetNumber());
1242 CPPUNIT_ASSERT_EQUAL(sal_uInt16(1), rFootnotes[4]->GetFootnote().GetNumberRLHidden());
1243 CPPUNIT_ASSERT_EQUAL(sal_uInt16(4), rFootnotes[5]->GetFootnote().GetNumber());
1244 CPPUNIT_ASSERT_EQUAL(sal_uInt16(2), rFootnotes[5]->GetFootnote().GetNumberRLHidden());
1245 }
1246
1247 DECLARE_ODFEXPORT_TEST(testFdo43807, "fdo43807.odt")
1248 {
1249 CPPUNIT_ASSERT_EQUAL(1, getPages());
1250 uno::Reference<beans::XPropertySet> xSet(getParagraph(1), uno::UNO_QUERY);
1251 CPPUNIT_ASSERT_EQUAL(u"Drop Caps"_ustr,getProperty<OUString>(xSet,u"DropCapCharStyleName"_ustr));
1252
1253 xSet.set(getParagraph(2), uno::UNO_QUERY);
1254 CPPUNIT_ASSERT_EQUAL(u"User Defined Drop Caps"_ustr,getProperty<OUString>(xSet,u"DropCapCharStyleName"_ustr));
1255 }
1256
CPPUNIT_TEST_FIXTURE(Test,testTdf103091)1257 CPPUNIT_TEST_FIXTURE(Test, testTdf103091)
1258 {
1259 loadAndReload("tdf103091.fodt");
1260 // check that all conditional paragraph style conditions are imported
1261 uno::Reference<container::XNameAccess> xParaStyles(getStyles(u"ParagraphStyles"_ustr));
1262 uno::Reference<beans::XPropertySet> xStyle1(xParaStyles->getByName(
1263 u"Text body"_ustr), uno::UNO_QUERY);
1264 auto conditions(getProperty<uno::Sequence<beans::NamedValue>>(xStyle1, u"ParaStyleConditions"_ustr));
1265
1266 CPPUNIT_ASSERT_EQUAL(sal_Int32(28), conditions.getLength());
1267 CPPUNIT_ASSERT_EQUAL(u"TableHeader"_ustr, conditions[0].Name);
1268 CPPUNIT_ASSERT_EQUAL(uno::Any(u"Addressee"_ustr), conditions[0].Value);
1269 CPPUNIT_ASSERT_EQUAL(u"Table"_ustr, conditions[1].Name);
1270 CPPUNIT_ASSERT_EQUAL(uno::Any(u"Bibliography 1"_ustr), conditions[1].Value);
1271 CPPUNIT_ASSERT_EQUAL(u"Frame"_ustr, conditions[2].Name);
1272 CPPUNIT_ASSERT_EQUAL(uno::Any(u"Bibliography Heading"_ustr), conditions[2].Value);
1273 CPPUNIT_ASSERT_EQUAL(u"Section"_ustr, conditions[3].Name);
1274 CPPUNIT_ASSERT_EQUAL(uno::Any(u"Caption"_ustr), conditions[3].Value);
1275 CPPUNIT_ASSERT_EQUAL(u"Footnote"_ustr, conditions[4].Name);
1276 CPPUNIT_ASSERT_EQUAL(uno::Any(u"Salutation"_ustr), conditions[4].Value);
1277 CPPUNIT_ASSERT_EQUAL(u"Endnote"_ustr, conditions[5].Name);
1278 CPPUNIT_ASSERT_EQUAL(uno::Any(u"Contents 1"_ustr), conditions[5].Value);
1279 CPPUNIT_ASSERT_EQUAL(u"Header"_ustr, conditions[6].Name);
1280 CPPUNIT_ASSERT_EQUAL(uno::Any(u"Contents 2"_ustr), conditions[6].Value);
1281 CPPUNIT_ASSERT_EQUAL(u"Footer"_ustr, conditions[7].Name);
1282 CPPUNIT_ASSERT_EQUAL(uno::Any(u"Contents 3"_ustr), conditions[7].Value);
1283 CPPUNIT_ASSERT_EQUAL(u"OutlineLevel1"_ustr, conditions[8].Name);
1284 CPPUNIT_ASSERT_EQUAL(uno::Any(u"Contents 4"_ustr), conditions[8].Value);
1285 CPPUNIT_ASSERT_EQUAL(u"OutlineLevel2"_ustr, conditions[9].Name);
1286 CPPUNIT_ASSERT_EQUAL(uno::Any(u"Contents 5"_ustr), conditions[9].Value);
1287 CPPUNIT_ASSERT_EQUAL(u"OutlineLevel3"_ustr, conditions[10].Name);
1288 CPPUNIT_ASSERT_EQUAL(uno::Any(u"Contents 6"_ustr), conditions[10].Value);
1289 CPPUNIT_ASSERT_EQUAL(u"OutlineLevel4"_ustr, conditions[11].Name);
1290 CPPUNIT_ASSERT_EQUAL(uno::Any(u"Contents 7"_ustr), conditions[11].Value);
1291 CPPUNIT_ASSERT_EQUAL(u"OutlineLevel5"_ustr, conditions[12].Name);
1292 CPPUNIT_ASSERT_EQUAL(uno::Any(u"Contents 8"_ustr), conditions[12].Value);
1293 CPPUNIT_ASSERT_EQUAL(u"OutlineLevel6"_ustr, conditions[13].Name);
1294 CPPUNIT_ASSERT_EQUAL(uno::Any(u"Contents 9"_ustr), conditions[13].Value);
1295 CPPUNIT_ASSERT_EQUAL(u"OutlineLevel7"_ustr, conditions[14].Name);
1296 CPPUNIT_ASSERT_EQUAL(uno::Any(u"Contents 10"_ustr), conditions[14].Value);
1297 CPPUNIT_ASSERT_EQUAL(u"OutlineLevel8"_ustr, conditions[15].Name);
1298 CPPUNIT_ASSERT_EQUAL(uno::Any(u"Contents Heading"_ustr), conditions[15].Value);
1299 CPPUNIT_ASSERT_EQUAL(u"OutlineLevel9"_ustr, conditions[16].Name);
1300 CPPUNIT_ASSERT_EQUAL(uno::Any(u"Standard"_ustr), conditions[16].Value);
1301 CPPUNIT_ASSERT_EQUAL(u"OutlineLevel10"_ustr, conditions[17].Name);
1302 CPPUNIT_ASSERT_EQUAL(uno::Any(u"Drawing"_ustr), conditions[17].Value);
1303 CPPUNIT_ASSERT_EQUAL(u"NumberingLevel1"_ustr, conditions[18].Name);
1304 CPPUNIT_ASSERT_EQUAL(uno::Any(u"Endnote"_ustr), conditions[18].Value);
1305 CPPUNIT_ASSERT_EQUAL(u"NumberingLevel2"_ustr, conditions[19].Name);
1306 CPPUNIT_ASSERT_EQUAL(uno::Any(u"First line indent"_ustr), conditions[19].Value);
1307 CPPUNIT_ASSERT_EQUAL(u"NumberingLevel3"_ustr, conditions[20].Name);
1308 CPPUNIT_ASSERT_EQUAL(uno::Any(u"Footer"_ustr), conditions[20].Value);
1309 CPPUNIT_ASSERT_EQUAL(u"NumberingLevel4"_ustr, conditions[21].Name);
1310 CPPUNIT_ASSERT_EQUAL(uno::Any(u"Footer left"_ustr), conditions[21].Value);
1311 CPPUNIT_ASSERT_EQUAL(u"NumberingLevel5"_ustr, conditions[22].Name);
1312 CPPUNIT_ASSERT_EQUAL(uno::Any(u"Footer right"_ustr), conditions[22].Value);
1313 CPPUNIT_ASSERT_EQUAL(u"NumberingLevel6"_ustr, conditions[23].Name);
1314 CPPUNIT_ASSERT_EQUAL(uno::Any(u"Footnote"_ustr), conditions[23].Value);
1315 CPPUNIT_ASSERT_EQUAL(u"NumberingLevel7"_ustr, conditions[24].Name);
1316 CPPUNIT_ASSERT_EQUAL(uno::Any(u"Frame contents"_ustr), conditions[24].Value);
1317 CPPUNIT_ASSERT_EQUAL(u"NumberingLevel8"_ustr, conditions[25].Name);
1318 CPPUNIT_ASSERT_EQUAL(uno::Any(u"Hanging indent"_ustr), conditions[25].Value);
1319 CPPUNIT_ASSERT_EQUAL(u"NumberingLevel9"_ustr, conditions[26].Name);
1320 CPPUNIT_ASSERT_EQUAL(uno::Any(u"Header"_ustr), conditions[26].Value);
1321 CPPUNIT_ASSERT_EQUAL(u"NumberingLevel10"_ustr, conditions[27].Name);
1322 CPPUNIT_ASSERT_EQUAL(uno::Any(u"Header left"_ustr), conditions[27].Value);
1323 }
1324
1325 DECLARE_ODFEXPORT_TEST(testTextframeTransparentShadow, "textframe-transparent-shadow.odt")
1326 {
1327 CPPUNIT_ASSERT_EQUAL(1, getShapes());
1328 CPPUNIT_ASSERT_EQUAL(1, getPages());
1329 uno::Reference<drawing::XShape> xPicture = getShape(1);
1330 // ODF stores opacity of 75%, that means 25% transparency.
1331 CPPUNIT_ASSERT_EQUAL(sal_Int32(25), getProperty<sal_Int32>(xPicture, u"ShadowTransparence"_ustr));
1332 }
1333
1334 DECLARE_ODFEXPORT_TEST(testRelhPage, "relh-page.odt")
1335 {
1336 CPPUNIT_ASSERT_EQUAL(1, getShapes());
1337 CPPUNIT_ASSERT_EQUAL(1, getPages());
1338 uno::Reference<drawing::XShape> xTextFrame = getShape(1);
1339 // This was text::RelOrientation::FRAME (the default), RelativeHeightRelation was not handled in xmloff.
1340 CPPUNIT_ASSERT_EQUAL(text::RelOrientation::PAGE_FRAME, getProperty<sal_Int16>(xTextFrame, u"RelativeHeightRelation"_ustr));
1341 // Make sure rel-height-rel doesn't affect width.
1342 CPPUNIT_ASSERT_EQUAL(text::RelOrientation::FRAME, getProperty<sal_Int16>(xTextFrame, u"RelativeWidthRelation"_ustr));
1343
1344 // This was 2601, 20% height was relative from margin, not page.
1345 xmlDocUniquePtr pXmlDoc = parseLayoutDump();
1346 CPPUNIT_ASSERT_EQUAL(sal_Int32(3168), getXPath(pXmlDoc, "/root/page/body/txt/anchored/fly/infos/bounds", "height").toInt32());
1347 }
1348
1349 DECLARE_ODFEXPORT_TEST(testRelhPageTdf80282, "relh-page-tdf80282.odt")
1350 {
1351 CPPUNIT_ASSERT_EQUAL(1, getShapes());
1352 CPPUNIT_ASSERT_EQUAL(1, getPages());
1353 uno::Reference<drawing::XShape> xTextFrame = getShape(1);
1354 xmlDocUniquePtr pXmlDoc = parseLayoutDump();
1355 assertXPath(pXmlDoc, "//anchored/fly/infos/bounds", "height", u"8391");
1356 assertXPath(pXmlDoc, "//anchored/fly/infos/bounds", "width", u"5953");
1357 }
1358
1359 DECLARE_ODFEXPORT_TEST(testRelwPage, "relw-page.odt")
1360 {
1361 CPPUNIT_ASSERT_EQUAL(1, getShapes());
1362 CPPUNIT_ASSERT_EQUAL(1, getPages());
1363 uno::Reference<drawing::XShape> xTextFrame = getShape(1);
1364 // This was text::RelOrientation::FRAME (the default), RelativeWidthRelation was not handled in xmloff.
1365 CPPUNIT_ASSERT_EQUAL(text::RelOrientation::PAGE_FRAME, getProperty<sal_Int16>(xTextFrame, u"RelativeWidthRelation"_ustr));
1366 // Make sure rel-width-rel doesn't affect height.
1367 CPPUNIT_ASSERT_EQUAL(text::RelOrientation::FRAME, getProperty<sal_Int16>(xTextFrame, u"RelativeHeightRelation"_ustr));
1368
1369 // This was 3762, 40% width was relative from margin, not page.
1370 xmlDocUniquePtr pXmlDoc = parseLayoutDump();
1371 CPPUNIT_ASSERT_EQUAL(sal_Int32(4896), getXPath(pXmlDoc, "/root/page/body/txt/anchored/fly/infos/bounds", "width").toInt32());
1372 }
1373
1374 DECLARE_ODFEXPORT_TEST(testTextFrameVertAdjust, "textframe-vertadjust.odt")
1375 {
1376 CPPUNIT_ASSERT_EQUAL(3, getShapes());
1377 CPPUNIT_ASSERT_EQUAL(1, getPages());
1378 // Test import/export of new frame attribute called TextVerticalAdjust
1379
1380 // 1st frame's context is adjusted to the top
1381 uno::Reference<beans::XPropertySet> xFrame(getTextFrameByName(u"Rectangle 1"_ustr), uno::UNO_QUERY);
1382 CPPUNIT_ASSERT_EQUAL(drawing::TextVerticalAdjust_TOP, getProperty<drawing::TextVerticalAdjust>(xFrame, u"TextVerticalAdjust"_ustr));
1383 // 2nd frame's context is adjusted to the center
1384 xFrame.set(getTextFrameByName(u"Rectangle 2"_ustr), uno::UNO_QUERY);
1385 CPPUNIT_ASSERT_EQUAL(drawing::TextVerticalAdjust_CENTER, getProperty<drawing::TextVerticalAdjust>(xFrame, u"TextVerticalAdjust"_ustr));
1386 // 3rd frame's context is adjusted to the bottom
1387 xFrame.set(getTextFrameByName(u"Rectangle 3"_ustr), uno::UNO_QUERY);
1388 CPPUNIT_ASSERT_EQUAL(drawing::TextVerticalAdjust_BOTTOM, getProperty<drawing::TextVerticalAdjust>(xFrame, u"TextVerticalAdjust"_ustr));
1389 }
1390
CPPUNIT_TEST_FIXTURE(Test,testTdf69500)1391 CPPUNIT_TEST_FIXTURE(Test, testTdf69500)
1392 {
1393 createSwDoc();
1394
1395 static constexpr OUString sToolBarName = u"private:resource/toolbar/custom_toolbar_1"_ustr;
1396
1397 auto getUIConfigManager = [this]() {
1398 css::uno::Reference<css::uno::XComponentContext> xContext
1399 = comphelper::getProcessComponentContext();
1400 uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
1401 CPPUNIT_ASSERT(xModel.is());
1402 uno::Reference<ui::XUIConfigurationManagerSupplier> xConfigSupplier(xModel, uno::UNO_QUERY);
1403 CPPUNIT_ASSERT(xConfigSupplier.is());
1404 uno::Reference<ui::XUIConfigurationManager> xConfigManager
1405 = xConfigSupplier->getUIConfigurationManager();
1406 return xConfigManager;
1407 };
1408
1409 // Create and persist a custom toolbar to the document
1410 {
1411 uno::Reference<ui::XUIConfigurationManager> xConfigManager = getUIConfigManager();
1412
1413 uno::Reference<container::XIndexContainer> xIndexContainer(xConfigManager->createSettings(),
1414 uno::UNO_SET_THROW);
1415 uno::Reference<container::XIndexAccess> xIndexAccess(xIndexContainer, uno::UNO_QUERY_THROW);
1416 uno::Reference<beans::XPropertySet> xProps(xIndexContainer, uno::UNO_QUERY_THROW);
1417
1418 xProps->setPropertyValue(u"UIName"_ustr, uno::Any(u"Custom Toolbar 1"_ustr));
1419
1420 xConfigManager->insertSettings(sToolBarName, xIndexAccess);
1421
1422 uno::Reference<ui::XUIConfigurationPersistence> xPersistence(xConfigManager,
1423 uno::UNO_QUERY_THROW);
1424 xPersistence->store();
1425 }
1426
1427 saveAndReload(mpFilter);
1428
1429 // Without the fix, the toolbar will be gone after save-and-reload
1430 {
1431 uno::Reference<ui::XUIConfigurationManager> xConfigManager = getUIConfigManager();
1432
1433 CPPUNIT_ASSERT(xConfigManager->hasSettings(sToolBarName));
1434 }
1435 }
1436
CPPUNIT_TEST_FIXTURE(Test,testTdf60700_images)1437 CPPUNIT_TEST_FIXTURE(Test, testTdf60700_images)
1438 {
1439 createSwDoc();
1440
1441 auto getUIConfigManager = [this]() {
1442 css::uno::Reference<css::uno::XComponentContext> xContext
1443 = comphelper::getProcessComponentContext();
1444 uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
1445 CPPUNIT_ASSERT(xModel.is());
1446 uno::Reference<ui::XUIConfigurationManagerSupplier> xConfigSupplier(xModel, uno::UNO_QUERY);
1447 CPPUNIT_ASSERT(xConfigSupplier.is());
1448 uno::Reference<ui::XUIConfigurationManager> xConfigManager
1449 = xConfigSupplier->getUIConfigurationManager();
1450 return xConfigManager;
1451 };
1452
1453 static constexpr sal_Int16 imageType
1454 = css::ui::ImageType::COLOR_NORMAL | css::ui::ImageType::SIZE_DEFAULT;
1455
1456 // Create and persist a custom icon to the document
1457 {
1458 Image aImage(m_directories.getURLFromSrc(u"/sw/qa/extras/odfexport/data/libreoffice.png"));
1459 CPPUNIT_ASSERT(!!aImage);
1460
1461 uno::Reference<graphic::XGraphic> xGraphic = Graphic(aImage.GetBitmap()).GetXGraphic();
1462 CPPUNIT_ASSERT(xGraphic.is());
1463
1464 uno::Sequence<OUString> aImportURL{ u".uno:OpenFromWriter"_ustr };
1465 uno::Sequence<uno::Reference<graphic::XGraphic>> aImportGraph{ xGraphic };
1466
1467 css::uno::Reference<css::ui::XImageManager> xImgMgr(getUIConfigManager()->getImageManager(),
1468 uno::UNO_QUERY);
1469
1470 xImgMgr->insertImages(imageType, aImportURL, aImportGraph);
1471 xImgMgr->store();
1472 }
1473
1474 saveAndReload(mpFilter);
1475
1476 // Verify that the custom icon is still present after save-and-reload
1477 {
1478 uno::Reference<ui::XUIConfigurationManager> xConfigManager = getUIConfigManager();
1479 css::uno::Reference<css::ui::XImageManager> xImgMgr(xConfigManager->getImageManager(),
1480 uno::UNO_QUERY);
1481
1482 CPPUNIT_ASSERT(xImgMgr->hasImage(imageType, u".uno:OpenFromWriter"_ustr));
1483 }
1484 }
1485
CPPUNIT_TEST_FIXTURE(Test,testTdf60700_accelerators)1486 CPPUNIT_TEST_FIXTURE(Test, testTdf60700_accelerators)
1487 {
1488 createSwDoc();
1489
1490 auto getUIConfigManager = [this]() {
1491 css::uno::Reference<css::uno::XComponentContext> xContext
1492 = comphelper::getProcessComponentContext();
1493 uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
1494 CPPUNIT_ASSERT(xModel.is());
1495 uno::Reference<ui::XUIConfigurationManagerSupplier> xConfigSupplier(xModel, uno::UNO_QUERY);
1496 CPPUNIT_ASSERT(xConfigSupplier.is());
1497 uno::Reference<ui::XUIConfigurationManager> xConfigManager
1498 = xConfigSupplier->getUIConfigurationManager();
1499 return xConfigManager;
1500 };
1501
1502 awt::KeyEvent aCtrlU;
1503 aCtrlU.KeyCode = css::awt::Key::U;
1504 aCtrlU.Modifiers = css::awt::KeyModifier::MOD1;
1505
1506 static constexpr OUString sCommand = u".uno:OpenFromWriter"_ustr;
1507
1508 // Create and persist a custom keyboard shortcut to the document
1509 {
1510 css::uno::Reference<css::ui::XAcceleratorConfiguration> xAccel
1511 = getUIConfigManager()->getShortCutManager();
1512
1513 xAccel->setKeyEvent(aCtrlU, sCommand);
1514
1515 xAccel->store();
1516 }
1517
1518 saveAndReload(mpFilter);
1519
1520 // Verify that the custom keyboard shortcut is still present after save-and-reload
1521 {
1522 uno::Reference<ui::XUIConfigurationManager> xConfigManager = getUIConfigManager();
1523 css::uno::Reference<css::ui::XAcceleratorConfiguration> xAccel
1524 = getUIConfigManager()->getShortCutManager();
1525
1526 CPPUNIT_ASSERT_EQUAL(sCommand, xAccel->getCommandByKeyEvent(aCtrlU));
1527 }
1528 }
1529
CPPUNIT_TEST_FIXTURE(Test,testTdf60700_directories)1530 CPPUNIT_TEST_FIXTURE(Test, testTdf60700_directories)
1531 {
1532 createSwDoc();
1533 save(mpFilter);
1534
1535 // There is no way to read the contents of Configurations2/ from a loaded document,
1536 // because only UIConfigurationManager has a reference to it and there is no method
1537 // to access that reference from outside the class. So, we inspect the zipfile
1538 // directly.
1539
1540 uno::Sequence<uno::Any> aArgs{ uno::Any(maTempFile.GetURL()) };
1541 uno::Reference<container::XNameAccess> xNameAccess(
1542 m_xSFactory->createInstanceWithArguments(u"com.sun.star.packages.zip.ZipFileAccess"_ustr,
1543 aArgs),
1544 uno::UNO_QUERY);
1545 const css::uno::Sequence<OUString> aNames(xNameAccess->getElementNames());
1546
1547 int nMatches = 0;
1548 for (const OUString& sName : aNames)
1549 {
1550 OUString sRest;
1551 if (sName.startsWith("Configurations2/", &sRest) && !sRest.isEmpty())
1552 {
1553 ++nMatches;
1554 }
1555 }
1556
1557 // There should be zero elements within Configurations2/ on a fresh document.
1558 CPPUNIT_ASSERT_EQUAL(0, nMatches);
1559 }
1560
1561
1562 } // end of anonymous namespace
1563 CPPUNIT_PLUGIN_IMPLEMENT();
1564 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1565