1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 #include <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>
26 #include <patattr.hxx>
27 #include <docpool.hxx>
28 #include <scitems.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>
38 #include <tokenstringcontext.hxx>
39 #include <chgtrack.hxx>
40 #include <validat.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
90 virtual void registerNamespaces(xmlXPathContextPtr
& pXmlXPathCtx
) override
;
94 virtual void setUp() override
;
95 virtual void tearDown() override
;
100 void testExtCondFormatXLSX();
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();
137 void testCustomColumnWidthExportXLSX();
139 void testXfDefaultValuesXLSX();
141 void testColumnWidthResaveXLSX();
143 void testColumnWidthExportFromODStoXLSX();
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();
209 void testTdf130108();
212 void testTdf129985();
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();
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();
268 void testTdf122331();
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();
288 void testTdf136721_paper_size();
289 void testTdf139258_rotated_image();
290 void testTdf140431();
291 void testTdf142264ManyChartsToXLSX();
293 CPPUNIT_TEST_SUITE(ScExportTest
);
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
);
332 CPPUNIT_TEST(testCustomColumnWidthExportXLSX
);
334 CPPUNIT_TEST(testXfDefaultValuesXLSX
);
335 CPPUNIT_TEST(testODF13
);
336 CPPUNIT_TEST(testColumnWidthResaveXLSX
);
338 CPPUNIT_TEST(testColumnWidthExportFromODStoXLSX
);
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();
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
);
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);
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",
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");
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
);
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");
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");
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
);
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");
659 void ScExportTest::testPasswordExportODS()
661 ScDocShell
* pShell
= new ScDocShell(
662 SfxModelFlags::EMBEDDED_OBJECT
|
663 SfxModelFlags::DISABLE_EMBEDDED_SCRIPTS
|
664 SfxModelFlags::DISABLE_DOCUMENT_RECOVERY
);
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);
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)));
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();
713 createCSVPath( "new_cond_format_test_export.", aCSVPath
);
714 testCondFile(aCSVPath
, &rDoc
, 0);
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
);
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();
765 createCSVPath( "new_cond_format_test_export.", aCSVPath
);
766 testCondFile(aCSVPath
, &rDoc
, 0);
770 createCSVPath( "new_cond_format_test_sheet2.", aCSVPath
);
771 testCondFile(aCSVPath
, &rDoc
, 1);
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());
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']");
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']");
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']");
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']");
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']");
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
);
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
);
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
);
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
);
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",
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");
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",
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);
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
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");
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);
1151 // TODO where to put this?
1155 std::function
<void ()> m_Func
;
1158 Resetter(std::function
<void ()> const& rFunc
)
1168 catch (...) // has to be reliable
1170 fprintf(stderr
, "resetter failed with exception\n");
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()
1198 ScDocShellRef pShell
= loadDoc("spreadsheet13e.", FORMAT_ODS
);
1201 verifySpreadsheet13("import", pShell
);
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();
1212 std::shared_ptr
<comphelper::ConfigurationChanges
> pBatch(
1213 comphelper::ConfigurationChanges::create());
1214 officecfg::Office::Common::Save::ODF::DefaultVersion::set(10, pBatch
);
1217 std::shared_ptr
<utl::TempFile
> pXPathFile
= ScBootstrapFixture::exportTo(&(*pShell
), FORMAT_ODS
);
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']");
1227 pShell
= load(pXPathFile
->GetURL(), "calc8", OUString(), OUString(), ODS_FORMAT_TYPE
, SotClipboardFormatId::STARCALC_8
);
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
);
1239 std::shared_ptr
<utl::TempFile
> pXPathFile
= ScBootstrapFixture::saveAs(&(*pShell
), FORMAT_ODS
);
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']");
1250 pShell
= load(pXPathFile
->GetURL(), "calc8", OUString(), OUString(), ODS_FORMAT_TYPE
, SotClipboardFormatId::STARCALC_8
);
1253 verifySpreadsheet13("1.2 Extended reload", pShell
);
1257 std::shared_ptr
<comphelper::ConfigurationChanges
> pBatch(
1258 comphelper::ConfigurationChanges::create());
1259 officecfg::Office::Common::Save::ODF::DefaultVersion::set(4, pBatch
);
1262 std::shared_ptr
<utl::TempFile
> pXPathFile
= ScBootstrapFixture::saveAs(&(*pShell
), FORMAT_ODS
);
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);
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();
1354 sal_uInt16 nCalcWidth
;
1355 nCalcWidth
= rDoc
.GetColWidth(static_cast<SCCOL
>(0), static_cast<SCTAB
>(0), false);
1356 CPPUNIT_ASSERT_EQUAL( nExpectedColumn0Width
, nCalcWidth
);
1359 nCalcWidth
= rDoc
.GetColWidth(static_cast<SCCOL
>(1), static_cast<SCTAB
>(0), false);
1360 CPPUNIT_ASSERT_EQUAL( nExpectedColumn1Width
, nCalcWidth
);
1363 nCalcWidth
= rDoc
.GetColWidth(static_cast<SCCOL
>(2), static_cast<SCTAB
>(0), false);
1364 CPPUNIT_ASSERT_EQUAL( nExpectedColumn2Width
, nCalcWidth
);
1367 nCalcWidth
= rDoc
.GetColWidth(static_cast<SCCOL
>(3), static_cast<SCTAB
>(0), false);
1368 CPPUNIT_ASSERT_EQUAL( nExpectedColumn3Width
, nCalcWidth
);
1371 nCalcWidth
= rDoc
.GetColWidth(static_cast<SCCOL
>(4), static_cast<SCTAB
>(0), false);
1372 CPPUNIT_ASSERT_EQUAL( nExpectedColumn4Width
, nCalcWidth
);
1374 xXlsxDocSh
->DoClose();
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);
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");
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");
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
);
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
) );
1634 void setAttribute( ScFieldEditEngine
& rEE
, sal_Int32 nPara
, sal_Int32 nStart
, sal_Int32 nEnd
, sal_uInt16 nType
, Color nColor
= COL_BLACK
)
1637 aSel
.nStartPara
= aSel
.nEndPara
= nPara
;
1638 aSel
.nStartPos
= nStart
;
1639 aSel
.nEndPos
= nEnd
;
1641 SfxItemSet aItemSet
= rEE
.GetEmptyItemSet();
1644 case EE_CHAR_WEIGHT
:
1646 SvxWeightItem
aWeight(WEIGHT_BOLD
, nType
);
1647 aItemSet
.Put(aWeight
);
1648 rEE
.QuickSetAttribs(aItemSet
, aSel
);
1651 case EE_CHAR_ITALIC
:
1653 SvxPostureItem
aItalic(ITALIC_NORMAL
, nType
);
1654 aItemSet
.Put(aItalic
);
1655 rEE
.QuickSetAttribs(aItemSet
, aSel
);
1658 case EE_CHAR_STRIKEOUT
:
1660 SvxCrossedOutItem
aCrossOut(STRIKEOUT_SINGLE
, nType
);
1661 aItemSet
.Put(aCrossOut
);
1662 rEE
.QuickSetAttribs(aItemSet
, aSel
);
1665 case EE_CHAR_OVERLINE
:
1667 SvxOverlineItem
aItem(LINESTYLE_DOUBLE
, nType
);
1668 aItemSet
.Put(aItem
);
1669 rEE
.QuickSetAttribs(aItemSet
, aSel
);
1672 case EE_CHAR_UNDERLINE
:
1674 SvxUnderlineItem
aItem(LINESTYLE_DOUBLE
, nType
);
1675 aItemSet
.Put(aItem
);
1676 rEE
.QuickSetAttribs(aItemSet
, aSel
);
1681 SvxColorItem
aItem(nColor
, nType
);
1682 aItemSet
.Put(aItem
);
1683 rEE
.QuickSetAttribs(aItemSet
, aSel
);
1691 void setFont( ScFieldEditEngine
& rEE
, sal_Int32 nPara
, sal_Int32 nStart
, sal_Int32 nEnd
, const OUString
& rFontName
)
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
)
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());
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
);
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());
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());
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);
1770 void ScExportTest::testRichTextExportODS()
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
)
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
1839 if (pText
->GetParagraphCount() != 1)
1842 if (pText
->GetText(0) != "Bold and Italic")
1845 std::vector
<editeng::Section
> aSecAttrs
;
1846 pText
->GetAllSections(aSecAttrs
);
1847 if (aSecAttrs
.size() != 3)
1850 // Check the first bold section.
1851 const editeng::Section
* pAttr
= aSecAttrs
.data();
1852 if (pAttr
->mnParagraph
!= 0 ||pAttr
->mnStart
!= 0 || pAttr
->mnEnd
!= 4)
1855 if (pAttr
->maAttributes
.size() != 1 || !isBold(*pAttr
))
1858 // The middle section should be unformatted.
1859 pAttr
= &aSecAttrs
[1];
1860 if (pAttr
->mnParagraph
!= 0 ||pAttr
->mnStart
!= 4 || pAttr
->mnEnd
!= 9)
1863 if (!pAttr
->maAttributes
.empty())
1866 // The last section should be italic.
1867 pAttr
= &aSecAttrs
[2];
1868 if (pAttr
->mnParagraph
!= 0 ||pAttr
->mnStart
!= 9 || pAttr
->mnEnd
!= 15)
1871 if (pAttr
->maAttributes
.size() != 1 || !isItalic(*pAttr
))
1877 bool checkB4(const EditTextObject
* pText
) const
1882 if (pText
->GetParagraphCount() != 3)
1885 if (pText
->GetText(0) != "One")
1888 if (pText
->GetText(1) != "Two")
1891 if (pText
->GetText(2) != "Three")
1897 bool checkB5(const EditTextObject
* pText
) const
1902 if (pText
->GetParagraphCount() != 6)
1905 if (!pText
->GetText(0).isEmpty())
1908 if (pText
->GetText(1) != "Two")
1911 if (pText
->GetText(2) != "Three")
1914 if (!pText
->GetText(3).isEmpty())
1917 if (pText
->GetText(4) != "Five")
1920 if (!pText
->GetText(5).isEmpty())
1926 bool checkB6(const EditTextObject
* pText
) const
1931 if (pText
->GetParagraphCount() != 1)
1934 if (pText
->GetText(0) != "Strike Me")
1937 std::vector
<editeng::Section
> aSecAttrs
;
1938 pText
->GetAllSections(aSecAttrs
);
1939 if (aSecAttrs
.size() != 2)
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)
1947 if (pAttr
->maAttributes
.size() != 1 || !isStrikeOut(*pAttr
))
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
1960 if (pText
->GetParagraphCount() != 1)
1963 if (pText
->GetText(0) != "Font1 and Font2")
1966 std::vector
<editeng::Section
> aSecAttrs
;
1967 pText
->GetAllSections(aSecAttrs
);
1968 if (aSecAttrs
.size() != 3)
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)
1976 if (pAttr
->maAttributes
.size() != 1 || !isFont(*pAttr
, "Courier"))
1979 // Last section should have "Luxi Mono" applied.
1980 pAttr
= &aSecAttrs
[2];
1981 if (pAttr
->mnParagraph
!= 0 ||pAttr
->mnStart
!= 10 || pAttr
->mnEnd
!= 15)
1984 if (pAttr
->maAttributes
.size() != 1 || !isFont(*pAttr
, "Luxi Mono"))
1990 bool checkB8(const EditTextObject
* pText
) const
1995 if (pText
->GetParagraphCount() != 1)
1998 if (pText
->GetText(0) != "Over and Under")
2001 std::vector
<editeng::Section
> aSecAttrs
;
2002 pText
->GetAllSections(aSecAttrs
);
2003 if (aSecAttrs
.size() != 3)
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)
2011 if (pAttr
->maAttributes
.size() != 1 || !isOverline(*pAttr
, LINESTYLE_DOUBLE
))
2014 // Last section should have underline applied.
2015 pAttr
= &aSecAttrs
[2];
2016 if (pAttr
->mnParagraph
!= 0 ||pAttr
->mnStart
!= 9 || pAttr
->mnEnd
!= 14)
2019 if (pAttr
->maAttributes
.size() != 1 || !isUnderline(*pAttr
, LINESTYLE_DOUBLE
))
2025 bool checkB9(const EditTextObject
* pText
) const
2030 if (pText
->GetParagraphCount() != 1)
2033 if (pText
->GetText(0) != "Sub and Super")
2036 std::vector
<editeng::Section
> aSecAttrs
;
2037 pText
->GetAllSections(aSecAttrs
);
2038 if (aSecAttrs
.size() != 3)
2042 const editeng::Section
* pAttr
= aSecAttrs
.data();
2043 if (pAttr
->mnParagraph
!= 0 ||pAttr
->mnStart
!= 0 || pAttr
->mnEnd
!= 3)
2046 if (pAttr
->maAttributes
.size() != 1 || !isEscapement(*pAttr
, 32, 64))
2050 pAttr
= &aSecAttrs
[2];
2051 if (pAttr
->mnParagraph
!= 0 ||pAttr
->mnStart
!= 8 || pAttr
->mnEnd
!= 13)
2054 if (pAttr
->maAttributes
.size() != 1 || !isEscapement(*pAttr
, -32, 66))
2060 bool checkB10(const EditTextObject
* pText
) const
2065 if (pText
->GetParagraphCount() != 1)
2068 if (pText
->GetText(0) != "BLUE AUTO")
2071 std::vector
<editeng::Section
> aSecAttrs
;
2072 pText
->GetAllSections(aSecAttrs
);
2073 if (aSecAttrs
.size() != 2)
2077 const editeng::Section
* pAttr
= &aSecAttrs
[1];
2078 if (pAttr
->mnParagraph
!= 0 ||pAttr
->mnStart
!= 5 || pAttr
->mnEnd
!= 9)
2081 if (pAttr
->maAttributes
.size() != 1 || !isColor(*pAttr
, COL_AUTO
))
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
);
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.
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.
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.
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.
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.
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
));
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
);
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");
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
);
2271 ScDocument
& rDoc
= xNewDocSh
->GetDocument();
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
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
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
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);
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));
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));
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
));
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();
2427 void checkMatrixRange(ScDocument
& rDoc
, const ScRange
& rRange
)
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
);
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));
2469 checkMatrixRange(rDoc
, ScRange(1,7,0,2,9,0));
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
);
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");
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
);
2499 CPPUNIT_ASSERT(xDocSh
.is());
2501 ScDocument
& rDoc
= xDocSh
->GetDocument();
2503 // Make sure the 2nd sheet is named 'Chart1'.
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)));
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);
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
);
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");
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
);
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
) );
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
));
2611 const char* toBorderName( SvxBorderLineStyle 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";
2631 void ScExportTest::testExcelCellBorders( sal_uLong nFormatType
)
2636 SvxBorderLineStyle mnStyle
;
2637 tools::Long mnWidth
;
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
);
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;
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 */
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
);
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());
2783 static OUString
toString( const ScBigRange
& rRange
)
2785 OUStringBuffer aBuf
;
2786 aBuf
.append("(columns:");
2787 aBuf
.append(rRange
.aStart
.Col());
2789 aBuf
.append(rRange
.aEnd
.Col());
2790 aBuf
.append(";rows:");
2791 aBuf
.append(rRange
.aStart
.Row());
2793 aBuf
.append(rRange
.aEnd
.Row());
2794 aBuf
.append(";sheets:");
2795 aBuf
.append(rRange
.aStart
.Tab());
2797 aBuf
.append(rRange
.aEnd
.Tab());
2800 return aBuf
.makeStringAndClear();
2803 void ScExportTest::testTrackChangesSimpleXLSX()
2807 sal_uLong mnActionId
;
2808 ScChangeActionType meType
;
2810 sal_Int32 mnStartCol
;
2811 sal_Int32 mnStartRow
;
2812 sal_Int32 mnStartTab
;
2817 bool mbRowInsertedAtBottom
;
2822 bool checkRange( ScChangeActionType eType
, const ScBigRange
& rExpected
, const ScBigRange
& rActual
)
2824 ScBigRange
aExpected(rExpected
), aActual(rActual
);
2828 case SC_CAT_INSERT_ROWS
:
2831 aExpected
.aStart
.SetCol(0);
2832 aExpected
.aEnd
.SetCol(0);
2833 aActual
.aStart
.SetCol(0);
2834 aActual
.aEnd
.SetCol(0);
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();
2866 cerr
<< "Change track instance doesn't exist." << endl
;
2870 sal_uLong nActionMax
= pCT
->GetActionMax();
2871 if (nActionMax
!= 13)
2873 cerr
<< "Unexpected highest action ID value." << endl
;
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
);
2883 cerr
<< "No action for action number " << nActId
<< " found." << endl
;
2887 if (pAction
->GetType() != aChecks
[i
].meType
)
2889 cerr
<< "Unexpected action type for action number " << nActId
<< "." << endl
;
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
;
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
;
2924 bool checkRevisionUserAndTime( ScDocument
& rDoc
, const OUString
& rOwnerName
)
2926 ScChangeTrack
* pCT
= rDoc
.GetChangeTrack();
2929 cerr
<< "Change track instance doesn't exist." << endl
;
2933 ScChangeAction
* pAction
= pCT
->GetLast();
2934 if (pAction
->GetUser() != "Kohei Yoshida")
2936 cerr
<< "Wrong user name." << endl
;
2940 DateTime aDT
= pAction
->GetDateTime();
2941 if (aDT
.GetYear() != 2014 || aDT
.GetMonth() != 7 || aDT
.GetDay() != 11)
2943 cerr
<< "Wrong time stamp." << endl
;
2947 // Insert a new record to make sure the user and date-time are correct.
2948 rDoc
.SetString(ScAddress(1,8,0), "New String");
2950 pCT
->AppendContent(ScAddress(1,8,0), aEmpty
);
2951 pAction
= pCT
->GetLast();
2954 cerr
<< "Failed to retrieve last revision." << endl
;
2958 if (rOwnerName
!= pAction
->GetUser())
2960 cerr
<< "Wrong user name." << endl
;
2964 DateTime aDTNew
= pAction
->GetDateTime();
2967 cerr
<< "Time stamp of the new revision should be more recent than that of the last revision." << endl
;
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
);
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
);
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
);
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();
3016 CPPUNIT_ASSERT_MESSAGE("Initial check failed (xlsx).", bGood
);
3018 xDocSh2
= saveAndReload(xDocSh
.get(), FORMAT_XLSX
);
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
);
3030 void ScExportTest::testSheetTabColorsXLSX()
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
;
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
;
3057 static const Color aXclColors
[] =
3059 0x0000B050, // green
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
;
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());
3090 ScDocument
& rDoc
= xDocSh2
->GetDocument();
3091 bool bRes
= aTest
.checkContent(rDoc
);
3092 CPPUNIT_ASSERT_MESSAGE("Failed on the content check after reload.", bRes
);
3097 void ScExportTest::testSharedFormulaExportXLS()
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
;
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
;
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
;
3138 ScFormulaCell
* pFC
= rDoc
.GetFormulaCell(aPos
);
3141 cerr
<< "B" << (i
+2) << " should be a formula cell." << endl
;
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
;
3153 fActual
= rDoc
.GetValue(aPos
);
3154 if (fExpected
!= fActual
)
3156 cerr
<< "Wrong value in B" << (i
+2) << ": expected=" << fExpected
<< ", actual=" << fActual
<< endl
;
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
);
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
);
3189 void ScExportTest::testSharedFormulaExportXLSX()
3193 bool checkContent( const ScDocument
& rDoc
)
3195 SCTAB nTabCount
= rDoc
.GetTableCount();
3198 cerr
<< "Document should have exactly 2 sheets. " << nTabCount
<< " found." << endl
;
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
;
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
;
3226 // C2:C7 should show 10,20,...,60.
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
;
3239 // D2:D7 should show 1,2,...,6.
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
;
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
);
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
);
3284 void ScExportTest::testSharedFormulaStringResultExportXLSX()
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
;
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
;
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.
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
);
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
);
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
);
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
);
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);
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
);
3445 static sal_Unicode
lcl_getWindowsDrive(const OUString
& aURL
)
3447 static const sal_Int32 nMinLen
= strlen("file:///X:/");
3448 if (aURL
.getLength() <= nMinLen
)
3450 const OUString aUrlStart
= aURL
.copy(0, nMinLen
);
3451 return (aUrlStart
.startsWith("file:///") && aUrlStart
.endsWith(":/")) ? aUrlStart
[8] : 0;
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");
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
);
3477 // make sure that the URL is relative
3478 CPPUNIT_ASSERT(aURL
.startsWith(".."));
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
);
3515 void ScExportTest::testFunctionsExcel2010ODS()
3517 //testFunctionsExcel2010(FORMAT_ODS);
3520 void ScExportTest::testSwappedOutImageExport()
3522 const char* aFilterNames
[] = {
3525 "Calc Office Open XML",
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
);
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
);
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
);
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
);
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
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
);
3616 CPPUNIT_ASSERT(xDocSh
.is());
3618 ScDocument
& rDoc
= xDocSh
->GetDocument();
3620 ScAddress
aPos(0,0,0);
3621 ScTokenArray
* pCode
= getTokens(rDoc
, aPos
);
3623 CppUnit::Asserter::fail("empty token array", CPPUNIT_SOURCELINE());
3625 OUString aFormula
= toString(rDoc
, aPos
, *pCode
, rDoc
.GetGrammar());
3627 aFormula
= aFormula
.copy(0, 9) + aFormula
.copy(12); // strip drive letter, e.g. 'C:/'
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"));
3639 void ScExportTest::testLinkedGraphicRT()
3641 // Problem was with linked images
3642 const char* aFilterNames
[] = {
3645 "Calc Office Open XML",
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
);
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());
3677 void ScExportTest::testImageWithSpecialID()
3679 const char* aFilterNames
[] = {
3682 "Calc Office Open XML",
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
);
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
);
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
);
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
);
3743 void ScExportTest::testAbsNamedRangeHTML()
3745 ScDocShellRef xDocSh
= loadDoc("numberformat.", FORMAT_HTML
);
3746 xDocSh
->DoHardRecalc();
3747 ScDocShellRef xDocSh2
= saveAndReload(xDocSh
.get(), FORMAT_ODS
);
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());
3760 void ScExportTest::testSheetLocalRangeNameXLS()
3762 ScDocShellRef xDocSh
= loadDoc("named-ranges-local.", FORMAT_XLS
);
3763 xDocSh
->DoHardRecalc();
3764 ScDocShellRef xDocSh2
= saveAndReload(xDocSh
.get(), FORMAT_XLS
);
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());
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
);
3784 void ScExportTest::testRelativeNamedExpressionsXLS()
3786 ScDocShellRef xDocSh
= loadDoc("tdf113991_relativeNamedRanges.", FORMAT_ODS
);
3787 xDocSh
->DoHardRecalc();
3788 ScDocShellRef xDocSh2
= saveAndReload(xDocSh
.get(), FORMAT_XLS
);
3790 xDocSh2
->DoHardRecalc();
3791 ScDocument
& rDoc
= xDocSh2
->GetDocument();
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);
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);
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);
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);
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);
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
);
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
);
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
);
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);
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
);
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");
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");
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());
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");
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);
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");
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
);
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
);
4055 rDoc
.InsertRow(ScRange( 0, aDataStart
.Row() - 1, 0, MAXCOL
, aDataStart
.Row(), 0));
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
);
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
);
4116 rDoc1
.InsertCol(ScRange( aDataStart
.Col(), 0 , 0 , aDataStart
.Col(), MAXROW
, 0 ));
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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());
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
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
);
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");
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)");
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);
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");
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;@");
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
);
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",
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");
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");
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)))");
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();
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();
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
);
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
);
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");
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");
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]\\-# #/#####");
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");
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
);
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
);
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");
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
);
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;
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
);
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
);
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());
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);
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);
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");
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");
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]]",
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");
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());
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");
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());
4908 std::shared_ptr
<utl::TempFile
> pTemp
= saveAs(xDocSh
.get(), FORMAT_XLSX
);
4910 ScDocument
& rDoc
= xDocSh
->GetDocument();
4911 CPPUNIT_ASSERT(rDoc
.HasPivotTable());
4914 ScDPCollection
* pDPColl
= rDoc
.GetDPCollection();
4915 CPPUNIT_ASSERT(pDPColl
);
4916 CPPUNIT_ASSERT_EQUAL(size_t(2), pDPColl
->GetCount());
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
);
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");
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");
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");
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
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
);
5002 std::shared_ptr
<utl::TempFile
> pXPathFile
5003 = ScBootstrapFixture::exportTo(&(*pShell2
), FORMAT_XLSX
);
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());
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);
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");
5036 comphelper::ScopeGuard
g([&aOptions
, &sLocaleConfigString
] {
5037 aOptions
.SetLocaleConfigString(sLocaleConfigString
);
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());
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);
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");
5063 comphelper::ScopeGuard
g([&aOptions
, &sLocaleConfigString
] {
5064 aOptions
.SetLocaleConfigString(sLocaleConfigString
);
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());
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");
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");
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");
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");
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");
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");
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");
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");
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(
5237 "/office:document-content/office:body/office:spreadsheet/"
5238 "table:table/table:shapes/draw:frame",
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"));
5251 void ScExportTest::testTdf128976()
5253 ScDocShellRef xShell
= loadDoc("tdf128976.", FORMAT_XLS
);
5254 CPPUNIT_ASSERT(xShell
.is());
5256 ScDocShellRef xDocSh
= saveAndReload(xShell
.get(), FORMAT_XLS
);
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
);
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
);
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");
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");
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");
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()");
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");
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");
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");
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");
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
);
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");
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",
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");
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);
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();
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));
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
);
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
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");
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"));
5800 void ScExportTest::testTdf84874()
5802 ScDocShellRef xShell
= loadDoc("tdf84874.", FORMAT_ODS
);
5803 CPPUNIT_ASSERT(xShell
.is());
5805 ScDocShellRef xDocSh
= saveAndReload(xShell
.get(), FORMAT_XLSX
);
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
);
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"));
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
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());
5960 CPPUNIT_TEST_SUITE_REGISTRATION(ScExportTest
);
5962 CPPUNIT_PLUGIN_IMPLEMENT();
5964 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */