Version 6.4.0.3, tag libreoffice-6.4.0.3
[LibreOffice.git] / sc / qa / unit / subsequent_filters-test.cxx
blob9110505667fc72a01ace11fbdfda5e03ac14a899
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #include <memory>
11 #include <sal/config.h>
12 #include <unotest/filters-test.hxx>
13 #include <test/bootstrapfixture.hxx>
14 #include <rtl/strbuf.hxx>
15 #include <osl/file.hxx>
16 #include <config_features.h>
18 #include <vcl/svapp.hxx>
19 #include <sfx2/docfilt.hxx>
20 #include <sfx2/docfile.hxx>
21 #include <svl/stritem.hxx>
22 #include <svl/zformat.hxx>
23 #include <svx/svdograf.hxx>
24 #include <svx/svxids.hrc>
26 #include <drwlayer.hxx>
27 #include <svx/svdpage.hxx>
28 #include <svx/svdoole2.hxx>
29 #include <editeng/eeitem.hxx>
30 #include <editeng/wghtitem.hxx>
31 #include <editeng/postitem.hxx>
32 #include <editeng/crossedoutitem.hxx>
33 #include <editeng/udlnitem.hxx>
34 #include <editeng/editobj.hxx>
35 #include <editeng/borderline.hxx>
36 #include <editeng/boxitem.hxx>
37 #include <editeng/fhgtitem.hxx>
38 #include <editeng/brushitem.hxx>
39 #include <editeng/fontitem.hxx>
40 #include <editeng/flditem.hxx>
41 #include <editeng/justifyitem.hxx>
42 #include <editeng/lineitem.hxx>
43 #include <editeng/colritem.hxx>
44 #include <dbdata.hxx>
45 #include <validat.hxx>
46 #include <formulacell.hxx>
47 #include <formulaopt.hxx>
48 #include <userdat.hxx>
49 #include <stlsheet.hxx>
50 #include <docfunc.hxx>
51 #include <markdata.hxx>
52 #include <colorscale.hxx>
53 #include <olinetab.hxx>
54 #include <patattr.hxx>
55 #include <scitems.hxx>
56 #include <docsh.hxx>
57 #include <editutil.hxx>
58 #include <cellvalue.hxx>
59 #include <attrib.hxx>
60 #include <fillinfo.hxx>
61 #include <scopetools.hxx>
62 #include <columnspanset.hxx>
63 #include <tokenstringcontext.hxx>
64 #include <formula/errorcodes.hxx>
65 #include <externalrefmgr.hxx>
66 #include <stlpool.hxx>
67 #include <hints.hxx>
69 #include <orcusfilters.hxx>
70 #include <filter.hxx>
72 #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
73 #include <com/sun/star/drawing/XControlShape.hpp>
74 #include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
75 #include <com/sun/star/container/XIndexAccess.hpp>
76 #include <com/sun/star/text/textfield/Type.hpp>
78 #include "helper/qahelper.hxx"
79 #include "helper/shared_test_impl.hxx"
81 namespace com { namespace sun { namespace star { namespace frame { class XModel; } } } }
83 using namespace ::com::sun::star;
84 using namespace ::com::sun::star::uno;
86 /* Implementation of Filters test */
88 class ScFiltersTest
89 : public test::FiltersTest
90 , public ScBootstrapFixture
92 public:
93 ScFiltersTest();
95 virtual bool load( const OUString &rFilter, const OUString &rURL,
96 const OUString &rUserData, SfxFilterFlags nFilterFlags,
97 SotClipboardFormatId nClipboardID, unsigned int nFilterVersion) override;
99 virtual void setUp() override;
100 virtual void tearDown() override;
102 //ods, xls, xlsx filter tests
103 void testBooleanFormatXLSX();
104 void testBasicCellContentODS();
105 void testRangeNameXLS();
106 void testRangeNameLocalXLS();
107 void testRangeNameXLSX();
108 void testHyperlinksXLSX();
109 void testHardRecalcODS();
110 void testFunctionsODS();
111 void testFunctionsExcel2010();
112 void testCeilingFloorXLSX();
113 void testCachedFormulaResultsODS();
114 void testCachedMatrixFormulaResultsODS();
115 void testFormulaDepAcrossSheetsODS();
116 void testFormulaDepDeleteContentsODS();
117 void testDatabaseRangesODS();
118 void testDatabaseRangesXLS();
119 void testDatabaseRangesXLSX();
120 void testFormatsODS();
121 // void testFormatsXLS();
122 // void testFormatsXLSX();
123 void testMatrixODS();
124 void testMatrixXLS();
125 void testDoubleThinBorder();
126 void testBorderODS();
127 void testBordersOoo33();
128 void testBugFixesODS();
129 void testBugFixesXLS();
130 void testBugFixesXLSX();
131 void testBrokenQuotesCSV();
132 void testMergedCellsODS();
133 void testRepeatedColumnsODS();
134 void testDataValidityODS();
135 void testDataValidityXLSX();
136 void testDataTableMortgageXLS();
137 void testDataTableOneVarXLSX();
138 void testDataTableMultiTableXLSX();
140 void testDataBarODS();
141 void testDataBarXLSX();
142 void testColorScaleODS();
143 void testColorScaleXLSX();
144 void testNewCondFormatODS();
145 void testNewCondFormatXLSX();
146 void testCondFormatThemeColorXLSX();
147 void testCondFormatImportCellIs();
148 void testCondFormatThemeColor2XLSX(); // negative bar color and axis color
149 void testCondFormatThemeColor3XLSX(); // theme index 2 and 3 are switched
150 void testComplexIconSetsXLSX();
151 void testCondFormatParentXLSX();
152 void testColorScaleNumWithRefXLSX();
153 void testCondFormatXLSB();
155 void testOrcusODSStyleInterface();
157 void testLiteralInFormulaXLS();
159 //change this test file only in excel and not in calc
160 void testCellValueXLSX();
163 * Test importing of xlsx document that previously had its row index off
164 * by one. (fdo#76032)
166 void testRowIndex1BasedXLSX();
167 void testErrorOnExternalReferences();
169 //misc tests unrelated to the import filters
170 void testPasswordNew();
171 void testPasswordOld();
172 void testPasswordWrongSHA();
174 //test shape import
175 void testControlImport();
176 void testActiveXOptionButtonGroup();
177 void testChartImportODS();
178 #if HAVE_MORE_FONTS
179 void testChartImportXLS();
180 #endif
182 void testNumberFormatHTML();
183 void testNumberFormatCSV();
185 void testCellAnchoredShapesODS();
186 void testCellAnchoredHiddenShapesXLSX();
188 void testFormulaDependency();
190 void testRowHeightODS();
191 void testRichTextContentODS();
192 void testMiscRowHeights();
193 void testOptimalHeightReset();
194 void testCustomNumFormatHybridCellODS();
195 void testTdf121040();
197 void testPrintRangeODS();
198 void testOutlineODS();
200 void testColumnStyleXLSX();
201 void testColumnStyleAutoFilterXLSX();
203 void testSharedFormulaHorizontalXLS();
204 void testSharedFormulaWrappedRefsXLS();
205 void testSharedFormulaBIFF5();
206 void testSharedFormulaXLSB();
207 void testSharedFormulaXLS();
208 void testSharedFormulaColumnLabelsODS();
209 void testSharedFormulaColumnRowLabelsODS();
210 void testExternalRefCacheXLSX();
211 void testExternalRefCacheODS();
212 void testHybridSharedStringODS();
213 void testCopyMergedNumberFormats();
214 void testVBAUserFunctionXLSM();
215 void testEmbeddedImageXLS();
216 void testEditEngStrikeThroughXLSX();
217 void testRefStringXLSX();
218 void testHiddenSheetsXLSX();
219 void testRelFormulaValidationXLS();
220 void testColumnStyle2XLSX();
221 void testAutofilterXLSX();
223 void testBnc762542();
225 void testTdf100458();
226 void testTdf100709XLSX();
227 void testTdf97598XLSX();
228 void testTdf110440XLSX();
229 void testTdf111974XLSM();
230 void testTdf83672XLSX();
232 void testPageScalingXLSX();
233 void testActiveXCheckboxXLSX();
234 void testtdf120301_xmlSpaceParsingXLSX();
235 #ifdef UNX
236 void testUnicodeFileNameGnumeric();
237 #endif
238 void testCondFormatFormulaListenerXLSX();
240 void testMergedCellsXLSXML();
241 void testBackgroundColorStandardXLSXML();
242 void testNamedExpressionsXLSXML();
243 void testEmptyRowsXLSXML();
244 void testBorderDirectionsXLSXML();
245 void testBorderColorsXLSXML();
246 void testHiddenRowsColumnsXLSXML();
247 void testColumnWidthRowHeightXLSXML();
248 void testCharacterSetXLSXML();
249 void testTdf62268();
250 void testVBAMacroFunctionODS();
251 void testAutoheight2Rows();
252 void testXLSDefColWidth();
253 void testPreviewMissingObjLink();
255 CPPUNIT_TEST_SUITE(ScFiltersTest);
256 CPPUNIT_TEST(testBooleanFormatXLSX);
257 CPPUNIT_TEST(testBasicCellContentODS);
258 CPPUNIT_TEST(testRangeNameXLS);
259 CPPUNIT_TEST(testRangeNameLocalXLS);
260 CPPUNIT_TEST(testRangeNameXLSX);
261 CPPUNIT_TEST(testHyperlinksXLSX);
262 CPPUNIT_TEST(testHardRecalcODS);
263 CPPUNIT_TEST(testFunctionsODS);
264 CPPUNIT_TEST(testFunctionsExcel2010);
265 CPPUNIT_TEST(testCeilingFloorXLSX);
266 CPPUNIT_TEST(testCachedFormulaResultsODS);
267 CPPUNIT_TEST(testFormulaDepAcrossSheetsODS);
268 CPPUNIT_TEST(testFormulaDepDeleteContentsODS);
269 CPPUNIT_TEST(testCachedMatrixFormulaResultsODS);
270 CPPUNIT_TEST(testDatabaseRangesODS);
271 CPPUNIT_TEST(testDatabaseRangesXLS);
272 CPPUNIT_TEST(testDatabaseRangesXLSX);
273 CPPUNIT_TEST(testFormatsODS);
274 // CPPUNIT_TEST(testFormatsXLS); TODO: Fix this
275 // CPPUNIT_TEST(testFormatsXLSX); TODO: Fix this
276 CPPUNIT_TEST(testMatrixODS);
277 CPPUNIT_TEST(testMatrixXLS);
278 CPPUNIT_TEST(testDoubleThinBorder);
279 CPPUNIT_TEST(testBorderODS);
280 CPPUNIT_TEST(testBordersOoo33);
281 CPPUNIT_TEST(testBugFixesODS);
282 CPPUNIT_TEST(testBugFixesXLS);
283 CPPUNIT_TEST(testBugFixesXLSX);
284 CPPUNIT_TEST(testMergedCellsODS);
285 CPPUNIT_TEST(testRepeatedColumnsODS);
286 CPPUNIT_TEST(testDataValidityODS);
287 CPPUNIT_TEST(testDataValidityXLSX);
288 CPPUNIT_TEST(testDataTableMortgageXLS);
289 CPPUNIT_TEST(testDataTableOneVarXLSX);
290 CPPUNIT_TEST(testDataTableMultiTableXLSX);
291 CPPUNIT_TEST(testBrokenQuotesCSV);
292 CPPUNIT_TEST(testCellValueXLSX);
293 CPPUNIT_TEST(testRowIndex1BasedXLSX);
294 CPPUNIT_TEST(testControlImport);
295 CPPUNIT_TEST(testActiveXOptionButtonGroup);
296 CPPUNIT_TEST(testChartImportODS);
297 #if HAVE_MORE_FONTS
298 CPPUNIT_TEST(testChartImportXLS);
299 #endif
301 CPPUNIT_TEST(testDataBarODS);
302 CPPUNIT_TEST(testDataBarXLSX);
303 CPPUNIT_TEST(testColorScaleODS);
304 CPPUNIT_TEST(testColorScaleXLSX);
305 CPPUNIT_TEST(testNewCondFormatODS);
306 CPPUNIT_TEST(testNewCondFormatXLSX);
307 CPPUNIT_TEST(testCondFormatThemeColorXLSX);
308 CPPUNIT_TEST(testCondFormatImportCellIs);
309 CPPUNIT_TEST(testCondFormatThemeColor2XLSX);
310 CPPUNIT_TEST(testCondFormatThemeColor3XLSX);
311 CPPUNIT_TEST(testComplexIconSetsXLSX);
312 CPPUNIT_TEST(testCondFormatParentXLSX);
313 CPPUNIT_TEST(testColorScaleNumWithRefXLSX);
314 CPPUNIT_TEST(testCondFormatXLSB);
316 CPPUNIT_TEST(testOrcusODSStyleInterface);
318 CPPUNIT_TEST(testLiteralInFormulaXLS);
320 CPPUNIT_TEST(testNumberFormatHTML);
321 CPPUNIT_TEST(testNumberFormatCSV);
323 CPPUNIT_TEST(testCellAnchoredShapesODS);
324 CPPUNIT_TEST(testCellAnchoredHiddenShapesXLSX);
326 CPPUNIT_TEST(testRowHeightODS);
327 CPPUNIT_TEST(testFormulaDependency);
328 CPPUNIT_TEST(testRichTextContentODS);
330 //disable testPassword on MacOSX due to problems with libsqlite3
331 //also crashes on DragonFly due to problems with nss/nspr headers
332 CPPUNIT_TEST(testPasswordWrongSHA);
333 CPPUNIT_TEST(testPasswordOld);
334 CPPUNIT_TEST(testPasswordNew);
336 CPPUNIT_TEST(testMiscRowHeights);
337 CPPUNIT_TEST(testOptimalHeightReset);
338 CPPUNIT_TEST(testCustomNumFormatHybridCellODS);
339 CPPUNIT_TEST(testTdf121040);
340 CPPUNIT_TEST(testPrintRangeODS);
341 CPPUNIT_TEST(testOutlineODS);
342 CPPUNIT_TEST(testColumnStyleXLSX);
343 CPPUNIT_TEST(testColumnStyleAutoFilterXLSX);
344 CPPUNIT_TEST(testSharedFormulaHorizontalXLS);
345 CPPUNIT_TEST(testSharedFormulaWrappedRefsXLS);
346 CPPUNIT_TEST(testSharedFormulaBIFF5);
347 CPPUNIT_TEST(testSharedFormulaXLSB);
348 CPPUNIT_TEST(testSharedFormulaXLS);
349 CPPUNIT_TEST(testSharedFormulaColumnLabelsODS);
350 CPPUNIT_TEST(testSharedFormulaColumnRowLabelsODS);
351 CPPUNIT_TEST(testExternalRefCacheXLSX);
352 CPPUNIT_TEST(testExternalRefCacheODS);
353 CPPUNIT_TEST(testHybridSharedStringODS);
354 CPPUNIT_TEST(testCopyMergedNumberFormats);
355 CPPUNIT_TEST(testVBAUserFunctionXLSM);
356 CPPUNIT_TEST(testEmbeddedImageXLS);
357 CPPUNIT_TEST(testErrorOnExternalReferences);
358 CPPUNIT_TEST(testEditEngStrikeThroughXLSX);
359 CPPUNIT_TEST(testRefStringXLSX);
360 CPPUNIT_TEST(testRelFormulaValidationXLS);
361 CPPUNIT_TEST(testColumnStyle2XLSX);
362 CPPUNIT_TEST(testAutofilterXLSX);
364 CPPUNIT_TEST(testBnc762542);
366 CPPUNIT_TEST(testHiddenSheetsXLSX);
368 CPPUNIT_TEST(testTdf100458);
369 CPPUNIT_TEST(testTdf100709XLSX);
370 CPPUNIT_TEST(testTdf97598XLSX);
371 CPPUNIT_TEST(testTdf110440XLSX);
372 CPPUNIT_TEST(testTdf111974XLSM);
373 CPPUNIT_TEST(testTdf83672XLSX);
375 CPPUNIT_TEST(testPageScalingXLSX);
376 CPPUNIT_TEST(testActiveXCheckboxXLSX);
377 CPPUNIT_TEST(testtdf120301_xmlSpaceParsingXLSX);
378 #ifdef UNX
379 CPPUNIT_TEST(testUnicodeFileNameGnumeric);
380 #endif
381 CPPUNIT_TEST(testMergedCellsXLSXML);
382 CPPUNIT_TEST(testBackgroundColorStandardXLSXML);
383 CPPUNIT_TEST(testNamedExpressionsXLSXML);
384 CPPUNIT_TEST(testEmptyRowsXLSXML);
385 CPPUNIT_TEST(testBorderDirectionsXLSXML);
386 CPPUNIT_TEST(testBorderColorsXLSXML);
387 CPPUNIT_TEST(testHiddenRowsColumnsXLSXML);
388 CPPUNIT_TEST(testColumnWidthRowHeightXLSXML);
389 CPPUNIT_TEST(testCharacterSetXLSXML);
390 CPPUNIT_TEST(testCondFormatFormulaListenerXLSX);
391 CPPUNIT_TEST(testTdf62268);
392 CPPUNIT_TEST(testVBAMacroFunctionODS);
393 CPPUNIT_TEST(testAutoheight2Rows);
394 CPPUNIT_TEST(testXLSDefColWidth);
395 CPPUNIT_TEST(testPreviewMissingObjLink);
397 CPPUNIT_TEST_SUITE_END();
399 private:
400 void testPassword_Impl(const OUString& rFileNameBase);
402 uno::Reference<uno::XInterface> m_xCalcComponent;
405 bool ScFiltersTest::load(const OUString &rFilter, const OUString &rURL,
406 const OUString &rUserData, SfxFilterFlags nFilterFlags,
407 SotClipboardFormatId nClipboardID, unsigned int nFilterVersion)
409 ScDocShellRef xDocShRef = ScBootstrapFixture::load( rURL, rFilter, rUserData,
410 OUString(), nFilterFlags, nClipboardID, nFilterVersion);
411 bool bLoaded = xDocShRef.is();
412 //reference counting of ScDocShellRef is very confused.
413 if (bLoaded)
414 xDocShRef->DoClose();
415 return bLoaded;
418 namespace {
420 void testRangeNameImpl(const ScDocument& rDoc)
422 //check one range data per sheet and one global more detailed
423 //add some more checks here
424 ScRangeData* pRangeData = rDoc.GetRangeName()->findByUpperName(OUString("GLOBAL1"));
425 CPPUNIT_ASSERT_MESSAGE("range name Global1 not found", pRangeData);
426 double aValue;
427 rDoc.GetValue(1,0,0,aValue);
428 CPPUNIT_ASSERT_EQUAL_MESSAGE("range name Global1 should reference Sheet1.A1", 1.0, aValue);
429 pRangeData = rDoc.GetRangeName(0)->findByUpperName(OUString("LOCAL1"));
430 CPPUNIT_ASSERT_MESSAGE("range name Sheet1.Local1 not found", pRangeData);
431 rDoc.GetValue(1,2,0,aValue);
432 CPPUNIT_ASSERT_EQUAL_MESSAGE("range name Sheet1.Local1 should reference Sheet1.A3", 3.0, aValue);
433 pRangeData = rDoc.GetRangeName(1)->findByUpperName(OUString("LOCAL2"));
434 CPPUNIT_ASSERT_MESSAGE("range name Sheet2.Local2 not found", pRangeData);
435 rDoc.GetValue(1,1,1,aValue);
436 CPPUNIT_ASSERT_EQUAL_MESSAGE("range name Sheet2.Local2 should reference Sheet2.A2", 7.0, aValue);
437 //check for correct results for the remaining formulas
438 rDoc.GetValue(1,1,0, aValue);
439 CPPUNIT_ASSERT_EQUAL_MESSAGE("=global2 should be 2", 2.0, aValue);
440 rDoc.GetValue(1,3,0, aValue);
441 CPPUNIT_ASSERT_EQUAL_MESSAGE("=local2 should be 4", 4.0, aValue);
442 rDoc.GetValue(2,0,0, aValue);
443 CPPUNIT_ASSERT_EQUAL_MESSAGE("=SUM(global3) should be 10", 10.0, aValue);
444 rDoc.GetValue(1,0,1,aValue);
445 CPPUNIT_ASSERT_EQUAL_MESSAGE("range name Sheet2.local1 should reference Sheet1.A5", 5.0, aValue);
446 // Test if Global5 ( which depends on Global6 ) is evaluated
447 rDoc.GetValue(0,5,1, aValue);
448 CPPUNIT_ASSERT_EQUAL_MESSAGE("formula Global5 should reference Global6 ( which is evaluated as local1 )", 5.0, aValue);
453 void ScFiltersTest::testBasicCellContentODS()
455 ScDocShellRef xDocSh = loadDoc("basic-cell-content.", FORMAT_ODS);
456 CPPUNIT_ASSERT_MESSAGE("Failed to load basic-cell-content.ods", xDocSh.is());
458 ScDocument& rDoc = xDocSh->GetDocument();
459 OUString aStr = rDoc.GetString(1, 1, 0); // B2
460 CPPUNIT_ASSERT_EQUAL(OUString("LibreOffice Calc"), aStr);
461 double fVal = rDoc.GetValue(1, 2, 0); // B3
462 CPPUNIT_ASSERT_EQUAL(12345.0, fVal);
463 aStr = rDoc.GetString(1, 3, 0); // B4
464 CPPUNIT_ASSERT_EQUAL(OUString("A < B"), aStr);
466 // Numeric value of 0.
467 ScRefCellValue aCell;
468 aCell.assign(rDoc, ScAddress(1,4,0)); // B5
469 CPPUNIT_ASSERT_EQUAL_MESSAGE(
470 "This cell must be numeric.", CELLTYPE_VALUE, aCell.meType);
471 CPPUNIT_ASSERT_EQUAL(0.0, aCell.mfValue);
473 xDocSh->DoClose();
476 void ScFiltersTest::testBooleanFormatXLSX()
478 ScDocShellRef xDocSh = loadDoc("check-boolean.", FORMAT_XLSX);
479 ScDocument& rDoc = xDocSh->GetDocument();
480 SvNumberFormatter* pNumFormatter = rDoc.GetFormatTable();
481 // Saved as >"TRUE";"TRUE";"FALSE"< but reading converted back to >BOOLEAN<
482 const OUString aBooleanTypeStr = "BOOLEAN";
484 CPPUNIT_ASSERT_MESSAGE("Failed to load check-boolean.xlsx", xDocSh.is());
485 sal_uInt32 nNumberFormat;
487 for (SCROW i = 0; i <= 1; i++)
489 rDoc.GetNumberFormat(0, i, 0, nNumberFormat);
490 const SvNumberformat* pNumberFormat = pNumFormatter->GetEntry(nNumberFormat);
491 const OUString& rFormatStr = pNumberFormat->GetFormatstring();
492 CPPUNIT_ASSERT_EQUAL_MESSAGE("Number format != boolean", aBooleanTypeStr, rFormatStr);
495 xDocSh->DoClose();
498 void ScFiltersTest::testRangeNameXLS()
500 ScDocShellRef xDocSh = loadDoc("named-ranges-global.", FORMAT_XLS);
501 xDocSh->DoHardRecalc();
503 ScDocument& rDoc = xDocSh->GetDocument();
504 testRangeNameImpl(rDoc);
506 OUString aCSVPath;
507 createCSVPath( "rangeExp_Sheet2.", aCSVPath );
508 // fdo#44587
509 testFile( aCSVPath, rDoc, 1);
511 xDocSh->DoClose();
514 void ScFiltersTest::testRangeNameLocalXLS()
516 ScDocShellRef xDocSh = loadDoc("named-ranges-local.", FORMAT_XLS);
517 xDocSh->DoHardRecalc();
519 ScDocument& rDoc = xDocSh->GetDocument();
520 ScRangeName* pRangeName = rDoc.GetRangeName(0);
521 CPPUNIT_ASSERT(pRangeName);
522 CPPUNIT_ASSERT_EQUAL(size_t(2), pRangeName->size());
524 OUString aFormula;
525 rDoc.GetFormula(3, 11, 0, aFormula);
526 CPPUNIT_ASSERT_EQUAL(OUString("=SUM(local_name2)"), aFormula);
527 ASSERT_DOUBLES_EQUAL(14.0, rDoc.GetValue(3, 11, 0));
529 rDoc.GetFormula(6, 4, 0, aFormula);
530 CPPUNIT_ASSERT_EQUAL(OUString("=local_name1"), aFormula);
532 xDocSh->DoClose();
535 void ScFiltersTest::testRangeNameXLSX()
537 ScDocShellRef xDocSh = loadDoc("named-ranges-global.", FORMAT_XLSX);
538 xDocSh->DoHardRecalc();
540 ScDocument& rDoc = xDocSh->GetDocument();
541 testRangeNameImpl(rDoc);
543 xDocSh->DoClose();
546 void ScFiltersTest::testHyperlinksXLSX()
548 ScDocShellRef xDocSh = loadDoc("hyperlinks.", FORMAT_XLSX);
549 ScDocument& rDoc = xDocSh->GetDocument();
551 CPPUNIT_ASSERT_EQUAL(OUString("10:ABC10"), rDoc.GetString(ScAddress(0,1,0)));
552 CPPUNIT_ASSERT_EQUAL(OUString("10:ABC11"), rDoc.GetString(ScAddress(0,2,0)));
553 CPPUNIT_ASSERT_EQUAL(OUString("10:ABC12"), rDoc.GetString(ScAddress(0,3,0)));
555 xDocSh->DoClose();
558 void ScFiltersTest::testHardRecalcODS()
560 ScDocShellRef xDocSh = loadDoc("hard-recalc.", FORMAT_ODS);
561 xDocSh->DoHardRecalc();
563 CPPUNIT_ASSERT_MESSAGE("Failed to load hard-recalc.*", xDocSh.is());
564 ScDocument& rDoc = xDocSh->GetDocument();
565 OUString aCSVFileName;
567 //test hard recalc: document has an incorrect cached formula result
568 //hard recalc should have updated to the correct result
569 createCSVPath("hard-recalc.", aCSVFileName);
570 testFile(aCSVFileName, rDoc, 0);
572 xDocSh->DoClose();
575 void ScFiltersTest::testFunctionsODS()
577 ScDocShellRef xDocSh = loadDoc("functions.", FORMAT_ODS);
578 xDocSh->DoHardRecalc();
580 CPPUNIT_ASSERT_MESSAGE("Failed to load functions.*", xDocSh.is());
581 ScDocument& rDoc = xDocSh->GetDocument();
582 OUString aCSVFileName;
584 //test logical functions
585 createCSVPath("logical-functions.", aCSVFileName);
586 testFile(aCSVFileName, rDoc, 0);
587 //test spreadsheet functions
588 createCSVPath("spreadsheet-functions.", aCSVFileName);
589 testFile(aCSVFileName, rDoc, 1);
590 //test mathematical functions
591 createCSVPath("mathematical-functions.", aCSVFileName);
592 testFile(aCSVFileName, rDoc, 2, StringType::PureString);
593 //test information functions
594 createCSVPath("information-functions.", aCSVFileName);
595 testFile(aCSVFileName, rDoc, 3);
596 // text functions
597 createCSVPath("text-functions.", aCSVFileName);
598 testFile(aCSVFileName, rDoc, 4, StringType::PureString);
599 // statistical functions
600 createCSVPath("statistical-functions.", aCSVFileName);
601 testFile(aCSVFileName, rDoc, 5);
602 // financial functions
603 createCSVPath("financial-functions.", aCSVFileName);
604 testFile(aCSVFileName, rDoc, 6);
606 xDocSh->DoClose();
608 xDocSh = loadDoc("database-functions.", FORMAT_ODS);
609 CPPUNIT_ASSERT_MESSAGE("Failed to load functions.*", xDocSh.is());
610 xDocSh->DoHardRecalc();
611 ScDocument& rDoc2 = xDocSh->GetDocument();
613 createCSVPath("database-functions.", aCSVFileName);
614 testFile(aCSVFileName, rDoc2, 0);
616 xDocSh->DoClose();
618 xDocSh = loadDoc("date-time-functions.", FORMAT_ODS);
619 CPPUNIT_ASSERT_MESSAGE("Failed to load functions.*", xDocSh.is());
620 xDocSh->DoHardRecalc();
621 ScDocument& rDoc3 = xDocSh->GetDocument();
622 createCSVPath("date-time-functions.", aCSVFileName);
623 testFile(aCSVFileName, rDoc3, 0, StringType::PureString);
625 xDocSh->DoClose();
627 // crashes at exit while unloading StarBasic code
628 // xDocSh = loadDoc("user-defined-function.", FORMAT_ODS);
629 // xDocSh->DoHardRecalc();
630 // ScDocument& rDocUserDef = xDocSh->GetDocument();
631 // createCSVPath("user-defined-function.", aCSVFileName);
632 // testFile(aCSVFileName, rDocUserDef, 0);
635 void ScFiltersTest::testFunctionsExcel2010()
637 ScDocShellRef xDocSh = loadDoc("functions-excel-2010.", FORMAT_XLSX);
638 CPPUNIT_ASSERT_MESSAGE("Failed to load the document.", xDocSh.is());
639 ScDocument& rDoc = xDocSh->GetDocument();
640 rDoc.CalcAll(); // perform hard re-calculation.
642 testFunctionsExcel2010_Impl(rDoc);
644 xDocSh->DoClose();
647 void ScFiltersTest::testCeilingFloorXLSX()
649 ScDocShellRef xDocSh = loadDoc("ceiling-floor.", FORMAT_XLSX);
650 CPPUNIT_ASSERT_MESSAGE("Failed to load the document.", xDocSh.is());
651 ScDocument& rDoc = xDocSh->GetDocument();
652 rDoc.CalcAll(); // perform hard re-calculation.
654 testCeilingFloor_Impl(rDoc);
656 xDocSh->DoClose();
659 void ScFiltersTest::testCachedFormulaResultsODS()
662 ScDocShellRef xDocSh = loadDoc("functions.", FORMAT_ODS);
663 CPPUNIT_ASSERT_MESSAGE("Failed to load functions.*", xDocSh.is());
665 ScDocument& rDoc = xDocSh->GetDocument();
666 OUString aCSVFileName;
668 //test cached formula results of logical functions
669 createCSVPath("logical-functions.", aCSVFileName);
670 testFile(aCSVFileName, rDoc, 0);
671 //test cached formula results of spreadsheet functions
672 createCSVPath("spreadsheet-functions.", aCSVFileName);
673 testFile(aCSVFileName, rDoc, 1);
674 //test cached formula results of mathematical functions
675 createCSVPath("mathematical-functions.", aCSVFileName);
676 testFile(aCSVFileName, rDoc, 2, StringType::PureString);
677 //test cached formula results of information functions
678 createCSVPath("information-functions.", aCSVFileName);
679 testFile(aCSVFileName, rDoc, 3);
680 // text functions
681 createCSVPath("text-functions.", aCSVFileName);
682 testFile(aCSVFileName, rDoc, 4, StringType::PureString);
684 xDocSh->DoClose();
688 ScDocShellRef xDocSh = loadDoc("cachedValue.", FORMAT_ODS);
689 CPPUNIT_ASSERT_MESSAGE("Failed to load cachedValue.*", xDocSh.is());
691 ScDocument& rDoc = xDocSh->GetDocument();
692 OUString aCSVFileName;
693 createCSVPath("cachedValue.", aCSVFileName);
694 testFile(aCSVFileName, rDoc, 0);
696 //we want to me sure that volatile functions are always recalculated
697 //regardless of cached results. if you update the ods file, you must
698 //update the values here.
699 //if NOW() is recalculated, then it should never equal sTodayCache
700 OUString const sTodayCache("01/25/13 01:06 PM");
701 OUString sTodayRecalc(rDoc.GetString(0,0,1));
703 CPPUNIT_ASSERT(sTodayCache != sTodayRecalc);
705 OUString sTodayRecalcRef(rDoc.GetString(1,0,1));
706 CPPUNIT_ASSERT_EQUAL(sTodayRecalc, sTodayRecalcRef);
708 // make sure that error values are not being treated as string values
709 for(SCCOL nCol = 0; nCol < 4; ++nCol)
711 for(SCROW nRow = 0; nRow < 2; ++nRow)
713 OUString aFormula = "=ISERROR(" +
714 OUStringChar(static_cast<char>('A'+nCol)) + OUString::number(nRow) +
715 ")";
716 rDoc.SetString(nCol, nRow + 2, 2, aFormula);
717 CPPUNIT_ASSERT_EQUAL_MESSAGE(OUStringToOString(aFormula, RTL_TEXTENCODING_UTF8).getStr(), OUString("TRUE"), rDoc.GetString(nCol, nRow +2, 2));
719 OUString aIsTextFormula = "=ISTEXT(" +
720 OUString::number(static_cast<char>('A'+nCol))+ OUString::number(nRow) +
721 ")";
722 rDoc.SetString(nCol, nRow + 4, 2, aIsTextFormula);
723 CPPUNIT_ASSERT_EQUAL(OUString("FALSE"), rDoc.GetString(nCol, nRow +4, 2));
727 xDocSh->DoClose();
731 void ScFiltersTest::testCachedMatrixFormulaResultsODS()
733 ScDocShellRef xDocSh = loadDoc("matrix.", FORMAT_ODS);
735 CPPUNIT_ASSERT_MESSAGE("Failed to load matrix.*", xDocSh.is());
736 ScDocument& rDoc = xDocSh->GetDocument();
738 //test matrix
739 OUString aCSVFileName;
740 createCSVPath("matrix.", aCSVFileName);
741 testFile(aCSVFileName, rDoc, 0);
742 //test matrices with special cases
743 createCSVPath("matrix2.", aCSVFileName);
744 testFile(aCSVFileName, rDoc, 1);
745 createCSVPath("matrix3.", aCSVFileName);
746 testFile(aCSVFileName, rDoc, 2);
747 //The above testFile() does not catch the below case.
748 //If a matrix formula has a matrix reference cell that is intended to have
749 //a blank text result, the matrix reference cell is actually saved(export)
750 //as a float cell with 0 as the value and an empty <text:p/>.
751 //Import works around this by setting these cells as text cells so that
752 //the blank text is used for display instead of the number 0.
753 //If this is working properly, the following cell should NOT have value data.
754 CPPUNIT_ASSERT_EQUAL(OUString(), rDoc.GetString(3,0,2));
756 // fdo#59293 with cached value import error formulas require special
757 // treatment
758 rDoc.SetString(2, 5, 2, "=ISERROR(A6)");
759 double nVal = rDoc.GetValue(2,5,2);
760 CPPUNIT_ASSERT_EQUAL(1.0, nVal);
762 xDocSh->DoClose();
765 void ScFiltersTest::testFormulaDepAcrossSheetsODS()
767 ScDocShellRef xDocSh = loadDoc("formula-across-sheets.", FORMAT_ODS);
768 CPPUNIT_ASSERT_MESSAGE("Failed to load the file.", xDocSh.is());
769 ScDocument& rDoc = xDocSh->GetDocument();
771 sc::AutoCalcSwitch aACSwitch(rDoc, true); // Make sure auto calc is turned on.
773 // Save the original values of A4:C4.
774 double fA4 = rDoc.GetValue(ScAddress(0,3,2));
775 double fB4 = rDoc.GetValue(ScAddress(1,3,2));
776 double fC4 = rDoc.GetValue(ScAddress(2,3,2));
778 // Change the value of D4. This should trigger A4:C4 to be recalculated.
779 double fD4 = rDoc.GetValue(ScAddress(3,3,2));
780 rDoc.SetValue(ScAddress(3,3,2), fD4+1.0);
782 CPPUNIT_ASSERT_MESSAGE("The value must differ from the original.", fA4 != rDoc.GetValue(ScAddress(0,3,2)));
783 CPPUNIT_ASSERT_MESSAGE("The value must differ from the original.", fB4 != rDoc.GetValue(ScAddress(1,3,2)));
784 CPPUNIT_ASSERT_MESSAGE("The value must differ from the original.", fC4 != rDoc.GetValue(ScAddress(2,3,2)));
786 xDocSh->DoClose();
789 void ScFiltersTest::testFormulaDepDeleteContentsODS()
791 ScDocShellRef xDocSh = loadDoc("formula-delete-contents.", FORMAT_ODS, true);
792 CPPUNIT_ASSERT_MESSAGE("Failed to load the file.", xDocSh.is());
793 ScDocument& rDoc = xDocSh->GetDocument();
795 sc::UndoSwitch aUndoSwitch(rDoc, true); // Enable undo.
796 sc::AutoCalcSwitch aACSwitch(rDoc, true); // Make sure auto calc is turned on.
798 CPPUNIT_ASSERT_EQUAL(195.0, rDoc.GetValue(ScAddress(3,15,0))); // formula in D16
800 // Delete D2:D5.
801 ScDocFunc& rFunc = xDocSh->GetDocFunc();
802 ScRange aRange(3,1,0,3,4,0);
803 ScMarkData aMark(MAXROW, MAXCOL);
804 aMark.SetMarkArea(aRange);
805 aMark.MarkToMulti();
806 bool bGood = rFunc.DeleteContents(aMark, InsertDeleteFlags::ALL, true, true);
807 CPPUNIT_ASSERT(bGood);
808 CPPUNIT_ASSERT_EQUAL(0.0, rDoc.GetValue(ScAddress(3,1,0)));
809 CPPUNIT_ASSERT_EQUAL(0.0, rDoc.GetValue(ScAddress(3,2,0)));
810 CPPUNIT_ASSERT_EQUAL(0.0, rDoc.GetValue(ScAddress(3,3,0)));
811 CPPUNIT_ASSERT_EQUAL(0.0, rDoc.GetValue(ScAddress(3,4,0)));
813 CPPUNIT_ASSERT_EQUAL(94.0, rDoc.GetValue(ScAddress(3,15,0))); // formula in D16
815 SfxUndoManager* pUndoMgr = rDoc.GetUndoManager();
816 CPPUNIT_ASSERT(pUndoMgr);
817 pUndoMgr->Undo();
818 CPPUNIT_ASSERT_EQUAL(195.0, rDoc.GetValue(ScAddress(3,15,0))); // formula in D16
820 xDocSh->DoClose();
823 namespace {
825 void testDBRanges_Impl(ScDocument& rDoc, sal_Int32 nFormat)
827 ScDBCollection* pDBCollection = rDoc.GetDBCollection();
828 CPPUNIT_ASSERT_MESSAGE("no database collection", pDBCollection);
830 ScDBData* pAnonDBData = rDoc.GetAnonymousDBData(0);
831 CPPUNIT_ASSERT_MESSAGE("missing anonymous DB data in sheet 1", pAnonDBData);
832 //control hidden rows
833 bool bHidden;
834 SCROW nRow1, nRow2;
835 bHidden = rDoc.RowHidden(0, 0, &nRow1, &nRow2);
836 CPPUNIT_ASSERT_MESSAGE("Sheet1: row 0 should be visible", !bHidden && nRow1 == 0 && nRow2 == 0);
837 bHidden = rDoc.RowHidden(1, 0, &nRow1, &nRow2);
838 CPPUNIT_ASSERT_MESSAGE("Sheet1: rows 1-2 should be hidden", bHidden && nRow1 == 1 && nRow2 == 2);
839 bHidden = rDoc.RowHidden(3, 0, &nRow1, &nRow2);
840 CPPUNIT_ASSERT_MESSAGE("Sheet1: row 3 should be visible", !bHidden && nRow1 == 3 && nRow2 == 3);
841 bHidden = rDoc.RowHidden(4, 0, &nRow1, &nRow2);
842 CPPUNIT_ASSERT_MESSAGE("Sheet1: row 4-5 should be hidden", bHidden && nRow1 == 4 && nRow2 == 5);
843 bHidden = rDoc.RowHidden(6, 0, &nRow1, &nRow2);
844 CPPUNIT_ASSERT_MESSAGE("Sheet1: row 6-end should be visible", !bHidden && nRow1 == 6 && nRow2 == MAXROW);
845 if (nFormat == FORMAT_ODS) //excel doesn't support named db ranges
847 double aValue;
848 rDoc.GetValue(0,10,1, aValue);
849 CPPUNIT_ASSERT_EQUAL_MESSAGE("Sheet2: A11: formula result is incorrect", 4.0, aValue);
850 rDoc.GetValue(1, 10, 1, aValue);
851 CPPUNIT_ASSERT_EQUAL_MESSAGE("Sheet2: B11: formula result is incorrect", 2.0, aValue);
853 double aValue;
854 rDoc.GetValue(3,10,1, aValue);
855 CPPUNIT_ASSERT_EQUAL_MESSAGE("Sheet2: D11: formula result is incorrect", 4.0, aValue);
856 rDoc.GetValue(4, 10, 1, aValue);
857 CPPUNIT_ASSERT_EQUAL_MESSAGE("Sheet2: E11: formula result is incorrect", 2.0, aValue);
862 void ScFiltersTest::testDatabaseRangesODS()
864 ScDocShellRef xDocSh = loadDoc("database.", FORMAT_ODS);
865 xDocSh->DoHardRecalc();
867 ScDocument& rDoc = xDocSh->GetDocument();
869 testDBRanges_Impl(rDoc, FORMAT_ODS);
870 xDocSh->DoClose();
873 void ScFiltersTest::testDatabaseRangesXLS()
875 ScDocShellRef xDocSh = loadDoc("database.", FORMAT_XLS);
876 xDocSh->DoHardRecalc();
878 ScDocument& rDoc = xDocSh->GetDocument();
880 testDBRanges_Impl(rDoc, FORMAT_XLS);
881 xDocSh->DoClose();
884 void ScFiltersTest::testDatabaseRangesXLSX()
886 ScDocShellRef xDocSh = loadDoc("database.", FORMAT_XLSX);
887 xDocSh->DoHardRecalc();
889 ScDocument& rDoc = xDocSh->GetDocument();
891 testDBRanges_Impl(rDoc, FORMAT_XLSX);
892 xDocSh->DoClose();
895 void ScFiltersTest::testFormatsODS()
897 ScDocShellRef xDocSh = loadDoc("formats.", FORMAT_ODS);
898 xDocSh->DoHardRecalc();
900 ScDocument& rDoc = xDocSh->GetDocument();
902 testFormats(this, &rDoc, FORMAT_ODS);
903 xDocSh->DoClose();
906 // void ScFiltersTest::testFormatsXLS()
907 // {
908 // ScDocShellRef xDocSh = loadDoc("formats.", FORMAT_XLS);
909 // xDocSh->DoHardRecalc();
911 // ScDocument& rDoc = xDocSh->GetDocument();
913 // testFormats(this, rDoc, FORMAT_XLS);
914 // xDocSh->DoClose();
915 // }
917 // void ScFiltersTest::testFormatsXLSX()
918 // {
919 // ScDocShellRef xDocSh = loadDoc("formats.", FORMAT_XLSX);
920 // xDocSh->DoHardRecalc();
922 // ScDocument& rDoc = xDocSh->GetDocument();
924 // testFormats(this, rDoc, FORMAT_XLSX);
925 // xDocSh->DoClose();
926 // }
928 void ScFiltersTest::testMatrixODS()
930 ScDocShellRef xDocSh = loadDoc("matrix.", FORMAT_ODS);
931 xDocSh->DoHardRecalc();
933 ScDocument& rDoc = xDocSh->GetDocument();
935 OUString aCSVFileName;
936 createCSVPath("matrix.", aCSVFileName);
937 testFile(aCSVFileName, rDoc, 0);
939 xDocSh->DoClose();
942 void ScFiltersTest::testMatrixXLS()
944 ScDocShellRef xDocSh = loadDoc("matrix.", FORMAT_XLS);
945 xDocSh->DoHardRecalc();
947 CPPUNIT_ASSERT_MESSAGE("Failed to load matrix.*", xDocSh.is());
948 ScDocument& rDoc = xDocSh->GetDocument();
950 OUString aCSVFileName;
951 createCSVPath("matrix.", aCSVFileName);
952 testFile(aCSVFileName, rDoc, 0);
954 xDocSh->DoClose();
957 void ScFiltersTest::testDoubleThinBorder()
959 // double-thin borders created with size less than 1.15 where invisible (and subsequently lost) on round-trips.
960 ScDocShellRef xDocSh = loadDoc("tdf88827_borderDoubleThin.", FORMAT_ODS);
962 CPPUNIT_ASSERT_MESSAGE("Failed to load tdf88827_borderDoubleThin.*", xDocSh.is());
963 ScDocument& rDoc = xDocSh->GetDocument();
965 const editeng::SvxBorderLine* pLeft = nullptr;
966 const editeng::SvxBorderLine* pTop = nullptr;
967 const editeng::SvxBorderLine* pRight = nullptr;
968 const editeng::SvxBorderLine* pBottom = nullptr;
970 rDoc.GetBorderLines( 2, 2, 0, &pLeft, &pTop, &pRight, &pBottom );
971 CPPUNIT_ASSERT(pTop);
972 CPPUNIT_ASSERT(pRight);
973 CPPUNIT_ASSERT_EQUAL( SvxBorderLineStyle::DOUBLE_THIN, pRight->GetBorderLineStyle() );
974 xDocSh->DoClose();
977 void ScFiltersTest::testBorderODS()
979 ScDocShellRef xDocSh = loadDoc("border.", FORMAT_ODS);
981 CPPUNIT_ASSERT_MESSAGE("Failed to load border.*", xDocSh.is());
982 ScDocument& rDoc = xDocSh->GetDocument();
984 const editeng::SvxBorderLine* pLeft = nullptr;
985 const editeng::SvxBorderLine* pTop = nullptr;
986 const editeng::SvxBorderLine* pRight = nullptr;
987 const editeng::SvxBorderLine* pBottom = nullptr;
989 rDoc.GetBorderLines( 0, 1, 0, &pLeft, &pTop, &pRight, &pBottom );
990 CPPUNIT_ASSERT(!pLeft);
991 CPPUNIT_ASSERT(!pTop);
992 CPPUNIT_ASSERT(!pBottom);
993 CPPUNIT_ASSERT(pRight);
994 CPPUNIT_ASSERT_EQUAL(SvxBorderLineStyle::SOLID, pRight->GetBorderLineStyle());
996 rDoc.GetBorderLines( 2, 1, 0, &pLeft, &pTop, &pRight, &pBottom );
997 CPPUNIT_ASSERT(!pLeft);
998 CPPUNIT_ASSERT(!pTop);
999 CPPUNIT_ASSERT(!pBottom);
1001 CPPUNIT_ASSERT(pRight);
1002 CPPUNIT_ASSERT_EQUAL(SvxBorderLineStyle::SOLID, pRight->GetBorderLineStyle());
1003 CPPUNIT_ASSERT_EQUAL(20L, pRight->GetWidth());
1005 rDoc.GetBorderLines( 2, 8, 0, &pLeft, &pTop, &pRight, &pBottom );
1007 CPPUNIT_ASSERT(pLeft);
1008 CPPUNIT_ASSERT(pTop);
1009 CPPUNIT_ASSERT(pBottom);
1010 CPPUNIT_ASSERT(pRight);
1011 CPPUNIT_ASSERT_EQUAL(SvxBorderLineStyle::SOLID, pRight->GetBorderLineStyle());
1012 CPPUNIT_ASSERT_EQUAL(5L, pRight->GetWidth());
1013 CPPUNIT_ASSERT_EQUAL(COL_BLUE, pRight->GetColor());
1015 xDocSh->DoClose();
1018 struct Border
1020 sal_Int16 column;
1021 sal_Int32 row;
1022 long leftWidth;
1023 long topWidth;
1024 long rightWidth;
1025 long bottomWidth;
1026 sal_uInt16 lOutWidth;
1027 sal_uInt16 lInWidth;
1028 sal_uInt16 lDistance;
1029 sal_uInt16 tOutWidth;
1030 sal_uInt16 tInWidth;
1031 sal_uInt16 tDistance;
1032 sal_uInt16 rOutWidth;
1033 sal_uInt16 rInWidth;
1034 sal_uInt16 rDistance;
1035 sal_uInt16 bOutWidth;
1036 sal_uInt16 bInWidth;
1037 sal_uInt16 bDistance;
1038 SvxBorderLineStyle lStyle;
1039 SvxBorderLineStyle tStyle;
1040 SvxBorderLineStyle rStyle;
1041 SvxBorderLineStyle bStyle;
1042 // that's a monster
1043 Border(sal_Int16 col, sal_Int32 r, sal_Int32 lW, sal_Int32 tW, sal_Int32 rW, sal_Int32 bW, sal_uInt16 lOutW, sal_uInt16 lInW,
1044 sal_uInt16 lDist, sal_uInt16 tOutW, sal_uInt16 tInW, sal_uInt16 tDist, sal_uInt16 rOutW, sal_uInt16 rInW, sal_uInt16 rDist,
1045 sal_uInt16 bOutW, sal_uInt16 bInW, sal_uInt16 bDist, sal_Int16 lSt, sal_Int16 tSt, sal_Int16 rSt, sal_Int16 bSt):
1046 column(col), row(r), leftWidth(lW), topWidth(tW), rightWidth(rW), bottomWidth(bW), lOutWidth(lOutW), lInWidth(lInW), lDistance(lDist),
1047 tOutWidth(tOutW), tInWidth(tInW), tDistance(tDist), rOutWidth(rOutW), rInWidth(rInW), rDistance(rDist), bOutWidth(bOutW), bInWidth(bInW),
1048 bDistance(bDist),
1049 lStyle(static_cast<SvxBorderLineStyle>(lSt)), tStyle(static_cast<SvxBorderLineStyle>(tSt)), rStyle(static_cast<SvxBorderLineStyle>(rSt)), bStyle(static_cast<SvxBorderLineStyle>(bSt)) {};
1052 void ScFiltersTest::testBordersOoo33()
1054 std::vector<Border> borders;
1055 borders.emplace_back(1, 1, 22, 22, 22, 22, 1, 1, 20, 1, 1, 20, 1, 1, 20, 1, 1, 20, 3, 3, 3, 3);
1056 borders.emplace_back(1, 3, 52, 52, 52, 52, 1, 1, 50, 1, 1, 50, 1, 1, 50, 1, 1, 50, 3, 3, 3, 3);
1057 borders.emplace_back(1, 5, 60, 60, 60, 60, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 3, 3, 3, 3);
1058 borders.emplace_back(1, 7, 150, 150, 150, 150, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 3, 3, 3, 3);
1059 borders.emplace_back(1, 9, 71, 71, 71, 71, 20, 1, 50, 20, 1, 50, 20, 1, 50, 20, 1, 50, 3, 3, 3, 3);
1060 borders.emplace_back(1, 11, 101, 101, 101, 101, 50, 1, 50, 50, 1, 50, 50, 1, 50, 50, 1, 50, 3, 3, 3, 3);
1061 borders.emplace_back(1, 13, 131, 131, 131, 131, 80, 1, 50, 80, 1, 50, 80, 1, 50, 80, 1, 50, 3, 3, 3, 3);
1062 borders.emplace_back(1, 15, 120, 120, 120, 120, 50, 20, 50, 50, 20, 50, 50, 20, 50, 50, 20, 50, 3, 3, 3, 3);
1063 borders.emplace_back(1, 17, 90, 90, 90, 90, 20, 50, 20, 20, 50, 20, 20, 50, 20, 20, 50, 20, 3, 3, 3, 3);
1064 borders.emplace_back(1, 19, 180, 180, 180, 180, 80, 50, 50, 80, 50, 50, 80, 50, 50, 80, 50, 50, 3, 3, 3, 3);
1065 borders.emplace_back(1, 21, 180, 180, 180, 180, 50, 80, 50, 50, 80, 50, 50, 80, 50, 50, 80, 50, 3, 3, 3, 3);
1066 borders.emplace_back(4, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0);
1067 borders.emplace_back(4, 3, 10, 10, 10, 10, 10, 0, 0, 10, 0, 0, 10, 0, 0, 10, 0, 0, 0, 0, 0, 0);
1068 borders.emplace_back(4, 5, 20, 20, 20, 20, 20, 0, 0, 20, 0, 0, 20, 0, 0, 20, 0, 0, 0, 0, 0, 0);
1069 borders.emplace_back(4, 7, 50, 50, 50, 50, 50, 0, 0, 50, 0, 0, 50, 0, 0, 50, 0, 0, 0, 0, 0, 0);
1070 borders.emplace_back(4, 9, 80, 80, 80, 80, 80, 0, 0, 80, 0, 0, 80, 0, 0, 80, 0, 0, 0, 0, 0, 0);
1071 borders.emplace_back(4, 11, 100, 100, 100, 100, 100, 0, 0, 100, 0, 0, 100, 0, 0, 100, 0, 0, 0, 0, 0, 0);
1073 ScDocShellRef xDocSh = loadDoc("borders_ooo33.", FORMAT_ODS);
1075 CPPUNIT_ASSERT_MESSAGE("Failed to load borders_ooo33.*", xDocSh.is());
1076 ScDocument& rDoc = xDocSh->GetDocument();
1078 const editeng::SvxBorderLine* pLeft = nullptr;
1079 const editeng::SvxBorderLine* pTop = nullptr;
1080 const editeng::SvxBorderLine* pRight = nullptr;
1081 const editeng::SvxBorderLine* pBottom = nullptr;
1082 sal_Int16 temp = 0;
1083 for(sal_Int16 i = 0; i<6; ++i)
1085 for(sal_Int32 j = 0; j<22; ++j)
1087 rDoc.GetBorderLines( i, j, 0, &pLeft, &pTop, &pRight, &pBottom );
1088 if(pLeft!=nullptr && pTop!=nullptr && pRight!=nullptr && pBottom!=nullptr)
1090 CPPUNIT_ASSERT_EQUAL(borders[temp].column, i);
1091 CPPUNIT_ASSERT_EQUAL(borders[temp].row, j);
1092 CPPUNIT_ASSERT_EQUAL(borders[temp].leftWidth, pLeft->GetWidth());
1093 CPPUNIT_ASSERT_EQUAL(borders[temp].topWidth, pTop->GetWidth());
1094 CPPUNIT_ASSERT_EQUAL(borders[temp].rightWidth, pRight->GetWidth());
1095 CPPUNIT_ASSERT_EQUAL(borders[temp].bottomWidth, pBottom->GetWidth());
1096 CPPUNIT_ASSERT_EQUAL(borders[temp].lOutWidth, pLeft->GetOutWidth());
1097 CPPUNIT_ASSERT_EQUAL(borders[temp].lInWidth, pLeft->GetInWidth());
1098 CPPUNIT_ASSERT_EQUAL(borders[temp].lDistance, pLeft->GetDistance());
1099 CPPUNIT_ASSERT_EQUAL(borders[temp].tOutWidth, pTop->GetOutWidth());
1100 CPPUNIT_ASSERT_EQUAL(borders[temp].tInWidth, pTop->GetInWidth());
1101 CPPUNIT_ASSERT_EQUAL(borders[temp].tDistance, pTop->GetDistance());
1102 CPPUNIT_ASSERT_EQUAL(borders[temp].rOutWidth, pRight->GetOutWidth());
1103 CPPUNIT_ASSERT_EQUAL(borders[temp].rInWidth, pRight->GetInWidth());
1104 CPPUNIT_ASSERT_EQUAL(borders[temp].rDistance, pRight->GetDistance());
1105 CPPUNIT_ASSERT_EQUAL(borders[temp].bOutWidth, pBottom->GetOutWidth());
1106 CPPUNIT_ASSERT_EQUAL(borders[temp].bInWidth, pBottom->GetInWidth());
1107 CPPUNIT_ASSERT_EQUAL(borders[temp].bDistance, pBottom->GetDistance());
1108 SvxBorderLineStyle tempStyle = pLeft->GetBorderLineStyle();
1109 CPPUNIT_ASSERT_EQUAL(borders[temp].lStyle, tempStyle);
1110 tempStyle = pTop->GetBorderLineStyle();
1111 CPPUNIT_ASSERT_EQUAL(borders[temp].tStyle, tempStyle);
1112 tempStyle = pRight->GetBorderLineStyle();
1113 CPPUNIT_ASSERT_EQUAL(borders[temp].rStyle, tempStyle);
1114 tempStyle = pBottom->GetBorderLineStyle();
1115 CPPUNIT_ASSERT_EQUAL(borders[temp].bStyle, tempStyle);
1116 ++temp;
1121 xDocSh->DoClose();
1124 void ScFiltersTest::testBugFixesODS()
1126 ScDocShellRef xDocSh = loadDoc("bug-fixes.", FORMAT_ODS);
1127 CPPUNIT_ASSERT_MESSAGE("Failed to load bugFixes.ods", xDocSh.is());
1129 xDocSh->DoHardRecalc();
1130 ScDocument& rDoc = xDocSh->GetDocument();
1133 // fdo#40967
1134 OUString aCSVFileName;
1135 createCSVPath("bugFix_Sheet2.", aCSVFileName);
1136 testFile(aCSVFileName, rDoc, 1);
1140 // fdo#40426
1141 ScDBData* pDBData = rDoc.GetDBCollection()->getNamedDBs().findByUpperName("DBRANGE1");
1142 CPPUNIT_ASSERT(pDBData);
1143 CPPUNIT_ASSERT(pDBData->HasHeader());
1144 // no header
1145 pDBData = rDoc.GetDBCollection()->getNamedDBs().findByUpperName("DBRANGE2");
1146 CPPUNIT_ASSERT(pDBData);
1147 CPPUNIT_ASSERT(!pDBData->HasHeader());
1151 // fdo#59240
1152 OUString aCSVFileName;
1153 createCSVPath("bugFix_Sheet4.", aCSVFileName);
1154 testFile(aCSVFileName, rDoc, 3);
1157 xDocSh->DoClose();
1160 void ScFiltersTest::testBugFixesXLS()
1162 ScDocShellRef xDocSh = loadDoc("bug-fixes.", FORMAT_XLS);
1163 CPPUNIT_ASSERT_MESSAGE("Failed to load bugFixes.xls", xDocSh.is());
1165 xDocSh->DoHardRecalc();
1166 xDocSh->DoClose();
1169 void ScFiltersTest::testBugFixesXLSX()
1171 ScDocShellRef xDocSh = loadDoc("bug-fixes.", FORMAT_XLSX);
1172 CPPUNIT_ASSERT_MESSAGE("Failed to load bugFixes.xls", xDocSh.is());
1174 xDocSh->DoHardRecalc();
1175 xDocSh->DoClose();
1178 namespace {
1180 void checkMergedCells( ScDocument& rDoc, const ScAddress& rStartAddress,
1181 const ScAddress& rExpectedEndAddress )
1183 SCCOL nActualEndCol = rStartAddress.Col();
1184 SCROW nActualEndRow = rStartAddress.Row();
1185 rDoc.ExtendMerge( rStartAddress.Col(), rStartAddress.Row(),
1186 nActualEndCol, nActualEndRow, rStartAddress.Tab() );
1187 OString sTab = OString::number( rStartAddress.Tab() + 1 );
1188 OString msg = "Merged cells are not correctly imported on sheet" + sTab;
1189 OString msgCol = msg + "; end col";
1190 OString msgRow = msg + "; end row";
1191 CPPUNIT_ASSERT_EQUAL_MESSAGE( msgCol.pData->buffer, rExpectedEndAddress.Col(), nActualEndCol );
1192 CPPUNIT_ASSERT_EQUAL_MESSAGE( msgRow.pData->buffer, rExpectedEndAddress.Row(), nActualEndRow );
1197 void ScFiltersTest::testMergedCellsODS()
1199 ScDocShellRef xDocSh = loadDoc("merged.", FORMAT_ODS);
1200 ScDocument& rDoc = xDocSh->GetDocument();
1202 //check sheet1 content
1203 OUString aCSVFileName1;
1204 createCSVPath("merged1.", aCSVFileName1);
1205 testFile(aCSVFileName1, rDoc, 0);
1207 //check sheet1 merged cells
1208 checkMergedCells( rDoc, ScAddress( 0, 0, 0 ), ScAddress( 5, 11, 0 ) );
1209 checkMergedCells( rDoc, ScAddress( 7, 2, 0 ), ScAddress( 9, 12, 0 ) );
1210 checkMergedCells( rDoc, ScAddress( 3, 15, 0 ), ScAddress( 7, 23, 0 ) );
1212 //check sheet2 content
1213 OUString aCSVFileName2;
1214 createCSVPath("merged2.", aCSVFileName2);
1215 testFile(aCSVFileName2, rDoc, 1);
1217 //check sheet2 merged cells
1218 checkMergedCells( rDoc, ScAddress( 4, 3, 1 ), ScAddress( 6, 15, 1 ) );
1220 xDocSh->DoClose();
1223 void ScFiltersTest::testRepeatedColumnsODS()
1225 ScDocShellRef xDocSh = loadDoc("repeatedColumns.", FORMAT_ODS);
1226 ScDocument& rDoc = xDocSh->GetDocument();
1228 //text
1229 OUString aCSVFileName1;
1230 createCSVPath("repeatedColumns1.", aCSVFileName1);
1231 testFile(aCSVFileName1, rDoc, 0);
1233 //numbers
1234 OUString aCSVFileName2;
1235 createCSVPath("repeatedColumns2.", aCSVFileName2);
1236 testFile(aCSVFileName2, rDoc, 1);
1238 xDocSh->DoClose();
1241 namespace {
1243 //for cleaner passing of parameters
1244 struct ValDataTestParams
1246 ScValidationMode eValMode;
1247 ScConditionMode eCondOp;
1248 OUString aStrVal1;
1249 OUString aStrVal2;
1250 ScDocument& rDocument;
1251 ScAddress aPosition;
1252 OUString aErrorTitle;
1253 OUString aErrorMessage;
1254 ScValidErrorStyle eErrorStyle;
1255 sal_uLong nExpectedIndex;
1257 ValDataTestParams( ScValidationMode eMode, ScConditionMode eOp,
1258 const OUString& aExpr1, const OUString& aExpr2, ScDocument& rDoc,
1259 const ScAddress& aPos, const OUString& aETitle, const OUString& aEMsg,
1260 ScValidErrorStyle eEStyle, sal_uLong nIndex ):
1261 eValMode(eMode), eCondOp(eOp), aStrVal1(aExpr1),
1262 aStrVal2(aExpr2), rDocument(rDoc), aPosition(aPos),
1263 aErrorTitle(aETitle), aErrorMessage(aEMsg),
1264 eErrorStyle(eEStyle), nExpectedIndex(nIndex) { };
1267 void checkValiditationEntries( const ValDataTestParams& rVDTParams )
1269 ScDocument& rDoc = rVDTParams.rDocument;
1271 //create expected data validation entry
1272 ScValidationData aValData(
1273 rVDTParams.eValMode, rVDTParams.eCondOp, rVDTParams.aStrVal1,
1274 rVDTParams.aStrVal2, &rDoc, rVDTParams.aPosition, EMPTY_OUSTRING,
1275 EMPTY_OUSTRING, rDoc.GetStorageGrammar(), rDoc.GetStorageGrammar()
1277 aValData.SetIgnoreBlank( true );
1278 aValData.SetListType( 1 );
1279 aValData.ResetInput();
1280 aValData.SetError( rVDTParams.aErrorTitle, rVDTParams.aErrorMessage, rVDTParams.eErrorStyle );
1281 aValData.SetSrcString( EMPTY_OUSTRING );
1283 //get actual data validation entry from document
1284 const ScValidationData* pValDataTest = rDoc.GetValidationEntry( rVDTParams.nExpectedIndex );
1286 sal_Int32 nCol( static_cast<sal_Int32>(rVDTParams.aPosition.Col()) );
1287 sal_Int32 nRow( static_cast<sal_Int32>(rVDTParams.aPosition.Row()) );
1288 sal_Int32 nTab( static_cast<sal_Int32>(rVDTParams.aPosition.Tab()) );
1289 OString aMsgPrefix = "Data Validation Entry with base-cell-address: (" +
1290 OString::number(nCol) + "," + OString::number(nRow) + "," + OString::number(nTab) + ") ";
1292 OString aMsg = aMsgPrefix + "did not get imported at all.";
1293 CPPUNIT_ASSERT_MESSAGE(aMsg.getStr(), pValDataTest);
1295 //check if expected and actual data validation entries are equal
1296 if (!aValData.EqualEntries(*pValDataTest))
1298 aMsg = aMsgPrefix + "got imported incorrectly.";
1299 CPPUNIT_FAIL(aMsg.getStr());
1303 void checkCellValidity( const ScAddress& rValBaseAddr, const ScRange& rRange, const ScDocument& rDoc )
1305 SCCOL nBCol( rValBaseAddr.Col() );
1306 SCROW nBRow( rValBaseAddr.Row() );
1307 SCTAB nTab( static_cast<sal_Int32>(rValBaseAddr.Tab()) );
1308 //get from the document the data validation entry we are checking against
1309 const SfxUInt32Item* pItem = rDoc.GetAttr(nBCol, nBRow, nTab, ATTR_VALIDDATA);
1310 const ScValidationData* pValData = rDoc.GetValidationEntry( pItem->GetValue() );
1311 CPPUNIT_ASSERT(pValData);
1313 //check that each cell in the expected range is associated with the data validation entry
1314 for(SCCOL i = rRange.aStart.Col(); i <= rRange.aEnd.Col(); ++i)
1316 for(SCROW j = rRange.aStart.Row(); j <= rRange.aEnd.Row(); ++j)
1318 const SfxUInt32Item* pItemTest = rDoc.GetAttr(i, j, nTab, ATTR_VALIDDATA);
1319 const ScValidationData* pValDataTest = rDoc.GetValidationEntry( pItemTest->GetValue() );
1320 //prevent string operations for occurring unnecessarily
1321 if(!(pValDataTest && pValData->GetKey() == pValDataTest->GetKey()))
1323 sal_Int32 nCol = static_cast<sal_Int32>(i);
1324 sal_Int32 nRow = static_cast<sal_Int32>(j);
1325 sal_Int32 nTab32 = static_cast<sal_Int32>(nTab);
1326 OString sMsg = "\nData validation entry base-cell-address: (" +
1327 OString::number( static_cast<sal_Int32>(nBCol) ) + "," +
1328 OString::number( static_cast<sal_Int32>(nBRow) ) + "," +
1329 OString::number( nTab32 ) + ")\n"
1330 "Cell: (" + OString::number(nCol) + "," +
1331 OString::number(nRow) + "," +
1332 OString::number(nTab32) + ")";
1333 sal_uInt32 expectedKey(pValData->GetKey());
1334 sal_uInt32 actualKey(0);
1335 if(pValDataTest)
1336 actualKey = pValDataTest->GetKey();
1337 CPPUNIT_ASSERT_EQUAL_MESSAGE(sMsg.getStr(), expectedKey, actualKey);
1345 void ScFiltersTest::testDataValidityODS()
1347 ScDocShellRef xDocSh = loadDoc("dataValidity.", FORMAT_ODS);
1348 ScDocument& rDoc = xDocSh->GetDocument();
1350 ScAddress aValBaseAddr1( 2,6,0 ); //sheet1
1351 ScAddress aValBaseAddr2( 2,3,1 ); //sheet2
1352 ScAddress aValBaseAddr3( 2,2,2 ); //sheet3
1354 //sheet1's expected Data Validation Entry values
1355 ValDataTestParams aVDTParams1(
1356 SC_VALID_DECIMAL, ScConditionMode::Greater, "3.14", EMPTY_OUSTRING, rDoc,
1357 aValBaseAddr1, "Too small",
1358 "The number you are trying to enter is not greater than 3.14! Are you sure you want to enter it anyway?",
1359 SC_VALERR_WARNING, 1
1361 //sheet2's expected Data Validation Entry values
1362 ValDataTestParams aVDTParams2(
1363 SC_VALID_WHOLE, ScConditionMode::Between, "1", "10", rDoc,
1364 aValBaseAddr2, "Error sheet 2",
1365 "Must be a whole number between 1 and 10.",
1366 SC_VALERR_STOP, 2
1368 //sheet3's expected Data Validation Entry values
1369 ValDataTestParams aVDTParams3(
1370 SC_VALID_CUSTOM, ScConditionMode::Direct, "ISTEXT(C3)", EMPTY_OUSTRING, rDoc,
1371 aValBaseAddr3, "Error sheet 3",
1372 "Must not be a numerical value.",
1373 SC_VALERR_STOP, 3
1375 //check each sheet's Data Validation Entries
1376 checkValiditationEntries( aVDTParams1 );
1377 checkValiditationEntries( aVDTParams2 );
1378 checkValiditationEntries( aVDTParams3 );
1380 //expected ranges to be associated with data validity
1381 ScRange aRange1( 2,2,0, 2,6,0 ); //sheet1
1382 ScRange aRange2( 2,3,1, 6,7,1 ); //sheet2
1383 ScRange aRange3( 2,2,2, 2,6,2 ); //sheet3
1385 //check each sheet's cells for data validity
1386 checkCellValidity( aValBaseAddr1, aRange1, rDoc );
1387 checkCellValidity( aValBaseAddr2, aRange2, rDoc );
1388 checkCellValidity( aValBaseAddr3, aRange3, rDoc );
1390 //check each sheet's content
1391 OUString aCSVFileName1;
1392 createCSVPath("dataValidity1.", aCSVFileName1);
1393 testFile(aCSVFileName1, rDoc, 0);
1395 OUString aCSVFileName2;
1396 createCSVPath("dataValidity2.", aCSVFileName2);
1397 testFile(aCSVFileName2, rDoc, 1);
1399 OUString aCSVFileName3;
1400 createCSVPath("dataValidity3.", aCSVFileName3);
1401 testFile(aCSVFileName3, rDoc, 2);
1403 xDocSh->DoClose();
1406 void ScFiltersTest::testDataValidityXLSX()
1408 ScDocShellRef xDocSh = loadDoc("dataValidity.", FORMAT_XLSX);
1409 ScDocument& rDoc = xDocSh->GetDocument();
1411 ScAddress aValBaseAddr1( 2,6,0 ); //sheet1
1412 ScAddress aValBaseAddr2( 2,3,1 ); //sheet2
1413 ScAddress aValBaseAddr3( 2,2,2 ); //sheet3
1415 //expected ranges to be associated with data validity
1416 ScRange aRange1( 2,2,0, 2,6,0 ); //sheet1
1417 ScRange aRange2( 2,3,1, 6,7,1 ); //sheet2
1418 ScRange aRange3( 2,2,2, 2,6,2 ); //sheet3
1420 //check each sheet's cells for data validity
1421 checkCellValidity( aValBaseAddr1, aRange1, rDoc );
1422 checkCellValidity( aValBaseAddr2, aRange2, rDoc );
1423 checkCellValidity( aValBaseAddr3, aRange3, rDoc );
1425 xDocSh->DoClose();
1428 void ScFiltersTest::testDataTableMortgageXLS()
1430 ScDocShellRef xDocSh = loadDoc("data-table/mortgage.", FORMAT_XLS);
1431 CPPUNIT_ASSERT_MESSAGE("Failed to load the document.", xDocSh.is());
1433 ScFormulaOptions aOptions;
1434 aOptions.SetFormulaSepArg(",");
1435 aOptions.SetFormulaSepArrayCol(",");
1436 aOptions.SetFormulaSepArrayRow(";");
1437 xDocSh->SetFormulaOptions(aOptions);
1439 ScDocument& rDoc = xDocSh->GetDocument();
1441 // One-variable table
1443 ASSERT_FORMULA_EQUAL(rDoc, ScAddress(3,1,0), "PMT(B3/12,B4,-B5)", "Wrong formula!");
1444 ASSERT_FORMULA_EQUAL(rDoc, ScAddress(3,2,0), "MULTIPLE.OPERATIONS(D$2,$B$3,$C3)", "Wrong formula!");
1445 ASSERT_FORMULA_EQUAL(rDoc, ScAddress(3,3,0), "MULTIPLE.OPERATIONS(D$2,$B$3,$C4)", "Wrong formula!");
1446 ASSERT_FORMULA_EQUAL(rDoc, ScAddress(3,4,0), "MULTIPLE.OPERATIONS(D$2,$B$3,$C5)", "Wrong formula!");
1448 // Two-variable table
1450 ASSERT_FORMULA_EQUAL(rDoc, ScAddress(2,7,0), "PMT(B9/12,B10,-B11)", "Wrong formula!");
1451 ASSERT_FORMULA_EQUAL(rDoc, ScAddress(3,8,0), "MULTIPLE.OPERATIONS($C$8,$B$9,$C9,$B$10,D$8)", "Wrong formula!");
1452 ASSERT_FORMULA_EQUAL(rDoc, ScAddress(3,9,0), "MULTIPLE.OPERATIONS($C$8,$B$9,$C10,$B$10,D$8)", "Wrong formula!");
1453 ASSERT_FORMULA_EQUAL(rDoc, ScAddress(3,10,0), "MULTIPLE.OPERATIONS($C$8,$B$9,$C11,$B$10,D$8)", "Wrong formula!");
1454 ASSERT_FORMULA_EQUAL(rDoc, ScAddress(4,8,0), "MULTIPLE.OPERATIONS($C$8,$B$9,$C9,$B$10,E$8)", "Wrong formula!");
1455 ASSERT_FORMULA_EQUAL(rDoc, ScAddress(4,9,0), "MULTIPLE.OPERATIONS($C$8,$B$9,$C10,$B$10,E$8)", "Wrong formula!");
1456 ASSERT_FORMULA_EQUAL(rDoc, ScAddress(4,10,0), "MULTIPLE.OPERATIONS($C$8,$B$9,$C11,$B$10,E$8)", "Wrong formula!");
1458 xDocSh->DoClose();
1461 void ScFiltersTest::testDataTableOneVarXLSX()
1463 ScDocShellRef xDocSh = loadDoc("data-table/one-variable.", FORMAT_XLSX);
1464 CPPUNIT_ASSERT_MESSAGE("Failed to load the document.", xDocSh.is());
1466 ScFormulaOptions aOptions;
1467 aOptions.SetFormulaSepArg(",");
1468 aOptions.SetFormulaSepArrayCol(",");
1469 aOptions.SetFormulaSepArrayRow(";");
1470 xDocSh->SetFormulaOptions(aOptions);
1472 ScDocument& rDoc = xDocSh->GetDocument();
1474 // Right now, we have a bug that prevents Calc from re-calculating these
1475 // cells automatically upon file load. We can remove this call if/when we
1476 // fix the aforementioned bug.
1477 rDoc.CalcAll();
1479 // B5:B11 should have multiple operations formula cells. Just check the
1480 // top and bottom cells.
1482 ASSERT_FORMULA_EQUAL(rDoc, ScAddress(1,4,0), "MULTIPLE.OPERATIONS(B$4,$A$2,$A5)", "Wrong formula!");
1484 CPPUNIT_ASSERT_EQUAL(2.0, rDoc.GetValue(ScAddress(1,4,0)));
1486 ASSERT_FORMULA_EQUAL(rDoc, ScAddress(1,10,0), "MULTIPLE.OPERATIONS(B$4,$A$2,$A11)", "Wrong formula!");
1488 CPPUNIT_ASSERT_EQUAL(14.0, rDoc.GetValue(ScAddress(1,10,0)));
1490 // Likewise, E5:I5 should have multiple operations formula cells. Just
1491 // check the left- and right-most cells.
1493 ASSERT_FORMULA_EQUAL(rDoc, ScAddress(4,4,0), "MULTIPLE.OPERATIONS($D5,$B$2,E$4)", "Wrong formula!");
1495 CPPUNIT_ASSERT_EQUAL(10.0, rDoc.GetValue(ScAddress(4,4,0)));
1497 ASSERT_FORMULA_EQUAL(rDoc, ScAddress(8,4,0), "MULTIPLE.OPERATIONS($D5,$B$2,I$4)", "Wrong formula!");
1499 CPPUNIT_ASSERT_EQUAL(50.0, rDoc.GetValue(ScAddress(8,4,0)));
1501 xDocSh->DoClose();
1504 void ScFiltersTest::testDataTableMultiTableXLSX()
1506 ScDocShellRef xDocSh = loadDoc("data-table/multi-table.", FORMAT_XLSX);
1507 CPPUNIT_ASSERT_MESSAGE("Failed to load the document.", xDocSh.is());
1509 ScFormulaOptions aOptions;
1510 aOptions.SetFormulaSepArg(",");
1511 aOptions.SetFormulaSepArrayCol(",");
1512 aOptions.SetFormulaSepArrayRow(";");
1513 xDocSh->SetFormulaOptions(aOptions);
1515 ScDocument& rDoc = xDocSh->GetDocument();
1517 // Right now, we have a bug that prevents Calc from re-calculating these
1518 // cells automatically upon file load. We can remove this call if/when we
1519 // fix the aforementioned bug.
1520 rDoc.CalcAll();
1522 // B4:M15 should have multiple operations formula cells. We'll just check
1523 // the top-left and bottom-right ones.
1525 ASSERT_FORMULA_EQUAL(rDoc, ScAddress(1,3,0), "MULTIPLE.OPERATIONS($A$3,$E$1,$A4,$D$1,B$3)", "Wrong formula!");
1527 CPPUNIT_ASSERT_EQUAL(1.0, rDoc.GetValue(ScAddress(1,3,0)));
1529 ASSERT_FORMULA_EQUAL(rDoc, ScAddress(12,14,0), "MULTIPLE.OPERATIONS($A$3,$E$1,$A15,$D$1,M$3)", "Wrong formula!");
1531 CPPUNIT_ASSERT_EQUAL(144.0, rDoc.GetValue(ScAddress(12,14,0)));
1533 xDocSh->DoClose();
1536 void ScFiltersTest::testBrokenQuotesCSV()
1538 const OUString aFileNameBase("fdo48621_broken_quotes.");
1539 OUString aFileExtension(getFileFormats()[FORMAT_CSV].pName, strlen(getFileFormats()[FORMAT_CSV].pName), RTL_TEXTENCODING_UTF8 );
1540 OUString aFilterName(getFileFormats()[FORMAT_CSV].pFilterName, strlen(getFileFormats()[FORMAT_CSV].pFilterName), RTL_TEXTENCODING_UTF8) ;
1541 OUString aFileName;
1542 createFileURL(aFileNameBase, aFileExtension, aFileName);
1543 OUString aFilterType(getFileFormats()[FORMAT_CSV].pTypeName, strlen(getFileFormats()[FORMAT_CSV].pTypeName), RTL_TEXTENCODING_UTF8);
1544 std::cout << getFileFormats()[FORMAT_CSV].pName << " Test" << std::endl;
1546 SfxFilterFlags nFormatType = getFileFormats()[FORMAT_CSV].nFormatType;
1547 SotClipboardFormatId nClipboardId = bool(nFormatType) ? SotClipboardFormatId::STARCALC_8 : SotClipboardFormatId::NONE;
1548 ScDocShellRef xDocSh = ScBootstrapFixture::load(aFileName, aFilterName, OUString(), aFilterType,
1549 nFormatType, nClipboardId);
1551 CPPUNIT_ASSERT_MESSAGE("Failed to load fdo48621_broken_quotes.csv", xDocSh.is());
1552 ScDocument& rDoc = xDocSh->GetDocument();
1554 OUString aCSVPath;
1555 createCSVPath( "fdo48621_broken_quotes_exported.", aCSVPath );
1556 // fdo#48621
1557 testFile( aCSVPath, rDoc, 0, StringType::PureString);
1559 xDocSh->DoClose();
1562 void ScFiltersTest::testCellValueXLSX()
1564 const OUString aFileNameBase("cell-value.");
1565 OUString aFileExtension(getFileFormats()[FORMAT_XLSX].pName, strlen(getFileFormats()[FORMAT_XLSX].pName), RTL_TEXTENCODING_UTF8 );
1566 OUString aFilterName(getFileFormats()[FORMAT_XLSX].pFilterName, strlen(getFileFormats()[FORMAT_XLSX].pFilterName), RTL_TEXTENCODING_UTF8) ;
1567 OUString aFileName;
1568 createFileURL(aFileNameBase, aFileExtension, aFileName);
1569 OUString aFilterType(getFileFormats()[FORMAT_XLSX].pTypeName, strlen(getFileFormats()[FORMAT_XLSX].pTypeName), RTL_TEXTENCODING_UTF8);
1570 std::cout << getFileFormats()[FORMAT_XLSX].pName << " Test" << std::endl;
1572 SfxFilterFlags nFormatType = getFileFormats()[FORMAT_XLSX].nFormatType;
1573 SotClipboardFormatId nClipboardId = bool(nFormatType) ? SotClipboardFormatId::STARCALC_8 : SotClipboardFormatId::NONE;
1574 ScDocShellRef xDocSh = ScBootstrapFixture::load( aFileName, aFilterName, OUString(), aFilterType,
1575 nFormatType, nClipboardId);
1577 CPPUNIT_ASSERT_MESSAGE("Failed to load cell-value.xlsx", xDocSh.is());
1578 ScDocument& rDoc = xDocSh->GetDocument();
1580 OUString aCSVPath;
1581 createCSVPath( aFileNameBase, aCSVPath );
1582 testFile( aCSVPath, rDoc, 0 );
1584 xDocSh->DoClose();
1587 void ScFiltersTest::testRowIndex1BasedXLSX()
1589 ScDocShellRef xDocSh = loadDoc("row-index-1-based.", FORMAT_XLSX);
1590 CPPUNIT_ASSERT(xDocSh.is());
1591 ScDocument& rDoc = xDocSh->GetDocument();
1593 // A1
1594 OUString aStr = rDoc.GetString(ScAddress(0,0,0));
1595 CPPUNIT_ASSERT_EQUAL(OUString("Action Plan.Name"), aStr);
1597 // B1
1598 aStr = rDoc.GetString(ScAddress(1,0,0));
1599 CPPUNIT_ASSERT_EQUAL(OUString("Action Plan.Description"), aStr);
1601 // A2
1602 aStr = rDoc.GetString(ScAddress(0,1,0));
1603 CPPUNIT_ASSERT_EQUAL(OUString("Jerry"), aStr);
1605 // B2 - multi-line text.
1606 const EditTextObject* pText = rDoc.GetEditText(ScAddress(1,1,0));
1607 CPPUNIT_ASSERT(pText);
1608 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(3), pText->GetParagraphCount());
1609 aStr = pText->GetText(0);
1610 CPPUNIT_ASSERT_EQUAL(OUString("This is a longer Text."), aStr);
1611 aStr = pText->GetText(1);
1612 CPPUNIT_ASSERT_EQUAL(OUString("Second line."), aStr);
1613 aStr = pText->GetText(2);
1614 CPPUNIT_ASSERT_EQUAL(OUString("Third line."), aStr);
1616 xDocSh->DoClose();
1619 void ScFiltersTest::testPassword_Impl(const OUString& aFileNameBase)
1621 OUString aFileExtension(getFileFormats()[0].pName, strlen(getFileFormats()[0].pName), RTL_TEXTENCODING_UTF8 );
1622 OUString aFilterName(getFileFormats()[0].pFilterName, strlen(getFileFormats()[0].pFilterName), RTL_TEXTENCODING_UTF8) ;
1623 OUString aFileName;
1624 createFileURL(aFileNameBase, aFileExtension, aFileName);
1625 OUString aFilterType(getFileFormats()[0].pTypeName, strlen(getFileFormats()[0].pTypeName), RTL_TEXTENCODING_UTF8);
1627 std::shared_ptr<const SfxFilter> pFilter(new SfxFilter(
1628 aFilterName,
1629 OUString(), getFileFormats()[0].nFormatType,
1630 SotClipboardFormatId::STARCALC_8,
1631 aFilterType, OUString(),
1632 OUString(), "private:factory/scalc*" ));
1633 const_cast<SfxFilter*>(pFilter.get())->SetVersion(SOFFICE_FILEFORMAT_CURRENT);
1635 ScDocShellRef xDocSh = new ScDocShell;
1636 SfxMedium* pMedium = new SfxMedium(aFileName, StreamMode::STD_READWRITE);
1637 SfxItemSet* pSet = pMedium->GetItemSet();
1638 pSet->Put(SfxStringItem(SID_PASSWORD, "test"));
1639 pMedium->SetFilter(pFilter);
1640 if (!xDocSh->DoLoad(pMedium))
1642 xDocSh->DoClose();
1643 // load failed.
1644 xDocSh.clear();
1647 CPPUNIT_ASSERT_MESSAGE("Failed to load password.ods", xDocSh.is());
1648 xDocSh->DoClose();
1651 void ScFiltersTest::testPasswordNew()
1653 //tests opening a file with new password algorithm
1654 const OUString aFileNameBase("password.");
1655 testPassword_Impl(aFileNameBase);
1658 void ScFiltersTest::testPasswordOld()
1660 //tests opening a file with old password algorithm
1661 const OUString aFileNameBase("passwordOld.");
1662 testPassword_Impl(aFileNameBase);
1665 void ScFiltersTest::testPasswordWrongSHA()
1667 //tests opening a file wrongly using the new password algorithm
1668 //in a sxc with the key algorithm missing
1669 const OUString aFileNameBase("passwordWrongSHA.");
1670 testPassword_Impl(aFileNameBase);
1673 void ScFiltersTest::testControlImport()
1675 ScDocShellRef xDocSh = loadDoc("singlecontrol.", FORMAT_XLSX);
1676 CPPUNIT_ASSERT_MESSAGE("Failed to load singlecontrol.xlsx", xDocSh.is());
1678 uno::Reference< frame::XModel > xModel = xDocSh->GetModel();
1679 uno::Reference< sheet::XSpreadsheetDocument > xDoc(xModel, UNO_QUERY_THROW);
1680 uno::Reference< container::XIndexAccess > xIA(xDoc->getSheets(), UNO_QUERY_THROW);
1681 uno::Reference< drawing::XDrawPageSupplier > xDrawPageSupplier( xIA->getByIndex(0), UNO_QUERY_THROW);
1682 uno::Reference< container::XIndexAccess > xIA_DrawPage(xDrawPageSupplier->getDrawPage(), UNO_QUERY_THROW);
1683 uno::Reference< drawing::XControlShape > xControlShape(xIA_DrawPage->getByIndex(0), UNO_QUERY_THROW);
1685 xDocSh->DoClose();
1688 void ScFiltersTest::testActiveXOptionButtonGroup()
1690 ScDocShellRef xDocSh = loadDoc("tdf111980_radioButtons.", FORMAT_XLSX);
1691 CPPUNIT_ASSERT_MESSAGE("Failed to load tdf111980_radioButtons.xlsx", xDocSh.is());
1692 uno::Reference< frame::XModel > xModel = xDocSh->GetModel();
1693 uno::Reference< sheet::XSpreadsheetDocument > xDoc(xModel, UNO_QUERY_THROW);
1694 uno::Reference< container::XIndexAccess > xIA(xDoc->getSheets(), UNO_QUERY_THROW);
1695 uno::Reference< drawing::XDrawPageSupplier > xDrawPageSupplier( xIA->getByIndex(0), UNO_QUERY_THROW);
1696 uno::Reference< container::XIndexAccess > xIA_DrawPage(xDrawPageSupplier->getDrawPage(), UNO_QUERY_THROW);
1698 OUString sGroupName;
1699 uno::Reference< drawing::XControlShape > xControlShape(xIA_DrawPage->getByIndex(0), UNO_QUERY_THROW);
1700 uno::Reference<beans::XPropertySet> xPropertySet(xControlShape->getControl(), uno::UNO_QUERY_THROW);
1701 xPropertySet->getPropertyValue("GroupName") >>= sGroupName;
1702 CPPUNIT_ASSERT_EQUAL(OUString("Sheet1"), sGroupName);
1704 // Optionbuttons (without Group names) were not grouped.
1705 // The two optionbuttons should have the same auto-generated group name.
1706 OUString sGroupName2; //ActiveX controls
1707 xControlShape.set(xIA_DrawPage->getByIndex(2), uno::UNO_QUERY_THROW);
1708 xPropertySet.set(xControlShape->getControl(), uno::UNO_QUERY_THROW);
1709 xPropertySet->getPropertyValue("GroupName") >>= sGroupName2;
1710 CPPUNIT_ASSERT_EQUAL( false, sGroupName2.isEmpty() );
1712 OUString sGroupName3;
1713 xControlShape.set(xIA_DrawPage->getByIndex(3), uno::UNO_QUERY_THROW);
1714 xPropertySet.set(xControlShape->getControl(), uno::UNO_QUERY_THROW);
1715 xPropertySet->getPropertyValue("GroupName") >>= sGroupName3;
1716 CPPUNIT_ASSERT_EQUAL( sGroupName2, sGroupName3 );
1717 CPPUNIT_ASSERT( sGroupName != sGroupName3 );
1719 OUString sGroupName4; //Form controls
1720 xControlShape.set(xIA_DrawPage->getByIndex(4), uno::UNO_QUERY_THROW);
1721 xPropertySet.set(xControlShape->getControl(), uno::UNO_QUERY_THROW);
1722 xPropertySet->getPropertyValue("GroupName") >>= sGroupName4;
1723 CPPUNIT_ASSERT_EQUAL( false, sGroupName4.isEmpty() );
1725 OUString sGroupName5;
1726 xControlShape.set(xIA_DrawPage->getByIndex(5), uno::UNO_QUERY_THROW);
1727 xPropertySet.set(xControlShape->getControl(), uno::UNO_QUERY_THROW);
1728 xPropertySet->getPropertyValue("GroupName") >>= sGroupName5;
1729 CPPUNIT_ASSERT_EQUAL( sGroupName4, sGroupName5 );
1730 CPPUNIT_ASSERT( sGroupName2 != sGroupName5 );
1731 CPPUNIT_ASSERT( sGroupName != sGroupName5 );
1733 OUString sGroupName7; //Form radiobutton autogrouped by GroupBox
1734 xControlShape.set(xIA_DrawPage->getByIndex(7), uno::UNO_QUERY_THROW);
1735 xPropertySet.set(xControlShape->getControl(), uno::UNO_QUERY_THROW);
1736 xPropertySet->getPropertyValue("GroupName") >>= sGroupName7;
1737 CPPUNIT_ASSERT_EQUAL( OUString("autoGroup_Group Box 7"), sGroupName7 );
1739 OUString sGroupName8;
1740 xControlShape.set(xIA_DrawPage->getByIndex(8), uno::UNO_QUERY_THROW);
1741 xPropertySet.set(xControlShape->getControl(), uno::UNO_QUERY_THROW);
1742 xPropertySet->getPropertyValue("GroupName") >>= sGroupName8;
1743 CPPUNIT_ASSERT_EQUAL( sGroupName7, sGroupName8 );
1744 CPPUNIT_ASSERT( sGroupName4 != sGroupName8 );
1745 CPPUNIT_ASSERT( sGroupName2 != sGroupName8 );
1746 CPPUNIT_ASSERT( sGroupName != sGroupName8 );
1748 OUString sGroupName9; //Form radiobutton not fully inside GroupBox
1749 xControlShape.set(xIA_DrawPage->getByIndex(9), uno::UNO_QUERY_THROW);
1750 xPropertySet.set(xControlShape->getControl(), uno::UNO_QUERY_THROW);
1751 xPropertySet->getPropertyValue("GroupName") >>= sGroupName9;
1752 CPPUNIT_ASSERT_EQUAL( sGroupName4, sGroupName9 );
1754 OUString sGroupName10; //ActiveX unaffected by GroupBox
1755 xControlShape.set(xIA_DrawPage->getByIndex(10), uno::UNO_QUERY_THROW);
1756 xPropertySet.set(xControlShape->getControl(), uno::UNO_QUERY_THROW);
1757 xPropertySet->getPropertyValue("GroupName") >>= sGroupName10;
1758 CPPUNIT_ASSERT_EQUAL( sGroupName, sGroupName10 );
1760 xDocSh->DoClose();
1763 void ScFiltersTest::testChartImportODS()
1765 ScDocShellRef xDocSh = loadDoc("chart-import-basic.", FORMAT_ODS);
1766 CPPUNIT_ASSERT_MESSAGE("Failed to load chart-import-basic.ods.", xDocSh.is());
1768 ScDocument& rDoc = xDocSh->GetDocument();
1770 // Ensure that the document contains "Empty", "Chart", "Data" and "Title" sheets in this exact order.
1771 CPPUNIT_ASSERT_EQUAL_MESSAGE(
1772 "There should be 4 sheets in this document.", sal_Int16(4),
1773 rDoc.GetTableCount());
1774 OUString aName;
1775 rDoc.GetName(0, aName);
1776 CPPUNIT_ASSERT_EQUAL(OUString("Empty"), aName);
1777 rDoc.GetName(1, aName);
1778 CPPUNIT_ASSERT_EQUAL(OUString("Chart"), aName);
1779 rDoc.GetName(2, aName);
1780 CPPUNIT_ASSERT_EQUAL(OUString("Data"), aName);
1781 rDoc.GetName(3, aName);
1782 CPPUNIT_ASSERT_EQUAL(OUString("Title"), aName);
1784 // Retrieve the chart object instance from the 2nd page (for the 2nd sheet).
1785 const SdrOle2Obj* pOleObj = getSingleChartObject(rDoc, 1);
1786 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve a chart object from the 2nd sheet.", pOleObj);
1788 ScRangeList aRanges = getChartRanges(rDoc, *pOleObj);
1790 CPPUNIT_ASSERT_MESSAGE("Data series title cell not found.", aRanges.In(ScAddress(1,0,3))); // B1 on Title
1791 CPPUNIT_ASSERT_MESSAGE("Data series label range not found.", aRanges.In(ScRange(0,1,2,0,3,2))); // A2:A4 on Data
1792 CPPUNIT_ASSERT_MESSAGE("Data series value range not found.", aRanges.In(ScRange(1,1,2,1,3,2))); // B2:B4 on Data
1794 xDocSh->DoClose();
1797 #if HAVE_MORE_FONTS
1798 void ScFiltersTest::testChartImportXLS()
1800 ScDocShellRef xDocSh = loadDoc("chartx.", FORMAT_XLS);
1801 CPPUNIT_ASSERT_MESSAGE("Failed to load chartx.xls.", xDocSh.is());
1803 ScDocument& rDoc = xDocSh->GetDocument();
1805 // Retrieve the chart object instance from the 2nd page (for the 2nd sheet).
1806 const SdrOle2Obj* pOleObj = getSingleChartObject(rDoc, 0);
1807 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve a chart object from the 2nd sheet.", pOleObj);
1809 CPPUNIT_ASSERT_EQUAL(11137L, pOleObj->GetLogicRect().getWidth());
1810 CPPUNIT_ASSERT(8640L > pOleObj->GetLogicRect().getHeight());
1812 xDocSh->DoClose();
1814 #endif
1816 void ScFiltersTest::testNumberFormatHTML()
1818 ScDocShellRef xDocSh = loadDoc("numberformat.", FORMAT_HTML);
1819 CPPUNIT_ASSERT_MESSAGE("Failed to load numberformat.html", xDocSh.is());
1821 ScDocument& rDoc = xDocSh->GetDocument();
1823 // Check the header just in case.
1824 CPPUNIT_ASSERT_EQUAL_MESSAGE(
1825 "Cell value is not as expected", OUString("Product"),
1826 rDoc.GetString(0, 0, 0));
1827 CPPUNIT_ASSERT_EQUAL_MESSAGE(
1828 "Cell value is not as expected", OUString("Price"),
1829 rDoc.GetString(1, 0, 0));
1830 CPPUNIT_ASSERT_EQUAL_MESSAGE(
1831 "Cell value is not as expected", OUString("Note"),
1832 rDoc.GetString(2, 0, 0));
1834 // B2 should be imported as a value cell.
1835 bool bHasValue = rDoc.HasValueData(1, 1, 0);
1836 CPPUNIT_ASSERT_MESSAGE("Fail to import number as a value cell.", bHasValue);
1837 CPPUNIT_ASSERT_EQUAL_MESSAGE(
1838 "Incorrect value.", 199.98, rDoc.GetValue(1, 1, 0));
1840 xDocSh->DoClose();
1843 void ScFiltersTest::testNumberFormatCSV()
1845 ScDocShellRef xDocSh = loadDoc("numberformat.", FORMAT_CSV);
1846 CPPUNIT_ASSERT_MESSAGE("Failed to load numberformat.csv", xDocSh.is());
1848 ScDocument& rDoc = xDocSh->GetDocument();
1850 // Check the header just in case.
1851 CPPUNIT_ASSERT_EQUAL_MESSAGE(
1852 "Cell value is not as expected", OUString("Product"),
1853 rDoc.GetString(0, 0, 0));
1854 CPPUNIT_ASSERT_EQUAL_MESSAGE(
1855 "Cell value is not as expected", OUString("Price"),
1856 rDoc.GetString(1, 0, 0));
1857 CPPUNIT_ASSERT_EQUAL_MESSAGE(
1858 "Cell value is not as expected", OUString("Note"),
1859 rDoc.GetString(2, 0, 0));
1861 // B2 should be imported as a value cell.
1862 bool bHasValue = rDoc.HasValueData(1, 1, 0);
1863 CPPUNIT_ASSERT_MESSAGE("Fail to import number as a value cell.", bHasValue);
1864 CPPUNIT_ASSERT_EQUAL_MESSAGE(
1865 "Incorrect value.", 199.98, rDoc.GetValue(1, 1, 0));
1867 xDocSh->DoClose();
1870 void ScFiltersTest::testCellAnchoredShapesODS()
1872 ScDocShellRef xDocSh = loadDoc("cell-anchored-shapes.", FORMAT_ODS);
1873 CPPUNIT_ASSERT_MESSAGE("Failed to load cell-anchored-shapes.ods", xDocSh.is());
1875 // There are two cell-anchored objects on the first sheet.
1876 ScDocument& rDoc = xDocSh->GetDocument();
1878 CPPUNIT_ASSERT_MESSAGE("There should be at least one sheet.", rDoc.GetTableCount() > 0);
1880 ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer();
1881 SdrPage* pPage = pDrawLayer->GetPage(0);
1882 CPPUNIT_ASSERT_MESSAGE("draw page for sheet 1 should exist.", pPage);
1883 const size_t nCount = pPage->GetObjCount();
1884 CPPUNIT_ASSERT_EQUAL_MESSAGE(
1885 "There should be 2 objects.", static_cast<size_t>(2), nCount);
1886 for (size_t i = 0; i < nCount; ++i)
1888 SdrObject* pObj = pPage->GetObj(i);
1889 CPPUNIT_ASSERT_MESSAGE("Failed to get drawing object.", pObj);
1890 ScDrawObjData* pData = ScDrawLayer::GetObjData(pObj);
1891 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve user data for this object.", pData);
1892 CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pData->getShapeRect().IsEmpty());
1895 xDocSh->DoClose();
1898 void ScFiltersTest::testCellAnchoredHiddenShapesXLSX()
1900 ScDocShellRef xDocSh = loadDoc("cell-anchored-hidden-shapes.", FORMAT_XLSX);
1901 CPPUNIT_ASSERT_MESSAGE("Failed to load cell-anchored-shapes.xlsx", xDocSh.is());
1903 // There are two cell-anchored objects on the first sheet.
1904 ScDocument& rDoc = xDocSh->GetDocument();
1906 CPPUNIT_ASSERT_MESSAGE("There should be at least one sheet.", rDoc.GetTableCount() > 0);
1908 ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer();
1909 SdrPage* pPage = pDrawLayer->GetPage(0);
1910 CPPUNIT_ASSERT_MESSAGE("draw page for sheet 1 should exist.", pPage);
1911 const size_t nCount = pPage->GetObjCount();
1912 CPPUNIT_ASSERT_MESSAGE("There should be 2 shapes.", !(nCount == 2));
1914 SdrObject* pObj = pPage->GetObj(1);
1915 CPPUNIT_ASSERT_MESSAGE("Failed to get drawing object.", pObj);
1916 CPPUNIT_ASSERT_MESSAGE("The shape having same twocellanchor from and to attribute values, is visible.", !pObj->IsVisible());
1918 xDocSh->DoClose();
1921 void ScFiltersTest::testRowHeightODS()
1923 ScDocShellRef xDocSh = loadDoc("row-height-import.", FORMAT_ODS);
1924 CPPUNIT_ASSERT_MESSAGE("Failed to load row-height-import.ods", xDocSh.is());
1926 SCTAB nTab = 0;
1927 SCROW nRow = 0;
1928 ScDocument& rDoc = xDocSh->GetDocument();
1930 // The first 3 rows have manual heights.
1931 int nHeight = rDoc.GetRowHeight(nRow, nTab, false);
1932 bool bManual = rDoc.IsManualRowHeight(nRow, nTab);
1933 CPPUNIT_ASSERT_EQUAL(600, nHeight);
1934 CPPUNIT_ASSERT_MESSAGE("this row should have a manual row height.", bManual);
1935 nHeight = rDoc.GetRowHeight(++nRow, nTab, false);
1936 bManual = rDoc.IsManualRowHeight(nRow, nTab);
1937 CPPUNIT_ASSERT_EQUAL(1200, nHeight);
1938 CPPUNIT_ASSERT_MESSAGE("this row should have a manual row height.", bManual);
1939 nHeight = rDoc.GetRowHeight(++nRow, nTab, false);
1940 bManual = rDoc.IsManualRowHeight(nRow, nTab);
1941 CPPUNIT_ASSERT_EQUAL(1800, nHeight);
1942 CPPUNIT_ASSERT_MESSAGE("this row should have a manual row height.", bManual);
1944 // This one should have an automatic row height.
1945 bManual = rDoc.IsManualRowHeight(++nRow, nTab);
1946 CPPUNIT_ASSERT_MESSAGE("Row should have an automatic height.", !bManual);
1948 // Followed by a row with manual height.
1949 nHeight = rDoc.GetRowHeight(++nRow, nTab, false);
1950 bManual = rDoc.IsManualRowHeight(nRow, nTab);
1951 CPPUNIT_ASSERT_EQUAL(2400, nHeight);
1952 CPPUNIT_ASSERT_MESSAGE("this row should have a manual row height.", bManual);
1954 // And all the rest should have automatic heights.
1955 bManual = rDoc.IsManualRowHeight(++nRow, nTab);
1956 CPPUNIT_ASSERT_MESSAGE("Row should have an automatic height.", !bManual);
1958 bManual = rDoc.IsManualRowHeight(MAXROW, nTab);
1959 CPPUNIT_ASSERT_MESSAGE("Row should have an automatic height.", !bManual);
1961 xDocSh->DoClose();
1964 void ScFiltersTest::testRichTextContentODS()
1966 ScDocShellRef xDocSh = loadDoc("rich-text-cells.", FORMAT_ODS);
1967 CPPUNIT_ASSERT_MESSAGE("Failed to load rich-text-cells.ods", xDocSh.is());
1968 ScDocument& rDoc = xDocSh->GetDocument();
1970 OUString aTabName;
1971 CPPUNIT_ASSERT_MESSAGE("Failed to get the name of the first sheet.", rDoc.GetName(0, aTabName));
1973 // All tested cells are in the first column.
1974 ScAddress aPos(0, 0, 0);
1976 // Normal simple string with no formatting.
1977 aPos.IncRow();
1978 CPPUNIT_ASSERT_EQUAL(CELLTYPE_STRING, rDoc.GetCellType(aPos));
1979 CPPUNIT_ASSERT_EQUAL(OUString("Normal"), rDoc.GetString(aPos.Col(), aPos.Row(), aPos.Tab()));
1981 // Normal string with bold applied to the whole cell.
1983 aPos.IncRow();
1984 CPPUNIT_ASSERT_EQUAL(CELLTYPE_STRING, rDoc.GetCellType(aPos));
1985 CPPUNIT_ASSERT_EQUAL(OUString("All bold"), rDoc.GetString(aPos.Col(), aPos.Row(), aPos.Tab()));
1986 const ScPatternAttr* pAttr = rDoc.GetPattern(aPos.Col(), aPos.Row(), aPos.Tab());
1987 CPPUNIT_ASSERT_MESSAGE("Failed to get cell attribute.", pAttr);
1988 const SvxWeightItem& rWeightItem = pAttr->GetItem(ATTR_FONT_WEIGHT);
1989 CPPUNIT_ASSERT_EQUAL(WEIGHT_BOLD, rWeightItem.GetWeight());
1992 // This cell has an unformatted but multi-line content. Multi-line text is
1993 // stored in edit cell even if it has no formatting applied.
1994 aPos.IncRow();
1995 CPPUNIT_ASSERT_EQUAL(CELLTYPE_EDIT, rDoc.GetCellType(aPos));
1996 const EditTextObject* pEditText = rDoc.GetEditText(aPos);
1997 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
1998 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(3), pEditText->GetParagraphCount());
1999 OUString aParaText = pEditText->GetText(0);
2000 CPPUNIT_ASSERT_EQUAL(OUString("one"), aParaText);
2001 aParaText = pEditText->GetText(1);
2002 CPPUNIT_ASSERT_EQUAL(OUString("two"), aParaText);
2003 aParaText = pEditText->GetText(2);
2004 CPPUNIT_ASSERT_EQUAL(OUString("three"), aParaText);
2006 // Cell with sheet name field item.
2007 aPos.IncRow();
2008 CPPUNIT_ASSERT_EQUAL(CELLTYPE_EDIT, rDoc.GetCellType(aPos));
2009 pEditText = rDoc.GetEditText(aPos);
2010 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
2011 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), pEditText->GetParagraphCount());
2012 aParaText = pEditText->GetText(0);
2013 CPPUNIT_ASSERT_MESSAGE("Unexpected text.", aParaText.startsWith("Sheet name is "));
2014 CPPUNIT_ASSERT_MESSAGE("Sheet name field item not found.", pEditText->HasField(text::textfield::Type::TABLE));
2015 CPPUNIT_ASSERT_EQUAL(OUString("Sheet name is Test."), ScEditUtil::GetString(*pEditText, &rDoc));
2016 CPPUNIT_ASSERT_EQUAL(OUString("Sheet name is ?."), ScEditUtil::GetString(*pEditText, nullptr));
2018 // Cell with URL field item.
2019 aPos.IncRow();
2020 CPPUNIT_ASSERT_EQUAL(CELLTYPE_EDIT, rDoc.GetCellType(aPos));
2021 pEditText = rDoc.GetEditText(aPos);
2022 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
2023 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), pEditText->GetParagraphCount());
2024 aParaText = pEditText->GetText(0);
2025 CPPUNIT_ASSERT_MESSAGE("Unexpected text.", aParaText.startsWith("URL: "));
2026 CPPUNIT_ASSERT_MESSAGE("URL field item not found.", pEditText->HasField(text::textfield::Type::URL));
2027 CPPUNIT_ASSERT_EQUAL(OUString("URL: http://libreoffice.org"), ScEditUtil::GetString(*pEditText, &rDoc));
2028 CPPUNIT_ASSERT_EQUAL(OUString("URL: http://libreoffice.org"), ScEditUtil::GetString(*pEditText, nullptr));
2030 // Cell with Date field item.
2031 aPos.IncRow();
2032 CPPUNIT_ASSERT_EQUAL(CELLTYPE_EDIT, rDoc.GetCellType(aPos));
2033 pEditText = rDoc.GetEditText(aPos);
2034 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
2035 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), pEditText->GetParagraphCount());
2036 aParaText = pEditText->GetText(0);
2037 CPPUNIT_ASSERT_MESSAGE("Unexpected text.", aParaText.startsWith("Date: "));
2038 CPPUNIT_ASSERT_MESSAGE("Date field item not found.", pEditText->HasField(text::textfield::Type::DATE));
2039 CPPUNIT_ASSERT_MESSAGE("Date field not resolved with rDoc.", ScEditUtil::GetString(*pEditText, &rDoc).indexOf("/20") > 0);
2040 CPPUNIT_ASSERT_MESSAGE("Date field not resolved with NULL.", ScEditUtil::GetString(*pEditText, nullptr).indexOf("/20") > 0);
2042 // Cell with DocInfo title field item.
2043 aPos.IncRow();
2044 CPPUNIT_ASSERT_EQUAL(CELLTYPE_EDIT, rDoc.GetCellType(aPos));
2045 pEditText = rDoc.GetEditText(aPos);
2046 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
2047 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), pEditText->GetParagraphCount());
2048 aParaText = pEditText->GetText(0);
2049 CPPUNIT_ASSERT_MESSAGE("Unexpected text.", aParaText.startsWith("Title: "));
2050 CPPUNIT_ASSERT_MESSAGE("DocInfo title field item not found.", pEditText->HasField(text::textfield::Type::DOCINFO_TITLE));
2051 CPPUNIT_ASSERT_EQUAL(OUString("Title: Test Document"), ScEditUtil::GetString(*pEditText, &rDoc));
2052 CPPUNIT_ASSERT_EQUAL(OUString("Title: ?"), ScEditUtil::GetString(*pEditText, nullptr));
2054 // Cell with sentence with both bold and italic sequences.
2055 aPos.IncRow();
2056 CPPUNIT_ASSERT_EQUAL(CELLTYPE_EDIT, rDoc.GetCellType(aPos));
2057 pEditText = rDoc.GetEditText(aPos);
2058 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
2059 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), pEditText->GetParagraphCount());
2060 aParaText = pEditText->GetText(0);
2061 CPPUNIT_ASSERT_EQUAL(OUString("Sentence with bold and italic."), aParaText);
2062 std::vector<EECharAttrib> aAttribs;
2063 pEditText->GetCharAttribs(0, aAttribs);
2065 bool bHasBold = false, bHasItalic = false;
2066 for (const auto& rAttrib : aAttribs)
2068 OUString aSeg = aParaText.copy(rAttrib.nStart, rAttrib.nEnd - rAttrib.nStart);
2069 const SfxPoolItem* pAttr = rAttrib.pAttr;
2070 if (aSeg == "bold" && pAttr->Which() == EE_CHAR_WEIGHT && !bHasBold)
2072 const SvxWeightItem& rItem = static_cast<const SvxWeightItem&>(*pAttr);
2073 bHasBold = (rItem.GetWeight() == WEIGHT_BOLD);
2075 else if (aSeg == "italic" && pAttr->Which() == EE_CHAR_ITALIC && !bHasItalic)
2077 const SvxPostureItem& rItem = static_cast<const SvxPostureItem&>(*pAttr);
2078 bHasItalic = (rItem.GetPosture() == ITALIC_NORMAL);
2081 CPPUNIT_ASSERT_MESSAGE("This sentence is expected to have both bold and italic sequences.", bHasBold && bHasItalic);
2084 // Cell with multi-line content with formatting applied.
2085 aPos.IncRow();
2086 CPPUNIT_ASSERT_EQUAL(CELLTYPE_EDIT, rDoc.GetCellType(aPos));
2087 pEditText = rDoc.GetEditText(aPos);
2088 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
2089 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(3), pEditText->GetParagraphCount());
2090 aParaText = pEditText->GetText(0);
2091 CPPUNIT_ASSERT_EQUAL(OUString("bold"), aParaText);
2092 aParaText = pEditText->GetText(1);
2093 CPPUNIT_ASSERT_EQUAL(OUString("italic"), aParaText);
2094 aParaText = pEditText->GetText(2);
2095 CPPUNIT_ASSERT_EQUAL(OUString("underlined"), aParaText);
2097 // first line is bold.
2098 pEditText->GetCharAttribs(0, aAttribs);
2100 bool bHasBold = std::any_of(aAttribs.begin(), aAttribs.end(), [](const EECharAttrib& rAttrib) {
2101 return rAttrib.pAttr->Which() == EE_CHAR_WEIGHT &&
2102 static_cast<const SvxWeightItem&>(*rAttrib.pAttr).GetWeight() == WEIGHT_BOLD; });
2103 CPPUNIT_ASSERT_MESSAGE("First line should be bold.", bHasBold);
2106 // second line is italic.
2107 pEditText->GetCharAttribs(1, aAttribs);
2108 bool bHasItalic = std::any_of(aAttribs.begin(), aAttribs.end(), [](const EECharAttrib& rAttrib) {
2109 return rAttrib.pAttr->Which() == EE_CHAR_ITALIC &&
2110 static_cast<const SvxPostureItem&>(*rAttrib.pAttr).GetPosture() == ITALIC_NORMAL; });
2111 CPPUNIT_ASSERT_MESSAGE("Second line should be italic.", bHasItalic);
2113 // third line is underlined.
2114 pEditText->GetCharAttribs(2, aAttribs);
2115 bool bHasUnderline = std::any_of(aAttribs.begin(), aAttribs.end(), [](const EECharAttrib& rAttrib) {
2116 return rAttrib.pAttr->Which() == EE_CHAR_UNDERLINE &&
2117 static_cast<const SvxUnderlineItem&>(*rAttrib.pAttr).GetLineStyle() == LINESTYLE_SINGLE; });
2118 CPPUNIT_ASSERT_MESSAGE("Second line should be underlined.", bHasUnderline);
2120 // URL with formats applied. For now, we'll check whether or not the
2121 // field objects gets imported. Later we should add checks for the
2122 // formats.
2123 aPos.IncRow();
2124 pEditText = rDoc.GetEditText(aPos);
2125 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
2126 CPPUNIT_ASSERT_MESSAGE("URL field item not found.", pEditText->HasField(text::textfield::Type::URL));
2128 // Sheet name with formats applied.
2129 aPos.IncRow();
2130 pEditText = rDoc.GetEditText(aPos);
2131 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
2132 CPPUNIT_ASSERT_MESSAGE("Sheet name field item not found.", pEditText->HasField(text::textfield::Type::TABLE));
2134 // Date with formats applied.
2135 aPos.IncRow();
2136 pEditText = rDoc.GetEditText(aPos);
2137 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
2138 CPPUNIT_ASSERT_MESSAGE("Date field item not found.", pEditText->HasField(text::textfield::Type::DATE));
2140 // Document title with formats applied.
2141 aPos.IncRow();
2142 pEditText = rDoc.GetEditText(aPos);
2143 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
2144 CPPUNIT_ASSERT_MESSAGE("Date field item not found.", pEditText->HasField(text::textfield::Type::DOCINFO_TITLE));
2146 // URL for a file in the same directory. It should be converted into an absolute URL on import.
2147 aPos.IncRow();
2148 pEditText = rDoc.GetEditText(aPos);
2149 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
2150 const SvxFieldData* pData = pEditText->GetFieldData(0, 0, text::textfield::Type::URL);
2151 CPPUNIT_ASSERT_MESSAGE("Failed to get the URL data.", pData && pData->GetClassId() == text::textfield::Type::URL);
2152 const SvxURLField* pURLData = static_cast<const SvxURLField*>(pData);
2153 CPPUNIT_ASSERT_MESSAGE("URL is not absolute with respect to the file system.", pURLData->GetURL().startsWith("file:///"));
2155 // Embedded spaces as <text:s text:c='4' />, normal text
2156 aPos.IncRow();
2157 CPPUNIT_ASSERT_EQUAL(CELLTYPE_STRING, rDoc.GetCellType(aPos));
2158 CPPUNIT_ASSERT_EQUAL(OUString("one two"), rDoc.GetString(aPos.Col(), aPos.Row(), aPos.Tab()));
2160 // Leading space as <text:s />.
2161 aPos.IncRow();
2162 CPPUNIT_ASSERT_EQUAL(CELLTYPE_STRING, rDoc.GetCellType(aPos));
2163 CPPUNIT_ASSERT_EQUAL(OUString(" =3+4"), rDoc.GetString(aPos.Col(), aPos.Row(), aPos.Tab()));
2165 // Embedded spaces with <text:s text:c='4' /> inside a <text:span>, text
2166 // partly bold.
2167 aPos.IncRow();
2168 CPPUNIT_ASSERT_EQUAL(CELLTYPE_EDIT, rDoc.GetCellType(aPos));
2169 pEditText = rDoc.GetEditText(aPos);
2170 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
2171 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), pEditText->GetParagraphCount());
2172 aParaText = pEditText->GetText(0);
2173 CPPUNIT_ASSERT_EQUAL(OUString("one two"), aParaText);
2174 pEditText->GetCharAttribs(0, aAttribs);
2176 auto it = std::find_if(aAttribs.begin(), aAttribs.end(), [](const EECharAttrib& rAttrib) {
2177 return rAttrib.pAttr->Which() == EE_CHAR_WEIGHT &&
2178 static_cast<const SvxWeightItem&>(*rAttrib.pAttr).GetWeight() == WEIGHT_BOLD; });
2179 bool bHasBold = (it != aAttribs.end());
2180 if (bHasBold)
2182 OUString aSeg = aParaText.copy(it->nStart, it->nEnd - it->nStart);
2183 CPPUNIT_ASSERT_EQUAL(OUString("e t"), aSeg);
2185 CPPUNIT_ASSERT_MESSAGE("Expected a bold sequence.", bHasBold);
2188 xDocSh->DoClose();
2191 void ScFiltersTest::testDataBarODS()
2193 ScDocShellRef xDocSh = loadDoc("databar.", FORMAT_ODS);
2194 CPPUNIT_ASSERT(xDocSh.is());
2196 ScDocument& rDoc = xDocSh->GetDocument();
2197 testDataBar_Impl(rDoc);
2199 xDocSh->DoClose();
2202 void ScFiltersTest::testDataBarXLSX()
2204 ScDocShellRef xDocSh = loadDoc("databar.", FORMAT_XLSX);
2205 CPPUNIT_ASSERT(xDocSh.is());
2207 ScDocument& rDoc = xDocSh->GetDocument();
2208 testDataBar_Impl(rDoc);
2210 xDocSh->DoClose();
2213 void ScFiltersTest::testColorScaleODS()
2215 ScDocShellRef xDocSh = loadDoc("colorscale.", FORMAT_ODS);
2216 CPPUNIT_ASSERT(xDocSh.is());
2217 ScDocument& rDoc = xDocSh->GetDocument();
2219 testColorScale2Entry_Impl(rDoc);
2220 testColorScale3Entry_Impl(rDoc);
2222 xDocSh->DoClose();
2225 void ScFiltersTest::testColorScaleXLSX()
2227 ScDocShellRef xDocSh = loadDoc("colorscale.", FORMAT_XLSX);
2228 CPPUNIT_ASSERT(xDocSh.is());
2229 ScDocument& rDoc = xDocSh->GetDocument();
2231 testColorScale2Entry_Impl(rDoc);
2232 testColorScale3Entry_Impl(rDoc);
2234 xDocSh->DoClose();
2237 void ScFiltersTest::testNewCondFormatODS()
2239 ScDocShellRef xDocSh = ScBootstrapFixture::loadDoc("new_cond_format_test.", FORMAT_ODS);
2241 CPPUNIT_ASSERT_MESSAGE("Failed to load new_cond_format_test.ods", xDocSh.is());
2243 ScDocument& rDoc = xDocSh->GetDocument();
2245 OUString aCSVPath;
2246 createCSVPath( "new_cond_format_test.", aCSVPath );
2247 testCondFile(aCSVPath, &rDoc, 0);
2249 xDocSh->DoClose();
2252 void ScFiltersTest::testNewCondFormatXLSX()
2254 ScDocShellRef xDocSh = ScBootstrapFixture::loadDoc("new_cond_format_test.", FORMAT_XLSX);
2256 CPPUNIT_ASSERT_MESSAGE("Failed to load new_cond_format_test.xlsx", xDocSh.is());
2258 ScDocument& rDoc = xDocSh->GetDocument();
2260 OUString aCSVPath;
2261 createCSVPath( "new_cond_format_test.", aCSVPath );
2262 testCondFile(aCSVPath, &rDoc, 0);
2264 xDocSh->DoClose();
2267 void ScFiltersTest::testCondFormatImportCellIs()
2269 ScDocShellRef xDocSh = ScBootstrapFixture::loadDoc("condFormat_cellis.", FORMAT_XLSX);
2270 CPPUNIT_ASSERT_MESSAGE("Failed to load condFormat_cellis.xlsx", xDocSh.is());
2272 ScDocument& rDoc = xDocSh->GetDocument();
2273 CPPUNIT_ASSERT_EQUAL(size_t(1), rDoc.GetCondFormList(0)->size());
2275 ScConditionalFormat* pFormat = rDoc.GetCondFormat(0, 0, 0);
2276 CPPUNIT_ASSERT(pFormat);
2278 const ScFormatEntry* pEntry = pFormat->GetEntry(0);
2279 CPPUNIT_ASSERT(pEntry);
2280 CPPUNIT_ASSERT_EQUAL(ScFormatEntry::Type::ExtCondition, pEntry->GetType());
2282 const ScCondFormatEntry* pCondition = static_cast<const ScCondFormatEntry*>(pEntry);
2283 CPPUNIT_ASSERT_EQUAL( ScConditionMode::Equal, pCondition->GetOperation());
2285 OUString aStr = pCondition->GetExpression(ScAddress(0, 0, 0), 0);
2286 CPPUNIT_ASSERT_EQUAL( OUString("$Sheet2.$A$1"), aStr );
2288 pEntry = pFormat->GetEntry(1);
2289 CPPUNIT_ASSERT(pEntry);
2290 CPPUNIT_ASSERT_EQUAL(ScFormatEntry::Type::ExtCondition, pEntry->GetType());
2292 pCondition = static_cast<const ScCondFormatEntry*>(pEntry);
2293 CPPUNIT_ASSERT_EQUAL( ScConditionMode::Equal, pCondition->GetOperation());
2295 aStr = pCondition->GetExpression(ScAddress(0, 0, 0), 0);
2296 CPPUNIT_ASSERT_EQUAL( OUString("$Sheet2.$A$2"), aStr );
2298 xDocSh->DoClose();
2301 void ScFiltersTest::testCondFormatThemeColorXLSX()
2303 ScDocShellRef xDocSh = ScBootstrapFixture::loadDoc("condformat_theme_color.", FORMAT_XLSX);
2305 CPPUNIT_ASSERT_MESSAGE("Failed to load condformat_theme_color.xlsx", xDocSh.is());
2307 ScDocument& rDoc = xDocSh->GetDocument();
2308 ScConditionalFormat* pFormat = rDoc.GetCondFormat(0, 0, 0);
2309 const ScFormatEntry* pEntry = pFormat->GetEntry(0);
2310 CPPUNIT_ASSERT(pEntry);
2311 CPPUNIT_ASSERT_EQUAL(ScFormatEntry::Type::Databar, pEntry->GetType());
2312 const ScDataBarFormat* pDataBar = static_cast<const ScDataBarFormat*>(pEntry);
2313 const ScDataBarFormatData* pDataBarFormatData = pDataBar->GetDataBarData();
2315 CPPUNIT_ASSERT_EQUAL(Color(157, 195, 230), pDataBarFormatData->maPositiveColor);
2316 CPPUNIT_ASSERT(pDataBarFormatData->mpNegativeColor);
2317 CPPUNIT_ASSERT_EQUAL(COL_LIGHTRED, *pDataBarFormatData->mpNegativeColor);
2319 CPPUNIT_ASSERT_EQUAL(size_t(1), rDoc.GetCondFormList(1)->size());
2320 pFormat = rDoc.GetCondFormat(0, 0, 1);
2321 CPPUNIT_ASSERT(pFormat);
2322 CPPUNIT_ASSERT_EQUAL(size_t(1), pFormat->size());
2323 pEntry = pFormat->GetEntry(0);
2324 CPPUNIT_ASSERT(pEntry);
2325 CPPUNIT_ASSERT_EQUAL(ScFormatEntry::Type::Colorscale, pEntry->GetType());
2326 const ScColorScaleFormat* pColorScale = static_cast<const ScColorScaleFormat*>(pEntry);
2327 CPPUNIT_ASSERT_EQUAL(size_t(2), pColorScale->size());
2328 const ScColorScaleEntry* pColorScaleEntry = pColorScale->GetEntry(0);
2329 CPPUNIT_ASSERT(pColorScaleEntry);
2330 CPPUNIT_ASSERT_EQUAL(Color(255, 230, 153), pColorScaleEntry->GetColor());
2332 pColorScaleEntry = pColorScale->GetEntry(1);
2333 CPPUNIT_ASSERT(pColorScaleEntry);
2334 CPPUNIT_ASSERT_EQUAL(Color(157, 195, 230), pColorScaleEntry->GetColor());
2336 xDocSh->DoClose();
2339 void ScFiltersTest::testCondFormatThemeColor2XLSX()
2341 ScDocShellRef xDocSh = ScBootstrapFixture::loadDoc("cond_format_theme_color2.", FORMAT_XLSX);
2343 CPPUNIT_ASSERT_MESSAGE("Failed to load cond_format_theme_color2.xlsx", xDocSh.is());
2345 ScDocument& rDoc = xDocSh->GetDocument();
2346 ScConditionalFormat* pFormat = rDoc.GetCondFormat(5, 5, 0);
2347 CPPUNIT_ASSERT(pFormat);
2348 const ScFormatEntry* pEntry = pFormat->GetEntry(0);
2349 CPPUNIT_ASSERT(pEntry);
2350 CPPUNIT_ASSERT_EQUAL(ScFormatEntry::Type::Databar, pEntry->GetType());
2351 const ScDataBarFormat* pDataBar = static_cast<const ScDataBarFormat*>(pEntry);
2352 const ScDataBarFormatData* pDataBarFormatData = pDataBar->GetDataBarData();
2354 CPPUNIT_ASSERT_EQUAL(Color(99, 142, 198), pDataBarFormatData->maPositiveColor);
2355 CPPUNIT_ASSERT(pDataBarFormatData->mpNegativeColor);
2356 CPPUNIT_ASSERT_EQUAL(Color(217, 217, 217), *pDataBarFormatData->mpNegativeColor);
2357 CPPUNIT_ASSERT_EQUAL(Color(197, 90, 17), pDataBarFormatData->maAxisColor);
2359 xDocSh->DoClose();
2362 namespace {
2364 void checkDatabarPositiveColor(const ScConditionalFormat* pFormat, const Color& rColor)
2366 CPPUNIT_ASSERT(pFormat);
2367 const ScFormatEntry* pEntry = pFormat->GetEntry(0);
2368 CPPUNIT_ASSERT(pEntry);
2369 CPPUNIT_ASSERT_EQUAL(ScFormatEntry::Type::Databar, pEntry->GetType());
2370 const ScDataBarFormat* pDataBar = static_cast<const ScDataBarFormat*>(pEntry);
2371 const ScDataBarFormatData* pDataBarFormatData = pDataBar->GetDataBarData();
2373 CPPUNIT_ASSERT_EQUAL(rColor, pDataBarFormatData->maPositiveColor);
2378 void ScFiltersTest::testCondFormatThemeColor3XLSX()
2380 ScDocShellRef xDocSh = ScBootstrapFixture::loadDoc("cond_format_theme_color3.", FORMAT_XLSX);
2382 CPPUNIT_ASSERT_MESSAGE("Failed to load document", xDocSh.is());
2384 ScDocument& rDoc = xDocSh->GetDocument();
2385 ScConditionalFormat* pFormat = rDoc.GetCondFormat(1, 3, 0);
2386 CPPUNIT_ASSERT(pFormat);
2387 const ScFormatEntry* pEntry = pFormat->GetEntry(0);
2388 CPPUNIT_ASSERT(pEntry);
2389 CPPUNIT_ASSERT_EQUAL(ScFormatEntry::Type::Colorscale, pEntry->GetType());
2390 const ScColorScaleFormat* pColorScale = static_cast<const ScColorScaleFormat*>(pEntry);
2392 CPPUNIT_ASSERT_EQUAL(size_t(2), pColorScale->size());
2393 const ScColorScaleEntry* pColorScaleEntry = pColorScale->GetEntry(0);
2394 CPPUNIT_ASSERT(pColorScaleEntry);
2395 CPPUNIT_ASSERT_EQUAL(Color(175, 171, 171), pColorScaleEntry->GetColor());
2397 pColorScaleEntry = pColorScale->GetEntry(1);
2398 CPPUNIT_ASSERT(pColorScaleEntry);
2399 CPPUNIT_ASSERT_EQUAL(Color(51, 63, 80), pColorScaleEntry->GetColor());
2401 pFormat = rDoc.GetCondFormat(3, 3, 0);
2402 checkDatabarPositiveColor(pFormat, Color(59, 56, 56));
2404 pFormat = rDoc.GetCondFormat(5, 3, 0);
2405 checkDatabarPositiveColor(pFormat, Color(173, 185, 202));
2407 pFormat = rDoc.GetCondFormat(7, 3, 0);
2408 checkDatabarPositiveColor(pFormat, Color(89, 89, 89));
2410 pFormat = rDoc.GetCondFormat(9, 3, 0);
2411 checkDatabarPositiveColor(pFormat, Color(217, 217, 217));
2413 xDocSh->DoClose();
2416 namespace {
2418 void testComplexIconSetsXLSX_Impl(const ScDocument& rDoc, SCCOL nCol, ScIconSetType eType)
2420 ScConditionalFormat* pFormat = rDoc.GetCondFormat(nCol, 1, 0);
2421 CPPUNIT_ASSERT(pFormat);
2422 CPPUNIT_ASSERT_EQUAL(size_t(1), pFormat->size());
2423 const ScFormatEntry* pEntry = pFormat->GetEntry(0);
2424 CPPUNIT_ASSERT(pEntry);
2425 CPPUNIT_ASSERT_EQUAL(ScFormatEntry::Type::Iconset, pEntry->GetType());
2426 const ScIconSetFormat* pIconSet = static_cast<const ScIconSetFormat*>(pEntry);
2427 CPPUNIT_ASSERT_EQUAL(eType, pIconSet->GetIconSetData()->eIconSetType);
2430 void testCustomIconSetsXLSX_Impl(const ScDocument& rDoc, SCCOL nCol, SCROW nRow, ScIconSetType eType, sal_Int32 nIndex)
2432 ScConditionalFormat* pFormat = rDoc.GetCondFormat(nCol, 1, 1);
2433 CPPUNIT_ASSERT(pFormat);
2434 CPPUNIT_ASSERT_EQUAL(size_t(1), pFormat->size());
2435 const ScFormatEntry* pEntry = pFormat->GetEntry(0);
2436 CPPUNIT_ASSERT(pEntry);
2437 CPPUNIT_ASSERT_EQUAL(ScFormatEntry::Type::Iconset, pEntry->GetType());
2438 const ScIconSetFormat* pIconSet = static_cast<const ScIconSetFormat*>(pEntry);
2439 std::unique_ptr<ScIconSetInfo> pInfo(pIconSet->GetIconSetInfo(ScAddress(nCol, nRow, 1)));
2440 if (nIndex == -1)
2441 CPPUNIT_ASSERT(!pInfo);
2442 else
2444 CPPUNIT_ASSERT(pInfo);
2445 CPPUNIT_ASSERT_EQUAL(nIndex, pInfo->nIconIndex);
2446 CPPUNIT_ASSERT_EQUAL(eType, pInfo->eIconSetType);
2452 void ScFiltersTest::testComplexIconSetsXLSX()
2454 ScDocShellRef xDocSh = ScBootstrapFixture::loadDoc("complex_icon_set.", FORMAT_XLSX);
2456 CPPUNIT_ASSERT_MESSAGE("Failed to load complex_icon_set.xlsx", xDocSh.is());
2458 ScDocument& rDoc = xDocSh->GetDocument();
2459 CPPUNIT_ASSERT_EQUAL(size_t(3), rDoc.GetCondFormList(0)->size());
2460 testComplexIconSetsXLSX_Impl(rDoc, 1, IconSet_3Triangles);
2461 testComplexIconSetsXLSX_Impl(rDoc, 3, IconSet_3Stars);
2462 testComplexIconSetsXLSX_Impl(rDoc, 5, IconSet_5Boxes);
2464 CPPUNIT_ASSERT_EQUAL(size_t(2), rDoc.GetCondFormList(1)->size());
2465 testCustomIconSetsXLSX_Impl(rDoc, 1, 1, IconSet_3ArrowsGray, 0);
2466 testCustomIconSetsXLSX_Impl(rDoc, 1, 2, IconSet_3ArrowsGray, -1);
2467 testCustomIconSetsXLSX_Impl(rDoc, 1, 3, IconSet_3Arrows, 1);
2468 testCustomIconSetsXLSX_Impl(rDoc, 1, 4, IconSet_3ArrowsGray, -1);
2469 testCustomIconSetsXLSX_Impl(rDoc, 1, 5, IconSet_3Arrows, 2);
2471 testCustomIconSetsXLSX_Impl(rDoc, 3, 1, IconSet_4RedToBlack, 3);
2472 testCustomIconSetsXLSX_Impl(rDoc, 3, 2, IconSet_3TrafficLights1, 1);
2473 testCustomIconSetsXLSX_Impl(rDoc, 3, 3, IconSet_3Arrows, 2);
2475 xDocSh->DoClose();
2478 void ScFiltersTest::testCondFormatParentXLSX()
2480 ScDocShellRef xDocSh = ScBootstrapFixture::loadDoc("cond_parent.", FORMAT_XLSX);
2482 CPPUNIT_ASSERT_MESSAGE("Failed to load cond_parent.xlsx", xDocSh.is());
2484 ScDocument& rDoc = xDocSh->GetDocument();
2485 const SfxItemSet* pCondSet = rDoc.GetCondResult(2, 5, 0);
2486 const ScPatternAttr* pPattern = rDoc.GetPattern(2, 5, 0);
2487 const SfxPoolItem& rPoolItem = pPattern->GetItem(ATTR_VER_JUSTIFY, pCondSet);
2488 const SvxVerJustifyItem& rVerJustify = static_cast<const SvxVerJustifyItem&>(rPoolItem);
2489 CPPUNIT_ASSERT_EQUAL(SvxCellVerJustify::Top, rVerJustify.GetValue());
2491 xDocSh->DoClose();
2494 void ScFiltersTest::testColorScaleNumWithRefXLSX()
2496 ScDocShellRef xDocSh = ScBootstrapFixture::loadDoc("colorscale_num_with_ref.", FORMAT_XLSX);
2498 CPPUNIT_ASSERT_MESSAGE("Failed to load colorscale_num_with_ref.xlsx", xDocSh.is());
2500 ScDocument& rDoc = xDocSh->GetDocument();
2501 ScConditionalFormatList* pList = rDoc.GetCondFormList(0);
2502 CPPUNIT_ASSERT(pList);
2504 CPPUNIT_ASSERT_EQUAL(size_t(1), pList->size());
2506 ScConditionalFormat* pFormat = pList->begin()->get();
2507 CPPUNIT_ASSERT(pFormat);
2509 CPPUNIT_ASSERT_EQUAL(size_t(1), pFormat->size());
2510 const ScFormatEntry* pEntry = pFormat->GetEntry(0);
2511 CPPUNIT_ASSERT(pEntry);
2513 CPPUNIT_ASSERT_EQUAL(ScFormatEntry::Type::Colorscale, pEntry->GetType());
2515 const ScColorScaleFormat* pColorScale= dynamic_cast<const ScColorScaleFormat*>(pEntry);
2516 CPPUNIT_ASSERT(pColorScale);
2518 const ScColorScaleEntry* pColorScaleEntry = pColorScale->GetEntry(1);
2519 CPPUNIT_ASSERT_EQUAL(OUString("=$A$1"),
2520 pColorScaleEntry->GetFormula(formula::FormulaGrammar::GRAM_NATIVE));
2522 xDocSh->DoClose();
2525 void ScFiltersTest::testOrcusODSStyleInterface()
2527 ScDocument aDoc;
2528 OUString aFullUrl = m_directories.getURLFromSrc("sc/qa/unit/data/xml/styles.xml");
2530 /* This loop below trims file:// from the start because orcus doesn't accept such a URL */
2531 OUString aValidPath;
2532 osl::FileBase::getSystemPathFromFileURL(aFullUrl, aValidPath);
2534 ScOrcusFilters* pOrcus = ScFormatFilter::Get().GetOrcusFilters();
2535 CPPUNIT_ASSERT(pOrcus);
2537 pOrcus->importODS_Styles(aDoc, aValidPath);
2538 ScStyleSheetPool* pStyleSheetPool = aDoc.GetStyleSheetPool();
2540 /* Test cases for Style "Name1"
2541 * Has Border and Fill.
2543 ScStyleSheet* pStyleSheet = pStyleSheetPool->FindCaseIns("Name1", SfxStyleFamily::Para);
2544 const SfxPoolItem* pItem = nullptr;
2546 CPPUNIT_ASSERT_MESSAGE("Style Name1 : Doesn't have Attribute background, but it should have.",
2547 pStyleSheet->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem));
2548 const SvxBrushItem* pBackground = static_cast<const SvxBrushItem*>(pItem);
2549 CPPUNIT_ASSERT_EQUAL(Color(254, 255, 204), pBackground->GetColor());
2551 CPPUNIT_ASSERT_MESSAGE("Style Name1 : Doesn't have Attribute border, but it should have.",
2552 pStyleSheet->GetItemSet().HasItem(ATTR_BORDER, &pItem));
2553 const SvxBoxItem* pBoxItem = static_cast<const SvxBoxItem*>(pItem);
2554 CPPUNIT_ASSERT_EQUAL(Color(255, 204, 18), pBoxItem->GetLeft()->GetColor());
2555 CPPUNIT_ASSERT_EQUAL(Color(255, 204, 18), pBoxItem->GetRight()->GetColor());
2556 CPPUNIT_ASSERT_EQUAL(Color(255, 204, 18), pBoxItem->GetTop()->GetColor());
2557 CPPUNIT_ASSERT_EQUAL(Color(255, 204, 18), pBoxItem->GetBottom()->GetColor());
2558 CPPUNIT_ASSERT_EQUAL(SvxBorderLineStyle::DOTTED, pBoxItem->GetLeft()->GetBorderLineStyle());
2559 CPPUNIT_ASSERT_EQUAL(SvxBorderLineStyle::DOTTED, pBoxItem->GetRight()->GetBorderLineStyle());
2560 CPPUNIT_ASSERT_EQUAL(SvxBorderLineStyle::DOTTED, pBoxItem->GetTop()->GetBorderLineStyle());
2561 CPPUNIT_ASSERT_EQUAL(SvxBorderLineStyle::DOTTED, pBoxItem->GetBottom()->GetBorderLineStyle());
2562 ASSERT_DOUBLES_EQUAL_MESSAGE("Error with left width", 1, pBoxItem->GetLeft()->GetWidth());
2563 ASSERT_DOUBLES_EQUAL_MESSAGE("Error with right width", 1, pBoxItem->GetRight()->GetWidth());
2564 ASSERT_DOUBLES_EQUAL_MESSAGE("Error with top width", 1, pBoxItem->GetTop()->GetWidth());
2565 ASSERT_DOUBLES_EQUAL_MESSAGE("Error with bottom width", 1, pBoxItem->GetBottom()->GetWidth());
2567 CPPUNIT_ASSERT_MESSAGE("Style Name1 : Has Attribute Protection, but it shouldn't.",
2568 !pStyleSheet->GetItemSet().HasItem(ATTR_PROTECTION, &pItem));
2569 CPPUNIT_ASSERT_MESSAGE("Style Name1 : Has Attribute font, but it shouldn't.",
2570 !pStyleSheet->GetItemSet().HasItem(ATTR_FONT, &pItem));
2571 CPPUNIT_ASSERT_MESSAGE("Style Name1 : Has Attribute number format, but it shouldn't.",
2572 !pStyleSheet->GetItemSet().HasItem(ATTR_VALUE_FORMAT, &pItem));
2574 /* Test for Style "Name2"
2575 * Has 4 sided borders + Diagonal borders.
2577 pStyleSheet = pStyleSheetPool->FindCaseIns("Name2", SfxStyleFamily::Para);
2579 CPPUNIT_ASSERT_MESSAGE("Style Name2 : Doesn't have Attribute background, but it should have.",
2580 pStyleSheet->GetItemSet().HasItem(ATTR_BORDER, &pItem));
2582 pBoxItem = static_cast<const SvxBoxItem*>(pItem);
2583 CPPUNIT_ASSERT_EQUAL(Color(0, 0, 0), pBoxItem->GetLeft()->GetColor());
2584 CPPUNIT_ASSERT_EQUAL(Color(255, 0, 0), pBoxItem->GetRight()->GetColor());
2585 CPPUNIT_ASSERT_EQUAL(SvxBorderLineStyle::SOLID, pBoxItem->GetLeft()->GetBorderLineStyle());
2586 CPPUNIT_ASSERT_EQUAL(SvxBorderLineStyle::DOTTED, pBoxItem->GetRight()->GetBorderLineStyle());
2587 ASSERT_DOUBLES_EQUAL_MESSAGE("Error with left width", 0, pBoxItem->GetLeft()->GetWidth());
2588 ASSERT_DOUBLES_EQUAL_MESSAGE("Error with right width", 14, pBoxItem->GetRight()->GetWidth());
2590 CPPUNIT_ASSERT_MESSAGE("Style Name2 : Doesn't have Attribute diagonal(tl-br) border, but it should have.",
2591 pStyleSheet->GetItemSet().HasItem(ATTR_BORDER_TLBR, &pItem));
2593 const SvxLineItem* pTLBR= static_cast<const SvxLineItem*>(pItem);
2594 CPPUNIT_ASSERT_EQUAL(Color(18, 0, 0), pTLBR->GetLine()->GetColor());
2595 CPPUNIT_ASSERT_EQUAL(SvxBorderLineStyle::DASH_DOT, pTLBR->GetLine()->GetBorderLineStyle());
2596 ASSERT_DOUBLES_EQUAL_MESSAGE("Error with diagonal tl-br width", 14, pTLBR->GetLine()->GetWidth());
2598 CPPUNIT_ASSERT_MESSAGE("Style Name2 : Doesn't have Attribute diagonal(bl-tr) border, but it should have.",
2599 pStyleSheet->GetItemSet().HasItem(ATTR_BORDER_BLTR, &pItem));
2601 const SvxLineItem* pBLTR= static_cast<const SvxLineItem*>(pItem);
2602 CPPUNIT_ASSERT_EQUAL(Color(255, 204, 238), pBLTR->GetLine()->GetColor());
2603 CPPUNIT_ASSERT_EQUAL(SvxBorderLineStyle::DASHED, pBLTR->GetLine()->GetBorderLineStyle());
2604 ASSERT_DOUBLES_EQUAL_MESSAGE("Error with diagonal tl-br width", 34, pBLTR->GetLine()->GetWidth());
2606 CPPUNIT_ASSERT_MESSAGE("Style Name2 : Has Attribute background, but it shouldn't.",
2607 !pStyleSheet->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem));
2608 CPPUNIT_ASSERT_MESSAGE("Style Name2 : Has Attribute font, but it shouldn't.",
2609 !pStyleSheet->GetItemSet().HasItem(ATTR_FONT, &pItem));
2610 CPPUNIT_ASSERT_MESSAGE("Style Name2 : Has Attribute number format, but it shouldn't.",
2611 !pStyleSheet->GetItemSet().HasItem(ATTR_VALUE_FORMAT, &pItem));
2613 /* Test for Style "Name3"
2614 * Hidden, protected and content is printed.
2616 pStyleSheet = pStyleSheetPool->FindCaseIns("Name3", SfxStyleFamily::Para);
2617 CPPUNIT_ASSERT_MESSAGE("Style Name3 : Doesn't have Attribute Protection, but it should have.",
2618 pStyleSheet->GetItemSet().HasItem(ATTR_PROTECTION, &pItem));
2620 CPPUNIT_ASSERT_MESSAGE("Style Name 3 : Error with Protection attribute." ,bool(ScProtectionAttr(true, false, true, true) == *pItem));
2622 /* Test for Style "Name4"
2623 * Hidden, protected and content is printed.
2625 pStyleSheet = pStyleSheetPool->FindCaseIns("Name4", SfxStyleFamily::Para);
2626 CPPUNIT_ASSERT_MESSAGE("Style Name4 : Doesn't have Attribute Protection, but it should have.",
2627 pStyleSheet->GetItemSet().HasItem(ATTR_PROTECTION, &pItem));
2629 CPPUNIT_ASSERT_MESSAGE("Style Name 4 : Error with Protection attribute." ,bool(ScProtectionAttr(true, true, false, false) == *pItem));
2631 /* Test for Style "Name3"
2632 * Hidden, protected and content is printed.
2634 pStyleSheet = pStyleSheetPool->FindCaseIns("Name5", SfxStyleFamily::Para);
2635 CPPUNIT_ASSERT_MESSAGE("Style Name5 : Doesn't have Attribute Protection, but it should have.",
2636 pStyleSheet->GetItemSet().HasItem(ATTR_PROTECTION, &pItem));
2638 CPPUNIT_ASSERT_MESSAGE("Style Name 5 : Error with Protection attribute." ,bool(ScProtectionAttr(false, false, false, true) == *pItem));
2640 CPPUNIT_ASSERT_MESSAGE("Style Name5 : Has Attribute Border, but it shouldn't.",
2641 !pStyleSheet->GetItemSet().HasItem(ATTR_BORDER, &pItem));
2642 CPPUNIT_ASSERT_MESSAGE("Style Name5: Has Attribute background, but it shouldn't.",
2643 !pStyleSheet->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem));
2644 CPPUNIT_ASSERT_MESSAGE("Style Name5 : Has Attribute font, but it shouldn't.",
2645 !pStyleSheet->GetItemSet().HasItem(ATTR_FONT, &pItem));
2646 CPPUNIT_ASSERT_MESSAGE("Style Name5 : Has Attribute number format, but it shouldn't.",
2647 !pStyleSheet->GetItemSet().HasItem(ATTR_VALUE_FORMAT, &pItem));
2649 /* Test for Style "Name6"
2650 * Has Font name, posture, weight, color, height
2652 pStyleSheet = pStyleSheetPool->FindCaseIns("Name6", SfxStyleFamily::Para);
2653 CPPUNIT_ASSERT_MESSAGE("Style Name6 : Doesn't have Attribute Font, but it should have.",
2654 pStyleSheet->GetItemSet().HasItem(ATTR_FONT, &pItem));
2656 const SvxFontItem* pFontItem= static_cast<const SvxFontItem*>(pItem);
2657 CPPUNIT_ASSERT_EQUAL_MESSAGE("Style Name6 :Error with Font name", OUString("Liberation Sans"), pFontItem->GetStyleName());
2659 CPPUNIT_ASSERT_MESSAGE("Style Name6 : Doesn't have Attribute Font Height, but it should have.",
2660 pStyleSheet->GetItemSet().HasItem(ATTR_FONT_HEIGHT, &pItem));
2662 const SvxFontHeightItem* pFontHeightItem= static_cast<const SvxFontHeightItem*>(pItem);
2663 CPPUNIT_ASSERT_EQUAL_MESSAGE("Style Name6 :Error with Font Height", static_cast<sal_uInt32>(480), pFontHeightItem->GetHeight());
2665 CPPUNIT_ASSERT_MESSAGE("Style Name6 : Doesn't have Attribute Font Posture, but it should have.",
2666 pStyleSheet->GetItemSet().HasItem(ATTR_FONT_POSTURE, &pItem));
2668 const SvxPostureItem* pFontPostureItem= static_cast<const SvxPostureItem*>(pItem);
2669 CPPUNIT_ASSERT_EQUAL_MESSAGE("Style Name6 :Error with Font Posture", ITALIC_NORMAL, pFontPostureItem->GetPosture());
2671 CPPUNIT_ASSERT_MESSAGE("Style Name6 : Doesn't have Attribute Font Weight, but it should have.",
2672 pStyleSheet->GetItemSet().HasItem(ATTR_FONT_WEIGHT, &pItem));
2674 const SvxWeightItem* pFontWeightItem= static_cast<const SvxWeightItem*>(pItem);
2675 CPPUNIT_ASSERT_EQUAL_MESSAGE("Style Name6 :Error with Font Weight", WEIGHT_BOLD, pFontWeightItem->GetWeight());
2677 CPPUNIT_ASSERT_MESSAGE("Style Name6 : Doesn't have Attribute Font Color, but it should have.",
2678 pStyleSheet->GetItemSet().HasItem(ATTR_FONT_COLOR, &pItem));
2680 const SvxColorItem* pFontColorItem= static_cast<const SvxColorItem*>(pItem);
2681 CPPUNIT_ASSERT_EQUAL_MESSAGE("Style Name6 :Error with Font Color", Color(128, 128, 128), pFontColorItem->GetValue());
2683 CPPUNIT_ASSERT_MESSAGE("Style Name6 : Doesn't have Attribute Underline, but it should have.",
2684 pStyleSheet->GetItemSet().HasItem(ATTR_FONT_UNDERLINE, &pItem));
2686 const SvxUnderlineItem* pUnderlineItem= static_cast<const SvxUnderlineItem*>(pItem);
2687 CPPUNIT_ASSERT_EQUAL_MESSAGE("Style Name6 :Error with Font Underline Style", LINESTYLE_SINGLE, pUnderlineItem->GetLineStyle());
2688 CPPUNIT_ASSERT_EQUAL_MESSAGE("Style Name6 :Error with Font Underline Color", Color(128, 128, 128), pUnderlineItem->GetColor());
2690 /* Test for Style Name "7"
2691 * Has strikethrough single
2693 pStyleSheet = pStyleSheetPool->FindCaseIns("Name7", SfxStyleFamily::Para);
2694 CPPUNIT_ASSERT_MESSAGE("Style Name7 : Doesn't have Attribute Strikeout, but it should have.",
2695 pStyleSheet->GetItemSet().HasItem(ATTR_FONT_CROSSEDOUT, &pItem));
2697 const SvxCrossedOutItem* pCrossedOutItem = static_cast<const SvxCrossedOutItem*>(pItem);
2698 CPPUNIT_ASSERT_EQUAL_MESSAGE("Style Name7 :Error with Strikeout", STRIKEOUT_SINGLE, pCrossedOutItem->GetStrikeout());
2700 /* Test for Style Name "8"
2701 * Has strikethrough bold
2703 pStyleSheet = pStyleSheetPool->FindCaseIns("Name8", SfxStyleFamily::Para);
2704 CPPUNIT_ASSERT_MESSAGE("Style Name8 : Doesn't have Attribute Strikeout, but it should have.",
2705 pStyleSheet->GetItemSet().HasItem(ATTR_FONT_CROSSEDOUT, &pItem));
2707 pCrossedOutItem = static_cast<const SvxCrossedOutItem*>(pItem);
2708 CPPUNIT_ASSERT_EQUAL_MESSAGE("Style Name7 :Error with Strikeout", STRIKEOUT_BOLD, pCrossedOutItem->GetStrikeout());
2710 /* Test for Style Name "9"
2711 * Has strikethrough slash
2713 pStyleSheet = pStyleSheetPool->FindCaseIns("Name9", SfxStyleFamily::Para);
2714 CPPUNIT_ASSERT_MESSAGE("Style Name9 : Doesn't have Attribute Strikeout, but it should have.",
2715 pStyleSheet->GetItemSet().HasItem(ATTR_FONT_CROSSEDOUT, &pItem));
2717 pCrossedOutItem = static_cast<const SvxCrossedOutItem*>(pItem);
2718 CPPUNIT_ASSERT_EQUAL_MESSAGE("Style Name9 :Error with Strikeout", STRIKEOUT_SLASH, pCrossedOutItem->GetStrikeout());
2720 /* Test for Style Name "10"
2721 * Has ver align, and hor align
2724 pStyleSheet = pStyleSheetPool->FindCaseIns("Name10", SfxStyleFamily::Para);
2725 CPPUNIT_ASSERT_MESSAGE("Style Name10 : Doesn't have Attribute hor justify, but it should have.",
2726 pStyleSheet->GetItemSet().HasItem(ATTR_HOR_JUSTIFY, &pItem));
2728 const SvxHorJustifyItem* pHorJustify = static_cast<const SvxHorJustifyItem*>(pItem);
2729 CPPUNIT_ASSERT_EQUAL_MESSAGE("Style Name10 :Error with hor justify", SvxCellHorJustify::Right, pHorJustify->GetValue());
2731 pStyleSheet = pStyleSheetPool->FindCaseIns("Name10", SfxStyleFamily::Para);
2732 CPPUNIT_ASSERT_MESSAGE("Style Name10 : Doesn't have Attribute ver justify, but it should have.",
2733 pStyleSheet->GetItemSet().HasItem(ATTR_VER_JUSTIFY, &pItem));
2735 const SvxVerJustifyItem* pVerJustify = static_cast<const SvxVerJustifyItem*>(pItem);
2736 CPPUNIT_ASSERT_EQUAL_MESSAGE("Style Name10 :Error with ver justify", SvxCellVerJustify::Center, pVerJustify->GetValue());
2740 void ScFiltersTest::testLiteralInFormulaXLS()
2742 ScDocShellRef xDocSh = loadDoc("shared-string/literal-in-formula.", FORMAT_XLS);
2743 CPPUNIT_ASSERT(xDocSh.is());
2745 ScDocument& rDoc = xDocSh->GetDocument();
2746 rDoc.CalcAll();
2748 CPPUNIT_ASSERT_EQUAL(2.0, rDoc.GetValue(ScAddress(0,0,0)));
2750 xDocSh->DoClose();
2753 void ScFiltersTest::testFormulaDependency()
2755 ScDocShellRef xDocSh = ScBootstrapFixture::loadDoc("dependencyTree.", FORMAT_ODS);
2757 ScDocument& rDoc = xDocSh->GetDocument();
2759 // check if formula in A1 changes value
2760 double nVal = rDoc.GetValue(0,0,0);
2761 CPPUNIT_ASSERT_DOUBLES_EQUAL(nVal, 1.0, 1e-10);
2762 rDoc.SetValue(0,1,0, 0.0);
2763 nVal = rDoc.GetValue(0,0,0);
2764 CPPUNIT_ASSERT_DOUBLES_EQUAL(nVal, 2.0, 1e-10);
2766 // check that the number format is implicitly inherited
2767 // CPPUNIT_ASSERT_EQUAL(rDoc.GetString(0,4,0), rDoc.GetString(0,5,0));
2769 xDocSh->DoClose();
2772 void ScFiltersTest::testMiscRowHeights()
2774 // FIXME: the DPI check should be removed when either (1) the test is fixed to work with
2775 // non-default DPI; or (2) unit tests on Windows are made to use svp VCL plugin.
2776 if (Application::GetDefaultDevice()->GetDPIX() != 96
2777 || Application::GetDefaultDevice()->GetDPIY() != 96)
2778 return;
2780 static const TestParam::RowData DfltRowData[] =
2782 // check rows at the beginning and end of document
2783 // and make sure they are reported as the default row
2784 // height ( indicated by -1 )
2785 { 2, 4, 0, -1, 0, false },
2786 { 1048573, 1048575, 0, -1, 0, false },
2789 static const TestParam::RowData MultiLineOptData[] =
2791 // Row 0 is 12.63 mm and optimal flag is set => 12.36 mm
2792 { 0, 0, 0, 1236, CHECK_OPTIMAL, true },
2793 // Row 1 is 11.99 mm and optimal flag is NOT set
2794 { 1, 1, 0, 1199, CHECK_OPTIMAL, false },
2797 TestParam aTestValues[] =
2799 /* Checks that a document saved to ods with default rows does indeed
2800 have default row heights ( there was a problem where the optimal
2801 height was being calculated after import if no hard height )
2803 { "alldefaultheights.", FORMAT_ODS, -1, SAL_N_ELEMENTS(DfltRowData), DfltRowData },
2804 /* Checks the imported height of some multiline input, additionally checks
2805 that the optimal height flag is set ( or not )
2807 { "multilineoptimal.", FORMAT_ODS, -1, SAL_N_ELEMENTS(MultiLineOptData), MultiLineOptData },
2809 miscRowHeightsTest( aTestValues, SAL_N_ELEMENTS(aTestValues) );
2812 // regression test at least fdo#59193
2813 // what we want to test here is that when cell contents are deleted
2814 // and the optimal flag is set for that row that the row is actually resized
2816 void ScFiltersTest::testOptimalHeightReset()
2818 // FIXME: the DPI check should be removed when either (1) the test is fixed to work with
2819 // non-default DPI; or (2) unit tests on Windows are made to use svp VCL plugin.
2820 if (Application::GetDefaultDevice()->GetDPIX() != 96
2821 || Application::GetDefaultDevice()->GetDPIY() != 96)
2822 return;
2824 ScDocShellRef xDocSh = loadDoc("multilineoptimal.", FORMAT_ODS, true);
2825 SCTAB nTab = 0;
2826 SCROW nRow = 0;
2827 ScDocument& rDoc = xDocSh->GetDocument();
2828 // open document in read/write mode ( otherwise optimal height stuff won't
2829 // be triggered ) *and* you can't delete cell contents.
2830 int nHeight = sc::TwipsToHMM ( rDoc.GetRowHeight(nRow, nTab, false) );
2831 CPPUNIT_ASSERT_EQUAL(1236, nHeight);
2833 ScDocFunc &rFunc = xDocSh->GetDocFunc();
2835 // delete content of A1
2836 ScRange aDelRange(0,0,0,0,0,0);
2837 ScMarkData aMark(MAXROW, MAXCOL);
2838 aMark.SetMarkArea(aDelRange);
2839 bool bRet = rFunc.DeleteContents( aMark, InsertDeleteFlags::ALL, false, true );
2840 CPPUNIT_ASSERT_MESSAGE("DeleteContents failed", bRet);
2842 // get the new height of A1
2843 nHeight = sc::TwipsToHMM( rDoc.GetRowHeight(nRow, nTab, false) );
2845 // set optimal height for empty row 2
2846 std::vector<sc::ColRowSpan> aRowArr(1, sc::ColRowSpan(2,2));
2847 rFunc.SetWidthOrHeight(false, aRowArr, nTab, SC_SIZE_OPTIMAL, 0, true, true);
2849 // retrieve optimal height
2850 int nOptimalHeight = sc::TwipsToHMM( rDoc.GetRowHeight(aRowArr[0].mnStart, nTab, false) );
2852 // check if the new height of A1 ( after delete ) is now the optimal height of an empty cell
2853 CPPUNIT_ASSERT_EQUAL(nOptimalHeight, nHeight );
2854 xDocSh->DoClose();
2857 void ScFiltersTest::testCustomNumFormatHybridCellODS()
2859 ScDocShellRef xDocSh = loadDoc("custom-numfmt-hybrid-cell.", FORMAT_ODS, false);
2860 ScDocument& rDoc = xDocSh->GetDocument();
2861 rDoc.SetAutoCalc(true);
2863 // All of B14, B16 and B18 should be displaying empty strings by virtue
2864 // of the custom number format being set on those cells.
2866 for (SCROW nRow : {13, 15, 17})
2868 ScAddress aPos(1, nRow, 0);
2869 OUString aStr = rDoc.GetString(aPos);
2870 CPPUNIT_ASSERT(aStr.isEmpty());
2873 // Now, set value of 1 to B15. This should trigger re-calc on B18 and B18
2874 // should now show a value of 1.
2875 rDoc.SetValue(ScAddress(1,15,0), 1.0);
2877 OUString aStr = rDoc.GetString(ScAddress(1,17,0));
2878 CPPUNIT_ASSERT_EQUAL(OUString("1"), aStr);
2880 // Make sure the cell doesn't have an error value.
2881 ScFormulaCell* pFC = rDoc.GetFormulaCell(ScAddress(1,17,0));
2882 CPPUNIT_ASSERT(pFC);
2883 CPPUNIT_ASSERT_EQUAL(FormulaError::NONE, pFC->GetErrCode());
2885 xDocSh->DoClose();
2888 void ScFiltersTest::testTdf121040()
2890 ScDocShellRef xDocSh = loadDoc("tdf121040.", FORMAT_ODS);
2891 CPPUNIT_ASSERT_MESSAGE("Failed to load tdf121040.ods", xDocSh.is());
2893 const SCTAB nTab = 0;
2894 ScDocument& rDoc = xDocSh->GetDocument();
2896 // The first 9 rows should have the same height
2897 const sal_uInt16 nHeight = rDoc.GetRowHeight(0, nTab, false);
2898 for (SCTAB nRow=1; nRow<9; nRow++)
2900 CPPUNIT_ASSERT_EQUAL(nHeight, rDoc.GetRowHeight(nRow, nTab, false));
2903 xDocSh->DoClose();
2906 void ScFiltersTest::testPrintRangeODS()
2908 ScDocShellRef xDocSh = loadDoc("print-range.", FORMAT_ODS);
2909 ScDocument& rDoc = xDocSh->GetDocument();
2910 const ScRange* pRange = rDoc.GetRepeatRowRange(0);
2911 CPPUNIT_ASSERT(pRange);
2912 CPPUNIT_ASSERT_EQUAL(ScRange(0,0,0,0,1,0), *pRange);
2914 pRange = rDoc.GetRepeatRowRange(1);
2915 CPPUNIT_ASSERT(pRange);
2916 CPPUNIT_ASSERT_EQUAL(ScRange(0,2,0,0,4,0), *pRange);
2918 xDocSh->DoClose();
2921 void ScFiltersTest::testOutlineODS()
2923 ScDocShellRef xDocSh = loadDoc("outline.", FORMAT_ODS);
2924 ScDocument& rDoc = xDocSh->GetDocument();
2926 const ScOutlineTable* pTable = rDoc.GetOutlineTable(0);
2927 CPPUNIT_ASSERT(pTable);
2929 const ScOutlineArray& rArr = pTable->GetRowArray();
2930 size_t nDepth = rArr.GetDepth();
2931 CPPUNIT_ASSERT_EQUAL(size_t(4), nDepth);
2933 for(size_t i = 0; i < nDepth; ++i)
2935 CPPUNIT_ASSERT_EQUAL(size_t(1), rArr.GetCount(i));
2938 struct OutlineData {
2939 SCCOLROW nStart;
2940 SCCOLROW nEnd;
2941 bool bHidden;
2942 bool bVisible;
2944 size_t nDepth;
2945 size_t nIndex;
2948 static const OutlineData aRow[] =
2950 { 1, 29, false, true, 0, 0 },
2951 { 2, 26, false, true, 1, 0 },
2952 { 4, 23, false, true, 2, 0 },
2953 { 6, 20, true, true, 3, 0 }
2956 for(size_t i = 0; i < SAL_N_ELEMENTS(aRow); ++i)
2959 const ScOutlineEntry* pEntry = rArr.GetEntry(aRow[i].nDepth, aRow[i].nIndex);
2960 SCCOLROW nStart = pEntry->GetStart();
2961 CPPUNIT_ASSERT_EQUAL(aRow[i].nStart, nStart);
2963 SCCOLROW nEnd = pEntry->GetEnd();
2964 CPPUNIT_ASSERT_EQUAL(aRow[i].nEnd, nEnd);
2966 bool bHidden = pEntry->IsHidden();
2967 CPPUNIT_ASSERT_EQUAL(aRow[i].bHidden, bHidden);
2969 bool bVisible = pEntry->IsVisible();
2970 CPPUNIT_ASSERT_EQUAL(aRow[i].bVisible, bVisible);
2973 xDocSh->DoClose();
2976 void ScFiltersTest::testColumnStyleXLSX()
2978 ScDocShellRef xDocSh = loadDoc("column-style.", FORMAT_XLSX);
2979 CPPUNIT_ASSERT(xDocSh.is());
2980 ScDocument& rDoc = xDocSh->GetDocument();
2982 const ScPatternAttr* pPattern = rDoc.GetPattern(0,0,0);
2983 CPPUNIT_ASSERT(pPattern);
2985 const ScProtectionAttr& rAttr = pPattern->GetItem(ATTR_PROTECTION);
2986 CPPUNIT_ASSERT(rAttr.GetProtection());
2988 pPattern = rDoc.GetPattern(0,1,0);
2989 CPPUNIT_ASSERT(pPattern);
2991 const ScProtectionAttr& rAttrNew = pPattern->GetItem(ATTR_PROTECTION);
2992 CPPUNIT_ASSERT(!rAttrNew.GetProtection());
2994 xDocSh->DoClose();
2997 void ScFiltersTest::testColumnStyleAutoFilterXLSX()
2999 ScDocShellRef xDocSh = loadDoc("column-style-autofilter.", FORMAT_XLSX);
3000 CPPUNIT_ASSERT(xDocSh.is());
3001 ScDocument& rDoc = xDocSh->GetDocument();
3003 const ScPatternAttr* pPattern = rDoc.GetPattern(0, 10, 18);
3004 CPPUNIT_ASSERT(pPattern);
3006 const ScMergeFlagAttr& rAttr = pPattern->GetItem(ATTR_MERGE_FLAG);
3007 CPPUNIT_ASSERT(!rAttr.HasAutoFilter());
3009 xDocSh->DoClose();
3012 void ScFiltersTest::testSharedFormulaHorizontalXLS()
3014 ScDocShellRef xDocSh = loadDoc("shared-formula/horizontal.", FORMAT_XLS);
3015 CPPUNIT_ASSERT(xDocSh.is());
3016 ScDocument& rDoc = xDocSh->GetDocument();
3018 // Make sure K2:S2 on the 2nd sheet are all formula cells.
3019 ScAddress aPos(0, 1, 1);
3020 for (SCCOL nCol = 10; nCol <= 18; ++nCol)
3022 aPos.SetCol(nCol);
3023 CPPUNIT_ASSERT_EQUAL_MESSAGE("Formula cell is expected here.", CELLTYPE_FORMULA, rDoc.GetCellType(aPos));
3026 // Likewise, B3:J9 all should be formula cells.
3027 for (SCCOL nCol = 1; nCol <= 9; ++nCol)
3029 aPos.SetCol(nCol);
3030 for (SCROW nRow = 2; nRow <= 8; ++nRow)
3032 aPos.SetRow(nRow);
3033 CPPUNIT_ASSERT_EQUAL_MESSAGE("Formula cell is expected here.", CELLTYPE_FORMULA, rDoc.GetCellType(aPos));
3037 // B2:I2 too.
3038 aPos.SetRow(1);
3039 for (SCCOL nCol = 1; nCol <= 8; ++nCol)
3041 aPos.SetCol(nCol);
3042 CPPUNIT_ASSERT_EQUAL_MESSAGE("Formula cell is expected here.", CELLTYPE_FORMULA, rDoc.GetCellType(aPos));
3045 // J2 has a string of "MW".
3046 aPos.SetCol(9);
3047 CPPUNIT_ASSERT_EQUAL(OUString("MW"), rDoc.GetString(aPos));
3049 xDocSh->DoClose();
3052 void ScFiltersTest::testSharedFormulaWrappedRefsXLS()
3054 ScDocShellRef xDocSh = loadDoc("shared-formula/wrapped-refs.", FORMAT_XLS);
3055 CPPUNIT_ASSERT(xDocSh.is());
3056 ScDocument& rDoc = xDocSh->GetDocument();
3057 rDoc.CalcAll();
3059 // Check the values of H7:H10.
3060 CPPUNIT_ASSERT_EQUAL(7.0, rDoc.GetValue(ScAddress(7,6,0)));
3061 CPPUNIT_ASSERT_EQUAL(8.0, rDoc.GetValue(ScAddress(7,7,0)));
3062 CPPUNIT_ASSERT_EQUAL(9.0, rDoc.GetValue(ScAddress(7,8,0)));
3063 CPPUNIT_ASSERT_EQUAL(10.0, rDoc.GetValue(ScAddress(7,9,0)));
3065 // EM7:EM10 should reference H7:H10.
3066 CPPUNIT_ASSERT_EQUAL(7.0, rDoc.GetValue(ScAddress(142,6,0)));
3067 CPPUNIT_ASSERT_EQUAL(8.0, rDoc.GetValue(ScAddress(142,7,0)));
3068 CPPUNIT_ASSERT_EQUAL(9.0, rDoc.GetValue(ScAddress(142,8,0)));
3069 CPPUNIT_ASSERT_EQUAL(10.0, rDoc.GetValue(ScAddress(142,9,0)));
3071 // Make sure EM7:EM10 are grouped.
3072 const ScFormulaCell *pFC = rDoc.GetFormulaCell(ScAddress(142,6,0));
3073 CPPUNIT_ASSERT(pFC);
3074 CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(6), pFC->GetSharedTopRow());
3075 CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(4), pFC->GetSharedLength());
3077 xDocSh->DoClose();
3080 void ScFiltersTest::testSharedFormulaBIFF5()
3082 ScDocShellRef xDocSh = loadDoc("shared-formula/biff5.", FORMAT_XLS);
3083 CPPUNIT_ASSERT(xDocSh.is());
3084 ScDocument& rDoc = xDocSh->GetDocument();
3085 rDoc.CalcAll();
3087 // E6:E376 should be all formulas, and they should belong to the same group.
3088 const ScFormulaCell* pFC = rDoc.GetFormulaCell(ScAddress(4,5,0));
3089 CPPUNIT_ASSERT(pFC);
3090 CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(5), pFC->GetSharedTopRow());
3091 CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(371), pFC->GetSharedLength());
3093 xDocSh->DoClose();
3096 void ScFiltersTest::testSharedFormulaXLSB()
3098 ScDocShellRef xDocSh = loadDoc("shared_formula.", FORMAT_XLSB);
3099 CPPUNIT_ASSERT(xDocSh.is());
3100 ScDocument& rDoc = xDocSh->GetDocument();
3101 rDoc.CalcAll();
3103 // A1:A30 should be all formulas, and they should belong to the same group.
3104 const ScFormulaCell* pFC = rDoc.GetFormulaCell(ScAddress(0,0,0));
3105 CPPUNIT_ASSERT(pFC);
3106 CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(0), pFC->GetSharedTopRow());
3107 CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(30), pFC->GetSharedLength());
3109 for(SCROW nRow = 0; nRow < 30; ++nRow)
3111 ASSERT_DOUBLES_EQUAL(3.0, rDoc.GetValue(0, nRow, 0));
3114 xDocSh->DoClose();
3117 void ScFiltersTest::testSharedFormulaXLS()
3120 // fdo#80091
3121 ScDocShellRef xDocSh = loadDoc("shared-formula/relative-refs1.", FORMAT_XLS);
3122 CPPUNIT_ASSERT(xDocSh.is());
3123 ScDocument& rDoc = xDocSh->GetDocument();
3124 rDoc.CalcAll();
3126 // A1:A30 should be all formulas, and they should belong to the same group.
3127 const ScFormulaCell* pFC = rDoc.GetFormulaCell(ScAddress(0,1,0));
3128 CPPUNIT_ASSERT(pFC);
3129 CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(1), pFC->GetSharedTopRow());
3130 CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(29), pFC->GetSharedLength());
3132 for(SCROW nRow = 0; nRow < 30; ++nRow)
3134 ASSERT_DOUBLES_EQUAL(double(nRow+1), rDoc.GetValue(0, nRow, 0));
3137 xDocSh->DoClose();
3141 // fdo#84556 and some related tests
3142 ScDocShellRef xDocSh = loadDoc("shared-formula/relative-refs2.", FORMAT_XLS);
3143 CPPUNIT_ASSERT(xDocSh.is());
3144 ScDocument& rDoc = xDocSh->GetDocument();
3145 rDoc.CalcAll();
3148 const ScFormulaCell* pFC = rDoc.GetFormulaCell(ScAddress(2,1,0));
3149 CPPUNIT_ASSERT(pFC);
3150 CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(1), pFC->GetSharedTopRow());
3151 CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(10), pFC->GetSharedLength());
3153 pFC = rDoc.GetFormulaCell(ScAddress(2,10,0));
3154 CPPUNIT_ASSERT(pFC);
3155 CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(1), pFC->GetSharedTopRow());
3156 CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(10), pFC->GetSharedLength());
3158 OUString aFormula;
3159 rDoc.GetFormula(2, 1, 0, aFormula);
3160 CPPUNIT_ASSERT_EQUAL(OUString("=SUM(B9:D9)"), aFormula);
3162 rDoc.GetFormula(2, 10, 0, aFormula);
3163 CPPUNIT_ASSERT_EQUAL(OUString("=SUM(B18:D18)"), aFormula);
3167 const ScFormulaCell* pFC = rDoc.GetFormulaCell(ScAddress(4,8,0));
3168 CPPUNIT_ASSERT(pFC);
3169 CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(8), pFC->GetSharedTopRow());
3170 CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(10), pFC->GetSharedLength());
3172 pFC = rDoc.GetFormulaCell(ScAddress(4,17,0));
3173 CPPUNIT_ASSERT(pFC);
3174 CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(8), pFC->GetSharedTopRow());
3175 CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(10), pFC->GetSharedLength());
3177 OUString aFormula;
3178 rDoc.GetFormula(4, 8, 0, aFormula);
3179 CPPUNIT_ASSERT_EQUAL(OUString("=SUM(G9:EY9)"), aFormula);
3181 rDoc.GetFormula(4, 17, 0, aFormula);
3182 CPPUNIT_ASSERT_EQUAL(OUString("=SUM(G18:EY18)"), aFormula);
3186 const ScFormulaCell* pFC = rDoc.GetFormulaCell(ScAddress(6,15,0));
3187 CPPUNIT_ASSERT(pFC);
3188 CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(15), pFC->GetSharedTopRow());
3189 CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(10), pFC->GetSharedLength());
3191 pFC = rDoc.GetFormulaCell(ScAddress(6,24,0));
3192 CPPUNIT_ASSERT(pFC);
3193 CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(15), pFC->GetSharedTopRow());
3194 CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(10), pFC->GetSharedLength());
3196 OUString aFormula;
3197 rDoc.GetFormula(6, 15, 0, aFormula);
3198 CPPUNIT_ASSERT_EQUAL(OUString("=SUM(A16:A40000)"), aFormula);
3200 rDoc.GetFormula(6, 24, 0, aFormula);
3201 CPPUNIT_ASSERT_EQUAL(OUString("=SUM(A25:A40009)"), aFormula);
3204 xDocSh->DoClose();
3208 void ScFiltersTest::testSharedFormulaColumnLabelsODS()
3210 ScDocShellRef xDocSh = loadDoc("shared-formula/column-labels.", FORMAT_ODS);
3212 CPPUNIT_ASSERT(xDocSh.is());
3213 ScDocument& rDoc = xDocSh->GetDocument();
3214 rDoc.CalcAll();
3216 CPPUNIT_ASSERT_EQUAL( 5.0, rDoc.GetValue(ScAddress(2,1,0)));
3217 CPPUNIT_ASSERT_EQUAL(15.0, rDoc.GetValue(ScAddress(2,2,0)));
3218 CPPUNIT_ASSERT_EQUAL(30.0, rDoc.GetValue(ScAddress(2,3,0)));
3219 CPPUNIT_ASSERT_EQUAL(28.0, rDoc.GetValue(ScAddress(2,4,0)));
3220 CPPUNIT_ASSERT_EQUAL(48.0, rDoc.GetValue(ScAddress(2,5,0)));
3222 CPPUNIT_ASSERT_EQUAL( 0.0, rDoc.GetValue(ScAddress(3,1,0)));
3223 CPPUNIT_ASSERT_EQUAL( 50.0, rDoc.GetValue(ScAddress(3,2,0)));
3224 CPPUNIT_ASSERT_EQUAL(144.0, rDoc.GetValue(ScAddress(3,3,0)));
3225 CPPUNIT_ASSERT_EQUAL(147.0, rDoc.GetValue(ScAddress(3,4,0)));
3226 CPPUNIT_ASSERT_EQUAL(320.0, rDoc.GetValue(ScAddress(3,5,0)));
3228 CPPUNIT_ASSERT_EQUAL(0.0, rDoc.GetValue(ScAddress(4,1,0)));
3229 CPPUNIT_ASSERT_EQUAL(2.0, rDoc.GetValue(ScAddress(4,2,0)));
3230 CPPUNIT_ASSERT_EQUAL(4.0, rDoc.GetValue(ScAddress(4,3,0)));
3231 CPPUNIT_ASSERT_EQUAL(3.0, rDoc.GetValue(ScAddress(4,4,0)));
3232 CPPUNIT_ASSERT_EQUAL(5.0, rDoc.GetValue(ScAddress(4,5,0)));
3234 xDocSh->DoClose();
3237 void ScFiltersTest::testSharedFormulaColumnRowLabelsODS()
3239 ScDocShellRef xDocSh = loadDoc("shared-formula/column-row-labels.", FORMAT_ODS);
3241 CPPUNIT_ASSERT(xDocSh.is());
3242 ScDocument& rDoc = xDocSh->GetDocument();
3243 rDoc.CalcAll();
3245 // Expected output in each of the three ranges.
3247 // +---+---+---+
3248 // | 1 | 4 | 7 |
3249 // +---+---+---+
3250 // | 2 | 5 | 8 |
3251 // +---+---+---+
3252 // | 3 | 6 | 9 |
3253 // +---+---+---+
3255 auto aCheckFunc = [&](SCCOL nStartCol, SCROW nStartRow)
3257 double fExpected = 1.0;
3258 for (SCCOL nCol = 0; nCol <= 2; ++nCol)
3260 for (SCROW nRow = 0; nRow <= 2; ++nRow)
3262 ScAddress aPos(nStartCol+nCol, nStartRow+nRow, 0);
3263 CPPUNIT_ASSERT_EQUAL(fExpected, rDoc.GetValue(aPos));
3264 fExpected += 1.0;
3269 aCheckFunc(5, 1); // F2:H4
3270 aCheckFunc(9, 1); // J2:L4
3271 aCheckFunc(1, 6); // B7:D9
3273 xDocSh->DoClose();
3276 void ScFiltersTest::testExternalRefCacheXLSX()
3278 ScDocShellRef xDocSh = loadDoc("external-refs.", FORMAT_XLSX);
3279 CPPUNIT_ASSERT(xDocSh.is());
3280 ScDocument& rDoc = xDocSh->GetDocument();
3282 // These string values are cached external cell values.
3283 CPPUNIT_ASSERT_EQUAL(OUString("Name"), rDoc.GetString(ScAddress(0,0,0)));
3284 CPPUNIT_ASSERT_EQUAL(OUString("Andy"), rDoc.GetString(ScAddress(0,1,0)));
3285 CPPUNIT_ASSERT_EQUAL(OUString("Bruce"), rDoc.GetString(ScAddress(0,2,0)));
3286 CPPUNIT_ASSERT_EQUAL(OUString("Charlie"), rDoc.GetString(ScAddress(0,3,0)));
3288 xDocSh->DoClose();
3291 void ScFiltersTest::testExternalRefCacheODS()
3293 ScDocShellRef xDocSh = loadDoc("external-ref-cache.", FORMAT_ODS);
3295 CPPUNIT_ASSERT(xDocSh.is());
3296 ScDocument& rDoc = xDocSh->GetDocument();
3298 // Cells B2:B4 have VLOOKUP with external references which should all show "text".
3299 CPPUNIT_ASSERT_EQUAL(OUString("text"), rDoc.GetString(ScAddress(1,1,0)));
3300 CPPUNIT_ASSERT_EQUAL(OUString("text"), rDoc.GetString(ScAddress(1,2,0)));
3301 CPPUNIT_ASSERT_EQUAL(OUString("text"), rDoc.GetString(ScAddress(1,3,0)));
3303 // Both cells A6 and A7 should be registered with scExternalRefManager properly
3304 CPPUNIT_ASSERT_EQUAL(true, rDoc.GetExternalRefManager()->hasCellExternalReference(ScAddress(0, 5, 0)));
3305 CPPUNIT_ASSERT_EQUAL(true, rDoc.GetExternalRefManager()->hasCellExternalReference(ScAddress(0, 6, 0)));
3307 xDocSh->DoClose();
3310 void ScFiltersTest::testHybridSharedStringODS()
3312 ScDocShellRef xDocSh = loadDoc("hybrid-shared-string.", FORMAT_ODS);
3314 CPPUNIT_ASSERT(xDocSh.is());
3315 ScDocument& rDoc = xDocSh->GetDocument();
3317 // A2 contains formula with MATCH function. The result must be 2, not #N/A!
3318 CPPUNIT_ASSERT_EQUAL(2.0, rDoc.GetValue(ScAddress(0,1,0)));
3320 xDocSh->DoClose();
3323 void ScFiltersTest::testCopyMergedNumberFormats()
3325 ScDocShellRef xDocSh = loadDoc("copy-merged-number-formats.", FORMAT_ODS);
3326 CPPUNIT_ASSERT(xDocSh.is());
3327 ScDocument& rDoc = xDocSh->GetDocument();
3329 // Cells B1, C1 and D1 are formatted as dates.
3330 OUString aStrB1 = rDoc.GetString(ScAddress(1,0,0));
3331 OUString aStrC1 = rDoc.GetString(ScAddress(2,0,0));
3332 OUString aStrD1 = rDoc.GetString(ScAddress(3,0,0));
3334 ScDocument aCopyDoc;
3335 aCopyDoc.InsertTab(0, "CopyHere");
3336 rDoc.CopyStaticToDocument(ScRange(1,0,0,3,0,0), 0, &aCopyDoc);
3338 // Make sure the date formats are copied to the new document.
3339 CPPUNIT_ASSERT_EQUAL(aStrB1, aCopyDoc.GetString(ScAddress(1,0,0)));
3340 CPPUNIT_ASSERT_EQUAL(aStrC1, aCopyDoc.GetString(ScAddress(2,0,0)));
3341 CPPUNIT_ASSERT_EQUAL(aStrD1, aCopyDoc.GetString(ScAddress(3,0,0)));
3343 xDocSh->DoClose();
3346 void ScFiltersTest::testVBAUserFunctionXLSM()
3348 ScDocShellRef xDocSh = loadDoc("vba-user-function.", FORMAT_XLSM);
3349 CPPUNIT_ASSERT(xDocSh.is());
3350 ScDocument& rDoc = xDocSh->GetDocument();
3352 // A1 contains formula with user-defined function, and the function is defined in VBA.
3353 ScFormulaCell* pFC = rDoc.GetFormulaCell(ScAddress(0,0,0));
3354 CPPUNIT_ASSERT(pFC);
3356 sc::CompileFormulaContext aCxt(&rDoc);
3357 OUString aFormula = pFC->GetFormula(aCxt);
3359 CPPUNIT_ASSERT_EQUAL(OUString("=MYFUNC()"), aFormula);
3361 // Check the formula state after the load.
3362 FormulaError nErrCode = pFC->GetErrCode();
3363 CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(nErrCode));
3365 // Check the result.
3366 CPPUNIT_ASSERT_EQUAL(42.0, rDoc.GetValue(ScAddress(0,0,0)));
3368 xDocSh->DoClose();
3371 void ScFiltersTest::testEmbeddedImageXLS()
3373 // The document has one embedded image on the first sheet. Make sure it's
3374 // imported properly.
3376 ScDocShellRef xDocSh = loadDoc("file-with-png-image.", FORMAT_XLS);
3377 CPPUNIT_ASSERT(xDocSh.is());
3378 ScDocument& rDoc = xDocSh->GetDocument();
3380 ScDrawLayer* pDL = rDoc.GetDrawLayer();
3381 CPPUNIT_ASSERT(pDL);
3382 const SdrPage* pPage = pDL->GetPage(0);
3383 CPPUNIT_ASSERT(pPage);
3384 const SdrObject* pObj = pPage->GetObj(0);
3385 CPPUNIT_ASSERT(pObj);
3386 const SdrGrafObj* pImageObj = dynamic_cast<const SdrGrafObj*>(pObj);
3387 CPPUNIT_ASSERT(pImageObj);
3388 const Graphic& rGrf = pImageObj->GetGraphic();
3389 BitmapEx aBMP = rGrf.GetBitmapEx();
3390 CPPUNIT_ASSERT_MESSAGE("Bitmap content should not be empty if the image has been properly imported.", !aBMP.IsEmpty());
3392 xDocSh->DoClose();
3395 void ScFiltersTest::testErrorOnExternalReferences()
3397 ScDocShellRef xDocSh = loadDoc("blank.", FORMAT_ODS);
3398 CPPUNIT_ASSERT_MESSAGE("Failed to open empty doc", xDocSh.is());
3400 ScDocument& rDoc = xDocSh->GetDocument();
3402 // Test tdf#89330
3403 rDoc.SetString(ScAddress(0,0,0), "='file:///Path/To/FileA.ods'#$Sheet1.A1A");
3405 ScFormulaCell* pFC = rDoc.GetFormulaCell(ScAddress(0,0,0));
3406 CPPUNIT_ASSERT(pFC);
3407 CPPUNIT_ASSERT_EQUAL(int(FormulaError::NoName), static_cast<int>(pFC->GetErrCode()));
3409 ASSERT_FORMULA_EQUAL(rDoc, ScAddress(0,0,0), "'file:///Path/To/FileA.ods'#$Sheet1.A1A", "Formula changed");
3411 xDocSh->DoClose();
3414 void ScFiltersTest::testEditEngStrikeThroughXLSX()
3416 ScDocShellRef xDocSh = loadDoc("strike-through.", FORMAT_XLSX);
3417 CPPUNIT_ASSERT_MESSAGE("Failed to open doc", xDocSh.is());
3419 ScDocument& rDoc = xDocSh->GetDocument();
3421 const EditTextObject* pObj = rDoc.GetEditText(ScAddress(0, 0, 0));
3422 CPPUNIT_ASSERT(pObj);
3423 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pObj->GetParagraphCount());
3424 CPPUNIT_ASSERT_EQUAL(OUString("this is strike through this not"), pObj->GetText(0));
3426 std::vector<EECharAttrib> aAttribs;
3427 pObj->GetCharAttribs(0, aAttribs);
3428 for (const auto& rAttrib : aAttribs)
3430 if (rAttrib.pAttr->Which() == EE_CHAR_STRIKEOUT)
3432 const SvxCrossedOutItem& rItem = static_cast<const SvxCrossedOutItem&>(*rAttrib.pAttr);
3433 if (rAttrib.nStart == 0)
3435 CPPUNIT_ASSERT(rItem.GetStrikeout() != STRIKEOUT_NONE);
3437 else
3439 CPPUNIT_ASSERT_EQUAL(STRIKEOUT_NONE, rItem.GetStrikeout());
3444 xDocSh->DoClose();
3447 void ScFiltersTest::testRefStringXLSX()
3449 ScDocShellRef xDocSh = loadDoc("ref_string.", FORMAT_XLSX);
3450 CPPUNIT_ASSERT_MESSAGE("Failed to open doc", xDocSh.is());
3452 ScDocument& rDoc = xDocSh->GetDocument();
3454 double nVal = rDoc.GetValue(2, 2, 0);
3455 ASSERT_DOUBLES_EQUAL(3.0, nVal);
3457 const ScCalcConfig& rCalcConfig = rDoc.GetCalcConfig();
3458 CPPUNIT_ASSERT_EQUAL(formula::FormulaGrammar::CONV_XL_A1, rCalcConfig.meStringRefAddressSyntax);
3460 xDocSh->DoClose();
3463 void ScFiltersTest::testColumnStyle2XLSX()
3465 ScDocShellRef xDocSh = loadDoc("column_style.", FORMAT_XLSX);
3466 CPPUNIT_ASSERT_MESSAGE("Failed to open doc", xDocSh.is());
3468 ScDocument& rDoc = xDocSh->GetDocument();
3469 const ScPatternAttr* pAttr = rDoc.GetPattern(1, 1, 0);
3472 const SfxPoolItem& rItem = pAttr->GetItem(ATTR_BACKGROUND);
3473 const SvxBrushItem& rBackground = static_cast<const SvxBrushItem&>(rItem);
3474 const Color& rColor = rBackground.GetColor();
3475 CPPUNIT_ASSERT_EQUAL(Color(255, 51, 51), rColor);
3479 const SfxPoolItem& rItem = pAttr->GetItem(ATTR_HOR_JUSTIFY);
3480 const SvxHorJustifyItem& rJustify = static_cast<const SvxHorJustifyItem&>(rItem);
3481 CPPUNIT_ASSERT_EQUAL(SvxCellHorJustify::Center, rJustify.GetValue());
3485 const SfxPoolItem& rItem = pAttr->GetItem(ATTR_FONT_HEIGHT);
3486 const SvxFontHeightItem& rFontHeight = static_cast<const SvxFontHeightItem&>(rItem);
3487 sal_uInt16 nHeight = rFontHeight.GetHeight();
3488 CPPUNIT_ASSERT_EQUAL(sal_uInt16(240), nHeight);
3492 const SfxPoolItem& rItem = pAttr->GetItem(ATTR_FONT);
3493 const SvxFontItem& rFont = static_cast<const SvxFontItem&>(rItem);
3494 OUString aName = rFont.GetFamilyName();
3495 CPPUNIT_ASSERT_EQUAL(OUString("Linux Biolinum G"), aName);
3498 xDocSh->DoClose();
3501 void ScFiltersTest::testTdf110440XLSX()
3503 ScDocShellRef xDocSh = loadDoc("tdf110440.", FORMAT_XLSX);
3504 CPPUNIT_ASSERT_MESSAGE("Failed to open doc", xDocSh.is());
3506 uno::Reference<frame::XModel> xModel = xDocSh->GetModel();
3507 uno::Reference<sheet::XSpreadsheetDocument> xDoc(xModel, uno::UNO_QUERY_THROW);
3508 uno::Reference<container::XIndexAccess> xIA(xDoc->getSheets(), uno::UNO_QUERY_THROW);
3509 uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(xIA->getByIndex(0), uno::UNO_QUERY_THROW);
3510 xIA.set(xDrawPageSupplier->getDrawPage(), uno::UNO_QUERY_THROW);
3511 uno::Reference<beans::XPropertySet> xShape(xIA->getByIndex(0), uno::UNO_QUERY_THROW);
3512 bool bVisible = true;
3513 xShape->getPropertyValue("Visible") >>= bVisible;
3514 // This failed: group shape's hidden property was lost on import.
3515 CPPUNIT_ASSERT(!bVisible);
3517 xDocSh->DoClose();
3520 void ScFiltersTest::testTdf111974XLSM()
3522 // Would crash without the fix on loading
3523 ScDocShellRef xDocSh = loadDoc("tdf111974.", FORMAT_XLSM);
3524 CPPUNIT_ASSERT_MESSAGE("Failed to open doc", xDocSh.is());
3525 xDocSh->DoClose();
3528 void ScFiltersTest::testBnc762542()
3530 ScDocShellRef xDocSh = loadDoc("bnc762542.", FORMAT_XLSX);
3531 CPPUNIT_ASSERT_MESSAGE("Failed to open doc", xDocSh.is());
3533 ScDocument& rDoc = xDocSh->GetDocument();
3534 ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer();
3535 SdrPage* pPage = pDrawLayer->GetPage(0);
3536 CPPUNIT_ASSERT_MESSAGE("draw page for sheet 1 should exist.", pPage);
3538 const size_t nCount = pPage->GetObjCount();
3539 CPPUNIT_ASSERT_EQUAL_MESSAGE("There should be 10 shapes.", static_cast<size_t>(10), nCount);
3541 // previously, some of the shapes were (incorrectly) rotated by 90 degrees
3542 for (size_t i : { 1, 2, 4, 5, 7, 9 })
3544 SdrObject* pObj = pPage->GetObj(i);
3545 CPPUNIT_ASSERT_MESSAGE("Failed to get drawing object.", pObj);
3547 tools::Rectangle aRect(pObj->GetCurrentBoundRect());
3548 CPPUNIT_ASSERT_MESSAGE("Drawing object shouldn't be rotated.", aRect.GetWidth() > aRect.GetHeight());
3551 xDocSh->DoClose();
3554 void ScFiltersTest::testHiddenSheetsXLSX()
3556 ScDocShellRef xDocSh = loadDoc("hidden_sheets.", FORMAT_XLSX);
3557 CPPUNIT_ASSERT_MESSAGE("Failed to open doc", xDocSh.is());
3559 ScDocument& rDoc = xDocSh->GetDocument();
3560 CPPUNIT_ASSERT_EQUAL_MESSAGE("1st sheet should be hidden", false, rDoc.IsVisible(0));
3561 CPPUNIT_ASSERT_EQUAL_MESSAGE("2nd sheet should be visible", true, rDoc.IsVisible(1));
3562 CPPUNIT_ASSERT_EQUAL_MESSAGE("3rd sheet should be hidden", false, rDoc.IsVisible(2));
3564 xDocSh->DoClose();
3567 void ScFiltersTest::testAutofilterXLSX()
3569 ScDocShellRef xDocSh = loadDoc("autofilter.", FORMAT_XLSX);
3570 CPPUNIT_ASSERT_MESSAGE("Failed to open doc", xDocSh.is());
3572 ScDocument& rDoc = xDocSh->GetDocument();
3573 const ScDBData* pData = rDoc.GetDBCollection()->GetDBNearCursor(0,0,0);
3574 CPPUNIT_ASSERT(pData);
3575 ScRange aRange;
3576 pData->GetArea(aRange);
3577 CPPUNIT_ASSERT_EQUAL(ScRange(0,0,0,2,4,0), aRange);
3579 xDocSh->DoClose();
3582 namespace {
3584 void checkValidationFormula(const ScAddress& rPos, const ScDocument& rDoc, const OUString& rExpectedFormula)
3586 const SfxUInt32Item* pItem = rDoc.GetAttr(rPos, ATTR_VALIDDATA);
3587 CPPUNIT_ASSERT(pItem);
3588 sal_uLong nKey = pItem->GetValue();
3589 const ScValidationData* pData = rDoc.GetValidationEntry(nKey);
3590 CPPUNIT_ASSERT(pData);
3592 OUString aFormula = pData->GetExpression(rPos, 0);
3593 CPPUNIT_ASSERT_EQUAL(rExpectedFormula, aFormula);
3598 void ScFiltersTest::testRelFormulaValidationXLS()
3600 ScDocShellRef xDocSh = loadDoc("validation.", FORMAT_XLS);
3601 CPPUNIT_ASSERT_MESSAGE("Failed to open doc", xDocSh.is());
3603 ScDocument& rDoc = xDocSh->GetDocument();
3605 checkValidationFormula(ScAddress(3, 4, 0), rDoc, "C5");
3606 checkValidationFormula(ScAddress(5, 8, 0), rDoc, "D7");
3608 xDocSh->DoClose();
3611 void ScFiltersTest::testTdf100458()
3613 ScDocShellRef xDocSh = loadDoc("tdf100458_lost_zero_value.", FORMAT_ODS);
3614 CPPUNIT_ASSERT_MESSAGE("Failed to open doc", xDocSh.is());
3615 ScDocument& rDoc = xDocSh->GetDocument();
3616 CPPUNIT_ASSERT(rDoc.HasValueData(0, 0, 0));
3617 CPPUNIT_ASSERT_EQUAL(0.0, rDoc.GetValue(0,0,0));
3618 CPPUNIT_ASSERT(!rDoc.HasStringData(0, 0, 0));
3619 xDocSh->DoClose();
3622 void ScFiltersTest::testTdf100709XLSX()
3624 ScDocShellRef xDocSh = ScBootstrapFixture::loadDoc("tdf100709.", FORMAT_XLSX);
3625 CPPUNIT_ASSERT_MESSAGE("Failed to load tdf100709.xlsx", xDocSh.is());
3627 ScDocument& rDoc = xDocSh->GetDocument();
3628 CPPUNIT_ASSERT_EQUAL_MESSAGE("Cell B52 should not be formatted with a $", OUString("218"), rDoc.GetString(1, 51, 0));
3629 CPPUNIT_ASSERT_EQUAL_MESSAGE("Cell A75 should not be formatted as a date", OUString("218"), rDoc.GetString(0, 74, 0));
3631 xDocSh->DoClose();
3634 void ScFiltersTest::testTdf97598XLSX()
3636 ScDocShellRef xDocSh = loadDoc("tdf97598_scenarios.", FORMAT_XLSX);
3637 CPPUNIT_ASSERT_MESSAGE("Failed to load tdf97598_scenarios.xlsx", xDocSh.is());
3639 ScDocument& rDoc = xDocSh->GetDocument();
3640 OUString aStr = rDoc.GetString(0, 0, 0); // A1
3641 CPPUNIT_ASSERT_EQUAL(OUString("Cell A1"), aStr);
3643 xDocSh->DoClose();
3646 void ScFiltersTest::testTdf83672XLSX()
3648 ScDocShellRef xDocSh = loadDoc("tdf83672.", FORMAT_XLSX);
3649 CPPUNIT_ASSERT_MESSAGE("Failed to load tdf83672.xlsx", xDocSh.is());
3650 uno::Reference< drawing::XDrawPagesSupplier > xDoc(
3651 xDocSh->GetModel(), uno::UNO_QUERY_THROW );
3652 uno::Reference< drawing::XDrawPage > xPage(
3653 xDoc->getDrawPages()->getByIndex(0), uno::UNO_QUERY_THROW );
3654 uno::Reference< drawing::XShape > xShape(
3655 xPage->getByIndex(0), uno::UNO_QUERY_THROW );
3656 uno::Reference< beans::XPropertySet > xShapeProperties(
3657 xShape, uno::UNO_QUERY );
3658 sal_Int32 nRotate = 0;
3659 xShapeProperties->getPropertyValue("RotateAngle") >>= nRotate;
3660 CPPUNIT_ASSERT(nRotate != 0);
3661 xDocSh->DoClose();
3664 #ifdef UNX
3665 void ScFiltersTest::testUnicodeFileNameGnumeric()
3667 // Mapping the LO-internal URL
3668 // <file:///.../sc/qa/unit/data/gnumeric/t%C3%A4%C3%9Ft.gnumeric> to the
3669 // repo's file sc/qa/unit/data/gnumeric/t\303\244\303\237t.gnumeric only
3670 // works when the system encoding is UTF-8:
3671 if (osl_getThreadTextEncoding() != RTL_TEXTENCODING_UTF8) {
3672 return;
3674 ScDocShellRef xDocSh = loadDoc(u"t\u00E4\u00DFt.", FORMAT_GNUMERIC);
3675 CPPUNIT_ASSERT(xDocSh.is());
3677 xDocSh->DoClose();
3679 #endif
3681 void ScFiltersTest::testMergedCellsXLSXML()
3683 ScDocShellRef xDocSh = loadDoc("merged-cells.", FORMAT_XLS_XML);
3684 CPPUNIT_ASSERT_MESSAGE("Failed to load merged-cells.xml", xDocSh.is());
3685 ScDocument& rDoc = xDocSh->GetDocument();
3687 // B1:C1 is merged.
3688 ScRange aMergedRange(1,0,0); // B1
3689 rDoc.ExtendTotalMerge(aMergedRange);
3690 CPPUNIT_ASSERT_EQUAL(ScRange(1,0,0,2,0,0), aMergedRange);
3692 // D1:F1 is merged.
3693 aMergedRange = ScRange(3,0,0); // D1
3694 rDoc.ExtendTotalMerge(aMergedRange);
3695 CPPUNIT_ASSERT_EQUAL(ScRange(3,0,0,5,0,0), aMergedRange);
3697 // A2:A3 is merged.
3698 aMergedRange = ScRange(0,1,0); // A2
3699 rDoc.ExtendTotalMerge(aMergedRange);
3700 CPPUNIT_ASSERT_EQUAL(ScRange(0,1,0,0,2,0), aMergedRange);
3702 // A4:A6 is merged.
3703 aMergedRange = ScRange(0,3,0); // A4
3704 rDoc.ExtendTotalMerge(aMergedRange);
3705 CPPUNIT_ASSERT_EQUAL(ScRange(0,3,0,0,5,0), aMergedRange);
3707 // C3:F6 is merged.
3708 aMergedRange = ScRange(2,2,0); // C3
3709 rDoc.ExtendTotalMerge(aMergedRange);
3710 CPPUNIT_ASSERT_EQUAL(ScRange(2,2,0,5,5,0), aMergedRange);
3712 xDocSh->DoClose();
3715 void ScFiltersTest::testBackgroundColorStandardXLSXML()
3717 ScDocShellRef xDocSh = loadDoc("background-color-standard.", FORMAT_XLS_XML);
3718 CPPUNIT_ASSERT_MESSAGE("Failed to load background-color-standard.xml", xDocSh.is());
3719 ScDocument& rDoc = xDocSh->GetDocument();
3721 struct Check
3723 OUString aCellValue;
3724 Color aFontColor;
3725 Color aBgColor;
3728 const std::vector<Check> aChecks =
3730 { OUString("Background Color"), COL_BLACK, COL_TRANSPARENT },
3731 { OUString("Dark Red"), COL_WHITE, Color(192, 0, 0) },
3732 { OUString("Red"), COL_WHITE, Color(255, 0, 0) },
3733 { OUString("Orange"), COL_WHITE, Color(255, 192, 0) },
3734 { OUString("Yellow"), COL_WHITE, Color(255, 255, 0) },
3735 { OUString("Light Green"), COL_WHITE, Color(146, 208, 80) },
3736 { OUString("Green"), COL_WHITE, Color( 0, 176, 80) },
3737 { OUString("Light Blue"), COL_WHITE, Color( 0, 176, 240) },
3738 { OUString("Blue"), COL_WHITE, Color( 0, 112, 192) },
3739 { OUString("Dark Blue"), COL_WHITE, Color( 0, 32, 96) },
3740 { OUString("Purple"), COL_WHITE, Color(112, 48, 160) },
3743 for (size_t nRow = 0; nRow < aChecks.size(); ++nRow)
3745 ScAddress aPos(0, nRow, 0);
3746 OUString aStr = rDoc.GetString(aPos);
3747 CPPUNIT_ASSERT_EQUAL(aChecks[nRow].aCellValue, aStr);
3749 const ScPatternAttr* pPat = rDoc.GetPattern(aPos);
3750 CPPUNIT_ASSERT(pPat);
3752 const SvxColorItem& rColor = pPat->GetItem(ATTR_FONT_COLOR);
3753 CPPUNIT_ASSERT_EQUAL(aChecks[nRow].aFontColor, rColor.GetValue());
3755 const SvxBrushItem& rBgColor = pPat->GetItem(ATTR_BACKGROUND);
3756 CPPUNIT_ASSERT_EQUAL(aChecks[nRow].aBgColor, rBgColor.GetColor());
3759 xDocSh->DoClose();
3762 void ScFiltersTest::testNamedExpressionsXLSXML()
3765 // global named expressions
3767 ScDocShellRef xDocSh = loadDoc("named-exp-global.", FORMAT_XLS_XML);
3768 CPPUNIT_ASSERT_MESSAGE("Failed to load named-exp-global.xml", xDocSh.is());
3769 ScDocument& rDoc = xDocSh->GetDocument();
3771 // A7
3772 ScAddress aPos(0,6,0);
3773 CPPUNIT_ASSERT_EQUAL(15.0, rDoc.GetValue(aPos));
3774 ASSERT_FORMULA_EQUAL(rDoc, aPos, "SUM(MyRange)", nullptr);
3776 // B7
3777 aPos.IncCol();
3778 CPPUNIT_ASSERT_EQUAL(55.0, rDoc.GetValue(aPos));
3779 ASSERT_FORMULA_EQUAL(rDoc, aPos, "SUM(MyRange2)", nullptr);
3781 const ScRangeData* pRD = rDoc.GetRangeName()->findByUpperName("MYRANGE");
3782 CPPUNIT_ASSERT(pRD);
3783 pRD = rDoc.GetRangeName()->findByUpperName("MYRANGE2");
3784 CPPUNIT_ASSERT(pRD);
3786 xDocSh->DoClose();
3790 // sheet-local named expressions
3792 ScDocShellRef xDocSh = loadDoc("named-exp-local.", FORMAT_XLS_XML);
3793 CPPUNIT_ASSERT_MESSAGE("Failed to load named-exp-local.xml", xDocSh.is());
3794 ScDocument& rDoc = xDocSh->GetDocument();
3796 // A7 on Sheet1
3797 ScAddress aPos(0,6,0);
3798 CPPUNIT_ASSERT_EQUAL(27.0, rDoc.GetValue(aPos));
3799 ASSERT_FORMULA_EQUAL(rDoc, aPos, "SUM(MyRange)", nullptr);
3801 // A7 on Sheet2
3802 aPos.IncTab();
3803 CPPUNIT_ASSERT_EQUAL(74.0, rDoc.GetValue(aPos));
3804 ASSERT_FORMULA_EQUAL(rDoc, aPos, "SUM(MyRange)", nullptr);
3806 const ScRangeName* pRN = rDoc.GetRangeName(0);
3807 CPPUNIT_ASSERT(pRN);
3808 const ScRangeData* pRD = pRN->findByUpperName("MYRANGE");
3809 CPPUNIT_ASSERT(pRD);
3810 pRN = rDoc.GetRangeName(1);
3811 CPPUNIT_ASSERT(pRN);
3812 pRD = pRN->findByUpperName("MYRANGE");
3813 CPPUNIT_ASSERT(pRD);
3815 xDocSh->DoClose();
3819 void ScFiltersTest::testEmptyRowsXLSXML()
3821 ScDocShellRef xDocSh = loadDoc("empty-rows.", FORMAT_XLS_XML);
3822 CPPUNIT_ASSERT_MESSAGE("Failed to load empty-rows.xml", xDocSh.is());
3823 ScDocument& rDoc = xDocSh->GetDocument();
3826 // Expected output table content. 0 = empty cell
3827 std::vector<std::vector<const char*>> aOutputCheck = {
3828 { "Top row, followed by 2 empty rows.", nullptr },
3829 { nullptr, nullptr },
3830 { nullptr, nullptr },
3831 { nullptr, "1" },
3832 { nullptr, "2" },
3833 { nullptr, "3" },
3834 { nullptr, "4" },
3835 { nullptr, "5" },
3836 { nullptr, "15" },
3839 ScRange aDataRange;
3840 aDataRange.Parse("A1:B9", &rDoc);
3841 bool bSuccess = checkOutput(&rDoc, aDataRange, aOutputCheck, "Expected output");
3842 CPPUNIT_ASSERT_MESSAGE("Table output check failed", bSuccess);
3845 ScAddress aPos;
3846 aPos.Parse("B9", &rDoc);
3847 ASSERT_FORMULA_EQUAL(rDoc, aPos, "SUM(B4:B8)", nullptr);
3849 xDocSh->DoClose();
3852 void ScFiltersTest::testBorderDirectionsXLSXML()
3854 ScDocShellRef xDocSh = loadDoc("border-directions.", FORMAT_XLS_XML);
3855 CPPUNIT_ASSERT_MESSAGE("Failed to load border-directions.xml", xDocSh.is());
3856 ScDocument& rDoc = xDocSh->GetDocument();
3858 struct Check
3860 ScAddress aPos;
3861 bool bTop;
3862 bool bBottom;
3863 bool bLeft;
3864 bool bRight;
3865 bool bTLtoBR;
3866 bool bTRtoBL;
3869 std::vector<Check> aChecks = {
3870 { { 1, 1, 0 }, true, false, false, false, false, false }, // B2 - top
3871 { { 1, 3, 0 }, false, false, true, false, false, false }, // B4 - left
3872 { { 1, 5, 0 }, false, false, false, true, false, false }, // B6 - right
3873 { { 1, 7, 0 }, false, true, false, false, false, false }, // B8 - bottom
3874 { { 1, 9, 0 }, false, false, false, false, true, false }, // B10 - tl to br
3875 { { 1, 11, 0 }, false, false, false, false, false, true }, // B12 - tr to bl
3876 { { 1, 13, 0 }, false, false, false, false, true, true }, // B14 - cross-diagonal
3879 auto funcCheckBorder = []( bool bHasBorder, const editeng::SvxBorderLine* pLine ) -> bool
3881 if (bHasBorder)
3883 if (!pLine)
3885 std::cout << "Border was expected, but not found!" << std::endl;
3886 return false;
3889 if (SvxBorderLineStyle::SOLID != pLine->GetBorderLineStyle())
3891 std::cout << "Border type was expected to be of SOLID, but is not." << std::endl;
3892 return false;
3895 if (COL_BLACK != pLine->GetColor())
3897 std::cout << "Border color was expected to be black, but is not." << std::endl;
3898 return false;
3901 else
3903 if (pLine)
3905 std::cout << "Border was not expected, but is found!" << std::endl;
3906 return false;
3910 return true;
3913 for (const Check& c : aChecks)
3915 const ScPatternAttr* pPat = rDoc.GetPattern(c.aPos);
3916 CPPUNIT_ASSERT(pPat);
3918 const SvxBoxItem& rBox = pPat->GetItem(ATTR_BORDER);
3920 const editeng::SvxBorderLine* pLine = rBox.GetTop();
3921 CPPUNIT_ASSERT(funcCheckBorder(c.bTop, pLine));
3923 pLine = rBox.GetBottom();
3924 CPPUNIT_ASSERT(funcCheckBorder(c.bBottom, pLine));
3926 pLine = rBox.GetLeft();
3927 CPPUNIT_ASSERT(funcCheckBorder(c.bLeft, pLine));
3929 pLine = rBox.GetRight();
3930 CPPUNIT_ASSERT(funcCheckBorder(c.bRight, pLine));
3932 pLine = pPat->GetItem(ATTR_BORDER_TLBR).GetLine();
3933 CPPUNIT_ASSERT(funcCheckBorder(c.bTLtoBR, pLine));
3935 pLine = pPat->GetItem(ATTR_BORDER_BLTR).GetLine();
3936 CPPUNIT_ASSERT(funcCheckBorder(c.bTRtoBL, pLine));
3939 xDocSh->DoClose();
3942 void ScFiltersTest::testBorderColorsXLSXML()
3944 ScDocShellRef xDocSh = loadDoc("border-colors.", FORMAT_XLS_XML);
3945 CPPUNIT_ASSERT_MESSAGE("Failed to load border-colors.xml", xDocSh.is());
3946 ScDocument& rDoc = xDocSh->GetDocument();
3948 // B3 - red
3949 const ScPatternAttr* pPat = rDoc.GetPattern(ScAddress(1,2,0));
3950 CPPUNIT_ASSERT(pPat);
3951 const editeng::SvxBorderLine* pLine = pPat->GetItem(ATTR_BORDER).GetRight();
3952 CPPUNIT_ASSERT(pLine);
3953 CPPUNIT_ASSERT_EQUAL(SvxBorderLineStyle::SOLID, pLine->GetBorderLineStyle());
3954 CPPUNIT_ASSERT_EQUAL(Color(255,0,0), pLine->GetColor());
3956 // B4 - blue
3957 pPat = rDoc.GetPattern(ScAddress(1,3,0));
3958 CPPUNIT_ASSERT(pPat);
3959 pLine = pPat->GetItem(ATTR_BORDER).GetRight();
3960 CPPUNIT_ASSERT(pLine);
3961 CPPUNIT_ASSERT_EQUAL(SvxBorderLineStyle::SOLID, pLine->GetBorderLineStyle());
3962 CPPUNIT_ASSERT_EQUAL(Color(0,112,192), pLine->GetColor());
3964 // B5 - green
3965 pPat = rDoc.GetPattern(ScAddress(1,4,0));
3966 CPPUNIT_ASSERT(pPat);
3967 pLine = pPat->GetItem(ATTR_BORDER).GetRight();
3968 CPPUNIT_ASSERT(pLine);
3969 CPPUNIT_ASSERT_EQUAL(SvxBorderLineStyle::SOLID, pLine->GetBorderLineStyle());
3970 CPPUNIT_ASSERT_EQUAL(Color(0,176,80), pLine->GetColor());
3972 // B7 - yellow (left), purple (right), light blue (cross)
3973 pPat = rDoc.GetPattern(ScAddress(1,6,0));
3974 CPPUNIT_ASSERT(pPat);
3976 pLine = pPat->GetItem(ATTR_BORDER).GetLeft();
3977 CPPUNIT_ASSERT(pLine);
3978 CPPUNIT_ASSERT_EQUAL(SvxBorderLineStyle::SOLID, pLine->GetBorderLineStyle());
3979 CPPUNIT_ASSERT_EQUAL(Color(255,255,0), pLine->GetColor()); // yellow
3981 pLine = pPat->GetItem(ATTR_BORDER).GetRight();
3982 CPPUNIT_ASSERT(pLine);
3983 CPPUNIT_ASSERT_EQUAL(SvxBorderLineStyle::SOLID, pLine->GetBorderLineStyle());
3984 CPPUNIT_ASSERT_EQUAL(Color(112,48,160), pLine->GetColor()); // purple
3986 pLine = pPat->GetItem(ATTR_BORDER_TLBR).GetLine();
3987 CPPUNIT_ASSERT(pLine);
3988 CPPUNIT_ASSERT_EQUAL(SvxBorderLineStyle::SOLID, pLine->GetBorderLineStyle());
3989 CPPUNIT_ASSERT_EQUAL(Color(0,176,240), pLine->GetColor()); // light blue
3991 pLine = pPat->GetItem(ATTR_BORDER_BLTR).GetLine();
3992 CPPUNIT_ASSERT(pLine);
3993 CPPUNIT_ASSERT_EQUAL(SvxBorderLineStyle::SOLID, pLine->GetBorderLineStyle());
3994 CPPUNIT_ASSERT_EQUAL(Color(0,176,240), pLine->GetColor()); // light blue
3996 xDocSh->DoClose();
3999 void ScFiltersTest::testHiddenRowsColumnsXLSXML()
4001 ScDocShellRef xDocSh = loadDoc("hidden-rows-columns.", FORMAT_XLS_XML);
4002 CPPUNIT_ASSERT_MESSAGE("Failed to load hidden-rows-columns.xml", xDocSh.is());
4003 ScDocument& rDoc = xDocSh->GetDocument();
4005 struct Check
4007 SCCOLROW nPos1;
4008 SCCOLROW nPos2;
4009 bool bVisible;
4012 std::vector<Check> aRowChecks = {
4013 { 0, 0, true },
4014 { 1, 2, false },
4015 { 3, 3, true },
4016 { 4, 4, false },
4017 { 5, 7, true },
4018 { 8, 8, false },
4019 { 9, MAXROW, true },
4022 for (const Check& c : aRowChecks)
4024 SCROW nRow1 = -1, nRow2 = -1;
4025 bool bVisible = !rDoc.RowHidden(c.nPos1, 0, &nRow1, &nRow2);
4026 CPPUNIT_ASSERT_EQUAL(bVisible, c.bVisible);
4027 CPPUNIT_ASSERT_EQUAL(c.nPos1, nRow1);
4028 CPPUNIT_ASSERT_EQUAL(c.nPos2, nRow2);
4031 std::vector<Check> aColChecks = {
4032 { 0, 1, true },
4033 { 2, 5, false },
4034 { 6, 9, true },
4035 { 10, 10, false },
4036 { 11, MAXCOL, true },
4039 for (const Check& c : aColChecks)
4041 SCCOL nCol1 = -1, nCol2 = -1;
4042 bool bVisible = !rDoc.ColHidden(c.nPos1, 1, &nCol1, &nCol2);
4043 CPPUNIT_ASSERT_EQUAL(bVisible, c.bVisible);
4044 CPPUNIT_ASSERT_EQUAL(c.nPos1, SCCOLROW(nCol1));
4045 CPPUNIT_ASSERT_EQUAL(c.nPos2, SCCOLROW(nCol2));
4048 xDocSh->DoClose();
4051 void ScFiltersTest::testColumnWidthRowHeightXLSXML()
4053 ScDocShellRef xDocSh = loadDoc("column-width-row-height.", FORMAT_XLS_XML);
4054 CPPUNIT_ASSERT_MESSAGE("Failed to load column-width-row-height.xml", xDocSh.is());
4055 ScDocument& rDoc = xDocSh->GetDocument();
4057 struct RowHeight
4059 SCROW nRow1;
4060 SCROW nRow2;
4061 sal_uInt16 nHeight; // in points (1 point == 20 twips)
4064 std::vector<RowHeight> aRowChecks = {
4065 { 2, 2, 20 },
4066 { 3, 3, 30 },
4067 { 4, 4, 40 },
4068 { 5, 5, 50 },
4069 { 7, 9, 25 },
4070 { 12, 13, 35 },
4073 for (const RowHeight& rh : aRowChecks)
4075 for (SCROW i = rh.nRow1; i <= rh.nRow2; ++i)
4077 sal_uInt16 nHeight = rDoc.GetRowHeight(i, 0);
4078 CPPUNIT_ASSERT_EQUAL(sal_uInt16(rh.nHeight*20), nHeight);
4082 struct ColWidth
4084 SCCOL nCol1;
4085 SCCOL nCol2;
4086 sal_uInt16 nWidth; // in points (1 point == 20 twips
4089 std::vector<ColWidth> aColChecks = {
4090 { 1, 1, 56 },
4091 { 2, 2, 83 },
4092 { 3, 3, 109 },
4093 { 5, 7, 67 },
4094 { 10, 11, 119 },
4097 for (const ColWidth& cw : aColChecks)
4099 for (SCCOL i = cw.nCol1; i <= cw.nCol2; ++i)
4101 sal_uInt16 nWidth = rDoc.GetColWidth(i, 0);
4102 CPPUNIT_ASSERT_EQUAL(sal_uInt16(cw.nWidth*20), nWidth);
4106 xDocSh->DoClose();
4109 void ScFiltersTest::testCharacterSetXLSXML()
4111 ScDocShellRef xDocSh = loadDoc("character-set.", FORMAT_XLS_XML);
4112 CPPUNIT_ASSERT_MESSAGE("Failed to load column-width-row-height.xml", xDocSh.is());
4113 ScDocument& rDoc = xDocSh->GetDocument();
4115 CPPUNIT_ASSERT_EQUAL(SCTAB(1), rDoc.GetTableCount());
4117 OUString aName;
4118 rDoc.GetName(0, aName);
4120 // Check the sheet name. The values are all Cyrillic letters.
4121 std::vector<sal_Unicode> aBuf = { 0x041b, 0x0438, 0x0441, 0x0442, 0x0031 };
4122 OUString aExpected(aBuf.data(), aBuf.size());
4123 CPPUNIT_ASSERT_EQUAL(aExpected, aName);
4125 // Check the value of I4
4126 OUString aVal = rDoc.GetString(ScAddress(8,3,0));
4127 aBuf = { 0x0421, 0x0443, 0x043c, 0x043c, 0x0430 };
4128 aExpected = OUString(aBuf.data(), aBuf.size());
4129 CPPUNIT_ASSERT_EQUAL(aExpected, aVal);
4131 // Check the value of J3
4132 aVal = rDoc.GetString(ScAddress(9,2,0));
4133 aBuf = { 0x041e, 0x0441, 0x0442, 0x0430, 0x0442, 0x043e, 0x043a };
4134 aExpected = OUString(aBuf.data(), aBuf.size());
4135 CPPUNIT_ASSERT_EQUAL(aExpected, aVal);
4137 xDocSh->DoClose();
4140 void ScFiltersTest::testCondFormatXLSB()
4142 ScDocShellRef xDocSh = loadDoc("cond_format.", FORMAT_XLSB);
4144 ScDocument& rDoc = xDocSh->GetDocument();
4145 ScConditionalFormatList* pList = rDoc.GetCondFormList(0);
4146 CPPUNIT_ASSERT(pList);
4148 CPPUNIT_ASSERT_EQUAL(size_t(1), pList->size());
4149 ScConditionalFormat* pFormat = pList->begin()->get();
4150 CPPUNIT_ASSERT(pFormat);
4151 CPPUNIT_ASSERT_EQUAL(size_t(1), pFormat->size());
4153 xDocSh->DoClose();
4156 void ScFiltersTest::testPageScalingXLSX()
4158 ScDocShellRef xDocSh = loadDoc("page_scale.", FORMAT_XLSX);
4159 ScDocument& rDoc = xDocSh->GetDocument();
4161 OUString aStyleName = rDoc.GetPageStyle(0);
4162 ScStyleSheetPool* pStylePool = rDoc.GetStyleSheetPool();
4163 SfxStyleSheetBase* pStyleSheet = pStylePool->Find( aStyleName, SfxStyleFamily::Page );
4164 CPPUNIT_ASSERT(pStyleSheet);
4166 SfxItemSet& rSet = pStyleSheet->GetItemSet();
4167 sal_uInt16 nVal = rSet.Get(ATTR_PAGE_SCALE).GetValue();
4168 CPPUNIT_ASSERT_EQUAL(sal_uInt16(90), nVal);
4170 xDocSh->DoClose();
4173 void ScFiltersTest::testActiveXCheckboxXLSX()
4175 ScDocShellRef xDocSh = loadDoc("activex_checkbox.", FORMAT_XLSX);
4176 uno::Reference< frame::XModel > xModel = xDocSh->GetModel();
4177 uno::Reference< sheet::XSpreadsheetDocument > xDoc(xModel, UNO_QUERY_THROW);
4178 uno::Reference< container::XIndexAccess > xIA(xDoc->getSheets(), UNO_QUERY_THROW);
4179 uno::Reference< drawing::XDrawPageSupplier > xDrawPageSupplier(xIA->getByIndex(0), UNO_QUERY_THROW);
4180 uno::Reference< container::XIndexAccess > xIA_DrawPage(xDrawPageSupplier->getDrawPage(), UNO_QUERY_THROW);
4181 uno::Reference< drawing::XControlShape > xControlShape(xIA_DrawPage->getByIndex(0), UNO_QUERY_THROW);
4183 // Check control type
4184 uno::Reference<beans::XPropertySet> xPropertySet(xControlShape->getControl(), uno::UNO_QUERY);
4185 uno::Reference<lang::XServiceInfo> xServiceInfo(xPropertySet, uno::UNO_QUERY);
4186 CPPUNIT_ASSERT_EQUAL(true, bool(xServiceInfo->supportsService("com.sun.star.form.component.CheckBox")));
4188 // Check custom label
4189 OUString sLabel;
4190 xPropertySet->getPropertyValue("Label") >>= sLabel;
4191 CPPUNIT_ASSERT_EQUAL(OUString("Custom Caption"), sLabel);
4193 // Check background color (highlight system color)
4194 sal_Int32 nColor;
4195 xPropertySet->getPropertyValue("BackgroundColor") >>= nColor;
4196 CPPUNIT_ASSERT_EQUAL(sal_Int32(0x316AC5), nColor);
4198 // Check Text color (active border system color)
4199 xPropertySet->getPropertyValue("TextColor") >>= nColor;
4200 CPPUNIT_ASSERT_EQUAL(sal_Int32(0xD4D0C8), nColor);
4202 // Check state of the checkbox
4203 sal_Int16 nState;
4204 xPropertySet->getPropertyValue("State") >>= nState;
4205 CPPUNIT_ASSERT_EQUAL(sal_Int16(1), nState);
4207 xDocSh->DoClose();
4210 void ScFiltersTest::testtdf120301_xmlSpaceParsingXLSX()
4212 ScDocShellRef xDocSh = loadDoc("tdf120301_xmlSpaceParsing.", FORMAT_XLSX);
4213 uno::Reference< frame::XModel > xModel = xDocSh->GetModel();
4214 uno::Reference< sheet::XSpreadsheetDocument > xDoc(xModel, UNO_QUERY_THROW);
4215 uno::Reference< container::XIndexAccess > xIA(xDoc->getSheets(), UNO_QUERY_THROW);
4216 uno::Reference< drawing::XDrawPageSupplier > xDrawPageSupplier( xIA->getByIndex(0), UNO_QUERY_THROW);
4217 uno::Reference< container::XIndexAccess > xIA_DrawPage(xDrawPageSupplier->getDrawPage(), UNO_QUERY_THROW);
4219 uno::Reference< drawing::XControlShape > xControlShape(xIA_DrawPage->getByIndex(0), UNO_QUERY_THROW);
4220 uno::Reference< beans::XPropertySet > XPropSet( xControlShape->getControl(), uno::UNO_QUERY_THROW );
4221 OUString sCaption;
4222 XPropSet->getPropertyValue("Label") >>= sCaption;
4223 CPPUNIT_ASSERT_EQUAL(OUString("Check Box 1"), sCaption);
4224 xDocSh->DoClose();
4227 namespace {
4229 struct PaintListener : public SfxListener
4231 bool mbCalled = false;
4232 virtual void Notify(SfxBroadcaster& /*rBC*/, const SfxHint& rHint) override
4234 const ScPaintHint* pPaintHint = dynamic_cast<const ScPaintHint*>(&rHint);
4235 if (pPaintHint)
4237 if (pPaintHint->GetStartCol() <= 0 && pPaintHint->GetEndCol() >= 0
4238 && pPaintHint->GetStartRow() <= 9 && pPaintHint->GetEndRow() >= 9)
4240 mbCalled = true;
4248 void ScFiltersTest::testCondFormatFormulaListenerXLSX()
4250 ScDocShellRef xDocSh = loadDoc("cond_format_formula_listener.", FORMAT_XLSX);
4251 PaintListener aListener;
4252 aListener.StartListening(*xDocSh);
4253 ScDocument& rDoc = xDocSh->GetDocument();
4254 ScConditionalFormatList* pList = rDoc.GetCondFormList(0);
4255 CPPUNIT_ASSERT(pList);
4257 CPPUNIT_ASSERT_EQUAL(size_t(1), pList->size());
4258 ScConditionalFormat* pFormat = pList->begin()->get();
4259 CPPUNIT_ASSERT(pFormat);
4260 rDoc.SetDocVisible(true);
4261 rDoc.SetValue(0, 0, 0, 2.0);
4263 CPPUNIT_ASSERT(aListener.mbCalled);
4265 xDocSh->DoClose();
4268 void ScFiltersTest::testTdf62268()
4270 ScDocShellRef xDocSh = loadDoc("tdf62268.", FORMAT_ODS);
4271 ScDocument& rDoc = xDocSh->GetDocument();
4272 int nHeight;
4274 SCTAB nTab = 0;
4275 nHeight = rDoc.GetRowHeight(0, nTab, false);
4276 CPPUNIT_ASSERT_LESSEQUAL( 3, abs( 256 - nHeight ) );
4277 nHeight = rDoc.GetRowHeight(1, nTab, false);
4278 CPPUNIT_ASSERT_LESSEQUAL( 19, abs( 1905 - nHeight ) );
4280 xDocSh->DoClose();
4283 void ScFiltersTest::testVBAMacroFunctionODS()
4285 ScDocShellRef xDocSh = loadDoc("vba_macro_functions.", FORMAT_ODS);
4286 ScDocument& rDoc = xDocSh->GetDocument();
4288 OUString aFunction;
4289 rDoc.GetFormula(2, 0, 0, aFunction);
4290 std::cout << aFunction << std::endl;
4291 CPPUNIT_ASSERT_DOUBLES_EQUAL(10.0, rDoc.GetValue(2, 0, 0), 1e-6);
4293 xDocSh->DoClose();
4296 void ScFiltersTest::testAutoheight2Rows()
4298 ScDocShellRef xDocSh = loadDoc("autoheight2rows.", FORMAT_ODS);
4299 ScDocument& rDoc = xDocSh->GetDocument();
4301 SCTAB nTab = 0;
4302 int nHeight1 = rDoc.GetRowHeight(0, nTab, false);
4303 int nHeight3 = rDoc.GetRowHeight(2, nTab, false);
4305 // We will do relative comparison, because calculated autoheight
4306 // can be different on different platforms
4307 CPPUNIT_ASSERT_MESSAGE("Row #3 should be thinner than #1", nHeight3 < nHeight1);
4309 xDocSh->DoClose();
4312 void ScFiltersTest::testXLSDefColWidth()
4314 // XLS has only 256 columns; but on import, we need to set default width to all above that limit
4315 ScDocShellRef xDocSh = loadDoc("chartx.", FORMAT_XLS); // just some XLS with narrow columns
4316 ScDocument& rDoc = xDocSh->GetDocument();
4318 int nWidth = rDoc.GetColWidth(MAXCOL, 0, false);
4319 // This was 1280
4320 CPPUNIT_ASSERT_EQUAL(1005, nWidth);
4322 xDocSh->DoClose();
4325 void ScFiltersTest::testPreviewMissingObjLink()
4327 ScDocShellRef xDocSh = loadDoc("keep-preview-missing-obj-link.", FORMAT_ODS);
4328 CPPUNIT_ASSERT_MESSAGE("Failed to load keep-preview-missing-obj-link.ods.", xDocSh.is());
4330 ScDocument& rDoc = xDocSh->GetDocument();
4332 // Retrieve the ole object
4333 const SdrOle2Obj* pOleObj = getSingleOleObject(rDoc, 0);
4334 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve an ole object from the 2nd sheet.", pOleObj);
4336 const Graphic* pGraphic = pOleObj->GetGraphic();
4337 CPPUNIT_ASSERT_MESSAGE("the ole object links to a missing file, but we should retain its preview", pGraphic);
4339 xDocSh->DoClose();
4342 ScFiltersTest::ScFiltersTest()
4343 : ScBootstrapFixture( "sc/qa/unit/data" )
4347 void ScFiltersTest::setUp()
4349 test::BootstrapFixture::setUp();
4351 // This is a bit of a fudge, we do this to ensure that ScGlobals::ensure,
4352 // which is a private symbol to us, gets called
4353 m_xCalcComponent =
4354 getMultiServiceFactory()->createInstance("com.sun.star.comp.Calc.SpreadsheetDocument");
4355 CPPUNIT_ASSERT_MESSAGE("no calc component!", m_xCalcComponent.is());
4358 void ScFiltersTest::tearDown()
4360 uno::Reference< lang::XComponent >( m_xCalcComponent, UNO_QUERY_THROW )->dispose();
4361 test::BootstrapFixture::tearDown();
4364 CPPUNIT_TEST_SUITE_REGISTRATION(ScFiltersTest);
4366 CPPUNIT_PLUGIN_IMPLEMENT();
4368 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */