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 <config_fonts.h>
13 #include "helper/debughelper.hxx"
15 #include "helper/qahelper.hxx"
16 #include "helper/shared_test_impl.hxx"
18 #include <userdat.hxx>
19 #include <docpool.hxx>
20 #include <scitems.hxx>
22 #include <stlpool.hxx>
23 #include <editutil.hxx>
24 #include <scopetools.hxx>
26 #include <tokenstringcontext.hxx>
27 #include <chgtrack.hxx>
28 #include <validat.hxx>
31 #include <svx/svdpage.hxx>
32 #include <svx/svdograf.hxx>
33 #include <tabprotection.hxx>
34 #include <editeng/wghtitem.hxx>
35 #include <editeng/postitem.hxx>
36 #include <editeng/eeitem.hxx>
37 #include <editeng/section.hxx>
38 #include <editeng/crossedoutitem.hxx>
39 #include <editeng/borderline.hxx>
40 #include <editeng/escapementitem.hxx>
41 #include <editeng/fontitem.hxx>
42 #include <editeng/fhgtitem.hxx>
43 #include <editeng/udlnitem.hxx>
44 #include <editeng/colritem.hxx>
45 #include <unotools/tempfile.hxx>
46 #include <unotools/useroptions.hxx>
47 #include <tools/datetime.hxx>
49 #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
50 #include <com/sun/star/awt/XBitmap.hpp>
51 #include <com/sun/star/graphic/GraphicType.hpp>
53 using namespace ::com::sun::star
;
54 using namespace ::com::sun::star::uno
;
56 class ScExportTest
: public ScModelTestBase
59 virtual void registerNamespaces(xmlXPathContextPtr
& pXmlXPathCtx
) override
;
63 : ScModelTestBase("sc/qa/unit/data")
68 void testDefaultFontHeight();
72 void testExtCondFormatXLSX();
75 void testPasswordExport();
77 void testConditionalFormatExportODS();
78 void testConditionalFormatExportXLSX();
79 void testCondFormatExportCellIs();
80 void testTdf99856_dataValidationTest();
81 void testProtectionKeyODS_UTF16LErtlSHA1();
82 void testProtectionKeyODS_UTF8SHA1();
83 void testProtectionKeyODS_UTF8SHA256ODF12();
84 void testProtectionKeyODS_UTF8SHA256W3C();
85 void testProtectionKeyODS_XL_SHA1();
86 void testColorScaleExportODS();
87 void testColorScaleExportXLSX();
88 void testDataBarExportODS();
89 void testDataBarExportXLSX();
90 void testConditionalFormatRangeListXLSX();
91 void testConditionalFormatContainsTextXLSX();
92 void testConditionalFormatPriorityCheckXLSX();
93 void testConditionalFormatOriginXLSX();
95 void testLegacyCellAnchoredRotatedShape();
96 void testMiscRowHeightExport();
97 void testNamedRangeBugfdo62729();
98 void testBuiltinRangesXLSX();
99 void testRichTextExportODS();
100 void testRichTextCellFormatXLSX();
101 void testFormulaRefSheetNameODS();
103 void testCellValuesExportODS();
104 void testCellNoteExportODS();
105 void testCellNoteExportXLS();
106 void testFormatExportODS();
108 void testCommentExportXLSX();
109 void testCommentExportXLSX_2_XLSX();
111 void testCustomColumnWidthExportXLSX();
113 void testXfDefaultValuesXLSX();
115 void testColumnWidthResaveXLSX();
117 void testColumnWidthExportFromODStoXLSX();
119 void testOutlineExportXLSX();
120 void testHiddenEmptyRowsXLSX();
121 void testHiddenEmptyColsODS();
122 void testAllRowsHiddenXLSX();
123 void testLandscapeOrientationXLSX();
125 void testInlineArrayXLS();
126 void testEmbeddedChartODS();
127 void testEmbeddedChartXLS();
128 void testCellAnchoredGroupXLS();
130 void testFormulaReferenceXLS();
131 void testSheetProtectionXLSX();
132 void testSheetProtectionXLSB();
134 void testCellBordersXLS();
135 void testCellBordersXLSX();
136 void testBordersExchangeXLSX();
137 void testTrackChangesSimpleXLSX();
138 void testSheetTabColorsXLSX();
140 void testTdf133487();
142 void testSharedFormulaExportXLS();
143 void testSharedFormulaExportXLSX();
144 void testSharedFormulaStringResultExportXLSX();
146 void testFunctionsExcel2010(const OUString
& sFormatType
);
147 void testFunctionsExcel2010XLSX();
148 void testFunctionsExcel2010XLS();
149 void testFunctionsExcel2010ODS();
151 void testCeilingFloor(const OUString
& sFormatType
);
152 void testCeilingFloorXLSX();
153 void testCeilingFloorODSToXLSX();
154 void testCeilingFloorXLS();
155 void testCeilingFloorODS();
157 void testCustomXml();
159 void testRelativePathsODS();
160 void testSheetProtectionODS();
162 void testSwappedOutImageExport();
163 void testLinkedGraphicRT();
164 void testImageWithSpecialID();
166 void testSupBookVirtualPathXLS();
167 void testAbsNamedRangeHTML();
169 void testSheetLocalRangeNameXLS();
170 void testRelativeNamedExpressionsXLS();
171 void testSheetTextBoxHyperlinkXLSX();
172 void testFontSizeXLSX();
173 void testSheetCharacterKerningSpaceXLSX();
174 void testSheetCondensedCharacterSpaceXLSX();
175 void testTextUnderlineColorXLSX();
176 void testSheetRunParagraphPropertyXLSX();
177 void testHiddenShapeXLS();
178 void testHiddenShapeXLSX();
179 void testShapeAutofitXLSX();
180 void testHyperlinkXLSX();
181 void testMoveCellAnchoredShapesODS();
182 void testPreserveTextWhitespaceXLSX();
183 void testPreserveTextWhitespace2XLSX();
184 void testTdf113646();
185 void testDateStandardfilterXLSX();
187 CPPUNIT_TEST_SUITE(ScExportTest
);
189 CPPUNIT_TEST(testDefaultFontHeight
);
190 CPPUNIT_TEST(testTdf139167
);
191 CPPUNIT_TEST(testTdf113271
);
192 CPPUNIT_TEST(testTdf139394
);
193 CPPUNIT_TEST(testExtCondFormatXLSX
);
194 CPPUNIT_TEST(testTdf90104
);
195 CPPUNIT_TEST(testTdf111876
);
196 CPPUNIT_TEST(testPasswordExport
);
197 CPPUNIT_TEST(testTdf134332
);
198 CPPUNIT_TEST(testConditionalFormatExportODS
);
199 CPPUNIT_TEST(testCondFormatExportCellIs
);
200 CPPUNIT_TEST(testConditionalFormatExportXLSX
);
201 CPPUNIT_TEST(testTdf99856_dataValidationTest
);
202 CPPUNIT_TEST(testProtectionKeyODS_UTF16LErtlSHA1
);
203 CPPUNIT_TEST(testProtectionKeyODS_UTF8SHA1
);
204 CPPUNIT_TEST(testProtectionKeyODS_UTF8SHA256ODF12
);
205 CPPUNIT_TEST(testProtectionKeyODS_UTF8SHA256W3C
);
206 CPPUNIT_TEST(testProtectionKeyODS_XL_SHA1
);
207 CPPUNIT_TEST(testColorScaleExportODS
);
208 CPPUNIT_TEST(testColorScaleExportXLSX
);
209 CPPUNIT_TEST(testDataBarExportODS
);
210 CPPUNIT_TEST(testDataBarExportXLSX
);
211 CPPUNIT_TEST(testConditionalFormatRangeListXLSX
);
212 CPPUNIT_TEST(testConditionalFormatContainsTextXLSX
);
213 CPPUNIT_TEST(testConditionalFormatPriorityCheckXLSX
);
214 CPPUNIT_TEST(testConditionalFormatOriginXLSX
);
215 CPPUNIT_TEST(testTdf79998
);
216 CPPUNIT_TEST(testLegacyCellAnchoredRotatedShape
);
217 CPPUNIT_TEST(testMiscRowHeightExport
);
218 CPPUNIT_TEST(testNamedRangeBugfdo62729
);
219 CPPUNIT_TEST(testBuiltinRangesXLSX
);
220 CPPUNIT_TEST(testRichTextExportODS
);
221 CPPUNIT_TEST(testRichTextCellFormatXLSX
);
222 CPPUNIT_TEST(testFormulaRefSheetNameODS
);
223 CPPUNIT_TEST(testCellValuesExportODS
);
224 CPPUNIT_TEST(testCellNoteExportODS
);
225 CPPUNIT_TEST(testCellNoteExportXLS
);
226 CPPUNIT_TEST(testFormatExportODS
);
227 CPPUNIT_TEST(testCommentExportXLSX
);
228 CPPUNIT_TEST(testCommentExportXLSX_2_XLSX
);
230 CPPUNIT_TEST(testCustomColumnWidthExportXLSX
);
232 CPPUNIT_TEST(testXfDefaultValuesXLSX
);
233 CPPUNIT_TEST(testODF13
);
234 CPPUNIT_TEST(testColumnWidthResaveXLSX
);
236 CPPUNIT_TEST(testColumnWidthExportFromODStoXLSX
);
238 CPPUNIT_TEST(testOutlineExportXLSX
);
239 CPPUNIT_TEST(testHiddenEmptyRowsXLSX
);
240 CPPUNIT_TEST(testHiddenEmptyColsODS
);
241 CPPUNIT_TEST(testAllRowsHiddenXLSX
);
242 CPPUNIT_TEST(testLandscapeOrientationXLSX
);
243 CPPUNIT_TEST(testInlineArrayXLS
);
244 CPPUNIT_TEST(testEmbeddedChartODS
);
245 CPPUNIT_TEST(testEmbeddedChartXLS
);
246 CPPUNIT_TEST(testCellAnchoredGroupXLS
);
248 CPPUNIT_TEST(testFormulaReferenceXLS
);
249 CPPUNIT_TEST(testSheetProtectionXLSX
);
250 CPPUNIT_TEST(testSheetProtectionXLSB
);
251 CPPUNIT_TEST(testCellBordersXLS
);
252 CPPUNIT_TEST(testCellBordersXLSX
);
253 CPPUNIT_TEST(testBordersExchangeXLSX
);
254 CPPUNIT_TEST(testTrackChangesSimpleXLSX
);
255 CPPUNIT_TEST(testSheetTabColorsXLSX
);
256 CPPUNIT_TEST(testTdf133487
);
257 CPPUNIT_TEST(testSharedFormulaExportXLS
);
258 CPPUNIT_TEST(testSharedFormulaExportXLSX
);
259 CPPUNIT_TEST(testSharedFormulaStringResultExportXLSX
);
260 CPPUNIT_TEST(testFunctionsExcel2010XLSX
);
261 CPPUNIT_TEST(testFunctionsExcel2010XLS
);
262 CPPUNIT_TEST(testFunctionsExcel2010ODS
);
263 CPPUNIT_TEST(testCeilingFloorXLSX
);
264 CPPUNIT_TEST(testCeilingFloorODSToXLSX
);
265 CPPUNIT_TEST(testCeilingFloorXLS
);
266 CPPUNIT_TEST(testCeilingFloorODS
);
267 CPPUNIT_TEST(testCustomXml
);
268 CPPUNIT_TEST(testRelativePathsODS
);
269 CPPUNIT_TEST(testSheetProtectionODS
);
270 CPPUNIT_TEST(testSupBookVirtualPathXLS
);
271 CPPUNIT_TEST(testSwappedOutImageExport
);
272 CPPUNIT_TEST(testLinkedGraphicRT
);
273 CPPUNIT_TEST(testImageWithSpecialID
);
274 CPPUNIT_TEST(testPreserveTextWhitespaceXLSX
);
275 CPPUNIT_TEST(testPreserveTextWhitespace2XLSX
);
276 CPPUNIT_TEST(testAbsNamedRangeHTML
);
277 CPPUNIT_TEST(testTdf80149
);
278 CPPUNIT_TEST(testSheetLocalRangeNameXLS
);
279 CPPUNIT_TEST(testRelativeNamedExpressionsXLS
);
280 CPPUNIT_TEST(testSheetTextBoxHyperlinkXLSX
);
281 CPPUNIT_TEST(testFontSizeXLSX
);
282 CPPUNIT_TEST(testSheetCharacterKerningSpaceXLSX
);
283 CPPUNIT_TEST(testSheetCondensedCharacterSpaceXLSX
);
284 CPPUNIT_TEST(testTextUnderlineColorXLSX
);
285 CPPUNIT_TEST(testSheetRunParagraphPropertyXLSX
);
286 CPPUNIT_TEST(testHiddenShapeXLS
);
287 CPPUNIT_TEST(testHiddenShapeXLSX
);
288 CPPUNIT_TEST(testShapeAutofitXLSX
);
289 CPPUNIT_TEST(testHyperlinkXLSX
);
290 CPPUNIT_TEST(testMoveCellAnchoredShapesODS
);
291 CPPUNIT_TEST(testTdf113646
);
292 CPPUNIT_TEST(testDateStandardfilterXLSX
);
293 CPPUNIT_TEST_SUITE_END();
296 void testExcelCellBorders(const OUString
& sFormatType
);
299 void ScExportTest::registerNamespaces(xmlXPathContextPtr
& pXmlXPathCtx
)
301 XmlTestTools::registerOOXMLNamespaces(pXmlXPathCtx
);
302 XmlTestTools::registerODFNamespaces(pXmlXPathCtx
);
305 void ScExportTest::test()
309 ScDocument
* pDoc
= getScDoc();
311 pDoc
->SetValue(0, 0, 0, 1.0);
313 saveAndReload("calc8");
316 double aVal
= pDoc
->GetValue(0, 0, 0);
317 ASSERT_DOUBLES_EQUAL(aVal
, 1.0);
320 void ScExportTest::testDefaultFontHeight()
324 ScDocument
* pDoc
= getScDoc();
325 ScDocumentPool
* pPool
= pDoc
->GetPool();
326 pPool
->SetPoolDefaultItem(SvxFontHeightItem(400, 100, ATTR_FONT_HEIGHT
));
327 pPool
->SetPoolDefaultItem(SvxFontHeightItem(400, 100, ATTR_CJK_FONT_HEIGHT
));
328 pPool
->SetPoolDefaultItem(SvxFontHeightItem(400, 100, ATTR_CTL_FONT_HEIGHT
));
330 saveAndReload("calc8");
333 pPool
= pDoc
->GetPool();
334 const SvxFontHeightItem
& rItem
= pPool
->GetDefaultItem(ATTR_FONT_HEIGHT
);
335 CPPUNIT_ASSERT_EQUAL(sal_uInt32(400), rItem
.GetHeight());
336 const SvxFontHeightItem
& rCJKItem
= pPool
->GetDefaultItem(ATTR_CJK_FONT_HEIGHT
);
337 CPPUNIT_ASSERT_EQUAL(sal_uInt32(400), rCJKItem
.GetHeight());
338 const SvxFontHeightItem
& rCTLItem
= pPool
->GetDefaultItem(ATTR_CTL_FONT_HEIGHT
);
339 CPPUNIT_ASSERT_EQUAL(sal_uInt32(400), rCTLItem
.GetHeight());
342 void ScExportTest::testTdf139167()
344 createScDoc("xlsx/tdf139167.xlsx");
346 save("Calc Office Open XML");
347 xmlDocUniquePtr pDoc
= parseExport("xl/styles.xml");
348 CPPUNIT_ASSERT(pDoc
);
350 assertXPath(pDoc
, "/x:styleSheet/x:cellStyles", "count", "6");
351 assertXPath(pDoc
, "/x:styleSheet/x:dxfs/x:dxf/x:fill/x:patternFill/x:bgColor", "rgb",
355 void ScExportTest::testTdf113271()
357 createScDoc("xlsx/tdf113271.xlsx");
359 save("Calc Office Open XML");
360 xmlDocUniquePtr pDoc
= parseExport("xl/styles.xml");
361 CPPUNIT_ASSERT(pDoc
);
363 assertXPath(pDoc
, "/x:styleSheet/x:fonts", "count", "6");
365 // Without the fix in place, this test would have failed with
366 // - Expected: FF000000
367 // - Actual : FFFFFFFF
368 assertXPath(pDoc
, "/x:styleSheet/x:fonts/x:font[1]/x:color", "rgb", "FF000000");
369 assertXPath(pDoc
, "/x:styleSheet/x:fonts/x:font[1]/x:name", "val", "Calibri");
372 void ScExportTest::testTdf139394()
374 createScDoc("xlsx/tdf139394.xlsx");
376 save("Calc Office Open XML");
377 xmlDocUniquePtr pDoc
= parseExport("xl/worksheets/sheet1.xml");
378 CPPUNIT_ASSERT(pDoc
);
382 "/x:worksheet/x:extLst/x:ext/x14:conditionalFormattings/x14:conditionalFormatting[1]/"
384 "LEFT(A1,LEN(\"+\"))=\"+\"");
387 "/x:worksheet/x:extLst/x:ext/x14:conditionalFormattings/x14:conditionalFormatting[2]/"
389 "RIGHT(A2,LEN(\"-\"))=\"-\"");
392 "/x:worksheet/x:extLst/x:ext/x14:conditionalFormattings/x14:conditionalFormatting[3]/"
394 "LEFT(A3,LEN($B$3))=$B$3");
397 void ScExportTest::testExtCondFormatXLSX()
399 createScDoc("xlsx/tdf139021.xlsx");
401 save("Calc Office Open XML");
402 xmlDocUniquePtr pDoc
= parseExport("xl/worksheets/sheet1.xml");
403 CPPUNIT_ASSERT(pDoc
);
407 "/x:worksheet/x:extLst/x:ext/x14:conditionalFormattings/x14:conditionalFormatting[1]/"
409 "type", "containsText");
412 "/x:worksheet/x:extLst/x:ext/x14:conditionalFormattings/x14:conditionalFormatting[1]/"
413 "x14:cfRule/xm:f[1]",
414 "NOT(ISERROR(SEARCH($B$1,A1)))");
417 "/x:worksheet/x:extLst/x:ext/x14:conditionalFormattings/x14:conditionalFormatting[1]/"
418 "x14:cfRule/xm:f[2]",
422 "/x:worksheet/x:extLst/x:ext/x14:conditionalFormattings/x14:conditionalFormatting[2]/"
424 "type", "notContainsText");
427 "/x:worksheet/x:extLst/x:ext/x14:conditionalFormattings/x14:conditionalFormatting[2]/"
428 "x14:cfRule/xm:f[1]",
429 "ISERROR(SEARCH($B$2,A2))");
432 "/x:worksheet/x:extLst/x:ext/x14:conditionalFormattings/x14:conditionalFormatting[2]/"
433 "x14:cfRule/xm:f[2]",
437 void ScExportTest::testTdf90104()
439 createScDoc("xlsx/tdf90104.xlsx");
441 save("Calc Office Open XML");
443 xmlDocUniquePtr pDoc
= parseExport("xl/worksheets/sheet1.xml");
444 CPPUNIT_ASSERT(pDoc
);
446 assertXPathContent(pDoc
,
447 "/x:worksheet/x:dataValidations/x:dataValidation/mc:AlternateContent"
448 "/mc:Choice/x12ac:list",
449 "1,\"2,3\",4,\"5,6\"");
450 assertXPathContent(pDoc
,
451 "/x:worksheet/x:dataValidations/x:dataValidation/mc:AlternateContent"
452 "/mc:Fallback/x:formula1",
456 void ScExportTest::testTdf111876()
458 // Document with relative path hyperlink
460 createScDoc("xlsx/tdf111876.xlsx");
462 save("Calc Office Open XML");
463 xmlDocUniquePtr pDoc
= parseExport("xl/worksheets/_rels/sheet1.xml.rels");
464 CPPUNIT_ASSERT(pDoc
);
465 OUString sTarget
= getXPath(pDoc
, "/rels:Relationships/rels:Relationship", "Target");
467 // Document is saved to the temporary directory, relative path should be different than original one
468 CPPUNIT_ASSERT(sTarget
!= "../xls/bug-fixes.xls");
471 void ScExportTest::testPasswordExport()
473 std::vector
<OUString
> aFilterNames
{ "calc8", "MS Excel 97", "Calc Office Open XML" };
475 for (size_t i
= 0; i
< aFilterNames
.size(); ++i
)
479 ScDocument
* pDoc
= getScDoc();
481 pDoc
->SetValue(0, 0, 0, 1.0);
483 saveAndReload(aFilterNames
[i
], /*pPassword*/ "test");
486 double aVal
= pDoc
->GetValue(0, 0, 0);
487 ASSERT_DOUBLES_EQUAL(aVal
, 1.0);
491 void ScExportTest::testTdf134332()
493 createScDoc("ods/tdf134332.ods");
495 ScDocument
* pDoc
= getScDoc();
497 ASSERT_DOUBLES_EQUAL(190.0, pDoc
->GetValue(ScAddress(0, 0, 0)));
499 ASSERT_DOUBLES_EQUAL(238.0, pDoc
->GetValue(ScAddress(0, 10144, 0)));
501 saveAndReload("calc8", /*pPassword*/ "test");
503 // Without the fixes in place, it would have failed here
505 ASSERT_DOUBLES_EQUAL(190.0, pDoc
->GetValue(ScAddress(0, 0, 0)));
507 ASSERT_DOUBLES_EQUAL(238.0, pDoc
->GetValue(ScAddress(0, 10144, 0)));
510 void ScExportTest::testConditionalFormatExportODS()
512 createScDoc("ods/new_cond_format_test_export.ods");
514 saveAndReload("calc8");
515 ScDocument
* pDoc
= getScDoc();
516 OUString aCSVPath
= createFilePath(u
"contentCSV/new_cond_format_test_export.csv");
517 testCondFile(aCSVPath
, &*pDoc
, 0);
520 void ScExportTest::testCondFormatExportCellIs()
522 createScDoc("xlsx/condFormat_cellis.xlsx");
523 saveAndReload("Calc Office Open XML");
525 ScDocument
* pDoc
= getScDoc();
526 CPPUNIT_ASSERT_EQUAL(size_t(1), pDoc
->GetCondFormList(0)->size());
528 ScConditionalFormat
* pFormat
= pDoc
->GetCondFormat(0, 0, 0);
529 CPPUNIT_ASSERT(pFormat
);
531 const ScFormatEntry
* pEntry
= pFormat
->GetEntry(0);
532 CPPUNIT_ASSERT(pEntry
);
533 CPPUNIT_ASSERT_EQUAL(ScFormatEntry::Type::ExtCondition
, pEntry
->GetType());
535 const ScCondFormatEntry
* pCondition
= static_cast<const ScCondFormatEntry
*>(pEntry
);
536 CPPUNIT_ASSERT_EQUAL(ScConditionMode::Equal
, pCondition
->GetOperation());
538 OUString aStr
= pCondition
->GetExpression(ScAddress(0, 0, 0), 0);
539 CPPUNIT_ASSERT_EQUAL(OUString("$Sheet2.$A$2"), aStr
);
541 pEntry
= pFormat
->GetEntry(1);
542 CPPUNIT_ASSERT(pEntry
);
543 CPPUNIT_ASSERT_EQUAL(ScFormatEntry::Type::ExtCondition
, pEntry
->GetType());
545 pCondition
= static_cast<const ScCondFormatEntry
*>(pEntry
);
546 CPPUNIT_ASSERT_EQUAL(ScConditionMode::Equal
, pCondition
->GetOperation());
548 aStr
= pCondition
->GetExpression(ScAddress(0, 0, 0), 0);
549 CPPUNIT_ASSERT_EQUAL(OUString("$Sheet2.$A$1"), aStr
);
552 void ScExportTest::testConditionalFormatExportXLSX()
554 createScDoc("xlsx/new_cond_format_test_export.xlsx");
556 saveAndReload("Calc Office Open XML");
557 ScDocument
* pDoc
= getScDoc();
559 OUString aCSVPath
= createFilePath(u
"contentCSV/new_cond_format_test_export.csv");
560 testCondFile(aCSVPath
, &*pDoc
, 0);
563 OUString aCSVPath
= createFilePath(u
"contentCSV/new_cond_format_test_sheet2.csv");
564 testCondFile(aCSVPath
, &*pDoc
, 1);
568 void ScExportTest::testTdf99856_dataValidationTest()
570 createScDoc("ods/tdf99856_dataValidationTest.ods");
572 saveAndReload("Calc Office Open XML");
574 ScDocument
* pDoc
= getScDoc();
575 const ScValidationData
* pData
= pDoc
->GetValidationEntry(2);
576 CPPUNIT_ASSERT(pData
);
578 // Excel can't open corrupt file if the list is longer than 255 characters
579 std::vector
<ScTypedStrData
> aList
;
580 pData
->FillSelectionList(aList
, ScAddress(0, 1, 1));
581 CPPUNIT_ASSERT_EQUAL(size_t(18), aList
.size());
582 CPPUNIT_ASSERT_EQUAL(OUString("18 Missis"), aList
[17].GetString());
585 void ScExportTest::testProtectionKeyODS_UTF16LErtlSHA1()
587 OUString
const password("1012345678901234567890123456789012345678901234567890");
589 createScDoc("fods/protection-key1.fods");
591 ScDocument
* pDoc
= getScDoc();
592 ScDocProtection
* const pDocProt(pDoc
->GetDocProtection());
593 CPPUNIT_ASSERT(pDocProt
->verifyPassword(password
));
594 const ScTableProtection
* const pTabProt(pDoc
->GetTabProtection(0));
595 CPPUNIT_ASSERT(pTabProt
->verifyPassword(password
));
597 // we can't assume that the user entered the password; check that we
598 // round-trip the password as-is
600 xmlDocUniquePtr pXmlDoc
= parseExport("content.xml");
602 "//office:spreadsheet[@table:structure-protected='true' and "
603 "@table:protection-key='vbnhxyBKtPHCA1wB21zG1Oha8ZA=' and "
604 "@table:protection-key-digest-algorithm='http://www.w3.org/2000/09/xmldsig#sha1']");
606 "//table:table[@table:protected='true' and "
607 "@table:protection-key='vbnhxyBKtPHCA1wB21zG1Oha8ZA=' and "
608 "@table:protection-key-digest-algorithm='http://www.w3.org/2000/09/xmldsig#sha1']");
611 void ScExportTest::testProtectionKeyODS_UTF8SHA1()
613 OUString
const password("1012345678901234567890123456789012345678901234567890");
615 createScDoc("fods/protection-key2.fods");
617 ScDocument
* pDoc
= getScDoc();
618 ScDocProtection
* const pDocProt(pDoc
->GetDocProtection());
619 CPPUNIT_ASSERT(pDocProt
->verifyPassword(password
));
620 const ScTableProtection
* const pTabProt(pDoc
->GetTabProtection(0));
621 CPPUNIT_ASSERT(pTabProt
->verifyPassword(password
));
623 // we can't assume that the user entered the password; check that we
624 // round-trip the password as-is
626 xmlDocUniquePtr pXmlDoc
= parseExport("content.xml");
628 "//office:spreadsheet[@table:structure-protected='true' and "
629 "@table:protection-key='nLHas0RIwepGDaH4c2hpyIUvIS8=' and "
630 "@table:protection-key-digest-algorithm='http://www.w3.org/2000/09/xmldsig#sha1']");
632 "//table:table[@table:protected='true' and "
633 "@table:protection-key='nLHas0RIwepGDaH4c2hpyIUvIS8=' and "
634 "@table:protection-key-digest-algorithm='http://www.w3.org/2000/09/xmldsig#sha1']");
637 void ScExportTest::testProtectionKeyODS_UTF8SHA256ODF12()
639 OUString
const password("1012345678901234567890123456789012345678901234567890");
641 createScDoc("fods/protection-key3.fods");
643 ScDocument
* pDoc
= getScDoc();
644 ScDocProtection
* const pDocProt(pDoc
->GetDocProtection());
645 CPPUNIT_ASSERT(pDocProt
->verifyPassword(password
));
646 const ScTableProtection
* const pTabProt(pDoc
->GetTabProtection(0));
647 CPPUNIT_ASSERT(pTabProt
->verifyPassword(password
));
649 // we can't assume that the user entered the password; check that we
650 // round-trip the password as-is
652 xmlDocUniquePtr pXmlDoc
= parseExport("content.xml");
655 "//office:spreadsheet[@table:structure-protected='true' and "
656 "@table:protection-key='1tnJohagR2T0yF/v69hLPuumSTsj32CumW97nkKGuSQ=' and "
657 "@table:protection-key-digest-algorithm='http://www.w3.org/2000/09/xmldsig#sha256']");
660 "//table:table[@table:protected='true' and "
661 "@table:protection-key='1tnJohagR2T0yF/v69hLPuumSTsj32CumW97nkKGuSQ=' and "
662 "@table:protection-key-digest-algorithm='http://www.w3.org/2000/09/xmldsig#sha256']");
665 void ScExportTest::testProtectionKeyODS_UTF8SHA256W3C()
667 OUString
const password("1012345678901234567890123456789012345678901234567890");
669 createScDoc("fods/protection-key4.fods");
671 ScDocument
* pDoc
= getScDoc();
672 ScDocProtection
* const pDocProt(pDoc
->GetDocProtection());
673 CPPUNIT_ASSERT(pDocProt
->verifyPassword(password
));
674 const ScTableProtection
* const pTabProt(pDoc
->GetTabProtection(0));
675 CPPUNIT_ASSERT(pTabProt
->verifyPassword(password
));
677 // we can't assume that the user entered the password; check that we
678 // round-trip the password as-is
680 xmlDocUniquePtr pXmlDoc
= parseExport("content.xml");
683 "//office:spreadsheet[@table:structure-protected='true' and "
684 "@table:protection-key='1tnJohagR2T0yF/v69hLPuumSTsj32CumW97nkKGuSQ=' and "
685 "@table:protection-key-digest-algorithm='http://www.w3.org/2000/09/xmldsig#sha256']");
688 "//table:table[@table:protected='true' and "
689 "@table:protection-key='1tnJohagR2T0yF/v69hLPuumSTsj32CumW97nkKGuSQ=' and "
690 "@table:protection-key-digest-algorithm='http://www.w3.org/2000/09/xmldsig#sha256']");
693 void ScExportTest::testProtectionKeyODS_XL_SHA1()
695 OUString
const password("1012345678901234567890123456789012345678901234567890");
697 createScDoc("fods/protection-key5.fods");
699 ScDocument
* pDoc
= getScDoc();
700 ScDocProtection
* const pDocProt(pDoc
->GetDocProtection());
701 CPPUNIT_ASSERT(pDocProt
->verifyPassword(password
));
702 const ScTableProtection
* const pTabProt(pDoc
->GetTabProtection(0));
703 CPPUNIT_ASSERT(pTabProt
->verifyPassword(password
));
705 // we can't assume that the user entered the password; check that we
706 // round-trip the password as-is
708 xmlDocUniquePtr pXmlDoc
= parseExport("content.xml");
711 "//office:spreadsheet[@table:structure-protected='true' and "
712 "@table:protection-key='OX3WkEe79fv1PE+FUmfOLdwVoqI=' and "
713 "@table:protection-key-digest-algorithm='http://docs.oasis-open.org/office/ns/table/"
714 "legacy-hash-excel' and "
715 "@loext:protection-key-digest-algorithm-2='http://www.w3.org/2000/09/xmldsig#sha1']");
718 "//table:table[@table:protected='true' and "
719 "@table:protection-key='OX3WkEe79fv1PE+FUmfOLdwVoqI=' and "
720 "@table:protection-key-digest-algorithm='http://docs.oasis-open.org/office/ns/table/"
721 "legacy-hash-excel' and "
722 "@loext:protection-key-digest-algorithm-2='http://www.w3.org/2000/09/xmldsig#sha1']");
725 void ScExportTest::testColorScaleExportODS()
727 createScDoc("ods/colorscale.ods");
729 saveAndReload("calc8");
731 ScDocument
* pDoc
= getScDoc();
733 testColorScale2Entry_Impl(*pDoc
);
734 testColorScale3Entry_Impl(*pDoc
);
737 void ScExportTest::testColorScaleExportXLSX()
739 createScDoc("xlsx/colorscale.xlsx");
741 saveAndReload("Calc Office Open XML");
743 ScDocument
* pDoc
= getScDoc();
745 testColorScale2Entry_Impl(*pDoc
);
746 testColorScale3Entry_Impl(*pDoc
);
749 void ScExportTest::testDataBarExportODS()
751 createScDoc("ods/databar.ods");
753 saveAndReload("calc8");
755 ScDocument
* pDoc
= getScDoc();
757 testDataBar_Impl(*pDoc
);
760 void ScExportTest::testFormatExportODS()
762 createScDoc("ods/formats.ods");
764 saveAndReload("calc8");
766 ScDocument
* pDoc
= getScDoc();
768 testFormats(pDoc
, u
"calc8");
771 void ScExportTest::testCommentExportXLSX()
773 //tdf#104729 FILESAVE OpenOffice do not save author of the comment during export to .xlsx
774 createScDoc("ods/comment.ods");
776 save("Calc Office Open XML");
777 xmlDocUniquePtr pComments
= parseExport("xl/comments1.xml");
778 CPPUNIT_ASSERT(pComments
);
780 assertXPathContent(pComments
, "/x:comments/x:authors/x:author[1]", "BAKO");
781 assertXPath(pComments
, "/x:comments/x:authors/x:author", 1);
783 assertXPathContent(pComments
, "/x:comments/x:commentList/x:comment/x:text/x:r/x:t",
786 xmlDocUniquePtr pVmlDrawing
= parseExport("xl/drawings/vmlDrawing1.vml");
787 CPPUNIT_ASSERT(pVmlDrawing
);
789 //assertXPath(pVmlDrawing, "/xml/v:shapetype", "coordsize", "21600,21600");
790 assertXPath(pVmlDrawing
, "/xml/v:shapetype", "spt", "202");
791 assertXPath(pVmlDrawing
, "/xml/v:shapetype/v:stroke", "joinstyle", "miter");
792 const OUString sShapeTypeId
= "#" + getXPath(pVmlDrawing
, "/xml/v:shapetype", "id");
794 assertXPath(pVmlDrawing
, "/xml/v:shape", "type", sShapeTypeId
);
795 assertXPath(pVmlDrawing
, "/xml/v:shape/v:shadow", "color", "black");
796 assertXPath(pVmlDrawing
, "/xml/v:shape/v:shadow", "obscured", "t");
798 //tdf#117274 fix MSO interoperability with the secret VML shape type id
799 assertXPath(pVmlDrawing
, "/xml/v:shapetype", "id", "_x0000_t202");
800 assertXPath(pVmlDrawing
, "/xml/v:shape", "type", "#_x0000_t202");
803 void ScExportTest::testCommentExportXLSX_2_XLSX()
805 //tdf#117287 FILESAVE XLSX: Comments always disappear after opening the exported XLSX file with Excel
806 createScDoc("xlsx/tdf117287_comment.xlsx");
808 ScDocument
* pDoc
= getScDoc();
809 ScAddress
aPosC9(2, 8, 0);
810 ScPostIt
* pNote
= pDoc
->GetNote(aPosC9
);
812 CPPUNIT_ASSERT(pNote
);
813 CPPUNIT_ASSERT(!pNote
->IsCaptionShown());
815 pNote
->ShowCaption(aPosC9
, true);
817 save("Calc Office Open XML");
818 xmlDocUniquePtr pComments
= parseExport("xl/comments1.xml");
819 CPPUNIT_ASSERT(pComments
);
821 assertXPathContent(pComments
, "/x:comments/x:commentList/x:comment/x:text/x:r/x:t",
824 xmlDocUniquePtr pVmlDrawing
= parseExport("xl/drawings/vmlDrawing1.vml");
825 CPPUNIT_ASSERT(pVmlDrawing
);
827 assertXPath(pVmlDrawing
, "/xml/v:shape/x:ClientData/x:Visible", 0);
831 void ScExportTest::testCustomColumnWidthExportXLSX()
833 //tdf#100946 FILESAVE Excel on macOS ignored column widths in XLSX last saved by LO
834 createScDoc("ods/custom_column_width.ods");
836 save("Calc Office Open XML");
837 xmlDocUniquePtr pSheet
= parseExport("xl/worksheets/sheet1.xml");
838 CPPUNIT_ASSERT(pSheet
);
840 // tdf#124741: check that we export default width, otherwise the skipped columns would have
841 // wrong width. Previously defaultColWidth attribute was missing
843 = getXPath(pSheet
, "/x:worksheet/x:sheetFormatPr", "defaultColWidth").toDouble();
844 CPPUNIT_ASSERT_DOUBLES_EQUAL(11.53515625, nDefWidth
, 0.01);
846 // First column, has everything default (width in Calc: 1280), skipped
848 // Second column, has custom width (width in Calc: 1225)
849 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[1]", "hidden", "false");
850 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[1]", "outlineLevel", "0");
851 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[1]", "customWidth", "true");
852 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[1]", "collapsed", "false");
853 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[1]", "min", "2");
854 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[1]", "max", "2");
856 // Third column, has everything default (width in Calc: 1280), skipped
858 // Fourth column has custom width. Columns from 4 to 7 are hidden
859 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[2]", "hidden", "true");
860 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[2]", "outlineLevel", "0");
861 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[2]", "customWidth", "true");
862 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[2]", "collapsed", "false");
863 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[2]", "min", "4");
864 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[2]", "max", "4");
866 // 5th column has custom width. Columns from 4 to 7 are hidden
867 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[3]", "hidden", "true");
868 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[3]", "outlineLevel", "0");
869 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[3]", "customWidth", "true");
870 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[3]", "collapsed", "false");
871 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[3]", "min", "5");
872 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[3]", "max", "5");
874 // 6th and 7th columns have default width and they are hidden
875 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[4]", "hidden", "true");
876 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[4]", "outlineLevel", "0");
877 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[4]", "customWidth", "false");
878 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[4]", "collapsed", "false");
879 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[4]", "min", "6");
880 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[4]", "max", "7");
882 // 8th column has everything default - skipped
884 // 9th column has custom width
885 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[5]", "hidden", "false");
886 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[5]", "outlineLevel", "0");
887 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[5]", "customWidth", "true");
888 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[5]", "collapsed", "false");
889 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[5]", "min", "9");
890 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[5]", "max", "9");
892 // We expected that exactly 5 unique Nodes will be produced
893 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col", 5);
895 assertXPath(pSheet
, "/x:worksheet/x:sheetData/x:row[1]", "hidden", "false");
896 assertXPath(pSheet
, "/x:worksheet/x:sheetData/x:row[1]", "outlineLevel", "0");
897 assertXPath(pSheet
, "/x:worksheet/x:sheetData/x:row[1]", "collapsed", "false");
898 assertXPath(pSheet
, "/x:worksheet/x:sheetData/x:row[1]", "customFormat", "false");
899 assertXPath(pSheet
, "/x:worksheet/x:sheetData/x:row[1]", "customHeight", "false");
903 void ScExportTest::testXfDefaultValuesXLSX()
905 //tdf#70565 FORMATTING: User Defined Custom Formatting is not applied during importing XLSX documents
906 createScDoc("xlsx/xf_default_values.xlsx");
908 save("Calc Office Open XML");
909 xmlDocUniquePtr pSheet
= parseExport("xl/styles.xml");
910 CPPUNIT_ASSERT(pSheet
);
912 // cellStyleXfs don't need xfId, so we need to make sure it is not saved
913 assertXPathNoAttribute(pSheet
, "/x:styleSheet/x:cellStyleXfs/x:xf[1]", "xfId");
915 // Because numFmtId fontId fillId borderId xfId are not existing during import
916 // it should be created during export, with values set to "0"
917 assertXPath(pSheet
, "/x:styleSheet/x:cellXfs/x:xf[1]", "xfId", "0");
918 assertXPath(pSheet
, "/x:styleSheet/x:cellXfs/x:xf[2]", "xfId", "0");
919 assertXPath(pSheet
, "/x:styleSheet/x:cellXfs/x:xf[3]", "xfId", "0");
920 assertXPath(pSheet
, "/x:styleSheet/x:cellXfs/x:xf[4]", "xfId", "0");
922 // We expected that exactly 15 cellXfs:xf Nodes will be produced
923 assertXPath(pSheet
, "/x:styleSheet/x:cellXfs/x:xf", 14);
926 static auto verifySpreadsheet13(char const* const pTestName
, ScDocument
& rDoc
) -> void
928 // OFFICE-2173 table:tab-color
929 CPPUNIT_ASSERT_EQUAL_MESSAGE(pTestName
, Color(0xff3838), rDoc
.GetTabBgColor(0));
930 // OFFICE-3857 table:scale-to-X/table:scale-to-Y
931 OUString styleName
= rDoc
.GetPageStyle(0);
932 ScStyleSheetPool
* pStylePool
= rDoc
.GetStyleSheetPool();
933 SfxStyleSheetBase
* pStyleSheet
= pStylePool
->Find(styleName
, SfxStyleFamily::Page
);
934 CPPUNIT_ASSERT_MESSAGE(pTestName
, pStyleSheet
);
936 SfxItemSet
const& rSet
= pStyleSheet
->GetItemSet();
937 ScPageScaleToItem
const& rItem(rSet
.Get(ATTR_PAGE_SCALETO
));
938 CPPUNIT_ASSERT_EQUAL_MESSAGE(pTestName
, sal_uInt16(2), rItem
.GetWidth());
939 CPPUNIT_ASSERT_EQUAL_MESSAGE(pTestName
, sal_uInt16(3), rItem
.GetHeight());
942 void ScExportTest::testODF13()
945 createScDoc("ods/spreadsheet13e.ods");
946 ScDocument
* pDoc
= getScDoc();
949 verifySpreadsheet13("import", *pDoc
);
952 std::shared_ptr
<comphelper::ConfigurationChanges
> pBatch(
953 comphelper::ConfigurationChanges::create());
954 officecfg::Office::Common::Save::ODF::DefaultVersion::set(3, pBatch
);
955 return pBatch
->commit();
960 std::shared_ptr
<comphelper::ConfigurationChanges
> pBatch(
961 comphelper::ConfigurationChanges::create());
962 officecfg::Office::Common::Save::ODF::DefaultVersion::set(10, pBatch
);
965 // FIXME: Error: unexpected attribute "loext:scale-to-X"
968 saveAndReload("calc8");
972 xmlDocUniquePtr pContentXml
= parseExport("content.xml");
973 assertXPath(pContentXml
, "/office:document-content/office:automatic-styles/style:style/"
974 "style:table-properties[@table:tab-color='#ff3838']");
975 xmlDocUniquePtr pStylesXml
= parseExport("styles.xml");
976 assertXPath(pStylesXml
, "/office:document-styles/office:automatic-styles/style:page-layout/"
977 "style:page-layout-properties[@style:scale-to-X='2']");
978 assertXPath(pStylesXml
, "/office:document-styles/office:automatic-styles/style:page-layout/"
979 "style:page-layout-properties[@style:scale-to-Y='3']");
982 verifySpreadsheet13("1.3 reload", *pDoc
);
985 // export ODF 1.2 Extended
986 std::shared_ptr
<comphelper::ConfigurationChanges
> pBatch(
987 comphelper::ConfigurationChanges::create());
988 officecfg::Office::Common::Save::ODF::DefaultVersion::set(9, pBatch
);
991 saveAndReload("calc8");
995 xmlDocUniquePtr pContentXml
= parseExport("content.xml");
996 assertXPath(pContentXml
, "/office:document-content/office:automatic-styles/style:style/"
997 "style:table-properties[@tableooo:tab-color='#ff3838']");
998 xmlDocUniquePtr pStylesXml
= parseExport("styles.xml");
999 assertXPath(pStylesXml
, "/office:document-styles/office:automatic-styles/style:page-layout/"
1000 "style:page-layout-properties[@loext:scale-to-X='2']");
1001 assertXPath(pStylesXml
, "/office:document-styles/office:automatic-styles/style:page-layout/"
1002 "style:page-layout-properties[@loext:scale-to-Y='3']");
1005 verifySpreadsheet13("1.2 Extended reload", *pDoc
);
1009 std::shared_ptr
<comphelper::ConfigurationChanges
> pBatch(
1010 comphelper::ConfigurationChanges::create());
1011 officecfg::Office::Common::Save::ODF::DefaultVersion::set(4, pBatch
);
1017 xmlDocUniquePtr pContentXml
= parseExport("content.xml");
1018 assertXPathNoAttribute(
1020 "/office:document-content/office:automatic-styles/style:style/style:table-properties",
1022 xmlDocUniquePtr pStylesXml
= parseExport("styles.xml");
1023 assertXPathNoAttribute(pStylesXml
,
1024 "/office:document-styles/office:automatic-styles/"
1025 "style:page-layout[1]/style:page-layout-properties",
1027 assertXPathNoAttribute(pStylesXml
,
1028 "/office:document-styles/office:automatic-styles/"
1029 "style:page-layout[1]/style:page-layout-properties",
1032 // don't reload - no point
1036 void ScExportTest::testColumnWidthResaveXLSX()
1038 // tdf#91475 FILESAVE: Column width is not preserved in XLSX / after round trip.
1039 // Test if after resave .xlsx file, columns width is identical with previous one
1040 createScDoc("xlsx/different-column-width-excel2010.xlsx");
1042 save("Calc Office Open XML");
1043 xmlDocUniquePtr pSheet
= parseExport("xl/worksheets/sheet1.xml");
1044 CPPUNIT_ASSERT(pSheet
);
1046 // In original Excel document the width is "24"
1047 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[1]", "width", "24");
1048 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[1]", "customWidth", "true");
1050 // In original Excel document the width is "12"
1051 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[2]", "width", "12");
1052 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[2]", "customWidth", "true");
1054 // In original Excel document the width is "6"
1055 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[3]", "width", "6");
1056 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[3]", "customWidth", "true");
1058 // In original Excel document the width is "1"
1059 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[4]", "width", "1");
1060 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[4]", "customWidth", "true");
1062 // In original Excel document the width is "250"
1063 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[5]", "width", "250");
1064 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[5]", "customWidth", "true");
1066 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col", 5);
1070 void ScExportTest::testColumnWidthExportFromODStoXLSX()
1072 // tdf#91475 FILESAVE: Column width is not preserved in XLSX / after round trip.
1073 // Test if after export .ods to .xlsx format, displayed columns width
1074 // is identical with previous (.ods) one
1076 createScDoc("ods/different-column-width.ods");
1078 ScDocument
* pDoc
= getScDoc();
1080 // Col 1, Tab 0 (Column width 2.00 in)
1081 sal_uInt16 nExpectedColumn0Width
1082 = pDoc
->GetColWidth(static_cast<SCCOL
>(0), static_cast<SCTAB
>(0), false);
1083 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16
>(2880), nExpectedColumn0Width
);
1085 // Col 2, Tab 0 (Column width 1.00 in)
1086 sal_uInt16 nExpectedColumn1Width
1087 = pDoc
->GetColWidth(static_cast<SCCOL
>(1), static_cast<SCTAB
>(0), false);
1088 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16
>(1440), nExpectedColumn1Width
);
1090 // Col 3, Tab 0 (Column width 0.50 in)
1091 sal_uInt16 nExpectedColumn2Width
1092 = pDoc
->GetColWidth(static_cast<SCCOL
>(2), static_cast<SCTAB
>(0), false);
1093 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16
>(720), nExpectedColumn2Width
);
1095 // Col 4, Tab 0 (Column width 0.25 in)
1096 sal_uInt16 nExpectedColumn3Width
1097 = pDoc
->GetColWidth(static_cast<SCCOL
>(3), static_cast<SCTAB
>(0), false);
1098 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16
>(360), nExpectedColumn3Width
);
1100 // Col 5, Tab 0 (Column width 13.57 in)
1101 sal_uInt16 nExpectedColumn4Width
1102 = pDoc
->GetColWidth(static_cast<SCCOL
>(4), static_cast<SCTAB
>(0), false);
1103 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16
>(19539), nExpectedColumn4Width
);
1105 // Export to .xlsx and compare column width with the .ods
1106 // We expect that column width from .ods will be exactly the same as imported from .xlsx
1108 saveAndReload("Calc Office Open XML");
1113 sal_uInt16 nCalcWidth
;
1114 nCalcWidth
= pDoc
->GetColWidth(static_cast<SCCOL
>(0), static_cast<SCTAB
>(0), false);
1115 CPPUNIT_ASSERT_EQUAL(nExpectedColumn0Width
, nCalcWidth
);
1118 nCalcWidth
= pDoc
->GetColWidth(static_cast<SCCOL
>(1), static_cast<SCTAB
>(0), false);
1119 CPPUNIT_ASSERT_EQUAL(nExpectedColumn1Width
, nCalcWidth
);
1122 nCalcWidth
= pDoc
->GetColWidth(static_cast<SCCOL
>(2), static_cast<SCTAB
>(0), false);
1123 CPPUNIT_ASSERT_EQUAL(nExpectedColumn2Width
, nCalcWidth
);
1126 nCalcWidth
= pDoc
->GetColWidth(static_cast<SCCOL
>(3), static_cast<SCTAB
>(0), false);
1127 CPPUNIT_ASSERT_EQUAL(nExpectedColumn3Width
, nCalcWidth
);
1130 nCalcWidth
= pDoc
->GetColWidth(static_cast<SCCOL
>(4), static_cast<SCTAB
>(0), false);
1131 CPPUNIT_ASSERT_EQUAL(nExpectedColumn4Width
, nCalcWidth
);
1135 void ScExportTest::testOutlineExportXLSX()
1137 //tdf#100347 FILESAVE FILEOPEN after exporting to .xlsx format grouping are lost
1138 //tdf#51524 FILESAVE .xlsx and.xls looses width information for hidden/collapsed grouped columns
1139 createScDoc("ods/outline.ods");
1141 save("Calc Office Open XML");
1142 xmlDocUniquePtr pSheet
= parseExport("xl/worksheets/sheet1.xml");
1143 CPPUNIT_ASSERT(pSheet
);
1145 // Maximum Outline Row is 4 for this document
1146 assertXPath(pSheet
, "/x:worksheet/x:sheetFormatPr", "outlineLevelRow", "4");
1147 // Maximum Outline Column is 4 for this document
1148 assertXPath(pSheet
, "/x:worksheet/x:sheetFormatPr", "outlineLevelCol", "4");
1150 // First XML node, creates two columns (from min=1 to max=2)
1151 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[1]", "hidden", "false");
1152 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[1]", "outlineLevel", "1");
1153 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[1]", "collapsed", "false");
1154 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[1]", "min", "1");
1155 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[1]", "max", "2");
1157 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[2]", "hidden", "true");
1158 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[2]", "outlineLevel", "2");
1159 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[2]", "collapsed", "false");
1160 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[2]", "min", "3");
1161 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[2]", "max", "3");
1163 // Column 4 has custom width and it is hidden. We need to make sure that it is created
1164 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[3]", "hidden", "true");
1165 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[3]", "outlineLevel", "2");
1166 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[3]", "collapsed", "false");
1167 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[3]", "min", "4");
1168 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[3]", "max", "4");
1170 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[4]", "hidden", "true");
1171 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[4]", "outlineLevel", "3");
1172 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[4]", "collapsed", "false");
1173 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[4]", "min", "5");
1174 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[4]", "max", "6");
1176 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[5]", "hidden", "true");
1177 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[5]", "outlineLevel", "4");
1178 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[5]", "collapsed", "false");
1179 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[5]", "min", "7");
1180 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[5]", "max", "7");
1182 // Column 8 has custom width and it is hidden. We need to make sure that it is created
1183 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[6]", "hidden", "true");
1184 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[6]", "outlineLevel", "4");
1185 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[6]", "collapsed", "false");
1186 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[6]", "min", "8");
1187 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[6]", "max", "8");
1189 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[7]", "hidden", "true");
1190 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[7]", "outlineLevel", "4");
1191 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[7]", "collapsed", "false");
1192 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[7]", "min", "9");
1193 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[7]", "max", "19");
1195 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[8]", "hidden", "true");
1196 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[8]", "outlineLevel", "3");
1197 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[8]", "collapsed", "true");
1198 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[8]", "min", "20");
1199 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[8]", "max", "20");
1201 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[9]", "hidden", "true");
1202 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[9]", "outlineLevel", "3");
1203 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[9]", "collapsed", "false");
1204 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[9]", "min", "21");
1205 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[9]", "max", "21");
1207 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[10]", "hidden", "true");
1208 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[10]", "outlineLevel", "2");
1209 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[10]", "collapsed", "false");
1210 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[10]", "min", "22");
1211 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[10]", "max", "23");
1213 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[11]", "hidden", "false");
1214 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[11]", "outlineLevel", "1");
1215 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[11]", "collapsed", "true");
1216 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[11]", "min", "24");
1217 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[11]", "max", "24");
1219 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[12]", "hidden", "false");
1220 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[12]", "outlineLevel", "1");
1221 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[12]", "collapsed", "false");
1222 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[12]", "min", "25");
1223 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col[12]", "max", "26");
1225 // We expected that exactly 12 unique Nodes will be produced
1226 assertXPath(pSheet
, "/x:worksheet/x:cols/x:col", 12);
1228 // First row is empty and default so it is not written into XML file
1229 // so we need to save 29 rows, as it provides information about outLineLevel
1230 assertXPath(pSheet
, "/x:worksheet/x:sheetData/x:row[1]", "r", "2");
1231 assertXPath(pSheet
, "/x:worksheet/x:sheetData/x:row[1]", "hidden", "false");
1232 assertXPath(pSheet
, "/x:worksheet/x:sheetData/x:row[1]", "outlineLevel", "1");
1233 assertXPath(pSheet
, "/x:worksheet/x:sheetData/x:row[1]", "collapsed", "false");
1234 assertXPath(pSheet
, "/x:worksheet/x:sheetData/x:row[2]", "r", "3");
1235 assertXPath(pSheet
, "/x:worksheet/x:sheetData/x:row[2]", "hidden", "false");
1236 assertXPath(pSheet
, "/x:worksheet/x:sheetData/x:row[2]", "outlineLevel", "2");
1237 assertXPath(pSheet
, "/x:worksheet/x:sheetData/x:row[2]", "collapsed", "false");
1238 assertXPath(pSheet
, "/x:worksheet/x:sheetData/x:row[3]", "r", "4");
1239 assertXPath(pSheet
, "/x:worksheet/x:sheetData/x:row[3]", "hidden", "false");
1240 assertXPath(pSheet
, "/x:worksheet/x:sheetData/x:row[3]", "outlineLevel", "2");
1241 assertXPath(pSheet
, "/x:worksheet/x:sheetData/x:row[3]", "collapsed", "false");
1242 assertXPath(pSheet
, "/x:worksheet/x:sheetData/x:row[4]", "r", "5");
1243 assertXPath(pSheet
, "/x:worksheet/x:sheetData/x:row[4]", "hidden", "false");
1244 assertXPath(pSheet
, "/x:worksheet/x:sheetData/x:row[4]", "outlineLevel", "3");
1245 assertXPath(pSheet
, "/x:worksheet/x:sheetData/x:row[4]", "collapsed", "false");
1246 assertXPath(pSheet
, "/x:worksheet/x:sheetData/x:row[5]", "r", "6");
1247 assertXPath(pSheet
, "/x:worksheet/x:sheetData/x:row[5]", "hidden", "false");
1248 assertXPath(pSheet
, "/x:worksheet/x:sheetData/x:row[5]", "outlineLevel", "3");
1249 assertXPath(pSheet
, "/x:worksheet/x:sheetData/x:row[5]", "collapsed", "false");
1250 assertXPath(pSheet
, "/x:worksheet/x:sheetData/x:row[6]", "r", "7");
1251 assertXPath(pSheet
, "/x:worksheet/x:sheetData/x:row[6]", "hidden", "true");
1252 assertXPath(pSheet
, "/x:worksheet/x:sheetData/x:row[6]", "outlineLevel", "4");
1253 assertXPath(pSheet
, "/x:worksheet/x:sheetData/x:row[6]", "collapsed", "false");
1254 assertXPath(pSheet
, "/x:worksheet/x:sheetData/x:row[7]", "r", "8");
1255 assertXPath(pSheet
, "/x:worksheet/x:sheetData/x:row[7]", "hidden", "true");
1256 assertXPath(pSheet
, "/x:worksheet/x:sheetData/x:row[7]", "outlineLevel", "4");
1257 assertXPath(pSheet
, "/x:worksheet/x:sheetData/x:row[7]", "collapsed", "false");
1258 assertXPath(pSheet
, "/x:worksheet/x:sheetData/x:row[8]", "r", "9");
1259 assertXPath(pSheet
, "/x:worksheet/x:sheetData/x:row[8]", "hidden", "true");
1260 assertXPath(pSheet
, "/x:worksheet/x:sheetData/x:row[8]", "outlineLevel", "4");
1261 assertXPath(pSheet
, "/x:worksheet/x:sheetData/x:row[8]", "collapsed", "false");
1262 // Next rows are the same as the previous one but it needs to be preserved,
1263 // as they contain information about outlineLevel
1264 assertXPath(pSheet
, "/x:worksheet/x:sheetData/x:row[20]", "r", "21");
1265 assertXPath(pSheet
, "/x:worksheet/x:sheetData/x:row[20]", "hidden", "true");
1266 assertXPath(pSheet
, "/x:worksheet/x:sheetData/x:row[20]", "outlineLevel", "4");
1267 assertXPath(pSheet
, "/x:worksheet/x:sheetData/x:row[20]", "collapsed", "false");
1268 assertXPath(pSheet
, "/x:worksheet/x:sheetData/x:row[21]", "r", "22");
1269 assertXPath(pSheet
, "/x:worksheet/x:sheetData/x:row[21]", "hidden", "false");
1270 assertXPath(pSheet
, "/x:worksheet/x:sheetData/x:row[21]", "outlineLevel", "3");
1271 assertXPath(pSheet
, "/x:worksheet/x:sheetData/x:row[21]", "collapsed", "true");
1272 assertXPath(pSheet
, "/x:worksheet/x:sheetData/x:row[22]", "r", "23");
1273 assertXPath(pSheet
, "/x:worksheet/x:sheetData/x:row[22]", "hidden", "false");
1274 assertXPath(pSheet
, "/x:worksheet/x:sheetData/x:row[22]", "outlineLevel", "3");
1275 assertXPath(pSheet
, "/x:worksheet/x:sheetData/x:row[22]", "collapsed", "false");
1277 // We expected that exactly 29 Row Nodes will be produced
1278 assertXPath(pSheet
, "/x:worksheet/x:sheetData/x:row", 29);
1281 void ScExportTest::testAllRowsHiddenXLSX()
1283 createScDoc("xlsx/tdf105840_allRowsHidden.xlsx");
1285 save("Calc Office Open XML");
1286 xmlDocUniquePtr pSheet
= parseExport("xl/worksheets/sheet1.xml");
1287 CPPUNIT_ASSERT(pSheet
);
1288 assertXPath(pSheet
, "/x:worksheet/x:sheetFormatPr", "zeroHeight", "true");
1289 assertXPath(pSheet
, "/x:worksheet/x:sheetData/x:row", 0);
1292 void ScExportTest::testHiddenEmptyRowsXLSX()
1294 //tdf#98106 FILESAVE: Hidden and empty rows became visible when export to .XLSX
1295 createScDoc("ods/hidden-empty-rows.ods");
1297 save("Calc Office Open XML");
1298 xmlDocUniquePtr pSheet
= parseExport("xl/worksheets/sheet1.xml");
1299 CPPUNIT_ASSERT(pSheet
);
1301 assertXPath(pSheet
, "/x:worksheet/x:sheetFormatPr", "zeroHeight", "false");
1302 assertXPath(pSheet
, "/x:worksheet/x:sheetData/x:row[1]", "hidden", "true");
1303 assertXPath(pSheet
, "/x:worksheet/x:sheetData/x:row[2]", "hidden", "true");
1304 assertXPath(pSheet
, "/x:worksheet/x:sheetData/x:row[3]", "hidden", "true");
1305 assertXPath(pSheet
, "/x:worksheet/x:sheetData/x:row[4]", "hidden", "false");
1308 void ScExportTest::testHiddenEmptyColsODS()
1310 //tdf#98106 FILESAVE: Hidden and empty rows became visible when export to .XLSX
1311 createScDoc("ods/tdf128895_emptyHiddenCols.ods");
1314 xmlDocUniquePtr pSheet
= parseExport("content.xml");
1315 CPPUNIT_ASSERT(pSheet
);
1316 assertXPath(pSheet
, "//table:table/table:table-column[2]");
1317 assertXPath(pSheet
, "//table:table/table:table-column[2]", "number-columns-repeated", "1017");
1320 void ScExportTest::testLandscapeOrientationXLSX()
1322 //tdf#48767 - Landscape page orientation is not loaded from .xlsx format with MS Excel, after export with Libre Office
1323 createScDoc("ods/hidden-empty-rows.ods");
1325 save("Calc Office Open XML");
1326 xmlDocUniquePtr pSheet
= parseExport("xl/worksheets/sheet1.xml");
1327 CPPUNIT_ASSERT(pSheet
);
1329 // the usePrinterDefaults cannot be saved to allow opening sheets in Landscape mode via MS Excel
1330 assertXPathNoAttribute(pSheet
, "/x:worksheet/x:pageSetup", "usePrinterDefaults");
1331 assertXPath(pSheet
, "/x:worksheet/x:pageSetup", "orientation", "landscape");
1334 void ScExportTest::testDataBarExportXLSX()
1336 createScDoc("xlsx/databar.xlsx");
1338 saveAndReload("Calc Office Open XML");
1340 ScDocument
* pDoc
= getScDoc();
1342 testDataBar_Impl(*pDoc
);
1345 void ScExportTest::testMiscRowHeightExport()
1347 static const TestParam::RowData DfltRowData
[] = {
1348 { 0, 4, 0, 529, 0, false },
1349 { 5, 10, 0, 1058, 0, false },
1350 { 17, 20, 0, 1746, 0, false },
1351 // check last couple of row in document to ensure
1352 // they are 5.29mm ( effective default row xlsx height )
1353 { 1048573, 1048575, 0, 529, 0, false },
1356 static const TestParam::RowData EmptyRepeatRowData
[] = {
1357 // rows 0-4, 5-10, 17-20 are all set at various
1358 // heights, there is no content in the rows, there
1359 // was a bug where only the first row ( of repeated rows )
1360 // was set after export
1361 { 0, 4, 0, 529, 0, false },
1362 { 5, 10, 0, 1058, 0, false },
1363 { 17, 20, 0, 1767, 0, false },
1366 TestParam aTestValues
[] = {
1367 // Checks that some distributed ( non-empty ) heights remain set after export (roundtrip)
1368 // additionally there is effectively a default row height ( 5.29 mm ). So we test the
1369 // unset rows at the end of the document to ensure the effective xlsx default height
1370 // is set there too.
1371 { u
"xlsx/miscrowheights.xlsx", "Calc Office Open XML", SAL_N_ELEMENTS(DfltRowData
),
1373 // Checks that some distributed ( non-empty ) heights remain set after export (to xls)
1374 { u
"xlsx/miscrowheights.xlsx", "MS Excel 97", SAL_N_ELEMENTS(DfltRowData
), DfltRowData
},
1375 // Checks that repreated rows ( of various heights ) remain set after export ( to xlsx )
1376 { u
"ods/miscemptyrepeatedrowheights.ods", "Calc Office Open XML",
1377 SAL_N_ELEMENTS(EmptyRepeatRowData
), EmptyRepeatRowData
},
1378 // Checks that repreated rows ( of various heights ) remain set after export ( to xls )
1379 { u
"ods/miscemptyrepeatedrowheights.ods", "MS Excel 97", SAL_N_ELEMENTS(EmptyRepeatRowData
),
1380 EmptyRepeatRowData
},
1382 miscRowHeightsTest(aTestValues
, SAL_N_ELEMENTS(aTestValues
));
1387 void setAttribute(ScFieldEditEngine
& rEE
, sal_Int32 nPara
, sal_Int32 nStart
, sal_Int32 nEnd
,
1388 sal_uInt16 nType
, Color nColor
= COL_BLACK
)
1391 aSel
.nStartPara
= aSel
.nEndPara
= nPara
;
1392 aSel
.nStartPos
= nStart
;
1393 aSel
.nEndPos
= nEnd
;
1395 SfxItemSet aItemSet
= rEE
.GetEmptyItemSet();
1398 case EE_CHAR_WEIGHT
:
1400 SvxWeightItem
aWeight(WEIGHT_BOLD
, nType
);
1401 aItemSet
.Put(aWeight
);
1402 rEE
.QuickSetAttribs(aItemSet
, aSel
);
1405 case EE_CHAR_ITALIC
:
1407 SvxPostureItem
aItalic(ITALIC_NORMAL
, nType
);
1408 aItemSet
.Put(aItalic
);
1409 rEE
.QuickSetAttribs(aItemSet
, aSel
);
1412 case EE_CHAR_STRIKEOUT
:
1414 SvxCrossedOutItem
aCrossOut(STRIKEOUT_SINGLE
, nType
);
1415 aItemSet
.Put(aCrossOut
);
1416 rEE
.QuickSetAttribs(aItemSet
, aSel
);
1419 case EE_CHAR_OVERLINE
:
1421 SvxOverlineItem
aItem(LINESTYLE_DOUBLE
, nType
);
1422 aItemSet
.Put(aItem
);
1423 rEE
.QuickSetAttribs(aItemSet
, aSel
);
1426 case EE_CHAR_UNDERLINE
:
1428 SvxUnderlineItem
aItem(LINESTYLE_DOUBLE
, nType
);
1429 aItemSet
.Put(aItem
);
1430 rEE
.QuickSetAttribs(aItemSet
, aSel
);
1435 SvxColorItem
aItem(nColor
, nType
);
1436 aItemSet
.Put(aItem
);
1437 rEE
.QuickSetAttribs(aItemSet
, aSel
);
1444 void setFont(ScFieldEditEngine
& rEE
, sal_Int32 nPara
, sal_Int32 nStart
, sal_Int32 nEnd
,
1445 const OUString
& rFontName
)
1448 aSel
.nStartPara
= aSel
.nEndPara
= nPara
;
1449 aSel
.nStartPos
= nStart
;
1450 aSel
.nEndPos
= nEnd
;
1452 SfxItemSet aItemSet
= rEE
.GetEmptyItemSet();
1453 SvxFontItem
aItem(FAMILY_MODERN
, rFontName
, "", PITCH_VARIABLE
, RTL_TEXTENCODING_UTF8
,
1455 aItemSet
.Put(aItem
);
1456 rEE
.QuickSetAttribs(aItemSet
, aSel
);
1459 void setEscapement(ScFieldEditEngine
& rEE
, sal_Int32 nPara
, sal_Int32 nStart
, sal_Int32 nEnd
,
1460 short nEsc
, sal_uInt8 nRelSize
)
1463 aSel
.nStartPara
= aSel
.nEndPara
= nPara
;
1464 aSel
.nStartPos
= nStart
;
1465 aSel
.nEndPos
= nEnd
;
1467 SfxItemSet aItemSet
= rEE
.GetEmptyItemSet();
1468 SvxEscapementItem
aItem(nEsc
, nRelSize
, EE_CHAR_ESCAPEMENT
);
1469 aItemSet
.Put(aItem
);
1470 rEE
.QuickSetAttribs(aItemSet
, aSel
);
1474 void ScExportTest::testNamedRangeBugfdo62729()
1476 #if !defined(MACOSX) // FIXME: infinite loop on jenkins' mac
1477 createScDoc("ods/fdo62729.ods");
1478 ScDocument
* pDoc
= getScDoc();
1480 ScRangeName
* pNames
= pDoc
->GetRangeName();
1481 //should be just a single named range
1482 CPPUNIT_ASSERT_EQUAL(size_t(1), pNames
->size());
1484 //should be still a single named range
1485 CPPUNIT_ASSERT_EQUAL(size_t(1), pNames
->size());
1486 saveAndReload("calc8");
1490 pNames
= pDoc
->GetRangeName();
1491 //after reload should still have a named range
1492 CPPUNIT_ASSERT_EQUAL(size_t(1), pNames
->size());
1496 void ScExportTest::testBuiltinRangesXLSX()
1498 createScDoc("xlsx/built-in_ranges.xlsx");
1500 save("Calc Office Open XML");
1501 xmlDocUniquePtr pDoc
= parseExport("xl/workbook.xml");
1502 CPPUNIT_ASSERT(pDoc
);
1504 //assert the existing OOXML built-in names are still there
1505 assertXPathContent(pDoc
,
1506 "/x:workbook/x:definedNames/"
1507 "x:definedName[@name='_xlnm._FilterDatabase'][@localSheetId='0']",
1508 "'Sheet1 Test'!$A$1:$A$5");
1509 assertXPathContent(pDoc
,
1510 "/x:workbook/x:definedNames/"
1511 "x:definedName[@name='_xlnm._FilterDatabase'][@localSheetId='1']",
1512 "'Sheet2 Test'!$K$10:$K$14");
1515 "/x:workbook/x:definedNames/x:definedName[@name='_xlnm.Print_Area'][@localSheetId='0']",
1516 "'Sheet1 Test'!$A$1:$A$5");
1519 "/x:workbook/x:definedNames/x:definedName[@name='_xlnm.Print_Area'][@localSheetId='1']",
1520 "'Sheet2 Test'!$K$10:$M$18");
1522 //...and that no extra ones are added (see tdf#112571)
1524 "/x:workbook/x:definedNames/"
1525 "x:definedName[@name='_xlnm._FilterDatabase_0'][@localSheetId='0']",
1528 "/x:workbook/x:definedNames/"
1529 "x:definedName[@name='_xlnm._FilterDatabase_0'][@localSheetId='1']",
1533 "/x:workbook/x:definedNames/x:definedName[@name='_xlnm.Print_Area_0'][@localSheetId='0']",
1537 "/x:workbook/x:definedNames/x:definedName[@name='_xlnm.Print_Area_0'][@localSheetId='1']",
1541 void ScExportTest::testRichTextExportODS()
1545 static bool isBold(const editeng::Section
& rAttr
)
1548 rAttr
.maAttributes
.begin(), rAttr
.maAttributes
.end(), [](const SfxPoolItem
* p
) {
1549 return p
->Which() == EE_CHAR_WEIGHT
1550 && static_cast<const SvxWeightItem
*>(p
)->GetWeight() == WEIGHT_BOLD
;
1554 static bool isItalic(const editeng::Section
& rAttr
)
1557 rAttr
.maAttributes
.begin(), rAttr
.maAttributes
.end(), [](const SfxPoolItem
* p
) {
1558 return p
->Which() == EE_CHAR_ITALIC
1559 && static_cast<const SvxPostureItem
*>(p
)->GetPosture() == ITALIC_NORMAL
;
1563 static bool isStrikeOut(const editeng::Section
& rAttr
)
1566 rAttr
.maAttributes
.begin(), rAttr
.maAttributes
.end(), [](const SfxPoolItem
* p
) {
1567 return p
->Which() == EE_CHAR_STRIKEOUT
1568 && static_cast<const SvxCrossedOutItem
*>(p
)->GetStrikeout()
1569 == STRIKEOUT_SINGLE
;
1573 static bool isOverline(const editeng::Section
& rAttr
, FontLineStyle eStyle
)
1575 return std::any_of(rAttr
.maAttributes
.begin(), rAttr
.maAttributes
.end(),
1576 [&eStyle
](const SfxPoolItem
* p
) {
1577 return p
->Which() == EE_CHAR_OVERLINE
1578 && static_cast<const SvxOverlineItem
*>(p
)->GetLineStyle()
1583 static bool isUnderline(const editeng::Section
& rAttr
, FontLineStyle eStyle
)
1585 return std::any_of(rAttr
.maAttributes
.begin(), rAttr
.maAttributes
.end(),
1586 [&eStyle
](const SfxPoolItem
* p
) {
1587 return p
->Which() == EE_CHAR_UNDERLINE
1588 && static_cast<const SvxUnderlineItem
*>(p
)->GetLineStyle()
1593 static bool isFont(const editeng::Section
& rAttr
, const OUString
& rFontName
)
1595 return std::any_of(rAttr
.maAttributes
.begin(), rAttr
.maAttributes
.end(),
1596 [&rFontName
](const SfxPoolItem
* p
) {
1597 return p
->Which() == EE_CHAR_FONTINFO
1598 && static_cast<const SvxFontItem
*>(p
)->GetFamilyName()
1603 static bool isEscapement(const editeng::Section
& rAttr
, short nEsc
, sal_uInt8 nRelSize
)
1605 return std::any_of(rAttr
.maAttributes
.begin(), rAttr
.maAttributes
.end(),
1606 [&nEsc
, &nRelSize
](const SfxPoolItem
* p
) {
1607 if (p
->Which() != EE_CHAR_ESCAPEMENT
)
1609 const SvxEscapementItem
* pItem
1610 = static_cast<const SvxEscapementItem
*>(p
);
1611 return ((pItem
->GetEsc() == nEsc
)
1612 && (pItem
->GetProportionalHeight() == nRelSize
));
1616 static bool isColor(const editeng::Section
& rAttr
, Color nColor
)
1618 return std::any_of(rAttr
.maAttributes
.begin(), rAttr
.maAttributes
.end(),
1619 [&nColor
](const SfxPoolItem
* p
) {
1620 return p
->Which() == EE_CHAR_COLOR
1621 && static_cast<const SvxColorItem
*>(p
)->GetValue()
1626 bool checkB2(const EditTextObject
* pText
) const
1631 if (pText
->GetParagraphCount() != 1)
1634 if (pText
->GetText(0) != "Bold and Italic")
1637 std::vector
<editeng::Section
> aSecAttrs
;
1638 pText
->GetAllSections(aSecAttrs
);
1639 if (aSecAttrs
.size() != 3)
1642 // Check the first bold section.
1643 const editeng::Section
* pAttr
= aSecAttrs
.data();
1644 if (pAttr
->mnParagraph
!= 0 || pAttr
->mnStart
!= 0 || pAttr
->mnEnd
!= 4)
1647 if (pAttr
->maAttributes
.size() != 1 || !isBold(*pAttr
))
1650 // The middle section should be unformatted.
1651 pAttr
= &aSecAttrs
[1];
1652 if (pAttr
->mnParagraph
!= 0 || pAttr
->mnStart
!= 4 || pAttr
->mnEnd
!= 9)
1655 if (!pAttr
->maAttributes
.empty())
1658 // The last section should be italic.
1659 pAttr
= &aSecAttrs
[2];
1660 if (pAttr
->mnParagraph
!= 0 || pAttr
->mnStart
!= 9 || pAttr
->mnEnd
!= 15)
1663 if (pAttr
->maAttributes
.size() != 1 || !isItalic(*pAttr
))
1669 bool checkB4(const EditTextObject
* pText
) const
1674 if (pText
->GetParagraphCount() != 3)
1677 if (pText
->GetText(0) != "One")
1680 if (pText
->GetText(1) != "Two")
1683 if (pText
->GetText(2) != "Three")
1689 bool checkB5(const EditTextObject
* pText
) const
1694 if (pText
->GetParagraphCount() != 6)
1697 if (!pText
->GetText(0).isEmpty())
1700 if (pText
->GetText(1) != "Two")
1703 if (pText
->GetText(2) != "Three")
1706 if (!pText
->GetText(3).isEmpty())
1709 if (pText
->GetText(4) != "Five")
1712 if (!pText
->GetText(5).isEmpty())
1718 bool checkB6(const EditTextObject
* pText
) const
1723 if (pText
->GetParagraphCount() != 1)
1726 if (pText
->GetText(0) != "Strike Me")
1729 std::vector
<editeng::Section
> aSecAttrs
;
1730 pText
->GetAllSections(aSecAttrs
);
1731 if (aSecAttrs
.size() != 2)
1734 // Check the first strike-out section.
1735 const editeng::Section
* pAttr
= aSecAttrs
.data();
1736 if (pAttr
->mnParagraph
!= 0 || pAttr
->mnStart
!= 0 || pAttr
->mnEnd
!= 6)
1739 if (pAttr
->maAttributes
.size() != 1 || !isStrikeOut(*pAttr
))
1742 // The last section should be unformatted.
1743 pAttr
= &aSecAttrs
[1];
1744 return pAttr
->mnParagraph
== 0 && pAttr
->mnStart
== 6 && pAttr
->mnEnd
== 9;
1747 bool checkB7(const EditTextObject
* pText
) const
1752 if (pText
->GetParagraphCount() != 1)
1755 if (pText
->GetText(0) != "Font1 and Font2")
1758 std::vector
<editeng::Section
> aSecAttrs
;
1759 pText
->GetAllSections(aSecAttrs
);
1760 if (aSecAttrs
.size() != 3)
1763 // First section should have "Courier" font applied.
1764 const editeng::Section
* pAttr
= aSecAttrs
.data();
1765 if (pAttr
->mnParagraph
!= 0 || pAttr
->mnStart
!= 0 || pAttr
->mnEnd
!= 5)
1768 if (pAttr
->maAttributes
.size() != 1 || !isFont(*pAttr
, "Courier"))
1771 // Last section should have "Luxi Mono" applied.
1772 pAttr
= &aSecAttrs
[2];
1773 if (pAttr
->mnParagraph
!= 0 || pAttr
->mnStart
!= 10 || pAttr
->mnEnd
!= 15)
1776 if (pAttr
->maAttributes
.size() != 1 || !isFont(*pAttr
, "Luxi Mono"))
1782 bool checkB8(const EditTextObject
* pText
) const
1787 if (pText
->GetParagraphCount() != 1)
1790 if (pText
->GetText(0) != "Over and Under")
1793 std::vector
<editeng::Section
> aSecAttrs
;
1794 pText
->GetAllSections(aSecAttrs
);
1795 if (aSecAttrs
.size() != 3)
1798 // First section should have overline applied.
1799 const editeng::Section
* pAttr
= aSecAttrs
.data();
1800 if (pAttr
->mnParagraph
!= 0 || pAttr
->mnStart
!= 0 || pAttr
->mnEnd
!= 4)
1803 if (pAttr
->maAttributes
.size() != 1 || !isOverline(*pAttr
, LINESTYLE_DOUBLE
))
1806 // Last section should have underline applied.
1807 pAttr
= &aSecAttrs
[2];
1808 if (pAttr
->mnParagraph
!= 0 || pAttr
->mnStart
!= 9 || pAttr
->mnEnd
!= 14)
1811 if (pAttr
->maAttributes
.size() != 1 || !isUnderline(*pAttr
, LINESTYLE_DOUBLE
))
1817 bool checkB9(const EditTextObject
* pText
) const
1822 if (pText
->GetParagraphCount() != 1)
1825 if (pText
->GetText(0) != "Sub and Super")
1828 std::vector
<editeng::Section
> aSecAttrs
;
1829 pText
->GetAllSections(aSecAttrs
);
1830 if (aSecAttrs
.size() != 3)
1834 const editeng::Section
* pAttr
= aSecAttrs
.data();
1835 if (pAttr
->mnParagraph
!= 0 || pAttr
->mnStart
!= 0 || pAttr
->mnEnd
!= 3)
1838 if (pAttr
->maAttributes
.size() != 1 || !isEscapement(*pAttr
, 32, 64))
1842 pAttr
= &aSecAttrs
[2];
1843 if (pAttr
->mnParagraph
!= 0 || pAttr
->mnStart
!= 8 || pAttr
->mnEnd
!= 13)
1846 if (pAttr
->maAttributes
.size() != 1 || !isEscapement(*pAttr
, -32, 66))
1852 bool checkB10(const EditTextObject
* pText
) const
1857 if (pText
->GetParagraphCount() != 1)
1860 if (pText
->GetText(0) != "BLUE AUTO")
1863 std::vector
<editeng::Section
> aSecAttrs
;
1864 pText
->GetAllSections(aSecAttrs
);
1865 if (aSecAttrs
.size() != 2)
1869 const editeng::Section
* pAttr
= &aSecAttrs
[1];
1870 if (pAttr
->mnParagraph
!= 0 || pAttr
->mnStart
!= 5 || pAttr
->mnEnd
!= 9)
1873 if (pAttr
->maAttributes
.size() != 1 || !isColor(*pAttr
, COL_AUTO
))
1881 // Start with an empty document, put one edit text cell, and make sure it
1882 // survives the save and reload.
1884 const EditTextObject
* pEditText
;
1886 ScDocument
* pDoc
= getScDoc();
1887 CPPUNIT_ASSERT_MESSAGE("This document should at least have one sheet.",
1888 pDoc
->GetTableCount() > 0);
1890 // Insert an edit text cell.
1891 ScFieldEditEngine
* pEE
= &pDoc
->GetEditEngine();
1892 pEE
->SetTextCurrentDefaults("Bold and Italic");
1893 // Set the 'Bold' part bold.
1894 setAttribute(*pEE
, 0, 0, 4, EE_CHAR_WEIGHT
);
1895 // Set the 'Italic' part italic.
1896 setAttribute(*pEE
, 0, 9, 15, EE_CHAR_ITALIC
);
1898 aSel
.nStartPara
= aSel
.nEndPara
= 0;
1900 // Set this edit text to cell B2.
1901 pDoc
->SetEditText(ScAddress(1, 1, 0), pEE
->CreateTextObject());
1902 pEditText
= pDoc
->GetEditText(ScAddress(1, 1, 0));
1903 CPPUNIT_ASSERT_MESSAGE("Incorrect B2 value.", aCheckFunc
.checkB2(pEditText
));
1906 // Now, save and reload this document.
1907 saveAndReload("calc8");
1909 ScDocument
* pDoc
= getScDoc();
1910 CPPUNIT_ASSERT_MESSAGE("Reloaded document should at least have one sheet.",
1911 pDoc
->GetTableCount() > 0);
1912 ScFieldEditEngine
* pEE
= &pDoc
->GetEditEngine();
1913 pEditText
= pDoc
->GetEditText(ScAddress(1, 1, 0));
1915 // Make sure the content of B2 is still intact.
1916 CPPUNIT_ASSERT_MESSAGE("Incorrect B2 value.", aCheckFunc
.checkB2(pEditText
));
1918 // Insert a multi-line content to B4.
1920 pEE
->SetTextCurrentDefaults("One\nTwo\nThree");
1921 pDoc
->SetEditText(ScAddress(1, 3, 0), pEE
->CreateTextObject());
1922 pEditText
= pDoc
->GetEditText(ScAddress(1, 3, 0));
1923 CPPUNIT_ASSERT_MESSAGE("Incorrect B4 value.", aCheckFunc
.checkB4(pEditText
));
1926 // Reload the doc again, and check the content of B2 and B4.
1927 saveAndReload("calc8");
1929 ScDocument
* pDoc
= getScDoc();
1930 ScFieldEditEngine
* pEE
= &pDoc
->GetEditEngine();
1932 pEditText
= pDoc
->GetEditText(ScAddress(1, 1, 0));
1933 CPPUNIT_ASSERT_MESSAGE("B2 should be an edit text.", pEditText
);
1934 pEditText
= pDoc
->GetEditText(ScAddress(1, 3, 0));
1935 CPPUNIT_ASSERT_MESSAGE("Incorrect B4 value.", aCheckFunc
.checkB4(pEditText
));
1937 // Insert a multi-line content to B5, but this time, set some empty paragraphs.
1939 pEE
->SetTextCurrentDefaults("\nTwo\nThree\n\nFive\n");
1940 pDoc
->SetEditText(ScAddress(1, 4, 0), pEE
->CreateTextObject());
1941 pEditText
= pDoc
->GetEditText(ScAddress(1, 4, 0));
1942 CPPUNIT_ASSERT_MESSAGE("Incorrect B5 value.", aCheckFunc
.checkB5(pEditText
));
1944 // Insert a text with strikethrough in B6.
1946 pEE
->SetTextCurrentDefaults("Strike Me");
1947 // Set the 'Strike' part strikethrough.
1948 setAttribute(*pEE
, 0, 0, 6, EE_CHAR_STRIKEOUT
);
1949 pDoc
->SetEditText(ScAddress(1, 5, 0), pEE
->CreateTextObject());
1950 pEditText
= pDoc
->GetEditText(ScAddress(1, 5, 0));
1951 CPPUNIT_ASSERT_MESSAGE("Incorrect B6 value.", aCheckFunc
.checkB6(pEditText
));
1953 // Insert a text with different font segments in B7.
1955 pEE
->SetTextCurrentDefaults("Font1 and Font2");
1956 setFont(*pEE
, 0, 0, 5, "Courier");
1957 setFont(*pEE
, 0, 10, 15, "Luxi Mono");
1958 pDoc
->SetEditText(ScAddress(1, 6, 0), pEE
->CreateTextObject());
1959 pEditText
= pDoc
->GetEditText(ScAddress(1, 6, 0));
1960 CPPUNIT_ASSERT_MESSAGE("Incorrect B7 value.", aCheckFunc
.checkB7(pEditText
));
1962 // Insert a text with overline and underline in B8.
1964 pEE
->SetTextCurrentDefaults("Over and Under");
1965 setAttribute(*pEE
, 0, 0, 4, EE_CHAR_OVERLINE
);
1966 setAttribute(*pEE
, 0, 9, 14, EE_CHAR_UNDERLINE
);
1967 pDoc
->SetEditText(ScAddress(1, 7, 0), pEE
->CreateTextObject());
1968 pEditText
= pDoc
->GetEditText(ScAddress(1, 7, 0));
1969 CPPUNIT_ASSERT_MESSAGE("Incorrect B8 value.", aCheckFunc
.checkB8(pEditText
));
1972 pEE
->SetTextCurrentDefaults("Sub and Super");
1973 setEscapement(*pEE
, 0, 0, 3, 32, 64);
1974 setEscapement(*pEE
, 0, 8, 13, -32, 66);
1975 pDoc
->SetEditText(ScAddress(1, 8, 0), pEE
->CreateTextObject());
1976 pEditText
= pDoc
->GetEditText(ScAddress(1, 8, 0));
1977 CPPUNIT_ASSERT_MESSAGE("Incorrect B9 value.", aCheckFunc
.checkB9(pEditText
));
1979 ScPatternAttr
aCellFontColor(pDoc
->GetPool());
1980 aCellFontColor
.GetItemSet().Put(SvxColorItem(COL_BLUE
, ATTR_FONT_COLOR
));
1981 // Set font color of B10 to blue.
1982 pDoc
->ApplyPattern(1, 9, 0, aCellFontColor
);
1984 pEE
->SetTextCurrentDefaults("BLUE AUTO");
1985 // Set the color of the string "AUTO" to automatic color.
1986 setAttribute(*pEE
, 0, 5, 9, EE_CHAR_COLOR
, COL_AUTO
);
1987 pDoc
->SetEditText(ScAddress(1, 9, 0), pEE
->CreateTextObject());
1988 pEditText
= pDoc
->GetEditText(ScAddress(1, 9, 0));
1989 CPPUNIT_ASSERT_MESSAGE("Incorrect B10 value.", aCheckFunc
.checkB10(pEditText
));
1992 // Reload the doc again, and check the content of B2, B4, B6 and B7.
1993 saveAndReload("calc8");
1994 ScDocument
* pDoc
= getScDoc();
1996 pEditText
= pDoc
->GetEditText(ScAddress(1, 1, 0));
1997 CPPUNIT_ASSERT_MESSAGE("Incorrect B2 value after save and reload.",
1998 aCheckFunc
.checkB2(pEditText
));
1999 pEditText
= pDoc
->GetEditText(ScAddress(1, 3, 0));
2000 CPPUNIT_ASSERT_MESSAGE("Incorrect B4 value after save and reload.",
2001 aCheckFunc
.checkB4(pEditText
));
2002 pEditText
= pDoc
->GetEditText(ScAddress(1, 4, 0));
2003 CPPUNIT_ASSERT_MESSAGE("Incorrect B5 value after save and reload.",
2004 aCheckFunc
.checkB5(pEditText
));
2005 pEditText
= pDoc
->GetEditText(ScAddress(1, 5, 0));
2006 CPPUNIT_ASSERT_MESSAGE("Incorrect B6 value after save and reload.",
2007 aCheckFunc
.checkB6(pEditText
));
2008 pEditText
= pDoc
->GetEditText(ScAddress(1, 6, 0));
2009 CPPUNIT_ASSERT_MESSAGE("Incorrect B7 value after save and reload.",
2010 aCheckFunc
.checkB7(pEditText
));
2011 pEditText
= pDoc
->GetEditText(ScAddress(1, 7, 0));
2012 CPPUNIT_ASSERT_MESSAGE("Incorrect B8 value after save and reload.",
2013 aCheckFunc
.checkB8(pEditText
));
2014 pEditText
= pDoc
->GetEditText(ScAddress(1, 9, 0));
2015 CPPUNIT_ASSERT_MESSAGE("Incorrect B10 value after save and reload.",
2016 aCheckFunc
.checkB10(pEditText
));
2019 void ScExportTest::testRichTextCellFormatXLSX()
2021 createScDoc("xls/cellformat.xls");
2023 save("Calc Office Open XML");
2024 xmlDocUniquePtr pSheet
= parseExport("xl/worksheets/sheet1.xml");
2025 CPPUNIT_ASSERT(pSheet
);
2027 // make sure the only cell in this doc is assigned some formatting record
2028 OUString aCellFormat
= getXPath(pSheet
, "/x:worksheet/x:sheetData/x:row/x:c", "s");
2029 CPPUNIT_ASSERT_MESSAGE("Cell format is missing", !aCellFormat
.isEmpty());
2031 xmlDocUniquePtr pStyles
= parseExport("xl/styles.xml");
2032 CPPUNIT_ASSERT(pStyles
);
2034 OString nFormatIdx
= OString::number(aCellFormat
.toInt32() + 1);
2035 const OString
aXPath1("/x:styleSheet/x:cellXfs/x:xf[" + nFormatIdx
+ "]/x:alignment");
2036 // formatting record is set to wrap text
2037 assertXPath(pStyles
, aXPath1
, "wrapText", "true");
2039 // see what font it references
2040 const OString
aXPath2("/x:styleSheet/x:cellXfs/x:xf[" + nFormatIdx
+ "]");
2041 OUString aFontId
= getXPath(pStyles
, aXPath2
, "fontId");
2042 OString nFontIdx
= OString::number(aFontId
.toInt32() + 1);
2044 // that font should be bold
2045 const OString
aXPath3("/x:styleSheet/x:fonts/x:font[" + nFontIdx
+ "]/x:b");
2046 assertXPath(pStyles
, aXPath3
, "val", "true");
2049 void ScExportTest::testFormulaRefSheetNameODS()
2051 createScDoc("ods/formula-quote-in-sheet-name.ods");
2053 ScDocument
* pDoc
= getScDoc();
2055 sc::AutoCalcSwitch
aACSwitch(*pDoc
, true); // turn on auto calc.
2056 pDoc
->SetString(ScAddress(1, 1, 0), "='90''s Data'.B2");
2057 CPPUNIT_ASSERT_EQUAL(1.1, pDoc
->GetValue(ScAddress(1, 1, 0)));
2058 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong formula", OUString("='90''s Data'.B2"),
2059 pDoc
->GetFormula(1, 1, 0));
2061 // Now, save and reload this document.
2062 saveAndReload("calc8");
2064 ScDocument
* pDoc
= getScDoc();
2066 CPPUNIT_ASSERT_EQUAL(1.1, pDoc
->GetValue(ScAddress(1, 1, 0)));
2067 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong formula", OUString("='90''s Data'.B2"),
2068 pDoc
->GetFormula(1, 1, 0));
2071 void ScExportTest::testCellValuesExportODS()
2073 // Start with an empty document
2076 ScDocument
* pDoc
= getScDoc();
2077 CPPUNIT_ASSERT_MESSAGE("This document should at least have one sheet.",
2078 pDoc
->GetTableCount() > 0);
2080 // set a value double
2081 pDoc
->SetValue(ScAddress(0, 0, 0), 2.0); // A1
2084 pDoc
->SetValue(ScAddress(2, 0, 0), 3.0); // C1
2085 pDoc
->SetValue(ScAddress(3, 0, 0), 3); // D1
2086 pDoc
->SetString(ScAddress(4, 0, 0), "=10*C1/4"); // E1
2087 pDoc
->SetValue(ScAddress(5, 0, 0), 3.0); // F1
2088 pDoc
->SetString(ScAddress(7, 0, 0), "=SUM(C1:F1)"); //H1
2091 pDoc
->SetString(ScAddress(0, 2, 0), "a simple line"); //A3
2093 // set a digit string
2094 pDoc
->SetString(ScAddress(0, 4, 0), "'12"); //A5
2095 // set a contiguous value
2096 pDoc
->SetValue(ScAddress(0, 5, 0), 12.0); //A6
2097 // set a contiguous string
2098 pDoc
->SetString(ScAddress(0, 6, 0), "a string"); //A7
2099 // set a contiguous formula
2100 pDoc
->SetString(ScAddress(0, 7, 0), "=$A$6"); //A8
2103 saveAndReload("calc8");
2104 ScDocument
* pDoc
= getScDoc();
2105 CPPUNIT_ASSERT_MESSAGE("Reloaded document should at least have one sheet.",
2106 pDoc
->GetTableCount() > 0);
2109 CPPUNIT_ASSERT_EQUAL(2.0, pDoc
->GetValue(0, 0, 0));
2110 CPPUNIT_ASSERT_EQUAL(3.0, pDoc
->GetValue(2, 0, 0));
2111 CPPUNIT_ASSERT_EQUAL(3.0, pDoc
->GetValue(3, 0, 0));
2112 CPPUNIT_ASSERT_EQUAL(7.5, pDoc
->GetValue(4, 0, 0));
2113 CPPUNIT_ASSERT_EQUAL(3.0, pDoc
->GetValue(5, 0, 0));
2116 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong formula =10*C1/4", OUString("=10*C1/4"),
2117 pDoc
->GetFormula(4, 0, 0));
2118 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong formula =SUM(C1:F1)", OUString("=SUM(C1:F1)"),
2119 pDoc
->GetFormula(7, 0, 0));
2120 CPPUNIT_ASSERT_EQUAL(16.5, pDoc
->GetValue(7, 0, 0));
2123 ScRefCellValue aCell
;
2124 aCell
.assign(*pDoc
, ScAddress(0, 2, 0));
2125 CPPUNIT_ASSERT_EQUAL(CELLTYPE_STRING
, aCell
.getType());
2127 // check for an empty cell
2128 aCell
.assign(*pDoc
, ScAddress(0, 3, 0));
2129 CPPUNIT_ASSERT_EQUAL(CELLTYPE_NONE
, aCell
.getType());
2131 // check a digit string
2132 aCell
.assign(*pDoc
, ScAddress(0, 4, 0));
2133 CPPUNIT_ASSERT_EQUAL(CELLTYPE_STRING
, aCell
.getType());
2135 //check contiguous values
2136 CPPUNIT_ASSERT_EQUAL(12.0, pDoc
->GetValue(0, 5, 0));
2137 CPPUNIT_ASSERT_EQUAL(OUString("a string"), pDoc
->GetString(0, 6, 0));
2138 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong formula =$A$6", OUString("=$A$6"),
2139 pDoc
->GetFormula(0, 7, 0));
2140 CPPUNIT_ASSERT_EQUAL(pDoc
->GetValue(0, 5, 0), pDoc
->GetValue(0, 7, 0));
2143 void ScExportTest::testCellNoteExportODS()
2145 createScDoc("ods/single-note.ods");
2146 ScAddress
aPos(0, 0, 0); // Start with A1.
2148 ScDocument
* pDoc
= getScDoc();
2150 CPPUNIT_ASSERT_MESSAGE("There should be a note at A1.", pDoc
->HasNote(aPos
));
2152 aPos
.IncRow(); // Move to A2.
2153 ScPostIt
* pNote
= pDoc
->GetOrCreateNote(aPos
);
2154 pNote
->SetText(aPos
, "Note One");
2155 pNote
->SetAuthor("Author One");
2156 CPPUNIT_ASSERT_MESSAGE("There should be a note at A2.", pDoc
->HasNote(aPos
));
2159 saveAndReload("calc8");
2160 ScDocument
* pDoc
= getScDoc();
2162 aPos
.SetRow(0); // Move back to A1.
2163 CPPUNIT_ASSERT_MESSAGE("There should be a note at A1.", pDoc
->HasNote(aPos
));
2164 aPos
.IncRow(); // Move to A2.
2165 CPPUNIT_ASSERT_MESSAGE("There should be a note at A2.", pDoc
->HasNote(aPos
));
2168 void ScExportTest::testCellNoteExportXLS()
2170 // Start with an empty document.s
2171 createScDoc("ods/notes-on-3-sheets.ods");
2173 ScDocument
* pDoc
= getScDoc();
2174 CPPUNIT_ASSERT_EQUAL_MESSAGE("This document should have 3 sheets.", SCTAB(3),
2175 pDoc
->GetTableCount());
2177 // Check note's presence.
2178 CPPUNIT_ASSERT(pDoc
->HasNote(ScAddress(0, 0, 0)));
2179 CPPUNIT_ASSERT(!pDoc
->HasNote(ScAddress(0, 1, 0)));
2180 CPPUNIT_ASSERT(!pDoc
->HasNote(ScAddress(0, 2, 0)));
2182 CPPUNIT_ASSERT(!pDoc
->HasNote(ScAddress(0, 0, 1)));
2183 CPPUNIT_ASSERT(pDoc
->HasNote(ScAddress(0, 1, 1)));
2184 CPPUNIT_ASSERT(!pDoc
->HasNote(ScAddress(0, 2, 1)));
2186 CPPUNIT_ASSERT(!pDoc
->HasNote(ScAddress(0, 0, 2)));
2187 CPPUNIT_ASSERT(!pDoc
->HasNote(ScAddress(0, 1, 2)));
2188 CPPUNIT_ASSERT(pDoc
->HasNote(ScAddress(0, 2, 2)));
2190 // save and reload as XLS.
2191 saveAndReload("MS Excel 97");
2193 ScDocument
* pDoc
= getScDoc();
2194 CPPUNIT_ASSERT_EQUAL_MESSAGE("This document should have 3 sheets.", SCTAB(3),
2195 pDoc
->GetTableCount());
2197 // Check note's presence again.
2198 CPPUNIT_ASSERT(pDoc
->HasNote(ScAddress(0, 0, 0)));
2199 CPPUNIT_ASSERT(!pDoc
->HasNote(ScAddress(0, 1, 0)));
2200 CPPUNIT_ASSERT(!pDoc
->HasNote(ScAddress(0, 2, 0)));
2202 CPPUNIT_ASSERT(!pDoc
->HasNote(ScAddress(0, 0, 1)));
2203 CPPUNIT_ASSERT(pDoc
->HasNote(ScAddress(0, 1, 1)));
2204 CPPUNIT_ASSERT(!pDoc
->HasNote(ScAddress(0, 2, 1)));
2206 CPPUNIT_ASSERT(!pDoc
->HasNote(ScAddress(0, 0, 2)));
2207 CPPUNIT_ASSERT(!pDoc
->HasNote(ScAddress(0, 1, 2)));
2208 CPPUNIT_ASSERT(pDoc
->HasNote(ScAddress(0, 2, 2)));
2214 void checkMatrixRange(ScDocument
& rDoc
, const ScRange
& rRange
)
2217 ScAddress aMatOrigin
;
2218 for (SCCOL nCol
= rRange
.aStart
.Col(); nCol
<= rRange
.aEnd
.Col(); ++nCol
)
2220 for (SCROW nRow
= rRange
.aStart
.Row(); nRow
<= rRange
.aEnd
.Row(); ++nRow
)
2222 ScAddress
aPos(nCol
, nRow
, rRange
.aStart
.Tab());
2223 bool bIsMatrix
= rDoc
.GetMatrixFormulaRange(aPos
, aMatRange
);
2224 CPPUNIT_ASSERT_MESSAGE("Matrix expected, but not found.", bIsMatrix
);
2225 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong matrix range.", rRange
, aMatRange
);
2226 const ScFormulaCell
* pCell
= rDoc
.GetFormulaCell(aPos
);
2227 CPPUNIT_ASSERT_MESSAGE("This must be a formula cell.", pCell
);
2229 bIsMatrix
= pCell
->GetMatrixOrigin(rDoc
, aMatOrigin
);
2230 CPPUNIT_ASSERT_MESSAGE("Not a part of matrix formula.", bIsMatrix
);
2231 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong matrix origin.", aMatRange
.aStart
, aMatOrigin
);
2237 void ScExportTest::testInlineArrayXLS()
2239 createScDoc("xls/inline-array.xls");
2241 saveAndReload("MS Excel 97");
2243 ScDocument
* pDoc
= getScDoc();
2245 // B2:C3 contains a matrix.
2246 checkMatrixRange(*pDoc
, ScRange(1, 1, 0, 2, 2, 0));
2248 // B5:D6 contains a matrix.
2249 checkMatrixRange(*pDoc
, ScRange(1, 4, 0, 3, 5, 0));
2252 checkMatrixRange(*pDoc
, ScRange(1, 7, 0, 2, 9, 0));
2255 void ScExportTest::testEmbeddedChartODS()
2257 createScDoc("xls/embedded-chart.xls");
2261 xmlDocUniquePtr pDoc
= parseExport("content.xml");
2262 CPPUNIT_ASSERT(pDoc
);
2264 "/office:document-content/office:body/office:spreadsheet/table:table[2]/"
2265 "table:table-row[7]/table:table-cell[2]/draw:frame/draw:object",
2266 "notify-on-update-of-ranges",
2267 "Chart1.B3:Chart1.B5 Chart1.C2:Chart1.C2 Chart1.C3:Chart1.C5");
2270 void ScExportTest::testEmbeddedChartXLS()
2272 createScDoc("xls/embedded-chart.xls");
2274 saveAndReload("MS Excel 97");
2276 ScDocument
* pDoc
= getScDoc();
2278 // Make sure the 2nd sheet is named 'Chart1'.
2280 pDoc
->GetName(1, aName
);
2281 CPPUNIT_ASSERT_EQUAL(OUString("Chart1"), aName
);
2283 const SdrOle2Obj
* pOleObj
= getSingleChartObject(*pDoc
, 1);
2284 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve a chart object from the 2nd sheet.", pOleObj
);
2286 ScRangeList aRanges
= getChartRanges(*pDoc
, *pOleObj
);
2287 CPPUNIT_ASSERT_MESSAGE("Label range (B3:B5) not found.",
2288 aRanges
.Contains(ScRange(1, 2, 1, 1, 4, 1)));
2289 CPPUNIT_ASSERT_MESSAGE("Data label (C2) not found.", aRanges
.Contains(ScAddress(2, 1, 1)));
2290 CPPUNIT_ASSERT_MESSAGE("Data range (C3:C5) not found.",
2291 aRanges
.Contains(ScRange(2, 2, 1, 2, 4, 1)));
2294 void ScExportTest::testCellAnchoredGroupXLS()
2296 createScDoc("xls/cell-anchored-group.xls");
2298 saveAndReload("calc8");
2300 // the document contains a group anchored on the first cell, make sure it's there in the right place
2301 ScDocument
* pDoc
= getScDoc();
2302 CPPUNIT_ASSERT_MESSAGE("There should be at least one sheet.", pDoc
->GetTableCount() > 0);
2303 ScDrawLayer
* pDrawLayer
= pDoc
->GetDrawLayer();
2304 SdrPage
* pPage
= pDrawLayer
->GetPage(0);
2305 CPPUNIT_ASSERT_MESSAGE("draw page for sheet 1 should exist.", pPage
);
2306 const size_t nCount
= pPage
->GetObjCount();
2307 CPPUNIT_ASSERT_EQUAL_MESSAGE("There should be 1 objects.", static_cast<size_t>(1), nCount
);
2309 SdrObject
* pObj
= pPage
->GetObj(0);
2310 CPPUNIT_ASSERT_MESSAGE("Failed to get drawing object.", pObj
);
2311 ScDrawObjData
* pData
= ScDrawLayer::GetObjData(pObj
);
2312 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve user data for this object.", pData
);
2313 CPPUNIT_ASSERT_MESSAGE("Upper left of bounding rectangle should be nonnegative.",
2314 pData
->getShapeRect().Left() >= 0 || pData
->getShapeRect().Top() >= 0);
2317 void ScExportTest::testFormulaReferenceXLS()
2319 createScDoc("xls/formula-reference.xls");
2321 saveAndReload("MS Excel 97");
2323 ScDocument
* pDoc
= getScDoc();
2325 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong formula in D2", OUString("=$A$2+$B$2+$C$2"),
2326 pDoc
->GetFormula(3, 1, 0));
2327 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong formula in D3", OUString("=A3+B3+C3"),
2328 pDoc
->GetFormula(3, 2, 0));
2329 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong formula in D6", OUString("=SUM($A$6:$C$6)"),
2330 pDoc
->GetFormula(3, 5, 0));
2331 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong formula in D7", OUString("=SUM(A7:C7)"),
2332 pDoc
->GetFormula(3, 6, 0));
2333 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong formula in D10", OUString("=$Two.$A$2+$Two.$B$2+$Two.$C$2"),
2334 pDoc
->GetFormula(3, 9, 0));
2335 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong formula in D11", OUString("=$Two.A3+$Two.B3+$Two.C3"),
2336 pDoc
->GetFormula(3, 10, 0));
2337 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong formula in D14", OUString("=MIN($Two.$A$2:$C$2)"),
2338 pDoc
->GetFormula(3, 13, 0));
2339 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong formula in D15", OUString("=MAX($Two.A3:C3)"),
2340 pDoc
->GetFormula(3, 14, 0));
2343 void ScExportTest::testSheetProtectionXLSX()
2345 createScDoc("xlsx/ProtecteSheet1234Pass.xlsx");
2347 saveAndReload("Calc Office Open XML");
2349 ScDocument
* pDoc
= getScDoc();
2350 const ScTableProtection
* pTabProtect
= pDoc
->GetTabProtection(0);
2351 CPPUNIT_ASSERT(pTabProtect
);
2352 Sequence
<sal_Int8
> aHash
= pTabProtect
->getPasswordHash(PASSHASH_XL
);
2354 if (aHash
.getLength() >= 2)
2356 CPPUNIT_ASSERT_EQUAL(sal_uInt8(204), static_cast<sal_uInt8
>(aHash
[0]));
2357 CPPUNIT_ASSERT_EQUAL(sal_uInt8(61), static_cast<sal_uInt8
>(aHash
[1]));
2359 // we could flesh out this check I guess
2360 CPPUNIT_ASSERT(!pTabProtect
->isOptionEnabled(ScTableProtection::OBJECTS
));
2361 CPPUNIT_ASSERT(!pTabProtect
->isOptionEnabled(ScTableProtection::SCENARIOS
));
2364 void ScExportTest::testSheetProtectionXLSB()
2366 createScDoc("xlsb/tdf108017_calcProtection.xlsb");
2368 saveAndReload("Calc Office Open XML");
2370 ScDocument
* pDoc
= getScDoc();
2371 const ScTableProtection
* pTabProtect
= pDoc
->GetTabProtection(0);
2372 CPPUNIT_ASSERT(pTabProtect
);
2373 CPPUNIT_ASSERT(pTabProtect
->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS
));
2374 CPPUNIT_ASSERT(!pTabProtect
->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS
));
2379 const char* toBorderName(SvxBorderLineStyle eStyle
)
2383 case SvxBorderLineStyle::SOLID
:
2385 case SvxBorderLineStyle::DOTTED
:
2387 case SvxBorderLineStyle::DASHED
:
2389 case SvxBorderLineStyle::DASH_DOT
:
2391 case SvxBorderLineStyle::DASH_DOT_DOT
:
2392 return "DASH_DOT_DOT";
2393 case SvxBorderLineStyle::DOUBLE_THIN
:
2394 return "DOUBLE_THIN";
2395 case SvxBorderLineStyle::FINE_DASHED
:
2396 return "FINE_DASHED";
2404 void ScExportTest::testExcelCellBorders(const OUString
& sFormatType
)
2409 SvxBorderLineStyle mnStyle
;
2410 tools::Long mnWidth
;
2412 { 1, SvxBorderLineStyle::SOLID
, 1 }, // hair
2413 { 3, SvxBorderLineStyle::DOTTED
, 15 }, // dotted
2414 { 5, SvxBorderLineStyle::DASH_DOT_DOT
, 15 }, // dash dot dot
2415 { 7, SvxBorderLineStyle::DASH_DOT
, 15 }, // dash dot
2416 { 9, SvxBorderLineStyle::FINE_DASHED
, 15 }, // dashed
2417 { 11, SvxBorderLineStyle::SOLID
, 15 }, // thin
2418 { 13, SvxBorderLineStyle::DASH_DOT_DOT
, 35 }, // medium dash dot dot
2419 { 17, SvxBorderLineStyle::DASH_DOT
, 35 }, // medium dash dot
2420 { 19, SvxBorderLineStyle::DASHED
, 35 }, // medium dashed
2421 { 21, SvxBorderLineStyle::SOLID
, 35 }, // medium
2422 { 23, SvxBorderLineStyle::SOLID
, 50 }, // thick
2423 { 25, SvxBorderLineStyle::DOUBLE_THIN
, -1 }, // double (don't check width)
2427 ScDocument
* pDoc
= getScDoc();
2429 for (size_t i
= 0; i
< SAL_N_ELEMENTS(aChecks
); ++i
)
2431 const editeng::SvxBorderLine
* pLine
= nullptr;
2432 pDoc
->GetBorderLines(2, aChecks
[i
].mnRow
, 0, nullptr, &pLine
, nullptr, nullptr);
2433 CPPUNIT_ASSERT(pLine
);
2434 CPPUNIT_ASSERT_EQUAL(toBorderName(aChecks
[i
].mnStyle
),
2435 toBorderName(pLine
->GetBorderLineStyle()));
2436 if (aChecks
[i
].mnWidth
>= 0)
2437 CPPUNIT_ASSERT_EQUAL(aChecks
[i
].mnWidth
, pLine
->GetWidth());
2441 saveAndReload(sFormatType
);
2442 ScDocument
* pDoc
= getScDoc();
2443 for (size_t i
= 0; i
< SAL_N_ELEMENTS(aChecks
); ++i
)
2445 const editeng::SvxBorderLine
* pLine
= nullptr;
2446 pDoc
->GetBorderLines(2, aChecks
[i
].mnRow
, 0, nullptr, &pLine
, nullptr, nullptr);
2447 CPPUNIT_ASSERT(pLine
);
2448 CPPUNIT_ASSERT_EQUAL(toBorderName(aChecks
[i
].mnStyle
),
2449 toBorderName(pLine
->GetBorderLineStyle()));
2450 if (aChecks
[i
].mnWidth
>= 0)
2451 CPPUNIT_ASSERT_EQUAL(aChecks
[i
].mnWidth
, pLine
->GetWidth());
2455 void ScExportTest::testCellBordersXLS()
2457 createScDoc("xls/cell-borders.xls");
2458 testExcelCellBorders("MS Excel 97");
2461 void ScExportTest::testCellBordersXLSX()
2463 createScDoc("xlsx/cell-borders.xlsx");
2464 testExcelCellBorders("Calc Office Open XML");
2467 void ScExportTest::testBordersExchangeXLSX()
2469 // Document: sc/qa/unit/data/README.cellborders
2471 // short name for the table
2472 const SvxBorderLineStyle None
= SvxBorderLineStyle::NONE
;
2473 const SvxBorderLineStyle Solid
= SvxBorderLineStyle::SOLID
;
2474 const SvxBorderLineStyle Dotted
= SvxBorderLineStyle::DOTTED
;
2475 const SvxBorderLineStyle Dashed
= SvxBorderLineStyle::DASHED
;
2476 const SvxBorderLineStyle FineDash
= SvxBorderLineStyle::FINE_DASHED
;
2477 const SvxBorderLineStyle DashDot
= SvxBorderLineStyle::DASH_DOT
;
2478 const SvxBorderLineStyle DashDoDo
= SvxBorderLineStyle::DASH_DOT_DOT
;
2479 const SvxBorderLineStyle DoubThin
= SvxBorderLineStyle::DOUBLE_THIN
;
2481 const size_t nMaxCol
= 18;
2482 const size_t nMaxRow
= 7;
2486 SvxBorderLineStyle BorderStyleTop
, BorderStyleBottom
;
2487 tools::Long WidthTop
, WidthBottom
;
2488 } aCheckBorderWidth
[nMaxCol
][nMaxRow
]
2490 /* 0,05 */ { { Solid
, Solid
, 1, 1 }, // SOLID
2491 { Dotted
, Dotted
, 15, 15 }, // DOTTED
2492 { Dotted
, Dotted
, 15, 15 }, // DASHED
2493 { FineDash
, FineDash
, 15, 15 }, // FINE_DASHED
2494 { FineDash
, FineDash
, 15, 15 }, // DASH_DOT
2495 { FineDash
, FineDash
, 15, 15 }, // DASH_DOT_DOT
2496 { None
, None
, 0, 0 } }, // DOUBLE_THIN
2498 { { Solid
, Solid
, 1, 1 },
2499 { Dotted
, Dotted
, 15, 15 },
2500 { Dotted
, Dotted
, 15, 15 },
2501 { FineDash
, FineDash
, 15, 15 },
2502 { FineDash
, FineDash
, 15, 15 },
2503 { FineDash
, FineDash
, 15, 15 },
2504 { None
, None
, 0, 0 } },
2506 { { Solid
, Solid
, 1, 1 },
2507 { Dotted
, Dotted
, 15, 15 },
2508 { Dotted
, Dotted
, 15, 15 },
2509 { FineDash
, FineDash
, 15, 15 },
2510 { FineDash
, FineDash
, 15, 15 },
2511 { FineDash
, FineDash
, 15, 15 },
2512 { None
, None
, 0, 0 } },
2514 { { Solid
, Solid
, 15, 15 },
2515 { Dotted
, Dotted
, 15, 15 },
2516 { FineDash
, FineDash
, 15, 15 },
2517 { FineDash
, FineDash
, 15, 15 },
2518 { DashDot
, DashDot
, 15, 15 },
2519 { DashDoDo
, DashDoDo
, 15, 15 },
2520 { DoubThin
, DoubThin
, 35, 35 } },
2522 { { Solid
, Solid
, 15, 15 },
2523 { Dotted
, Dotted
, 15, 15 },
2524 { FineDash
, FineDash
, 15, 15 },
2525 { FineDash
, FineDash
, 15, 15 },
2526 { DashDot
, DashDot
, 15, 15 },
2527 { DashDoDo
, DashDoDo
, 15, 15 },
2528 { DoubThin
, DoubThin
, 35, 35 } },
2530 { { Solid
, Solid
, 15, 15 },
2531 { Dotted
, Dotted
, 15, 15 },
2532 { FineDash
, FineDash
, 15, 15 },
2533 { FineDash
, FineDash
, 15, 15 },
2534 { DashDot
, DashDot
, 15, 15 },
2535 { DashDoDo
, DashDoDo
, 15, 15 },
2536 { DoubThin
, DoubThin
, 35, 35 } },
2538 { { Solid
, Solid
, 15, 15 },
2539 { Dotted
, Dotted
, 15, 15 },
2540 { FineDash
, FineDash
, 15, 15 },
2541 { FineDash
, FineDash
, 15, 15 },
2542 { DashDot
, DashDot
, 15, 15 },
2543 { DashDoDo
, DashDoDo
, 15, 15 },
2544 { DoubThin
, DoubThin
, 35, 35 } },
2547 { { Solid
, Solid
, 35, 35 },
2548 { FineDash
, FineDash
, 35, 35 },
2549 { Dashed
, Dashed
, 35, 35 },
2550 { FineDash
, FineDash
, 35, 35 },
2551 { DashDot
, DashDot
, 35, 35 },
2552 { DashDoDo
, DashDoDo
, 35, 35 },
2553 { DoubThin
, DoubThin
, 35, 35 } },
2555 { { Solid
, Solid
, 35, 35 },
2556 { FineDash
, FineDash
, 35, 35 },
2557 { Dashed
, Dashed
, 35, 35 },
2558 { FineDash
, FineDash
, 35, 35 },
2559 { DashDot
, DashDot
, 35, 35 },
2560 { DashDoDo
, DashDoDo
, 35, 35 },
2561 { DoubThin
, DoubThin
, 35, 35 } },
2563 { { Solid
, Solid
, 35, 35 },
2564 { FineDash
, FineDash
, 35, 35 },
2565 { Dashed
, Dashed
, 35, 35 },
2566 { FineDash
, FineDash
, 35, 35 },
2567 { DashDot
, DashDot
, 35, 35 },
2568 { DashDoDo
, DashDoDo
, 35, 35 },
2569 { DoubThin
, DoubThin
, 35, 35 } },
2572 { { Solid
, Solid
, 50, 50 },
2573 { FineDash
, FineDash
, 35, 35 },
2574 { Dashed
, Dashed
, 35, 35 },
2575 { FineDash
, FineDash
, 35, 35 },
2576 { DashDot
, DashDot
, 35, 35 },
2577 { DashDoDo
, DashDoDo
, 35, 35 },
2578 { DoubThin
, DoubThin
, 35, 35 } },
2580 { { Solid
, Solid
, 50, 50 },
2581 { FineDash
, FineDash
, 35, 35 },
2582 { Dashed
, Dashed
, 35, 35 },
2583 { FineDash
, FineDash
, 35, 35 },
2584 { DashDot
, DashDot
, 35, 35 },
2585 { DashDoDo
, DashDoDo
, 35, 35 },
2586 { DoubThin
, DoubThin
, 35, 35 } },
2588 { { Solid
, Solid
, 50, 50 },
2589 { FineDash
, FineDash
, 35, 35 },
2590 { Dashed
, Dashed
, 35, 35 },
2591 { FineDash
, FineDash
, 35, 35 },
2592 { DashDot
, DashDot
, 35, 35 },
2593 { DashDoDo
, DashDoDo
, 35, 35 },
2594 { DoubThin
, DoubThin
, 35, 35 } },
2596 { { Solid
, Solid
, 50, 50 },
2597 { FineDash
, FineDash
, 35, 35 },
2598 { Dashed
, Dashed
, 35, 35 },
2599 { FineDash
, FineDash
, 35, 35 },
2600 { DashDot
, DashDot
, 35, 35 },
2601 { DashDoDo
, DashDoDo
, 35, 35 },
2602 { DoubThin
, DoubThin
, 35, 35 } },
2604 { { Solid
, Solid
, 50, 50 },
2605 { FineDash
, FineDash
, 35, 35 },
2606 { Dashed
, Dashed
, 35, 35 },
2607 { FineDash
, FineDash
, 35, 35 },
2608 { DashDot
, DashDot
, 35, 35 },
2609 { DashDoDo
, DashDoDo
, 35, 35 },
2610 { DoubThin
, DoubThin
, 35, 35 } },
2612 { { Solid
, Solid
, 50, 50 },
2613 { FineDash
, FineDash
, 35, 35 },
2614 { Dashed
, Dashed
, 35, 35 },
2615 { FineDash
, FineDash
, 35, 35 },
2616 { DashDot
, DashDot
, 35, 35 },
2617 { DashDoDo
, DashDoDo
, 35, 35 },
2618 { DoubThin
, DoubThin
, 35, 35 } },
2620 { { Solid
, Solid
, 50, 50 },
2621 { FineDash
, FineDash
, 35, 35 },
2622 { Dashed
, Dashed
, 35, 35 },
2623 { FineDash
, FineDash
, 35, 35 },
2624 { DashDot
, DashDot
, 35, 35 },
2625 { DashDoDo
, DashDoDo
, 35, 35 },
2626 { DoubThin
, DoubThin
, 35, 35 } },
2628 { { Solid
, Solid
, 50, 50 },
2629 { FineDash
, FineDash
, 35, 35 },
2630 { Dashed
, Dashed
, 35, 35 },
2631 { FineDash
, FineDash
, 35, 35 },
2632 { DashDot
, DashDot
, 35, 35 },
2633 { DashDoDo
, DashDoDo
, 35, 35 },
2634 { DoubThin
, DoubThin
, 35, 35 } }
2637 createScDoc("ods/test_borders_export.ods");
2639 saveAndReload("Calc Office Open XML");
2640 ScDocument
* pDoc
= getScDoc();
2642 for (size_t nCol
= 0; nCol
< nMaxCol
; ++nCol
)
2644 for (size_t nRow
= 0; nRow
< nMaxRow
; ++nRow
)
2646 const editeng::SvxBorderLine
* pLineTop
= nullptr;
2647 const editeng::SvxBorderLine
* pLineBottom
= nullptr;
2648 pDoc
->GetBorderLines(nCol
+ 2, (nRow
* 2) + 8, 0, nullptr, &pLineTop
, nullptr,
2650 if ((nCol
< 3) && (nRow
== 6))
2651 { // in this range no lines since minimum size to create a double is 0.5
2652 CPPUNIT_ASSERT(!pLineTop
);
2653 CPPUNIT_ASSERT(!pLineBottom
);
2658 CPPUNIT_ASSERT(pLineTop
);
2659 CPPUNIT_ASSERT(pLineBottom
);
2662 CPPUNIT_ASSERT_EQUAL_MESSAGE("Top Border-Line-Style wrong",
2663 aCheckBorderWidth
[nCol
][nRow
].BorderStyleTop
,
2664 pLineTop
->GetBorderLineStyle());
2665 CPPUNIT_ASSERT_EQUAL_MESSAGE("Bottom Border-Line-Style wrong",
2666 aCheckBorderWidth
[nCol
][nRow
].BorderStyleBottom
,
2667 pLineBottom
->GetBorderLineStyle());
2668 CPPUNIT_ASSERT_EQUAL_MESSAGE("Top Width-Line wrong",
2669 aCheckBorderWidth
[nCol
][nRow
].WidthTop
,
2670 pLineTop
->GetWidth());
2671 CPPUNIT_ASSERT_EQUAL_MESSAGE("Bottom Width-Line wrong",
2672 aCheckBorderWidth
[nCol
][nRow
].WidthBottom
,
2673 pLineBottom
->GetWidth());
2678 static OUString
toString(const ScBigRange
& rRange
)
2680 OUStringBuffer aBuf
;
2681 aBuf
.append("(columns:");
2682 aBuf
.append(rRange
.aStart
.Col());
2684 aBuf
.append(rRange
.aEnd
.Col());
2685 aBuf
.append(";rows:");
2686 aBuf
.append(rRange
.aStart
.Row());
2688 aBuf
.append(rRange
.aEnd
.Row());
2689 aBuf
.append(";sheets:");
2690 aBuf
.append(rRange
.aStart
.Tab());
2692 aBuf
.append(rRange
.aEnd
.Tab());
2695 return aBuf
.makeStringAndClear();
2698 void ScExportTest::testTrackChangesSimpleXLSX()
2702 sal_uLong mnActionId
;
2703 ScChangeActionType meType
;
2705 sal_Int32 mnStartCol
;
2706 sal_Int32 mnStartRow
;
2707 sal_Int32 mnStartTab
;
2712 bool mbRowInsertedAtBottom
;
2717 bool checkRange(ScChangeActionType eType
, const ScBigRange
& rExpected
,
2718 const ScBigRange
& rActual
)
2720 ScBigRange
aExpected(rExpected
), aActual(rActual
);
2724 case SC_CAT_INSERT_ROWS
:
2727 aExpected
.aStart
.SetCol(0);
2728 aExpected
.aEnd
.SetCol(0);
2729 aActual
.aStart
.SetCol(0);
2730 aActual
.aEnd
.SetCol(0);
2736 return aExpected
== aActual
;
2739 bool check(ScDocument
& rDoc
)
2741 static const CheckItem aChecks
[] = {
2742 { 1, SC_CAT_CONTENT
, 1, 1, 0, 1, 1, 0, false },
2743 { 2, SC_CAT_INSERT_ROWS
, 0, 2, 0, 0, 2, 0, true },
2744 { 3, SC_CAT_CONTENT
, 1, 2, 0, 1, 2, 0, false },
2745 { 4, SC_CAT_INSERT_ROWS
, 0, 3, 0, 0, 3, 0, true },
2746 { 5, SC_CAT_CONTENT
, 1, 3, 0, 1, 3, 0, false },
2747 { 6, SC_CAT_INSERT_ROWS
, 0, 4, 0, 0, 4, 0, true },
2748 { 7, SC_CAT_CONTENT
, 1, 4, 0, 1, 4, 0, false },
2749 { 8, SC_CAT_INSERT_ROWS
, 0, 5, 0, 0, 5, 0, true },
2750 { 9, SC_CAT_CONTENT
, 1, 5, 0, 1, 5, 0, false },
2751 { 10, SC_CAT_INSERT_ROWS
, 0, 6, 0, 0, 6, 0, true },
2752 { 11, SC_CAT_CONTENT
, 1, 6, 0, 1, 6, 0, false },
2753 { 12, SC_CAT_INSERT_ROWS
, 0, 7, 0, 0, 7, 0, true },
2754 { 13, SC_CAT_CONTENT
, 1, 7, 0, 1, 7, 0, false },
2757 ScChangeTrack
* pCT
= rDoc
.GetChangeTrack();
2760 cerr
<< "Change track instance doesn't exist." << endl
;
2764 sal_uLong nActionMax
= pCT
->GetActionMax();
2765 if (nActionMax
!= 13)
2767 cerr
<< "Unexpected highest action ID value." << endl
;
2771 for (size_t i
= 0; i
< SAL_N_ELEMENTS(aChecks
); ++i
)
2773 sal_uInt16 nActId
= aChecks
[i
].mnActionId
;
2774 const ScChangeAction
* pAction
= pCT
->GetAction(nActId
);
2777 cerr
<< "No action for action number " << nActId
<< " found." << endl
;
2781 if (pAction
->GetType() != aChecks
[i
].meType
)
2783 cerr
<< "Unexpected action type for action number " << nActId
<< "." << endl
;
2787 const ScBigRange
& rRange
= pAction
->GetBigRange();
2788 ScBigRange
aCheck(aChecks
[i
].mnStartCol
, aChecks
[i
].mnStartRow
,
2789 aChecks
[i
].mnStartTab
, aChecks
[i
].mnEndCol
, aChecks
[i
].mnEndRow
,
2790 aChecks
[i
].mnEndTab
);
2792 if (!checkRange(pAction
->GetType(), aCheck
, rRange
))
2794 cerr
<< "Unexpected range for action number " << nActId
2795 << ": expected=" << toString(aCheck
) << " actual=" << toString(rRange
)
2800 switch (pAction
->GetType())
2802 case SC_CAT_INSERT_ROWS
:
2804 const ScChangeActionIns
* p
= static_cast<const ScChangeActionIns
*>(pAction
);
2805 if (p
->IsEndOfList() != aChecks
[i
].mbRowInsertedAtBottom
)
2807 cerr
<< "Unexpected end-of-list flag for action number " << nActId
2820 bool checkRevisionUserAndTime(ScDocument
& rDoc
, std::u16string_view rOwnerName
)
2822 ScChangeTrack
* pCT
= rDoc
.GetChangeTrack();
2825 cerr
<< "Change track instance doesn't exist." << endl
;
2829 ScChangeAction
* pAction
= pCT
->GetLast();
2830 if (pAction
->GetUser() != "Kohei Yoshida")
2832 cerr
<< "Wrong user name." << endl
;
2836 DateTime aDT
= pAction
->GetDateTime();
2837 if (aDT
.GetYear() != 2014 || aDT
.GetMonth() != 7 || aDT
.GetDay() != 11)
2839 cerr
<< "Wrong time stamp." << endl
;
2843 // Insert a new record to make sure the user and date-time are correct.
2844 rDoc
.SetString(ScAddress(1, 8, 0), "New String");
2846 pCT
->AppendContent(ScAddress(1, 8, 0), aEmpty
);
2847 pAction
= pCT
->GetLast();
2850 cerr
<< "Failed to retrieve last revision." << endl
;
2854 if (rOwnerName
!= pAction
->GetUser())
2856 cerr
<< "Wrong user name." << endl
;
2860 DateTime aDTNew
= pAction
->GetDateTime();
2863 cerr
<< "Time stamp of the new revision should be more recent than that of the "
2874 SvtUserOptions
& rUserOpt
= SC_MOD()->GetUserOptions();
2875 rUserOpt
.SetToken(UserOptToken::FirstName
, "Export");
2876 rUserOpt
.SetToken(UserOptToken::LastName
, "Test");
2878 OUString aOwnerName
= rUserOpt
.GetFirstName() + " " + rUserOpt
.GetLastName();
2880 // First, test the xls variant.
2882 createScDoc("xls/track-changes/simple-cell-changes.xls");
2883 ScDocument
* pDoc
= getScDoc();
2884 bool bGood
= aTest
.check(*pDoc
);
2885 CPPUNIT_ASSERT_MESSAGE("Initial check failed (xls).", bGood
);
2887 saveAndReload("MS Excel 97");
2889 bGood
= aTest
.check(*pDoc
);
2890 CPPUNIT_ASSERT_MESSAGE("Check after reload failed (xls).", bGood
);
2892 // fdo#81445 : Check the blank value string to make sure it's "<empty>".
2893 ScChangeTrack
* pCT
= pDoc
->GetChangeTrack();
2894 CPPUNIT_ASSERT(pCT
);
2895 ScChangeAction
* pAction
= pCT
->GetAction(1);
2896 CPPUNIT_ASSERT(pAction
);
2897 OUString aDesc
= pAction
->GetDescription(*pDoc
);
2898 CPPUNIT_ASSERT_EQUAL(OUString("Cell B2 changed from '<empty>' to '1'"), aDesc
);
2901 bGood
= aTest
.checkRevisionUserAndTime(*pDoc
, aOwnerName
);
2902 CPPUNIT_ASSERT_MESSAGE("Check revision and time failed after reload (xls).", bGood
);
2904 // Now, test the xlsx variant the same way.
2906 createScDoc("xlsx/track-changes/simple-cell-changes.xlsx");
2909 CPPUNIT_ASSERT_MESSAGE("Initial check failed (xlsx).", bGood
);
2911 saveAndReload("Calc Office Open XML");
2913 bGood
= aTest
.check(*pDoc
);
2914 CPPUNIT_ASSERT_MESSAGE("Check after reload failed (xlsx).", bGood
);
2916 bGood
= aTest
.checkRevisionUserAndTime(*pDoc
, aOwnerName
);
2917 CPPUNIT_ASSERT_MESSAGE("Check revision and time failed after reload (xlsx).", bGood
);
2920 void ScExportTest::testSheetTabColorsXLSX()
2924 bool checkContent(ScDocument
& rDoc
)
2926 std::vector
<OUString
> aTabNames
= rDoc
.GetAllTableNames();
2928 // green, red, blue, yellow (from left to right).
2929 if (aTabNames
.size() != 4)
2931 cerr
<< "There should be exactly 4 sheets." << endl
;
2935 const char* pNames
[] = { "Green", "Red", "Blue", "Yellow" };
2936 for (size_t i
= 0; i
< SAL_N_ELEMENTS(pNames
); ++i
)
2938 OUString aExpected
= OUString::createFromAscii(pNames
[i
]);
2939 if (aExpected
!= aTabNames
[i
])
2941 cerr
<< "incorrect sheet name: expected='" << aExpected
<< "', actual='"
2942 << aTabNames
[i
] << "'" << endl
;
2947 static const Color aXclColors
[] = {
2948 0x0000B050, // green
2951 0x00FFFF00, // yellow
2954 for (size_t i
= 0; i
< SAL_N_ELEMENTS(aXclColors
); ++i
)
2956 if (aXclColors
[i
] != rDoc
.GetTabBgColor(i
))
2958 cerr
<< "wrong sheet color for sheet " << i
<< endl
;
2968 createScDoc("xlsx/sheet-tab-color.xlsx");
2970 ScDocument
* pDoc
= getScDoc();
2971 bool bRes
= aTest
.checkContent(*pDoc
);
2972 CPPUNIT_ASSERT_MESSAGE("Failed on the initial content check.", bRes
);
2975 saveAndReload("Calc Office Open XML");
2976 ScDocument
* pDoc
= getScDoc();
2977 bool bRes
= aTest
.checkContent(*pDoc
);
2978 CPPUNIT_ASSERT_MESSAGE("Failed on the content check after reload.", bRes
);
2981 void ScExportTest::testTdf133487()
2983 createScDoc("fods/shapes_foreground_background.fods");
2986 xmlDocUniquePtr pXmlDoc
= parseExport("content.xml");
2987 CPPUNIT_ASSERT(pXmlDoc
);
2989 // shape in background has lowest index
2990 assertXPath(pXmlDoc
,
2991 "/office:document-content/office:body/office:spreadsheet/table:table[1]/"
2992 "table:table-row[1]/table:table-cell[1]/draw:custom-shape",
2994 assertXPath(pXmlDoc
,
2995 "/office:document-content/office:body/office:spreadsheet/table:table[1]/"
2996 "table:table-row[1]/table:table-cell[1]/draw:custom-shape"
2997 "/attribute::table:table-background",
2999 assertXPath(pXmlDoc
,
3000 "/office:document-content/office:body/office:spreadsheet/table:table[1]/"
3001 "table:table-row[1]/table:table-cell[1]/draw:custom-shape",
3002 "table-background", "true");
3003 // shape in foreground, previously index 1
3004 assertXPath(pXmlDoc
,
3005 "/office:document-content/office:body/office:spreadsheet/table:table[1]/"
3006 "table:table-row[1]/table:table-cell[2]/draw:custom-shape",
3008 // attribute is only written for value "true"
3009 assertXPath(pXmlDoc
,
3010 "/office:document-content/office:body/office:spreadsheet/table:table[1]/"
3011 "table:table-row[1]/table:table-cell[2]/draw:custom-shape"
3012 "/attribute::table:table-background",
3014 // shape in foreground, previously index 0
3015 assertXPath(pXmlDoc
,
3016 "/office:document-content/office:body/office:spreadsheet/table:table[1]/"
3017 "table:table-row[3]/table:table-cell[1]/draw:custom-shape",
3019 // attribute is only written for value "true"
3020 assertXPath(pXmlDoc
,
3021 "/office:document-content/office:body/office:spreadsheet/table:table[1]/"
3022 "table:table-row[3]/table:table-cell[1]/draw:custom-shape"
3023 "/attribute::table:table-background",
3025 // shape in foreground, previously index 4
3026 assertXPath(pXmlDoc
,
3027 "/office:document-content/office:body/office:spreadsheet/table:table[1]/"
3028 "table:shapes/draw:custom-shape",
3030 // attribute is only written for value "true"
3031 assertXPath(pXmlDoc
,
3032 "/office:document-content/office:body/office:spreadsheet/table:table[1]/"
3033 "table:shapes/draw:custom-shape"
3034 "/attribute::table:table-background",
3036 // form control, previously index 3
3037 assertXPath(pXmlDoc
,
3038 "/office:document-content/office:body/office:spreadsheet/table:table[1]/"
3039 "table:shapes/draw:control",
3041 // attribute is only written for value "true"
3042 assertXPath(pXmlDoc
,
3043 "/office:document-content/office:body/office:spreadsheet/table:table[1]/"
3044 "table:shapes/draw:control"
3045 "/attribute::table:table-background",
3049 void ScExportTest::testSharedFormulaExportXLS()
3053 bool checkContent(ScDocument
& rDoc
)
3055 formula::FormulaGrammar::Grammar eGram
= formula::FormulaGrammar::GRAM_ENGLISH_XL_R1C1
;
3056 rDoc
.SetGrammar(eGram
);
3057 sc::TokenStringContext
aCxt(rDoc
, eGram
);
3059 // Check the title row.
3061 OUString aActual
= rDoc
.GetString(0, 1, 0);
3062 OUString aExpected
= "Response";
3063 if (aActual
!= aExpected
)
3065 cerr
<< "Wrong content in A2: expected='" << aExpected
<< "', actual='" << aActual
3070 aActual
= rDoc
.GetString(1, 1, 0);
3071 aExpected
= "Response";
3072 if (aActual
!= aExpected
)
3074 cerr
<< "Wrong content in B2: expected='" << aExpected
<< "', actual='" << aActual
3079 // A3:A12 and B3:B12 are numbers from 1 to 10.
3080 for (SCROW i
= 0; i
<= 9; ++i
)
3082 double fExpected
= i
+ 1.0;
3083 ScAddress
aPos(0, i
+ 2, 0);
3084 double fActual
= rDoc
.GetValue(aPos
);
3085 if (fExpected
!= fActual
)
3087 cerr
<< "Wrong value in A" << (i
+ 2) << ": expected=" << fExpected
3088 << ", actual=" << fActual
<< endl
;
3093 ScFormulaCell
* pFC
= rDoc
.GetFormulaCell(aPos
);
3096 cerr
<< "B" << (i
+ 2) << " should be a formula cell." << endl
;
3100 OUString aFormula
= pFC
->GetCode()->CreateString(aCxt
, aPos
);
3101 aExpected
= "Coefficients!RC[-1]";
3102 if (aFormula
!= aExpected
)
3104 cerr
<< "Wrong formula in B" << (i
+ 2) << ": expected='" << aExpected
3105 << "', actual='" << aFormula
<< "'" << endl
;
3109 fActual
= rDoc
.GetValue(aPos
);
3110 if (fExpected
!= fActual
)
3112 cerr
<< "Wrong value in B" << (i
+ 2) << ": expected=" << fExpected
3113 << ", actual=" << fActual
<< endl
;
3123 createScDoc("ods/shared-formula/3d-reference.ods");
3125 // Check the content of the original.
3126 ScDocument
* pDoc
= getScDoc();
3127 bool bRes
= aTest
.checkContent(*pDoc
);
3128 CPPUNIT_ASSERT_MESSAGE("Content check on the original document failed.", bRes
);
3131 saveAndReload("MS Excel 97");
3133 // Check the content of the reloaded. This should be identical.
3134 ScDocument
* pDoc
= getScDoc();
3135 bool bRes
= aTest
.checkContent(*pDoc
);
3136 CPPUNIT_ASSERT_MESSAGE("Content check on the reloaded document failed.", bRes
);
3139 void ScExportTest::testSharedFormulaExportXLSX()
3143 bool checkContent(ScDocument
& rDoc
)
3145 SCTAB nTabCount
= rDoc
.GetTableCount();
3148 cerr
<< "Document should have exactly 2 sheets. " << nTabCount
<< " found."
3153 // Make sure the sheet tab colors are not set.
3154 for (SCROW i
= 0; i
<= 1; ++i
)
3156 Color aTabBgColor
= rDoc
.GetTabBgColor(i
);
3157 if (aTabBgColor
!= COL_AUTO
)
3159 cerr
<< "The tab color of Sheet " << (i
+ 1) << " should not be explicitly set."
3165 // B2:B7 should show 1,2,3,4,5,6.
3166 double fExpected
= 1.0;
3167 for (SCROW i
= 1; i
<= 6; ++i
, ++fExpected
)
3169 ScAddress
aPos(1, i
, 0);
3170 double fVal
= rDoc
.GetValue(aPos
);
3171 if (fVal
!= fExpected
)
3173 cerr
<< "Wrong value in B" << (i
+ 1) << ": expected=" << fExpected
3174 << ", actual=" << fVal
<< endl
;
3179 // C2:C7 should show 10,20,...,60.
3181 for (SCROW i
= 1; i
<= 6; ++i
, fExpected
+= 10.0)
3183 ScAddress
aPos(2, i
, 0);
3184 double fVal
= rDoc
.GetValue(aPos
);
3185 if (fVal
!= fExpected
)
3187 cerr
<< "Wrong value in C" << (i
+ 1) << ": expected=" << fExpected
3188 << ", actual=" << fVal
<< endl
;
3193 // D2:D7 should show 1,2,...,6.
3195 for (SCROW i
= 1; i
<= 6; ++i
, ++fExpected
)
3197 ScAddress
aPos(3, i
, 0);
3198 double fVal
= rDoc
.GetValue(aPos
);
3199 if (fVal
!= fExpected
)
3201 cerr
<< "Wrong value in D" << (i
+ 1) << ": expected=" << fExpected
3202 << ", actual=" << fVal
<< endl
;
3212 createScDoc("xlsx/shared-formula/3d-reference.xlsx");
3214 ScDocument
* pDoc
= getScDoc();
3215 bool bRes
= aTest
.checkContent(*pDoc
);
3216 CPPUNIT_ASSERT_MESSAGE("Content check on the initial document failed.", bRes
);
3218 pDoc
->CalcAll(); // Recalculate to flush all cached results.
3219 bRes
= aTest
.checkContent(*pDoc
);
3220 CPPUNIT_ASSERT_MESSAGE("Content check on the initial recalculated document failed.", bRes
);
3223 // Save and reload, and check the content again.
3224 saveAndReload("Calc Office Open XML");
3226 ScDocument
* pDoc
= getScDoc();
3227 pDoc
->CalcAll(); // Recalculate to flush all cached results.
3229 bool bRes
= aTest
.checkContent(*pDoc
);
3230 CPPUNIT_ASSERT_MESSAGE("Content check on the reloaded document failed.", bRes
);
3233 void ScExportTest::testSharedFormulaStringResultExportXLSX()
3237 bool checkContent(ScDocument
& rDoc
)
3240 // B2:B7 should show A,B,...,F.
3241 const char* const expected
[] = { "A", "B", "C", "D", "E", "F" };
3242 for (SCROW i
= 0; i
<= 5; ++i
)
3244 ScAddress
aPos(1, i
+ 1, 0);
3245 OUString aStr
= rDoc
.GetString(aPos
);
3246 OUString aExpected
= OUString::createFromAscii(expected
[i
]);
3247 if (aStr
!= aExpected
)
3249 cerr
<< "Wrong value in B" << (i
+ 2) << ": expected='" << aExpected
3250 << "', actual='" << aStr
<< "'" << endl
;
3257 // C2:C7 should show AA,BB,...,FF.
3258 const char* const expected
[] = { "AA", "BB", "CC", "DD", "EE", "FF" };
3259 for (SCROW i
= 0; i
<= 5; ++i
)
3261 ScAddress
aPos(2, i
+ 1, 0);
3262 OUString aStr
= rDoc
.GetString(aPos
);
3263 OUString aExpected
= OUString::createFromAscii(expected
[i
]);
3264 if (aStr
!= aExpected
)
3266 cerr
<< "Wrong value in C" << (i
+ 2) << ": expected='" << aExpected
3267 << "', actual='" << aStr
<< "'" << endl
;
3278 createScDoc("xlsx/shared-formula/text-results.xlsx");
3280 ScDocument
* pDoc
= getScDoc();
3282 // Check content without re-calculation, to test cached formula results.
3283 bool bRes
= aTest
.checkContent(*pDoc
);
3284 CPPUNIT_ASSERT_MESSAGE("Content check on the initial document failed.", bRes
);
3286 // Now, re-calculate and check the results.
3288 bRes
= aTest
.checkContent(*pDoc
);
3289 CPPUNIT_ASSERT_MESSAGE("Content check on the initial recalculated document failed.", bRes
);
3291 // Reload and check again.
3292 saveAndReload("Calc Office Open XML");
3293 ScDocument
* pDoc
= getScDoc();
3295 bool bRes
= aTest
.checkContent(*pDoc
);
3296 CPPUNIT_ASSERT_MESSAGE("Content check on the reloaded document failed.", bRes
);
3299 void ScExportTest::testFunctionsExcel2010(const OUString
& sFormatType
)
3301 createScDoc("xlsx/functions-excel-2010.xlsx");
3303 saveAndReload(sFormatType
);
3304 ScDocument
* pDoc
= getScDoc();
3305 pDoc
->CalcAll(); // perform hard re-calculation.
3307 testFunctionsExcel2010_Impl(*pDoc
);
3310 void ScExportTest::testFunctionsExcel2010XLSX() { testFunctionsExcel2010("Calc Office Open XML"); }
3312 void ScExportTest::testFunctionsExcel2010XLS() { testFunctionsExcel2010("MS Excel 97"); }
3314 void ScExportTest::testCeilingFloor(const OUString
& sFormatType
)
3316 createScDoc("xlsx/ceiling-floor.xlsx");
3318 saveAndReload(sFormatType
);
3319 ScDocument
* pDoc
= getScDoc();
3320 pDoc
->CalcAll(); // perform hard re-calculation.
3322 testCeilingFloor_Impl(*pDoc
);
3325 void ScExportTest::testCeilingFloorXLSX() { testCeilingFloor("Calc Office Open XML"); }
3327 void ScExportTest::testCeilingFloorODSToXLSX()
3329 // tdf#100011 - Cannot open sheet containing FLOOR/CEILING functions by MS Excel, after export to .xlsx
3330 createScDoc("ods/ceiling-floor.ods");
3332 save("Calc Office Open XML");
3333 xmlDocUniquePtr pSheet
= parseExport("xl/workbook.xml");
3334 CPPUNIT_ASSERT(pSheet
);
3336 // there shouldn't be any defined names during export of FLOOR and CEILING functions to .xlsx
3337 assertXPath(pSheet
, "/x:workbook/x:definedNames", 0);
3340 void ScExportTest::testCeilingFloorXLS() { testCeilingFloor("MS Excel 97"); }
3342 void ScExportTest::testCeilingFloorODS() { testCeilingFloor("calc8"); }
3344 void ScExportTest::testCustomXml()
3346 // Load document and export it to a temporary file
3347 createScDoc("xlsx/customxml.xlsx");
3349 save("Calc Office Open XML");
3350 xmlDocUniquePtr pXmlDoc
= parseExport("customXml/item1.xml");
3351 CPPUNIT_ASSERT(pXmlDoc
);
3352 xmlDocUniquePtr pRelsDoc
= parseExport("customXml/_rels/item1.xml.rels");
3353 CPPUNIT_ASSERT(pRelsDoc
);
3355 // Check there is a relation to itemProps1.xml.
3356 assertXPath(pRelsDoc
, "/rels:Relationships/rels:Relationship", 1);
3357 assertXPath(pRelsDoc
, "/rels:Relationships/rels:Relationship[@Id='rId1']", "Target",
3360 std::unique_ptr
<SvStream
> pStream
= parseExportStream(maTempFile
.GetURL(), "ddp/ddpfile.xen");
3361 CPPUNIT_ASSERT(pStream
);
3365 static sal_Unicode
lcl_getWindowsDrive(const OUString
& aURL
)
3367 static const sal_Int32 nMinLen
= strlen("file:///X:/");
3368 if (aURL
.getLength() <= nMinLen
)
3370 const OUString aUrlStart
= aURL
.copy(0, nMinLen
);
3371 return (aUrlStart
.startsWith("file:///") && aUrlStart
.endsWith(":/")) ? aUrlStart
[8] : 0;
3375 void ScExportTest::testRelativePathsODS()
3377 createScDoc("ods/fdo79305.ods");
3380 xmlDocUniquePtr pDoc
= parseExport("content.xml");
3381 CPPUNIT_ASSERT(pDoc
);
3382 OUString aURL
= getXPath(pDoc
,
3383 "/office:document-content/office:body/office:spreadsheet/table:table/"
3384 "table:table-row[2]/table:table-cell[2]/text:p/text:a",
3387 // if the exported document is not on the same drive then the linked document,
3388 // there is no way to get a relative URL for the link, because ../X:/ is undefined.
3389 if (!aURL
.startsWith(".."))
3391 sal_Unicode aDocDrive
= lcl_getWindowsDrive(maTempFile
.GetURL());
3392 sal_Unicode aLinkDrive
= lcl_getWindowsDrive(aURL
);
3393 CPPUNIT_ASSERT_MESSAGE("document on the same drive but no relative link!", aDocDrive
!= 0);
3394 CPPUNIT_ASSERT_MESSAGE("document on the same drive but no relative link!", aLinkDrive
!= 0);
3395 CPPUNIT_ASSERT_MESSAGE("document on the same drive but no relative link!",
3396 aDocDrive
!= aLinkDrive
);
3400 // make sure that the URL is relative
3401 CPPUNIT_ASSERT(aURL
.startsWith(".."));
3406 void testSheetProtection_Impl(ScDocument
& rDoc
)
3408 CPPUNIT_ASSERT(rDoc
.IsTabProtected(0));
3409 const ScTableProtection
* pTabProtection
= rDoc
.GetTabProtection(0);
3410 CPPUNIT_ASSERT(pTabProtection
);
3411 CPPUNIT_ASSERT(pTabProtection
->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS
));
3412 CPPUNIT_ASSERT(!pTabProtection
->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS
));
3416 void ScExportTest::testSheetProtectionODS()
3418 createScDoc("ods/sheet-protection.ods");
3420 ScDocument
* pDoc
= getScDoc();
3422 testSheetProtection_Impl(*pDoc
);
3424 saveAndReload("calc8");
3428 testSheetProtection_Impl(*pDoc
);
3431 void ScExportTest::testFunctionsExcel2010ODS()
3433 //testFunctionsExcel2010("calc8");
3436 void ScExportTest::testSwappedOutImageExport()
3438 std::vector
<OUString
> aFilterNames
{ "calc8", "MS Excel 97", "Calc Office Open XML" };
3440 // Set cache size to a very small value to make sure one of the images is swapped out
3441 std::shared_ptr
<comphelper::ConfigurationChanges
> xBatch(
3442 comphelper::ConfigurationChanges::create());
3443 officecfg::Office::Common::Cache::GraphicManager::TotalCacheSize::set(sal_Int32(1), xBatch
);
3446 for (size_t i
= 0; i
< aFilterNames
.size(); ++i
)
3448 // Check whether the export code swaps in the image which was swapped out before.
3449 createScDoc("ods/document_with_two_images.ods");
3451 const OString sFailedMessage
3452 = OString::Concat("Failed on filter: ") + aFilterNames
[i
].toUtf8();
3454 // Export the document and import again for a check
3455 saveAndReload(aFilterNames
[i
]);
3457 // Check whether graphic exported well after it was swapped out
3458 uno::Reference
<sheet::XSpreadsheetDocument
> xDoc(mxComponent
, UNO_QUERY_THROW
);
3459 uno::Reference
<container::XIndexAccess
> xIA(xDoc
->getSheets(), UNO_QUERY_THROW
);
3460 uno::Reference
<drawing::XDrawPageSupplier
> xDrawPageSupplier(xIA
->getByIndex(0),
3462 uno::Reference
<container::XIndexAccess
> xDraws(xDrawPageSupplier
->getDrawPage(),
3464 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage
.getStr(), static_cast<sal_Int32
>(2),
3465 xDraws
->getCount());
3467 uno::Reference
<drawing::XShape
> xImage(xDraws
->getByIndex(0), uno::UNO_QUERY
);
3468 uno::Reference
<beans::XPropertySet
> XPropSet(xImage
, uno::UNO_QUERY_THROW
);
3470 // Check Graphic, Size
3472 uno::Reference
<graphic::XGraphic
> xGraphic
;
3473 XPropSet
->getPropertyValue("Graphic") >>= xGraphic
;
3474 CPPUNIT_ASSERT_MESSAGE(sFailedMessage
.getStr(), xGraphic
.is());
3475 CPPUNIT_ASSERT_MESSAGE(sFailedMessage
.getStr(),
3476 xGraphic
->getType() != graphic::GraphicType::EMPTY
);
3477 uno::Reference
<awt::XBitmap
> xBitmap(xGraphic
, uno::UNO_QUERY
);
3478 CPPUNIT_ASSERT_MESSAGE(sFailedMessage
.getStr(), xBitmap
.is());
3479 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage
.getStr(), static_cast<sal_Int32
>(610),
3480 xBitmap
->getSize().Width
);
3481 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage
.getStr(), static_cast<sal_Int32
>(381),
3482 xBitmap
->getSize().Height
);
3485 xImage
.set(xDraws
->getByIndex(1), uno::UNO_QUERY
);
3486 XPropSet
.set(xImage
, uno::UNO_QUERY_THROW
);
3488 // Check Graphic, Size
3490 uno::Reference
<graphic::XGraphic
> xGraphic
;
3491 XPropSet
->getPropertyValue("Graphic") >>= xGraphic
;
3492 CPPUNIT_ASSERT_MESSAGE(sFailedMessage
.getStr(), xGraphic
.is());
3493 CPPUNIT_ASSERT_MESSAGE(sFailedMessage
.getStr(),
3494 xGraphic
->getType() != graphic::GraphicType::EMPTY
);
3495 uno::Reference
<awt::XBitmap
> xBitmap(xGraphic
, uno::UNO_QUERY
);
3496 CPPUNIT_ASSERT_MESSAGE(sFailedMessage
.getStr(), xBitmap
.is());
3497 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage
.getStr(), static_cast<sal_Int32
>(900),
3498 xBitmap
->getSize().Width
);
3499 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage
.getStr(), static_cast<sal_Int32
>(600),
3500 xBitmap
->getSize().Height
);
3505 void ScExportTest::testSupBookVirtualPathXLS()
3507 createScDoc("xls/external-ref.xls");
3509 saveAndReload("MS Excel 97");
3511 ScDocument
* pDoc
= getScDoc();
3513 OUString aFormula
= pDoc
->GetFormula(0, 0, 0);
3515 aFormula
= OUString::Concat(aFormula
.subView(0, 9)) + aFormula
.subView(12);
3516 // strip drive letter, e.g. 'C:/'
3518 CPPUNIT_ASSERT_EQUAL_MESSAGE(
3519 "Wrong SupBook VirtualPath URL",
3520 OUString("='file:///home/timar/Documents/external.xls'#$Sheet1.A1"), aFormula
);
3523 void ScExportTest::testLinkedGraphicRT()
3525 // Problem was with linked images
3526 std::vector
<OUString
> aFilterNames
{ "calc8", "MS Excel 97", "Calc Office Open XML" };
3528 for (size_t i
= 0; i
< aFilterNames
.size(); ++i
)
3530 // Load the original file with one image
3531 createScDoc("ods/document_with_linked_graphic.ods");
3532 const OString sFailedMessage
3533 = OString::Concat("Failed on filter: ") + aFilterNames
[i
].toUtf8();
3535 // Export the document and import again for a check
3536 saveAndReload(aFilterNames
[i
]);
3538 // Check whether graphic imported well after export
3539 ScDocument
* pDoc
= getScDoc();
3540 ScDrawLayer
* pDrawLayer
= pDoc
->GetDrawLayer();
3541 CPPUNIT_ASSERT_MESSAGE(sFailedMessage
.getStr(), pDrawLayer
!= nullptr);
3542 const SdrPage
* pPage
= pDrawLayer
->GetPage(0);
3543 CPPUNIT_ASSERT_MESSAGE(sFailedMessage
.getStr(), pPage
!= nullptr);
3544 SdrGrafObj
* pObject
= dynamic_cast<SdrGrafObj
*>(pPage
->GetObj(0));
3545 CPPUNIT_ASSERT_MESSAGE(sFailedMessage
.getStr(), pObject
!= nullptr);
3546 if (aFilterNames
[i
] == "Calc Office Open XML")
3548 // FIXME: tdf#152036
3549 CPPUNIT_ASSERT_MESSAGE(sFailedMessage
.getStr(), !pObject
->IsLinkedGraphic());
3552 CPPUNIT_ASSERT_MESSAGE(sFailedMessage
.getStr(), pObject
->IsLinkedGraphic());
3554 const GraphicObject
& rGraphicObj
= pObject
->GetGraphicObject(true);
3555 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage
.getStr(), int(GraphicType::Bitmap
),
3556 int(rGraphicObj
.GetGraphic().GetType()));
3557 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage
.getStr(), sal_uLong(864900),
3558 rGraphicObj
.GetGraphic().GetSizeBytes());
3562 void ScExportTest::testImageWithSpecialID()
3564 std::vector
<OUString
> aFilterNames
{ "calc8", "MS Excel 97", "Calc Office Open XML" };
3566 // Trigger swap out mechanism to test swapped state factor too.
3567 std::shared_ptr
<comphelper::ConfigurationChanges
> batch(
3568 comphelper::ConfigurationChanges::create());
3569 officecfg::Office::Common::Cache::GraphicManager::TotalCacheSize::set(sal_Int32(1), batch
);
3572 for (size_t i
= 0; i
< aFilterNames
.size(); ++i
)
3574 createScDoc("ods/images_with_special_IDs.ods");
3576 const OString sFailedMessage
3577 = OString::Concat("Failed on filter: ") + aFilterNames
[i
].toUtf8();
3579 // Export the document and import again for a check
3580 saveAndReload(aFilterNames
[i
]);
3582 // Check whether graphic was exported well
3583 uno::Reference
<sheet::XSpreadsheetDocument
> xDoc(mxComponent
, UNO_QUERY_THROW
);
3584 uno::Reference
<container::XIndexAccess
> xIA(xDoc
->getSheets(), UNO_QUERY_THROW
);
3585 uno::Reference
<drawing::XDrawPageSupplier
> xDrawPageSupplier(xIA
->getByIndex(0),
3587 uno::Reference
<container::XIndexAccess
> xDraws(xDrawPageSupplier
->getDrawPage(),
3589 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage
.getStr(), static_cast<sal_Int32
>(2),
3590 xDraws
->getCount());
3592 uno::Reference
<drawing::XShape
> xImage(xDraws
->getByIndex(0), uno::UNO_QUERY
);
3593 uno::Reference
<beans::XPropertySet
> XPropSet(xImage
, uno::UNO_QUERY_THROW
);
3595 // Check Graphic, Size
3597 uno::Reference
<graphic::XGraphic
> xGraphic
;
3598 XPropSet
->getPropertyValue("Graphic") >>= xGraphic
;
3599 CPPUNIT_ASSERT_MESSAGE(sFailedMessage
.getStr(), xGraphic
.is());
3600 CPPUNIT_ASSERT_MESSAGE(sFailedMessage
.getStr(),
3601 xGraphic
->getType() != graphic::GraphicType::EMPTY
);
3602 uno::Reference
<awt::XBitmap
> xBitmap(xGraphic
, uno::UNO_QUERY
);
3603 CPPUNIT_ASSERT_MESSAGE(sFailedMessage
.getStr(), xBitmap
.is());
3604 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage
.getStr(), static_cast<sal_Int32
>(610),
3605 xBitmap
->getSize().Width
);
3606 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage
.getStr(), static_cast<sal_Int32
>(381),
3607 xBitmap
->getSize().Height
);
3610 xImage
.set(xDraws
->getByIndex(1), uno::UNO_QUERY
);
3611 XPropSet
.set(xImage
, uno::UNO_QUERY_THROW
);
3613 // Check Graphic, Size
3615 uno::Reference
<graphic::XGraphic
> xGraphic
;
3616 XPropSet
->getPropertyValue("Graphic") >>= xGraphic
;
3617 CPPUNIT_ASSERT_MESSAGE(sFailedMessage
.getStr(), xGraphic
.is());
3618 CPPUNIT_ASSERT_MESSAGE(sFailedMessage
.getStr(),
3619 xGraphic
->getType() != graphic::GraphicType::EMPTY
);
3620 uno::Reference
<awt::XBitmap
> xBitmap(xGraphic
, uno::UNO_QUERY
);
3621 CPPUNIT_ASSERT_MESSAGE(sFailedMessage
.getStr(), xBitmap
.is());
3622 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage
.getStr(), static_cast<sal_Int32
>(900),
3623 xBitmap
->getSize().Width
);
3624 CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage
.getStr(), static_cast<sal_Int32
>(600),
3625 xBitmap
->getSize().Height
);
3630 void ScExportTest::testAbsNamedRangeHTML()
3632 setImportFilterName("calc_HTML_WebQuery");
3633 createScDoc("html/numberformat.html");
3634 ScDocShell
* pDocSh
= getScDocShell();
3635 pDocSh
->DoHardRecalc();
3637 //reset import filter
3638 setImportFilterName("calc8");
3639 saveAndReload("calc8");
3640 pDocSh
= getScDocShell();
3641 pDocSh
->DoHardRecalc();
3643 ScDocument
* pDoc
= getScDoc();
3644 ScRangeData
* pRangeData
= pDoc
->GetRangeName()->findByUpperName(OUString("HTML_1"));
3645 ScSingleRefData
* pRef
= pRangeData
->GetCode()->FirstToken()->GetSingleRef();
3646 // see tdf#119141 for the reason why this isn't Sheet1.HTML_1
3647 CPPUNIT_ASSERT_MESSAGE("HTML_1 is an absolute reference", !pRef
->IsTabRel());
3650 void ScExportTest::testTdf80149()
3652 createScDoc("csv/tdf80149.csv");
3653 ScDocShell
* pDocSh
= getScDocShell();
3654 pDocSh
->DoHardRecalc();
3655 saveAndReload("Calc Office Open XML");
3656 pDocSh
= getScDocShell();
3657 pDocSh
->DoHardRecalc();
3659 ScDocument
* pDoc
= getScDoc();
3660 CPPUNIT_ASSERT_EQUAL(OUString("row 1"), pDoc
->GetString(0, 0, 0));
3662 // Without the fix in place, this test would have failed with
3663 // - Expected: Character 0x16 is here ->>\x16<<--
3665 CPPUNIT_ASSERT_EQUAL(OUString("Character 0x16 is here ->>\x16<<--"), pDoc
->GetString(1, 0, 0));
3666 CPPUNIT_ASSERT_EQUAL(OUString("File opens in libre office, but can't be saved as xlsx"),
3667 pDoc
->GetString(2, 0, 0));
3668 CPPUNIT_ASSERT_EQUAL(OUString("row 2"), pDoc
->GetString(0, 1, 0));
3669 CPPUNIT_ASSERT_EQUAL(OUString("Subsequent rows get truncated"), pDoc
->GetString(1, 1, 0));
3670 CPPUNIT_ASSERT_EQUAL(OUString("This cell goes missing"), pDoc
->GetString(2, 1, 0));
3671 CPPUNIT_ASSERT_EQUAL(OUString("row 3"), pDoc
->GetString(0, 2, 0));
3672 CPPUNIT_ASSERT_EQUAL(OUString("Subsequent rows get truncated"), pDoc
->GetString(1, 2, 0));
3673 CPPUNIT_ASSERT_EQUAL(OUString("This cell goes missing"), pDoc
->GetString(2, 2, 0));
3676 void ScExportTest::testSheetLocalRangeNameXLS()
3678 createScDoc("xls/named-ranges-local.xls");
3679 ScDocShell
* pDocSh
= getScDocShell();
3680 pDocSh
->DoHardRecalc();
3681 saveAndReload("MS Excel 97");
3682 pDocSh
= getScDocShell();
3683 pDocSh
->DoHardRecalc();
3685 ScDocument
* pDoc
= getScDoc();
3686 ScRangeName
* pRangeName
= pDoc
->GetRangeName(0);
3687 CPPUNIT_ASSERT(pRangeName
);
3688 CPPUNIT_ASSERT_EQUAL(size_t(2), pRangeName
->size());
3690 OUString aFormula
= pDoc
->GetFormula(3, 11, 0);
3691 CPPUNIT_ASSERT_EQUAL(OUString("=SUM(local_name2)"), aFormula
);
3692 ASSERT_DOUBLES_EQUAL(14.0, pDoc
->GetValue(3, 11, 0));
3694 aFormula
= pDoc
->GetFormula(6, 4, 0);
3695 CPPUNIT_ASSERT_EQUAL(OUString("=local_name1"), aFormula
);
3698 void ScExportTest::testRelativeNamedExpressionsXLS()
3700 createScDoc("ods/tdf113991_relativeNamedRanges.ods");
3701 ScDocShell
* pDocSh
= getScDocShell();
3702 pDocSh
->DoHardRecalc();
3703 saveAndReload("MS Excel 97");
3704 pDocSh
= getScDocShell();
3705 pDocSh
->DoHardRecalc();
3707 ScDocument
* pDoc
= getScDoc();
3709 ScAddress
aPos(6, 2, 0);
3710 CPPUNIT_ASSERT_EQUAL(1.0, pDoc
->GetValue(aPos
));
3711 CPPUNIT_ASSERT_EQUAL(OUString("=single_cell_A3"),
3712 pDoc
->GetFormula(aPos
.Col(), aPos
.Row(), aPos
.Tab()));
3714 aPos
= ScAddress(5, 5, 1);
3715 CPPUNIT_ASSERT_EQUAL(18.0, pDoc
->GetValue(aPos
));
3716 CPPUNIT_ASSERT_EQUAL(OUString("=SUM(test_conflict)"),
3717 pDoc
->GetFormula(aPos
.Col(), aPos
.Row(), aPos
.Tab()));
3719 aPos
= ScAddress(7, 2, 1);
3720 CPPUNIT_ASSERT_EQUAL(10.0, pDoc
->GetValue(aPos
));
3721 CPPUNIT_ASSERT_EQUAL(OUString("=single_global_A3"),
3722 pDoc
->GetFormula(aPos
.Col(), aPos
.Row(), aPos
.Tab()));
3724 aPos
= ScAddress(7, 5, 1);
3725 CPPUNIT_ASSERT_EQUAL(75.0, pDoc
->GetValue(aPos
));
3726 CPPUNIT_ASSERT_EQUAL(OUString("=SUM(A6:F6)"),
3727 pDoc
->GetFormula(aPos
.Col(), aPos
.Row(), aPos
.Tab()));
3730 void ScExportTest::testSheetTextBoxHyperlinkXLSX()
3732 createScDoc("xlsx/textbox-hyperlink.xlsx");
3734 save("Calc Office Open XML");
3735 xmlDocUniquePtr pDoc
= parseExport("xl/drawings/drawing1.xml");
3736 CPPUNIT_ASSERT(pDoc
);
3740 "/xdr:wsDr[1]/xdr:twoCellAnchor[1]/xdr:sp[1]/xdr:nvSpPr[1]/xdr:cNvPr[1]/a:hlinkClick[1]",
3744 void ScExportTest::testFontSizeXLSX()
3746 createScDoc("xlsx/fontSize.xlsx");
3748 save("Calc Office Open XML");
3749 xmlDocUniquePtr pDoc
= parseExport("xl/drawings/drawing1.xml");
3750 CPPUNIT_ASSERT(pDoc
);
3751 OUString fontSize
= getXPath(
3752 pDoc
, "/xdr:wsDr/xdr:twoCellAnchor/xdr:sp[1]/xdr:txBody/a:p[1]/a:r[1]/a:rPr", "sz");
3753 // make sure that the font size is 18
3754 CPPUNIT_ASSERT_EQUAL(OUString("1800"), fontSize
);
3757 void ScExportTest::testSheetCharacterKerningSpaceXLSX()
3759 createScDoc("xlsx/textbox-CharKerningSpace.xlsx");
3761 saveAndReload("Calc Office Open XML");
3763 save("Calc Office Open XML");
3764 xmlDocUniquePtr pDoc
= parseExport("xl/drawings/drawing1.xml");
3765 CPPUNIT_ASSERT(pDoc
);
3767 OUString CharKerningSpace
= getXPath(
3768 pDoc
, "/xdr:wsDr[1]/xdr:twoCellAnchor[1]/xdr:sp[1]/xdr:txBody[1]/a:p[1]/a:r[1]/a:rPr[1]",
3771 // make sure that the CharKerning is 1997.
3772 CPPUNIT_ASSERT_EQUAL(OUString("1997"), CharKerningSpace
);
3775 void ScExportTest::testSheetCondensedCharacterSpaceXLSX()
3777 createScDoc("xlsx/textbox-CondensedCharacterSpace.xlsx");
3779 save("Calc Office Open XML");
3780 xmlDocUniquePtr pDoc
= parseExport("xl/drawings/drawing1.xml");
3781 CPPUNIT_ASSERT(pDoc
);
3783 OUString CondensedCharSpace
= getXPath(
3784 pDoc
, "/xdr:wsDr[1]/xdr:twoCellAnchor[1]/xdr:sp[1]/xdr:txBody[1]/a:p[1]/a:r[1]/a:rPr[1]",
3787 // make sure that the CondensedCharSpace is -1002.
3788 CPPUNIT_ASSERT_EQUAL(OUString("-1002"), CondensedCharSpace
);
3791 void ScExportTest::testTextUnderlineColorXLSX()
3793 createScDoc("xlsx/underlineColor.xlsx");
3795 save("Calc Office Open XML");
3796 xmlDocUniquePtr pDoc
= parseExport("xl/drawings/drawing1.xml");
3797 CPPUNIT_ASSERT(pDoc
);
3798 // Make sure the underline type is double line
3799 assertXPath(pDoc
, "/xdr:wsDr/xdr:twoCellAnchor[1]/xdr:sp[1]/xdr:txBody/a:p[1]/a:r[1]/a:rPr",
3802 assertXPath(pDoc
, "/xdr:wsDr/xdr:twoCellAnchor[1]/xdr:sp[1]/xdr:txBody/a:p[1]/a:r[1]/a:rPr",
3804 // Make sure that the underline color is RED
3806 "/xdr:wsDr/xdr:twoCellAnchor[1]/xdr:sp[1]/xdr:txBody/a:p[1]/a:r[1]/a:rPr/a:uFill/"
3807 "a:solidFill/a:srgbClr",
3810 // Make sure the underline type is drawn with heavy line
3811 assertXPath(pDoc
, "/xdr:wsDr/xdr:twoCellAnchor[2]/xdr:sp[1]/xdr:txBody/a:p[1]/a:r[1]/a:rPr",
3813 // tdf#104219 Make sure that uFill is not existing and uFillTx is set.
3814 // It mean that color is automatic, should be the same color as the text.
3816 pDoc
, "/xdr:wsDr/xdr:twoCellAnchor[2]/xdr:sp[1]/xdr:txBody/a:p[1]/a:r[1]/a:rPr/a:uFill", 0);
3818 "/xdr:wsDr/xdr:twoCellAnchor[2]/xdr:sp[1]/xdr:txBody/a:p[1]/a:r[1]/a:rPr/a:uFillTx",
3822 void ScExportTest::testSheetRunParagraphPropertyXLSX()
3824 createScDoc("xlsx/TextColor.xlsx");
3826 save("Calc Office Open XML");
3827 xmlDocUniquePtr pDoc
= parseExport("xl/sharedStrings.xml");
3828 CPPUNIT_ASSERT(pDoc
);
3830 OUString aColor
= getXPath(pDoc
, "/x:sst/x:si/x:r[1]/x:rPr[1]/x:color", "rgb");
3831 CPPUNIT_ASSERT_EQUAL(OUString("FFFF0000"), aColor
);
3834 void ScExportTest::testPreserveTextWhitespaceXLSX()
3836 createScDoc("xlsx/preserve-whitespace.xlsx");
3838 save("Calc Office Open XML");
3839 xmlDocUniquePtr pDoc
= parseExport("xl/sharedStrings.xml");
3840 CPPUNIT_ASSERT(pDoc
);
3841 assertXPath(pDoc
, "/x:sst/x:si/x:t", "space", "preserve");
3844 void ScExportTest::testPreserveTextWhitespace2XLSX()
3846 createScDoc("xlsx/preserve_space.xlsx");
3848 save("Calc Office Open XML");
3849 xmlDocUniquePtr pDoc
= parseExport("xl/sharedStrings.xml");
3850 CPPUNIT_ASSERT(pDoc
);
3851 assertXPath(pDoc
, "/x:sst/x:si[1]/x:t", "space", "preserve");
3852 assertXPath(pDoc
, "/x:sst/x:si[2]/x:r[1]/x:t", "space", "preserve");
3853 assertXPath(pDoc
, "/x:sst/x:si[2]/x:r[2]/x:t", "space", "preserve");
3856 void ScExportTest::testHiddenShapeXLS()
3858 createScDoc("xls/hiddenShape.xls");
3860 ScDocument
* pDoc
= getScDoc();
3861 CPPUNIT_ASSERT(pDoc
->GetTableCount() > 0);
3862 ScDrawLayer
* pDrawLayer
= pDoc
->GetDrawLayer();
3863 SdrPage
* pPage
= pDrawLayer
->GetPage(0);
3864 CPPUNIT_ASSERT(pPage
);
3865 SdrObject
* pObj
= pPage
->GetObj(0);
3866 CPPUNIT_ASSERT(pObj
);
3867 CPPUNIT_ASSERT_MESSAGE("Drawing object should not be visible.", !pObj
->IsVisible());
3868 CPPUNIT_ASSERT_MESSAGE("Drawing object should not be printable.", !pObj
->IsPrintable());
3871 void ScExportTest::testHiddenShapeXLSX()
3873 createScDoc("xlsx/hiddenShape.xlsx");
3875 ScDocument
* pDoc
= getScDoc();
3876 CPPUNIT_ASSERT(pDoc
->GetTableCount() > 0);
3877 ScDrawLayer
* pDrawLayer
= pDoc
->GetDrawLayer();
3878 SdrPage
* pPage
= pDrawLayer
->GetPage(0);
3879 CPPUNIT_ASSERT(pPage
);
3880 SdrObject
* pObj
= pPage
->GetObj(0);
3881 CPPUNIT_ASSERT(pObj
);
3882 CPPUNIT_ASSERT_MESSAGE("Drawing object should not be visible.", !pObj
->IsVisible());
3883 CPPUNIT_ASSERT_MESSAGE("Drawing object should not be printable.", !pObj
->IsPrintable());
3885 save("Calc Office Open XML");
3886 xmlDocUniquePtr pDocXml
= parseExport("xl/drawings/drawing1.xml");
3887 CPPUNIT_ASSERT(pDocXml
);
3888 assertXPath(pDocXml
, "/xdr:wsDr/xdr:twoCellAnchor/xdr:sp[1]/xdr:nvSpPr/xdr:cNvPr", "hidden",
3892 void ScExportTest::testShapeAutofitXLSX()
3894 createScDoc("xlsx/testShapeAutofit.xlsx");
3896 save("Calc Office Open XML");
3897 xmlDocUniquePtr pDoc
= parseExport("xl/drawings/drawing1.xml");
3898 CPPUNIT_ASSERT(pDoc
);
3900 // TextAutoGrowHeight --> "Fit height to text" / "Resize shape to fit text" --> true
3901 assertXPath(pDoc
, "/xdr:wsDr/xdr:twoCellAnchor[1]/xdr:sp/xdr:txBody/a:bodyPr/a:spAutoFit", 1);
3902 // TextAutoGrowHeight --> "Fit height to text" / "Resize shape to fit text" --> false
3903 assertXPath(pDoc
, "/xdr:wsDr/xdr:twoCellAnchor[2]/xdr:sp/xdr:txBody/a:bodyPr/a:noAutofit", 1);
3906 void ScExportTest::testHyperlinkXLSX()
3908 createScDoc("xlsx/hyperlink.xlsx");
3910 save("Calc Office Open XML");
3911 xmlDocUniquePtr pDoc
= parseExport("xl/drawings/_rels/drawing1.xml.rels");
3912 CPPUNIT_ASSERT(pDoc
);
3913 assertXPath(pDoc
, "/rels:Relationships/rels:Relationship", "Target", "#Sheet2!A1");
3916 void ScExportTest::testMoveCellAnchoredShapesODS()
3918 createScDoc("ods/move-cell-anchored-shapes.ods");
3920 // There are two cell-anchored objects on the first sheet.
3921 ScDocument
* pDoc
= getScDoc();
3923 CPPUNIT_ASSERT_MESSAGE("There should be at least one sheet.", pDoc
->GetTableCount() > 0);
3925 ScDrawLayer
* pDrawLayer
= pDoc
->GetDrawLayer();
3926 SdrPage
* pPage
= pDrawLayer
->GetPage(0);
3927 CPPUNIT_ASSERT_MESSAGE("draw page for sheet 1 should exist.", pPage
);
3928 SdrObject
* pObj
= pPage
->GetObj(0);
3929 CPPUNIT_ASSERT_MESSAGE("Failed to get drawing object.", pObj
);
3931 // Check cell anchor state
3932 ScAnchorType oldType
= ScDrawLayer::GetAnchorType(*pObj
);
3933 CPPUNIT_ASSERT_EQUAL_MESSAGE("Failed to get anchor type", SCA_CELL_RESIZE
, oldType
);
3936 ScDrawObjData
* pData
= ScDrawLayer::GetObjData(pObj
);
3937 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve user data for this object.", pData
);
3938 CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.",
3939 !pData
->getShapeRect().IsEmpty());
3941 ScAddress aDataStart
= pData
->maStart
;
3942 ScAddress aDataEnd
= pData
->maEnd
;
3944 // Get non rotated anchor data
3945 ScDrawObjData
* pNData
= ScDrawLayer::GetNonRotatedObjData(pObj
);
3946 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve non rotated user data for this object.", pNData
);
3947 CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.",
3948 !pNData
->getShapeRect().IsEmpty());
3950 ScAddress aNDataStart
= pNData
->maStart
;
3951 ScAddress aNDataEnd
= pNData
->maEnd
;
3952 CPPUNIT_ASSERT_EQUAL(aDataStart
, aNDataStart
);
3953 CPPUNIT_ASSERT_EQUAL(aDataEnd
, aNDataEnd
);
3956 pDoc
->InsertRow(ScRange(0, aDataStart
.Row() - 1, 0, pDoc
->MaxCol(), aDataStart
.Row(), 0));
3959 pData
= ScDrawLayer::GetObjData(pObj
);
3960 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve user data for this object.", pData
);
3961 CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.",
3962 !pData
->getShapeRect().IsEmpty());
3964 // Get non rotated anchor data
3965 pNData
= ScDrawLayer::GetNonRotatedObjData(pObj
);
3966 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve non rotated user data for this object.", pNData
);
3967 CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.",
3968 !pNData
->getShapeRect().IsEmpty());
3970 // Check if data has moved to new rows
3971 CPPUNIT_ASSERT_EQUAL(pData
->maStart
.Row(), aDataStart
.Row() + 2);
3972 CPPUNIT_ASSERT_EQUAL(pData
->maEnd
.Row(), aDataEnd
.Row() + 2);
3974 CPPUNIT_ASSERT_EQUAL(pNData
->maStart
.Row(), aNDataStart
.Row() + 2);
3975 CPPUNIT_ASSERT_EQUAL(pNData
->maEnd
.Row(), aNDataEnd
.Row() + 2);
3977 // Save the anchor data
3978 aDataStart
= pData
->maStart
;
3979 aDataEnd
= pData
->maEnd
;
3980 aNDataStart
= pNData
->maStart
;
3981 aNDataEnd
= pNData
->maEnd
;
3983 // Save the document and load again to check anchor persist
3984 saveAndReload("calc8");
3986 // There are two cell-anchored objects on the first sheet.
3989 CPPUNIT_ASSERT_MESSAGE("There should be at least one sheet.", pDoc
->GetTableCount() > 0);
3991 pDrawLayer
= pDoc
->GetDrawLayer();
3992 pPage
= pDrawLayer
->GetPage(0);
3993 CPPUNIT_ASSERT_MESSAGE("draw page for sheet 1 should exist.", pPage
);
3994 pObj
= pPage
->GetObj(0);
3995 CPPUNIT_ASSERT_MESSAGE("Failed to get drawing object.", pObj
);
3997 // Check cell anchor state
3998 oldType
= ScDrawLayer::GetAnchorType(*pObj
);
3999 CPPUNIT_ASSERT_EQUAL_MESSAGE("Failed to get anchor type", SCA_CELL_RESIZE
, oldType
);
4002 pData
= ScDrawLayer::GetObjData(pObj
);
4003 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve user data for this object.", pData
);
4004 CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.",
4005 !pData
->getShapeRect().IsEmpty());
4007 // Get non rotated anchor data
4008 pNData
= ScDrawLayer::GetNonRotatedObjData(pObj
);
4009 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve non rotated user data for this object.", pNData
);
4010 CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.",
4011 !pNData
->getShapeRect().IsEmpty());
4013 // Check if data after save it
4014 CPPUNIT_ASSERT_EQUAL(pData
->maStart
, aDataStart
);
4015 CPPUNIT_ASSERT_EQUAL(pData
->maEnd
, aDataEnd
);
4017 CPPUNIT_ASSERT_EQUAL(pNData
->maStart
, aNDataStart
);
4018 CPPUNIT_ASSERT_EQUAL(pNData
->maEnd
, aNDataEnd
);
4021 pDoc
->InsertCol(ScRange(aDataStart
.Col(), 0, 0, aDataStart
.Col(), pDoc
->MaxRow(), 0));
4024 pData
= ScDrawLayer::GetObjData(pObj
);
4025 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve user data for this object.", pData
);
4026 CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.",
4027 !pData
->getShapeRect().IsEmpty());
4029 // Get non rotated anchor data
4030 pNData
= ScDrawLayer::GetNonRotatedObjData(pObj
);
4031 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve non rotated user data for this object.", pNData
);
4032 CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.",
4033 !pNData
->getShapeRect().IsEmpty());
4035 // Check if data has moved to new rows
4036 CPPUNIT_ASSERT_EQUAL(pData
->maStart
.Col(), SCCOL(aDataStart
.Col() + 1));
4037 CPPUNIT_ASSERT_EQUAL(pData
->maEnd
.Col(), SCCOL(aDataEnd
.Col() + 1));
4039 CPPUNIT_ASSERT_EQUAL(pNData
->maStart
.Col(), SCCOL(aNDataStart
.Col() + 1));
4040 CPPUNIT_ASSERT_EQUAL(pNData
->maEnd
.Col(), SCCOL(aNDataEnd
.Col() + 1));
4042 // Save the anchor data
4043 aDataStart
= pData
->maStart
;
4044 aDataEnd
= pData
->maEnd
;
4045 aNDataStart
= pNData
->maStart
;
4046 aNDataEnd
= pNData
->maEnd
;
4048 // Save the document and load again to check anchor persist
4049 saveAndReload("calc8");
4051 // There are two cell-anchored objects on the first sheet.
4054 CPPUNIT_ASSERT_MESSAGE("There should be at least one sheet.", pDoc
->GetTableCount() > 0);
4056 pDrawLayer
= pDoc
->GetDrawLayer();
4057 pPage
= pDrawLayer
->GetPage(0);
4058 CPPUNIT_ASSERT_MESSAGE("draw page for sheet 1 should exist.", pPage
);
4059 pObj
= pPage
->GetObj(0);
4060 CPPUNIT_ASSERT_MESSAGE("Failed to get drawing object.", pObj
);
4062 // Check cell anchor state
4063 oldType
= ScDrawLayer::GetAnchorType(*pObj
);
4064 CPPUNIT_ASSERT_EQUAL_MESSAGE("Failed to get anchor type", SCA_CELL_RESIZE
, oldType
);
4067 pData
= ScDrawLayer::GetObjData(pObj
);
4068 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve user data for this object.", pData
);
4069 CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.",
4070 !pData
->getShapeRect().IsEmpty());
4072 // Get non rotated anchor data
4073 pNData
= ScDrawLayer::GetNonRotatedObjData(pObj
);
4074 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve non rotated user data for this object.", pNData
);
4075 CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.",
4076 !pNData
->getShapeRect().IsEmpty());
4078 // Check if data after save it
4079 CPPUNIT_ASSERT_EQUAL(pData
->maStart
, aDataStart
);
4080 CPPUNIT_ASSERT_EQUAL(pData
->maEnd
, aDataEnd
);
4082 CPPUNIT_ASSERT_EQUAL(pNData
->maStart
, aNDataStart
);
4083 CPPUNIT_ASSERT_EQUAL(pNData
->maEnd
, aNDataEnd
);
4086 void ScExportTest::testConditionalFormatRangeListXLSX()
4088 createScDoc("ods/conditionalformat_rangelist.ods");
4089 save("Calc Office Open XML");
4090 xmlDocUniquePtr pDoc
= parseExport("xl/worksheets/sheet1.xml");
4091 CPPUNIT_ASSERT(pDoc
);
4092 assertXPath(pDoc
, "//x:conditionalFormatting", "sqref", "F4 F10");
4095 void ScExportTest::testConditionalFormatContainsTextXLSX()
4097 createScDoc("ods/conditionalformat_containstext.ods");
4098 save("Calc Office Open XML");
4099 xmlDocUniquePtr pDoc
= parseExport("xl/worksheets/sheet1.xml");
4100 CPPUNIT_ASSERT(pDoc
);
4101 assertXPathContent(pDoc
, "//x:conditionalFormatting/x:cfRule/x:formula",
4102 "NOT(ISERROR(SEARCH(\"test\",A1)))");
4105 void ScExportTest::testConditionalFormatPriorityCheckXLSX()
4107 createScDoc("xlsx/conditional_fmt_checkpriority.xlsx");
4108 save("Calc Office Open XML");
4109 xmlDocUniquePtr pDoc
= parseExport("xl/worksheets/sheet1.xml");
4110 CPPUNIT_ASSERT(pDoc
);
4111 constexpr bool bHighPriorityExtensionA1
4112 = true; // Should A1's extension cfRule has higher priority than normal cfRule ?
4113 constexpr bool bHighPriorityExtensionA3
4114 = false; // Should A3's extension cfRule has higher priority than normal cfRule ?
4115 size_t nA1NormalPriority
= 0;
4116 size_t nA1ExtPriority
= 0;
4117 size_t nA3NormalPriority
= 0;
4118 size_t nA3ExtPriority
= 0;
4119 for (size_t nIdx
= 1; nIdx
<= 2; ++nIdx
)
4121 OString aIdx
= OString::number(nIdx
);
4122 OUString aCellAddr
= getXPath(pDoc
, "//x:conditionalFormatting[" + aIdx
+ "]", "sqref");
4124 = getXPath(pDoc
, "//x:conditionalFormatting[" + aIdx
+ "]/x:cfRule", "priority");
4125 CPPUNIT_ASSERT_MESSAGE("conditionalFormatting sqref must be either A1 or A3",
4126 aCellAddr
== "A1" || aCellAddr
== "A3");
4127 if (aCellAddr
== "A1")
4128 nA1NormalPriority
= aPriority
.toUInt32();
4130 nA3NormalPriority
= aPriority
.toUInt32();
4131 aCellAddr
= getXPathContent(
4132 pDoc
, "//x:extLst/x:ext[1]/x14:conditionalFormattings/x14:conditionalFormatting[" + aIdx
4136 "//x:extLst/x:ext[1]/x14:conditionalFormattings/x14:conditionalFormatting["
4137 + aIdx
+ "]/x14:cfRule",
4139 CPPUNIT_ASSERT_MESSAGE("x14:conditionalFormatting sqref must be either A1 or A3",
4140 aCellAddr
== "A1" || aCellAddr
== "A3");
4141 if (aCellAddr
== "A1")
4142 nA1ExtPriority
= aPriority
.toUInt32();
4144 nA3ExtPriority
= aPriority
.toUInt32();
4146 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong priorities for A1", bHighPriorityExtensionA1
,
4147 nA1ExtPriority
< nA1NormalPriority
);
4148 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong priorities for A3", bHighPriorityExtensionA3
,
4149 nA3ExtPriority
< nA3NormalPriority
);
4152 void ScExportTest::testConditionalFormatOriginXLSX()
4154 createScDoc("xlsx/conditional_fmt_origin.xlsx");
4155 save("Calc Office Open XML");
4156 xmlDocUniquePtr pDoc
= parseExport("xl/worksheets/sheet1.xml");
4157 CPPUNIT_ASSERT(pDoc
);
4158 // tdf#124953 : The range-list is B3:C6 F1:G2, origin address in the formula should be B1, not B3.
4159 OUString aFormula
= getXPathContent(pDoc
, "//x:conditionalFormatting/x:cfRule/x:formula");
4160 CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong origin address in formula",
4161 OUString("NOT(ISERROR(SEARCH(\"BAC\",B1)))"), aFormula
);
4164 // FILESAVE: XLSX export with long sheet names (length > 31 characters)
4165 void ScExportTest::testTdf79998()
4167 // check: original document has tab name > 31 characters
4168 createScDoc("ods/tdf79998.ods");
4169 ScDocument
* pDoc
= getScDoc();
4170 const std::vector
<OUString
> aTabNames1
= pDoc
->GetAllTableNames();
4171 CPPUNIT_ASSERT_EQUAL(OUString("Utilities (FX Kurse, Kreditkarten etc)"), aTabNames1
[1]);
4173 // check: saved XLSX document has truncated tab name
4174 saveAndReload("Calc Office Open XML");
4176 const std::vector
<OUString
> aTabNames2
= pDoc
->GetAllTableNames();
4177 CPPUNIT_ASSERT_EQUAL(OUString("Utilities (FX Kurse, Kreditkart"), aTabNames2
[1]);
4180 static void impl_testLegacyCellAnchoredRotatedShape(ScDocument
& rDoc
, const tools::Rectangle
& aRect
,
4181 const ScDrawObjData
& aAnchor
,
4182 tools::Long TOLERANCE
= 30 /* 30 hmm */)
4184 ScDrawLayer
* pDrawLayer
= rDoc
.GetDrawLayer();
4185 CPPUNIT_ASSERT_MESSAGE("No drawing layer.", pDrawLayer
);
4186 SdrPage
* pPage
= pDrawLayer
->GetPage(0);
4187 CPPUNIT_ASSERT_MESSAGE("No page instance for the 1st sheet.", pPage
);
4188 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pPage
->GetObjCount());
4190 SdrObject
* pObj
= pPage
->GetObj(0);
4191 const tools::Rectangle
& aSnap
= pObj
->GetSnapRect();
4192 CPPUNIT_ASSERT_DOUBLES_EQUAL(aRect
.GetHeight(), aSnap
.GetHeight(), TOLERANCE
);
4193 CPPUNIT_ASSERT_DOUBLES_EQUAL(aRect
.GetWidth(), aSnap
.GetWidth(), TOLERANCE
);
4194 CPPUNIT_ASSERT_DOUBLES_EQUAL(aRect
.Left(), aSnap
.Left(), TOLERANCE
);
4195 CPPUNIT_ASSERT_DOUBLES_EQUAL(aRect
.Top(), aSnap
.Top(), TOLERANCE
);
4197 ScDrawObjData
* pData
= ScDrawLayer::GetObjData(pObj
);
4198 CPPUNIT_ASSERT_MESSAGE("expected object meta data", pData
);
4199 CPPUNIT_ASSERT_EQUAL(aAnchor
.maStart
.Row(), pData
->maStart
.Row());
4200 CPPUNIT_ASSERT_EQUAL(aAnchor
.maStart
.Col(), pData
->maStart
.Col());
4201 CPPUNIT_ASSERT_EQUAL(aAnchor
.maEnd
.Row(), pData
->maEnd
.Row());
4202 CPPUNIT_ASSERT_EQUAL(aAnchor
.maEnd
.Col(), pData
->maEnd
.Col());
4205 void ScExportTest::testLegacyCellAnchoredRotatedShape()
4208 // This example doc contains cell anchored shape that is rotated, the
4209 // rotated shape is in fact clipped by the sheet boundaries (and thus
4210 // is a good edge case test to see if we import it still correctly)
4211 createScDoc("ods/legacycellanchoredrotatedclippedshape.ods");
4213 ScDocument
* pDoc
= getScDoc();
4214 // ensure the imported legacy rotated shape is in the expected position
4215 tools::Rectangle
aRect(6000, -2000, 8000, 4000);
4216 // ensure the imported ( and converted ) anchor ( note we internally now store the anchor in
4217 // terms of the rotated shape ) is more or less contains the correct info
4218 ScDrawObjData aAnchor
;
4219 aAnchor
.maStart
.SetRow(0);
4220 aAnchor
.maStart
.SetCol(5);
4221 aAnchor
.maEnd
.SetRow(3);
4222 aAnchor
.maEnd
.SetCol(7);
4223 impl_testLegacyCellAnchoredRotatedShape(*pDoc
, aRect
, aAnchor
);
4224 // test save and reload
4225 // for some reason having this test in subsequent_export-test.cxx causes
4226 // a core dump in editeng ( so moved to here )
4227 saveAndReload("calc8");
4229 impl_testLegacyCellAnchoredRotatedShape(*pDoc
, aRect
, aAnchor
);
4232 // This example doc contains cell anchored shape that is rotated, the
4233 // rotated shape is in fact clipped by the sheet boundaries, additionally
4234 // the shape is completely hidden because the rows the shape occupies
4236 createScDoc("ods/legacycellanchoredrotatedhiddenshape.ods");
4237 ScDocument
* pDoc
= getScDoc();
4238 // ensure the imported legacy rotated shape is in the expected position
4239 tools::Rectangle
aRect(6000, -2000, 8000, 4000);
4241 // ensure the imported (and converted) anchor (note we internally now store the anchor in
4242 // terms of the rotated shape) is more or less contains the correct info
4243 ScDrawObjData aAnchor
;
4244 aAnchor
.maStart
.SetRow(0);
4245 aAnchor
.maStart
.SetCol(5);
4246 aAnchor
.maEnd
.SetRow(3);
4247 aAnchor
.maEnd
.SetCol(7);
4248 pDoc
->ShowRows(0, 9, 0, true); // show relevant rows
4249 pDoc
->SetDrawPageSize(0); // trigger recalcpos
4250 impl_testLegacyCellAnchoredRotatedShape(*pDoc
, aRect
, aAnchor
);
4251 // test save and reload
4252 saveAndReload("calc8");
4254 impl_testLegacyCellAnchoredRotatedShape(*pDoc
, aRect
, aAnchor
);
4257 // This example doc contains cell anchored shape that is rotated
4258 createScDoc("ods/legacycellanchoredrotatedshape.ods");
4260 ScDocument
* pDoc
= getScDoc();
4261 // ensure the imported legacy rotated shape is in the expected position
4262 tools::Rectangle
aRect(6000, 3000, 8000, 9000);
4263 // ensure the imported (and converted) anchor (note we internally now store the anchor in
4264 // terms of the rotated shape) more or less contains the correct info
4266 ScDrawObjData aAnchor
;
4267 aAnchor
.maStart
.SetRow(3);
4268 aAnchor
.maStart
.SetCol(6);
4269 aAnchor
.maEnd
.SetRow(9);
4270 aAnchor
.maEnd
.SetCol(8);
4272 impl_testLegacyCellAnchoredRotatedShape(*pDoc
, aRect
, aAnchor
);
4273 // test save and reload
4274 saveAndReload("calc8");
4276 impl_testLegacyCellAnchoredRotatedShape(*pDoc
, aRect
, aAnchor
);
4280 void ScExportTest::testTdf113646()
4282 createScDoc("ods/tdf113646.ods");
4284 save("Calc Office Open XML");
4285 xmlDocUniquePtr pSheet
= parseExport("xl/styles.xml");
4286 CPPUNIT_ASSERT(pSheet
);
4288 assertXPath(pSheet
, "/x:styleSheet/x:dxfs/x:dxf/x:font/x:sz", "val", "36");
4291 void ScExportTest::testDateStandardfilterXLSX()
4293 // XLSX Roundtripping standard filter with date
4294 createScDoc("ods/tdf142607.ods");
4296 save("Calc Office Open XML");
4297 xmlDocUniquePtr pDoc
= parseExport("xl/worksheets/sheet1.xml");
4298 CPPUNIT_ASSERT(pDoc
);
4300 assertXPath(pDoc
, "//x:autoFilter", "ref", "A1:B6");
4301 assertXPath(pDoc
, "//x:autoFilter/x:filterColumn/x:filters/x:dateGroupItem[1]", "day", "03");
4302 assertXPath(pDoc
, "//x:autoFilter/x:filterColumn/x:filters/x:dateGroupItem[1]", "month", "12");
4303 assertXPath(pDoc
, "//x:autoFilter/x:filterColumn/x:filters/x:dateGroupItem[1]", "year", "2011");
4304 assertXPath(pDoc
, "//x:autoFilter/x:filterColumn/x:filters/x:dateGroupItem[1]",
4305 "dateTimeGrouping", "day");
4308 CPPUNIT_TEST_SUITE_REGISTRATION(ScExportTest
);
4310 CPPUNIT_PLUGIN_IMPLEMENT();
4312 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */