nss: upgrade to release 3.73
[LibreOffice.git] / sc / qa / unit / subsequent_export-test.cxx
blob56a84f4624e360c86e3b4c359ae8303aa142fca8
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #include <officecfg/Office/Common.hxx>
11 #include <sal/config.h>
12 #include <config_features.h>
14 #include <sfx2/docfile.hxx>
15 #include <sfx2/sfxmodelfactory.hxx>
16 #include <sfx2/sfxsids.hrc>
17 #include <sfx2/docfilt.hxx>
19 #include "helper/debughelper.hxx"
20 #include "helper/qahelper.hxx"
21 #include "helper/xpath.hxx"
22 #include "helper/shared_test_impl.hxx"
24 #include <userdat.hxx>
25 #include <docsh.hxx>
26 #include <patattr.hxx>
27 #include <docpool.hxx>
28 #include <scitems.hxx>
29 #include <attrib.hxx>
30 #include <stlpool.hxx>
31 #include <document.hxx>
32 #include <formulacell.hxx>
33 #include <tokenarray.hxx>
34 #include <editutil.hxx>
35 #include <scopetools.hxx>
36 #include <cellvalue.hxx>
37 #include <postit.hxx>
38 #include <tokenstringcontext.hxx>
39 #include <chgtrack.hxx>
40 #include <validat.hxx>
41 #include <global.hxx>
42 #include <scmod.hxx>
43 #include <dpcache.hxx>
44 #include <dpobject.hxx>
45 #include <clipparam.hxx>
47 #include <svx/svdpage.hxx>
48 #include <svx/svdograf.hxx>
49 #include <tabprotection.hxx>
50 #include <editeng/wghtitem.hxx>
51 #include <editeng/postitem.hxx>
52 #include <editeng/editdata.hxx>
53 #include <editeng/eeitem.hxx>
54 #include <editeng/editobj.hxx>
55 #include <editeng/section.hxx>
56 #include <editeng/crossedoutitem.hxx>
57 #include <editeng/borderline.hxx>
58 #include <editeng/escapementitem.hxx>
59 #include <editeng/fontitem.hxx>
60 #include <editeng/udlnitem.hxx>
61 #include <editeng/flditem.hxx>
62 #include <editeng/colritem.hxx>
63 #include <formula/grammar.hxx>
64 #include <unotools/useroptions.hxx>
65 #include <comphelper/scopeguard.hxx>
66 #include <unotools/syslocaleoptions.hxx>
67 #include <tools/datetime.hxx>
68 #include <tools/fldunit.hxx>
69 #include <svl/zformat.hxx>
71 #include <test/xmltesttools.hxx>
72 #include <com/sun/star/chart2/XChartDocument.hpp>
73 #include <com/sun/star/chart2/XChartTypeContainer.hpp>
74 #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
75 #include <com/sun/star/drawing/XDrawPage.hpp>
76 #include <com/sun/star/drawing/XDrawPages.hpp>
77 #include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
78 #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
79 #include <com/sun/star/awt/XBitmap.hpp>
80 #include <com/sun/star/frame/Desktop.hpp>
81 #include <com/sun/star/graphic/GraphicType.hpp>
82 #include <com/sun/star/sheet/GlobalSheetSettings.hpp>
84 using namespace ::com::sun::star;
85 using namespace ::com::sun::star::uno;
87 class ScExportTest : public ScBootstrapFixture, public XmlTestTools
89 protected:
90 virtual void registerNamespaces(xmlXPathContextPtr& pXmlXPathCtx) override;
91 public:
92 ScExportTest();
94 virtual void setUp() override;
95 virtual void tearDown() override;
97 void test();
98 void testTdf139167();
99 void testTdf139394();
100 void testExtCondFormatXLSX();
101 void testTdf90104();
102 void testTdf111876();
103 void testPasswordExportODS();
104 void testTdf134332();
105 void testConditionalFormatExportODS();
106 void testConditionalFormatExportXLSX();
107 void testCondFormatExportCellIs();
108 void testTdf99856_dataValidationTest();
109 void testProtectionKeyODS_UTF16LErtlSHA1();
110 void testProtectionKeyODS_UTF8SHA1();
111 void testProtectionKeyODS_UTF8SHA256ODF12();
112 void testProtectionKeyODS_UTF8SHA256W3C();
113 void testProtectionKeyODS_XL_SHA1();
114 void testColorScaleExportODS();
115 void testColorScaleExportXLSX();
116 void testDataBarExportODS();
117 void testDataBarExportXLSX();
118 void testConditionalFormatRangeListXLSX();
119 void testConditionalFormatContainsTextXLSX();
120 void testConditionalFormatPriorityCheckXLSX();
121 void testConditionalFormatOriginXLSX();
122 void testMiscRowHeightExport();
123 void testNamedRangeBugfdo62729();
124 void testBuiltinRangesXLSX();
125 void testRichTextExportODS();
126 void testRichTextCellFormatXLSX();
127 void testFormulaRefSheetNameODS();
129 void testCellValuesExportODS();
130 void testCellNoteExportODS();
131 void testCellNoteExportXLS();
132 void testFormatExportODS();
134 void testCommentExportXLSX();
135 void testCommentExportXLSX_2_XLSX();
136 #if HAVE_MORE_FONTS
137 void testCustomColumnWidthExportXLSX();
138 #endif
139 void testXfDefaultValuesXLSX();
140 void testODF13();
141 void testColumnWidthResaveXLSX();
142 #if HAVE_MORE_FONTS
143 void testColumnWidthExportFromODStoXLSX();
144 #endif
145 void testOutlineExportXLSX();
146 void testHiddenEmptyRowsXLSX();
147 void testAllRowsHiddenXLSX();
148 void testLandscapeOrientationXLSX();
150 void testInlineArrayXLS();
151 void testEmbeddedChartODS();
152 void testEmbeddedChartXLS();
153 void testCellAnchoredGroupXLS();
155 void testFormulaReferenceXLS();
156 void testSheetProtectionXLSX();
157 void testSheetProtectionXLSB();
159 void testCellBordersXLS();
160 void testCellBordersXLSX();
161 void testBordersExchangeXLSX();
162 void testTrackChangesSimpleXLSX();
163 void testSheetTabColorsXLSX();
165 void testSharedFormulaExportXLS();
166 void testSharedFormulaExportXLSX();
167 void testSharedFormulaStringResultExportXLSX();
169 void testFunctionsExcel2010( sal_uLong nFormatType );
170 void testFunctionsExcel2010XLSX();
171 void testFunctionsExcel2010XLS();
172 void testFunctionsExcel2010ODS();
174 void testCeilingFloor( sal_uLong nFormatType );
175 void testCeilingFloorXLSX();
176 void testCeilingFloorODSToXLSX();
177 void testCeilingFloorXLS();
178 void testCeilingFloorODS();
180 void testCustomXml();
182 void testRelativePathsODS();
183 void testSheetProtectionODS();
185 void testSwappedOutImageExport();
186 void testLinkedGraphicRT();
187 void testImageWithSpecialID();
189 void testSupBookVirtualPathXLS();
190 void testAbsNamedRangeHTML();
191 void testSheetLocalRangeNameXLS();
192 void testRelativeNamedExpressionsXLS();
193 void testSheetTextBoxHyperlinkXLSX();
194 void testFontSizeXLSX();
195 void testSheetCharacterKerningSpaceXLSX();
196 void testSheetCondensedCharacterSpaceXLSX();
197 void testTextUnderlineColorXLSX();
198 void testSheetRunParagraphPropertyXLSX();
199 void testHiddenShapeXLS();
200 void testHiddenShapeXLSX();
201 void testShapeAutofitXLSX();
202 void testHyperlinkXLSX();
203 void testMoveCellAnchoredShapesODS();
204 void testMatrixMultiplicationXLSX();
205 void testPreserveTextWhitespaceXLSX();
206 void testPreserveTextWhitespace2XLSX();
207 void testTextDirectionXLSX();
208 void testTdf66668();
209 void testTdf130108();
210 void testTdf76949();
211 void testTdf55417();
212 void testTdf129985();
213 void testTdf73063();
215 xmlDocUniquePtr testTdf95640(const OUString& rFileName, sal_Int32 nSourceFormat,
216 sal_Int32 nDestFormat);
217 void testTdf95640_ods_to_xlsx();
218 void testTdf95640_ods_to_xlsx_with_standard_list();
219 void testTdf95640_xlsx_to_xlsx();
221 void testRefStringXLSX();
222 void testRefStringConfigXLSX();
223 void testRefStringUnspecified();
224 void testHeaderImageODS();
226 void testTdf88657ODS();
227 void testTdf41722();
228 void testTdf113621();
229 void testEscapeCharInNumberFormatXLSX();
230 void testNatNumInNumberFormatXLSX();
231 void testExponentWithoutSignFormatXLSX();
232 void testExtendedLCIDXLSX();
234 void testHiddenRepeatedRowsODS();
235 void testHyperlinkTargetFrameODS();
236 void testOpenDocumentAsReadOnly();
237 void testKeepSettingsOfBlankRows();
239 void testTdf133595();
240 void testTdf134769();
241 void testTdf106181();
242 void testTdf105272();
243 void testTdf118990();
244 void testTdf121612();
245 void testTdf112936();
246 void testPivotCacheAfterExportXLSX();
247 void testTdf114969XLSX();
248 void testTdf115192XLSX();
249 void testTdf91634XLSX();
250 void testTdf115159();
251 void testTdf112567();
252 void testTdf112567b();
253 void testTdf123645XLSX();
254 void testTdf125173XLSX();
255 void testTdf79972XLSX();
256 void testTdf126024XLSX();
257 void testTdf126177XLSX();
258 void testCommentTextVAlignment();
259 void testCommentTextHAlignment();
260 void testValidationCopyPaste();
262 void testXltxExport();
263 void testRotatedImageODS();
264 void testTdf128976();
265 void testTdf120502();
266 void testTdf131372();
267 void testTdf81470();
268 void testTdf122331();
269 void testTdf83779();
270 void testTdf121716_ExportEvenHeaderFooterXLSX();
271 void testTdf134459_HeaderFooterColorXLSX();
272 void testTdf134817_HeaderFooterTextWith2SectionXLSX();
273 void testTdf121718_UseFirstPageNumberXLSX();
274 void testHeaderFontStyleXLSX();
275 void testTdf135828_Shape_Rect();
276 void testTdf123353();
277 void testTdf133688_precedents();
278 void testTdf91251_missingOverflowRoundtrip();
279 void testTdf137000_handle_upright();
280 void testTdf126305_DataValidatyErrorAlert();
281 void testTdf76047_externalLink();
282 void testTdf87973_externalLinkSkipUnuseds();
283 void testTdf51022_lostPrintRange();
284 void testTdf138741_externalLinkSkipUnusedsCrash();
285 void testTdf138824_linkToParentDirectory();
286 void testTdf129969();
287 void testTdf84874();
288 void testTdf136721_paper_size();
289 void testTdf139258_rotated_image();
290 void testTdf140431();
291 void testTdf142264ManyChartsToXLSX();
293 CPPUNIT_TEST_SUITE(ScExportTest);
294 CPPUNIT_TEST(test);
295 CPPUNIT_TEST(testTdf139167);
296 CPPUNIT_TEST(testTdf139394);
297 CPPUNIT_TEST(testExtCondFormatXLSX);
298 CPPUNIT_TEST(testTdf90104);
299 CPPUNIT_TEST(testTdf111876);
300 CPPUNIT_TEST(testPasswordExportODS);
301 CPPUNIT_TEST(testTdf134332);
302 CPPUNIT_TEST(testConditionalFormatExportODS);
303 CPPUNIT_TEST(testCondFormatExportCellIs);
304 CPPUNIT_TEST(testConditionalFormatExportXLSX);
305 CPPUNIT_TEST(testTdf99856_dataValidationTest);
306 CPPUNIT_TEST(testProtectionKeyODS_UTF16LErtlSHA1);
307 CPPUNIT_TEST(testProtectionKeyODS_UTF8SHA1);
308 CPPUNIT_TEST(testProtectionKeyODS_UTF8SHA256ODF12);
309 CPPUNIT_TEST(testProtectionKeyODS_UTF8SHA256W3C);
310 CPPUNIT_TEST(testProtectionKeyODS_XL_SHA1);
311 CPPUNIT_TEST(testColorScaleExportODS);
312 CPPUNIT_TEST(testColorScaleExportXLSX);
313 CPPUNIT_TEST(testDataBarExportODS);
314 CPPUNIT_TEST(testDataBarExportXLSX);
315 CPPUNIT_TEST(testConditionalFormatRangeListXLSX);
316 CPPUNIT_TEST(testConditionalFormatContainsTextXLSX);
317 CPPUNIT_TEST(testConditionalFormatPriorityCheckXLSX);
318 CPPUNIT_TEST(testConditionalFormatOriginXLSX);
319 CPPUNIT_TEST(testMiscRowHeightExport);
320 CPPUNIT_TEST(testNamedRangeBugfdo62729);
321 CPPUNIT_TEST(testBuiltinRangesXLSX);
322 CPPUNIT_TEST(testRichTextExportODS);
323 CPPUNIT_TEST(testRichTextCellFormatXLSX);
324 CPPUNIT_TEST(testFormulaRefSheetNameODS);
325 CPPUNIT_TEST(testCellValuesExportODS);
326 CPPUNIT_TEST(testCellNoteExportODS);
327 CPPUNIT_TEST(testCellNoteExportXLS);
328 CPPUNIT_TEST(testFormatExportODS);
329 CPPUNIT_TEST(testCommentExportXLSX);
330 CPPUNIT_TEST(testCommentExportXLSX_2_XLSX);
331 #if HAVE_MORE_FONTS
332 CPPUNIT_TEST(testCustomColumnWidthExportXLSX);
333 #endif
334 CPPUNIT_TEST(testXfDefaultValuesXLSX);
335 CPPUNIT_TEST(testODF13);
336 CPPUNIT_TEST(testColumnWidthResaveXLSX);
337 #if HAVE_MORE_FONTS
338 CPPUNIT_TEST(testColumnWidthExportFromODStoXLSX);
339 #endif
340 CPPUNIT_TEST(testOutlineExportXLSX);
341 CPPUNIT_TEST(testHiddenEmptyRowsXLSX);
342 CPPUNIT_TEST(testAllRowsHiddenXLSX);
343 CPPUNIT_TEST(testLandscapeOrientationXLSX);
344 CPPUNIT_TEST(testInlineArrayXLS);
345 CPPUNIT_TEST(testEmbeddedChartODS);
346 CPPUNIT_TEST(testEmbeddedChartXLS);
347 CPPUNIT_TEST(testCellAnchoredGroupXLS);
349 CPPUNIT_TEST(testFormulaReferenceXLS);
350 CPPUNIT_TEST(testSheetProtectionXLSX);
351 CPPUNIT_TEST(testSheetProtectionXLSB);
352 CPPUNIT_TEST(testCellBordersXLS);
353 CPPUNIT_TEST(testCellBordersXLSX);
354 CPPUNIT_TEST(testBordersExchangeXLSX);
355 CPPUNIT_TEST(testTrackChangesSimpleXLSX);
356 CPPUNIT_TEST(testSheetTabColorsXLSX);
357 CPPUNIT_TEST(testSharedFormulaExportXLS);
358 CPPUNIT_TEST(testSharedFormulaExportXLSX);
359 CPPUNIT_TEST(testSharedFormulaStringResultExportXLSX);
360 CPPUNIT_TEST(testFunctionsExcel2010XLSX);
361 CPPUNIT_TEST(testFunctionsExcel2010XLS);
362 CPPUNIT_TEST(testFunctionsExcel2010ODS);
363 CPPUNIT_TEST(testCeilingFloorXLSX);
364 CPPUNIT_TEST(testCeilingFloorODSToXLSX);
365 CPPUNIT_TEST(testCeilingFloorXLS);
366 CPPUNIT_TEST(testCeilingFloorODS);
367 CPPUNIT_TEST(testCustomXml);
368 CPPUNIT_TEST(testRelativePathsODS);
369 CPPUNIT_TEST(testSheetProtectionODS);
370 CPPUNIT_TEST(testSupBookVirtualPathXLS);
371 CPPUNIT_TEST(testSwappedOutImageExport);
372 CPPUNIT_TEST(testLinkedGraphicRT);
373 CPPUNIT_TEST(testImageWithSpecialID);
374 CPPUNIT_TEST(testPreserveTextWhitespaceXLSX);
375 CPPUNIT_TEST(testPreserveTextWhitespace2XLSX);
376 CPPUNIT_TEST(testAbsNamedRangeHTML);
377 CPPUNIT_TEST(testSheetLocalRangeNameXLS);
378 CPPUNIT_TEST(testRelativeNamedExpressionsXLS);
379 CPPUNIT_TEST(testSheetTextBoxHyperlinkXLSX);
380 CPPUNIT_TEST(testFontSizeXLSX);
381 CPPUNIT_TEST(testSheetCharacterKerningSpaceXLSX);
382 CPPUNIT_TEST(testSheetCondensedCharacterSpaceXLSX);
383 CPPUNIT_TEST(testTextUnderlineColorXLSX);
384 CPPUNIT_TEST(testSheetRunParagraphPropertyXLSX);
385 CPPUNIT_TEST(testHiddenShapeXLS);
386 CPPUNIT_TEST(testHiddenShapeXLSX);
387 CPPUNIT_TEST(testShapeAutofitXLSX);
388 CPPUNIT_TEST(testHyperlinkXLSX);
389 CPPUNIT_TEST(testMoveCellAnchoredShapesODS);
390 CPPUNIT_TEST(testMatrixMultiplicationXLSX);
391 CPPUNIT_TEST(testTextDirectionXLSX);
392 CPPUNIT_TEST(testTdf66668);
393 CPPUNIT_TEST(testTdf130108);
394 CPPUNIT_TEST(testTdf76949);
395 CPPUNIT_TEST(testTdf55417);
396 CPPUNIT_TEST(testTdf129985);
397 CPPUNIT_TEST(testTdf73063);
398 CPPUNIT_TEST(testTdf95640_ods_to_xlsx);
399 CPPUNIT_TEST(testTdf95640_ods_to_xlsx_with_standard_list);
400 CPPUNIT_TEST(testTdf95640_xlsx_to_xlsx);
402 CPPUNIT_TEST(testRefStringXLSX);
403 CPPUNIT_TEST(testRefStringConfigXLSX);
404 CPPUNIT_TEST(testRefStringUnspecified);
405 CPPUNIT_TEST(testHeaderImageODS);
407 CPPUNIT_TEST(testTdf88657ODS);
408 CPPUNIT_TEST(testTdf41722);
409 CPPUNIT_TEST(testTdf113621);
410 CPPUNIT_TEST(testEscapeCharInNumberFormatXLSX);
411 CPPUNIT_TEST(testNatNumInNumberFormatXLSX);
412 CPPUNIT_TEST(testExponentWithoutSignFormatXLSX);
413 CPPUNIT_TEST(testExtendedLCIDXLSX);
415 CPPUNIT_TEST(testHiddenRepeatedRowsODS);
416 CPPUNIT_TEST(testHyperlinkTargetFrameODS);
417 CPPUNIT_TEST(testOpenDocumentAsReadOnly);
418 CPPUNIT_TEST(testKeepSettingsOfBlankRows);
420 CPPUNIT_TEST(testTdf133595);
421 CPPUNIT_TEST(testTdf134769);
422 CPPUNIT_TEST(testTdf106181);
423 CPPUNIT_TEST(testTdf105272);
424 CPPUNIT_TEST(testTdf118990);
425 CPPUNIT_TEST(testTdf121612);
426 CPPUNIT_TEST(testTdf112936);
427 CPPUNIT_TEST(testPivotCacheAfterExportXLSX);
428 CPPUNIT_TEST(testTdf114969XLSX);
429 CPPUNIT_TEST(testTdf115192XLSX);
430 CPPUNIT_TEST(testTdf91634XLSX);
431 CPPUNIT_TEST(testTdf115159);
432 CPPUNIT_TEST(testTdf112567);
433 CPPUNIT_TEST(testTdf112567b);
434 CPPUNIT_TEST(testTdf123645XLSX);
435 CPPUNIT_TEST(testTdf125173XLSX);
436 CPPUNIT_TEST(testTdf79972XLSX);
437 CPPUNIT_TEST(testTdf126024XLSX);
438 CPPUNIT_TEST(testTdf126177XLSX);
439 CPPUNIT_TEST(testCommentTextVAlignment);
440 CPPUNIT_TEST(testCommentTextHAlignment);
441 CPPUNIT_TEST(testValidationCopyPaste);
443 CPPUNIT_TEST(testXltxExport);
444 CPPUNIT_TEST(testRotatedImageODS);
445 CPPUNIT_TEST(testTdf128976);
446 CPPUNIT_TEST(testTdf120502);
447 CPPUNIT_TEST(testTdf131372);
448 CPPUNIT_TEST(testTdf81470);
449 CPPUNIT_TEST(testTdf122331);
450 CPPUNIT_TEST(testTdf83779);
451 CPPUNIT_TEST(testTdf121716_ExportEvenHeaderFooterXLSX);
452 CPPUNIT_TEST(testTdf134459_HeaderFooterColorXLSX);
453 CPPUNIT_TEST(testTdf134817_HeaderFooterTextWith2SectionXLSX);
454 CPPUNIT_TEST(testTdf121718_UseFirstPageNumberXLSX);
455 CPPUNIT_TEST(testHeaderFontStyleXLSX);
456 CPPUNIT_TEST(testTdf135828_Shape_Rect);
457 CPPUNIT_TEST(testTdf123353);
458 CPPUNIT_TEST(testTdf133688_precedents);
459 CPPUNIT_TEST(testTdf91251_missingOverflowRoundtrip);
460 CPPUNIT_TEST(testTdf137000_handle_upright);
461 CPPUNIT_TEST(testTdf126305_DataValidatyErrorAlert);
462 CPPUNIT_TEST(testTdf76047_externalLink);
463 CPPUNIT_TEST(testTdf87973_externalLinkSkipUnuseds);
464 CPPUNIT_TEST(testTdf51022_lostPrintRange);
465 CPPUNIT_TEST(testTdf138741_externalLinkSkipUnusedsCrash);
466 CPPUNIT_TEST(testTdf138824_linkToParentDirectory);
467 CPPUNIT_TEST(testTdf129969);
468 CPPUNIT_TEST(testTdf84874);
469 CPPUNIT_TEST(testTdf136721_paper_size);
470 CPPUNIT_TEST(testTdf139258_rotated_image);
471 CPPUNIT_TEST(testTdf140431);
472 CPPUNIT_TEST(testTdf142264ManyChartsToXLSX);
474 CPPUNIT_TEST_SUITE_END();
476 private:
477 void testExcelCellBorders( sal_uLong nFormatType );
479 uno::Reference<uno::XInterface> m_xCalcComponent;
483 void ScExportTest::registerNamespaces(xmlXPathContextPtr& pXmlXPathCtx)
485 static const struct { xmlChar* pPrefix; xmlChar* pURI; } aNamespaces[] =
487 { BAD_CAST("w"), BAD_CAST("http://schemas.openxmlformats.org/wordprocessingml/2006/main") },
488 { BAD_CAST("x"), BAD_CAST("http://schemas.openxmlformats.org/spreadsheetml/2006/main") },
489 { BAD_CAST("v"), BAD_CAST("urn:schemas-microsoft-com:vml") },
490 { BAD_CAST("c"), BAD_CAST("http://schemas.openxmlformats.org/drawingml/2006/chart") },
491 { BAD_CAST("a"), BAD_CAST("http://schemas.openxmlformats.org/drawingml/2006/main") },
492 { BAD_CAST("mc"), BAD_CAST("http://schemas.openxmlformats.org/markup-compatibility/2006") },
493 { BAD_CAST("wps"), BAD_CAST("http://schemas.microsoft.com/office/word/2010/wordprocessingShape") },
494 { BAD_CAST("wpg"), BAD_CAST("http://schemas.microsoft.com/office/word/2010/wordprocessingGroup") },
495 { BAD_CAST("wp"), BAD_CAST("http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing") },
496 { BAD_CAST("office"), BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:office:1.0") },
497 { BAD_CAST("table"), BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:table:1.0") },
498 { BAD_CAST("text"), BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:text:1.0") },
499 { BAD_CAST("style"), BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:style:1.0") },
500 { BAD_CAST("draw"), BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:drawing:1.0") },
501 { BAD_CAST("xlink"), BAD_CAST("http://www.w3c.org/1999/xlink") },
502 { BAD_CAST("xdr"), BAD_CAST("http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing") },
503 { BAD_CAST("xx"), BAD_CAST("urn:schemas-microsoft-com:office:excel") },
504 { BAD_CAST("r"), BAD_CAST("http://schemas.openxmlformats.org/package/2006/relationships") },
505 { BAD_CAST("number"), BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0") },
506 { BAD_CAST("loext"), BAD_CAST("urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0") },
507 { BAD_CAST("tableooo"), BAD_CAST("http://openoffice.org/2009/table") },
508 { BAD_CAST("ContentType"), BAD_CAST("http://schemas.openxmlformats.org/package/2006/content-types") },
509 { BAD_CAST("x14"), BAD_CAST("http://schemas.microsoft.com/office/spreadsheetml/2009/9/main") },
510 { BAD_CAST("xm"), BAD_CAST("http://schemas.microsoft.com/office/excel/2006/main") },
511 { BAD_CAST("x12ac"), BAD_CAST("http://schemas.microsoft.com/office/spreadsheetml/2011/1/ac") },
513 for(size_t i = 0; i < SAL_N_ELEMENTS(aNamespaces); ++i)
515 xmlXPathRegisterNs(pXmlXPathCtx, aNamespaces[i].pPrefix, aNamespaces[i].pURI );
519 void ScExportTest::test()
521 ScDocShell* pShell = new ScDocShell(
522 SfxModelFlags::EMBEDDED_OBJECT |
523 SfxModelFlags::DISABLE_EMBEDDED_SCRIPTS |
524 SfxModelFlags::DISABLE_DOCUMENT_RECOVERY);
525 pShell->DoInitNew();
527 ScDocument& rDoc = pShell->GetDocument();
529 rDoc.SetValue(0,0,0, 1.0);
531 ScDocShellRef xDocSh = saveAndReload(pShell, FORMAT_ODS);
533 CPPUNIT_ASSERT(xDocSh.is());
534 ScDocument& rLoadedDoc = xDocSh->GetDocument();
535 double aVal = rLoadedDoc.GetValue(0,0,0);
536 ASSERT_DOUBLES_EQUAL(aVal, 1.0);
537 xDocSh->DoClose();
540 void ScExportTest::testTdf139167()
542 ScDocShellRef xShell = loadDoc(u"tdf139167.", FORMAT_XLSX);
543 CPPUNIT_ASSERT(xShell.is());
545 ScDocShellRef xDocSh = saveAndReload(&(*xShell), FORMAT_XLSX);
546 CPPUNIT_ASSERT(xDocSh.is());
548 std::shared_ptr<utl::TempFile> pXPathFile = ScBootstrapFixture::exportTo(&(*xDocSh), FORMAT_XLSX);
549 xmlDocUniquePtr pDoc = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/styles.xml");
550 CPPUNIT_ASSERT(pDoc);
552 assertXPath(pDoc, "/x:styleSheet/x:cellStyles", "count", "6");
553 assertXPath(pDoc, "/x:styleSheet/x:dxfs/x:dxf/x:fill/x:patternFill/x:bgColor", "rgb",
554 "FFFFFF00");
556 xDocSh->DoClose();
559 void ScExportTest::testTdf139394()
561 ScDocShellRef xShell = loadDoc(u"tdf139394.", FORMAT_XLSX);
562 CPPUNIT_ASSERT(xShell.is());
564 ScDocShellRef xDocSh = saveAndReload(&(*xShell), FORMAT_XLSX);
565 CPPUNIT_ASSERT(xDocSh.is());
567 std::shared_ptr<utl::TempFile> pXPathFile = ScBootstrapFixture::exportTo(&(*xDocSh), FORMAT_XLSX);
568 xmlDocUniquePtr pDoc = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/worksheets/sheet1.xml");
569 CPPUNIT_ASSERT(pDoc);
571 assertXPathContent(pDoc,
572 "/x:worksheet/x:extLst/x:ext/x14:conditionalFormattings/x14:conditionalFormatting[1]/"
573 "x14:cfRule/xm:f", "LEFT(A1,LEN(\"+\"))=\"+\"");
574 assertXPathContent(pDoc,
575 "/x:worksheet/x:extLst/x:ext/x14:conditionalFormattings/x14:conditionalFormatting[2]/"
576 "x14:cfRule/xm:f", "RIGHT(A2,LEN(\"-\"))=\"-\"");
577 assertXPathContent(pDoc,
578 "/x:worksheet/x:extLst/x:ext/x14:conditionalFormattings/x14:conditionalFormatting[3]/"
579 "x14:cfRule/xm:f", "LEFT(A3,LEN($B$3))=$B$3");
581 xDocSh->DoClose();
584 void ScExportTest::testExtCondFormatXLSX()
586 ScDocShellRef xShell = loadDoc("tdf139021.", FORMAT_XLSX);
587 CPPUNIT_ASSERT(xShell.is());
589 ScDocShellRef xDocSh = saveAndReload(&(*xShell), FORMAT_XLSX);
590 CPPUNIT_ASSERT(xDocSh.is());
592 std::shared_ptr<utl::TempFile> pXPathFile = ScBootstrapFixture::exportTo(&(*xDocSh), FORMAT_XLSX);
593 xmlDocUniquePtr pDoc = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/worksheets/sheet1.xml");
594 CPPUNIT_ASSERT(pDoc);
596 assertXPath(pDoc,
597 "/x:worksheet/x:extLst/x:ext/x14:conditionalFormattings/x14:conditionalFormatting[1]/"
598 "x14:cfRule", "type", "containsText");
599 assertXPathContent(pDoc,
600 "/x:worksheet/x:extLst/x:ext/x14:conditionalFormattings/x14:conditionalFormatting[1]/"
601 "x14:cfRule/xm:f[1]", "NOT(ISERROR(SEARCH($B$1,A1)))");
602 assertXPathContent(pDoc,
603 "/x:worksheet/x:extLst/x:ext/x14:conditionalFormattings/x14:conditionalFormatting[1]/"
604 "x14:cfRule/xm:f[2]", "$B$1");
605 assertXPath(pDoc,
606 "/x:worksheet/x:extLst/x:ext/x14:conditionalFormattings/x14:conditionalFormatting[2]/"
607 "x14:cfRule", "type", "notContainsText");
608 assertXPathContent(pDoc,
609 "/x:worksheet/x:extLst/x:ext/x14:conditionalFormattings/x14:conditionalFormatting[2]/"
610 "x14:cfRule/xm:f[1]", "ISERROR(SEARCH($B$2,A2))");
611 assertXPathContent(pDoc,
612 "/x:worksheet/x:extLst/x:ext/x14:conditionalFormattings/x14:conditionalFormatting[2]/"
613 "x14:cfRule/xm:f[2]", "$B$2");
615 xDocSh->DoClose();
618 void ScExportTest::testTdf90104()
620 ScDocShellRef xShell = loadDoc("tdf90104.", FORMAT_XLSX);
621 CPPUNIT_ASSERT(xShell.is());
623 ScDocShellRef xDocSh = saveAndReload(&(*xShell), FORMAT_XLSX);
624 CPPUNIT_ASSERT(xDocSh.is());
626 std::shared_ptr<utl::TempFile> pXPathFile
627 = ScBootstrapFixture::exportTo(&(*xDocSh), FORMAT_XLSX);
629 xmlDocUniquePtr pDoc
630 = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/worksheets/sheet1.xml");
631 CPPUNIT_ASSERT(pDoc);
633 assertXPathContent(pDoc, "/x:worksheet/x:dataValidations/x:dataValidation/mc:AlternateContent"
634 "/mc:Choice/x12ac:list", "1,\"2,3\",4,\"5,6\"");
635 assertXPathContent(pDoc, "/x:worksheet/x:dataValidations/x:dataValidation/mc:AlternateContent"
636 "/mc:Fallback/x:formula1", "\"1,2,3,4,5,6\"");
639 void ScExportTest::testTdf111876()
641 // Document with relative path hyperlink
643 ScDocShellRef xShell = loadDoc("tdf111876.", FORMAT_XLSX);
644 CPPUNIT_ASSERT(xShell.is());
646 ScDocShellRef xDocSh = saveAndReload(&(*xShell), FORMAT_XLSX);
647 CPPUNIT_ASSERT(xDocSh.is());
649 xmlDocUniquePtr pDoc = XPathHelper::parseExport2(*this, *xDocSh, m_xSFactory, "xl/worksheets/_rels/sheet1.xml.rels", FORMAT_XLSX);
650 CPPUNIT_ASSERT(pDoc);
651 OUString sTarget = getXPath(pDoc, "/r:Relationships/r:Relationship", "Target");
653 // Document is saved to the temporary directory, relative path should be different than original one
654 CPPUNIT_ASSERT(sTarget != "../xls/bug-fixes.xls");
656 xDocSh->DoClose();
659 void ScExportTest::testPasswordExportODS()
661 ScDocShell* pShell = new ScDocShell(
662 SfxModelFlags::EMBEDDED_OBJECT |
663 SfxModelFlags::DISABLE_EMBEDDED_SCRIPTS |
664 SfxModelFlags::DISABLE_DOCUMENT_RECOVERY);
665 pShell->DoInitNew();
667 ScDocument& rDoc = pShell->GetDocument();
669 rDoc.SetValue(0, 0, 0, 1.0);
671 ScDocShellRef xDocSh = saveAndReloadPassword(pShell, FORMAT_ODS);
673 CPPUNIT_ASSERT(xDocSh.is());
674 ScDocument& rLoadedDoc = xDocSh->GetDocument();
675 double aVal = rLoadedDoc.GetValue(0,0,0);
676 ASSERT_DOUBLES_EQUAL(aVal, 1.0);
678 xDocSh->DoClose();
681 void ScExportTest::testTdf134332()
683 ScDocShellRef xShell = loadDoc("tdf134332.", FORMAT_ODS);
684 CPPUNIT_ASSERT(xShell.is());
686 ScDocument& rDoc = xShell->GetDocument();
688 ASSERT_DOUBLES_EQUAL(190.0, rDoc.GetValue(ScAddress(0,0,0)));
690 ASSERT_DOUBLES_EQUAL(238.0, rDoc.GetValue(ScAddress(0,10144,0)));
692 ScDocShellRef xDocSh = saveAndReloadPassword(xShell.get(), FORMAT_ODS);
694 // Without the fixes in place, it would have failed here
695 CPPUNIT_ASSERT(xDocSh.is());
696 ScDocument& rLoadedDoc = xDocSh->GetDocument();
697 ASSERT_DOUBLES_EQUAL(190.0, rLoadedDoc.GetValue(ScAddress(0,0,0)));
699 ASSERT_DOUBLES_EQUAL(238.0, rLoadedDoc.GetValue(ScAddress(0,10144,0)));
701 xDocSh->DoClose();
704 void ScExportTest::testConditionalFormatExportODS()
706 ScDocShellRef xShell = loadDoc("new_cond_format_test_export.", FORMAT_ODS);
707 CPPUNIT_ASSERT(xShell.is());
709 ScDocShellRef xDocSh = saveAndReload(&(*xShell), FORMAT_ODS);
710 CPPUNIT_ASSERT(xDocSh.is());
711 ScDocument& rDoc = xDocSh->GetDocument();
712 OUString aCSVPath;
713 createCSVPath( "new_cond_format_test_export.", aCSVPath );
714 testCondFile(aCSVPath, &rDoc, 0);
716 xDocSh->DoClose();
719 void ScExportTest::testCondFormatExportCellIs()
721 ScDocShellRef xShell = loadDoc("condFormat_cellis.", FORMAT_XLSX);
722 CPPUNIT_ASSERT(xShell.is());
723 ScDocShellRef xDocSh = saveAndReload(&(*xShell), FORMAT_XLSX);
724 CPPUNIT_ASSERT(xDocSh.is());
726 ScDocument& rDoc = xDocSh->GetDocument();
727 CPPUNIT_ASSERT_EQUAL(size_t(1), rDoc.GetCondFormList(0)->size());
729 ScConditionalFormat* pFormat = rDoc.GetCondFormat(0, 0, 0);
730 CPPUNIT_ASSERT(pFormat);
732 const ScFormatEntry* pEntry = pFormat->GetEntry(0);
733 CPPUNIT_ASSERT(pEntry);
734 CPPUNIT_ASSERT_EQUAL(ScFormatEntry::Type::ExtCondition, pEntry->GetType());
736 const ScCondFormatEntry* pCondition = static_cast<const ScCondFormatEntry*>(pEntry);
737 CPPUNIT_ASSERT_EQUAL( ScConditionMode::Equal, pCondition->GetOperation());
739 OUString aStr = pCondition->GetExpression(ScAddress(0, 0, 0), 0);
740 CPPUNIT_ASSERT_EQUAL( OUString("$Sheet2.$A$2"), aStr );
742 pEntry = pFormat->GetEntry(1);
743 CPPUNIT_ASSERT(pEntry);
744 CPPUNIT_ASSERT_EQUAL(ScFormatEntry::Type::ExtCondition, pEntry->GetType());
746 pCondition = static_cast<const ScCondFormatEntry*>(pEntry);
747 CPPUNIT_ASSERT_EQUAL( ScConditionMode::Equal, pCondition->GetOperation());
749 aStr = pCondition->GetExpression(ScAddress(0, 0, 0), 0);
750 CPPUNIT_ASSERT_EQUAL( OUString("$Sheet2.$A$1"), aStr );
752 xDocSh->DoClose();
755 void ScExportTest::testConditionalFormatExportXLSX()
757 ScDocShellRef xShell = loadDoc("new_cond_format_test_export.", FORMAT_XLSX);
758 CPPUNIT_ASSERT(xShell.is());
760 ScDocShellRef xDocSh = saveAndReload(&(*xShell), FORMAT_XLSX);
761 CPPUNIT_ASSERT(xDocSh.is());
762 ScDocument& rDoc = xDocSh->GetDocument();
764 OUString aCSVPath;
765 createCSVPath( "new_cond_format_test_export.", aCSVPath );
766 testCondFile(aCSVPath, &rDoc, 0);
769 OUString aCSVPath;
770 createCSVPath( "new_cond_format_test_sheet2.", aCSVPath );
771 testCondFile(aCSVPath, &rDoc, 1);
774 xDocSh->DoClose();
777 void ScExportTest::testTdf99856_dataValidationTest()
779 ScDocShellRef xShell = loadDoc("tdf99856_dataValidationTest.", FORMAT_ODS);
780 CPPUNIT_ASSERT_MESSAGE("Failed to load doc", xShell.is());
782 ScDocShellRef xDocSh = saveAndReload( xShell.get(), FORMAT_XLSX);
783 CPPUNIT_ASSERT_MESSAGE("Failed to reload doc", xDocSh.is());
785 ScDocument& rDoc = xDocSh->GetDocument();
786 const ScValidationData* pData = rDoc.GetValidationEntry(2);
787 CPPUNIT_ASSERT(pData);
789 // Excel can't open corrupt file if the list is longer than 255 characters
790 std::vector<ScTypedStrData> aList;
791 pData->FillSelectionList(aList, ScAddress(0, 1, 1));
792 CPPUNIT_ASSERT_EQUAL(size_t(18), aList.size());
793 CPPUNIT_ASSERT_EQUAL(OUString("18 Missis"), aList[17].GetString());
795 xDocSh->DoClose();
798 void ScExportTest::testProtectionKeyODS_UTF16LErtlSHA1()
800 OUString const password("1012345678901234567890123456789012345678901234567890");
802 ScDocShellRef xShell = loadDoc("protection-key1.", FORMAT_FODS);
803 CPPUNIT_ASSERT_MESSAGE("Failed to load doc", xShell.is());
805 ScDocument& rDoc = xShell->GetDocument();
806 ScDocProtection *const pDocProt(rDoc.GetDocProtection());
807 CPPUNIT_ASSERT(pDocProt->verifyPassword(password));
808 ScTableProtection *const pTabProt(rDoc.GetTabProtection(0));
809 CPPUNIT_ASSERT(pTabProt->verifyPassword(password));
811 // we can't assume that the user entered the password; check that we
812 // round-trip the password as-is
813 std::shared_ptr<utl::TempFile> pXPathFile = ScBootstrapFixture::exportTo(&(*xShell), FORMAT_ODS);
814 xmlDocUniquePtr pXmlDoc = XPathHelper::parseExport(pXPathFile, m_xSFactory, "content.xml");
815 assertXPath(pXmlDoc, "//office:spreadsheet[@table:structure-protected='true' and @table:protection-key='vbnhxyBKtPHCA1wB21zG1Oha8ZA=' and @table:protection-key-digest-algorithm='http://www.w3.org/2000/09/xmldsig#sha1']");
816 assertXPath(pXmlDoc, "//table:table[@table:protected='true' and @table:protection-key='vbnhxyBKtPHCA1wB21zG1Oha8ZA=' and @table:protection-key-digest-algorithm='http://www.w3.org/2000/09/xmldsig#sha1']");
818 xShell->DoClose();
821 void ScExportTest::testProtectionKeyODS_UTF8SHA1()
823 OUString const password("1012345678901234567890123456789012345678901234567890");
825 ScDocShellRef xShell = loadDoc("protection-key2.", FORMAT_FODS);
826 CPPUNIT_ASSERT_MESSAGE("Failed to load doc", xShell.is());
828 ScDocument& rDoc = xShell->GetDocument();
829 ScDocProtection *const pDocProt(rDoc.GetDocProtection());
830 CPPUNIT_ASSERT(pDocProt->verifyPassword(password));
831 ScTableProtection *const pTabProt(rDoc.GetTabProtection(0));
832 CPPUNIT_ASSERT(pTabProt->verifyPassword(password));
834 // we can't assume that the user entered the password; check that we
835 // round-trip the password as-is
836 std::shared_ptr<utl::TempFile> pXPathFile = ScBootstrapFixture::exportTo(&(*xShell), FORMAT_ODS);
837 xmlDocUniquePtr pXmlDoc = XPathHelper::parseExport(pXPathFile, m_xSFactory, "content.xml");
838 assertXPath(pXmlDoc, "//office:spreadsheet[@table:structure-protected='true' and @table:protection-key='nLHas0RIwepGDaH4c2hpyIUvIS8=' and @table:protection-key-digest-algorithm='http://www.w3.org/2000/09/xmldsig#sha1']");
839 assertXPath(pXmlDoc, "//table:table[@table:protected='true' and @table:protection-key='nLHas0RIwepGDaH4c2hpyIUvIS8=' and @table:protection-key-digest-algorithm='http://www.w3.org/2000/09/xmldsig#sha1']");
841 xShell->DoClose();
844 void ScExportTest::testProtectionKeyODS_UTF8SHA256ODF12()
846 OUString const password("1012345678901234567890123456789012345678901234567890");
848 ScDocShellRef xShell = loadDoc("protection-key3.", FORMAT_FODS);
849 CPPUNIT_ASSERT_MESSAGE("Failed to load doc", xShell.is());
851 ScDocument& rDoc = xShell->GetDocument();
852 ScDocProtection *const pDocProt(rDoc.GetDocProtection());
853 CPPUNIT_ASSERT(pDocProt->verifyPassword(password));
854 ScTableProtection *const pTabProt(rDoc.GetTabProtection(0));
855 CPPUNIT_ASSERT(pTabProt->verifyPassword(password));
857 // we can't assume that the user entered the password; check that we
858 // round-trip the password as-is
859 std::shared_ptr<utl::TempFile> pXPathFile = ScBootstrapFixture::exportTo(&(*xShell), FORMAT_ODS);
860 xmlDocUniquePtr pXmlDoc = XPathHelper::parseExport(pXPathFile, m_xSFactory, "content.xml");
861 assertXPath(pXmlDoc, "//office:spreadsheet[@table:structure-protected='true' and @table:protection-key='1tnJohagR2T0yF/v69hLPuumSTsj32CumW97nkKGuSQ=' and @table:protection-key-digest-algorithm='http://www.w3.org/2000/09/xmldsig#sha256']");
862 assertXPath(pXmlDoc, "//table:table[@table:protected='true' and @table:protection-key='1tnJohagR2T0yF/v69hLPuumSTsj32CumW97nkKGuSQ=' and @table:protection-key-digest-algorithm='http://www.w3.org/2000/09/xmldsig#sha256']");
864 xShell->DoClose();
867 void ScExportTest::testProtectionKeyODS_UTF8SHA256W3C()
869 OUString const password("1012345678901234567890123456789012345678901234567890");
871 ScDocShellRef xShell = loadDoc("protection-key4.", FORMAT_FODS);
872 CPPUNIT_ASSERT_MESSAGE("Failed to load doc", xShell.is());
874 ScDocument& rDoc = xShell->GetDocument();
875 ScDocProtection *const pDocProt(rDoc.GetDocProtection());
876 CPPUNIT_ASSERT(pDocProt->verifyPassword(password));
877 ScTableProtection *const pTabProt(rDoc.GetTabProtection(0));
878 CPPUNIT_ASSERT(pTabProt->verifyPassword(password));
880 // we can't assume that the user entered the password; check that we
881 // round-trip the password as-is
882 std::shared_ptr<utl::TempFile> pXPathFile = ScBootstrapFixture::exportTo(&(*xShell), FORMAT_ODS);
883 xmlDocUniquePtr pXmlDoc = XPathHelper::parseExport(pXPathFile, m_xSFactory, "content.xml");
884 assertXPath(pXmlDoc, "//office:spreadsheet[@table:structure-protected='true' and @table:protection-key='1tnJohagR2T0yF/v69hLPuumSTsj32CumW97nkKGuSQ=' and @table:protection-key-digest-algorithm='http://www.w3.org/2000/09/xmldsig#sha256']");
885 assertXPath(pXmlDoc, "//table:table[@table:protected='true' and @table:protection-key='1tnJohagR2T0yF/v69hLPuumSTsj32CumW97nkKGuSQ=' and @table:protection-key-digest-algorithm='http://www.w3.org/2000/09/xmldsig#sha256']");
887 xShell->DoClose();
890 void ScExportTest::testProtectionKeyODS_XL_SHA1()
892 OUString const password("1012345678901234567890123456789012345678901234567890");
894 ScDocShellRef xShell = loadDoc("protection-key5.", FORMAT_FODS);
895 CPPUNIT_ASSERT_MESSAGE("Failed to load doc", xShell.is());
897 ScDocument& rDoc = xShell->GetDocument();
898 ScDocProtection *const pDocProt(rDoc.GetDocProtection());
899 CPPUNIT_ASSERT(pDocProt->verifyPassword(password));
900 ScTableProtection *const pTabProt(rDoc.GetTabProtection(0));
901 CPPUNIT_ASSERT(pTabProt->verifyPassword(password));
903 // we can't assume that the user entered the password; check that we
904 // round-trip the password as-is
905 std::shared_ptr<utl::TempFile> pXPathFile = ScBootstrapFixture::exportTo(&(*xShell), FORMAT_ODS);
906 xmlDocUniquePtr pXmlDoc = XPathHelper::parseExport(pXPathFile, m_xSFactory, "content.xml");
907 assertXPath(pXmlDoc, "//office:spreadsheet[@table:structure-protected='true' and @table:protection-key='OX3WkEe79fv1PE+FUmfOLdwVoqI=' and @table:protection-key-digest-algorithm='http://docs.oasis-open.org/office/ns/table/legacy-hash-excel' and @loext:protection-key-digest-algorithm-2='http://www.w3.org/2000/09/xmldsig#sha1']");
908 assertXPath(pXmlDoc, "//table:table[@table:protected='true' and @table:protection-key='OX3WkEe79fv1PE+FUmfOLdwVoqI=' and @table:protection-key-digest-algorithm='http://docs.oasis-open.org/office/ns/table/legacy-hash-excel' and @loext:protection-key-digest-algorithm-2='http://www.w3.org/2000/09/xmldsig#sha1']");
910 xShell->DoClose();
913 void ScExportTest::testColorScaleExportODS()
915 ScDocShellRef xShell = loadDoc("colorscale.", FORMAT_ODS);
916 CPPUNIT_ASSERT(xShell.is());
918 ScDocShellRef xDocSh = saveAndReload(xShell.get(), FORMAT_ODS);
919 CPPUNIT_ASSERT(xDocSh.is());
921 ScDocument& rDoc = xDocSh->GetDocument();
923 testColorScale2Entry_Impl(rDoc);
924 testColorScale3Entry_Impl(rDoc);
926 xDocSh->DoClose();
929 void ScExportTest::testColorScaleExportXLSX()
931 ScDocShellRef xShell = loadDoc("colorscale.", FORMAT_XLSX);
932 CPPUNIT_ASSERT(xShell.is());
934 ScDocShellRef xDocSh = saveAndReload(xShell.get(), FORMAT_XLSX);
935 CPPUNIT_ASSERT(xDocSh.is());
937 ScDocument& rDoc = xDocSh->GetDocument();
939 testColorScale2Entry_Impl(rDoc);
940 testColorScale3Entry_Impl(rDoc);
942 xDocSh->DoClose();
945 void ScExportTest::testDataBarExportODS()
947 ScDocShellRef xShell = loadDoc("databar.", FORMAT_ODS);
948 CPPUNIT_ASSERT(xShell.is());
950 ScDocShellRef xDocSh = saveAndReload(xShell.get(), FORMAT_ODS);
951 CPPUNIT_ASSERT(xDocSh.is());
953 ScDocument& rDoc = xDocSh->GetDocument();
955 testDataBar_Impl(rDoc);
957 xDocSh->DoClose();
960 void ScExportTest::testFormatExportODS()
962 ScDocShellRef xShell = loadDoc("formats.", FORMAT_ODS);
963 CPPUNIT_ASSERT(xShell.is());
965 ScDocShellRef xDocSh = saveAndReload(xShell.get(), FORMAT_ODS);
966 CPPUNIT_ASSERT(xDocSh.is());
968 ScDocument& rDoc = xDocSh->GetDocument();
970 testFormats(this, &rDoc, FORMAT_ODS);
972 xDocSh->DoClose();
975 void ScExportTest::testCommentExportXLSX()
977 //tdf#104729 FILESAVE OpenOffice do not save author of the comment during export to .xlsx
978 ScDocShellRef xShell = loadDoc("comment.", FORMAT_ODS);
979 CPPUNIT_ASSERT(xShell.is());
981 std::shared_ptr<utl::TempFile> pXPathFile
982 = ScBootstrapFixture::exportTo(&(*xShell), FORMAT_XLSX);
983 xmlDocUniquePtr pComments
984 = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/comments1.xml");
985 CPPUNIT_ASSERT(pComments);
987 assertXPathContent(pComments, "/x:comments/x:authors/x:author[1]", "BAKO");
988 assertXPath(pComments, "/x:comments/x:authors/x:author", 1);
990 assertXPathContent(pComments, "/x:comments/x:commentList/x:comment/x:text/x:r/x:t",
991 "Komentarz");
993 xmlDocUniquePtr pVmlDrawing
994 = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/drawings/vmlDrawing1.vml");
995 CPPUNIT_ASSERT(pVmlDrawing);
997 //assertXPath(pVmlDrawing, "/xml/v:shapetype", "coordsize", "21600,21600");
998 assertXPath(pVmlDrawing, "/xml/v:shapetype", "spt", "202");
999 assertXPath(pVmlDrawing, "/xml/v:shapetype/v:stroke", "joinstyle", "miter");
1000 const OUString sShapeTypeId = "#" + getXPath(pVmlDrawing, "/xml/v:shapetype", "id");
1002 assertXPath(pVmlDrawing, "/xml/v:shape", "type", sShapeTypeId);
1003 assertXPath(pVmlDrawing, "/xml/v:shape/v:shadow", "color", "black");
1004 assertXPath(pVmlDrawing, "/xml/v:shape/v:shadow", "obscured", "t");
1006 //tdf#117274 fix MSO interoperability with the secret VML shape type id
1007 assertXPath(pVmlDrawing, "/xml/v:shapetype", "id", "_x0000_t202");
1008 assertXPath(pVmlDrawing, "/xml/v:shape", "type", "#_x0000_t202");
1010 xShell->DoClose();
1013 void ScExportTest::testCommentExportXLSX_2_XLSX()
1015 //tdf#117287 FILESAVE XLSX: Comments always disappear after opening the exported XLSX file with Excel
1016 ScDocShellRef xShell = loadDoc("tdf117287_comment.", FORMAT_XLSX);
1017 CPPUNIT_ASSERT(xShell.is());
1020 ScDocument& rDoc = xShell->GetDocument();
1021 ScAddress aPosC9(2, 8, 0);
1022 ScPostIt *pNote = rDoc.GetNote(aPosC9);
1024 CPPUNIT_ASSERT(pNote);
1025 CPPUNIT_ASSERT(!pNote->IsCaptionShown());
1027 pNote->ShowCaption(aPosC9, true);
1029 std::shared_ptr<utl::TempFile> pXPathFile
1030 = ScBootstrapFixture::exportTo(&(*xShell), FORMAT_XLSX);
1031 xmlDocUniquePtr pComments
1032 = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/comments1.xml");
1033 CPPUNIT_ASSERT(pComments);
1035 assertXPathContent(pComments, "/x:comments/x:commentList/x:comment/x:text/x:r/x:t",
1036 "visible comment");
1038 xmlDocUniquePtr pVmlDrawing
1039 = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/drawings/vmlDrawing1.vml");
1040 CPPUNIT_ASSERT(pVmlDrawing);
1042 assertXPath(pVmlDrawing, "/xml/v:shape/x:ClientData/x:Visible", 0);
1044 xShell->DoClose();
1047 #if HAVE_MORE_FONTS
1048 void ScExportTest::testCustomColumnWidthExportXLSX()
1050 //tdf#100946 FILESAVE Excel on macOS ignored column widths in XLSX last saved by LO
1051 ScDocShellRef xShell = loadDoc("custom_column_width.", FORMAT_ODS);
1052 CPPUNIT_ASSERT(xShell.is());
1054 std::shared_ptr<utl::TempFile> pXPathFile = ScBootstrapFixture::exportTo(&(*xShell), FORMAT_XLSX);
1055 xmlDocUniquePtr pSheet = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/worksheets/sheet1.xml");
1056 CPPUNIT_ASSERT(pSheet);
1058 // tdf#124741: check that we export default width, otherwise the skipped columns would have
1059 // wrong width. Previously defaultColWidth attribute was missing
1060 double nDefWidth
1061 = getXPath(pSheet, "/x:worksheet/x:sheetFormatPr", "defaultColWidth").toDouble();
1062 CPPUNIT_ASSERT_DOUBLES_EQUAL(11.53515625, nDefWidth, 0.01);
1064 // First column, has everything default (width in Calc: 1280), skipped
1066 // Second column, has custom width (width in Calc: 1225)
1067 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[1]", "hidden", "false");
1068 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[1]", "outlineLevel", "0");
1069 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[1]", "customWidth", "true");
1070 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[1]", "collapsed", "false");
1071 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[1]", "min", "2");
1072 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[1]", "max", "2");
1074 // Third column, has everything default (width in Calc: 1280), skipped
1076 // Fourth column has custom width. Columns from 4 to 7 are hidden
1077 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[2]", "hidden", "true");
1078 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[2]", "outlineLevel", "0");
1079 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[2]", "customWidth", "true");
1080 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[2]", "collapsed", "false");
1081 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[2]", "min", "4");
1082 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[2]", "max", "4");
1084 // 5th column has custom width. Columns from 4 to 7 are hidden
1085 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[3]", "hidden", "true");
1086 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[3]", "outlineLevel", "0");
1087 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[3]", "customWidth", "true");
1088 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[3]", "collapsed", "false");
1089 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[3]", "min", "5");
1090 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[3]", "max", "5");
1092 // 6th and 7th columns have default width and they are hidden
1093 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[4]", "hidden", "true");
1094 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[4]", "outlineLevel", "0");
1095 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[4]", "customWidth", "false");
1096 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[4]", "collapsed", "false");
1097 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[4]", "min", "6");
1098 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[4]", "max", "7");
1100 // 8th column has everything default - skipped
1102 // 9th column has custom width
1103 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[5]", "hidden", "false");
1104 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[5]", "outlineLevel", "0");
1105 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[5]", "customWidth", "true");
1106 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[5]", "collapsed", "false");
1107 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[5]", "min", "9");
1108 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[5]", "max", "9");
1110 // We expected that exactly 5 unique Nodes will be produced
1111 assertXPath(pSheet, "/x:worksheet/x:cols/x:col", 5);
1113 assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[1]", "hidden", "false");
1114 assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[1]", "outlineLevel", "0");
1115 assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[1]", "collapsed", "false");
1116 assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[1]", "customFormat", "false");
1117 assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[1]", "customHeight", "false");
1119 xShell->DoClose();
1121 #endif
1123 void ScExportTest::testXfDefaultValuesXLSX()
1125 //tdf#70565 FORMATTING: User Defined Custom Formatting is not applied during importing XLSX documents
1126 ScDocShellRef xShell = loadDoc("xf_default_values.", FORMAT_XLSX);
1127 CPPUNIT_ASSERT(xShell.is());
1129 std::shared_ptr<utl::TempFile> pXPathFile = ScBootstrapFixture::exportTo(&(*xShell), FORMAT_XLSX);
1130 xmlDocUniquePtr pSheet = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/styles.xml");
1131 CPPUNIT_ASSERT(pSheet);
1133 // cellStyleXfs don't need xfId, so we need to make sure it is not saved
1134 assertXPathNoAttribute(pSheet, "/x:styleSheet/x:cellStyleXfs/x:xf[1]", "xfId");
1136 // Because numFmtId fontId fillId borderId xfId are not existing during import
1137 // it should be created during export, with values set to "0"
1138 assertXPath(pSheet, "/x:styleSheet/x:cellXfs/x:xf[1]", "xfId", "0");
1139 assertXPath(pSheet, "/x:styleSheet/x:cellXfs/x:xf[2]", "xfId", "0");
1140 assertXPath(pSheet, "/x:styleSheet/x:cellXfs/x:xf[3]", "xfId", "0");
1141 assertXPath(pSheet, "/x:styleSheet/x:cellXfs/x:xf[4]", "xfId", "0");
1143 // We expected that exactly 15 cellXfs:xf Nodes will be produced
1144 assertXPath(pSheet, "/x:styleSheet/x:cellXfs/x:xf", 14);
1146 xShell->DoClose();
1149 namespace {
1151 // TODO where to put this?
1152 class Resetter
1154 private:
1155 std::function<void ()> m_Func;
1157 public:
1158 Resetter(std::function<void ()> const& rFunc)
1159 : m_Func(rFunc)
1162 ~Resetter()
1166 m_Func();
1168 catch (...) // has to be reliable
1170 fprintf(stderr, "resetter failed with exception\n");
1171 abort();
1176 } // namespace
1178 static auto verifySpreadsheet13(char const*const pTestName, ScDocShellRef& pShell) -> void
1180 ScDocument const& rDoc(pShell->GetDocument());
1181 // OFFICE-2173 table:tab-color
1182 CPPUNIT_ASSERT_EQUAL_MESSAGE(pTestName, Color(0xff3838), rDoc.GetTabBgColor(0));
1183 // OFFICE-3857 table:scale-to-X/table:scale-to-Y
1184 OUString styleName = rDoc.GetPageStyle(0);
1185 ScStyleSheetPool * pStylePool = rDoc.GetStyleSheetPool();
1186 SfxStyleSheetBase * pStyleSheet = pStylePool->Find(styleName, SfxStyleFamily::Page);
1187 CPPUNIT_ASSERT_MESSAGE(pTestName, pStyleSheet);
1189 SfxItemSet const& rSet = pStyleSheet->GetItemSet();
1190 ScPageScaleToItem const& rItem(rSet.Get(ATTR_PAGE_SCALETO));
1191 CPPUNIT_ASSERT_EQUAL_MESSAGE(pTestName, sal_uInt16(2), rItem.GetWidth());
1192 CPPUNIT_ASSERT_EQUAL_MESSAGE(pTestName, sal_uInt16(3), rItem.GetHeight());
1195 void ScExportTest::testODF13()
1197 // import
1198 ScDocShellRef pShell = loadDoc("spreadsheet13e.", FORMAT_ODS);
1200 // check model
1201 verifySpreadsheet13("import", pShell);
1203 Resetter _([]() {
1204 std::shared_ptr<comphelper::ConfigurationChanges> pBatch(
1205 comphelper::ConfigurationChanges::create());
1206 officecfg::Office::Common::Save::ODF::DefaultVersion::set(3, pBatch);
1207 return pBatch->commit();
1211 // export ODF 1.3
1212 std::shared_ptr<comphelper::ConfigurationChanges> pBatch(
1213 comphelper::ConfigurationChanges::create());
1214 officecfg::Office::Common::Save::ODF::DefaultVersion::set(10, pBatch);
1215 pBatch->commit();
1217 std::shared_ptr<utl::TempFile> pXPathFile = ScBootstrapFixture::exportTo(&(*pShell), FORMAT_ODS);
1219 // check XML
1220 xmlDocUniquePtr pContentXml = XPathHelper::parseExport(pXPathFile, m_xSFactory, "content.xml");
1221 assertXPath(pContentXml, "/office:document-content/office:automatic-styles/style:style/style:table-properties[@table:tab-color='#ff3838']");
1222 xmlDocUniquePtr pStylesXml = XPathHelper::parseExport(pXPathFile, m_xSFactory, "styles.xml");
1223 assertXPath(pStylesXml, "/office:document-styles/office:automatic-styles/style:page-layout/style:page-layout-properties[@style:scale-to-X='2']");
1224 assertXPath(pStylesXml, "/office:document-styles/office:automatic-styles/style:page-layout/style:page-layout-properties[@style:scale-to-Y='3']");
1226 // reload
1227 pShell = load(pXPathFile->GetURL(), "calc8", OUString(), OUString(), ODS_FORMAT_TYPE, SotClipboardFormatId::STARCALC_8);
1229 // check model
1230 verifySpreadsheet13("1.3 reload", pShell);
1233 // export ODF 1.2 Extended
1234 std::shared_ptr<comphelper::ConfigurationChanges> pBatch(
1235 comphelper::ConfigurationChanges::create());
1236 officecfg::Office::Common::Save::ODF::DefaultVersion::set(9, pBatch);
1237 pBatch->commit();
1239 std::shared_ptr<utl::TempFile> pXPathFile = ScBootstrapFixture::saveAs(&(*pShell), FORMAT_ODS);
1240 pShell->DoClose();
1242 // check XML
1243 xmlDocUniquePtr pContentXml = XPathHelper::parseExport(pXPathFile, m_xSFactory, "content.xml");
1244 assertXPath(pContentXml, "/office:document-content/office:automatic-styles/style:style/style:table-properties[@tableooo:tab-color='#ff3838']");
1245 xmlDocUniquePtr pStylesXml = XPathHelper::parseExport(pXPathFile, m_xSFactory, "styles.xml");
1246 assertXPath(pStylesXml, "/office:document-styles/office:automatic-styles/style:page-layout/style:page-layout-properties[@loext:scale-to-X='2']");
1247 assertXPath(pStylesXml, "/office:document-styles/office:automatic-styles/style:page-layout/style:page-layout-properties[@loext:scale-to-Y='3']");
1249 // reload
1250 pShell = load(pXPathFile->GetURL(), "calc8", OUString(), OUString(), ODS_FORMAT_TYPE, SotClipboardFormatId::STARCALC_8);
1252 // check model
1253 verifySpreadsheet13("1.2 Extended reload", pShell);
1256 // export ODF 1.2
1257 std::shared_ptr<comphelper::ConfigurationChanges> pBatch(
1258 comphelper::ConfigurationChanges::create());
1259 officecfg::Office::Common::Save::ODF::DefaultVersion::set(4, pBatch);
1260 pBatch->commit();
1262 std::shared_ptr<utl::TempFile> pXPathFile = ScBootstrapFixture::saveAs(&(*pShell), FORMAT_ODS);
1263 pShell->DoClose();
1265 // check XML
1266 xmlDocUniquePtr pContentXml = XPathHelper::parseExport(pXPathFile, m_xSFactory, "content.xml");
1267 assertXPathNoAttribute(pContentXml, "/office:document-content/office:automatic-styles/style:style/style:table-properties", "tab-color");
1268 xmlDocUniquePtr pStylesXml = XPathHelper::parseExport(pXPathFile, m_xSFactory, "styles.xml");
1269 assertXPathNoAttribute(pStylesXml, "/office:document-styles/office:automatic-styles/style:page-layout[1]/style:page-layout-properties", "scale-to-X");
1270 assertXPathNoAttribute(pStylesXml, "/office:document-styles/office:automatic-styles/style:page-layout[1]/style:page-layout-properties", "scale-to-Y");
1272 // don't reload - no point
1276 void ScExportTest::testColumnWidthResaveXLSX()
1278 // tdf#91475 FILESAVE: Column width is not preserved in XLSX / after round trip.
1279 // Test if after resave .xlsx file, columns width is identical with previous one
1280 ScDocShellRef xShell = loadDoc("different-column-width-excel2010.", FORMAT_XLSX);
1281 CPPUNIT_ASSERT(xShell.is());
1283 std::shared_ptr<utl::TempFile> pXPathFile = ScBootstrapFixture::exportTo(&(*xShell), FORMAT_XLSX);
1284 xmlDocUniquePtr pSheet = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/worksheets/sheet1.xml");
1285 CPPUNIT_ASSERT(pSheet);
1287 // In original Excel document the width is "24"
1288 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[1]", "width", "24");
1289 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[1]", "customWidth", "true");
1291 // In original Excel document the width is "12"
1292 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[2]", "width", "12");
1293 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[2]", "customWidth", "true");
1295 // In original Excel document the width is "6"
1296 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[3]", "width", "6");
1297 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[3]", "customWidth", "true");
1299 // In original Excel document the width is "1"
1300 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[4]", "width", "1");
1301 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[4]", "customWidth", "true");
1303 // In original Excel document the width is "250"
1304 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[5]", "width", "250");
1305 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[5]", "customWidth", "true");
1307 assertXPath(pSheet, "/x:worksheet/x:cols/x:col", 5);
1309 xShell->DoClose();
1312 #if HAVE_MORE_FONTS
1313 void ScExportTest::testColumnWidthExportFromODStoXLSX()
1315 // tdf#91475 FILESAVE: Column width is not preserved in XLSX / after round trip.
1316 // Test if after export .ods to .xlsx format, displayed columns width
1317 // is identical with previous (.ods) one
1319 ScDocShellRef xShell = loadDoc("different-column-width.", FORMAT_ODS);
1321 CPPUNIT_ASSERT( xShell.is() );
1323 ScDocument& rOdsDoc = xShell->GetDocument();
1325 // Col 1, Tab 0 (Column width 2.00 in)
1326 sal_uInt16 nExpectedColumn0Width = rOdsDoc.GetColWidth(static_cast<SCCOL>(0), static_cast<SCTAB>(0), false);
1327 CPPUNIT_ASSERT_EQUAL( static_cast< sal_uInt16 >( 2880 ), nExpectedColumn0Width );
1329 // Col 2, Tab 0 (Column width 1.00 in)
1330 sal_uInt16 nExpectedColumn1Width = rOdsDoc.GetColWidth(static_cast<SCCOL>(1), static_cast<SCTAB>(0), false);
1331 CPPUNIT_ASSERT_EQUAL( static_cast< sal_uInt16 >( 1440 ), nExpectedColumn1Width );
1333 // Col 3, Tab 0 (Column width 0.50 in)
1334 sal_uInt16 nExpectedColumn2Width = rOdsDoc.GetColWidth(static_cast<SCCOL>(2), static_cast<SCTAB>(0), false);
1335 CPPUNIT_ASSERT_EQUAL( static_cast< sal_uInt16 >( 720 ), nExpectedColumn2Width );
1337 // Col 4, Tab 0 (Column width 0.25 in)
1338 sal_uInt16 nExpectedColumn3Width = rOdsDoc.GetColWidth(static_cast<SCCOL>(3), static_cast<SCTAB>(0), false);
1339 CPPUNIT_ASSERT_EQUAL( static_cast< sal_uInt16 >( 360 ), nExpectedColumn3Width );
1341 // Col 5, Tab 0 (Column width 13.57 in)
1342 sal_uInt16 nExpectedColumn4Width = rOdsDoc.GetColWidth(static_cast<SCCOL>(4), static_cast<SCTAB>(0), false);
1343 CPPUNIT_ASSERT_EQUAL( static_cast< sal_uInt16 >( 19539 ), nExpectedColumn4Width );
1345 // Export to .xlsx and compare column width with the .ods
1346 // We expect that column width from .ods will be exactly the same as imported from .xlsx
1348 ScDocShellRef xXlsxDocSh = saveAndReload( xShell.get(), FORMAT_XLSX );
1349 CPPUNIT_ASSERT( xXlsxDocSh.is() );
1351 ScDocument& rDoc = xXlsxDocSh->GetDocument();
1353 // Col 1, Tab 0
1354 sal_uInt16 nCalcWidth;
1355 nCalcWidth = rDoc.GetColWidth(static_cast<SCCOL>(0), static_cast<SCTAB>(0), false);
1356 CPPUNIT_ASSERT_EQUAL( nExpectedColumn0Width, nCalcWidth );
1358 // Col 2, Tab 0
1359 nCalcWidth = rDoc.GetColWidth(static_cast<SCCOL>(1), static_cast<SCTAB>(0), false);
1360 CPPUNIT_ASSERT_EQUAL( nExpectedColumn1Width, nCalcWidth );
1362 // Col 3, Tab 0
1363 nCalcWidth = rDoc.GetColWidth(static_cast<SCCOL>(2), static_cast<SCTAB>(0), false);
1364 CPPUNIT_ASSERT_EQUAL( nExpectedColumn2Width, nCalcWidth );
1366 // Col 4, Tab 0
1367 nCalcWidth = rDoc.GetColWidth(static_cast<SCCOL>(3), static_cast<SCTAB>(0), false);
1368 CPPUNIT_ASSERT_EQUAL( nExpectedColumn3Width, nCalcWidth );
1370 // Col 5, Tab 0
1371 nCalcWidth = rDoc.GetColWidth(static_cast<SCCOL>(4), static_cast<SCTAB>(0), false);
1372 CPPUNIT_ASSERT_EQUAL( nExpectedColumn4Width, nCalcWidth );
1374 xXlsxDocSh->DoClose();
1376 #endif
1378 void ScExportTest::testOutlineExportXLSX()
1380 //tdf#100347 FILESAVE FILEOPEN after exporting to .xlsx format grouping are lost
1381 //tdf#51524 FILESAVE .xlsx and.xls looses width information for hidden/collapsed grouped columns
1382 ScDocShellRef xShell = loadDoc("outline.", FORMAT_ODS);
1383 CPPUNIT_ASSERT(xShell.is());
1385 std::shared_ptr<utl::TempFile> pXPathFile = ScBootstrapFixture::exportTo(&(*xShell), FORMAT_XLSX);
1386 xmlDocUniquePtr pSheet = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/worksheets/sheet1.xml");
1387 CPPUNIT_ASSERT(pSheet);
1389 // Maximum Outline Row is 4 for this document
1390 assertXPath(pSheet, "/x:worksheet/x:sheetFormatPr", "outlineLevelRow", "4");
1391 // Maximum Outline Column is 4 for this document
1392 assertXPath(pSheet, "/x:worksheet/x:sheetFormatPr", "outlineLevelCol", "4");
1394 // First XML node, creates two columns (from min=1 to max=2)
1395 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[1]", "hidden", "false");
1396 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[1]", "outlineLevel", "1");
1397 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[1]", "collapsed", "false");
1398 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[1]", "min", "1");
1399 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[1]", "max", "2");
1401 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[2]", "hidden", "true");
1402 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[2]", "outlineLevel", "2");
1403 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[2]", "collapsed", "false");
1404 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[2]", "min", "3");
1405 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[2]", "max", "3");
1407 // Column 4 has custom width and it is hidden. We need to make sure that it is created
1408 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[3]", "hidden", "true");
1409 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[3]", "outlineLevel", "2");
1410 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[3]", "collapsed", "false");
1411 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[3]", "min", "4");
1412 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[3]", "max", "4");
1414 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[4]", "hidden", "true");
1415 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[4]", "outlineLevel", "3");
1416 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[4]", "collapsed", "false");
1417 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[4]", "min", "5");
1418 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[4]", "max", "6");
1420 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[5]", "hidden", "true");
1421 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[5]", "outlineLevel", "4");
1422 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[5]", "collapsed", "false");
1423 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[5]", "min", "7");
1424 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[5]", "max", "7");
1426 // Column 8 has custom width and it is hidden. We need to make sure that it is created
1427 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[6]", "hidden", "true");
1428 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[6]", "outlineLevel", "4");
1429 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[6]", "collapsed", "false");
1430 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[6]", "min", "8");
1431 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[6]", "max", "8");
1433 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[7]", "hidden", "true");
1434 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[7]", "outlineLevel", "4");
1435 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[7]", "collapsed", "false");
1436 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[7]", "min", "9");
1437 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[7]", "max", "19");
1439 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[8]", "hidden", "true");
1440 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[8]", "outlineLevel", "3");
1441 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[8]", "collapsed", "true");
1442 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[8]", "min", "20");
1443 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[8]", "max", "20");
1445 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[9]", "hidden", "true");
1446 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[9]", "outlineLevel", "3");
1447 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[9]", "collapsed", "false");
1448 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[9]", "min", "21");
1449 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[9]", "max", "21");
1451 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[10]", "hidden", "true");
1452 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[10]", "outlineLevel", "2");
1453 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[10]", "collapsed", "false");
1454 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[10]", "min", "22");
1455 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[10]", "max", "23");
1457 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[11]", "hidden", "false");
1458 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[11]", "outlineLevel", "1");
1459 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[11]", "collapsed", "true");
1460 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[11]", "min", "24");
1461 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[11]", "max", "24");
1463 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[12]", "hidden", "false");
1464 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[12]", "outlineLevel", "1");
1465 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[12]", "collapsed", "false");
1466 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[12]", "min", "25");
1467 assertXPath(pSheet, "/x:worksheet/x:cols/x:col[12]", "max", "26");
1469 // We expected that exactly 12 unique Nodes will be produced
1470 assertXPath(pSheet, "/x:worksheet/x:cols/x:col", 12);
1472 // First row is empty and default so it is not written into XML file
1473 // so we need to save 29 rows, as it provides information about outLineLevel
1474 assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[1]", "r", "2");
1475 assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[1]", "hidden", "false");
1476 assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[1]", "outlineLevel", "1");
1477 assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[1]", "collapsed", "false");
1478 assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[2]", "r", "3");
1479 assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[2]", "hidden", "false");
1480 assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[2]", "outlineLevel", "2");
1481 assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[2]", "collapsed", "false");
1482 assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[3]", "r", "4");
1483 assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[3]", "hidden", "false");
1484 assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[3]", "outlineLevel", "2");
1485 assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[3]", "collapsed", "false");
1486 assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[4]", "r", "5");
1487 assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[4]", "hidden", "false");
1488 assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[4]", "outlineLevel", "3");
1489 assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[4]", "collapsed", "false");
1490 assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[5]", "r", "6");
1491 assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[5]", "hidden", "false");
1492 assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[5]", "outlineLevel", "3");
1493 assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[5]", "collapsed", "false");
1494 assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[6]", "r", "7");
1495 assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[6]", "hidden", "true");
1496 assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[6]", "outlineLevel", "4");
1497 assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[6]", "collapsed", "false");
1498 assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[7]", "r", "8");
1499 assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[7]", "hidden", "true");
1500 assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[7]", "outlineLevel", "4");
1501 assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[7]", "collapsed", "false");
1502 assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[8]", "r", "9");
1503 assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[8]", "hidden", "true");
1504 assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[8]", "outlineLevel", "4");
1505 assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[8]", "collapsed", "false");
1506 // Next rows are the same as the previous one but it needs to be preserved,
1507 // as they contain information about outlineLevel
1508 assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[20]", "r", "21");
1509 assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[20]", "hidden", "true");
1510 assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[20]", "outlineLevel", "4");
1511 assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[20]", "collapsed", "false");
1512 assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[21]", "r", "22");
1513 assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[21]", "hidden", "false");
1514 assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[21]", "outlineLevel", "3");
1515 assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[21]", "collapsed", "true");
1516 assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[22]", "r", "23");
1517 assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[22]", "hidden", "false");
1518 assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[22]", "outlineLevel", "3");
1519 assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[22]", "collapsed", "false");
1521 // We expected that exactly 29 Row Nodes will be produced
1522 assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row", 29);
1524 xShell->DoClose();
1527 void ScExportTest::testAllRowsHiddenXLSX()
1529 ScDocShellRef xOrigDocSh = loadDoc("tdf105840_allRowsHidden.", FORMAT_XLSX);
1530 CPPUNIT_ASSERT(xOrigDocSh.is());
1532 std::shared_ptr<utl::TempFile> pXPathFile = ScBootstrapFixture::exportTo(&(*xOrigDocSh), FORMAT_XLSX);
1533 xmlDocUniquePtr pSheet = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/worksheets/sheet1.xml");
1534 CPPUNIT_ASSERT(pSheet);
1535 assertXPath(pSheet, "/x:worksheet/x:sheetFormatPr", "zeroHeight", "true" );
1536 assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row", 0);
1538 xOrigDocSh->DoClose();
1541 void ScExportTest::testHiddenEmptyRowsXLSX()
1543 //tdf#98106 FILESAVE: Hidden and empty rows became visible when export to .XLSX
1544 ScDocShellRef xShell = loadDoc("hidden-empty-rows.", FORMAT_ODS);
1545 CPPUNIT_ASSERT(xShell.is());
1547 std::shared_ptr<utl::TempFile> pXPathFile = ScBootstrapFixture::exportTo(&(*xShell), FORMAT_XLSX);
1548 xmlDocUniquePtr pSheet = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/worksheets/sheet1.xml");
1549 CPPUNIT_ASSERT(pSheet);
1551 assertXPath(pSheet, "/x:worksheet/x:sheetFormatPr", "zeroHeight", "false" );
1552 assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[1]", "hidden", "true");
1553 assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[2]", "hidden", "true");
1554 assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[3]", "hidden", "true");
1555 assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row[4]", "hidden", "false");
1557 xShell->DoClose();
1560 void ScExportTest::testLandscapeOrientationXLSX()
1562 //tdf#48767 - Landscape page orientation is not loaded from .xlsx format with MS Excel, after export with Libre Office
1563 ScDocShellRef xShell = loadDoc("hidden-empty-rows.", FORMAT_ODS);
1564 CPPUNIT_ASSERT(xShell.is());
1566 std::shared_ptr<utl::TempFile> pXPathFile = ScBootstrapFixture::exportTo(&(*xShell), FORMAT_XLSX);
1567 xmlDocUniquePtr pSheet = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/worksheets/sheet1.xml");
1568 CPPUNIT_ASSERT(pSheet);
1570 // the usePrinterDefaults cannot be saved to allow opening sheets in Landscape mode via MS Excel
1571 assertXPathNoAttribute(pSheet, "/x:worksheet/x:pageSetup", "usePrinterDefaults");
1572 assertXPath(pSheet, "/x:worksheet/x:pageSetup", "orientation", "landscape");
1574 xShell->DoClose();
1577 void ScExportTest::testDataBarExportXLSX()
1579 ScDocShellRef xShell = loadDoc("databar.", FORMAT_XLSX);
1580 CPPUNIT_ASSERT(xShell.is());
1582 ScDocShellRef xDocSh = saveAndReload(xShell.get(), FORMAT_XLSX);
1583 CPPUNIT_ASSERT(xDocSh.is());
1585 ScDocument& rDoc = xDocSh->GetDocument();
1587 testDataBar_Impl(rDoc);
1589 xDocSh->DoClose();
1592 void ScExportTest::testMiscRowHeightExport()
1594 static const TestParam::RowData DfltRowData[] =
1596 { 0, 4, 0, 529, 0, false },
1597 { 5, 10, 0, 1058, 0, false },
1598 { 17, 20, 0, 1767, 0, false },
1599 // check last couple of row in document to ensure
1600 // they are 5.29mm ( effective default row xlsx height )
1601 { 1048573, 1048575, 0, 529, 0, false },
1604 static const TestParam::RowData EmptyRepeatRowData[] =
1606 // rows 0-4, 5-10, 17-20 are all set at various
1607 // heights, there is no content in the rows, there
1608 // was a bug where only the first row ( of repeated rows )
1609 // was set after export
1610 { 0, 4, 0, 529, 0, false },
1611 { 5, 10, 0, 1058, 0, false },
1612 { 17, 20, 0, 1767, 0, false },
1615 TestParam aTestValues[] =
1617 // Checks that some distributed ( non-empty ) heights remain set after export (roundtrip)
1618 // additionally there is effectively a default row height ( 5.29 mm ). So we test the
1619 // unset rows at the end of the document to ensure the effective xlsx default height
1620 // is set there too.
1621 { "miscrowheights.", FORMAT_XLSX, FORMAT_XLSX, SAL_N_ELEMENTS(DfltRowData), DfltRowData },
1622 // Checks that some distributed ( non-empty ) heights remain set after export (to xls)
1623 { "miscrowheights.", FORMAT_XLSX, FORMAT_XLS, SAL_N_ELEMENTS(DfltRowData), DfltRowData },
1624 // Checks that repreated rows ( of various heights ) remain set after export ( to xlsx )
1625 { "miscemptyrepeatedrowheights.", FORMAT_ODS, FORMAT_XLSX, SAL_N_ELEMENTS(EmptyRepeatRowData), EmptyRepeatRowData },
1626 // Checks that repreated rows ( of various heights ) remain set after export ( to xls )
1627 { "miscemptyrepeatedrowheights.", FORMAT_ODS, FORMAT_XLS, SAL_N_ELEMENTS(EmptyRepeatRowData), EmptyRepeatRowData },
1629 miscRowHeightsTest( aTestValues, SAL_N_ELEMENTS(aTestValues) );
1632 namespace {
1634 void setAttribute( ScFieldEditEngine& rEE, sal_Int32 nPara, sal_Int32 nStart, sal_Int32 nEnd, sal_uInt16 nType, Color nColor = COL_BLACK )
1636 ESelection aSel;
1637 aSel.nStartPara = aSel.nEndPara = nPara;
1638 aSel.nStartPos = nStart;
1639 aSel.nEndPos = nEnd;
1641 SfxItemSet aItemSet = rEE.GetEmptyItemSet();
1642 switch (nType)
1644 case EE_CHAR_WEIGHT:
1646 SvxWeightItem aWeight(WEIGHT_BOLD, nType);
1647 aItemSet.Put(aWeight);
1648 rEE.QuickSetAttribs(aItemSet, aSel);
1650 break;
1651 case EE_CHAR_ITALIC:
1653 SvxPostureItem aItalic(ITALIC_NORMAL, nType);
1654 aItemSet.Put(aItalic);
1655 rEE.QuickSetAttribs(aItemSet, aSel);
1657 break;
1658 case EE_CHAR_STRIKEOUT:
1660 SvxCrossedOutItem aCrossOut(STRIKEOUT_SINGLE, nType);
1661 aItemSet.Put(aCrossOut);
1662 rEE.QuickSetAttribs(aItemSet, aSel);
1664 break;
1665 case EE_CHAR_OVERLINE:
1667 SvxOverlineItem aItem(LINESTYLE_DOUBLE, nType);
1668 aItemSet.Put(aItem);
1669 rEE.QuickSetAttribs(aItemSet, aSel);
1671 break;
1672 case EE_CHAR_UNDERLINE:
1674 SvxUnderlineItem aItem(LINESTYLE_DOUBLE, nType);
1675 aItemSet.Put(aItem);
1676 rEE.QuickSetAttribs(aItemSet, aSel);
1678 break;
1679 case EE_CHAR_COLOR:
1681 SvxColorItem aItem(nColor, nType);
1682 aItemSet.Put(aItem);
1683 rEE.QuickSetAttribs(aItemSet, aSel);
1685 break;
1686 default:
1691 void setFont( ScFieldEditEngine& rEE, sal_Int32 nPara, sal_Int32 nStart, sal_Int32 nEnd, const OUString& rFontName )
1693 ESelection aSel;
1694 aSel.nStartPara = aSel.nEndPara = nPara;
1695 aSel.nStartPos = nStart;
1696 aSel.nEndPos = nEnd;
1698 SfxItemSet aItemSet = rEE.GetEmptyItemSet();
1699 SvxFontItem aItem(FAMILY_MODERN, rFontName, "", PITCH_VARIABLE, RTL_TEXTENCODING_UTF8, EE_CHAR_FONTINFO);
1700 aItemSet.Put(aItem);
1701 rEE.QuickSetAttribs(aItemSet, aSel);
1704 void setEscapement( ScFieldEditEngine& rEE, sal_Int32 nPara, sal_Int32 nStart, sal_Int32 nEnd, short nEsc, sal_uInt8 nRelSize )
1706 ESelection aSel;
1707 aSel.nStartPara = aSel.nEndPara = nPara;
1708 aSel.nStartPos = nStart;
1709 aSel.nEndPos = nEnd;
1711 SfxItemSet aItemSet = rEE.GetEmptyItemSet();
1712 SvxEscapementItem aItem(nEsc, nRelSize, EE_CHAR_ESCAPEMENT);
1713 aItemSet.Put(aItem);
1714 rEE.QuickSetAttribs(aItemSet, aSel);
1719 void ScExportTest::testNamedRangeBugfdo62729()
1721 ScDocShellRef xShell = loadDoc("fdo62729.", FORMAT_ODS);
1722 CPPUNIT_ASSERT(xShell.is());
1723 ScDocument& rDoc = xShell->GetDocument();
1725 ScRangeName* pNames = rDoc.GetRangeName();
1726 //should be just a single named range
1727 CPPUNIT_ASSERT_EQUAL(size_t(1), pNames->size());
1728 rDoc.DeleteTab(0);
1729 //should be still a single named range
1730 CPPUNIT_ASSERT_EQUAL(size_t(1), pNames->size());
1731 ScDocShellRef xDocSh = saveAndReload(xShell.get(), FORMAT_ODS);
1732 xShell->DoClose();
1734 CPPUNIT_ASSERT(xDocSh.is());
1735 ScDocument& rDoc2 = xDocSh->GetDocument();
1737 pNames = rDoc2.GetRangeName();
1738 //after reload should still have a named range
1739 CPPUNIT_ASSERT_EQUAL(size_t(1), pNames->size());
1741 xDocSh->DoClose();
1744 void ScExportTest::testBuiltinRangesXLSX()
1746 ScDocShellRef xShell = loadDoc("built-in_ranges.", FORMAT_XLSX);
1747 CPPUNIT_ASSERT(xShell.is());
1748 ScDocShellRef xDocSh = saveAndReload(xShell.get(), FORMAT_XLSX);
1749 CPPUNIT_ASSERT(xDocSh.is());
1750 xShell->DoClose();
1752 xmlDocUniquePtr pDoc = XPathHelper::parseExport2(*this, *xDocSh, m_xSFactory, "xl/workbook.xml", FORMAT_XLSX);
1753 CPPUNIT_ASSERT(pDoc);
1755 //assert the existing OOXML built-in names are still there
1756 assertXPathContent(pDoc, "/x:workbook/x:definedNames/x:definedName[@name='_xlnm._FilterDatabase'][@localSheetId='0']", "'Sheet1 Test'!$A$1:$A$5");
1757 assertXPathContent(pDoc, "/x:workbook/x:definedNames/x:definedName[@name='_xlnm._FilterDatabase'][@localSheetId='1']", "'Sheet2 Test'!$K$10:$K$14");
1758 assertXPathContent(pDoc, "/x:workbook/x:definedNames/x:definedName[@name='_xlnm.Print_Area'][@localSheetId='0']", "'Sheet1 Test'!$A$1:$A$5");
1759 assertXPathContent(pDoc, "/x:workbook/x:definedNames/x:definedName[@name='_xlnm.Print_Area'][@localSheetId='1']", "'Sheet2 Test'!$K$10:$M$18");
1761 //...and that no extra ones are added (see tdf#112571)
1762 assertXPath(pDoc, "/x:workbook/x:definedNames/x:definedName[@name='_xlnm._FilterDatabase_0'][@localSheetId='0']", 0);
1763 assertXPath(pDoc, "/x:workbook/x:definedNames/x:definedName[@name='_xlnm._FilterDatabase_0'][@localSheetId='1']", 0);
1764 assertXPath(pDoc, "/x:workbook/x:definedNames/x:definedName[@name='_xlnm.Print_Area_0'][@localSheetId='0']", 0);
1765 assertXPath(pDoc, "/x:workbook/x:definedNames/x:definedName[@name='_xlnm.Print_Area_0'][@localSheetId='1']", 0);
1767 xDocSh->DoClose();
1770 void ScExportTest::testRichTextExportODS()
1772 struct
1774 static bool isBold(const editeng::Section& rAttr)
1776 return std::any_of(rAttr.maAttributes.begin(), rAttr.maAttributes.end(), [](const SfxPoolItem* p) {
1777 return p->Which() == EE_CHAR_WEIGHT &&
1778 static_cast<const SvxWeightItem*>(p)->GetWeight() == WEIGHT_BOLD; });
1781 static bool isItalic(const editeng::Section& rAttr)
1783 return std::any_of(rAttr.maAttributes.begin(), rAttr.maAttributes.end(), [](const SfxPoolItem* p) {
1784 return p->Which() == EE_CHAR_ITALIC &&
1785 static_cast<const SvxPostureItem*>(p)->GetPosture() == ITALIC_NORMAL; });
1788 static bool isStrikeOut(const editeng::Section& rAttr)
1790 return std::any_of(rAttr.maAttributes.begin(), rAttr.maAttributes.end(), [](const SfxPoolItem* p) {
1791 return p->Which() == EE_CHAR_STRIKEOUT &&
1792 static_cast<const SvxCrossedOutItem*>(p)->GetStrikeout() == STRIKEOUT_SINGLE; });
1795 static bool isOverline(const editeng::Section& rAttr, FontLineStyle eStyle)
1797 return std::any_of(rAttr.maAttributes.begin(), rAttr.maAttributes.end(), [&eStyle](const SfxPoolItem* p) {
1798 return p->Which() == EE_CHAR_OVERLINE &&
1799 static_cast<const SvxOverlineItem*>(p)->GetLineStyle() == eStyle; });
1802 static bool isUnderline(const editeng::Section& rAttr, FontLineStyle eStyle)
1804 return std::any_of(rAttr.maAttributes.begin(), rAttr.maAttributes.end(), [&eStyle](const SfxPoolItem* p) {
1805 return p->Which() == EE_CHAR_UNDERLINE &&
1806 static_cast<const SvxUnderlineItem*>(p)->GetLineStyle() == eStyle; });
1809 static bool isFont(const editeng::Section& rAttr, const OUString& rFontName)
1811 return std::any_of(rAttr.maAttributes.begin(), rAttr.maAttributes.end(), [&rFontName](const SfxPoolItem* p) {
1812 return p->Which() == EE_CHAR_FONTINFO &&
1813 static_cast<const SvxFontItem*>(p)->GetFamilyName() == rFontName; });
1816 static bool isEscapement(const editeng::Section& rAttr, short nEsc, sal_uInt8 nRelSize)
1818 return std::any_of(rAttr.maAttributes.begin(), rAttr.maAttributes.end(),
1819 [&nEsc, &nRelSize](const SfxPoolItem* p) {
1820 if (p->Which() != EE_CHAR_ESCAPEMENT)
1821 return false;
1822 const SvxEscapementItem* pItem = static_cast<const SvxEscapementItem*>(p);
1823 return ((pItem->GetEsc() == nEsc) && (pItem->GetProportionalHeight() == nRelSize));
1827 static bool isColor(const editeng::Section& rAttr, Color nColor)
1829 return std::any_of(rAttr.maAttributes.begin(), rAttr.maAttributes.end(), [&nColor](const SfxPoolItem* p) {
1830 return p->Which() == EE_CHAR_COLOR &&
1831 static_cast<const SvxColorItem*>(p)->GetValue() == nColor; });
1834 bool checkB2(const EditTextObject* pText) const
1836 if (!pText)
1837 return false;
1839 if (pText->GetParagraphCount() != 1)
1840 return false;
1842 if (pText->GetText(0) != "Bold and Italic")
1843 return false;
1845 std::vector<editeng::Section> aSecAttrs;
1846 pText->GetAllSections(aSecAttrs);
1847 if (aSecAttrs.size() != 3)
1848 return false;
1850 // Check the first bold section.
1851 const editeng::Section* pAttr = aSecAttrs.data();
1852 if (pAttr->mnParagraph != 0 ||pAttr->mnStart != 0 || pAttr->mnEnd != 4)
1853 return false;
1855 if (pAttr->maAttributes.size() != 1 || !isBold(*pAttr))
1856 return false;
1858 // The middle section should be unformatted.
1859 pAttr = &aSecAttrs[1];
1860 if (pAttr->mnParagraph != 0 ||pAttr->mnStart != 4 || pAttr->mnEnd != 9)
1861 return false;
1863 if (!pAttr->maAttributes.empty())
1864 return false;
1866 // The last section should be italic.
1867 pAttr = &aSecAttrs[2];
1868 if (pAttr->mnParagraph != 0 ||pAttr->mnStart != 9 || pAttr->mnEnd != 15)
1869 return false;
1871 if (pAttr->maAttributes.size() != 1 || !isItalic(*pAttr))
1872 return false;
1874 return true;
1877 bool checkB4(const EditTextObject* pText) const
1879 if (!pText)
1880 return false;
1882 if (pText->GetParagraphCount() != 3)
1883 return false;
1885 if (pText->GetText(0) != "One")
1886 return false;
1888 if (pText->GetText(1) != "Two")
1889 return false;
1891 if (pText->GetText(2) != "Three")
1892 return false;
1894 return true;
1897 bool checkB5(const EditTextObject* pText) const
1899 if (!pText)
1900 return false;
1902 if (pText->GetParagraphCount() != 6)
1903 return false;
1905 if (!pText->GetText(0).isEmpty())
1906 return false;
1908 if (pText->GetText(1) != "Two")
1909 return false;
1911 if (pText->GetText(2) != "Three")
1912 return false;
1914 if (!pText->GetText(3).isEmpty())
1915 return false;
1917 if (pText->GetText(4) != "Five")
1918 return false;
1920 if (!pText->GetText(5).isEmpty())
1921 return false;
1923 return true;
1926 bool checkB6(const EditTextObject* pText) const
1928 if (!pText)
1929 return false;
1931 if (pText->GetParagraphCount() != 1)
1932 return false;
1934 if (pText->GetText(0) != "Strike Me")
1935 return false;
1937 std::vector<editeng::Section> aSecAttrs;
1938 pText->GetAllSections(aSecAttrs);
1939 if (aSecAttrs.size() != 2)
1940 return false;
1942 // Check the first strike-out section.
1943 const editeng::Section* pAttr = aSecAttrs.data();
1944 if (pAttr->mnParagraph != 0 ||pAttr->mnStart != 0 || pAttr->mnEnd != 6)
1945 return false;
1947 if (pAttr->maAttributes.size() != 1 || !isStrikeOut(*pAttr))
1948 return false;
1950 // The last section should be unformatted.
1951 pAttr = &aSecAttrs[1];
1952 return pAttr->mnParagraph == 0 && pAttr->mnStart == 6 && pAttr->mnEnd == 9;
1955 bool checkB7(const EditTextObject* pText) const
1957 if (!pText)
1958 return false;
1960 if (pText->GetParagraphCount() != 1)
1961 return false;
1963 if (pText->GetText(0) != "Font1 and Font2")
1964 return false;
1966 std::vector<editeng::Section> aSecAttrs;
1967 pText->GetAllSections(aSecAttrs);
1968 if (aSecAttrs.size() != 3)
1969 return false;
1971 // First section should have "Courier" font applied.
1972 const editeng::Section* pAttr = aSecAttrs.data();
1973 if (pAttr->mnParagraph != 0 ||pAttr->mnStart != 0 || pAttr->mnEnd != 5)
1974 return false;
1976 if (pAttr->maAttributes.size() != 1 || !isFont(*pAttr, "Courier"))
1977 return false;
1979 // Last section should have "Luxi Mono" applied.
1980 pAttr = &aSecAttrs[2];
1981 if (pAttr->mnParagraph != 0 ||pAttr->mnStart != 10 || pAttr->mnEnd != 15)
1982 return false;
1984 if (pAttr->maAttributes.size() != 1 || !isFont(*pAttr, "Luxi Mono"))
1985 return false;
1987 return true;
1990 bool checkB8(const EditTextObject* pText) const
1992 if (!pText)
1993 return false;
1995 if (pText->GetParagraphCount() != 1)
1996 return false;
1998 if (pText->GetText(0) != "Over and Under")
1999 return false;
2001 std::vector<editeng::Section> aSecAttrs;
2002 pText->GetAllSections(aSecAttrs);
2003 if (aSecAttrs.size() != 3)
2004 return false;
2006 // First section shoul have overline applied.
2007 const editeng::Section* pAttr = aSecAttrs.data();
2008 if (pAttr->mnParagraph != 0 ||pAttr->mnStart != 0 || pAttr->mnEnd != 4)
2009 return false;
2011 if (pAttr->maAttributes.size() != 1 || !isOverline(*pAttr, LINESTYLE_DOUBLE))
2012 return false;
2014 // Last section should have underline applied.
2015 pAttr = &aSecAttrs[2];
2016 if (pAttr->mnParagraph != 0 ||pAttr->mnStart != 9 || pAttr->mnEnd != 14)
2017 return false;
2019 if (pAttr->maAttributes.size() != 1 || !isUnderline(*pAttr, LINESTYLE_DOUBLE))
2020 return false;
2022 return true;
2025 bool checkB9(const EditTextObject* pText) const
2027 if (!pText)
2028 return false;
2030 if (pText->GetParagraphCount() != 1)
2031 return false;
2033 if (pText->GetText(0) != "Sub and Super")
2034 return false;
2036 std::vector<editeng::Section> aSecAttrs;
2037 pText->GetAllSections(aSecAttrs);
2038 if (aSecAttrs.size() != 3)
2039 return false;
2041 // superscript
2042 const editeng::Section* pAttr = aSecAttrs.data();
2043 if (pAttr->mnParagraph != 0 ||pAttr->mnStart != 0 || pAttr->mnEnd != 3)
2044 return false;
2046 if (pAttr->maAttributes.size() != 1 || !isEscapement(*pAttr, 32, 64))
2047 return false;
2049 // subscript
2050 pAttr = &aSecAttrs[2];
2051 if (pAttr->mnParagraph != 0 ||pAttr->mnStart != 8 || pAttr->mnEnd != 13)
2052 return false;
2054 if (pAttr->maAttributes.size() != 1 || !isEscapement(*pAttr, -32, 66))
2055 return false;
2057 return true;
2060 bool checkB10(const EditTextObject* pText) const
2062 if (!pText)
2063 return false;
2065 if (pText->GetParagraphCount() != 1)
2066 return false;
2068 if (pText->GetText(0) != "BLUE AUTO")
2069 return false;
2071 std::vector<editeng::Section> aSecAttrs;
2072 pText->GetAllSections(aSecAttrs);
2073 if (aSecAttrs.size() != 2)
2074 return false;
2076 // auto color
2077 const editeng::Section* pAttr = &aSecAttrs[1];
2078 if (pAttr->mnParagraph != 0 ||pAttr->mnStart != 5 || pAttr->mnEnd != 9)
2079 return false;
2081 if (pAttr->maAttributes.size() != 1 || !isColor(*pAttr, COL_AUTO))
2082 return false;
2084 return true;
2087 } aCheckFunc;
2089 // Start with an empty document, put one edit text cell, and make sure it
2090 // survives the save and reload.
2091 ScDocShellRef xOrigDocSh = loadDoc("empty.", FORMAT_ODS, true);
2092 const EditTextObject* pEditText;
2094 ScDocument& rDoc = xOrigDocSh->GetDocument();
2095 CPPUNIT_ASSERT_MESSAGE("This document should at least have one sheet.", rDoc.GetTableCount() > 0);
2097 // Insert an edit text cell.
2098 ScFieldEditEngine* pEE = &rDoc.GetEditEngine();
2099 pEE->SetTextCurrentDefaults("Bold and Italic");
2100 // Set the 'Bold' part bold.
2101 setAttribute(*pEE, 0, 0, 4, EE_CHAR_WEIGHT);
2102 // Set the 'Italic' part italic.
2103 setAttribute(*pEE, 0, 9, 15, EE_CHAR_ITALIC);
2104 ESelection aSel;
2105 aSel.nStartPara = aSel.nEndPara = 0;
2107 // Set this edit text to cell B2.
2108 rDoc.SetEditText(ScAddress(1,1,0), pEE->CreateTextObject());
2109 pEditText = rDoc.GetEditText(ScAddress(1,1,0));
2110 CPPUNIT_ASSERT_MESSAGE("Incorrect B2 value.", aCheckFunc.checkB2(pEditText));
2113 // Now, save and reload this document.
2114 ScDocShellRef xNewDocSh = saveAndReload(xOrigDocSh.get(), FORMAT_ODS);
2116 xOrigDocSh->DoClose();
2117 CPPUNIT_ASSERT(xNewDocSh.is());
2118 ScDocument& rDoc2 = xNewDocSh->GetDocument();
2119 CPPUNIT_ASSERT_MESSAGE("Reloaded document should at least have one sheet.", rDoc2.GetTableCount() > 0);
2120 ScFieldEditEngine* pEE = &rDoc2.GetEditEngine();
2122 // Make sure the content of B2 is still intact.
2123 CPPUNIT_ASSERT_MESSAGE("Incorrect B2 value.", aCheckFunc.checkB2(pEditText));
2125 // Insert a multi-line content to B4.
2126 pEE->Clear();
2127 pEE->SetTextCurrentDefaults("One\nTwo\nThree");
2128 rDoc2.SetEditText(ScAddress(1,3,0), pEE->CreateTextObject());
2129 pEditText = rDoc2.GetEditText(ScAddress(1,3,0));
2130 CPPUNIT_ASSERT_MESSAGE("Incorrect B4 value.", aCheckFunc.checkB4(pEditText));
2133 // Reload the doc again, and check the content of B2 and B4.
2134 ScDocShellRef xNewDocSh2 = saveAndReload(xNewDocSh.get(), FORMAT_ODS);
2136 ScDocument& rDoc3 = xNewDocSh2->GetDocument();
2137 ScFieldEditEngine* pEE = &rDoc3.GetEditEngine();
2138 xNewDocSh->DoClose();
2140 pEditText = rDoc3.GetEditText(ScAddress(1,1,0));
2141 CPPUNIT_ASSERT_MESSAGE("B2 should be an edit text.", pEditText);
2142 pEditText = rDoc3.GetEditText(ScAddress(1,3,0));
2143 CPPUNIT_ASSERT_MESSAGE("Incorrect B4 value.", aCheckFunc.checkB4(pEditText));
2145 // Insert a multi-line content to B5, but this time, set some empty paragraphs.
2146 pEE->Clear();
2147 pEE->SetTextCurrentDefaults("\nTwo\nThree\n\nFive\n");
2148 rDoc3.SetEditText(ScAddress(1,4,0), pEE->CreateTextObject());
2149 pEditText = rDoc3.GetEditText(ScAddress(1,4,0));
2150 CPPUNIT_ASSERT_MESSAGE("Incorrect B5 value.", aCheckFunc.checkB5(pEditText));
2152 // Insert a text with strikethrough in B6.
2153 pEE->Clear();
2154 pEE->SetTextCurrentDefaults("Strike Me");
2155 // Set the 'Strike' part strikethrough.
2156 setAttribute(*pEE, 0, 0, 6, EE_CHAR_STRIKEOUT);
2157 rDoc3.SetEditText(ScAddress(1,5,0), pEE->CreateTextObject());
2158 pEditText = rDoc3.GetEditText(ScAddress(1,5,0));
2159 CPPUNIT_ASSERT_MESSAGE("Incorrect B6 value.", aCheckFunc.checkB6(pEditText));
2161 // Insert a text with different font segments in B7.
2162 pEE->Clear();
2163 pEE->SetTextCurrentDefaults("Font1 and Font2");
2164 setFont(*pEE, 0, 0, 5, "Courier");
2165 setFont(*pEE, 0, 10, 15, "Luxi Mono");
2166 rDoc3.SetEditText(ScAddress(1,6,0), pEE->CreateTextObject());
2167 pEditText = rDoc3.GetEditText(ScAddress(1,6,0));
2168 CPPUNIT_ASSERT_MESSAGE("Incorrect B7 value.", aCheckFunc.checkB7(pEditText));
2170 // Insert a text with overline and underline in B8.
2171 pEE->Clear();
2172 pEE->SetTextCurrentDefaults("Over and Under");
2173 setAttribute(*pEE, 0, 0, 4, EE_CHAR_OVERLINE);
2174 setAttribute(*pEE, 0, 9, 14, EE_CHAR_UNDERLINE);
2175 rDoc3.SetEditText(ScAddress(1,7,0), pEE->CreateTextObject());
2176 pEditText = rDoc3.GetEditText(ScAddress(1,7,0));
2177 CPPUNIT_ASSERT_MESSAGE("Incorrect B8 value.", aCheckFunc.checkB8(pEditText));
2179 pEE->Clear();
2180 pEE->SetTextCurrentDefaults("Sub and Super");
2181 setEscapement(*pEE, 0, 0, 3, 32, 64);
2182 setEscapement(*pEE, 0, 8, 13, -32, 66);
2183 rDoc3.SetEditText(ScAddress(1,8,0), pEE->CreateTextObject());
2184 pEditText = rDoc3.GetEditText(ScAddress(1,8,0));
2185 CPPUNIT_ASSERT_MESSAGE("Incorrect B9 value.", aCheckFunc.checkB9(pEditText));
2187 ScPatternAttr aCellFontColor(rDoc3.GetPool());
2188 aCellFontColor.GetItemSet().Put(SvxColorItem(COL_BLUE, ATTR_FONT_COLOR));
2189 // Set font color of B10 to blue.
2190 rDoc3.ApplyPattern(1, 9, 0, aCellFontColor);
2191 pEE->Clear();
2192 pEE->SetTextCurrentDefaults("BLUE AUTO");
2193 // Set the color of the string "AUTO" to automatic color.
2194 setAttribute(*pEE, 0, 5, 9, EE_CHAR_COLOR, COL_AUTO);
2195 rDoc3.SetEditText(ScAddress(1, 9, 0), pEE->CreateTextObject());
2196 pEditText = rDoc3.GetEditText(ScAddress(1, 9, 0));
2197 CPPUNIT_ASSERT_MESSAGE("Incorrect B10 value.", aCheckFunc.checkB10(pEditText));
2200 // Reload the doc again, and check the content of B2, B4, B6 and B7.
2201 ScDocShellRef xNewDocSh3 = saveAndReload(xNewDocSh2.get(), FORMAT_ODS);
2202 ScDocument& rDoc4 = xNewDocSh3->GetDocument();
2203 xNewDocSh2->DoClose();
2205 pEditText = rDoc4.GetEditText(ScAddress(1,1,0));
2206 CPPUNIT_ASSERT_MESSAGE("Incorrect B2 value after save and reload.", aCheckFunc.checkB2(pEditText));
2207 pEditText = rDoc4.GetEditText(ScAddress(1,3,0));
2208 CPPUNIT_ASSERT_MESSAGE("Incorrect B4 value after save and reload.", aCheckFunc.checkB4(pEditText));
2209 pEditText = rDoc4.GetEditText(ScAddress(1,4,0));
2210 CPPUNIT_ASSERT_MESSAGE("Incorrect B5 value after save and reload.", aCheckFunc.checkB5(pEditText));
2211 pEditText = rDoc4.GetEditText(ScAddress(1,5,0));
2212 CPPUNIT_ASSERT_MESSAGE("Incorrect B6 value after save and reload.", aCheckFunc.checkB6(pEditText));
2213 pEditText = rDoc4.GetEditText(ScAddress(1,6,0));
2214 CPPUNIT_ASSERT_MESSAGE("Incorrect B7 value after save and reload.", aCheckFunc.checkB7(pEditText));
2215 pEditText = rDoc4.GetEditText(ScAddress(1,7,0));
2216 CPPUNIT_ASSERT_MESSAGE("Incorrect B8 value after save and reload.", aCheckFunc.checkB8(pEditText));
2217 pEditText = rDoc4.GetEditText(ScAddress(1,9,0));
2218 CPPUNIT_ASSERT_MESSAGE("Incorrect B10 value after save and reload.", aCheckFunc.checkB10(pEditText));
2220 xNewDocSh3->DoClose();
2223 void ScExportTest::testRichTextCellFormatXLSX()
2225 ScDocShellRef xDocSh = loadDoc("cellformat.", FORMAT_XLS);
2226 CPPUNIT_ASSERT(xDocSh.is());
2228 std::shared_ptr<utl::TempFile> pXPathFile = ScBootstrapFixture::exportTo(&(*xDocSh), FORMAT_XLSX);
2229 xmlDocUniquePtr pSheet = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/worksheets/sheet1.xml");
2230 CPPUNIT_ASSERT(pSheet);
2232 // make sure the only cell in this doc is assigned some formatting record
2233 OUString aCellFormat = getXPath(pSheet, "/x:worksheet/x:sheetData/x:row/x:c", "s");
2234 CPPUNIT_ASSERT_MESSAGE("Cell format is missing", !aCellFormat.isEmpty());
2236 xmlDocUniquePtr pStyles = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/styles.xml");
2237 CPPUNIT_ASSERT(pStyles);
2239 OString nFormatIdx = OString::number( aCellFormat.toInt32() + 1 );
2240 const OString aXPath1( "/x:styleSheet/x:cellXfs/x:xf[" + nFormatIdx + "]/x:alignment" );
2241 // formatting record is set to wrap text
2242 assertXPath(pStyles, aXPath1, "wrapText", "true");
2244 // see what font it references
2245 const OString aXPath2( "/x:styleSheet/x:cellXfs/x:xf[" + nFormatIdx +"]" );
2246 OUString aFontId = getXPath(pStyles, aXPath2, "fontId");
2247 OString nFontIdx = OString::number( aFontId.toInt32() + 1 );
2249 // that font should be bold
2250 const OString aXPath3("/x:styleSheet/x:fonts/x:font[" + nFontIdx + "]/x:b");
2251 assertXPath(pStyles, aXPath3, "val", "true");
2253 xDocSh->DoClose();
2256 void ScExportTest::testFormulaRefSheetNameODS()
2258 ScDocShellRef xDocSh = loadDoc("formula-quote-in-sheet-name.", FORMAT_ODS, true);
2260 ScDocument& rDoc = xDocSh->GetDocument();
2262 sc::AutoCalcSwitch aACSwitch(rDoc, true); // turn on auto calc.
2263 rDoc.SetString(ScAddress(1,1,0), "='90''s Data'.B2");
2264 CPPUNIT_ASSERT_EQUAL(1.1, rDoc.GetValue(ScAddress(1,1,0)));
2265 ASSERT_FORMULA_EQUAL(rDoc, ScAddress(1,1,0), "'90''s Data'.B2", "Wrong formula");
2267 // Now, save and reload this document.
2268 ScDocShellRef xNewDocSh = saveAndReload(xDocSh.get(), FORMAT_ODS);
2269 xDocSh->DoClose();
2271 ScDocument& rDoc = xNewDocSh->GetDocument();
2272 rDoc.CalcAll();
2273 CPPUNIT_ASSERT_EQUAL(1.1, rDoc.GetValue(ScAddress(1,1,0)));
2274 ASSERT_FORMULA_EQUAL(rDoc, ScAddress(1,1,0), "'90''s Data'.B2", "Wrong formula");
2276 xNewDocSh->DoClose();
2279 void ScExportTest::testCellValuesExportODS()
2281 // Start with an empty document
2282 ScDocShellRef xOrigDocSh = loadDoc("empty.", FORMAT_ODS);
2284 ScDocument& rDoc = xOrigDocSh->GetDocument();
2285 CPPUNIT_ASSERT_MESSAGE("This document should at least have one sheet.", rDoc.GetTableCount() > 0);
2287 // set a value double
2288 rDoc.SetValue(ScAddress(0,0,0), 2.0); // A1
2290 // set a formula
2291 rDoc.SetValue(ScAddress(2,0,0), 3.0); // C1
2292 rDoc.SetValue(ScAddress(3,0,0), 3); // D1
2293 rDoc.SetString(ScAddress(4,0,0), "=10*C1/4"); // E1
2294 rDoc.SetValue(ScAddress(5,0,0), 3.0); // F1
2295 rDoc.SetString(ScAddress(7,0,0), "=SUM(C1:F1)"); //H1
2297 // set a string
2298 rDoc.SetString(ScAddress(0,2,0), "a simple line"); //A3
2300 // set a digit string
2301 rDoc.SetString(ScAddress(0,4,0), "'12"); //A5
2302 // set a contiguous value
2303 rDoc.SetValue(ScAddress(0,5,0), 12.0); //A6
2304 // set a contiguous string
2305 rDoc.SetString(ScAddress(0,6,0), "a string"); //A7
2306 // set a contiguous formula
2307 rDoc.SetString(ScAddress(0,7,0), "=$A$6"); //A8
2309 // save and reload
2310 ScDocShellRef xNewDocSh = saveAndReload(xOrigDocSh.get(), FORMAT_ODS);
2311 xOrigDocSh->DoClose();
2312 CPPUNIT_ASSERT(xNewDocSh.is());
2313 ScDocument& rDoc = xNewDocSh->GetDocument();
2314 CPPUNIT_ASSERT_MESSAGE("Reloaded document should at least have one sheet.", rDoc.GetTableCount() > 0);
2316 // check value
2317 CPPUNIT_ASSERT_EQUAL(2.0, rDoc.GetValue(0,0,0));
2318 CPPUNIT_ASSERT_EQUAL(3.0, rDoc.GetValue(2,0,0));
2319 CPPUNIT_ASSERT_EQUAL(3.0, rDoc.GetValue(3,0,0));
2320 CPPUNIT_ASSERT_EQUAL(7.5, rDoc.GetValue(4,0,0));
2321 CPPUNIT_ASSERT_EQUAL(3.0, rDoc.GetValue(5,0,0));
2323 // check formula
2324 ASSERT_FORMULA_EQUAL(rDoc, ScAddress(4,0,0), "10*C1/4", "Wrong formula =10*C1/4");
2325 ASSERT_FORMULA_EQUAL(rDoc, ScAddress(7,0,0), "SUM(C1:F1)", "Wrong formula =SUM(C1:F1)");
2326 CPPUNIT_ASSERT_EQUAL(16.5, rDoc.GetValue(7,0,0));
2328 // check string
2329 ScRefCellValue aCell;
2330 aCell.assign(rDoc, ScAddress(0,2,0));
2331 CPPUNIT_ASSERT_EQUAL( CELLTYPE_STRING, aCell.meType );
2333 // check for an empty cell
2334 aCell.assign(rDoc, ScAddress(0,3,0));
2335 CPPUNIT_ASSERT_EQUAL( CELLTYPE_NONE, aCell.meType);
2337 // check a digit string
2338 aCell.assign(rDoc, ScAddress(0,4,0));
2339 CPPUNIT_ASSERT_EQUAL( CELLTYPE_STRING, aCell.meType);
2341 //check contiguous values
2342 CPPUNIT_ASSERT_EQUAL( 12.0, rDoc.GetValue(0,5,0) );
2343 CPPUNIT_ASSERT_EQUAL( OUString("a string"), rDoc.GetString(0,6,0) );
2344 ASSERT_FORMULA_EQUAL(rDoc, ScAddress(0,7,0), "$A$6", "Wrong formula =$A$6");
2345 CPPUNIT_ASSERT_EQUAL( rDoc.GetValue(0,5,0), rDoc.GetValue(0,7,0) );
2347 xNewDocSh->DoClose();
2350 void ScExportTest::testCellNoteExportODS()
2352 ScDocShellRef xOrigDocSh = loadDoc("single-note.", FORMAT_ODS);
2353 ScAddress aPos(0,0,0); // Start with A1.
2355 ScDocument& rDoc = xOrigDocSh->GetDocument();
2357 CPPUNIT_ASSERT_MESSAGE("There should be a note at A1.", rDoc.HasNote(aPos));
2359 aPos.IncRow(); // Move to A2.
2360 ScPostIt* pNote = rDoc.GetOrCreateNote(aPos);
2361 pNote->SetText(aPos, "Note One");
2362 pNote->SetAuthor("Author One");
2363 CPPUNIT_ASSERT_MESSAGE("There should be a note at A2.", rDoc.HasNote(aPos));
2365 // save and reload
2366 ScDocShellRef xNewDocSh = saveAndReload(xOrigDocSh.get(), FORMAT_ODS);
2367 xOrigDocSh->DoClose();
2368 CPPUNIT_ASSERT(xNewDocSh.is());
2369 ScDocument& rDoc = xNewDocSh->GetDocument();
2371 aPos.SetRow(0); // Move back to A1.
2372 CPPUNIT_ASSERT_MESSAGE("There should be a note at A1.", rDoc.HasNote(aPos));
2373 aPos.IncRow(); // Move to A2.
2374 CPPUNIT_ASSERT_MESSAGE("There should be a note at A2.", rDoc.HasNote(aPos));
2376 xNewDocSh->DoClose();
2379 void ScExportTest::testCellNoteExportXLS()
2381 // Start with an empty document.s
2382 ScDocShellRef xOrigDocSh = loadDoc("notes-on-3-sheets.", FORMAT_ODS);
2384 ScDocument& rDoc = xOrigDocSh->GetDocument();
2385 CPPUNIT_ASSERT_EQUAL_MESSAGE("This document should have 3 sheets.", SCTAB(3), rDoc.GetTableCount());
2387 // Check note's presence.
2388 CPPUNIT_ASSERT( rDoc.HasNote(ScAddress(0,0,0)));
2389 CPPUNIT_ASSERT(!rDoc.HasNote(ScAddress(0,1,0)));
2390 CPPUNIT_ASSERT(!rDoc.HasNote(ScAddress(0,2,0)));
2392 CPPUNIT_ASSERT(!rDoc.HasNote(ScAddress(0,0,1)));
2393 CPPUNIT_ASSERT( rDoc.HasNote(ScAddress(0,1,1)));
2394 CPPUNIT_ASSERT(!rDoc.HasNote(ScAddress(0,2,1)));
2396 CPPUNIT_ASSERT(!rDoc.HasNote(ScAddress(0,0,2)));
2397 CPPUNIT_ASSERT(!rDoc.HasNote(ScAddress(0,1,2)));
2398 CPPUNIT_ASSERT( rDoc.HasNote(ScAddress(0,2,2)));
2400 // save and reload as XLS.
2401 ScDocShellRef xNewDocSh = saveAndReload(xOrigDocSh.get(), FORMAT_XLS);
2403 xOrigDocSh->DoClose();
2404 CPPUNIT_ASSERT(xNewDocSh.is());
2405 ScDocument& rDoc = xNewDocSh->GetDocument();
2406 CPPUNIT_ASSERT_EQUAL_MESSAGE("This document should have 3 sheets.", SCTAB(3), rDoc.GetTableCount());
2408 // Check note's presence again.
2409 CPPUNIT_ASSERT( rDoc.HasNote(ScAddress(0,0,0)));
2410 CPPUNIT_ASSERT(!rDoc.HasNote(ScAddress(0,1,0)));
2411 CPPUNIT_ASSERT(!rDoc.HasNote(ScAddress(0,2,0)));
2413 CPPUNIT_ASSERT(!rDoc.HasNote(ScAddress(0,0,1)));
2414 CPPUNIT_ASSERT( rDoc.HasNote(ScAddress(0,1,1)));
2415 CPPUNIT_ASSERT(!rDoc.HasNote(ScAddress(0,2,1)));
2417 CPPUNIT_ASSERT(!rDoc.HasNote(ScAddress(0,0,2)));
2418 CPPUNIT_ASSERT(!rDoc.HasNote(ScAddress(0,1,2)));
2419 CPPUNIT_ASSERT( rDoc.HasNote(ScAddress(0,2,2)));
2421 xNewDocSh->DoClose();
2425 namespace {
2427 void checkMatrixRange(ScDocument& rDoc, const ScRange& rRange)
2429 ScRange aMatRange;
2430 ScAddress aMatOrigin;
2431 for (SCCOL nCol = rRange.aStart.Col(); nCol <= rRange.aEnd.Col(); ++nCol)
2433 for (SCROW nRow = rRange.aStart.Row(); nRow <= rRange.aEnd.Row(); ++nRow)
2435 ScAddress aPos(nCol, nRow, rRange.aStart.Tab());
2436 bool bIsMatrix = rDoc.GetMatrixFormulaRange(aPos, aMatRange);
2437 CPPUNIT_ASSERT_MESSAGE("Matrix expected, but not found.", bIsMatrix);
2438 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong matrix range.", rRange, aMatRange);
2439 const ScFormulaCell* pCell = rDoc.GetFormulaCell(aPos);
2440 CPPUNIT_ASSERT_MESSAGE("This must be a formula cell.", pCell);
2442 bIsMatrix = pCell->GetMatrixOrigin(rDoc, aMatOrigin);
2443 CPPUNIT_ASSERT_MESSAGE("Not a part of matrix formula.", bIsMatrix);
2444 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong matrix origin.", aMatRange.aStart, aMatOrigin);
2451 void ScExportTest::testInlineArrayXLS()
2453 ScDocShellRef xShell = loadDoc("inline-array.", FORMAT_XLS);
2454 CPPUNIT_ASSERT(xShell.is());
2456 ScDocShellRef xDocSh = saveAndReload(xShell.get(), FORMAT_XLS);
2457 xShell->DoClose();
2458 CPPUNIT_ASSERT(xDocSh.is());
2460 ScDocument& rDoc = xDocSh->GetDocument();
2462 // B2:C3 contains a matrix.
2463 checkMatrixRange(rDoc, ScRange(1,1,0,2,2,0));
2465 // B5:D6 contains a matrix.
2466 checkMatrixRange(rDoc, ScRange(1,4,0,3,5,0));
2468 // B8:C10 as well.
2469 checkMatrixRange(rDoc, ScRange(1,7,0,2,9,0));
2471 xDocSh->DoClose();
2474 void ScExportTest::testEmbeddedChartODS()
2476 ScDocShellRef xShell = loadDoc("embedded-chart.", FORMAT_XLS);
2477 CPPUNIT_ASSERT(xShell.is());
2479 std::shared_ptr<utl::TempFile> pTempFile(
2480 ScBootstrapFixture::exportTo(xShell.get(), FORMAT_ODS));
2482 xmlDocUniquePtr pDoc = XPathHelper::parseExport(pTempFile, m_xSFactory, "content.xml");
2483 CPPUNIT_ASSERT(pDoc);
2484 assertXPath(pDoc,
2485 "/office:document-content/office:body/office:spreadsheet/table:table[2]/table:table-row[7]/table:table-cell[2]/draw:frame/draw:object",
2486 "notify-on-update-of-ranges",
2487 "Chart1.B3:Chart1.B5 Chart1.C2:Chart1.C2 Chart1.C3:Chart1.C5");
2489 xShell->DoClose();
2492 void ScExportTest::testEmbeddedChartXLS()
2494 ScDocShellRef xShell = loadDoc("embedded-chart.", FORMAT_XLS);
2495 CPPUNIT_ASSERT(xShell.is());
2497 ScDocShellRef xDocSh = saveAndReload(xShell.get(), FORMAT_XLS);
2498 xShell->DoClose();
2499 CPPUNIT_ASSERT(xDocSh.is());
2501 ScDocument& rDoc = xDocSh->GetDocument();
2503 // Make sure the 2nd sheet is named 'Chart1'.
2504 OUString aName;
2505 rDoc.GetName(1, aName);
2506 CPPUNIT_ASSERT_EQUAL(OUString("Chart1"), aName);
2508 const SdrOle2Obj* pOleObj = getSingleChartObject(rDoc, 1);
2509 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve a chart object from the 2nd sheet.", pOleObj);
2511 ScRangeList aRanges = getChartRanges(rDoc, *pOleObj);
2512 CPPUNIT_ASSERT_MESSAGE("Label range (B3:B5) not found.", aRanges.In(ScRange(1,2,1,1,4,1)));
2513 CPPUNIT_ASSERT_MESSAGE("Data label (C2) not found.", aRanges.In(ScAddress(2,1,1)));
2514 CPPUNIT_ASSERT_MESSAGE("Data range (C3:C5) not found.", aRanges.In(ScRange(2,2,1,2,4,1)));
2516 xDocSh->DoClose();
2519 void ScExportTest::testCellAnchoredGroupXLS()
2521 ScDocShellRef xDocSh_in = loadDoc("cell-anchored-group.", FORMAT_XLS);
2522 CPPUNIT_ASSERT_MESSAGE("Failed to load cell-anchored-group.xls", xDocSh_in.is());
2524 ScDocShellRef xDocSh = saveAndReload(&(*xDocSh_in), FORMAT_ODS);
2525 CPPUNIT_ASSERT_MESSAGE("Failed to save and reload cell-anchored-group.ods", xDocSh.is());
2527 // the document contains a group anchored on the first cell, make sure it's there in the right place
2528 ScDocument& rDoc = xDocSh->GetDocument();
2529 CPPUNIT_ASSERT_MESSAGE("There should be at least one sheet.", rDoc.GetTableCount() > 0);
2530 ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer();
2531 SdrPage* pPage = pDrawLayer->GetPage(0);
2532 CPPUNIT_ASSERT_MESSAGE("draw page for sheet 1 should exist.", pPage);
2533 const size_t nCount = pPage->GetObjCount();
2534 CPPUNIT_ASSERT_EQUAL_MESSAGE(
2535 "There should be 1 objects.", static_cast<size_t>(1), nCount);
2537 SdrObject* pObj = pPage->GetObj(0);
2538 CPPUNIT_ASSERT_MESSAGE("Failed to get drawing object.", pObj);
2539 ScDrawObjData* pData = ScDrawLayer::GetObjData(pObj);
2540 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve user data for this object.", pData);
2541 CPPUNIT_ASSERT_MESSAGE("Upper left of bounding rectangle should be nonnegative.",
2542 pData->getShapeRect().Left() >= 0 || pData->getShapeRect().Top() >= 0);
2543 xDocSh->DoClose();
2546 void ScExportTest::testFormulaReferenceXLS()
2548 ScDocShellRef xShell = loadDoc("formula-reference.", FORMAT_XLS);
2549 CPPUNIT_ASSERT(xShell.is());
2551 ScDocShellRef xDocSh = saveAndReload(xShell.get(), FORMAT_XLS);
2552 xShell->DoClose();
2553 CPPUNIT_ASSERT(xDocSh.is());
2555 ScDocument& rDoc = xDocSh->GetDocument();
2557 ASSERT_FORMULA_EQUAL(rDoc, ScAddress(3,1,0), "$A$2+$B$2+$C$2", "Wrong formula in D2");
2558 ASSERT_FORMULA_EQUAL(rDoc, ScAddress(3,2,0), "A3+B3+C3", "Wrong formula in D3");
2559 ASSERT_FORMULA_EQUAL(rDoc, ScAddress(3,5,0), "SUM($A$6:$C$6)", "Wrong formula in D6");
2560 ASSERT_FORMULA_EQUAL(rDoc, ScAddress(3,6,0), "SUM(A7:C7)", "Wrong formula in D7");
2561 ASSERT_FORMULA_EQUAL(rDoc, ScAddress(3,9,0), "$Two.$A$2+$Two.$B$2+$Two.$C$2", "Wrong formula in D10");
2562 ASSERT_FORMULA_EQUAL(rDoc, ScAddress(3,10,0), "$Two.A3+$Two.B3+$Two.C3", "Wrong formula in D11");
2563 ASSERT_FORMULA_EQUAL(rDoc, ScAddress(3,13,0), "MIN($Two.$A$2:$C$2)", "Wrong formula in D14");
2564 ASSERT_FORMULA_EQUAL(rDoc, ScAddress(3,14,0), "MAX($Two.A3:C3)", "Wrong formula in D15");
2566 xDocSh->DoClose();
2569 void ScExportTest::testSheetProtectionXLSX()
2571 ScDocShellRef xShell = loadDoc("ProtecteSheet1234Pass.", FORMAT_XLSX);
2572 CPPUNIT_ASSERT(xShell.is());
2574 ScDocShellRef xDocSh = saveAndReload(xShell.get(), FORMAT_XLSX);
2575 CPPUNIT_ASSERT(xDocSh.is());
2577 ScDocument& rDoc = xDocSh->GetDocument();
2578 const ScTableProtection* pTabProtect = rDoc.GetTabProtection(0);
2579 CPPUNIT_ASSERT(pTabProtect);
2580 Sequence<sal_Int8> aHash = pTabProtect->getPasswordHash(PASSHASH_XL);
2581 // check has
2582 if (aHash.getLength() >= 2)
2584 CPPUNIT_ASSERT_EQUAL(sal_uInt8(204), static_cast<sal_uInt8>(aHash[0]));
2585 CPPUNIT_ASSERT_EQUAL(sal_uInt8(61), static_cast<sal_uInt8>(aHash[1]));
2587 // we could flesh out this check I guess
2588 CPPUNIT_ASSERT ( !pTabProtect->isOptionEnabled( ScTableProtection::OBJECTS ) );
2589 CPPUNIT_ASSERT ( !pTabProtect->isOptionEnabled( ScTableProtection::SCENARIOS ) );
2590 xDocSh->DoClose();
2593 void ScExportTest::testSheetProtectionXLSB()
2595 ScDocShellRef xShell = loadDoc("tdf108017_calcProtection.", FORMAT_XLSB);
2596 CPPUNIT_ASSERT(xShell.is());
2598 ScDocShellRef xDocSh = saveAndReload(xShell.get(), FORMAT_XLSX);
2599 CPPUNIT_ASSERT(xDocSh.is());
2601 ScDocument& rDoc = xDocSh->GetDocument();
2602 const ScTableProtection* pTabProtect = rDoc.GetTabProtection(0);
2603 CPPUNIT_ASSERT(pTabProtect);
2604 CPPUNIT_ASSERT(pTabProtect->isOptionEnabled( ScTableProtection::SELECT_UNLOCKED_CELLS ));
2605 CPPUNIT_ASSERT(!pTabProtect->isOptionEnabled( ScTableProtection::SELECT_LOCKED_CELLS ));
2606 xDocSh->DoClose();
2609 namespace {
2611 const char* toBorderName( SvxBorderLineStyle eStyle )
2613 switch (eStyle)
2615 case SvxBorderLineStyle::SOLID: return "SOLID";
2616 case SvxBorderLineStyle::DOTTED: return "DOTTED";
2617 case SvxBorderLineStyle::DASHED: return "DASHED";
2618 case SvxBorderLineStyle::DASH_DOT: return "DASH_DOT";
2619 case SvxBorderLineStyle::DASH_DOT_DOT: return "DASH_DOT_DOT";
2620 case SvxBorderLineStyle::DOUBLE_THIN: return "DOUBLE_THIN";
2621 case SvxBorderLineStyle::FINE_DASHED: return "FINE_DASHED";
2622 default:
2626 return "";
2631 void ScExportTest::testExcelCellBorders( sal_uLong nFormatType )
2633 static const struct
2635 SCROW mnRow;
2636 SvxBorderLineStyle mnStyle;
2637 tools::Long mnWidth;
2638 } aChecks[] = {
2639 { 1, SvxBorderLineStyle::SOLID, 1 }, // hair
2640 { 3, SvxBorderLineStyle::DOTTED, 15 }, // dotted
2641 { 5, SvxBorderLineStyle::DASH_DOT_DOT, 15 }, // dash dot dot
2642 { 7, SvxBorderLineStyle::DASH_DOT, 15 }, // dash dot
2643 { 9, SvxBorderLineStyle::FINE_DASHED, 15 }, // dashed
2644 { 11, SvxBorderLineStyle::SOLID, 15 }, // thin
2645 { 13, SvxBorderLineStyle::DASH_DOT_DOT, 35 }, // medium dash dot dot
2646 { 17, SvxBorderLineStyle::DASH_DOT, 35 }, // medium dash dot
2647 { 19, SvxBorderLineStyle::DASHED, 35 }, // medium dashed
2648 { 21, SvxBorderLineStyle::SOLID, 35 }, // medium
2649 { 23, SvxBorderLineStyle::SOLID, 50 }, // thick
2650 { 25, SvxBorderLineStyle::DOUBLE_THIN, -1 }, // double (don't check width)
2653 ScDocShellRef xDocSh = loadDoc("cell-borders.", nFormatType);
2654 CPPUNIT_ASSERT_MESSAGE("Failed to load file", xDocSh.is());
2656 ScDocument& rDoc = xDocSh->GetDocument();
2658 for (size_t i = 0; i < SAL_N_ELEMENTS(aChecks); ++i)
2660 const editeng::SvxBorderLine* pLine = nullptr;
2661 rDoc.GetBorderLines(2, aChecks[i].mnRow, 0, nullptr, &pLine, nullptr, nullptr);
2662 CPPUNIT_ASSERT(pLine);
2663 CPPUNIT_ASSERT_EQUAL(toBorderName(aChecks[i].mnStyle), toBorderName(pLine->GetBorderLineStyle()));
2664 if (aChecks[i].mnWidth >= 0)
2665 CPPUNIT_ASSERT_EQUAL(aChecks[i].mnWidth, pLine->GetWidth());
2669 ScDocShellRef xNewDocSh = saveAndReload(xDocSh.get(), nFormatType);
2670 xDocSh->DoClose();
2671 ScDocument& rDoc = xNewDocSh->GetDocument();
2672 for (size_t i = 0; i < SAL_N_ELEMENTS(aChecks); ++i)
2674 const editeng::SvxBorderLine* pLine = nullptr;
2675 rDoc.GetBorderLines(2, aChecks[i].mnRow, 0, nullptr, &pLine, nullptr, nullptr);
2676 CPPUNIT_ASSERT(pLine);
2677 CPPUNIT_ASSERT_EQUAL(toBorderName(aChecks[i].mnStyle), toBorderName(pLine->GetBorderLineStyle()));
2678 if (aChecks[i].mnWidth >= 0)
2679 CPPUNIT_ASSERT_EQUAL(aChecks[i].mnWidth, pLine->GetWidth());
2682 xNewDocSh->DoClose();
2685 void ScExportTest::testCellBordersXLS()
2687 testExcelCellBorders(FORMAT_XLS);
2690 void ScExportTest::testCellBordersXLSX()
2692 testExcelCellBorders(FORMAT_XLSX);
2695 void ScExportTest::testBordersExchangeXLSX()
2697 // Document: sc/qa/unit/data/README.cellborders
2699 // short name for the table
2700 const SvxBorderLineStyle None = SvxBorderLineStyle::NONE;
2701 const SvxBorderLineStyle Solid = SvxBorderLineStyle::SOLID;
2702 const SvxBorderLineStyle Dotted = SvxBorderLineStyle::DOTTED;
2703 const SvxBorderLineStyle Dashed = SvxBorderLineStyle::DASHED;
2704 const SvxBorderLineStyle FineDash = SvxBorderLineStyle::FINE_DASHED;
2705 const SvxBorderLineStyle DashDot = SvxBorderLineStyle::DASH_DOT;
2706 const SvxBorderLineStyle DashDoDo = SvxBorderLineStyle::DASH_DOT_DOT;
2707 const SvxBorderLineStyle DoubThin = SvxBorderLineStyle::DOUBLE_THIN;
2709 const size_t nMaxCol = 18;
2710 const size_t nMaxRow = 7;
2712 static struct
2714 SvxBorderLineStyle BorderStyleTop, BorderStyleBottom;
2715 tools::Long WidthTop, WidthBottom;
2716 } aCheckBorderWidth[nMaxCol][nMaxRow] =
2718 /* Line 1 2 3 4 5 6 7
2719 SOLID DOTTED DASHED FINE_DASHED DASH_DOT DASH_DOT_DOT DOUBLE_THIN */
2720 /*Width */
2721 /* 0,05 */ {{Solid , Solid , 1, 1}, {Dotted , Dotted , 15, 15}, {Dotted , Dotted , 15, 15}, {FineDash, FineDash, 15, 15}, {FineDash, FineDash, 15, 15}, {FineDash, FineDash, 15, 15}, {None , None , 0, 0}},
2722 /* 0,25 */ {{Solid , Solid , 1, 1}, {Dotted , Dotted , 15, 15}, {Dotted , Dotted , 15, 15}, {FineDash, FineDash, 15, 15}, {FineDash, FineDash, 15, 15}, {FineDash, FineDash, 15, 15}, {None , None , 0, 0}},
2723 /* 0,50 */ {{Solid , Solid , 1, 1}, {Dotted , Dotted , 15, 15}, {Dotted , Dotted , 15, 15}, {FineDash, FineDash, 15, 15}, {FineDash, FineDash, 15, 15}, {FineDash, FineDash, 15, 15}, {None , None , 0, 0}},
2724 /* 0,75 */ {{Solid , Solid , 15, 15}, {Dotted , Dotted , 15, 15}, {FineDash, FineDash, 15, 15}, {FineDash, FineDash, 15, 15}, {DashDot , DashDot , 15, 15}, {DashDoDo, DashDoDo, 15, 15}, {DoubThin, DoubThin, 35, 35}},
2725 /* 1,00 */ {{Solid , Solid , 15, 15}, {Dotted , Dotted , 15, 15}, {FineDash, FineDash, 15, 15}, {FineDash, FineDash, 15, 15}, {DashDot , DashDot , 15, 15}, {DashDoDo, DashDoDo, 15, 15}, {DoubThin, DoubThin, 35, 35}},
2726 /* 1,25 */ {{Solid , Solid , 15, 15}, {Dotted , Dotted , 15, 15}, {FineDash, FineDash, 15, 15}, {FineDash, FineDash, 15, 15}, {DashDot , DashDot , 15, 15}, {DashDoDo, DashDoDo, 15, 15}, {DoubThin, DoubThin, 35, 35}},
2727 /* 1,50 */ {{Solid , Solid , 15, 15}, {Dotted , Dotted , 15, 15}, {FineDash, FineDash, 15, 15}, {FineDash, FineDash, 15, 15}, {DashDot , DashDot , 15, 15}, {DashDoDo, DashDoDo, 15, 15}, {DoubThin, DoubThin, 35, 35}},
2729 /* 1,75 */ {{Solid , Solid , 35, 35}, {FineDash, FineDash, 35, 35}, {Dashed , Dashed , 35, 35}, {FineDash, FineDash, 35, 35}, {DashDot , DashDot , 35, 35}, {DashDoDo, DashDoDo, 35, 35}, {DoubThin, DoubThin, 35, 35}},
2730 /* 2,00 */ {{Solid , Solid , 35, 35}, {FineDash, FineDash, 35, 35}, {Dashed , Dashed , 35, 35}, {FineDash, FineDash, 35, 35}, {DashDot , DashDot , 35, 35}, {DashDoDo, DashDoDo, 35, 35}, {DoubThin, DoubThin, 35, 35}},
2731 /* 2,25 */ {{Solid , Solid , 35, 35}, {FineDash, FineDash, 35, 35}, {Dashed , Dashed , 35, 35}, {FineDash, FineDash, 35, 35}, {DashDot , DashDot , 35, 35}, {DashDoDo, DashDoDo, 35, 35}, {DoubThin, DoubThin, 35, 35}},
2733 /* 2,50 */ {{Solid , Solid , 50, 50}, {FineDash, FineDash, 35, 35}, {Dashed , Dashed , 35, 35}, {FineDash, FineDash, 35, 35}, {DashDot , DashDot , 35, 35}, {DashDoDo, DashDoDo, 35, 35}, {DoubThin, DoubThin, 35, 35}},
2734 /* 2,75 */ {{Solid , Solid , 50, 50}, {FineDash, FineDash, 35, 35}, {Dashed , Dashed , 35, 35}, {FineDash, FineDash, 35, 35}, {DashDot , DashDot , 35, 35}, {DashDoDo, DashDoDo, 35, 35}, {DoubThin, DoubThin, 35, 35}},
2735 /* 3,00 */ {{Solid , Solid , 50, 50}, {FineDash, FineDash, 35, 35}, {Dashed , Dashed , 35, 35}, {FineDash, FineDash, 35, 35}, {DashDot , DashDot , 35, 35}, {DashDoDo, DashDoDo, 35, 35}, {DoubThin, DoubThin, 35, 35}},
2736 /* 3,50 */ {{Solid , Solid , 50, 50}, {FineDash, FineDash, 35, 35}, {Dashed , Dashed , 35, 35}, {FineDash, FineDash, 35, 35}, {DashDot , DashDot , 35, 35}, {DashDoDo, DashDoDo, 35, 35}, {DoubThin, DoubThin, 35, 35}},
2737 /* 4,00 */ {{Solid , Solid , 50, 50}, {FineDash, FineDash, 35, 35}, {Dashed , Dashed , 35, 35}, {FineDash, FineDash, 35, 35}, {DashDot , DashDot , 35, 35}, {DashDoDo, DashDoDo, 35, 35}, {DoubThin, DoubThin, 35, 35}},
2738 /* 5,00 */ {{Solid , Solid , 50, 50}, {FineDash, FineDash, 35, 35}, {Dashed , Dashed , 35, 35}, {FineDash, FineDash, 35, 35}, {DashDot , DashDot , 35, 35}, {DashDoDo, DashDoDo, 35, 35}, {DoubThin, DoubThin, 35, 35}},
2739 /* 7,00 */ {{Solid , Solid , 50, 50}, {FineDash, FineDash, 35, 35}, {Dashed , Dashed , 35, 35}, {FineDash, FineDash, 35, 35}, {DashDot , DashDot , 35, 35}, {DashDoDo, DashDoDo, 35, 35}, {DoubThin, DoubThin, 35, 35}},
2740 /* 9,00 */ {{Solid , Solid , 50, 50}, {FineDash, FineDash, 35, 35}, {Dashed , Dashed , 35, 35}, {FineDash, FineDash, 35, 35}, {DashDot , DashDot , 35, 35}, {DashDoDo, DashDoDo, 35, 35}, {DoubThin, DoubThin, 35, 35}}
2743 ScDocShellRef xShell = loadDoc("test_borders_export.", FORMAT_ODS); // load the ods with our Borders
2744 CPPUNIT_ASSERT(xShell.is());
2746 ScDocShellRef xDocSh = saveAndReload(&(*xShell), FORMAT_XLSX); // save the ods to xlsx and load xlsx
2747 CPPUNIT_ASSERT(xDocSh.is());
2748 ScDocument& rDoc = xDocSh->GetDocument();
2750 for (size_t nCol = 0; nCol < nMaxCol; ++nCol)
2752 for (size_t nRow = 0; nRow < nMaxRow; ++nRow)
2754 const editeng::SvxBorderLine* pLineTop = nullptr;
2755 const editeng::SvxBorderLine* pLineBottom = nullptr;
2756 rDoc.GetBorderLines(nCol + 2, (nRow * 2) + 8, 0, nullptr, &pLineTop, nullptr, &pLineBottom);
2757 if((nCol < 3) && (nRow == 6))
2758 { // in this range no lines since minimum size to create a double is 0.5
2759 CPPUNIT_ASSERT(!pLineTop);
2760 CPPUNIT_ASSERT(!pLineBottom);
2761 continue;
2763 else
2765 CPPUNIT_ASSERT(pLineTop);
2766 CPPUNIT_ASSERT(pLineBottom);
2769 CPPUNIT_ASSERT_EQUAL_MESSAGE("Top Border-Line-Style wrong", aCheckBorderWidth[nCol][nRow].BorderStyleTop,
2770 pLineTop->GetBorderLineStyle());
2771 CPPUNIT_ASSERT_EQUAL_MESSAGE("Bottom Border-Line-Style wrong", aCheckBorderWidth[nCol][nRow].BorderStyleBottom,
2772 pLineBottom->GetBorderLineStyle());
2773 CPPUNIT_ASSERT_EQUAL_MESSAGE("Top Width-Line wrong", aCheckBorderWidth[nCol][nRow].WidthTop,
2774 pLineTop->GetWidth());
2775 CPPUNIT_ASSERT_EQUAL_MESSAGE("Bottom Width-Line wrong", aCheckBorderWidth[nCol][nRow].WidthBottom,
2776 pLineBottom->GetWidth());
2780 xDocSh->DoClose();
2783 static OUString toString( const ScBigRange& rRange )
2785 OUStringBuffer aBuf;
2786 aBuf.append("(columns:");
2787 aBuf.append(rRange.aStart.Col());
2788 aBuf.append('-');
2789 aBuf.append(rRange.aEnd.Col());
2790 aBuf.append(";rows:");
2791 aBuf.append(rRange.aStart.Row());
2792 aBuf.append('-');
2793 aBuf.append(rRange.aEnd.Row());
2794 aBuf.append(";sheets:");
2795 aBuf.append(rRange.aStart.Tab());
2796 aBuf.append('-');
2797 aBuf.append(rRange.aEnd.Tab());
2798 aBuf.append(')');
2800 return aBuf.makeStringAndClear();
2803 void ScExportTest::testTrackChangesSimpleXLSX()
2805 struct CheckItem
2807 sal_uLong mnActionId;
2808 ScChangeActionType meType;
2810 sal_Int32 mnStartCol;
2811 sal_Int32 mnStartRow;
2812 sal_Int32 mnStartTab;
2813 sal_Int32 mnEndCol;
2814 sal_Int32 mnEndRow;
2815 sal_Int32 mnEndTab;
2817 bool mbRowInsertedAtBottom;
2820 struct
2822 bool checkRange( ScChangeActionType eType, const ScBigRange& rExpected, const ScBigRange& rActual )
2824 ScBigRange aExpected(rExpected), aActual(rActual);
2826 switch (eType)
2828 case SC_CAT_INSERT_ROWS:
2830 // Ignore columns.
2831 aExpected.aStart.SetCol(0);
2832 aExpected.aEnd.SetCol(0);
2833 aActual.aStart.SetCol(0);
2834 aActual.aEnd.SetCol(0);
2836 break;
2837 default:
2841 return aExpected == aActual;
2844 bool check( const ScDocument& rDoc )
2846 static const CheckItem aChecks[] =
2848 { 1, SC_CAT_CONTENT , 1, 1, 0, 1, 1, 0, false },
2849 { 2, SC_CAT_INSERT_ROWS , 0, 2, 0, 0, 2, 0, true },
2850 { 3, SC_CAT_CONTENT , 1, 2, 0, 1, 2, 0, false },
2851 { 4, SC_CAT_INSERT_ROWS , 0, 3, 0, 0, 3, 0, true },
2852 { 5, SC_CAT_CONTENT , 1, 3, 0, 1, 3, 0, false },
2853 { 6, SC_CAT_INSERT_ROWS , 0, 4, 0, 0, 4, 0, true },
2854 { 7, SC_CAT_CONTENT , 1, 4, 0, 1, 4, 0, false },
2855 { 8, SC_CAT_INSERT_ROWS , 0, 5, 0, 0, 5, 0, true },
2856 { 9, SC_CAT_CONTENT , 1, 5, 0, 1, 5, 0, false },
2857 { 10, SC_CAT_INSERT_ROWS , 0, 6, 0, 0, 6, 0, true },
2858 { 11, SC_CAT_CONTENT , 1, 6, 0, 1, 6, 0, false },
2859 { 12, SC_CAT_INSERT_ROWS , 0, 7, 0, 0, 7, 0, true },
2860 { 13, SC_CAT_CONTENT , 1, 7, 0, 1, 7, 0, false },
2863 ScChangeTrack* pCT = rDoc.GetChangeTrack();
2864 if (!pCT)
2866 cerr << "Change track instance doesn't exist." << endl;
2867 return false;
2870 sal_uLong nActionMax = pCT->GetActionMax();
2871 if (nActionMax != 13)
2873 cerr << "Unexpected highest action ID value." << endl;
2874 return false;
2877 for (size_t i = 0; i < SAL_N_ELEMENTS(aChecks); ++i)
2879 sal_uInt16 nActId = aChecks[i].mnActionId;
2880 const ScChangeAction* pAction = pCT->GetAction(nActId);
2881 if (!pAction)
2883 cerr << "No action for action number " << nActId << " found." << endl;
2884 return false;
2887 if (pAction->GetType() != aChecks[i].meType)
2889 cerr << "Unexpected action type for action number " << nActId << "." << endl;
2890 return false;
2893 const ScBigRange& rRange = pAction->GetBigRange();
2894 ScBigRange aCheck(aChecks[i].mnStartCol, aChecks[i].mnStartRow, aChecks[i].mnStartTab,
2895 aChecks[i].mnEndCol, aChecks[i].mnEndRow, aChecks[i].mnEndTab);
2897 if (!checkRange(pAction->GetType(), aCheck, rRange))
2899 cerr << "Unexpected range for action number " << nActId
2900 << ": expected=" << toString(aCheck) << " actual=" << toString(rRange) << endl;
2901 return false;
2904 switch (pAction->GetType())
2906 case SC_CAT_INSERT_ROWS:
2908 const ScChangeActionIns* p = static_cast<const ScChangeActionIns*>(pAction);
2909 if (p->IsEndOfList() != aChecks[i].mbRowInsertedAtBottom)
2911 cerr << "Unexpected end-of-list flag for action number " << nActId << "." << endl;
2912 return false;
2915 break;
2916 default:
2921 return true;
2924 bool checkRevisionUserAndTime( ScDocument& rDoc, const OUString& rOwnerName )
2926 ScChangeTrack* pCT = rDoc.GetChangeTrack();
2927 if (!pCT)
2929 cerr << "Change track instance doesn't exist." << endl;
2930 return false;
2933 ScChangeAction* pAction = pCT->GetLast();
2934 if (pAction->GetUser() != "Kohei Yoshida")
2936 cerr << "Wrong user name." << endl;
2937 return false;
2940 DateTime aDT = pAction->GetDateTime();
2941 if (aDT.GetYear() != 2014 || aDT.GetMonth() != 7 || aDT.GetDay() != 11)
2943 cerr << "Wrong time stamp." << endl;
2944 return false;
2947 // Insert a new record to make sure the user and date-time are correct.
2948 rDoc.SetString(ScAddress(1,8,0), "New String");
2949 ScCellValue aEmpty;
2950 pCT->AppendContent(ScAddress(1,8,0), aEmpty);
2951 pAction = pCT->GetLast();
2952 if (!pAction)
2954 cerr << "Failed to retrieve last revision." << endl;
2955 return false;
2958 if (rOwnerName != pAction->GetUser())
2960 cerr << "Wrong user name." << endl;
2961 return false;
2964 DateTime aDTNew = pAction->GetDateTime();
2965 if (aDTNew <= aDT)
2967 cerr << "Time stamp of the new revision should be more recent than that of the last revision." << endl;
2968 return false;
2971 return true;
2974 } aTest;
2976 SvtUserOptions& rUserOpt = SC_MOD()->GetUserOptions();
2977 rUserOpt.SetToken(UserOptToken::FirstName, "Export");
2978 rUserOpt.SetToken(UserOptToken::LastName, "Test");
2980 OUString aOwnerName = rUserOpt.GetFirstName() + " " + rUserOpt.GetLastName();
2982 // First, test the xls variant.
2984 ScDocShellRef xDocSh = loadDoc("track-changes/simple-cell-changes.", FORMAT_XLS);
2985 CPPUNIT_ASSERT(xDocSh.is());
2986 ScDocument* pDoc = &xDocSh->GetDocument();
2987 bool bGood = aTest.check(*pDoc);
2988 CPPUNIT_ASSERT_MESSAGE("Initial check failed (xls).", bGood);
2990 ScDocShellRef xDocSh2 = saveAndReload(xDocSh.get(), FORMAT_XLS);
2991 xDocSh->DoClose();
2992 pDoc = &xDocSh2->GetDocument();
2993 bGood = aTest.check(*pDoc);
2994 CPPUNIT_ASSERT_MESSAGE("Check after reload failed (xls).", bGood);
2996 // fdo#81445 : Check the blank value string to make sure it's "<empty>".
2997 ScChangeTrack* pCT = pDoc->GetChangeTrack();
2998 CPPUNIT_ASSERT(pCT);
2999 ScChangeAction* pAction = pCT->GetAction(1);
3000 CPPUNIT_ASSERT(pAction);
3001 OUString aDesc;
3002 pAction->GetDescription(aDesc, *pDoc);
3003 CPPUNIT_ASSERT_EQUAL(OUString("Cell B2 changed from '<empty>' to '1'"), aDesc);
3005 bGood = aTest.checkRevisionUserAndTime(*pDoc, aOwnerName);
3006 CPPUNIT_ASSERT_MESSAGE("Check revision and time failed after reload (xls).", bGood);
3008 xDocSh2->DoClose();
3010 // Now, test the xlsx variant the same way.
3012 xDocSh = loadDoc("track-changes/simple-cell-changes.", FORMAT_XLSX);
3013 CPPUNIT_ASSERT(xDocSh.is());
3014 pDoc = &xDocSh->GetDocument();
3015 aTest.check(*pDoc);
3016 CPPUNIT_ASSERT_MESSAGE("Initial check failed (xlsx).", bGood);
3018 xDocSh2 = saveAndReload(xDocSh.get(), FORMAT_XLSX);
3019 xDocSh->DoClose();
3020 pDoc = &xDocSh2->GetDocument();
3021 bGood = aTest.check(*pDoc);
3022 CPPUNIT_ASSERT_MESSAGE("Check after reload failed (xlsx).", bGood);
3024 bGood = aTest.checkRevisionUserAndTime(*pDoc, aOwnerName);
3025 CPPUNIT_ASSERT_MESSAGE("Check revision and time failed after reload (xlsx).", bGood);
3027 xDocSh2->DoClose();
3030 void ScExportTest::testSheetTabColorsXLSX()
3032 struct
3034 bool checkContent( const ScDocument& rDoc )
3037 std::vector<OUString> aTabNames = rDoc.GetAllTableNames();
3039 // green, red, blue, yellow (from left to right).
3040 if (aTabNames.size() != 4)
3042 cerr << "There should be exactly 4 sheets." << endl;
3043 return false;
3046 const char* pNames[] = { "Green", "Red", "Blue", "Yellow" };
3047 for (size_t i = 0; i < SAL_N_ELEMENTS(pNames); ++i)
3049 OUString aExpected = OUString::createFromAscii(pNames[i]);
3050 if (aExpected != aTabNames[i])
3052 cerr << "incorrect sheet name: expected='" << aExpected <<"', actual='" << aTabNames[i] << "'" << endl;
3053 return false;
3057 static const Color aXclColors[] =
3059 0x0000B050, // green
3060 0x00FF0000, // red
3061 0x000070C0, // blue
3062 0x00FFFF00, // yellow
3065 for (size_t i = 0; i < SAL_N_ELEMENTS(aXclColors); ++i)
3067 if (aXclColors[i] != rDoc.GetTabBgColor(i))
3069 cerr << "wrong sheet color for sheet " << i << endl;
3070 return false;
3074 return true;
3077 } aTest;
3079 ScDocShellRef xDocSh = loadDoc("sheet-tab-color.", FORMAT_XLSX);
3081 CPPUNIT_ASSERT_MESSAGE("Failed to load file.", xDocSh.is());
3082 ScDocument& rDoc = xDocSh->GetDocument();
3083 bool bRes = aTest.checkContent(rDoc);
3084 CPPUNIT_ASSERT_MESSAGE("Failed on the initial content check.", bRes);
3087 ScDocShellRef xDocSh2 = saveAndReload(xDocSh.get(), FORMAT_XLSX);
3088 CPPUNIT_ASSERT_MESSAGE("Failed to reload file.", xDocSh2.is());
3089 xDocSh->DoClose();
3090 ScDocument& rDoc = xDocSh2->GetDocument();
3091 bool bRes = aTest.checkContent(rDoc);
3092 CPPUNIT_ASSERT_MESSAGE("Failed on the content check after reload.", bRes);
3094 xDocSh2->DoClose();
3097 void ScExportTest::testSharedFormulaExportXLS()
3099 struct
3101 bool checkContent( ScDocument& rDoc )
3103 formula::FormulaGrammar::Grammar eGram = formula::FormulaGrammar::GRAM_ENGLISH_XL_R1C1;
3104 rDoc.SetGrammar(eGram);
3105 sc::TokenStringContext aCxt(rDoc, eGram);
3107 // Check the title row.
3109 OUString aActual = rDoc.GetString(0,1,0);
3110 OUString aExpected = "Response";
3111 if (aActual != aExpected)
3113 cerr << "Wrong content in A2: expected='" << aExpected << "', actual='" << aActual << "'" << endl;
3114 return false;
3117 aActual = rDoc.GetString(1,1,0);
3118 aExpected = "Response";
3119 if (aActual != aExpected)
3121 cerr << "Wrong content in B2: expected='" << aExpected << "', actual='" << aActual << "'" << endl;
3122 return false;
3125 // A3:A12 and B3:B12 are numbers from 1 to 10.
3126 for (SCROW i = 0; i <= 9; ++i)
3128 double fExpected = i + 1.0;
3129 ScAddress aPos(0,i+2,0);
3130 double fActual = rDoc.GetValue(aPos);
3131 if (fExpected != fActual)
3133 cerr << "Wrong value in A" << (i+2) << ": expected=" << fExpected << ", actual=" << fActual << endl;
3134 return false;
3137 aPos.IncCol();
3138 ScFormulaCell* pFC = rDoc.GetFormulaCell(aPos);
3139 if (!pFC)
3141 cerr << "B" << (i+2) << " should be a formula cell." << endl;
3142 return false;
3145 OUString aFormula = pFC->GetCode()->CreateString(aCxt, aPos);
3146 aExpected = "Coefficients!RC[-1]";
3147 if (aFormula != aExpected)
3149 cerr << "Wrong formula in B" << (i+2) << ": expected='" << aExpected << "', actual='" << aFormula << "'" << endl;
3150 return false;
3153 fActual = rDoc.GetValue(aPos);
3154 if (fExpected != fActual)
3156 cerr << "Wrong value in B" << (i+2) << ": expected=" << fExpected << ", actual=" << fActual << endl;
3157 return false;
3161 return true;
3164 } aTest;
3166 ScDocShellRef xDocSh = loadDoc("shared-formula/3d-reference.", FORMAT_ODS);
3168 CPPUNIT_ASSERT_MESSAGE("Failed to load file.", xDocSh.is());
3169 ScDocument& rDoc = xDocSh->GetDocument();
3171 // Check the content of the original.
3172 bool bRes = aTest.checkContent(rDoc);
3173 CPPUNIT_ASSERT_MESSAGE("Content check on the original document failed.", bRes);
3176 ScDocShellRef xDocSh2 = saveAndReload(xDocSh.get(), FORMAT_XLS);
3177 xDocSh->DoClose();
3178 CPPUNIT_ASSERT_MESSAGE("Failed to reload file.", xDocSh2.is());
3180 ScDocument& rDoc = xDocSh2->GetDocument();
3182 // Check the content of the reloaded. This should be identical.
3183 bool bRes = aTest.checkContent(rDoc);
3184 CPPUNIT_ASSERT_MESSAGE("Content check on the reloaded document failed.", bRes);
3186 xDocSh2->DoClose();
3189 void ScExportTest::testSharedFormulaExportXLSX()
3191 struct
3193 bool checkContent( const ScDocument& rDoc )
3195 SCTAB nTabCount = rDoc.GetTableCount();
3196 if (nTabCount != 2)
3198 cerr << "Document should have exactly 2 sheets. " << nTabCount << " found." << endl;
3199 return false;
3202 // Make sure the sheet tab colors are not set.
3203 for (SCROW i = 0; i <= 1; ++i)
3205 Color aTabBgColor = rDoc.GetTabBgColor(i);
3206 if (aTabBgColor != COL_AUTO)
3208 cerr << "The tab color of Sheet " << (i+1) << " should not be explicitly set." << endl;
3209 return false;
3213 // B2:B7 should show 1,2,3,4,5,6.
3214 double fExpected = 1.0;
3215 for (SCROW i = 1; i <= 6; ++i, ++fExpected)
3217 ScAddress aPos(1,i,0);
3218 double fVal = rDoc.GetValue(aPos);
3219 if (fVal != fExpected)
3221 cerr << "Wrong value in B" << (i+1) << ": expected=" << fExpected << ", actual=" << fVal << endl;
3222 return false;
3226 // C2:C7 should show 10,20,...,60.
3227 fExpected = 10.0;
3228 for (SCROW i = 1; i <= 6; ++i, fExpected+=10.0)
3230 ScAddress aPos(2,i,0);
3231 double fVal = rDoc.GetValue(aPos);
3232 if (fVal != fExpected)
3234 cerr << "Wrong value in C" << (i+1) << ": expected=" << fExpected << ", actual=" << fVal << endl;
3235 return false;
3239 // D2:D7 should show 1,2,...,6.
3240 fExpected = 1.0;
3241 for (SCROW i = 1; i <= 6; ++i, ++fExpected)
3243 ScAddress aPos(3,i,0);
3244 double fVal = rDoc.GetValue(aPos);
3245 if (fVal != fExpected)
3247 cerr << "Wrong value in D" << (i+1) << ": expected=" << fExpected << ", actual=" << fVal << endl;
3248 return false;
3252 return true;
3255 } aTest;
3257 ScDocShellRef xDocSh = loadDoc("shared-formula/3d-reference.", FORMAT_XLSX);
3259 CPPUNIT_ASSERT_MESSAGE("Failed to load file.", xDocSh.is());
3260 ScDocument& rDoc = xDocSh->GetDocument();
3262 bool bRes = aTest.checkContent(rDoc);
3263 CPPUNIT_ASSERT_MESSAGE("Content check on the initial document failed.", bRes);
3265 rDoc.CalcAll(); // Recalculate to flush all cached results.
3266 bRes = aTest.checkContent(rDoc);
3267 CPPUNIT_ASSERT_MESSAGE("Content check on the initial recalculated document failed.", bRes);
3270 // Save and reload, and check the content again.
3271 ScDocShellRef xDocSh2 = saveAndReload(xDocSh.get(), FORMAT_XLSX);
3272 xDocSh->DoClose();
3274 CPPUNIT_ASSERT_MESSAGE("Failed to load file.", xDocSh2.is());
3275 ScDocument& rDoc = xDocSh2->GetDocument();
3276 rDoc.CalcAll(); // Recalculate to flush all cached results.
3278 bool bRes = aTest.checkContent(rDoc);
3279 CPPUNIT_ASSERT_MESSAGE("Content check on the reloaded document failed.", bRes);
3281 xDocSh2->DoClose();
3284 void ScExportTest::testSharedFormulaStringResultExportXLSX()
3286 struct
3288 bool checkContent( const ScDocument& rDoc )
3291 // B2:B7 should show A,B,...,F.
3292 const char* const expected[] = { "A", "B", "C", "D", "E", "F" };
3293 for (SCROW i = 0; i <= 5; ++i)
3295 ScAddress aPos(1,i+1,0);
3296 OUString aStr = rDoc.GetString(aPos);
3297 OUString aExpected = OUString::createFromAscii(expected[i]);
3298 if (aStr != aExpected)
3300 cerr << "Wrong value in B" << (i+2) << ": expected='" << aExpected << "', actual='" << aStr << "'" << endl;
3301 return false;
3307 // C2:C7 should show AA,BB,...,FF.
3308 const char* const expected[] = { "AA", "BB", "CC", "DD", "EE", "FF" };
3309 for (SCROW i = 0; i <= 5; ++i)
3311 ScAddress aPos(2,i+1,0);
3312 OUString aStr = rDoc.GetString(aPos);
3313 OUString aExpected = OUString::createFromAscii(expected[i]);
3314 if (aStr != aExpected)
3316 cerr << "Wrong value in C" << (i+2) << ": expected='" << aExpected << "', actual='" << aStr << "'" << endl;
3317 return false;
3322 return true;
3325 } aTest;
3327 ScDocShellRef xDocSh = loadDoc("shared-formula/text-results.", FORMAT_XLSX);
3329 CPPUNIT_ASSERT_MESSAGE("Failed to load file.", xDocSh.is());
3330 ScDocument& rDoc = xDocSh->GetDocument();
3332 // Check content without re-calculation, to test cached formula results.
3333 bool bRes = aTest.checkContent(rDoc);
3334 CPPUNIT_ASSERT_MESSAGE("Content check on the initial document failed.", bRes);
3336 // Now, re-calculate and check the results.
3337 rDoc.CalcAll();
3338 bRes = aTest.checkContent(rDoc);
3339 CPPUNIT_ASSERT_MESSAGE("Content check on the initial recalculated document failed.", bRes);
3341 // Reload and check again.
3342 ScDocShellRef xDocSh2 = saveAndReload(xDocSh.get(), FORMAT_XLSX);
3343 xDocSh->DoClose();
3344 CPPUNIT_ASSERT_MESSAGE("Failed to re-load file.", xDocSh2.is());
3345 ScDocument& rDoc = xDocSh2->GetDocument();
3347 bool bRes = aTest.checkContent(rDoc);
3348 CPPUNIT_ASSERT_MESSAGE("Content check on the reloaded document failed.", bRes);
3350 xDocSh2->DoClose();
3353 void ScExportTest::testFunctionsExcel2010( sal_uLong nFormatType )
3355 ScDocShellRef xShell = loadDoc("functions-excel-2010.", FORMAT_XLSX);
3356 CPPUNIT_ASSERT_MESSAGE("Failed to load the document.", xShell.is());
3358 ScDocShellRef xDocSh = saveAndReload(xShell.get(), nFormatType);
3359 ScDocument& rDoc = xDocSh->GetDocument();
3360 rDoc.CalcAll(); // perform hard re-calculation.
3362 testFunctionsExcel2010_Impl(rDoc);
3364 xDocSh->DoClose();
3367 void ScExportTest::testFunctionsExcel2010XLSX()
3369 testFunctionsExcel2010(FORMAT_XLSX);
3372 void ScExportTest::testFunctionsExcel2010XLS()
3374 testFunctionsExcel2010(FORMAT_XLS);
3377 void ScExportTest::testCeilingFloor( sal_uLong nFormatType )
3379 ScDocShellRef xShell = loadDoc("ceiling-floor.", FORMAT_XLSX);
3380 CPPUNIT_ASSERT_MESSAGE("Failed to load the document.", xShell.is());
3382 ScDocShellRef xDocSh = saveAndReload(xShell.get(), nFormatType);
3383 ScDocument& rDoc = xDocSh->GetDocument();
3384 rDoc.CalcAll(); // perform hard re-calculation.
3386 testCeilingFloor_Impl(rDoc);
3388 xDocSh->DoClose();
3391 void ScExportTest::testCeilingFloorXLSX()
3393 testCeilingFloor(FORMAT_XLSX);
3396 void ScExportTest::testCeilingFloorODSToXLSX()
3398 // tdf#100011 - Cannot open sheet containing FLOOR/CEILING functions by MS Excel, after export to .xlsx
3399 ScDocShellRef xShell = loadDoc("ceiling-floor.", FORMAT_ODS);
3400 CPPUNIT_ASSERT_MESSAGE("Failed to load the document.", xShell.is());
3402 std::shared_ptr<utl::TempFile> pXPathFile = ScBootstrapFixture::exportTo(&(*xShell), FORMAT_XLSX);
3403 xmlDocUniquePtr pSheet = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/workbook.xml");
3404 CPPUNIT_ASSERT(pSheet);
3406 // there shouldn't be any defined names during export of FLOOR and CEILING functions to .xlsx
3407 assertXPath(pSheet, "/x:workbook/x:definedNames", 0);
3409 xShell->DoClose();
3412 void ScExportTest::testCeilingFloorXLS()
3414 testCeilingFloor(FORMAT_XLS);
3417 void ScExportTest::testCeilingFloorODS()
3419 testCeilingFloor(FORMAT_ODS);
3422 void ScExportTest::testCustomXml()
3424 // Load document and export it to a temporary file
3425 ScDocShellRef xShell = loadDoc("customxml.", FORMAT_XLSX);
3426 CPPUNIT_ASSERT_MESSAGE("Failed to load the document.", xShell.is());
3428 std::shared_ptr<utl::TempFile> pXPathFile = ScBootstrapFixture::exportTo(&(*xShell), FORMAT_XLSX);
3429 xmlDocUniquePtr pXmlDoc = XPathHelper::parseExport(pXPathFile, m_xSFactory, "customXml/item1.xml");
3430 CPPUNIT_ASSERT(pXmlDoc);
3431 xmlDocUniquePtr pRelsDoc = XPathHelper::parseExport(pXPathFile, m_xSFactory, "customXml/_rels/item1.xml.rels");
3432 CPPUNIT_ASSERT(pRelsDoc);
3434 // Check there is a relation to itemProps1.xml.
3435 assertXPath(pRelsDoc, "/r:Relationships/r:Relationship", 1);
3436 assertXPath(pRelsDoc, "/r:Relationships/r:Relationship[@Id='rId1']", "Target", "itemProps1.xml");
3438 std::unique_ptr<SvStream> pStream = XPathHelper::parseExportStream(pXPathFile, m_xSFactory, "ddp/ddpfile.xen");
3439 CPPUNIT_ASSERT(pStream);
3441 xShell->DoClose();
3444 #ifdef _WIN32
3445 static sal_Unicode lcl_getWindowsDrive(const OUString& aURL)
3447 static const sal_Int32 nMinLen = strlen("file:///X:/");
3448 if (aURL.getLength() <= nMinLen)
3449 return 0;
3450 const OUString aUrlStart = aURL.copy(0, nMinLen);
3451 return (aUrlStart.startsWith("file:///") && aUrlStart.endsWith(":/")) ? aUrlStart[8] : 0;
3453 #endif
3455 void ScExportTest::testRelativePathsODS()
3457 ScDocShellRef xDocSh = loadDoc("fdo79305.", FORMAT_ODS);
3458 CPPUNIT_ASSERT(xDocSh.is());
3460 std::shared_ptr<utl::TempFile> pTempFile = exportTo(xDocSh.get(), FORMAT_ODS);
3461 xmlDocUniquePtr pDoc = XPathHelper::parseExport(pTempFile, m_xSFactory, "content.xml");
3462 CPPUNIT_ASSERT(pDoc);
3463 OUString aURL = getXPath(pDoc,
3464 "/office:document-content/office:body/office:spreadsheet/table:table/table:table-row[2]/table:table-cell[2]/text:p/text:a", "href");
3465 #ifdef _WIN32
3466 // if the exported document is not on the same drive then the linked document,
3467 // there is no way to get a relative URL for the link, because ../X:/ is undefined.
3468 if (!aURL.startsWith(".."))
3470 sal_Unicode aDocDrive = lcl_getWindowsDrive(pTempFile->GetURL());
3471 sal_Unicode aLinkDrive = lcl_getWindowsDrive(aURL);
3472 CPPUNIT_ASSERT_MESSAGE("document on the same drive but no relative link!",
3473 aDocDrive != 0 && aLinkDrive != 0 && aDocDrive != aLinkDrive);
3474 return;
3476 #endif
3477 // make sure that the URL is relative
3478 CPPUNIT_ASSERT(aURL.startsWith(".."));
3480 xDocSh->DoClose();
3483 namespace {
3485 void testSheetProtection_Impl(const ScDocument& rDoc)
3487 CPPUNIT_ASSERT(rDoc.IsTabProtected(0));
3488 ScTableProtection* pTabProtection = rDoc.GetTabProtection(0);
3489 CPPUNIT_ASSERT(pTabProtection);
3490 CPPUNIT_ASSERT(pTabProtection->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS));
3491 CPPUNIT_ASSERT(!pTabProtection->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS));
3496 void ScExportTest::testSheetProtectionODS()
3498 ScDocShellRef xDocSh = loadDoc("sheet-protection.", FORMAT_ODS);
3499 CPPUNIT_ASSERT(xDocSh.is());
3502 ScDocument& rDoc = xDocSh->GetDocument();
3503 testSheetProtection_Impl(rDoc);
3506 ScDocShellRef xDocSh2 = saveAndReload(xDocSh.get(), FORMAT_ODS);
3508 ScDocument& rDoc = xDocSh2->GetDocument();
3509 testSheetProtection_Impl(rDoc);
3512 xDocSh2->DoClose();
3515 void ScExportTest::testFunctionsExcel2010ODS()
3517 //testFunctionsExcel2010(FORMAT_ODS);
3520 void ScExportTest::testSwappedOutImageExport()
3522 const char* aFilterNames[] = {
3523 "calc8",
3524 "MS Excel 97",
3525 "Calc Office Open XML",
3526 "generic_HTML",
3529 // Set cache size to a very small value to make sure one of the images is swapped out
3530 std::shared_ptr< comphelper::ConfigurationChanges > xBatch(comphelper::ConfigurationChanges::create());
3531 officecfg::Office::Common::Cache::GraphicManager::TotalCacheSize::set(sal_Int32(1), xBatch);
3532 xBatch->commit();
3534 for( size_t nFilter = 0; nFilter < SAL_N_ELEMENTS(aFilterNames); ++nFilter )
3536 // Check whether the export code swaps in the image which was swapped out before.
3537 ScDocShellRef xDocSh = loadDoc("document_with_two_images.", FORMAT_ODS);
3539 const OString sFailedMessage = OStringLiteral("Failed on filter: ") + aFilterNames[nFilter];
3540 CPPUNIT_ASSERT_MESSAGE(sFailedMessage.getStr(), xDocSh.is());
3542 // Export the document and import again for a check
3543 ScDocShellRef xDocSh2 = saveAndReload(xDocSh.get(), nFilter);
3544 xDocSh->DoClose();
3546 // Check whether graphic exported well after it was swapped out
3547 uno::Reference< frame::XModel > xModel = xDocSh2->GetModel();
3548 uno::Reference< sheet::XSpreadsheetDocument > xDoc(xModel, UNO_QUERY_THROW);
3549 uno::Reference< container::XIndexAccess > xIA(xDoc->getSheets(), UNO_QUERY_THROW);
3550 uno::Reference< drawing::XDrawPageSupplier > xDrawPageSupplier( xIA->getByIndex(0), UNO_QUERY_THROW);
3551 uno::Reference< container::XIndexAccess > xDraws(xDrawPageSupplier->getDrawPage(), UNO_QUERY_THROW);
3552 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), static_cast<sal_Int32>(2), xDraws->getCount());
3554 uno::Reference<drawing::XShape> xImage(xDraws->getByIndex(0), uno::UNO_QUERY);
3555 uno::Reference< beans::XPropertySet > XPropSet( xImage, uno::UNO_QUERY_THROW );
3557 // Check Graphic, Size
3559 uno::Reference<graphic::XGraphic> xGraphic;
3560 XPropSet->getPropertyValue("Graphic") >>= xGraphic;
3561 CPPUNIT_ASSERT_MESSAGE(sFailedMessage.getStr(), xGraphic.is());
3562 CPPUNIT_ASSERT_MESSAGE(sFailedMessage.getStr(), xGraphic->getType() != graphic::GraphicType::EMPTY);
3563 uno::Reference<awt::XBitmap> xBitmap(xGraphic, uno::UNO_QUERY);
3564 CPPUNIT_ASSERT_MESSAGE(sFailedMessage.getStr(), xBitmap.is());
3565 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), static_cast<sal_Int32>(610), xBitmap->getSize().Width );
3566 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), static_cast<sal_Int32>(381), xBitmap->getSize().Height );
3568 // Second Image
3569 xImage.set(xDraws->getByIndex(1), uno::UNO_QUERY);
3570 XPropSet.set( xImage, uno::UNO_QUERY_THROW );
3572 // Check Graphic, Size
3574 uno::Reference<graphic::XGraphic> xGraphic;
3575 XPropSet->getPropertyValue("Graphic") >>= xGraphic;
3576 CPPUNIT_ASSERT_MESSAGE(sFailedMessage.getStr(), xGraphic.is());
3577 CPPUNIT_ASSERT_MESSAGE(sFailedMessage.getStr(), xGraphic->getType() != graphic::GraphicType::EMPTY);
3578 uno::Reference<awt::XBitmap> xBitmap(xGraphic, uno::UNO_QUERY);
3579 CPPUNIT_ASSERT_MESSAGE(sFailedMessage.getStr(), xBitmap.is());
3580 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), static_cast<sal_Int32>(900), xBitmap->getSize().Width );
3581 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), static_cast<sal_Int32>(600), xBitmap->getSize().Height );
3583 xDocSh2->DoClose();
3587 ScExportTest::ScExportTest()
3588 : ScBootstrapFixture("sc/qa/unit/data")
3592 void ScExportTest::setUp()
3594 test::BootstrapFixture::setUp();
3596 // This is a bit of a fudge, we do this to ensure that ScGlobals::ensure,
3597 // which is a private symbol to us, gets called
3598 m_xCalcComponent =
3599 getMultiServiceFactory()->createInstance("com.sun.star.comp.Calc.SpreadsheetDocument");
3600 CPPUNIT_ASSERT_MESSAGE("no calc component!", m_xCalcComponent.is());
3603 void ScExportTest::tearDown()
3605 uno::Reference< lang::XComponent >( m_xCalcComponent, UNO_QUERY_THROW )->dispose();
3606 test::BootstrapFixture::tearDown();
3609 void ScExportTest::testSupBookVirtualPathXLS()
3611 ScDocShellRef xShell = loadDoc("external-ref.", FORMAT_XLS);
3612 CPPUNIT_ASSERT(xShell.is());
3614 ScDocShellRef xDocSh = saveAndReload(xShell.get(), FORMAT_XLS);
3615 xShell->DoClose();
3616 CPPUNIT_ASSERT(xDocSh.is());
3618 ScDocument& rDoc = xDocSh->GetDocument();
3620 ScAddress aPos(0,0,0);
3621 ScTokenArray* pCode = getTokens(rDoc, aPos);
3622 if (!pCode)
3623 CppUnit::Asserter::fail("empty token array", CPPUNIT_SOURCELINE());
3625 OUString aFormula = toString(rDoc, aPos, *pCode, rDoc.GetGrammar());
3626 #ifdef _WIN32
3627 aFormula = aFormula.copy(0, 9) + aFormula.copy(12); // strip drive letter, e.g. 'C:/'
3628 #endif
3629 OUString aExpectedFormula = "'file:///home/timar/Documents/external.xls'#$Sheet1.A1";
3630 if (aFormula != aExpectedFormula)
3632 CppUnit::Asserter::failNotEqual(to_std_string(aExpectedFormula),
3633 to_std_string(aFormula), CPPUNIT_SOURCELINE(), CppUnit::AdditionalMessage("Wrong SupBook VirtualPath URL"));
3636 xDocSh->DoClose();
3639 void ScExportTest::testLinkedGraphicRT()
3641 // Problem was with linked images
3642 const char* aFilterNames[] = {
3643 "calc8",
3644 "MS Excel 97",
3645 "Calc Office Open XML",
3646 "generic_HTML",
3649 for( size_t nFilter = 0; nFilter < SAL_N_ELEMENTS(aFilterNames); ++nFilter )
3651 // Load the original file with one image
3652 ScDocShellRef xDocSh = loadDoc("document_with_linked_graphic.", FORMAT_ODS);
3653 const OString sFailedMessage = OStringLiteral("Failed on filter: ") + aFilterNames[nFilter];
3655 // Export the document and import again for a check
3656 ScDocShellRef xDocSh2 = saveAndReload(xDocSh.get(), nFilter);
3657 xDocSh->DoClose();
3659 // Check whether graphic imported well after export
3660 ScDocument& rDoc = xDocSh->GetDocument();
3661 ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer();
3662 CPPUNIT_ASSERT_MESSAGE( sFailedMessage.getStr(), pDrawLayer != nullptr );
3663 const SdrPage *pPage = pDrawLayer->GetPage(0);
3664 CPPUNIT_ASSERT_MESSAGE( sFailedMessage.getStr(), pPage != nullptr );
3665 SdrGrafObj* pObject = dynamic_cast<SdrGrafObj*>(pPage->GetObj(0));
3666 CPPUNIT_ASSERT_MESSAGE( sFailedMessage.getStr(), pObject != nullptr );
3667 CPPUNIT_ASSERT_MESSAGE( sFailedMessage.getStr(), pObject->IsLinkedGraphic() );
3669 const GraphicObject& rGraphicObj = pObject->GetGraphicObject(true);
3670 CPPUNIT_ASSERT_EQUAL_MESSAGE( sFailedMessage.getStr(), int(GraphicType::Bitmap), int(rGraphicObj.GetGraphic().GetType()));
3671 CPPUNIT_ASSERT_EQUAL_MESSAGE( sFailedMessage.getStr(), sal_uLong(864900), rGraphicObj.GetGraphic().GetSizeBytes());
3673 xDocSh2->DoClose();
3677 void ScExportTest::testImageWithSpecialID()
3679 const char* aFilterNames[] = {
3680 "calc8",
3681 "MS Excel 97",
3682 "Calc Office Open XML",
3683 "generic_HTML",
3686 // Trigger swap out mechanism to test swapped state factor too.
3687 std::shared_ptr< comphelper::ConfigurationChanges > batch(comphelper::ConfigurationChanges::create());
3688 officecfg::Office::Common::Cache::GraphicManager::TotalCacheSize::set(sal_Int32(1), batch);
3689 batch->commit();
3691 for( size_t nFilter = 0; nFilter < SAL_N_ELEMENTS(aFilterNames); ++nFilter )
3693 ScDocShellRef xDocSh = loadDoc("images_with_special_IDs.", FORMAT_ODS);
3695 const OString sFailedMessage = OStringLiteral("Failed on filter: ") + aFilterNames[nFilter];
3696 CPPUNIT_ASSERT_MESSAGE(sFailedMessage.getStr(), xDocSh.is());
3698 // Export the document and import again for a check
3699 ScDocShellRef xDocSh2 = saveAndReload(xDocSh.get(), nFilter);
3700 xDocSh->DoClose();
3702 // Check whether graphic was exported well
3703 uno::Reference< frame::XModel > xModel = xDocSh2->GetModel();
3704 uno::Reference< sheet::XSpreadsheetDocument > xDoc(xModel, UNO_QUERY_THROW);
3705 uno::Reference< container::XIndexAccess > xIA(xDoc->getSheets(), UNO_QUERY_THROW);
3706 uno::Reference< drawing::XDrawPageSupplier > xDrawPageSupplier( xIA->getByIndex(0), UNO_QUERY_THROW);
3707 uno::Reference< container::XIndexAccess > xDraws(xDrawPageSupplier->getDrawPage(), UNO_QUERY_THROW);
3708 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), static_cast<sal_Int32>(2), xDraws->getCount());
3710 uno::Reference<drawing::XShape> xImage(xDraws->getByIndex(0), uno::UNO_QUERY);
3711 uno::Reference< beans::XPropertySet > XPropSet( xImage, uno::UNO_QUERY_THROW );
3713 // Check Graphic, Size
3715 uno::Reference<graphic::XGraphic> xGraphic;
3716 XPropSet->getPropertyValue("Graphic") >>= xGraphic;
3717 CPPUNIT_ASSERT_MESSAGE(sFailedMessage.getStr(), xGraphic.is());
3718 CPPUNIT_ASSERT_MESSAGE(sFailedMessage.getStr(), xGraphic->getType() != graphic::GraphicType::EMPTY);
3719 uno::Reference<awt::XBitmap> xBitmap(xGraphic, uno::UNO_QUERY);
3720 CPPUNIT_ASSERT_MESSAGE(sFailedMessage.getStr(), xBitmap.is());
3721 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), static_cast<sal_Int32>(610), xBitmap->getSize().Width );
3722 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), static_cast<sal_Int32>(381), xBitmap->getSize().Height );
3724 // Second Image
3725 xImage.set(xDraws->getByIndex(1), uno::UNO_QUERY);
3726 XPropSet.set( xImage, uno::UNO_QUERY_THROW );
3728 // Check Graphic, Size
3730 uno::Reference<graphic::XGraphic> xGraphic;
3731 XPropSet->getPropertyValue("Graphic") >>= xGraphic;
3732 CPPUNIT_ASSERT_MESSAGE(sFailedMessage.getStr(), xGraphic.is());
3733 CPPUNIT_ASSERT_MESSAGE(sFailedMessage.getStr(), xGraphic->getType() != graphic::GraphicType::EMPTY);
3734 uno::Reference<awt::XBitmap> xBitmap(xGraphic, uno::UNO_QUERY);
3735 CPPUNIT_ASSERT_MESSAGE(sFailedMessage.getStr(), xBitmap.is());
3736 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), static_cast<sal_Int32>(900), xBitmap->getSize().Width );
3737 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), static_cast<sal_Int32>(600), xBitmap->getSize().Height );
3739 xDocSh2->DoClose();
3743 void ScExportTest::testAbsNamedRangeHTML()
3745 ScDocShellRef xDocSh = loadDoc("numberformat.", FORMAT_HTML);
3746 xDocSh->DoHardRecalc();
3747 ScDocShellRef xDocSh2 = saveAndReload(xDocSh.get(), FORMAT_ODS);
3748 xDocSh->DoClose();
3749 xDocSh2->DoHardRecalc();
3751 ScDocument& rDoc = xDocSh2->GetDocument();
3752 ScRangeData* pRangeData = rDoc.GetRangeName()->findByUpperName(OUString("HTML_1"));
3753 ScSingleRefData* pRef = pRangeData->GetCode()->FirstToken()->GetSingleRef();
3754 // see tdf#119141 for the reason why this isn't Sheet1.HTML_1
3755 CPPUNIT_ASSERT_MESSAGE("HTML_1 is an absolute reference",!pRef->IsTabRel());
3757 xDocSh2->DoClose();
3760 void ScExportTest::testSheetLocalRangeNameXLS()
3762 ScDocShellRef xDocSh = loadDoc("named-ranges-local.", FORMAT_XLS);
3763 xDocSh->DoHardRecalc();
3764 ScDocShellRef xDocSh2 = saveAndReload(xDocSh.get(), FORMAT_XLS);
3765 xDocSh->DoClose();
3766 xDocSh2->DoHardRecalc();
3768 ScDocument& rDoc = xDocSh2->GetDocument();
3769 ScRangeName* pRangeName = rDoc.GetRangeName(0);
3770 CPPUNIT_ASSERT(pRangeName);
3771 CPPUNIT_ASSERT_EQUAL(size_t(2), pRangeName->size());
3773 OUString aFormula;
3774 rDoc.GetFormula(3, 11, 0, aFormula);
3775 CPPUNIT_ASSERT_EQUAL(OUString("=SUM(local_name2)"), aFormula);
3776 ASSERT_DOUBLES_EQUAL(14.0, rDoc.GetValue(3, 11, 0));
3778 rDoc.GetFormula(6, 4, 0, aFormula);
3779 CPPUNIT_ASSERT_EQUAL(OUString("=local_name1"), aFormula);
3781 xDocSh2->DoClose();
3784 void ScExportTest::testRelativeNamedExpressionsXLS()
3786 ScDocShellRef xDocSh = loadDoc("tdf113991_relativeNamedRanges.", FORMAT_ODS);
3787 xDocSh->DoHardRecalc();
3788 ScDocShellRef xDocSh2 = saveAndReload(xDocSh.get(), FORMAT_XLS);
3789 xDocSh->DoClose();
3790 xDocSh2->DoHardRecalc();
3791 ScDocument& rDoc = xDocSh2->GetDocument();
3793 // Sheet1:G3
3794 ScAddress aPos(6,2,0);
3795 CPPUNIT_ASSERT_EQUAL(1.0, rDoc.GetValue(aPos));
3796 ASSERT_FORMULA_EQUAL(rDoc, aPos, "single_cell_A3", nullptr);
3797 // Sheet2:F6
3798 aPos = ScAddress(5,5,1);
3799 CPPUNIT_ASSERT_EQUAL(18.0, rDoc.GetValue(aPos));
3800 ASSERT_FORMULA_EQUAL(rDoc, aPos, "SUM(test_conflict)", nullptr);
3801 // Sheet2:H3
3802 aPos = ScAddress(7,2,1);
3803 CPPUNIT_ASSERT_EQUAL(10.0, rDoc.GetValue(aPos));
3804 ASSERT_FORMULA_EQUAL(rDoc, aPos, "single_global_A3", nullptr);
3805 // Sheet2:H6
3806 aPos = ScAddress(7,5,1);
3807 CPPUNIT_ASSERT_EQUAL(75.0, rDoc.GetValue(aPos));
3808 ASSERT_FORMULA_EQUAL(rDoc, aPos, "SUM(A6:F6)", nullptr);
3809 xDocSh2->DoClose();
3812 void ScExportTest::testSheetTextBoxHyperlinkXLSX()
3814 ScDocShellRef xShell = loadDoc("textbox-hyperlink.", FORMAT_XLSX);
3815 CPPUNIT_ASSERT(xShell.is());
3817 ScDocShellRef xDocSh = saveAndReload(&(*xShell), FORMAT_XLSX);
3818 CPPUNIT_ASSERT(xDocSh.is());
3820 xmlDocUniquePtr pDoc = XPathHelper::parseExport2(*this, *xDocSh, m_xSFactory, "xl/drawings/drawing1.xml", FORMAT_XLSX);
3821 CPPUNIT_ASSERT(pDoc);
3823 assertXPath(pDoc, "/xdr:wsDr[1]/xdr:twoCellAnchor[1]/xdr:sp[1]/xdr:nvSpPr[1]/xdr:cNvPr[1]/a:hlinkClick[1]", 1);
3825 xDocSh->DoClose();
3828 void ScExportTest::testFontSizeXLSX()
3830 ScDocShellRef xDocSh = loadDoc("fontSize.", FORMAT_XLSX);
3831 CPPUNIT_ASSERT(xDocSh.is());
3833 xmlDocUniquePtr pDoc = XPathHelper::parseExport2(*this, *xDocSh, m_xSFactory, "xl/drawings/drawing1.xml", FORMAT_XLSX);
3834 CPPUNIT_ASSERT(pDoc);
3835 OUString fontSize = getXPath(pDoc,
3836 "/xdr:wsDr/xdr:twoCellAnchor/xdr:sp[1]/xdr:txBody/a:p[1]/a:r[1]/a:rPr", "sz");
3837 // make sure that the font size is 18
3838 CPPUNIT_ASSERT_EQUAL(OUString("1800"), fontSize);
3840 xDocSh->DoClose();
3843 void ScExportTest::testSheetCharacterKerningSpaceXLSX()
3845 ScDocShellRef xShell = loadDoc("textbox-CharKerningSpace.", FORMAT_XLSX);
3846 CPPUNIT_ASSERT(xShell.is());
3848 ScDocShellRef xDocSh = saveAndReload(&(*xShell), FORMAT_XLSX);
3849 CPPUNIT_ASSERT(xDocSh.is());
3851 xmlDocUniquePtr pDoc = XPathHelper::parseExport2(*this, *xDocSh, m_xSFactory, "xl/drawings/drawing1.xml", FORMAT_XLSX);
3852 CPPUNIT_ASSERT(pDoc);
3854 OUString CharKerningSpace = getXPath(pDoc,
3855 "/xdr:wsDr[1]/xdr:twoCellAnchor[1]/xdr:sp[1]/xdr:txBody[1]/a:p[1]/a:r[1]/a:rPr[1]","spc");
3857 // make sure that the CharKerning is 1997.
3858 CPPUNIT_ASSERT_EQUAL(OUString("1997"), CharKerningSpace);
3860 xDocSh->DoClose();
3863 void ScExportTest::testSheetCondensedCharacterSpaceXLSX()
3865 ScDocShellRef xShell = loadDoc("textbox-CondensedCharacterSpace.", FORMAT_XLSX);
3866 CPPUNIT_ASSERT(xShell.is());
3868 ScDocShellRef xDocSh = saveAndReload(&(*xShell), FORMAT_XLSX);
3869 CPPUNIT_ASSERT(xDocSh.is());
3871 xmlDocUniquePtr pDoc = XPathHelper::parseExport2(*this, *xDocSh, m_xSFactory, "xl/drawings/drawing1.xml", FORMAT_XLSX);
3872 CPPUNIT_ASSERT(pDoc);
3874 OUString CondensedCharSpace = getXPath(pDoc,
3875 "/xdr:wsDr[1]/xdr:twoCellAnchor[1]/xdr:sp[1]/xdr:txBody[1]/a:p[1]/a:r[1]/a:rPr[1]","spc");
3877 // make sure that the CondensedCharSpace is -1002.
3878 CPPUNIT_ASSERT_EQUAL(OUString("-1002"), CondensedCharSpace);
3880 xDocSh->DoClose();
3883 void ScExportTest::testTextUnderlineColorXLSX()
3885 ScDocShellRef xDocSh = loadDoc("underlineColor.", FORMAT_XLSX);
3886 CPPUNIT_ASSERT(xDocSh.is());
3888 xmlDocUniquePtr pDoc = XPathHelper::parseExport2(*this, *xDocSh, m_xSFactory, "xl/drawings/drawing1.xml", FORMAT_XLSX);
3889 CPPUNIT_ASSERT(pDoc);
3890 // Make sure the underline type is double line
3891 assertXPath(pDoc, "/xdr:wsDr/xdr:twoCellAnchor[1]/xdr:sp[1]/xdr:txBody/a:p[1]/a:r[1]/a:rPr", "u", "dbl");
3893 assertXPath(pDoc, "/xdr:wsDr/xdr:twoCellAnchor[1]/xdr:sp[1]/xdr:txBody/a:p[1]/a:r[1]/a:rPr", "b", "1");
3894 // Make sure that the underline color is RED
3895 assertXPath(pDoc, "/xdr:wsDr/xdr:twoCellAnchor[1]/xdr:sp[1]/xdr:txBody/a:p[1]/a:r[1]/a:rPr/a:uFill/a:solidFill/a:srgbClr", "val", "ff0000");
3897 // Make sure the underline type is drawn with heavy line
3898 assertXPath(pDoc, "/xdr:wsDr/xdr:twoCellAnchor[2]/xdr:sp[1]/xdr:txBody/a:p[1]/a:r[1]/a:rPr", "u", "heavy");
3899 // tdf#104219 Make sure that uFill is not existing and uFillTx is set.
3900 // It mean that color is automatic, should be the same color as the text.
3901 assertXPath(pDoc, "/xdr:wsDr/xdr:twoCellAnchor[2]/xdr:sp[1]/xdr:txBody/a:p[1]/a:r[1]/a:rPr/a:uFill", 0);
3902 assertXPath(pDoc, "/xdr:wsDr/xdr:twoCellAnchor[2]/xdr:sp[1]/xdr:txBody/a:p[1]/a:r[1]/a:rPr/a:uFillTx", 1);
3904 xDocSh->DoClose();
3907 void ScExportTest::testSheetRunParagraphPropertyXLSX()
3909 ScDocShellRef xShell = loadDoc("TextColor.", FORMAT_XLSX);
3910 CPPUNIT_ASSERT(xShell.is());
3912 ScDocShellRef xDocSh = saveAndReload(&(*xShell), FORMAT_XLSX);
3913 CPPUNIT_ASSERT(xDocSh.is());
3915 xmlDocUniquePtr pDoc = XPathHelper::parseExport2(*this, *xDocSh, m_xSFactory, "xl/sharedStrings.xml", FORMAT_XLSX);
3916 CPPUNIT_ASSERT(pDoc);
3918 OUString aColor = getXPath(pDoc, "/x:sst/x:si/x:r[1]/x:rPr[1]/x:color", "rgb");
3919 CPPUNIT_ASSERT_EQUAL(OUString("FFFF0000"), aColor);
3921 xDocSh->DoClose();
3924 void ScExportTest::testPreserveTextWhitespaceXLSX()
3926 ScDocShellRef xShell = loadDoc("preserve-whitespace.", FORMAT_XLSX);
3927 ScDocShellRef xDocSh = saveAndReload(&(*xShell), FORMAT_XLSX);
3928 CPPUNIT_ASSERT(xDocSh.is());
3930 xmlDocUniquePtr pDoc = XPathHelper::parseExport2(*this, *xDocSh, m_xSFactory, "xl/sharedStrings.xml", FORMAT_XLSX);
3931 CPPUNIT_ASSERT(pDoc);
3932 assertXPath(pDoc, "/x:sst/x:si/x:t", "space", "preserve");
3933 xDocSh->DoClose();
3936 void ScExportTest::testPreserveTextWhitespace2XLSX()
3938 ScDocShellRef xShell = loadDoc("preserve_space.", FORMAT_XLSX);
3939 ScDocShellRef xDocSh = saveAndReload(&(*xShell), FORMAT_XLSX);
3940 CPPUNIT_ASSERT(xDocSh.is());
3942 xmlDocUniquePtr pDoc = XPathHelper::parseExport2(*this, *xDocSh, m_xSFactory, "xl/sharedStrings.xml", FORMAT_XLSX);
3943 CPPUNIT_ASSERT(pDoc);
3944 assertXPath(pDoc, "/x:sst/x:si[1]/x:t", "space", "preserve");
3945 assertXPath(pDoc, "/x:sst/x:si[2]/x:r[1]/x:t", "space", "preserve");
3946 assertXPath(pDoc, "/x:sst/x:si[2]/x:r[2]/x:t", "space", "preserve");
3947 xDocSh->DoClose();
3950 void ScExportTest::testHiddenShapeXLS()
3952 ScDocShellRef xDocSh = loadDoc("hiddenShape.", FORMAT_XLS);
3953 CPPUNIT_ASSERT(xDocSh.is());
3955 ScDocument& rDoc = xDocSh->GetDocument();
3956 CPPUNIT_ASSERT(rDoc.GetTableCount() > 0);
3957 ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer();
3958 SdrPage* pPage = pDrawLayer->GetPage(0);
3959 CPPUNIT_ASSERT(pPage);
3960 SdrObject* pObj = pPage->GetObj(0);
3961 CPPUNIT_ASSERT(pObj);
3962 CPPUNIT_ASSERT_MESSAGE("Drawing object should not be visible.", !pObj->IsVisible());
3963 CPPUNIT_ASSERT_MESSAGE("Drawing object should not be printable.", !pObj->IsPrintable());
3964 xDocSh->DoClose();
3967 void ScExportTest::testHiddenShapeXLSX()
3969 ScDocShellRef xDocSh = loadDoc("hiddenShape.", FORMAT_XLSX);
3970 CPPUNIT_ASSERT(xDocSh.is());
3972 ScDocument& rDoc = xDocSh->GetDocument();
3973 CPPUNIT_ASSERT(rDoc.GetTableCount() > 0);
3974 ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer();
3975 SdrPage* pPage = pDrawLayer->GetPage(0);
3976 CPPUNIT_ASSERT(pPage);
3977 SdrObject* pObj = pPage->GetObj(0);
3978 CPPUNIT_ASSERT(pObj);
3979 CPPUNIT_ASSERT_MESSAGE("Drawing object should not be visible.", !pObj->IsVisible());
3980 CPPUNIT_ASSERT_MESSAGE("Drawing object should not be printable.", !pObj->IsPrintable());
3982 xmlDocUniquePtr pDoc = XPathHelper::parseExport2(*this, *xDocSh, m_xSFactory, "xl/drawings/drawing1.xml", FORMAT_XLSX);
3983 CPPUNIT_ASSERT(pDoc);
3984 assertXPath(pDoc, "/xdr:wsDr/xdr:twoCellAnchor/xdr:sp[1]/xdr:nvSpPr/xdr:cNvPr", "hidden", "1");
3985 xDocSh->DoClose();
3988 void ScExportTest::testShapeAutofitXLSX()
3990 ScDocShellRef xDocSh = loadDoc("testShapeAutofit.", FORMAT_XLSX);
3991 CPPUNIT_ASSERT(xDocSh.is());
3993 xmlDocUniquePtr pDoc = XPathHelper::parseExport2(*this, *xDocSh, m_xSFactory, "xl/drawings/drawing1.xml", FORMAT_XLSX);
3994 CPPUNIT_ASSERT(pDoc);
3996 // TextAutoGrowHeight --> "Fit height to text" / "Resize shape to fit text" --> true
3997 assertXPath(pDoc, "/xdr:wsDr/xdr:twoCellAnchor[1]/xdr:sp/xdr:txBody/a:bodyPr/a:spAutoFit", 1);
3998 // TextAutoGrowHeight --> "Fit height to text" / "Resize shape to fit text" --> false
3999 assertXPath(pDoc, "/xdr:wsDr/xdr:twoCellAnchor[2]/xdr:sp/xdr:txBody/a:bodyPr/a:noAutofit", 1);
4001 xDocSh->DoClose();
4004 void ScExportTest::testHyperlinkXLSX()
4006 ScDocShellRef xDocSh = loadDoc("hyperlink.", FORMAT_XLSX);
4007 CPPUNIT_ASSERT(xDocSh.is());
4009 xmlDocUniquePtr pDoc = XPathHelper::parseExport2(*this, *xDocSh, m_xSFactory, "xl/drawings/_rels/drawing1.xml.rels", FORMAT_XLSX);
4010 CPPUNIT_ASSERT(pDoc);
4011 assertXPath(pDoc, "/r:Relationships/r:Relationship", "Target", "#Sheet2!A1");
4013 xDocSh->DoClose();
4016 void ScExportTest::testMoveCellAnchoredShapesODS()
4018 ScDocShellRef xDocSh = loadDoc("move-cell-anchored-shapes.", FORMAT_ODS);
4019 CPPUNIT_ASSERT_MESSAGE("Failed to load move-cell-anchored-shapes.ods", xDocSh.is());
4021 // There are two cell-anchored objects on the first sheet.
4022 ScDocument& rDoc = xDocSh->GetDocument();
4024 CPPUNIT_ASSERT_MESSAGE("There should be at least one sheet.", rDoc.GetTableCount() > 0);
4026 ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer();
4027 SdrPage* pPage = pDrawLayer->GetPage(0);
4028 CPPUNIT_ASSERT_MESSAGE("draw page for sheet 1 should exist.", pPage);
4029 SdrObject* pObj = pPage->GetObj(0);
4030 CPPUNIT_ASSERT_MESSAGE("Failed to get drawing object.", pObj);
4032 // Check cell anchor state
4033 ScAnchorType oldType = ScDrawLayer::GetAnchorType(*pObj);
4034 CPPUNIT_ASSERT_EQUAL_MESSAGE( "Failed to get anchor type", SCA_CELL_RESIZE, oldType);
4036 // Get anchor data
4037 ScDrawObjData* pData = ScDrawLayer::GetObjData(pObj);
4038 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve user data for this object.", pData);
4039 CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pData->getShapeRect().IsEmpty());
4041 ScAddress aDataStart = pData->maStart;
4042 ScAddress aDataEnd = pData->maEnd;
4044 // Get non rotated anchor data
4045 ScDrawObjData* pNData = ScDrawLayer::GetNonRotatedObjData( pObj );
4046 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve non rotated user data for this object.", pNData);
4047 CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pNData->getShapeRect().IsEmpty());
4049 ScAddress aNDataStart = pNData->maStart;
4050 ScAddress aNDataEnd = pNData->maEnd;
4051 CPPUNIT_ASSERT_EQUAL(aDataStart, aNDataStart);
4052 CPPUNIT_ASSERT_EQUAL(aDataEnd , aNDataEnd);
4054 // Insert 2 rows.
4055 rDoc.InsertRow(ScRange( 0, aDataStart.Row() - 1, 0, MAXCOL, aDataStart.Row(), 0));
4057 // Get anchor data
4058 pData = ScDrawLayer::GetObjData(pObj);
4059 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve user data for this object.", pData);
4060 CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pData->getShapeRect().IsEmpty());
4062 // Get non rotated anchor data
4063 pNData = ScDrawLayer::GetNonRotatedObjData( pObj );
4064 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve non rotated user data for this object.", pNData);
4065 CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pNData->getShapeRect().IsEmpty());
4067 // Check if data has moved to new rows
4068 CPPUNIT_ASSERT_EQUAL( pData->maStart.Row(), aDataStart.Row() + 2 );
4069 CPPUNIT_ASSERT_EQUAL( pData->maEnd.Row(), aDataEnd.Row() + 2 );
4071 CPPUNIT_ASSERT_EQUAL( pNData->maStart.Row(), aNDataStart.Row() + 2 );
4072 CPPUNIT_ASSERT_EQUAL( pNData->maEnd.Row(), aNDataEnd.Row() + 2 );
4074 // Save the anchor data
4075 aDataStart = pData->maStart;
4076 aDataEnd = pData->maEnd;
4077 aNDataStart = pNData->maStart;
4078 aNDataEnd = pNData->maEnd;
4080 // Save the document and load again to check anchor persist
4081 ScDocShellRef xDocSh1 = saveAndReload(&(*xDocSh), FORMAT_ODS);
4083 // There are two cell-anchored objects on the first sheet.
4084 ScDocument& rDoc1 = xDocSh1->GetDocument();
4086 CPPUNIT_ASSERT_MESSAGE("There should be at least one sheet.", rDoc1.GetTableCount() > 0);
4088 pDrawLayer = rDoc1.GetDrawLayer();
4089 pPage = pDrawLayer->GetPage(0);
4090 CPPUNIT_ASSERT_MESSAGE("draw page for sheet 1 should exist.", pPage);
4091 pObj = pPage->GetObj(0);
4092 CPPUNIT_ASSERT_MESSAGE("Failed to get drawing object.", pObj);
4094 // Check cell anchor state
4095 oldType = ScDrawLayer::GetAnchorType(*pObj);
4096 CPPUNIT_ASSERT_EQUAL_MESSAGE( "Failed to get anchor type", SCA_CELL_RESIZE, oldType);
4098 // Get anchor data
4099 pData = ScDrawLayer::GetObjData(pObj);
4100 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve user data for this object.", pData);
4101 CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pData->getShapeRect().IsEmpty());
4103 // Get non rotated anchor data
4104 pNData = ScDrawLayer::GetNonRotatedObjData( pObj );
4105 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve non rotated user data for this object.", pNData);
4106 CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pNData->getShapeRect().IsEmpty());
4108 // Check if data after save it
4109 CPPUNIT_ASSERT_EQUAL(pData->maStart, aDataStart);
4110 CPPUNIT_ASSERT_EQUAL(pData->maEnd , aDataEnd);
4112 CPPUNIT_ASSERT_EQUAL(pNData->maStart, aNDataStart);
4113 CPPUNIT_ASSERT_EQUAL(pNData->maEnd , aNDataEnd);
4115 // Insert a column.
4116 rDoc1.InsertCol(ScRange( aDataStart.Col(), 0 , 0 , aDataStart.Col(), MAXROW, 0 ));
4118 // Get anchor data
4119 pData = ScDrawLayer::GetObjData(pObj);
4120 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve user data for this object.", pData);
4121 CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pData->getShapeRect().IsEmpty());
4123 // Get non rotated anchor data
4124 pNData = ScDrawLayer::GetNonRotatedObjData( pObj );
4125 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve non rotated user data for this object.", pNData);
4126 CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pNData->getShapeRect().IsEmpty());
4128 // Check if data has moved to new rows
4129 CPPUNIT_ASSERT_EQUAL(pData->maStart.Col(), SCCOL(aDataStart.Col() + 1));
4130 CPPUNIT_ASSERT_EQUAL(pData->maEnd.Col() , SCCOL(aDataEnd.Col() + 1));
4132 CPPUNIT_ASSERT_EQUAL(pNData->maStart.Col(), SCCOL(aNDataStart.Col() + 1));
4133 CPPUNIT_ASSERT_EQUAL(pNData->maEnd.Col() , SCCOL(aNDataEnd.Col() + 1));
4135 // Save the anchor data
4136 aDataStart = pData->maStart;
4137 aDataEnd = pData->maEnd;
4138 aNDataStart = pNData->maStart;
4139 aNDataEnd = pNData->maEnd;
4141 // Save the document and load again to check anchor persist
4142 ScDocShellRef xDocSh2 = saveAndReload(&(*xDocSh1), FORMAT_ODS);
4144 // There are two cell-anchored objects on the first sheet.
4145 ScDocument& rDoc2 = xDocSh2->GetDocument();
4147 CPPUNIT_ASSERT_MESSAGE("There should be at least one sheet.", rDoc2.GetTableCount() > 0);
4149 pDrawLayer = rDoc2.GetDrawLayer();
4150 pPage = pDrawLayer->GetPage(0);
4151 CPPUNIT_ASSERT_MESSAGE("draw page for sheet 1 should exist.", pPage);
4152 pObj = pPage->GetObj(0);
4153 CPPUNIT_ASSERT_MESSAGE("Failed to get drawing object.", pObj);
4155 // Check cell anchor state
4156 oldType = ScDrawLayer::GetAnchorType(*pObj);
4157 CPPUNIT_ASSERT_EQUAL_MESSAGE( "Failed to get anchor type", SCA_CELL_RESIZE, oldType);
4159 // Get anchor data
4160 pData = ScDrawLayer::GetObjData(pObj);
4161 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve user data for this object.", pData);
4162 CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pData->getShapeRect().IsEmpty());
4164 // Get non rotated anchor data
4165 pNData = ScDrawLayer::GetNonRotatedObjData( pObj );
4166 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve non rotated user data for this object.", pNData);
4167 CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pNData->getShapeRect().IsEmpty());
4169 // Check if data after save it
4170 CPPUNIT_ASSERT_EQUAL(pData->maStart, aDataStart);
4171 CPPUNIT_ASSERT_EQUAL(pData->maEnd , aDataEnd);
4173 CPPUNIT_ASSERT_EQUAL(pNData->maStart, aNDataStart);
4174 CPPUNIT_ASSERT_EQUAL(pNData->maEnd , aNDataEnd);
4176 xDocSh2->DoClose();
4179 void ScExportTest::testMatrixMultiplicationXLSX()
4181 ScDocShellRef xShell = loadDoc("matrix-multiplication.", FORMAT_XLSX);
4182 CPPUNIT_ASSERT(xShell.is());
4184 ScDocShellRef xDocSh = saveAndReload(&(*xShell), FORMAT_XLSX);
4185 CPPUNIT_ASSERT(xDocSh.is());
4187 xmlDocUniquePtr pDoc = XPathHelper::parseExport2(*this, *xDocSh, m_xSFactory, "xl/worksheets/sheet1.xml", FORMAT_XLSX);
4188 CPPUNIT_ASSERT(pDoc);
4190 OUString CellFormulaRange = getXPath(pDoc,
4191 "/x:worksheet/x:sheetData/x:row[4]/x:c/x:f","ref");
4193 // make sure that the CellFormulaRange is G5:G6.
4194 CPPUNIT_ASSERT_EQUAL(OUString("G5:G6"), CellFormulaRange);
4196 OUString CellFormulaType = getXPath(pDoc,
4197 "/x:worksheet/x:sheetData/x:row[4]/x:c/x:f","t");
4199 // make sure that the CellFormulaType is array.
4200 CPPUNIT_ASSERT_EQUAL(OUString("array"), CellFormulaType);
4202 xDocSh->DoClose();
4205 void ScExportTest::testRefStringXLSX()
4207 ScDocShellRef xDocSh = loadDoc("ref_string.", FORMAT_XLSX);
4208 CPPUNIT_ASSERT_MESSAGE("Failed to open doc", xDocSh.is());
4210 //make sure ref syntax gets saved for MSO-produced docs
4211 xDocSh = saveAndReload( &(*xDocSh), FORMAT_XLSX);
4212 CPPUNIT_ASSERT_MESSAGE("Failed to reload doc", xDocSh.is());
4214 ScDocument& rDoc = xDocSh->GetDocument();
4215 ScCalcConfig aCalcConfig = rDoc.GetCalcConfig();
4216 CPPUNIT_ASSERT_EQUAL(formula::FormulaGrammar::CONV_XL_A1, aCalcConfig.meStringRefAddressSyntax);
4218 xDocSh->DoClose();
4221 void ScExportTest::testRefStringConfigXLSX()
4223 // this doc is configured with CalcA1 ref syntax
4224 ScDocShellRef xDocSh = loadDoc("empty.", FORMAT_XLSX);
4225 CPPUNIT_ASSERT_MESSAGE("Failed to open doc", xDocSh.is());
4227 xDocSh = saveAndReload( &(*xDocSh), FORMAT_XLSX);
4228 CPPUNIT_ASSERT_MESSAGE("Failed to reload doc", xDocSh.is());
4230 ScDocument& rDoc = xDocSh->GetDocument();
4231 ScCalcConfig aConfig = rDoc.GetCalcConfig();
4232 CPPUNIT_ASSERT_EQUAL_MESSAGE("String ref syntax doesn't match", formula::FormulaGrammar::CONV_OOO,
4233 aConfig.meStringRefAddressSyntax);
4235 xDocSh->DoClose();
4237 // this doc has no entry for ref syntax
4238 xDocSh = loadDoc("empty-noconf.", FORMAT_XLSX);
4239 CPPUNIT_ASSERT_MESSAGE("Failed to open 2nd doc", xDocSh.is());
4241 ScDocument& rDoc2 = xDocSh->GetDocument();
4242 aConfig = rDoc2.GetCalcConfig();
4243 // therefore after import, ref syntax should be set to CalcA1 | ExcelA1
4244 CPPUNIT_ASSERT_EQUAL_MESSAGE("String ref syntax doesn't match", formula::FormulaGrammar::CONV_A1_XL_A1,
4245 aConfig.meStringRefAddressSyntax);
4247 //set ref syntax to something else than ExcelA1 (native to xlsx format) ...
4248 aConfig.meStringRefAddressSyntax = formula::FormulaGrammar::CONV_XL_R1C1;
4249 rDoc2.SetCalcConfig( aConfig );
4251 ScDocShellRef xNewDocSh = saveAndReload( &(*xDocSh), FORMAT_XLSX);
4252 CPPUNIT_ASSERT_MESSAGE("Failed to reload 2nd doc", xNewDocSh.is());
4254 // ... and make sure it got saved
4255 ScDocument& rDoc3 = xNewDocSh->GetDocument();
4256 aConfig = rDoc3.GetCalcConfig();
4257 CPPUNIT_ASSERT_EQUAL_MESSAGE("String ref syntax doesn't match", formula::FormulaGrammar::CONV_XL_R1C1,
4258 aConfig.meStringRefAddressSyntax);
4260 xDocSh->DoClose();
4261 xNewDocSh->DoClose();
4264 void ScExportTest::testRefStringUnspecified()
4266 ScDocShell* pShell = new ScDocShell(
4267 SfxModelFlags::EMBEDDED_OBJECT |
4268 SfxModelFlags::DISABLE_EMBEDDED_SCRIPTS |
4269 SfxModelFlags::DISABLE_DOCUMENT_RECOVERY);
4270 pShell->DoInitNew();
4272 ScDocument& rDoc = pShell->GetDocument();
4273 ScCalcConfig aConfig = rDoc.GetCalcConfig();
4274 CPPUNIT_ASSERT_EQUAL_MESSAGE("Default string ref syntax value doesn't match", formula::FormulaGrammar::CONV_UNSPECIFIED,
4275 aConfig.meStringRefAddressSyntax);
4277 // change formula syntax (i.e. not string ref syntax) to ExcelA1
4278 rDoc.SetGrammar( formula::FormulaGrammar::GRAM_NATIVE_XL_A1 );
4280 ScDocShellRef xDocSh = saveAndReload(pShell, FORMAT_ODS);
4281 CPPUNIT_ASSERT_MESSAGE("Failed to reload doc", xDocSh.is());
4283 // with string ref syntax at its default value, we should've saved ExcelA1
4284 ScDocument& rDoc2 = xDocSh->GetDocument();
4285 aConfig = rDoc2.GetCalcConfig();
4286 CPPUNIT_ASSERT_EQUAL_MESSAGE("String ref syntax doesn't match", formula::FormulaGrammar::CONV_XL_A1,
4287 aConfig.meStringRefAddressSyntax);
4289 xDocSh->DoClose();
4292 void ScExportTest::testHeaderImageODS()
4294 // Graphic as header background was lost on export.
4295 ScDocShellRef xShell = loadDoc("header-image.", FORMAT_ODS);
4296 ScDocShellRef xDocSh = saveAndReload(&(*xShell), FORMAT_ODS);
4297 uno::Reference<style::XStyleFamiliesSupplier> xStyleFamiliesSupplier(xDocSh->GetModel(), uno::UNO_QUERY);
4298 uno::Reference<container::XNameAccess> xStyleFamilies = xStyleFamiliesSupplier->getStyleFamilies();
4299 uno::Reference<container::XNameAccess> xPageStyles(xStyleFamilies->getByName("PageStyles"), uno::UNO_QUERY);
4300 uno::Reference<beans::XPropertySet> xStyle(xPageStyles->getByName("Default"), uno::UNO_QUERY);
4302 uno::Reference<graphic::XGraphic> xGraphic;
4303 xStyle->getPropertyValue("HeaderBackGraphic") >>= xGraphic;
4304 CPPUNIT_ASSERT(xGraphic.is());
4305 xDocSh->DoClose();
4308 void ScExportTest::testTextDirectionXLSX()
4310 ScDocShellRef xDocSh = loadDoc("writingMode.", FORMAT_XLSX);
4311 CPPUNIT_ASSERT(xDocSh.is());
4313 xmlDocUniquePtr pDoc = XPathHelper::parseExport2(*this, *xDocSh, m_xSFactory, "xl/styles.xml", FORMAT_XLSX);
4314 CPPUNIT_ASSERT(pDoc);
4316 assertXPath(pDoc, "/x:styleSheet/x:cellXfs/x:xf[2]/x:alignment", "readingOrder", "1");//LTR
4317 assertXPath(pDoc, "/x:styleSheet/x:cellXfs/x:xf[3]/x:alignment", "readingOrder", "2");//RTL
4319 xDocSh->DoClose();
4322 void ScExportTest::testTdf66668()
4324 // Would hang on exporting without the fix in place
4325 ScDocShellRef xDocSh = loadDoc("tdf66668.", FORMAT_XLSX);
4326 CPPUNIT_ASSERT_MESSAGE("Failed to open doc", xDocSh.is());
4328 xmlDocUniquePtr pDoc = XPathHelper::parseExport2(*this, *xDocSh, m_xSFactory, "xl/styles.xml", FORMAT_XLSX);
4329 CPPUNIT_ASSERT(pDoc);
4330 xDocSh->DoClose();
4333 void ScExportTest::testTdf130108()
4335 ScDocShellRef xDocSh = loadDoc("tdf130108.", FORMAT_ODS);
4336 CPPUNIT_ASSERT(xDocSh.is());
4338 xmlDocUniquePtr pDoc = XPathHelper::parseExport2(*this, *xDocSh, m_xSFactory, "xl/styles.xml", FORMAT_XLSX);
4339 CPPUNIT_ASSERT(pDoc);
4341 assertXPath(pDoc, "/x:styleSheet/x:dxfs/x:dxf/x:font/x:b", "val", "1");
4342 assertXPath(pDoc, "/x:styleSheet/x:dxfs/x:dxf/x:font/x:i", "val", "0");
4343 assertXPath(pDoc, "/x:styleSheet/x:dxfs/x:dxf/x:font/x:color", "rgb", "FFFFFFFF");
4344 assertXPath(pDoc, "/x:styleSheet/x:dxfs/x:dxf/x:font/x:sz", "val", "10");
4345 assertXPath(pDoc, "/x:styleSheet/x:dxfs/x:dxf/x:fill/x:patternFill/x:bgColor", "rgb", "FFCC0000");
4347 xDocSh->DoClose();
4350 void ScExportTest::testTdf76949()
4352 ScDocShellRef xDocSh = loadDoc("tdf76949.", FORMAT_ODS);
4353 CPPUNIT_ASSERT(xDocSh.is());
4355 xmlDocUniquePtr pSheet = XPathHelper::parseExport2(*this, *xDocSh, m_xSFactory, "xl/worksheets/sheet1.xml", FORMAT_XLSX);
4356 CPPUNIT_ASSERT(pSheet);
4358 assertXPathContent(pSheet, "/x:worksheet/x:sheetData/x:row/x:c/x:f", "_xlfn.CHISQ.DIST(1,1,1)");
4360 xDocSh->DoClose();
4363 void ScExportTest::testTdf55417()
4365 ScDocShellRef xDocSh = loadDoc("tdf55417.", FORMAT_XLSX);
4366 CPPUNIT_ASSERT(xDocSh.is());
4368 xmlDocUniquePtr pDoc = XPathHelper::parseExport2(*this, *xDocSh, m_xSFactory, "xl/styles.xml", FORMAT_XLSX);
4369 CPPUNIT_ASSERT(pDoc);
4370 assertXPath(pDoc, "/x:styleSheet/x:cellXfs/x:xf[1]/x:alignment", 1);
4371 assertXPath(pDoc, "/x:styleSheet/x:cellXfs/x:xf[2]/x:alignment", 1);
4373 xDocSh->DoClose();
4376 void ScExportTest::testTdf129985()
4378 ScDocShellRef xDocSh = loadDoc("tdf129985.", FORMAT_XLSX);
4379 CPPUNIT_ASSERT(xDocSh.is());
4381 xmlDocUniquePtr pDoc = XPathHelper::parseExport2(*this, *xDocSh, m_xSFactory, "xl/styles.xml", FORMAT_XLSX);
4382 CPPUNIT_ASSERT(pDoc);
4384 assertXPath(pDoc, "/x:styleSheet/x:numFmts/x:numFmt[2]", "formatCode", "m/d/yyyy");
4386 xDocSh->DoClose();
4389 void ScExportTest::testTdf73063()
4391 ScDocShellRef xDocSh = loadDoc("tdf73063.", FORMAT_XLSX);
4392 CPPUNIT_ASSERT(xDocSh.is());
4394 xmlDocUniquePtr pDoc = XPathHelper::parseExport2(*this, *xDocSh, m_xSFactory, "xl/styles.xml", FORMAT_XLSX);
4395 CPPUNIT_ASSERT(pDoc);
4397 assertXPath(pDoc, "/x:styleSheet/x:numFmts/x:numFmt[2]", "formatCode", "[$-1C1A]dddd\", \"d\". \"mmmm\\ yyyy;@");
4399 xDocSh->DoClose();
4402 xmlDocUniquePtr ScExportTest::testTdf95640(const OUString& rFileName, sal_Int32 nSourceFormat,
4403 sal_Int32 nDestFormat)
4405 ScDocShellRef xShell = loadDoc(rFileName, nSourceFormat);
4406 CPPUNIT_ASSERT(xShell);
4408 auto pXPathFile = ScBootstrapFixture::exportTo(&(*xShell), nDestFormat);
4409 xShell->DoClose();
4411 return XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/worksheets/sheet1.xml");
4414 void ScExportTest::testTdf95640_ods_to_xlsx()
4416 // Roundtripping sort options with user defined list to XLSX
4417 xmlDocUniquePtr pDoc = testTdf95640("tdf95640.", FORMAT_ODS, FORMAT_XLSX);
4419 assertXPath(pDoc, "//x:worksheet/x:autoFilter", "ref", "A1:B4");
4421 assertXPath(pDoc, "//x:worksheet/x:autoFilter/x:sortState/x:sortCondition", "ref", "A2:A4");
4423 assertXPath(pDoc, "//x:worksheet/x:autoFilter/x:sortState/x:sortCondition", "customList",
4424 "Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec");
4427 void ScExportTest::testTdf95640_ods_to_xlsx_with_standard_list()
4429 // Roundtripping sort options with user defined list to XLSX
4430 xmlDocUniquePtr pDoc = testTdf95640("tdf95640_standard_list.", FORMAT_ODS, FORMAT_XLSX);
4432 assertXPath(pDoc, "//x:worksheet/x:autoFilter", "ref", "A1:B4");
4434 assertXPath(pDoc, "//x:worksheet/x:autoFilter/x:sortState/x:sortCondition", "ref", "A2:A4");
4436 assertXPath(pDoc, "//x:worksheet/x:autoFilter/x:sortState/x:sortCondition", "customList",
4437 "Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday");
4440 void ScExportTest::testTdf95640_xlsx_to_xlsx()
4442 // XLSX Roundtripping sort options with custom sort list - note
4443 // that compared to ODS source documents above, here we _actually_
4444 // can use custom lists (beyond the global user defines), like
4445 // low, medium, high
4446 xmlDocUniquePtr pDoc = testTdf95640("tdf95640.", FORMAT_XLSX, FORMAT_XLSX);
4448 assertXPath(pDoc, "//x:worksheet/x:autoFilter", "ref", "A1:B4");
4450 assertXPath(pDoc, "//x:worksheet/x:autoFilter/x:sortState/x:sortCondition", "ref", "A2:A4");
4452 assertXPath(pDoc, "//x:worksheet/x:autoFilter/x:sortState/x:sortCondition", "customList",
4453 "Low,Medium,High");
4456 void ScExportTest::testTdf88657ODS()
4458 ScDocShellRef xDocSh = loadDoc("tdf88657.", FORMAT_ODS);
4459 CPPUNIT_ASSERT(xDocSh.is());
4461 xmlDocUniquePtr pDoc = XPathHelper::parseExport2(*this, *xDocSh, m_xSFactory, "styles.xml", FORMAT_ODS);
4462 CPPUNIT_ASSERT(pDoc);
4464 assertXPath(pDoc, "//number:fraction", "min-denominator-digits", "3");
4466 xDocSh->DoClose();
4469 void ScExportTest::testConditionalFormatRangeListXLSX()
4471 ScDocShellRef xDocSh = loadDoc("conditionalformat_rangelist.", FORMAT_ODS);
4472 CPPUNIT_ASSERT(xDocSh.is());
4474 xmlDocUniquePtr pDoc = XPathHelper::parseExport2(*this, *xDocSh, m_xSFactory, "xl/worksheets/sheet1.xml", FORMAT_XLSX);
4475 CPPUNIT_ASSERT(pDoc);
4477 assertXPath(pDoc, "//x:conditionalFormatting", "sqref", "F4 F10");
4479 xDocSh->DoClose();
4482 void ScExportTest::testConditionalFormatContainsTextXLSX()
4484 ScDocShellRef xDocSh = loadDoc("conditionalformat_containstext.", FORMAT_ODS);
4485 CPPUNIT_ASSERT(xDocSh.is());
4487 xmlDocUniquePtr pDoc = XPathHelper::parseExport2(*this, *xDocSh, m_xSFactory, "xl/worksheets/sheet1.xml", FORMAT_XLSX);
4488 CPPUNIT_ASSERT(pDoc);
4490 assertXPathContent(pDoc, "//x:conditionalFormatting/x:cfRule/x:formula", "NOT(ISERROR(SEARCH(\"test\",A1)))");
4492 xDocSh->DoClose();
4495 void ScExportTest::testConditionalFormatPriorityCheckXLSX()
4497 ScDocShellRef xDocSh = loadDoc("conditional_fmt_checkpriority.", FORMAT_XLSX);
4498 CPPUNIT_ASSERT(xDocSh.is());
4500 xmlDocUniquePtr pDoc = XPathHelper::parseExport2(*this, *xDocSh, m_xSFactory, "xl/worksheets/sheet1.xml", FORMAT_XLSX);
4501 CPPUNIT_ASSERT(pDoc);
4503 constexpr bool bHighPriorityExtensionA1 = true; // Should A1's extension cfRule has higher priority than normal cfRule ?
4504 constexpr bool bHighPriorityExtensionA3 = false; // Should A3's extension cfRule has higher priority than normal cfRule ?
4506 size_t nA1NormalPriority = 0;
4507 size_t nA1ExtPriority = 0;
4508 size_t nA3NormalPriority = 0;
4509 size_t nA3ExtPriority = 0;
4511 for (size_t nIdx = 1; nIdx <= 2; ++nIdx)
4513 OString aIdx = OString::number(nIdx);
4514 OUString aCellAddr = getXPath(pDoc, "//x:conditionalFormatting[" + aIdx + "]", "sqref");
4515 OUString aPriority = getXPath(pDoc, "//x:conditionalFormatting[" + aIdx + "]/x:cfRule", "priority");
4517 CPPUNIT_ASSERT_MESSAGE("conditionalFormatting sqref must be either A1 or A3", aCellAddr == "A1" || aCellAddr == "A3");
4519 if (aCellAddr == "A1")
4520 nA1NormalPriority = aPriority.toUInt32();
4521 else
4522 nA3NormalPriority = aPriority.toUInt32();
4524 aCellAddr = getXPathContent(pDoc, "//x:extLst/x:ext[1]/x14:conditionalFormattings/x14:conditionalFormatting[" + aIdx + "]/xm:sqref");
4525 aPriority = getXPath(pDoc, "//x:extLst/x:ext[1]/x14:conditionalFormattings/x14:conditionalFormatting[" + aIdx + "]/x14:cfRule", "priority");
4527 CPPUNIT_ASSERT_MESSAGE("x14:conditionalFormatting sqref must be either A1 or A3", aCellAddr == "A1" || aCellAddr == "A3");
4529 if (aCellAddr == "A1")
4530 nA1ExtPriority = aPriority.toUInt32();
4531 else
4532 nA3ExtPriority = aPriority.toUInt32();
4535 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong priorities for A1", bHighPriorityExtensionA1, nA1ExtPriority < nA1NormalPriority);
4536 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong priorities for A3", bHighPriorityExtensionA3, nA3ExtPriority < nA3NormalPriority);
4538 xDocSh->DoClose();
4541 void ScExportTest::testConditionalFormatOriginXLSX()
4543 ScDocShellRef xDocSh = loadDoc("conditional_fmt_origin.", FORMAT_XLSX);
4544 CPPUNIT_ASSERT(xDocSh.is());
4546 xmlDocUniquePtr pDoc = XPathHelper::parseExport2(*this, *xDocSh, m_xSFactory, "xl/worksheets/sheet1.xml", FORMAT_XLSX);
4547 CPPUNIT_ASSERT(pDoc);
4549 // tdf#124953 : The range-list is B3:C6 F1:G2, origin address in the formula should be B1, not B3.
4550 OUString aFormula = getXPathContent(pDoc, "//x:conditionalFormatting/x:cfRule/x:formula");
4551 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong origin address in formula", OUString("NOT(ISERROR(SEARCH(\"BAC\",B1)))"), aFormula);
4553 xDocSh->DoClose();
4556 void ScExportTest::testTdf41722()
4558 ScDocShellRef xDocSh = loadDoc("tdf41722.", FORMAT_XLSX);
4559 CPPUNIT_ASSERT(xDocSh.is());
4561 xmlDocUniquePtr pDoc = XPathHelper::parseExport2(*this, *xDocSh, m_xSFactory, "xl/worksheets/sheet1.xml", FORMAT_XLSX);
4562 CPPUNIT_ASSERT(pDoc);
4564 assertXPath(pDoc, "//x:conditionalFormatting/x:cfRule[1]", "operator", "containsText");
4565 assertXPath(pDoc, "//x:conditionalFormatting/x:cfRule[2]", "operator", "containsText");
4566 assertXPath(pDoc, "//x:conditionalFormatting/x:cfRule[3]", "operator", "containsText");
4568 xDocSh->DoClose();
4571 void ScExportTest::testTdf113621()
4573 ScDocShellRef xDocSh = loadDoc("tdf113621.", FORMAT_XLSX);
4574 CPPUNIT_ASSERT(xDocSh.is());
4576 xmlDocUniquePtr pDoc = XPathHelper::parseExport2(*this, *xDocSh, m_xSFactory, "xl/worksheets/sheet1.xml", FORMAT_XLSX);
4577 CPPUNIT_ASSERT(pDoc);
4579 assertXPath(pDoc, "//x:conditionalFormatting", "sqref", "A1:A1048576");
4581 xDocSh->DoClose();
4584 void ScExportTest::testEscapeCharInNumberFormatXLSX()
4586 ScDocShellRef xDocSh = loadDoc("tdf81939.", FORMAT_XLSX);
4587 CPPUNIT_ASSERT( xDocSh.is() );
4588 xDocSh = saveAndReload( &(*xDocSh), FORMAT_XLSX);
4589 CPPUNIT_ASSERT( xDocSh.is() );
4591 xmlDocUniquePtr pDoc = XPathHelper::parseExport2(*this, *xDocSh, m_xSFactory, "xl/styles.xml", FORMAT_XLSX);
4592 CPPUNIT_ASSERT(pDoc);
4594 const sal_Unicode cEuro (8364); // € symbol
4595 assertXPath(pDoc, "/x:styleSheet/x:numFmts/x:numFmt[2]", "formatCode", "00\\ 00\\ 00\\ 00\\ 00");
4596 assertXPath(pDoc, "/x:styleSheet/x:numFmts/x:numFmt[3]", "formatCode", "00\\.00\\.00\\.000\\.0"); // tdf#81939
4597 // "_-* #,##0\ _€_-;\-* #,##0\ _€_-;_-* "- "_€_-;_-@_-" // tdf#81222
4598 OUString rFormatStrExpected ( "_-* #,##0\\ _" + OUStringChar(cEuro) + "_-;\\-* #,##0\\ _" +
4599 OUStringChar(cEuro) + "_-;_-* \"- \"_" + OUStringChar(cEuro) + "_-;_-@_-" );
4600 assertXPath(pDoc, "/x:styleSheet/x:numFmts/x:numFmt[4]", "formatCode", rFormatStrExpected );
4601 // "_-* #,##0" €"_-;\-* #,##0" €"_-;_-* "- €"_-;_-@_-");
4602 rFormatStrExpected = "_-* #,##0\" " + OUStringChar(cEuro) + "\"_-;\\-* #,##0\" " +
4603 OUStringChar(cEuro) + "\"_-;_-* \"- " + OUStringChar(cEuro) + "\"_-;_-@_-";
4604 assertXPath(pDoc, "/x:styleSheet/x:numFmts/x:numFmt[5]", "formatCode", rFormatStrExpected );
4605 // remove escape char in fraction
4606 assertXPath(pDoc, "/x:styleSheet/x:numFmts/x:numFmt[6]", "formatCode", "# ?/?;[RED]\\-# #/#####");
4608 xDocSh->DoClose();
4611 void ScExportTest::testNatNumInNumberFormatXLSX()
4613 ScDocShellRef xDocSh = loadDoc("tdf79398_NatNum5.", FORMAT_ODS);
4614 CPPUNIT_ASSERT( xDocSh.is() );
4615 xDocSh = saveAndReload( &(*xDocSh), FORMAT_XLSX); // Convert [NatNum5] to [DBNum2] in Chinese
4616 CPPUNIT_ASSERT( xDocSh.is() );
4618 xmlDocUniquePtr pDoc = XPathHelper::parseExport2(*this, *xDocSh, m_xSFactory, "xl/styles.xml", FORMAT_XLSX);
4619 CPPUNIT_ASSERT(pDoc);
4621 assertXPath(pDoc, "/x:styleSheet/x:numFmts/x:numFmt[3]", "formatCode", "[DBNum2][$-804]General;[RED][DBNum2][$-804]General");
4623 xDocSh->DoClose();
4626 void ScExportTest::testExponentWithoutSignFormatXLSX()
4628 ScDocShellRef xDocSh = loadDoc("tdf102370_ExponentWithoutSign.", FORMAT_ODS);
4629 CPPUNIT_ASSERT( xDocSh.is() );
4630 xDocSh = saveAndReload( &(*xDocSh), FORMAT_XLSX);
4631 CPPUNIT_ASSERT( xDocSh.is() );
4633 xDocSh = saveAndReload( &(*xDocSh), FORMAT_ODS);
4634 CPPUNIT_ASSERT(xDocSh.is());
4636 ScDocument& rDoc = xDocSh->GetDocument();
4637 sal_uInt32 nNumberFormat;
4638 rDoc.GetNumberFormat(0, 0, 0, nNumberFormat);
4639 const SvNumberformat* pNumberFormat = rDoc.GetFormatTable()->GetEntry(nNumberFormat);
4640 const OUString& rFormatStr = pNumberFormat->GetFormatstring();
4642 CPPUNIT_ASSERT_EQUAL_MESSAGE("Number format lost exponent without sign during Excel export", OUString("0.00E0"), rFormatStr);
4644 xDocSh->DoClose();
4647 void ScExportTest::testExtendedLCIDXLSX()
4649 ScDocShellRef xDocSh = loadDoc("tdf36038_ExtendedLCID.", FORMAT_ODS);
4650 CPPUNIT_ASSERT( xDocSh.is() );
4651 xDocSh = saveAndReload( &(*xDocSh), FORMAT_XLSX);
4652 CPPUNIT_ASSERT( xDocSh.is() );
4654 xmlDocUniquePtr pDoc = XPathHelper::parseExport2(*this, *xDocSh, m_xSFactory, "xl/styles.xml", FORMAT_XLSX);
4655 CPPUNIT_ASSERT(pDoc);
4656 // Check export
4657 assertXPath(pDoc, "/x:styleSheet/x:numFmts/x:numFmt[2]", "formatCode", "[$-107041E]dd\\-mm\\-yyyy");
4658 assertXPath(pDoc, "/x:styleSheet/x:numFmts/x:numFmt[3]", "formatCode", "[$-D07041E]dd\\-mm\\-yyyy");
4659 assertXPath(pDoc, "/x:styleSheet/x:numFmts/x:numFmt[4]", "formatCode", "[$-1030411]dd\\-mm\\-ee");
4660 assertXPath(pDoc, "/x:styleSheet/x:numFmts/x:numFmt[5]", "formatCode", "[$-1B030411]dd\\-mm\\-ee");
4661 assertXPath(pDoc, "/x:styleSheet/x:numFmts/x:numFmt[6]", "formatCode", "[$-108040D]dd\\-mm\\-yyyy");
4662 //assertXPath(pDoc, "/x:styleSheet/x:numFmts/x:numFmt[7]", "formatCode", "[$-108040D]dd\\-mm\\-yyyy");
4663 assertXPath(pDoc, "/x:styleSheet/x:numFmts/x:numFmt[7]", "formatCode", "[$-1060401]dd\\-mm\\-yyyy");
4664 assertXPath(pDoc, "/x:styleSheet/x:numFmts/x:numFmt[8]", "formatCode", "[$-2060401]dd\\-mm\\-yyyy");
4666 // Check import
4667 ScDocument& rDoc = xDocSh->GetDocument();
4668 SvNumberFormatter* pNumFormatter = rDoc.GetFormatTable();
4669 sal_uInt32 nNumberFormat;
4670 const OUString aLang[5] = { "[$-41E]", "[$-411]", "[$-40D]", "[$-401]", "[$-500]" };
4671 const OUString aCalendar[5] = { "[~buddhist]DD-MM-YYYY", "[~gengou]DD-MM-EE", "[~jewish]DD-MM-YYYY", "[~hijri]DD-MM-YYYY", "[~dangi]YYYY/MM/DD" };
4672 for ( sal_Int16 nCol = 1; nCol <= 2; nCol++ )
4674 for ( sal_Int16 nRow = 1; nRow <= 4; nRow++ )
4676 rDoc.GetNumberFormat(nCol, nRow, 0, nNumberFormat);
4677 const SvNumberformat* pNumberFormat = pNumFormatter->GetEntry(nNumberFormat);
4678 const OUString& rFormatStr = pNumberFormat->GetFormatstring();
4679 const OUString aExpectedFormatStr = aLang[nRow-1] + ( (nCol==2 && nRow!=3) ? OUString("[NatNum1]") : OUString() ) + aCalendar[nRow-1];
4681 CPPUNIT_ASSERT_EQUAL_MESSAGE("Number format lost extended LCID during Excel export", aExpectedFormatStr, rFormatStr);
4685 xDocSh->DoClose();
4688 void ScExportTest::testHiddenRepeatedRowsODS()
4690 ScDocShellRef xDocSh = loadDoc("empty.", FORMAT_ODS);
4691 CPPUNIT_ASSERT( xDocSh.is() );
4694 ScDocument& rDoc = xDocSh->GetDocument();
4695 rDoc.SetRowHidden(0, 20, 0, true);
4698 xDocSh = saveAndReload( &(*xDocSh), FORMAT_ODS);
4699 ScDocument& rDoc = xDocSh->GetDocument();
4700 SCROW nFirstRow = 0;
4701 SCROW nLastRow = 0;
4702 bool bHidden = rDoc.RowHidden(0, 0, &nFirstRow, &nLastRow);
4703 CPPUNIT_ASSERT(bHidden);
4704 CPPUNIT_ASSERT_EQUAL(SCROW(0), nFirstRow);
4705 CPPUNIT_ASSERT_EQUAL(SCROW(20), nLastRow);
4706 xDocSh->DoClose();
4709 void ScExportTest::testHyperlinkTargetFrameODS()
4711 ScDocShellRef xDocSh = loadDoc("hyperlink_frame.", FORMAT_ODS);
4712 CPPUNIT_ASSERT(xDocSh.is());
4714 ScDocument& rDoc = xDocSh->GetDocument();
4715 const EditTextObject* pEditText = rDoc.GetEditText(ScAddress(2, 5, 0));
4716 CPPUNIT_ASSERT(pEditText);
4718 const SvxFieldData* pData = pEditText->GetFieldData(0, 0, text::textfield::Type::URL);
4719 CPPUNIT_ASSERT_MESSAGE("Failed to get the URL data.", pData && pData->GetClassId() == text::textfield::Type::URL);
4721 const SvxURLField* pURLData = static_cast<const SvxURLField*>(pData);
4722 OUString aTargetFrame = pURLData->GetTargetFrame();
4723 CPPUNIT_ASSERT_EQUAL(OUString("_blank"), aTargetFrame);
4725 xmlDocUniquePtr pDoc = XPathHelper::parseExport2(*this, *xDocSh, m_xSFactory, "content.xml", FORMAT_ODS);
4726 CPPUNIT_ASSERT(pDoc);
4727 OUString aTargetFrameExport = getXPath(pDoc,
4728 "/office:document-content/office:body/office:spreadsheet/table:table/table:table-row[2]/table:table-cell[2]/text:p/text:a", "target-frame-name");
4729 CPPUNIT_ASSERT_EQUAL(OUString("_blank"), aTargetFrameExport);
4731 xDocSh->DoClose();
4734 void ScExportTest::testOpenDocumentAsReadOnly()
4736 ScDocShellRef xDocSh = loadDoc("open-as-read-only.", FORMAT_XLSX);
4737 CPPUNIT_ASSERT(xDocSh->IsSecurityOptOpenReadOnly());
4738 ScDocShellRef xDocSh2 = saveAndReload(xDocSh.get(), FORMAT_XLSX);
4739 CPPUNIT_ASSERT(xDocSh2->IsSecurityOptOpenReadOnly());
4740 xDocSh->DoClose();
4741 xDocSh2->DoClose();
4744 void ScExportTest::testKeepSettingsOfBlankRows()
4746 ScDocShellRef xDocSh = loadDoc("tdf41425.", FORMAT_XLSX);
4747 CPPUNIT_ASSERT(xDocSh.is());
4749 std::shared_ptr<utl::TempFile> pXPathFile = ScBootstrapFixture::exportTo(&(*xDocSh), FORMAT_XLSX);
4750 xmlDocUniquePtr pSheet = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/worksheets/sheet1.xml");
4751 CPPUNIT_ASSERT(pSheet);
4753 // saved blank row with not default setting in A2
4754 assertXPath(pSheet, "/x:worksheet/x:sheetData/x:row", 2);
4756 xDocSh->DoClose();
4759 void ScExportTest::testTdf133595()
4761 ScDocShellRef xDocSh = loadDoc("tdf133595.", FORMAT_XLSX);
4762 CPPUNIT_ASSERT(xDocSh.is());
4764 std::shared_ptr<utl::TempFile> pXPathFile = ScBootstrapFixture::exportTo(&(*xDocSh), FORMAT_XLSX);
4765 xmlDocUniquePtr pSheet = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/worksheets/sheet1.xml");
4766 CPPUNIT_ASSERT(pSheet);
4768 // without the fix in place, mc:AlternateContent would have been added to sheet1
4769 assertXPath(pSheet, "/x:worksheet/mc:AlternateContent", 0);
4771 xDocSh->DoClose();
4774 void ScExportTest::testTdf134769()
4776 ScDocShellRef xDocSh = loadDoc("tdf134769.", FORMAT_XLSX);
4777 CPPUNIT_ASSERT(xDocSh.is());
4779 std::shared_ptr<utl::TempFile> pXPathFile = ScBootstrapFixture::exportTo(&(*xDocSh), FORMAT_XLSX);
4780 xmlDocUniquePtr pSheet = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/worksheets/sheet1.xml");
4781 CPPUNIT_ASSERT(pSheet);
4783 // without the fix in place, the legacyDrawing would have been exported after the checkbox
4784 // and Excel would have claimed the document is corrupted
4785 // Use their ids to check the order
4786 assertXPath(pSheet, "/x:worksheet/x:drawing", "id", "rId2");
4787 assertXPath(pSheet, "/x:worksheet/x:legacyDrawing", "id", "rId3");
4788 assertXPath(pSheet, "/x:worksheet/mc:AlternateContent/mc:Choice/x:controls/mc:AlternateContent/mc:Choice/x:control", "id", "rId4");
4790 xDocSh->DoClose();
4793 void ScExportTest::testTdf106181()
4795 ScDocShellRef xDocSh = loadDoc("tdf106181.", FORMAT_ODS);
4796 CPPUNIT_ASSERT(xDocSh.is());
4798 std::shared_ptr<utl::TempFile> pXPathFile = ScBootstrapFixture::exportTo(&(*xDocSh), FORMAT_XLSX);
4799 xmlDocUniquePtr pSheet = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/worksheets/sheet1.xml");
4800 CPPUNIT_ASSERT(pSheet);
4802 assertXPath(pSheet, "/x:worksheet/mc:AlternateContent/mc:Choice/x:controls/mc:AlternateContent/mc:Choice/x:control", "name", "Check Box");
4803 assertXPath(pSheet, "/x:worksheet/mc:AlternateContent/mc:Choice/x:controls/mc:AlternateContent/mc:Choice/x:control/x:controlPr", "altText", "Check Box 1");
4805 xmlDocUniquePtr pDrawing = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/drawings/drawing1.xml");
4806 CPPUNIT_ASSERT(pDrawing);
4808 assertXPath(pDrawing, "/xdr:wsDr/mc:AlternateContent/mc:Choice/xdr:twoCellAnchor/xdr:sp/xdr:nvSpPr/xdr:cNvPr", "name", "Check Box 1");
4809 assertXPath(pDrawing, "/xdr:wsDr/mc:AlternateContent/mc:Choice/xdr:twoCellAnchor/xdr:sp/xdr:nvSpPr/xdr:cNvPr", "descr", "Check Box");
4810 assertXPath(pDrawing, "/xdr:wsDr/mc:AlternateContent/mc:Choice/xdr:twoCellAnchor/xdr:sp/xdr:nvSpPr/xdr:cNvPr", "hidden", "0");
4812 xDocSh->DoClose();
4815 void ScExportTest::testTdf105272()
4817 ScDocShellRef xDocSh = loadDoc("tdf105272.", FORMAT_XLSX);
4818 CPPUNIT_ASSERT(xDocSh.is());
4819 xDocSh = saveAndReload(xDocSh.get(), FORMAT_XLSX);
4820 ScDocument& rDoc = xDocSh->GetDocument();
4821 //without the fix in place,it would fail
4822 //Expected: Table1[[#This Row],[Total]]/Table1[[#This Row],['# Athletes]]
4823 //Actual : table1[[#this row],[total]]/table1[[#this row],['# athletes]]
4825 ASSERT_FORMULA_EQUAL(rDoc, ScAddress(7, 3, 0),
4826 "Table1[[#This Row],[Total]]/Table1[[#This Row],['# Athletes]]",
4827 "Wrong formula");
4830 void ScExportTest::testTdf118990()
4832 ScDocShellRef xDocSh = loadDoc("tdf118990.", FORMAT_XLSX);
4833 CPPUNIT_ASSERT(xDocSh.is());
4834 xDocSh = saveAndReload(xDocSh.get(), FORMAT_XLSX);
4835 ScDocument& rDoc = xDocSh->GetDocument();
4837 // TODO: also test A1, which contains a UNC reference to \\localhost\share\lookupsource.xlsx,
4838 // but currently looses "localhost" part when normalized in INetURLObject, becoming
4839 // file:///share/lookupsource.xlsx - which is incorrect, since it points to local filesystem
4840 // and not to Windows network share.
4842 ASSERT_FORMULA_EQUAL(rDoc, ScAddress(0, 1, 0),
4843 "VLOOKUP(B1,'file://192.168.1.1/share/lookupsource.xlsx'#$Sheet1.A1:B5,2)",
4844 "Wrong Windows share (using host IP) URL in A2");
4846 ASSERT_FORMULA_EQUAL(rDoc, ScAddress(0, 2, 0),
4847 "VLOOKUP(B1,'file://NETWORKHOST/share/lookupsource.xlsx'#$Sheet1.A1:B5,2)",
4848 "Wrong Windows share (using hostname) URL in A3");
4850 xDocSh->DoClose();
4853 void ScExportTest::testTdf121612()
4855 ScDocShellRef xDocSh = loadDoc("tdf121612.", FORMAT_ODS);
4856 CPPUNIT_ASSERT(xDocSh.is());
4857 xDocSh = saveAndReload(xDocSh.get(), FORMAT_XLSX);
4859 ScDocument& rDoc = xDocSh->GetDocument();
4861 // There should be a pivot table
4862 CPPUNIT_ASSERT(rDoc.HasPivotTable());
4864 // DP collection is not lost after export and has one entry
4865 ScDPCollection* pDPColl = rDoc.GetDPCollection();
4866 CPPUNIT_ASSERT(pDPColl);
4867 CPPUNIT_ASSERT_EQUAL(size_t(1), pDPColl->GetCount());
4869 xDocSh->DoClose();
4872 void ScExportTest::testTdf112936()
4874 ScDocShellRef xDocSh = loadDoc("tdf112936.", FORMAT_XLSX);
4875 CPPUNIT_ASSERT(xDocSh.is());
4877 xmlDocUniquePtr pDoc = XPathHelper::parseExport2(*this, *xDocSh, m_xSFactory, "xl/pivotCache/pivotCacheDefinition1.xml", FORMAT_XLSX);
4878 CPPUNIT_ASSERT(pDoc);
4880 assertXPath(pDoc, "//x:pivotCacheDefinition", "recordCount", "4");
4881 assertXPath(pDoc, "//x:pivotCacheDefinition", "createdVersion", "3");
4883 xDocSh->DoClose();
4886 void ScExportTest::testXltxExport()
4888 // Create new document
4889 ScDocShell* pShell = new ScDocShell(
4890 SfxModelFlags::EMBEDDED_OBJECT |
4891 SfxModelFlags::DISABLE_EMBEDDED_SCRIPTS |
4892 SfxModelFlags::DISABLE_DOCUMENT_RECOVERY);
4893 pShell->DoInitNew();
4895 // Export as template and check content type
4896 xmlDocUniquePtr pDoc = XPathHelper::parseExport2(*this, *pShell, m_xSFactory, "[Content_Types].xml", FORMAT_XLTX);
4897 CPPUNIT_ASSERT(pDoc);
4898 assertXPath(pDoc, "/ContentType:Types/ContentType:Override[@PartName='/xl/workbook.xml']",
4899 "ContentType", "application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml");
4902 void ScExportTest::testPivotCacheAfterExportXLSX()
4904 ScDocShellRef xDocSh = loadDoc("numgroup_example.", FORMAT_ODS);
4905 CPPUNIT_ASSERT(xDocSh.is());
4907 // export only
4908 std::shared_ptr<utl::TempFile> pTemp = saveAs(xDocSh.get(), FORMAT_XLSX);
4910 ScDocument& rDoc = xDocSh->GetDocument();
4911 CPPUNIT_ASSERT(rDoc.HasPivotTable());
4913 // Two pivot tables
4914 ScDPCollection* pDPColl = rDoc.GetDPCollection();
4915 CPPUNIT_ASSERT(pDPColl);
4916 CPPUNIT_ASSERT_EQUAL(size_t(2), pDPColl->GetCount());
4918 // One cache
4919 ScDPCollection::SheetCaches& rSheetCaches = pDPColl->GetSheetCaches();
4920 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rSheetCaches.size());
4921 const ScDPCache* pCache = rSheetCaches.getExistingCache(ScRange(0, 0, 0, 3, 30, 0));
4922 CPPUNIT_ASSERT_MESSAGE("Pivot cache is expected for A1:D31 on the first sheet.", pCache);
4924 // See if XLSX export didn't damage group info of the 1st pivot table
4925 const ScDPNumGroupInfo* pInfo = pCache->GetNumGroupInfo(1);
4926 CPPUNIT_ASSERT_MESSAGE("No number group info :(", pInfo);
4928 xDocSh->DoClose();
4931 void ScExportTest::testTdf114969XLSX()
4933 ScDocShellRef xDocSh = loadDoc("sheet_name_with_dots.", FORMAT_ODS);
4934 CPPUNIT_ASSERT(xDocSh.is());
4936 xmlDocUniquePtr pDoc = XPathHelper::parseExport2(*this, *xDocSh, m_xSFactory, "xl/worksheets/sheet1.xml", FORMAT_XLSX);
4937 CPPUNIT_ASSERT(pDoc);
4938 assertXPath(pDoc, "/x:worksheet/x:hyperlinks/x:hyperlink[1]", "location", "'1.1.1.1'!C1");
4939 assertXPath(pDoc, "/x:worksheet/x:hyperlinks/x:hyperlink[2]", "location", "'1.1.1.1'!C2");
4941 xDocSh->DoClose();
4944 void ScExportTest::testTdf115192XLSX()
4946 ScDocShellRef xDocSh = loadDoc("test_115192.", FORMAT_XLSX);
4947 CPPUNIT_ASSERT(xDocSh.is());
4949 xmlDocUniquePtr pDoc = XPathHelper::parseExport2(*this, *xDocSh, m_xSFactory, "xl/drawings/_rels/drawing1.xml.rels", FORMAT_XLSX);
4950 CPPUNIT_ASSERT(pDoc);
4951 assertXPath(pDoc, "/r:Relationships/r:Relationship[@Id='rId1']", "TargetMode", "External");
4952 assertXPathNoAttribute(pDoc, "/r:Relationships/r:Relationship[@Id='rId2']", "TargetMode");
4953 assertXPath(pDoc, "/r:Relationships/r:Relationship[@Id='rId3']", "TargetMode", "External");
4955 xDocSh->DoClose();
4958 void ScExportTest::testTdf91634XLSX()
4960 ScDocShellRef xDocSh = loadDoc("image_hyperlink.", FORMAT_XLSX);
4961 CPPUNIT_ASSERT(xDocSh.is());
4962 std::shared_ptr<utl::TempFile> pXPathFile = ScBootstrapFixture::exportTo(&(*xDocSh), FORMAT_XLSX);
4964 xmlDocUniquePtr pDoc = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/drawings/drawing1.xml");
4965 CPPUNIT_ASSERT(pDoc);
4966 assertXPath(pDoc, "/xdr:wsDr/xdr:twoCellAnchor/xdr:pic/xdr:nvPicPr/xdr:cNvPr/a:hlinkClick", 1);
4968 xmlDocUniquePtr pXmlRels = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/drawings/_rels/drawing1.xml.rels");
4969 CPPUNIT_ASSERT(pXmlRels);
4970 assertXPath(pXmlRels, "/r:Relationships/r:Relationship[@Id='rId1']", "Target", "https://www.google.com/");
4971 assertXPath(pXmlRels, "/r:Relationships/r:Relationship[@Id='rId1']", "TargetMode", "External");
4973 xDocSh->DoClose();
4976 void ScExportTest::testValidationCopyPaste()
4978 ScDocShellRef xDocSh = loadDoc("validation-copypaste.", FORMAT_ODS);
4979 CPPUNIT_ASSERT(xDocSh.is());
4980 ScDocument& rSrcDoc = xDocSh->GetDocument();
4982 // Copy B1 from src doc to clip
4983 ScDocument aClipDoc(SCDOCMODE_CLIP);
4984 ScRange aSrcRange(1, 0, 1);
4985 ScClipParam aClipParam(aSrcRange, false);
4986 ScMarkData aMark(rSrcDoc.GetSheetLimits());
4987 aMark.SetMarkArea(aSrcRange);
4988 rSrcDoc.CopyToClip(aClipParam, &aClipDoc, &aMark, false, false);
4990 // Create second document, paste B1 from clip
4991 ScDocShell* pShell2
4992 = new ScDocShell(SfxModelFlags::EMBEDDED_OBJECT | SfxModelFlags::DISABLE_EMBEDDED_SCRIPTS
4993 | SfxModelFlags::DISABLE_DOCUMENT_RECOVERY);
4994 pShell2->DoInitNew();
4995 ScDocument& rDestDoc = pShell2->GetDocument();
4996 ScRange aDstRange(1, 0, 0);
4997 ScMarkData aMark2(rDestDoc.GetSheetLimits());
4998 aMark2.SetMarkArea(aDstRange);
4999 rDestDoc.CopyFromClip(aDstRange, aMark2, InsertDeleteFlags::ALL, nullptr, &aClipDoc);
5001 // save as XLSX
5002 std::shared_ptr<utl::TempFile> pXPathFile
5003 = ScBootstrapFixture::exportTo(&(*pShell2), FORMAT_XLSX);
5005 // check validation
5006 xmlDocUniquePtr pDoc
5007 = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/worksheets/sheet1.xml");
5008 CPPUNIT_ASSERT(pDoc);
5009 assertXPathContent(pDoc, "/x:worksheet/x:dataValidations/x:dataValidation/x:formula1", "#REF!");
5012 void ScExportTest::testTdf115159()
5014 ScDocShellRef xShell = loadDoc("tdf115159.", FORMAT_XLSX);
5015 CPPUNIT_ASSERT(xShell.is());
5016 ScDocShellRef xDocSh = saveAndReload(xShell.get(), FORMAT_XLSX);
5017 CPPUNIT_ASSERT(xDocSh.is());
5018 xShell->DoClose();
5020 xmlDocUniquePtr pDoc = XPathHelper::parseExport2(*this, *xDocSh, m_xSFactory, "xl/workbook.xml", FORMAT_XLSX);
5021 CPPUNIT_ASSERT(pDoc);
5023 //assert the existing OOXML built-in name is not duplicated
5024 assertXPath(pDoc, "/x:workbook/x:definedNames/x:definedName", 1);
5026 xDocSh->DoClose();
5029 void ScExportTest::testTdf112567()
5031 // Set the system locale to Hungarian (a language with different range separator)
5032 SvtSysLocaleOptions aOptions;
5033 OUString sLocaleConfigString = aOptions.GetLanguageTag().getBcp47();
5034 aOptions.SetLocaleConfigString("hu-HU");
5035 aOptions.Commit();
5036 comphelper::ScopeGuard g([&aOptions, &sLocaleConfigString] {
5037 aOptions.SetLocaleConfigString(sLocaleConfigString);
5038 aOptions.Commit();
5041 ScDocShellRef xShell = loadDoc("tdf112567.", FORMAT_XLSX);
5042 CPPUNIT_ASSERT(xShell.is());
5043 ScDocShellRef xDocSh = saveAndReload(xShell.get(), FORMAT_XLSX);
5044 CPPUNIT_ASSERT(xDocSh.is());
5045 xShell->DoClose();
5047 xmlDocUniquePtr pDoc = XPathHelper::parseExport2(*this, *xDocSh, m_xSFactory, "xl/workbook.xml", FORMAT_XLSX);
5048 CPPUNIT_ASSERT(pDoc);
5050 //assert the existing OOXML built-in name is not duplicated
5051 assertXPath(pDoc, "/x:workbook/x:definedNames/x:definedName", 1);
5053 xDocSh->DoClose();
5056 void ScExportTest::testTdf112567b()
5058 // Set the system locale to Hungarian (a language with different range separator)
5059 SvtSysLocaleOptions aOptions;
5060 OUString sLocaleConfigString = aOptions.GetLanguageTag().getBcp47();
5061 aOptions.SetLocaleConfigString("hu-HU");
5062 aOptions.Commit();
5063 comphelper::ScopeGuard g([&aOptions, &sLocaleConfigString] {
5064 aOptions.SetLocaleConfigString(sLocaleConfigString);
5065 aOptions.Commit();
5068 ScDocShellRef xShell = loadDoc("tdf112567.", FORMAT_ODS);
5069 CPPUNIT_ASSERT(xShell.is());
5070 ScDocShellRef xDocSh = saveAndReload(xShell.get(), FORMAT_XLSX);
5071 CPPUNIT_ASSERT(xDocSh.is());
5072 xShell->DoClose();
5074 xmlDocUniquePtr pDoc = XPathHelper::parseExport2(*this, *xDocSh, m_xSFactory, "xl/workbook.xml", FORMAT_XLSX);
5075 CPPUNIT_ASSERT(pDoc);
5077 //assert the existing OOXML built-in name is not duplicated
5078 assertXPath(pDoc, "/x:workbook/x:definedNames/x:definedName", 1);
5080 //and it contains "," instead of ";"
5081 assertXPathContent(pDoc, "/x:workbook/x:definedNames/x:definedName[1]", "Sheet1!$A:$A,Sheet1!$1:$1");
5083 xDocSh->DoClose();
5086 void ScExportTest::testTdf123645XLSX()
5088 ScDocShellRef xDocSh = loadDoc("chart_hyperlink.", FORMAT_XLSX);
5089 CPPUNIT_ASSERT(xDocSh.is());
5090 std::shared_ptr<utl::TempFile> pXPathFile = ScBootstrapFixture::exportTo(&(*xDocSh), FORMAT_XLSX);
5092 xmlDocUniquePtr pDoc = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/drawings/drawing1.xml");
5093 CPPUNIT_ASSERT(pDoc);
5094 assertXPath(pDoc, "/xdr:wsDr/xdr:twoCellAnchor[1]/xdr:graphicFrame/xdr:nvGraphicFramePr/xdr:cNvPr/a:hlinkClick", 1);
5095 assertXPath(pDoc, "/xdr:wsDr/xdr:twoCellAnchor[2]/xdr:graphicFrame/xdr:nvGraphicFramePr/xdr:cNvPr/a:hlinkClick", 1);
5096 assertXPath(pDoc, "/xdr:wsDr/xdr:twoCellAnchor[3]/xdr:graphicFrame/xdr:nvGraphicFramePr/xdr:cNvPr/a:hlinkClick", 1);
5098 xmlDocUniquePtr pXmlRels = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/drawings/_rels/drawing1.xml.rels");
5099 CPPUNIT_ASSERT(pXmlRels);
5100 assertXPath(pXmlRels, "/r:Relationships/r:Relationship[@Id='rId1']", "TargetMode", "External");
5101 assertXPathNoAttribute(pXmlRels, "/r:Relationships/r:Relationship[@Id='rId3']", "TargetMode");
5102 assertXPath(pXmlRels, "/r:Relationships/r:Relationship[@Id='rId5']", "TargetMode", "External");
5103 assertXPath(pXmlRels, "/r:Relationships/r:Relationship[@Id='rId1']", "Target", "file:///C:/TEMP/test.xlsx");
5104 assertXPath(pXmlRels, "/r:Relationships/r:Relationship[@Id='rId3']", "Target", "#Sheet2!A1");
5105 assertXPath(pXmlRels, "/r:Relationships/r:Relationship[@Id='rId5']", "Target", "https://bugs.documentfoundation.org/show_bug.cgi?id=123645");
5107 xDocSh->DoClose();
5110 void ScExportTest::testTdf125173XLSX()
5112 ScDocShellRef xDocSh = loadDoc("text_box_hyperlink.", FORMAT_ODS);
5113 CPPUNIT_ASSERT(xDocSh.is());
5114 std::shared_ptr<utl::TempFile> pXPathFile = ScBootstrapFixture::exportTo(&(*xDocSh), FORMAT_XLSX);
5116 xmlDocUniquePtr pDoc = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/drawings/drawing1.xml");
5117 CPPUNIT_ASSERT(pDoc);
5118 assertXPath(pDoc, "/xdr:wsDr/xdr:twoCellAnchor/xdr:sp/xdr:nvSpPr/xdr:cNvPr/a:hlinkClick", 1);
5120 xmlDocUniquePtr pXmlRels = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/drawings/_rels/drawing1.xml.rels");
5121 CPPUNIT_ASSERT(pXmlRels);
5122 assertXPath(pXmlRels, "/r:Relationships/r:Relationship[@Id='rId1']", "Target", "http://www.google.com/");
5123 assertXPath(pXmlRels, "/r:Relationships/r:Relationship[@Id='rId1']", "TargetMode", "External");
5125 xDocSh->DoClose();
5128 void ScExportTest::testTdf79972XLSX()
5130 ScDocShellRef xDocSh = loadDoc("tdf79972.", FORMAT_XLSX);
5131 CPPUNIT_ASSERT(xDocSh.is());
5132 std::shared_ptr<utl::TempFile> pXPathFile = ScBootstrapFixture::exportTo(&(*xDocSh), FORMAT_XLSX);
5134 xmlDocUniquePtr pDoc = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/worksheets/sheet1.xml");
5135 CPPUNIT_ASSERT(pDoc);
5136 assertXPath(pDoc, "/x:worksheet/x:hyperlinks/x:hyperlink", "ref", "A1");
5138 xmlDocUniquePtr pXmlRels = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/worksheets/_rels/sheet1.xml.rels");
5139 CPPUNIT_ASSERT(pXmlRels);
5140 assertXPath(pXmlRels, "/r:Relationships/r:Relationship", "Target", "https://bugs.documentfoundation.org/show_bug.cgi?id=79972");
5141 assertXPath(pXmlRels, "/r:Relationships/r:Relationship", "TargetMode", "External");
5143 xDocSh->DoClose();
5146 void ScExportTest::testTdf126024XLSX()
5148 ScDocShellRef xDocSh = loadDoc("hyperlink_formula.", FORMAT_XLSX);
5149 CPPUNIT_ASSERT(xDocSh.is());
5150 std::shared_ptr<utl::TempFile> pXPathFile = ScBootstrapFixture::exportTo(&(*xDocSh), FORMAT_XLSX);
5152 xmlDocUniquePtr pDoc = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/worksheets/sheet1.xml");
5153 CPPUNIT_ASSERT(pDoc);
5154 assertXPath(pDoc, "/x:worksheet/x:hyperlinks/x:hyperlink", "ref", "A2");
5156 xmlDocUniquePtr pXmlRels = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/worksheets/_rels/sheet1.xml.rels");
5157 CPPUNIT_ASSERT(pXmlRels);
5158 assertXPath(pXmlRels, "/r:Relationships/r:Relationship", "Target", "https://bugs.documentfoundation.org/");
5159 assertXPath(pXmlRels, "/r:Relationships/r:Relationship", "TargetMode", "External");
5161 xDocSh->DoClose();
5164 void ScExportTest::testTdf126177XLSX()
5166 ScDocShellRef xDocSh = loadDoc("hyperlink_export.", FORMAT_XLSX);
5167 CPPUNIT_ASSERT(xDocSh.is());
5168 std::shared_ptr<utl::TempFile> pXPathFile = ScBootstrapFixture::exportTo(&(*xDocSh), FORMAT_XLSX);
5170 xmlDocUniquePtr pDoc = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/worksheets/sheet1.xml");
5171 CPPUNIT_ASSERT(pDoc);
5172 assertXPath(pDoc, "/x:worksheet/x:hyperlinks/x:hyperlink", "location", "Munka1!A5");
5174 xmlDocUniquePtr pXmlRels = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/worksheets/_rels/sheet1.xml.rels");
5175 CPPUNIT_ASSERT(pXmlRels);
5176 OUString aTarget = getXPath(pXmlRels, "/r:Relationships/r:Relationship", "Target");
5177 CPPUNIT_ASSERT(aTarget.endsWith("test.xlsx"));
5178 assertXPath(pXmlRels, "/r:Relationships/r:Relationship", "TargetMode", "External");
5180 xDocSh->DoClose();
5183 void ScExportTest::testCommentTextVAlignment()
5185 // Testing comment text alignments.
5186 ScDocShellRef xShell = loadDoc("CommentTextVAlign.", FORMAT_ODS);
5187 CPPUNIT_ASSERT(xShell.is());
5189 std::shared_ptr<utl::TempFile> pXPathFile
5190 = ScBootstrapFixture::exportTo(&(*xShell), FORMAT_XLSX);
5192 xmlDocUniquePtr pVmlDrawing
5193 = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/drawings/vmlDrawing1.vml");
5194 CPPUNIT_ASSERT(pVmlDrawing);
5196 assertXPathContent(pVmlDrawing, "/xml/v:shape/xx:ClientData/xx:TextVAlign", "Center");
5198 xShell->DoClose();
5201 void ScExportTest::testCommentTextHAlignment()
5203 // Testing comment text alignments.
5204 ScDocShellRef xShell = loadDoc("CommentTextHAlign.", FORMAT_ODS);
5205 CPPUNIT_ASSERT(xShell.is());
5207 std::shared_ptr<utl::TempFile> pXPathFile
5208 = ScBootstrapFixture::exportTo(&(*xShell), FORMAT_XLSX);
5210 xmlDocUniquePtr pVmlDrawing
5211 = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/drawings/vmlDrawing1.vml");
5212 CPPUNIT_ASSERT(pVmlDrawing);
5214 assertXPathContent(pVmlDrawing, "/xml/v:shape/xx:ClientData/xx:TextHAlign", "Center");
5216 xShell->DoClose();
5219 void ScExportTest::testRotatedImageODS()
5221 // Error was, that the length values in shapes were not
5222 // written in the given unit into the file.
5223 css::uno::Reference<css::sheet::XGlobalSheetSettings> xGlobalSheetSettings
5224 = css::sheet::GlobalSheetSettings::create(comphelper::getProcessComponentContext());
5225 xGlobalSheetSettings->setMetric(static_cast<sal_Int16>(FieldUnit::MM));
5227 ScDocShellRef xDocSh = loadDoc("tdf103092_RotatedImage.", FORMAT_ODS, true);
5228 CPPUNIT_ASSERT(xDocSh.is());
5230 std::shared_ptr<utl::TempFile> pTemp = saveAs(xDocSh.get(), FORMAT_ODS);
5231 CPPUNIT_ASSERT(pTemp);
5232 xmlDocUniquePtr pXmlDoc = XPathHelper::parseExport(pTemp, m_xSFactory, "content.xml");
5233 CPPUNIT_ASSERT(pXmlDoc);
5235 const OUString sTransform = getXPath(
5236 pXmlDoc,
5237 "/office:document-content/office:body/office:spreadsheet/"
5238 "table:table/table:shapes/draw:frame",
5239 "transform");
5240 // Attribute transform has the structure skew (...) rotate (...) translate (x y)
5241 // parts are separated by blank
5242 OUString sTranslate(sTransform.copy(sTransform.lastIndexOf('(')));
5243 sTranslate = sTranslate.copy(1, sTranslate.getLength()-2); // remove '(' and ')'
5244 const OUString sX(sTranslate.getToken(0, ' '));
5245 const OUString sY(sTranslate.getToken(1, ' '));
5246 CPPUNIT_ASSERT(sX.endsWith("mm") && sY.endsWith("mm"));
5248 xDocSh->DoClose();
5251 void ScExportTest::testTdf128976()
5253 ScDocShellRef xShell = loadDoc("tdf128976.", FORMAT_XLS);
5254 CPPUNIT_ASSERT(xShell.is());
5256 ScDocShellRef xDocSh = saveAndReload(xShell.get(), FORMAT_XLS);
5257 xShell->DoClose();
5258 CPPUNIT_ASSERT(xDocSh.is());
5260 ScDocument& rDoc = xDocSh->GetDocument();
5262 // Trying to save very small fractional default column width to XLS (where only integer values
5263 // between 0 and 255 are allowed as default) resulted in negative (-1) value after correction,
5264 // and was written as 65535 (invalid default width). As the result, all columns had large width
5265 // when reopened: 28415 (and Excel warned about invalid format).
5266 const sal_uInt16 nColumn0Width = rDoc.GetColWidth(SCCOL(0), SCTAB(0), false);
5267 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(45), nColumn0Width);
5269 xDocSh->DoClose();
5272 void ScExportTest::testTdf120502()
5274 // Create an empty worksheet; resize last column on its first sheet; export to XLSX, and check
5275 // that the last exported column number is correct
5276 css::uno::Reference<css::frame::XDesktop2> xDesktop
5277 = css::frame::Desktop::create(comphelper::getProcessComponentContext());
5278 CPPUNIT_ASSERT(xDesktop);
5280 css::uno::Sequence<css::beans::PropertyValue> args(1);
5281 args[0].Name = "Hidden";
5282 args[0].Value <<= true;
5284 css::uno::Reference<css::lang::XComponent> xComponent
5285 = xDesktop->loadComponentFromURL("private:factory/scalc", "_blank", 0, args);
5286 CPPUNIT_ASSERT(xComponent);
5288 // Get the document model
5289 SfxObjectShell* pFoundShell = SfxObjectShell::GetShellFromComponent(xComponent);
5290 CPPUNIT_ASSERT_MESSAGE("Failed to access document shell", pFoundShell);
5292 ScDocShellRef xShell = dynamic_cast<ScDocShell*>(pFoundShell);
5293 CPPUNIT_ASSERT(xShell);
5295 ScDocument& rDoc = xShell->GetDocument();
5296 const SCCOL nMaxCol = rDoc.MaxCol(); // 0-based
5298 const auto nOldWidth = rDoc.GetColWidth(nMaxCol, 0);
5299 rDoc.SetColWidth(nMaxCol, 0, nOldWidth + 100);
5301 std::shared_ptr<utl::TempFile> pXPathFile
5302 = ScBootstrapFixture::exportTo(&(*xShell), FORMAT_XLSX);
5303 xShell->DoClose();
5304 xmlDocUniquePtr pSheet1
5305 = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/worksheets/sheet1.xml");
5306 CPPUNIT_ASSERT(pSheet1);
5308 // This was 1025 when nMaxCol+1 was 1024
5309 assertXPath(pSheet1, "/x:worksheet/x:cols/x:col", "max", OUString::number(nMaxCol + 1));
5312 void ScExportTest::testTdf131372()
5314 ScDocShellRef xShell = loadDoc("tdf131372.", FORMAT_ODS);
5315 CPPUNIT_ASSERT(xShell);
5317 auto pXPathFile = ScBootstrapFixture::exportTo(&(*xShell), FORMAT_XLSX);
5319 xmlDocUniquePtr pSheet = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/worksheets/sheet1.xml");
5320 CPPUNIT_ASSERT(pSheet);
5322 assertXPathContent(pSheet, "/x:worksheet/x:sheetData/x:row/x:c[1]/x:f", "NA()");
5323 assertXPathContent(pSheet, "/x:worksheet/x:sheetData/x:row/x:c[2]/x:f", "#N/A");
5325 xShell->DoClose();
5328 void ScExportTest::testTdf81470()
5330 ScDocShellRef xShell = loadDoc("tdf81470.", FORMAT_XLS);
5331 CPPUNIT_ASSERT(xShell);
5333 //without the fix in place, it would have crashed at export time
5334 auto pXPathFile = ScBootstrapFixture::exportTo(&(*xShell), FORMAT_XLSX);
5336 //also check revisions are exported
5337 xmlDocUniquePtr pHeaders = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/revisions/revisionHeaders.xml");
5338 CPPUNIT_ASSERT(pHeaders);
5340 assertXPath(pHeaders, "/x:headers/x:header[1]", "dateTime", "2014-07-11T13:46:00.000000000Z");
5341 assertXPath(pHeaders, "/x:headers/x:header[1]", "userName", "Kohei Yoshida");
5342 assertXPath(pHeaders, "/x:headers/x:header[2]", "dateTime", "2014-07-11T18:38:00.000000000Z");
5343 assertXPath(pHeaders, "/x:headers/x:header[2]", "userName", "Kohei Yoshida");
5344 assertXPath(pHeaders, "/x:headers/x:header[3]", "dateTime", "2014-07-11T18:43:00.000000000Z");
5345 assertXPath(pHeaders, "/x:headers/x:header[3]", "userName", "Kohei Yoshida");
5347 xShell->DoClose();
5350 void ScExportTest::testTdf122331()
5352 ScDocShellRef xShell = loadDoc("tdf122331.", FORMAT_ODS);
5353 CPPUNIT_ASSERT(xShell);
5355 auto pXPathFile = ScBootstrapFixture::exportTo(&(*xShell), FORMAT_XLSX);
5357 xmlDocUniquePtr pSheet = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/worksheets/sheet1.xml");
5358 CPPUNIT_ASSERT(pSheet);
5360 assertXPath(pSheet, "/x:worksheet/x:sheetPr", "filterMode", "true");
5361 assertXPath(pSheet, "/x:worksheet/x:autoFilter", "ref", "A1:B761");
5362 assertXPath(pSheet, "/x:worksheet/x:autoFilter/x:filterColumn", "colId", "1");
5364 xShell->DoClose();
5367 void ScExportTest::testTdf83779()
5369 // Roundtripping TRUE/FALSE constants (not functions) must convert them to functions
5370 ScDocShellRef xShell = loadDoc("tdf83779.", FORMAT_XLSX);
5371 CPPUNIT_ASSERT(xShell);
5373 auto pXPathFile = ScBootstrapFixture::exportTo(&(*xShell), FORMAT_XLSX);
5375 xmlDocUniquePtr pVmlDrawing
5376 = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/worksheets/sheet1.xml");
5377 CPPUNIT_ASSERT(pVmlDrawing);
5379 assertXPathContent(pVmlDrawing, "/x:worksheet/x:sheetData/x:row[1]/x:c/x:f", "FALSE()");
5380 assertXPathContent(pVmlDrawing, "/x:worksheet/x:sheetData/x:row[2]/x:c/x:f", "TRUE()");
5382 xShell->DoClose();
5385 void ScExportTest::testTdf121716_ExportEvenHeaderFooterXLSX()
5387 // Header and footer on even pages should be exported properly
5388 // If there are separate odd/even header, but only 1 footer for all pages (this is possible only in LibreOffice)
5389 // then the footer will be duplicated to have the same footer separately for even/odd pages
5391 ScDocShellRef xShell = loadDoc("tdf121716_EvenHeaderFooter.", FORMAT_ODS);
5392 CPPUNIT_ASSERT(xShell.is());
5394 ScDocShellRef xDocSh = saveAndReload(&(*xShell), FORMAT_XLSX);
5395 CPPUNIT_ASSERT(xDocSh.is());
5397 std::shared_ptr<utl::TempFile> pXPathFile = ScBootstrapFixture::exportTo(&(*xDocSh), FORMAT_XLSX);
5398 xmlDocUniquePtr pDoc = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/worksheets/sheet1.xml");
5399 CPPUNIT_ASSERT(pDoc);
5401 assertXPath(pDoc, "/x:worksheet/x:headerFooter", "differentOddEven", "true");
5402 assertXPathContent(pDoc, "/x:worksheet/x:headerFooter/x:oddHeader", "&Lodd/right&Cpage&Rheader");
5403 assertXPathContent(pDoc, "/x:worksheet/x:headerFooter/x:oddFooter", "&Lboth&C&12page&Rfooter");
5404 assertXPathContent(pDoc, "/x:worksheet/x:headerFooter/x:evenHeader", "&Lpage&Cheader&Reven/left");
5405 assertXPathContent(pDoc, "/x:worksheet/x:headerFooter/x:evenFooter", "&Lboth&C&12page&Rfooter");
5407 pDoc = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/worksheets/sheet2.xml");
5408 CPPUNIT_ASSERT(pDoc);
5410 assertXPath(pDoc, "/x:worksheet/x:headerFooter", "differentOddEven", "true");
5411 assertXPathContent(pDoc, "/x:worksheet/x:headerFooter/x:oddHeader", "&Coddh");
5412 assertXPathContent(pDoc, "/x:worksheet/x:headerFooter/x:oddFooter", "&Coddf");
5413 assertXPathContent(pDoc, "/x:worksheet/x:headerFooter/x:evenHeader", "&Cevenh");
5414 assertXPathContent(pDoc, "/x:worksheet/x:headerFooter/x:evenFooter", "&Levenf");
5416 xDocSh->DoClose();
5419 void ScExportTest::testTdf134459_HeaderFooterColorXLSX()
5421 // Colors in header and footer should be exported, and imported properly
5422 ScDocShellRef xShell = loadDoc("tdf134459_HeaderFooterColor.", FORMAT_XLSX);
5423 CPPUNIT_ASSERT(xShell.is());
5425 ScDocShellRef xDocSh = saveAndReload(&(*xShell), FORMAT_XLSX);
5426 CPPUNIT_ASSERT(xDocSh.is());
5428 xmlDocUniquePtr pDoc = XPathHelper::parseExport2(*this, *xDocSh, m_xSFactory, "xl/worksheets/sheet1.xml", FORMAT_XLSX);
5429 CPPUNIT_ASSERT(pDoc);
5431 assertXPathContent(pDoc, "/x:worksheet/x:headerFooter/x:oddHeader", "&L&Kc06040l&C&K4c3789c&Rr");
5432 assertXPathContent(pDoc, "/x:worksheet/x:headerFooter/x:oddFooter", "&Ll&C&K64cf5fc&R&Kcd15aar");
5434 xDocSh->DoClose();
5437 void ScExportTest::testTdf134817_HeaderFooterTextWith2SectionXLSX()
5439 // Header/footer text with multiple selection should be exported, and imported properly
5440 ScDocShellRef xShell = loadDoc("tdf134817_HeaderFooterTextWith2Section.", FORMAT_XLSX);
5441 CPPUNIT_ASSERT(xShell.is());
5443 ScDocShellRef xDocSh = saveAndReload(&(*xShell), FORMAT_XLSX);
5444 CPPUNIT_ASSERT(xDocSh.is());
5446 xmlDocUniquePtr pDoc = XPathHelper::parseExport2(*this, *xDocSh, m_xSFactory, "xl/worksheets/sheet1.xml", FORMAT_XLSX);
5447 CPPUNIT_ASSERT(pDoc);
5449 assertXPathContent(pDoc, "/x:worksheet/x:headerFooter/x:oddHeader", "&L&\"Abadi,Regular\"&11aaa&\"Bembo,Regular\"&20bbb");
5450 assertXPathContent(pDoc, "/x:worksheet/x:headerFooter/x:oddFooter", "&R&\"Cambria,Regular\"&14camb&\"Dante,Regular\"&18dant");
5452 xDocSh->DoClose();
5455 void ScExportTest::testTdf121718_UseFirstPageNumberXLSX()
5457 // If "First page number" is not checked then useFirstPageNumb, and firstPageNumber should not be exported.
5458 ScDocShellRef xShell = loadDoc("tdf121718_UseFirstPageNumber.", FORMAT_ODS);
5459 CPPUNIT_ASSERT(xShell.is());
5461 ScDocShellRef xDocSh = saveAndReload(&(*xShell), FORMAT_XLSX);
5462 CPPUNIT_ASSERT(xDocSh.is());
5464 std::shared_ptr<utl::TempFile> pXPathFile = ScBootstrapFixture::exportTo(&(*xDocSh), FORMAT_XLSX);
5465 xmlDocUniquePtr pDoc = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/worksheets/sheet1.xml");
5466 CPPUNIT_ASSERT(pDoc);
5468 assertXPath(pDoc, "/x:worksheet/x:pageSetup", "useFirstPageNumber", "true");
5469 assertXPath(pDoc, "/x:worksheet/x:pageSetup", "firstPageNumber", "10");
5471 pDoc = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/worksheets/sheet2.xml");
5472 CPPUNIT_ASSERT(pDoc);
5474 assertXPathNoAttribute(pDoc, "/x:worksheet/x:pageSetup", "useFirstPageNumber");
5475 assertXPathNoAttribute(pDoc, "/x:worksheet/x:pageSetup", "firstPageNumber");
5477 xDocSh->DoClose();
5480 void ScExportTest::testHeaderFontStyleXLSX()
5482 ScDocShellRef xShell = loadDoc("tdf134826.", FORMAT_XLSX);
5483 CPPUNIT_ASSERT(xShell.is());
5485 ScDocument& rDoc = xShell->GetDocument();
5486 SfxStyleSheetBase* pStyleSheet = rDoc.GetStyleSheetPool()->Find(rDoc.GetPageStyle(0), SfxStyleFamily::Page);
5487 const SfxItemSet& rItemSet = pStyleSheet->GetItemSet();
5488 const ScPageHFItem& rHFItem = rItemSet.Get(ATTR_PAGE_HEADERRIGHT);
5489 const EditTextObject* pTextObj = rHFItem.GetLeftArea();
5491 std::vector<EECharAttrib> rLst;
5493 // first line is bold.
5494 pTextObj->GetCharAttribs(0, rLst);
5495 bool bHasBold = std::any_of(rLst.begin(), rLst.end(), [](const EECharAttrib& rAttrib) {
5496 return rAttrib.pAttr->Which() == EE_CHAR_WEIGHT &&
5497 static_cast<const SvxWeightItem&>(*rAttrib.pAttr).GetWeight() == WEIGHT_BOLD; });
5498 CPPUNIT_ASSERT_MESSAGE("First line should be bold.", bHasBold);
5500 // second line is italic.
5501 pTextObj->GetCharAttribs(1, rLst);
5502 bool bHasItalic = std::any_of(rLst.begin(), rLst.end(), [](const EECharAttrib& rAttrib) {
5503 return rAttrib.pAttr->Which() == EE_CHAR_ITALIC &&
5504 static_cast<const SvxPostureItem&>(*rAttrib.pAttr).GetPosture() == ITALIC_NORMAL; });
5505 CPPUNIT_ASSERT_MESSAGE("Second line should be italic.", bHasItalic);
5507 xShell->DoClose();
5510 void ScExportTest::testTdf135828_Shape_Rect()
5512 // tdf#135828 Check that the width and the height of rectangle of the shape is correct.
5513 // tdf#123613 Check the positioning, and allow massive rounding errors because of the back and
5514 // forth conversion between emu and hmm.
5515 ScDocShellRef xShell = loadDoc("tdf135828_Shape_Rect.", FORMAT_XLSX);
5516 CPPUNIT_ASSERT(xShell.is());
5518 ScDocShellRef xDocSh = saveAndReload(&(*xShell), FORMAT_XLSX);
5519 CPPUNIT_ASSERT(xDocSh.is());
5521 std::shared_ptr<utl::TempFile> pXPathFile = ScBootstrapFixture::exportTo(&(*xDocSh), FORMAT_XLSX);
5523 xmlDocUniquePtr pDrawing = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/drawings/drawing1.xml");
5524 CPPUNIT_ASSERT(pDrawing);
5526 double nXPosOfTopleft = getXPath(pDrawing, "/xdr:wsDr/xdr:twoCellAnchor/xdr:sp/xdr:spPr/a:xfrm/a:off", "x" ).toDouble();
5527 double nYPosOfTopleft = getXPath(pDrawing, "/xdr:wsDr/xdr:twoCellAnchor/xdr:sp/xdr:spPr/a:xfrm/a:off", "y" ).toDouble();
5528 double nWidth = getXPath(pDrawing, "/xdr:wsDr/xdr:twoCellAnchor/xdr:sp/xdr:spPr/a:xfrm/a:ext", "cx").toDouble();
5529 double nHeight = getXPath(pDrawing, "/xdr:wsDr/xdr:twoCellAnchor/xdr:sp/xdr:spPr/a:xfrm/a:ext", "cy").toDouble();
5531 CPPUNIT_ASSERT_DOUBLES_EQUAL( 854640, nXPosOfTopleft, 10000);
5532 CPPUNIT_ASSERT_DOUBLES_EQUAL( -570600, nYPosOfTopleft, 10000);
5533 CPPUNIT_ASSERT_DOUBLES_EQUAL( 294840, nWidth, 10000);
5534 CPPUNIT_ASSERT_DOUBLES_EQUAL( 1988280, nHeight, 10000);
5537 void ScExportTest::testTdf123353()
5539 ScDocShellRef xShell = loadDoc("tdf123353.", FORMAT_XLSX);
5540 CPPUNIT_ASSERT(xShell.is());
5542 ScDocShellRef xDocSh = saveAndReload(&(*xShell), FORMAT_XLSX);
5543 CPPUNIT_ASSERT(xDocSh.is());
5545 std::shared_ptr<utl::TempFile> pXPathFile = ScBootstrapFixture::exportTo(&(*xDocSh), FORMAT_XLSX);
5547 xmlDocUniquePtr pDoc = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/worksheets/sheet1.xml");
5548 CPPUNIT_ASSERT(pDoc);
5550 assertXPath(pDoc, "/x:worksheet/x:autoFilter/x:filterColumn/x:filters", "blank", "1");
5552 xShell->DoClose();
5555 void ScExportTest::testTdf133688_precedents()
5557 // tdf#133688 Check that we do not export detective shapes.
5558 ScDocShellRef xShell = loadDoc("tdf133688_dont_save_precedents_to_xlsx.", FORMAT_ODS);
5559 CPPUNIT_ASSERT(xShell.is());
5561 std::shared_ptr<utl::TempFile> pXPathFile
5562 = ScBootstrapFixture::exportTo(&(*xShell), FORMAT_XLSX);
5563 xmlDocUniquePtr pDrawing
5564 = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/drawings/drawing1.xml");
5565 CPPUNIT_ASSERT(pDrawing);
5567 // We do not export any shapes.
5568 assertXPath(pDrawing, "/xdr:wsDr/xdr:twoCellAnchor[1]", 0);
5571 void ScExportTest::testTdf91251_missingOverflowRoundtrip()
5573 // tdf#91251 check whether textBox overflow property (horzOverflow and vertOverflow) is
5574 // getting preserved after roundtrip
5575 ScDocShellRef xShell = loadDoc("tdf91251_missingOverflowRoundtrip.", FORMAT_XLSX);
5576 CPPUNIT_ASSERT(xShell.is());
5578 ScDocShellRef xDocSh = saveAndReload(&(*xShell), FORMAT_XLSX);
5579 CPPUNIT_ASSERT(xDocSh.is());
5581 std::shared_ptr<utl::TempFile> pXPathFile = ScBootstrapFixture::exportTo(&(*xDocSh), FORMAT_XLSX);
5583 xmlDocUniquePtr pDrawing = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/drawings/drawing1.xml");
5584 CPPUNIT_ASSERT(pDrawing);
5586 assertXPath(pDrawing, "/xdr:wsDr/xdr:twoCellAnchor/xdr:sp/xdr:txBody/a:bodyPr", "horzOverflow", "clip");
5587 assertXPath(pDrawing, "/xdr:wsDr/xdr:twoCellAnchor/xdr:sp/xdr:txBody/a:bodyPr", "horzOverflow", "clip");
5590 void ScExportTest::testTdf137000_handle_upright()
5592 // tdf#106197 When exporting the "upright" attribute, we must set
5593 // TextPreRotateAngle to 0.
5594 // (Upright is an xml attribute of xdr:txBody/a:bodyPr. It is set when
5595 // in a textbox menu we choose: do not rotate this element.)
5596 ScDocShellRef xShell = loadDoc("tdf137000_export_upright.", FORMAT_XLSX);
5597 CPPUNIT_ASSERT(xShell.is());
5599 std::shared_ptr<utl::TempFile> pXPathFile
5600 = ScBootstrapFixture::exportTo(&(*xShell), FORMAT_XLSX);
5601 xmlDocUniquePtr pDrawing
5602 = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/drawings/drawing1.xml");
5603 CPPUNIT_ASSERT(pDrawing);
5605 assertXPathNoAttribute(pDrawing, "/xdr:wsDr/xdr:twoCellAnchor/xdr:sp/xdr:txBody/a:bodyPr",
5606 "rot");
5609 void ScExportTest::testTdf126305_DataValidatyErrorAlert()
5611 ScDocShellRef xShell = loadDoc("tdf126305.", FORMAT_ODS);
5612 CPPUNIT_ASSERT(xShell.is());
5614 ScDocShellRef xDocSh = saveAndReload(&(*xShell), FORMAT_XLSX);
5615 CPPUNIT_ASSERT(xDocSh.is());
5617 std::shared_ptr<utl::TempFile> pXPathFile = ScBootstrapFixture::exportTo(&(*xDocSh), FORMAT_XLSX);
5618 xmlDocUniquePtr pDoc = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/worksheets/sheet1.xml");
5619 CPPUNIT_ASSERT(pDoc);
5621 assertXPath(pDoc, "/x:worksheet/x:dataValidations/x:dataValidation[1]", "errorStyle", "stop");
5622 assertXPath(pDoc, "/x:worksheet/x:dataValidations/x:dataValidation[2]", "errorStyle", "warning");
5623 assertXPath(pDoc, "/x:worksheet/x:dataValidations/x:dataValidation[3]", "errorStyle", "information");
5625 xDocSh->DoClose();
5628 void ScExportTest::testTdf76047_externalLink()
5630 ScDocShellRef pShell = loadDoc("tdf76047_externalLink.", FORMAT_XLSX);
5631 CPPUNIT_ASSERT(pShell.is());
5633 // load data from external links. (tdf76047_externalLinkSource.ods)
5634 // that file has to be in the same directory as tdf76047_externalLink.xlsx
5635 pShell->ReloadAllLinks();
5636 ScDocument& rDoc = pShell->GetDocument();
5638 // compare the data loaded from external links with the expected result stored in the test file
5639 for (int nCol = 1; nCol <= 5; nCol++)
5641 for (int nRow = 3; nRow <= 5; nRow++)
5643 OUString aStr1 = rDoc.GetString(ScAddress(nCol, nRow, 0));
5644 OUString aStr2 = rDoc.GetString(ScAddress(nCol, nRow + 5, 0));
5645 OUString aStr3 = rDoc.GetString(ScAddress(nCol, nRow + 11, 0));
5647 CPPUNIT_ASSERT_EQUAL(aStr1, aStr3);
5648 CPPUNIT_ASSERT_EQUAL(aStr2, aStr3);
5653 void ScExportTest::testTdf87973_externalLinkSkipUnuseds()
5655 ScDocShellRef pShell = loadDoc("tdf87973_externalLinkSkipUnuseds.", FORMAT_ODS);
5656 CPPUNIT_ASSERT(pShell.is());
5658 // try to load data from external link: tdf132105_external.ods
5659 // that file has to be in the same directory as tdf87973_externalLinkSkipUnuseds.ods
5660 pShell->ReloadAllLinks();
5661 ScDocument& rDoc = pShell->GetDocument();
5663 // change external link to: 87973_externalSource.ods
5664 OUString aFormula, aFormula2;
5665 rDoc.GetFormula(3, 1, 0, aFormula);
5666 auto nIdxOfFilename = aFormula.indexOf("tdf132105_external.ods");
5667 aFormula = aFormula.replaceAt(nIdxOfFilename, 22, "87973_externalSource.ods");
5668 auto nIdxOfFile = aFormula.indexOf("file");
5670 // saveAndReload save the file to a temporary directory
5671 // the link must be changed to point to that directory
5672 utl::TempFile aTempFile;
5673 auto aTempFilename = aTempFile.GetURL();
5674 auto nIdxOfTmpFile = aTempFilename.lastIndexOf('/');
5675 aTempFilename = aTempFilename.copy(0, nIdxOfTmpFile + 1);
5677 aFormula = aFormula.replaceAt(nIdxOfFile, nIdxOfFilename - nIdxOfFile, aTempFilename);
5678 rDoc.SetFormula(ScAddress(3, 1, 0), aFormula, formula::FormulaGrammar::GRAM_NATIVE_UI);
5680 // tdf#138832: test the same thing with singleref link
5681 rDoc.GetFormula(3, 2, 0, aFormula);
5682 nIdxOfFilename = aFormula.indexOf("tdf132105_external.ods");
5683 aFormula = aFormula.replaceAt(nIdxOfFilename, 22, "87973_externalSource.ods");
5684 nIdxOfFile = aFormula.indexOf("file");
5686 aFormula = aFormula.replaceAt(nIdxOfFile, nIdxOfFilename - nIdxOfFile, aTempFilename);
5687 rDoc.SetFormula(ScAddress(3, 2, 0), aFormula, formula::FormulaGrammar::GRAM_NATIVE_UI);
5689 // save and load back
5690 ScDocShellRef pDocSh = saveAndReload(&(*pShell), FORMAT_XLSX);
5691 CPPUNIT_ASSERT(pDocSh.is());
5693 // check if the the new filename is present in the link (and not replaced by '[2]')
5694 ScDocument& rDoc2 = pDocSh->GetDocument();
5695 rDoc2.GetFormula(3, 1, 0, aFormula2);
5696 CPPUNIT_ASSERT(aFormula2.indexOf("tdf132105_external.ods") < 0);
5697 CPPUNIT_ASSERT(aFormula2.indexOf("87973_externalSource.ods") >= 0);
5698 rDoc2.GetFormula(3, 2, 0, aFormula2);
5699 CPPUNIT_ASSERT(aFormula2.indexOf("tdf132105_external.ods") < 0);
5700 CPPUNIT_ASSERT(aFormula2.indexOf("87973_externalSource.ods") >= 0);
5702 pDocSh->DoClose();
5705 void ScExportTest::testTdf51022_lostPrintRange()
5707 ScDocShellRef pShell = loadDoc(u"tdf87973_externalLinkSkipUnuseds.", FORMAT_ODS);
5708 CPPUNIT_ASSERT(pShell.is());
5710 pShell->ReloadAllLinks();
5711 ScDocument& rDoc = pShell->GetDocument();
5713 //Add print ranges
5714 ScRange aRange1(1, 2, 0, 3, 4, 0);
5715 ScRange aRange2(1, 6, 0, 3, 7, 0);
5716 rDoc.AddPrintRange(0, aRange1);
5717 rDoc.AddPrintRange(0, aRange2);
5719 // save and load back
5720 ScDocShellRef pDocSh = saveAndReload(&(*pShell), FORMAT_ODS);
5721 CPPUNIT_ASSERT(pDocSh.is());
5723 // check if the same print ranges are present
5724 ScDocument& rDoc2 = pDocSh->GetDocument();
5725 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(2), rDoc2.GetPrintRangeCount(0));
5726 CPPUNIT_ASSERT_EQUAL(aRange1, *rDoc2.GetPrintRange(0, 0));
5727 CPPUNIT_ASSERT_EQUAL(aRange2, *rDoc2.GetPrintRange(0, 1));
5729 pDocSh->DoClose();
5732 void ScExportTest::testTdf138741_externalLinkSkipUnusedsCrash()
5734 ScDocShellRef xShell = loadDoc("tdf138741_externalLinkSkipUnusedsCrash.", FORMAT_XLSX);
5735 CPPUNIT_ASSERT(xShell);
5737 //without the fix in place, it would have crashed at export time
5738 ScBootstrapFixture::exportTo(&(*xShell), FORMAT_XLSX);
5740 xShell->DoClose();
5743 void ScExportTest::testTdf138824_linkToParentDirectory()
5745 ScDocShellRef xShell = loadDoc("childDir/tdf138824_linkToParentDirectory.", FORMAT_ODS);
5746 CPPUNIT_ASSERT(xShell.is());
5748 ScDocument& rDoc = xShell->GetDocument();
5750 // saveAndReload save the file to a temporary directory
5751 // the link must be changed to point to that parent directory
5752 utl::TempFile aTempFile;
5753 auto aTempFilename = aTempFile.GetURL();
5754 auto nIdxOfTmpFile = aTempFilename.lastIndexOf('/');
5755 nIdxOfTmpFile = aTempFilename.lastIndexOf('/', nIdxOfTmpFile);
5756 aTempFilename = aTempFilename.copy(0, nIdxOfTmpFile + 1);
5758 // change external link to tmp directory
5759 OUString aFormula;
5760 rDoc.GetFormula(3, 1, 0, aFormula);
5761 auto nIdxOfFilename = aFormula.indexOf("tdf138824_externalSource.ods");
5762 auto nIdxOfFile = aFormula.indexOf("file");
5764 aFormula = aFormula.replaceAt(nIdxOfFile, nIdxOfFilename - nIdxOfFile, aTempFilename);
5765 rDoc.SetFormula(ScAddress(3, 1, 0), aFormula, formula::FormulaGrammar::GRAM_NATIVE_UI);
5767 ScDocShellRef xDocSh = saveAndReload(&(*xShell), FORMAT_XLSX);
5768 CPPUNIT_ASSERT(xDocSh.is());
5770 std::shared_ptr<utl::TempFile> pXPathFile
5771 = ScBootstrapFixture::exportTo(&(*xDocSh), FORMAT_XLSX);
5772 xmlDocUniquePtr pDoc = XPathHelper::parseExport(
5773 pXPathFile, m_xSFactory, "xl/externalLinks/_rels/externalLink1.xml.rels");
5774 CPPUNIT_ASSERT(pDoc);
5776 // test also the Linux specific bug tdf#121472
5777 assertXPath(pDoc, "/r:Relationships/r:Relationship", "Target",
5778 "../tdf138824_externalSource.ods");
5780 xDocSh->DoClose();
5783 void ScExportTest::testTdf129969()
5785 ScDocShellRef xShell = loadDoc("external_hyperlink.", FORMAT_ODS);
5786 CPPUNIT_ASSERT(xShell.is());
5788 ScDocShellRef xDocSh = saveAndReload(&(*xShell), FORMAT_XLSX);
5789 CPPUNIT_ASSERT(xDocSh.is());
5790 ScDocument& rDoc = xDocSh->GetDocument();
5791 ScAddress aPos(0, 0, 0);
5792 const EditTextObject* pEditText = rDoc.GetEditText(aPos);
5793 const SvxFieldData* pData = pEditText->GetFieldData(0, 0, text::textfield::Type::URL);
5794 const SvxURLField* pURLData = static_cast<const SvxURLField*>(pData);
5795 CPPUNIT_ASSERT(pURLData->GetURL().endsWith("/%23folder/test.ods#Sheet2.B10"));
5797 xDocSh->DoClose();
5800 void ScExportTest::testTdf84874()
5802 ScDocShellRef xShell = loadDoc("tdf84874.", FORMAT_ODS);
5803 CPPUNIT_ASSERT(xShell.is());
5805 ScDocShellRef xDocSh = saveAndReload(xShell.get(), FORMAT_XLSX);
5806 xShell->DoClose();
5807 CPPUNIT_ASSERT(xDocSh.is());
5809 ScDocument& rDoc = xDocSh->GetDocument();
5811 const ScValidationData* pData = rDoc.GetValidationEntry(1);
5812 OUString aTitle, aText;
5813 pData->GetInput(aTitle, aText);
5814 sal_uInt32 nPromptTitleLen = aTitle.getLength();
5815 sal_uInt32 nPromptTextLen = aText.getLength();
5817 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32>(255), nPromptTitleLen);
5818 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32>(255), nPromptTextLen);
5820 ScValidErrorStyle eErrStyle = SC_VALERR_STOP;
5821 pData->GetErrMsg(aTitle, aText, eErrStyle);
5822 sal_uInt32 nErrorTitleLen = aTitle.getLength();
5823 sal_uInt32 nErrorTextLen = aText.getLength();
5825 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32>(255), nErrorTitleLen);
5826 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32>(255), nErrorTextLen);
5828 xDocSh->DoClose();
5831 void ScExportTest::testTdf136721_paper_size()
5833 ScDocShellRef xShell = loadDoc("tdf136721_letter_sized_paper.", FORMAT_XLSX);
5834 CPPUNIT_ASSERT(xShell.is());
5836 std::shared_ptr<utl::TempFile> pXPathFile = ScBootstrapFixture::exportTo(&(*xShell), FORMAT_XLSX);
5837 xmlDocUniquePtr pDoc = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/worksheets/sheet1.xml");
5838 CPPUNIT_ASSERT(pDoc);
5840 assertXPath(pDoc, "/x:worksheet/x:pageSetup", "paperSize", "70");
5843 void ScExportTest::testTdf139258_rotated_image()
5845 // Check that the topleft position of the image is correct.
5846 ScDocShellRef xShell = loadDoc(u"tdf139258_rotated_image.", FORMAT_ODS);
5847 CPPUNIT_ASSERT(xShell.is());
5849 std::shared_ptr<utl::TempFile> pXPathFile
5850 = ScBootstrapFixture::exportTo(&(*xShell), FORMAT_XLSX);
5852 xmlDocUniquePtr pDrawing
5853 = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/drawings/drawing1.xml");
5854 CPPUNIT_ASSERT(pDrawing);
5856 assertXPathContent(pDrawing, "/xdr:wsDr/xdr:twoCellAnchor/xdr:from/xdr:col", "1");
5857 assertXPathContent(pDrawing, "/xdr:wsDr/xdr:twoCellAnchor/xdr:from/xdr:row", "12");
5858 assertXPathContent(pDrawing, "/xdr:wsDr/xdr:twoCellAnchor/xdr:to/xdr:col", "6");
5859 assertXPathContent(pDrawing, "/xdr:wsDr/xdr:twoCellAnchor/xdr:to/xdr:row", "25");
5862 void ScExportTest::testTdf140431()
5864 ScDocShellRef xShell = loadDoc(u"129969-min.", FORMAT_XLSX);
5865 CPPUNIT_ASSERT(xShell.is());
5867 ScDocShellRef xDocSh = saveAndReload(&(*xShell), FORMAT_XLSX);
5868 CPPUNIT_ASSERT(xDocSh.is());
5869 ScDocument& rDoc = xDocSh->GetDocument();
5870 ScAddress aPos(0, 2, 0);
5871 const EditTextObject* pEditText = rDoc.GetEditText(aPos);
5872 const SvxFieldData* pData = pEditText->GetFieldData(0, 0, text::textfield::Type::URL);
5873 const SvxURLField* pURLData = static_cast<const SvxURLField*>(pData);
5874 CPPUNIT_ASSERT(pURLData->GetURL().startsWith("file://ndhlis"));
5876 xDocSh->DoClose();
5879 void ScExportTest::testTdf142264ManyChartsToXLSX()
5881 // The cache size for the test should be small enough, to make sure that some charts get
5882 // unloaded in the process, and then loaded on demand properly (default is currently 20)
5883 CPPUNIT_ASSERT_LESS(sal_Int32(40),
5884 officecfg::Office::Common::Cache::DrawingEngine::OLE_Objects::get());
5886 ScDocShellRef xDocSh = loadDoc(u"many_charts.", FORMAT_ODS);
5887 CPPUNIT_ASSERT(xDocSh.is());
5888 xDocSh = saveAndReload(xDocSh.get(), FORMAT_XLSX);
5889 CPPUNIT_ASSERT(xDocSh.is());
5891 auto xModel = xDocSh->GetModel();
5892 css::uno::Reference<css::drawing::XDrawPagesSupplier> xSupplier(xModel,
5893 css::uno::UNO_QUERY_THROW);
5894 auto xDrawPages = xSupplier->getDrawPages();
5896 // No charts (or other objects) on the first sheet, and resp. first draw page
5897 css::uno::Reference<css::drawing::XDrawPage> xPage(xDrawPages->getByIndex(0),
5898 css::uno::UNO_QUERY_THROW);
5899 CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xPage->getCount());
5901 // 20 charts on the second sheet, and resp. second draw page
5902 xPage.set(xDrawPages->getByIndex(1), css::uno::UNO_QUERY_THROW);
5903 // Without the fix in place, this test would have failed with
5904 // - Expected: 20
5905 // - Actual : 0
5906 // Because only the last 20 charts would get exported, all on the third sheet
5907 CPPUNIT_ASSERT_EQUAL(sal_Int32(20), xPage->getCount());
5908 for (sal_Int32 i = 0; i < xPage->getCount(); ++i)
5910 css::uno::Reference<css::beans::XPropertySet> xProps(xPage->getByIndex(i),
5911 css::uno::UNO_QUERY_THROW);
5912 css::uno::Reference<css::chart2::XChartDocument> xChart(xProps->getPropertyValue("Model"),
5913 css::uno::UNO_QUERY_THROW);
5914 const auto xDiagram = xChart->getFirstDiagram();
5915 CPPUNIT_ASSERT(xDiagram);
5917 css::uno::Reference<css::chart2::XCoordinateSystemContainer> xCooSysContainer(
5918 xDiagram, uno::UNO_QUERY_THROW);
5920 const auto xCooSysSeq = xCooSysContainer->getCoordinateSystems();
5921 for (const auto& rCooSys : xCooSysSeq)
5923 css::uno::Reference<css::chart2::XChartTypeContainer> xChartTypeCont(
5924 rCooSys, uno::UNO_QUERY_THROW);
5925 uno::Sequence<uno::Reference<chart2::XChartType>> xChartTypeSeq
5926 = xChartTypeCont->getChartTypes();
5927 CPPUNIT_ASSERT(xChartTypeSeq.hasElements());
5931 // 20 charts on the third sheet, and resp. third draw page
5932 xPage.set(xDrawPages->getByIndex(2), css::uno::UNO_QUERY_THROW);
5933 CPPUNIT_ASSERT_EQUAL(sal_Int32(20), xPage->getCount());
5934 for (sal_Int32 i = 0; i < xPage->getCount(); ++i)
5936 css::uno::Reference<css::beans::XPropertySet> xProps(xPage->getByIndex(i),
5937 css::uno::UNO_QUERY_THROW);
5938 css::uno::Reference<css::chart2::XChartDocument> xChart(xProps->getPropertyValue("Model"),
5939 css::uno::UNO_QUERY_THROW);
5940 const auto xDiagram = xChart->getFirstDiagram();
5941 CPPUNIT_ASSERT(xDiagram);
5943 css::uno::Reference<css::chart2::XCoordinateSystemContainer> xCooSysContainer(
5944 xDiagram, uno::UNO_QUERY_THROW);
5946 const auto xCooSysSeq = xCooSysContainer->getCoordinateSystems();
5947 for (const auto& rCooSys : xCooSysSeq)
5949 css::uno::Reference<css::chart2::XChartTypeContainer> xChartTypeCont(
5950 rCooSys, uno::UNO_QUERY_THROW);
5951 uno::Sequence<uno::Reference<chart2::XChartType>> xChartTypeSeq
5952 = xChartTypeCont->getChartTypes();
5953 CPPUNIT_ASSERT(xChartTypeSeq.hasElements());
5957 xDocSh->DoClose();
5960 CPPUNIT_TEST_SUITE_REGISTRATION(ScExportTest);
5962 CPPUNIT_PLUGIN_IMPLEMENT();
5964 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */