rtl::Static->thread-safe static in unotools
[LibreOffice.git] / sc / qa / unit / subsequent_filters_test.cxx
blob4e261b536edec868a40733ffa803f50b58760808
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 <sal/config.h>
12 #include <memory>
13 #include <string_view>
15 #include <unotest/filters-test.hxx>
16 #include <test/bootstrapfixture.hxx>
17 #include <osl/file.hxx>
18 #include <config_features.h>
20 #include <vcl/svapp.hxx>
21 #include <sfx2/docfilt.hxx>
22 #include <sfx2/docfile.hxx>
23 #include <svl/numformat.hxx>
24 #include <svl/stritem.hxx>
25 #include <svl/zformat.hxx>
26 #include <svx/svdograf.hxx>
27 #include <svx/svxids.hrc>
29 #include <drwlayer.hxx>
30 #include <svx/svdpage.hxx>
31 #include <svx/svdoole2.hxx>
32 #include <editeng/eeitem.hxx>
33 #include <editeng/wghtitem.hxx>
34 #include <editeng/postitem.hxx>
35 #include <editeng/crossedoutitem.hxx>
36 #include <editeng/udlnitem.hxx>
37 #include <editeng/editobj.hxx>
38 #include <editeng/borderline.hxx>
39 #include <editeng/boxitem.hxx>
40 #include <editeng/fhgtitem.hxx>
41 #include <editeng/brushitem.hxx>
42 #include <editeng/fontitem.hxx>
43 #include <editeng/flditem.hxx>
44 #include <editeng/justifyitem.hxx>
45 #include <editeng/lineitem.hxx>
46 #include <editeng/colritem.hxx>
47 #include <dbdata.hxx>
48 #include <validat.hxx>
49 #include <formulacell.hxx>
50 #include <formulaopt.hxx>
51 #include <userdat.hxx>
52 #include <stlsheet.hxx>
53 #include <docfunc.hxx>
54 #include <markdata.hxx>
55 #include <colorscale.hxx>
56 #include <olinetab.hxx>
57 #include <patattr.hxx>
58 #include <scitems.hxx>
59 #include <docsh.hxx>
60 #include <editutil.hxx>
61 #include <cellvalue.hxx>
62 #include <attrib.hxx>
63 #include <fillinfo.hxx>
64 #include <scopetools.hxx>
65 #include <columnspanset.hxx>
66 #include <tokenstringcontext.hxx>
67 #include <formula/errorcodes.hxx>
68 #include <externalrefmgr.hxx>
69 #include <stlpool.hxx>
70 #include <hints.hxx>
71 #include <detfunc.hxx>
72 #include <cellmergeoption.hxx>
73 #include <undoblk.hxx>
74 #include <sortparam.hxx>
76 #include <orcusfilters.hxx>
77 #include <filter.hxx>
79 #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
80 #include <com/sun/star/drawing/XControlShape.hpp>
81 #include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
82 #include <com/sun/star/container/XIndexAccess.hpp>
83 #include <com/sun/star/text/textfield/Type.hpp>
85 #include <comphelper/scopeguard.hxx>
86 #include <tools/UnitConversion.hxx>
87 #include <unotools/syslocaleoptions.hxx>
88 #include "helper/qahelper.hxx"
89 #include "helper/shared_test_impl.hxx"
91 using namespace ::com::sun::star;
92 using namespace ::com::sun::star::uno;
94 /* Implementation of Filters test */
96 class ScFiltersTest
97 : public test::FiltersTest
98 , public ScBootstrapFixture
100 public:
101 ScFiltersTest();
103 virtual bool load( const OUString &rFilter, const OUString &rURL,
104 const OUString &rUserData, SfxFilterFlags nFilterFlags,
105 SotClipboardFormatId nClipboardID, unsigned int nFilterVersion) override;
107 virtual void setUp() override;
108 virtual void tearDown() override;
110 //ods, xls, xlsx filter tests
111 void testCondFormatOperatorsSameRangeXLSX();
112 void testTdf119292();
113 void testTdf48731();
114 void testCondFormatFormulaIsXLSX();
115 void testCondFormatBeginsAndEndsWithXLSX();
116 void testExtCondFormatXLSX();
117 void testUpdateCircleInMergedCellODS();
118 void testDeleteCircleInMergedCellODS();
119 void testBooleanFormatXLSX();
120 void testTdf143809();
121 void testTdf76310();
122 void testBasicCellContentODS();
123 void testRangeNameXLS();
124 void testRangeNameLocalXLS();
125 void testRangeNameXLSX();
126 void testHyperlinksXLSX();
127 void testHardRecalcODS();
128 void testFunctionsODS();
129 void testFunctionsExcel2010();
130 void testCeilingFloorXLSX();
131 void testCachedFormulaResultsODS();
132 void testCachedMatrixFormulaResultsODS();
133 void testFormulaDepAcrossSheetsODS();
134 void testFormulaDepDeleteContentsODS();
135 void testDatabaseRangesODS();
136 void testDatabaseRangesXLS();
137 void testDatabaseRangesXLSX();
138 void testFormatsODS();
139 // void testFormatsXLS();
140 // void testFormatsXLSX();
141 void testMatrixODS();
142 void testMatrixXLS();
143 void testDoubleThinBorder();
144 void testBorderODS();
145 void testBordersOoo33();
146 void testBugFixesODS();
147 void testBugFixesXLS();
148 void testBugFixesXLSX();
149 void testBrokenQuotesCSV();
150 void testMergedCellsODS();
151 void testRepeatedColumnsODS();
152 void testDataValidityODS();
153 void testDataValidityXLSX();
154 void testDataTableMortgageXLS();
155 void testDataTableOneVarXLSX();
156 void testDataTableMultiTableXLSX();
158 void testDataBarODS();
159 void testDataBarXLSX();
160 void testColorScaleODS();
161 void testColorScaleXLSX();
162 void testNewCondFormatODS();
163 void testNewCondFormatXLSX();
164 void testCondFormatThemeColorXLSX();
165 void testCondFormatImportCellIs();
166 void testCondFormatThemeColor2XLSX(); // negative bar color and axis color
167 void testCondFormatThemeColor3XLSX(); // theme index 2 and 3 are switched
168 void testComplexIconSetsXLSX();
169 void testTdf101104();
170 void testTdf64401();
171 void testCondFormatParentXLSX();
172 void testColorScaleNumWithRefXLSX();
174 void testOrcusODSStyleInterface();
176 void testLiteralInFormulaXLS();
178 //change this test file only in excel and not in calc
179 void testCellValueXLSX();
182 * Test importing of xlsx document that previously had its row index off
183 * by one. (fdo#76032)
185 void testRowIndex1BasedXLSX();
187 //misc tests unrelated to the import filters
188 void testPasswordNew();
189 void testPasswordOld();
190 void testPasswordWrongSHA();
192 //test shape import
193 void testControlImport();
194 void testActiveXOptionButtonGroup();
195 void testChartImportODS();
196 #if HAVE_MORE_FONTS
197 void testChartImportXLS();
198 #endif
200 void testNumberFormatHTML();
201 void testNumberFormatCSV();
203 void testCellAnchoredShapesODS();
204 void testCellAnchoredHiddenShapesXLSX();
206 void testFormulaDependency();
208 void testRowHeightODS();
209 void testRichTextContentODS();
211 void testTdf122643();
212 void testTdf132278();
213 void testTdf130959();
214 void testTdf129410();
215 void testTdf138507();
216 void testTdf131380();
217 void testTdf139782();
218 void testTdf129681();
219 void testTdf111974XLSM();
220 void testEscapedUnicodeXLSX();
221 void testTdf144758_DBDataDefaultOrientation();
223 CPPUNIT_TEST_SUITE(ScFiltersTest);
224 CPPUNIT_TEST(testCondFormatOperatorsSameRangeXLSX);
225 CPPUNIT_TEST(testTdf119292);
226 CPPUNIT_TEST(testTdf48731);
227 CPPUNIT_TEST(testCondFormatFormulaIsXLSX);
228 CPPUNIT_TEST(testCondFormatBeginsAndEndsWithXLSX);
229 CPPUNIT_TEST(testExtCondFormatXLSX);
230 CPPUNIT_TEST(testUpdateCircleInMergedCellODS);
231 CPPUNIT_TEST(testDeleteCircleInMergedCellODS);
232 CPPUNIT_TEST(testBooleanFormatXLSX);
233 CPPUNIT_TEST(testTdf143809);
234 CPPUNIT_TEST(testTdf76310);
235 CPPUNIT_TEST(testBasicCellContentODS);
236 CPPUNIT_TEST(testRangeNameXLS);
237 CPPUNIT_TEST(testRangeNameLocalXLS);
238 CPPUNIT_TEST(testRangeNameXLSX);
239 CPPUNIT_TEST(testHyperlinksXLSX);
240 CPPUNIT_TEST(testHardRecalcODS);
241 CPPUNIT_TEST(testFunctionsODS);
242 CPPUNIT_TEST(testFunctionsExcel2010);
243 CPPUNIT_TEST(testCeilingFloorXLSX);
244 CPPUNIT_TEST(testCachedFormulaResultsODS);
245 CPPUNIT_TEST(testFormulaDepAcrossSheetsODS);
246 CPPUNIT_TEST(testFormulaDepDeleteContentsODS);
247 CPPUNIT_TEST(testCachedMatrixFormulaResultsODS);
248 CPPUNIT_TEST(testDatabaseRangesODS);
249 CPPUNIT_TEST(testDatabaseRangesXLS);
250 CPPUNIT_TEST(testDatabaseRangesXLSX);
251 CPPUNIT_TEST(testFormatsODS);
252 // CPPUNIT_TEST(testFormatsXLS); TODO: Fix this
253 // CPPUNIT_TEST(testFormatsXLSX); TODO: Fix this
254 CPPUNIT_TEST(testMatrixODS);
255 CPPUNIT_TEST(testMatrixXLS);
256 CPPUNIT_TEST(testDoubleThinBorder);
257 CPPUNIT_TEST(testBorderODS);
258 CPPUNIT_TEST(testBordersOoo33);
259 CPPUNIT_TEST(testBugFixesODS);
260 CPPUNIT_TEST(testBugFixesXLS);
261 CPPUNIT_TEST(testBugFixesXLSX);
262 CPPUNIT_TEST(testMergedCellsODS);
263 CPPUNIT_TEST(testRepeatedColumnsODS);
264 CPPUNIT_TEST(testDataValidityODS);
265 CPPUNIT_TEST(testDataValidityXLSX);
266 CPPUNIT_TEST(testDataTableMortgageXLS);
267 CPPUNIT_TEST(testDataTableOneVarXLSX);
268 CPPUNIT_TEST(testDataTableMultiTableXLSX);
269 CPPUNIT_TEST(testBrokenQuotesCSV);
270 CPPUNIT_TEST(testCellValueXLSX);
271 CPPUNIT_TEST(testRowIndex1BasedXLSX);
272 CPPUNIT_TEST(testControlImport);
273 CPPUNIT_TEST(testActiveXOptionButtonGroup);
274 CPPUNIT_TEST(testChartImportODS);
275 #if HAVE_MORE_FONTS
276 CPPUNIT_TEST(testChartImportXLS);
277 #endif
279 CPPUNIT_TEST(testDataBarODS);
280 CPPUNIT_TEST(testDataBarXLSX);
281 CPPUNIT_TEST(testColorScaleODS);
282 CPPUNIT_TEST(testColorScaleXLSX);
283 CPPUNIT_TEST(testNewCondFormatODS);
284 CPPUNIT_TEST(testNewCondFormatXLSX);
285 CPPUNIT_TEST(testCondFormatThemeColorXLSX);
286 CPPUNIT_TEST(testCondFormatImportCellIs);
287 CPPUNIT_TEST(testCondFormatThemeColor2XLSX);
288 CPPUNIT_TEST(testCondFormatThemeColor3XLSX);
289 CPPUNIT_TEST(testComplexIconSetsXLSX);
290 CPPUNIT_TEST(testTdf101104);
291 CPPUNIT_TEST(testTdf64401);
292 CPPUNIT_TEST(testCondFormatParentXLSX);
293 CPPUNIT_TEST(testColorScaleNumWithRefXLSX);
295 CPPUNIT_TEST(testOrcusODSStyleInterface);
297 CPPUNIT_TEST(testLiteralInFormulaXLS);
299 CPPUNIT_TEST(testNumberFormatHTML);
300 CPPUNIT_TEST(testNumberFormatCSV);
302 CPPUNIT_TEST(testCellAnchoredShapesODS);
303 CPPUNIT_TEST(testCellAnchoredHiddenShapesXLSX);
305 CPPUNIT_TEST(testRowHeightODS);
306 CPPUNIT_TEST(testFormulaDependency);
307 CPPUNIT_TEST(testRichTextContentODS);
309 //disable testPassword on MacOSX due to problems with libsqlite3
310 //also crashes on DragonFly due to problems with nss/nspr headers
311 CPPUNIT_TEST(testPasswordWrongSHA);
312 CPPUNIT_TEST(testPasswordOld);
313 CPPUNIT_TEST(testPasswordNew);
315 CPPUNIT_TEST(testTdf122643);
316 CPPUNIT_TEST(testTdf132278);
317 CPPUNIT_TEST(testTdf130959);
318 CPPUNIT_TEST(testTdf129410);
319 CPPUNIT_TEST(testTdf138507);
320 CPPUNIT_TEST(testTdf131380);
321 CPPUNIT_TEST(testTdf139782);
322 CPPUNIT_TEST(testTdf129681);
323 CPPUNIT_TEST(testTdf111974XLSM);
324 CPPUNIT_TEST(testEscapedUnicodeXLSX);
325 CPPUNIT_TEST(testTdf144758_DBDataDefaultOrientation);
327 CPPUNIT_TEST_SUITE_END();
329 private:
330 void testImportCrash(std::u16string_view rFileName, sal_Int32 nFormat);
331 void testPassword_Impl(std::u16string_view rFileNameBase);
333 uno::Reference<uno::XInterface> m_xCalcComponent;
336 bool ScFiltersTest::load(const OUString &rFilter, const OUString &rURL,
337 const OUString &rUserData, SfxFilterFlags nFilterFlags,
338 SotClipboardFormatId nClipboardID, unsigned int nFilterVersion)
340 ScDocShellRef xDocShRef = ScBootstrapFixture::load( rURL, rFilter, rUserData,
341 OUString(), nFilterFlags, nClipboardID, nFilterVersion);
342 bool bLoaded = xDocShRef.is();
343 //reference counting of ScDocShellRef is very confused.
344 if (bLoaded)
345 xDocShRef->DoClose();
346 return bLoaded;
349 namespace {
351 void testRangeNameImpl(const ScDocument& rDoc)
353 //check one range data per sheet and one global more detailed
354 //add some more checks here
355 ScRangeData* pRangeData = rDoc.GetRangeName()->findByUpperName(OUString("GLOBAL1"));
356 CPPUNIT_ASSERT_MESSAGE("range name Global1 not found", pRangeData);
357 double aValue = rDoc.GetValue(1,0,0);
358 CPPUNIT_ASSERT_EQUAL_MESSAGE("range name Global1 should reference Sheet1.A1", 1.0, aValue);
359 pRangeData = rDoc.GetRangeName(0)->findByUpperName(OUString("LOCAL1"));
360 CPPUNIT_ASSERT_MESSAGE("range name Sheet1.Local1 not found", pRangeData);
361 aValue = rDoc.GetValue(1,2,0);
362 CPPUNIT_ASSERT_EQUAL_MESSAGE("range name Sheet1.Local1 should reference Sheet1.A3", 3.0, aValue);
363 pRangeData = rDoc.GetRangeName(1)->findByUpperName(OUString("LOCAL2"));
364 CPPUNIT_ASSERT_MESSAGE("range name Sheet2.Local2 not found", pRangeData);
365 aValue = rDoc.GetValue(1,1,1);
366 CPPUNIT_ASSERT_EQUAL_MESSAGE("range name Sheet2.Local2 should reference Sheet2.A2", 7.0, aValue);
367 //check for correct results for the remaining formulas
368 aValue = rDoc.GetValue(1,1,0);
369 CPPUNIT_ASSERT_EQUAL_MESSAGE("=global2 should be 2", 2.0, aValue);
370 aValue = rDoc.GetValue(1,3,0);
371 CPPUNIT_ASSERT_EQUAL_MESSAGE("=local2 should be 4", 4.0, aValue);
372 aValue = rDoc.GetValue(2,0,0);
373 CPPUNIT_ASSERT_EQUAL_MESSAGE("=SUM(global3) should be 10", 10.0, aValue);
374 aValue = rDoc.GetValue(1,0,1);
375 CPPUNIT_ASSERT_EQUAL_MESSAGE("range name Sheet2.local1 should reference Sheet1.A5", 5.0, aValue);
376 // Test if Global5 ( which depends on Global6 ) is evaluated
377 aValue = rDoc.GetValue(0,5,1);
378 CPPUNIT_ASSERT_EQUAL_MESSAGE("formula Global5 should reference Global6 ( which is evaluated as local1 )", 5.0, aValue);
383 void ScFiltersTest::testCondFormatOperatorsSameRangeXLSX()
385 ScDocShellRef xDocSh = loadDoc(u"tdf139928.", FORMAT_XLSX);
386 CPPUNIT_ASSERT_MESSAGE("Failed to load tdf139928.xlsx", xDocSh.is());
388 ScDocument& rDoc = xDocSh->GetDocument();
390 ScConditionalFormat* pFormat = rDoc.GetCondFormat(0, 0, 0);
391 CPPUNIT_ASSERT(pFormat);
393 const ScFormatEntry* pEntry = pFormat->GetEntry(0);
394 CPPUNIT_ASSERT(pEntry);
395 CPPUNIT_ASSERT_EQUAL(ScFormatEntry::Type::ExtCondition, pEntry->GetType());
397 const ScCondFormatEntry* pCondition = static_cast<const ScCondFormatEntry*>(pEntry);
398 CPPUNIT_ASSERT_EQUAL(ScConditionMode::ContainsText, pCondition->GetOperation());
400 pEntry = pFormat->GetEntry(1);
401 CPPUNIT_ASSERT(pEntry);
402 CPPUNIT_ASSERT_EQUAL(ScFormatEntry::Type::ExtCondition, pEntry->GetType());
404 pCondition = static_cast<const ScCondFormatEntry*>(pEntry);
405 CPPUNIT_ASSERT_EQUAL(ScConditionMode::BeginsWith, pCondition->GetOperation());
407 pEntry = pFormat->GetEntry(2);
408 CPPUNIT_ASSERT(pEntry);
409 CPPUNIT_ASSERT_EQUAL(ScFormatEntry::Type::ExtCondition, pEntry->GetType());
411 pCondition = static_cast<const ScCondFormatEntry*>(pEntry);
412 CPPUNIT_ASSERT_EQUAL(ScConditionMode::EndsWith, pCondition->GetOperation());
414 xDocSh->DoClose();
417 void ScFiltersTest::testTdf119292()
419 ScDocShellRef xDocSh = loadDoc(u"tdf119292.", FORMAT_XLSX);
420 CPPUNIT_ASSERT_MESSAGE("Failed to load tdf119292.xlsx", xDocSh.is());
422 ScDocument& rDoc = xDocSh->GetDocument();
423 auto* pDev = rDoc.GetRefDevice();
424 Size aMarkSize(4, 6);
425 Color aArrowFillCol(COL_LIGHTRED);
427 // check the points of the polygon if the text is rotated 90 degrees
428 tools::Rectangle aMarkRect1(0, 0, 45, 3);
429 tools::Polygon aPoly90degrees = SvxFont::DrawArrow(*pDev, aMarkRect1, aMarkSize, aArrowFillCol, true, true);
430 Point aPoly90Pos1 = aPoly90degrees.GetPoint(0);
431 Point aPoly90Pos2 = aPoly90degrees.GetPoint(1);
432 Point aPoly90Pos3 = aPoly90degrees.GetPoint(2);
433 CPPUNIT_ASSERT_EQUAL(Point(19,3),aPoly90Pos1);
434 CPPUNIT_ASSERT_EQUAL(Point(22,0),aPoly90Pos2);
435 CPPUNIT_ASSERT_EQUAL(Point(25,3),aPoly90Pos3);
437 // check the points of the polygon if the text is rotated 270 degrees
438 tools::Rectangle aMarkRect2(89, 62, 134, 57);
439 tools::Polygon aPoly270degrees = SvxFont::DrawArrow(*pDev, aMarkRect2, aMarkSize, aArrowFillCol, false, true);
440 Point aPoly270Pos1 = aPoly270degrees.GetPoint(0);
441 Point aPoly270Pos2 = aPoly270degrees.GetPoint(1);
442 Point aPoly270Pos3 = aPoly270degrees.GetPoint(2);
443 CPPUNIT_ASSERT_EQUAL(Point(108,54),aPoly270Pos1);
444 CPPUNIT_ASSERT_EQUAL(Point(111,57),aPoly270Pos2);
445 CPPUNIT_ASSERT_EQUAL(Point(114,54),aPoly270Pos3);
447 xDocSh->DoClose();
450 void ScFiltersTest::testTdf48731()
452 ScDocShellRef xDocSh = loadDoc(u"tdf48731.", FORMAT_CSV);
453 CPPUNIT_ASSERT_MESSAGE("Failed to load document", xDocSh.is());
455 ScDocument& rDoc = xDocSh->GetDocument();
457 CPPUNIT_ASSERT_EQUAL(OUString("'"), rDoc.GetString(1, 1, 0));
458 CPPUNIT_ASSERT_EQUAL(OUString("''"), rDoc.GetString(1, 2, 0));
459 CPPUNIT_ASSERT_EQUAL(OUString("'''"), rDoc.GetString(1, 3, 0));
461 // Without the fix in place, this test would have failed with
462 // - Expected: '3
463 // - Actual : 3
464 CPPUNIT_ASSERT_EQUAL(OUString("'3"), rDoc.GetString(1, 4, 0));
465 CPPUNIT_ASSERT_EQUAL(OUString("'word"), rDoc.GetString(1, 5, 0));
466 CPPUNIT_ASSERT_EQUAL(OUString("'mword"), rDoc.GetString(1, 6, 0));
468 CPPUNIT_ASSERT_EQUAL(OUString("'"), rDoc.GetString(1, 9, 0));
469 CPPUNIT_ASSERT_EQUAL(OUString("''"), rDoc.GetString(1, 10, 0));
470 CPPUNIT_ASSERT_EQUAL(OUString("'''"), rDoc.GetString(1, 11, 0));
471 CPPUNIT_ASSERT_EQUAL(OUString("'3"), rDoc.GetString(1, 12, 0));
472 CPPUNIT_ASSERT_EQUAL(OUString("'word"), rDoc.GetString(1, 13, 0));
473 CPPUNIT_ASSERT_EQUAL(OUString("'mword"), rDoc.GetString(1, 14, 0));
475 xDocSh->DoClose();
478 void ScFiltersTest::testCondFormatFormulaIsXLSX()
480 ScDocShellRef xDocSh = loadDoc(u"tdf113013.", FORMAT_XLSX);
481 CPPUNIT_ASSERT_MESSAGE("Failed to load tdf113013.xlsx", xDocSh.is());
483 ScDocument& rDoc = xDocSh->GetDocument();
485 // "Formula is" condition
486 ScConditionalFormat* pFormatB1 = rDoc.GetCondFormat(1, 0, 0);
487 CPPUNIT_ASSERT(pFormatB1);
488 ScConditionalFormat* pFormatA2 = rDoc.GetCondFormat(0, 1, 0);
489 CPPUNIT_ASSERT(pFormatA2);
491 ScRefCellValue aCellB1(rDoc, ScAddress(1, 0, 0));
492 OUString aCellStyleB1 = pFormatB1->GetCellStyle(aCellB1, ScAddress(1, 0, 0));
493 CPPUNIT_ASSERT(!aCellStyleB1.isEmpty());
495 ScRefCellValue aCellA2(rDoc, ScAddress(0, 1, 0));
496 OUString aCellStyleA2 = pFormatA2->GetCellStyle(aCellA2, ScAddress(0, 1, 0));
497 CPPUNIT_ASSERT(!aCellStyleA2.isEmpty());
499 xDocSh->DoClose();
502 void ScFiltersTest::testCondFormatBeginsAndEndsWithXLSX()
504 ScDocShellRef xDocSh = loadDoc(u"tdf120749.", FORMAT_XLSX);
505 CPPUNIT_ASSERT_MESSAGE("Failed to load tdf120749.xlsx", xDocSh.is());
507 ScDocument& rDoc = xDocSh->GetDocument();
509 // begins with and ends with conditions
510 ScConditionalFormat* pFormatA1 = rDoc.GetCondFormat(0, 0, 0);
511 CPPUNIT_ASSERT(pFormatA1);
512 ScConditionalFormat* pFormatA2 = rDoc.GetCondFormat(0, 1, 0);
513 CPPUNIT_ASSERT(pFormatA2);
514 ScConditionalFormat* pFormatA3 = rDoc.GetCondFormat(0, 2, 0);
515 CPPUNIT_ASSERT(pFormatA3);
516 ScConditionalFormat* pFormatA4 = rDoc.GetCondFormat(0, 3, 0);
517 CPPUNIT_ASSERT(pFormatA4);
519 ScRefCellValue aCellA1(rDoc, ScAddress(0, 0, 0));
520 OUString aCellStyleA1 = pFormatA1->GetCellStyle(aCellA1, ScAddress(0, 0, 0));
521 CPPUNIT_ASSERT(!aCellStyleA1.isEmpty());
523 ScRefCellValue aCellA2(rDoc, ScAddress(0, 1, 0));
524 OUString aCellStyleA2 = pFormatA2->GetCellStyle(aCellA2, ScAddress(0, 1, 0));
525 CPPUNIT_ASSERT(!aCellStyleA2.isEmpty());
527 ScRefCellValue aCellA3(rDoc, ScAddress(0, 2, 0));
528 OUString aCellStyleA3 = pFormatA3->GetCellStyle(aCellA3, ScAddress(0, 2, 0));
529 CPPUNIT_ASSERT(!aCellStyleA3.isEmpty());
531 ScRefCellValue aCellA4(rDoc, ScAddress(0, 3, 0));
532 OUString aCellStyleA4 = pFormatA4->GetCellStyle(aCellA4, ScAddress(0, 3, 0));
533 CPPUNIT_ASSERT(!aCellStyleA4.isEmpty());
535 xDocSh->DoClose();
538 void ScFiltersTest::testExtCondFormatXLSX()
540 ScDocShellRef xDocSh = loadDoc(u"tdf122102.", FORMAT_XLSX);
541 CPPUNIT_ASSERT_MESSAGE("Failed to load tdf122102.xlsx", xDocSh.is());
543 ScDocument& rDoc = xDocSh->GetDocument();
545 // contains text and not contains text conditions
546 ScConditionalFormat* pFormatA1 = rDoc.GetCondFormat(0, 0, 0);
547 CPPUNIT_ASSERT(pFormatA1);
548 ScConditionalFormat* pFormatA2 = rDoc.GetCondFormat(0, 1, 0);
549 CPPUNIT_ASSERT(pFormatA2);
550 ScConditionalFormat* pFormatA3 = rDoc.GetCondFormat(0, 2, 0);
551 CPPUNIT_ASSERT(pFormatA3);
552 ScConditionalFormat* pFormatA4 = rDoc.GetCondFormat(0, 3, 0);
553 CPPUNIT_ASSERT(pFormatA4);
555 ScRefCellValue aCellA1(rDoc, ScAddress(0, 0, 0));
556 OUString aCellStyleA1 = pFormatA1->GetCellStyle(aCellA1, ScAddress(0, 0, 0));
557 CPPUNIT_ASSERT(!aCellStyleA1.isEmpty());
559 ScRefCellValue aCellA2(rDoc, ScAddress(0, 1, 0));
560 OUString aCellStyleA2 = pFormatA2->GetCellStyle(aCellA2, ScAddress(0, 1, 0));
561 CPPUNIT_ASSERT(!aCellStyleA2.isEmpty());
563 ScRefCellValue aCellA3(rDoc, ScAddress(0, 2, 0));
564 OUString aCellStyleA3 = pFormatA3->GetCellStyle(aCellA3, ScAddress(0, 2, 0));
565 CPPUNIT_ASSERT(!aCellStyleA3.isEmpty());
567 ScRefCellValue aCellA4(rDoc, ScAddress(0, 3, 0));
568 OUString aCellStyleA4 = pFormatA4->GetCellStyle(aCellA4, ScAddress(0, 3, 0));
569 CPPUNIT_ASSERT(!aCellStyleA4.isEmpty());
571 xDocSh->DoClose();
574 void ScFiltersTest::testUpdateCircleInMergedCellODS()
576 ScDocShellRef xDocSh = loadDoc(u"updateCircleInMergedCell.", FORMAT_ODS);
577 CPPUNIT_ASSERT_MESSAGE("Failed to load updateCircleInMergedCell.ods", xDocSh.is());
579 ScDocument& rDoc = xDocSh->GetDocument();
580 rDoc.EnableChangeReadOnly(true);
582 ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer();
583 SdrPage* pPage = pDrawLayer->GetPage(0);
584 CPPUNIT_ASSERT_MESSAGE("draw page for sheet 1 should exist.", pPage);
586 // There should be four circle objects!
587 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(4), pPage->GetObjCount());
589 ScCellMergeOption aCellMergeOption(0,0,1,1); // A1:B2
590 aCellMergeOption.maTabs.insert(0);
591 xDocSh->GetDocFunc().MergeCells(aCellMergeOption, false, true, true, false);
593 // There should be a circle object!
594 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pPage->GetObjCount());
596 xDocSh->GetDocFunc().UnmergeCells(aCellMergeOption, true, nullptr);
598 // There should be four circle objects!
599 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(4), pPage->GetObjCount());
601 xDocSh->DoClose();
604 void ScFiltersTest::testDeleteCircleInMergedCellODS()
606 ScDocShellRef xDocSh = loadDoc(u"deleteCircleInMergedCell.", FORMAT_ODS);
607 CPPUNIT_ASSERT_MESSAGE("Failed to load deleteCircleInMergedCell.ods", xDocSh.is());
609 ScDocument& rDoc = xDocSh->GetDocument();
611 ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer();
612 SdrPage* pPage = pDrawLayer->GetPage(0);
613 CPPUNIT_ASSERT_MESSAGE("draw page for sheet 1 should exist.", pPage);
615 // There should be a circle object!
616 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pPage->GetObjCount());
618 ScRefCellValue aMergedCell;
619 ScAddress aPosMergedCell(0, 0, 0);
620 aMergedCell.assign(rDoc, aPosMergedCell);
622 // The value of merged cell change to 6.
623 aMergedCell.mfValue = 6;
625 // Check that the data is valid.(True if the value = 6)
626 const ScValidationData* pData = rDoc.GetValidationEntry(1);
627 bool bValidA1 = pData->IsDataValid(aMergedCell, aPosMergedCell);
628 // if valid, delete circle.
629 if (bValidA1)
630 ScDetectiveFunc(rDoc, 0).DeleteCirclesAt(aPosMergedCell.Col(), aPosMergedCell.Row());
632 // There should not be a circle object!
633 CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0), pPage->GetObjCount());
635 xDocSh->DoClose();
638 void ScFiltersTest::testBasicCellContentODS()
640 ScDocShellRef xDocSh = loadDoc(u"basic-cell-content.", FORMAT_ODS);
641 CPPUNIT_ASSERT_MESSAGE("Failed to load basic-cell-content.ods", xDocSh.is());
643 ScDocument& rDoc = xDocSh->GetDocument();
644 OUString aStr = rDoc.GetString(1, 1, 0); // B2
645 CPPUNIT_ASSERT_EQUAL(OUString("LibreOffice Calc"), aStr);
646 double fVal = rDoc.GetValue(1, 2, 0); // B3
647 CPPUNIT_ASSERT_EQUAL(12345.0, fVal);
648 aStr = rDoc.GetString(1, 3, 0); // B4
649 CPPUNIT_ASSERT_EQUAL(OUString("A < B"), aStr);
651 // Numeric value of 0.
652 ScRefCellValue aCell;
653 aCell.assign(rDoc, ScAddress(1,4,0)); // B5
654 CPPUNIT_ASSERT_EQUAL_MESSAGE(
655 "This cell must be numeric.", CELLTYPE_VALUE, aCell.meType);
656 CPPUNIT_ASSERT_EQUAL(0.0, aCell.mfValue);
658 xDocSh->DoClose();
661 void ScFiltersTest::testBooleanFormatXLSX()
663 ScDocShellRef xDocSh = loadDoc(u"check-boolean.", FORMAT_XLSX);
664 ScDocument& rDoc = xDocSh->GetDocument();
665 SvNumberFormatter* pNumFormatter = rDoc.GetFormatTable();
666 // Saved as >"TRUE";"TRUE";"FALSE"< but reading converted back to >BOOLEAN<
667 const OUString aBooleanTypeStr = "BOOLEAN";
669 CPPUNIT_ASSERT_MESSAGE("Failed to load check-boolean.xlsx", xDocSh.is());
671 for (SCROW i = 0; i <= 1; i++)
673 sal_uInt32 nNumberFormat = rDoc.GetNumberFormat(0, i, 0);
674 const SvNumberformat* pNumberFormat = pNumFormatter->GetEntry(nNumberFormat);
675 const OUString& rFormatStr = pNumberFormat->GetFormatstring();
676 CPPUNIT_ASSERT_EQUAL_MESSAGE("Number format != boolean", aBooleanTypeStr, rFormatStr);
679 xDocSh->DoClose();
682 void ScFiltersTest::testTdf143809()
684 ScDocShellRef xDocSh = loadDoc(u"tdf143809.", FORMAT_ODS);
686 ScDocument& rDoc = xDocSh->GetDocument();
688 OUString aFormula = rDoc.GetFormula(0, 0, 0);
689 CPPUNIT_ASSERT_EQUAL(OUString("=SUMPRODUCT(IFERROR(CEILING.MATH(DURATIONS,300),0))"), aFormula);
691 // Without the fix in place, this test would have failed with
692 // - Expected: 53700
693 // - Actual : Err:502
694 CPPUNIT_ASSERT_EQUAL(OUString("53700"), rDoc.GetString(0, 0, 0));
696 aFormula = rDoc.GetFormula(0, 1, 0);
697 CPPUNIT_ASSERT_EQUAL(
698 OUString("=SUMPRODUCT(IFERROR(CEILING(SUMIFS(DURATIONS,IDS,IDS),300)/COUNTIFS(IDS,IDS),0))"), aFormula);
699 CPPUNIT_ASSERT_EQUAL(OUString("51900"), rDoc.GetString(0, 1, 0));
701 xDocSh->DoClose();
704 void ScFiltersTest::testTdf76310()
706 ScDocShellRef xDocSh = loadDoc(u"tdf76310.", FORMAT_ODS);
708 ScDocument& rDoc = xDocSh->GetDocument();
710 OUString aFormula = rDoc.GetFormula(0, 0, 0);
711 // Without the fix in place, this test would have failed with
712 // - Expected: =1
713 // +
714 // 2
715 // - Actual : =1 + 2
716 CPPUNIT_ASSERT_EQUAL(OUString("=1\n+\n2"), aFormula);
717 ASSERT_DOUBLES_EQUAL(3.0, rDoc.GetValue(0, 0, 0));
719 xDocSh->DoClose();
722 void ScFiltersTest::testRangeNameXLS()
724 ScDocShellRef xDocSh = loadDoc(u"named-ranges-global.", FORMAT_XLS);
725 xDocSh->DoHardRecalc();
727 ScDocument& rDoc = xDocSh->GetDocument();
728 testRangeNameImpl(rDoc);
730 OUString aCSVPath;
731 createCSVPath( "rangeExp_Sheet2.", aCSVPath );
732 // fdo#44587
733 testFile( aCSVPath, rDoc, 1);
735 xDocSh->DoClose();
738 void ScFiltersTest::testRangeNameLocalXLS()
740 ScDocShellRef xDocSh = loadDoc(u"named-ranges-local.", FORMAT_XLS);
741 xDocSh->DoHardRecalc();
743 ScDocument& rDoc = xDocSh->GetDocument();
744 ScRangeName* pRangeName = rDoc.GetRangeName(0);
745 CPPUNIT_ASSERT(pRangeName);
746 CPPUNIT_ASSERT_EQUAL(size_t(2), pRangeName->size());
748 OUString aFormula = rDoc.GetFormula(3, 11, 0);
749 CPPUNIT_ASSERT_EQUAL(OUString("=SUM(local_name2)"), aFormula);
750 ASSERT_DOUBLES_EQUAL(14.0, rDoc.GetValue(3, 11, 0));
752 aFormula = rDoc.GetFormula(6, 4, 0);
753 CPPUNIT_ASSERT_EQUAL(OUString("=local_name1"), aFormula);
755 xDocSh->DoClose();
758 void ScFiltersTest::testRangeNameXLSX()
760 ScDocShellRef xDocSh = loadDoc(u"named-ranges-global.", FORMAT_XLSX);
761 xDocSh->DoHardRecalc();
763 ScDocument& rDoc = xDocSh->GetDocument();
764 testRangeNameImpl(rDoc);
766 xDocSh->DoClose();
769 void ScFiltersTest::testHyperlinksXLSX()
771 ScDocShellRef xDocSh = loadDoc(u"hyperlinks.", FORMAT_XLSX);
772 ScDocument& rDoc = xDocSh->GetDocument();
774 CPPUNIT_ASSERT_EQUAL(OUString("10:ABC10"), rDoc.GetString(ScAddress(0,1,0)));
775 CPPUNIT_ASSERT_EQUAL(OUString("10:ABC11"), rDoc.GetString(ScAddress(0,2,0)));
776 CPPUNIT_ASSERT_EQUAL(OUString("10:ABC12"), rDoc.GetString(ScAddress(0,3,0)));
778 xDocSh->DoClose();
781 void ScFiltersTest::testHardRecalcODS()
783 ScDocShellRef xDocSh = loadDoc(u"hard-recalc.", FORMAT_ODS);
784 xDocSh->DoHardRecalc();
786 CPPUNIT_ASSERT_MESSAGE("Failed to load hard-recalc.*", xDocSh.is());
787 ScDocument& rDoc = xDocSh->GetDocument();
788 OUString aCSVFileName;
790 //test hard recalc: document has an incorrect cached formula result
791 //hard recalc should have updated to the correct result
792 createCSVPath("hard-recalc.", aCSVFileName);
793 testFile(aCSVFileName, rDoc, 0);
795 xDocSh->DoClose();
798 void ScFiltersTest::testFunctionsODS()
800 ScDocShellRef xDocSh = loadDoc(u"functions.", FORMAT_ODS);
801 xDocSh->DoHardRecalc();
803 CPPUNIT_ASSERT_MESSAGE("Failed to load functions.*", xDocSh.is());
804 ScDocument& rDoc = xDocSh->GetDocument();
805 OUString aCSVFileName;
807 //test logical functions
808 createCSVPath("logical-functions.", aCSVFileName);
809 testFile(aCSVFileName, rDoc, 0);
810 //test spreadsheet functions
811 createCSVPath("spreadsheet-functions.", aCSVFileName);
812 testFile(aCSVFileName, rDoc, 1);
813 //test mathematical functions
814 createCSVPath("mathematical-functions.", aCSVFileName);
815 testFile(aCSVFileName, rDoc, 2, StringType::PureString);
816 //test information functions
817 createCSVPath("information-functions.", aCSVFileName);
818 testFile(aCSVFileName, rDoc, 3);
819 // text functions
820 createCSVPath("text-functions.", aCSVFileName);
821 testFile(aCSVFileName, rDoc, 4, StringType::PureString);
822 // statistical functions
823 createCSVPath("statistical-functions.", aCSVFileName);
824 testFile(aCSVFileName, rDoc, 5);
825 // financial functions
826 createCSVPath("financial-functions.", aCSVFileName);
827 testFile(aCSVFileName, rDoc, 6);
829 xDocSh->DoClose();
831 xDocSh = loadDoc(u"database-functions.", FORMAT_ODS);
832 CPPUNIT_ASSERT_MESSAGE("Failed to load functions.*", xDocSh.is());
833 xDocSh->DoHardRecalc();
834 ScDocument& rDoc2 = xDocSh->GetDocument();
836 createCSVPath("database-functions.", aCSVFileName);
837 testFile(aCSVFileName, rDoc2, 0);
839 xDocSh->DoClose();
841 xDocSh = loadDoc(u"date-time-functions.", FORMAT_ODS);
842 CPPUNIT_ASSERT_MESSAGE("Failed to load functions.*", xDocSh.is());
843 xDocSh->DoHardRecalc();
844 ScDocument& rDoc3 = xDocSh->GetDocument();
845 createCSVPath("date-time-functions.", aCSVFileName);
846 testFile(aCSVFileName, rDoc3, 0, StringType::PureString);
848 xDocSh->DoClose();
850 // crashes at exit while unloading StarBasic code
851 // xDocSh = loadDoc("user-defined-function.", FORMAT_ODS);
852 // xDocSh->DoHardRecalc();
853 // ScDocument& rDocUserDef = xDocSh->GetDocument();
854 // createCSVPath("user-defined-function.", aCSVFileName);
855 // testFile(aCSVFileName, rDocUserDef, 0);
858 void ScFiltersTest::testFunctionsExcel2010()
860 ScDocShellRef xDocSh = loadDoc(u"functions-excel-2010.", FORMAT_XLSX);
861 CPPUNIT_ASSERT_MESSAGE("Failed to load the document.", xDocSh.is());
862 ScDocument& rDoc = xDocSh->GetDocument();
863 rDoc.CalcAll(); // perform hard re-calculation.
865 testFunctionsExcel2010_Impl(rDoc);
867 xDocSh->DoClose();
870 void ScFiltersTest::testCeilingFloorXLSX()
872 ScDocShellRef xDocSh = loadDoc(u"ceiling-floor.", FORMAT_XLSX);
873 CPPUNIT_ASSERT_MESSAGE("Failed to load the document.", xDocSh.is());
874 ScDocument& rDoc = xDocSh->GetDocument();
875 rDoc.CalcAll(); // perform hard re-calculation.
877 testCeilingFloor_Impl(rDoc);
879 xDocSh->DoClose();
882 void ScFiltersTest::testCachedFormulaResultsODS()
885 ScDocShellRef xDocSh = loadDoc(u"functions.", FORMAT_ODS);
886 CPPUNIT_ASSERT_MESSAGE("Failed to load functions.*", xDocSh.is());
888 ScDocument& rDoc = xDocSh->GetDocument();
889 OUString aCSVFileName;
891 //test cached formula results of logical functions
892 createCSVPath("logical-functions.", aCSVFileName);
893 testFile(aCSVFileName, rDoc, 0);
894 //test cached formula results of spreadsheet functions
895 createCSVPath("spreadsheet-functions.", aCSVFileName);
896 testFile(aCSVFileName, rDoc, 1);
897 //test cached formula results of mathematical functions
898 createCSVPath("mathematical-functions.", aCSVFileName);
899 testFile(aCSVFileName, rDoc, 2, StringType::PureString);
900 //test cached formula results of information functions
901 createCSVPath("information-functions.", aCSVFileName);
902 testFile(aCSVFileName, rDoc, 3);
903 // text functions
904 createCSVPath("text-functions.", aCSVFileName);
905 testFile(aCSVFileName, rDoc, 4, StringType::PureString);
907 xDocSh->DoClose();
911 ScDocShellRef xDocSh = loadDoc(u"cachedValue.", FORMAT_ODS);
912 CPPUNIT_ASSERT_MESSAGE("Failed to load cachedValue.*", xDocSh.is());
914 ScDocument& rDoc = xDocSh->GetDocument();
915 OUString aCSVFileName;
916 createCSVPath("cachedValue.", aCSVFileName);
917 testFile(aCSVFileName, rDoc, 0);
919 //we want to me sure that volatile functions are always recalculated
920 //regardless of cached results. if you update the ods file, you must
921 //update the values here.
922 //if NOW() is recalculated, then it should never equal "01/25/13 01:06 PM"
923 OUString sTodayRecalc(rDoc.GetString(0,0,1));
925 CPPUNIT_ASSERT("01/25/13 01:06 PM" != sTodayRecalc);
927 OUString sTodayRecalcRef(rDoc.GetString(1,0,1));
928 CPPUNIT_ASSERT_EQUAL(sTodayRecalc, sTodayRecalcRef);
930 // make sure that error values are not being treated as string values
931 for(SCCOL nCol = 0; nCol < 4; ++nCol)
933 for(SCROW nRow = 0; nRow < 2; ++nRow)
935 OUString aFormula = "=ISERROR(" +
936 OUStringChar(static_cast<char>('A'+nCol)) + OUString::number(nRow) +
937 ")";
938 rDoc.SetString(nCol, nRow + 2, 2, aFormula);
939 CPPUNIT_ASSERT_EQUAL_MESSAGE(OUStringToOString(aFormula, RTL_TEXTENCODING_UTF8).getStr(), OUString("TRUE"), rDoc.GetString(nCol, nRow +2, 2));
941 OUString aIsTextFormula = "=ISTEXT(" +
942 OUString::number(static_cast<char>('A'+nCol))+ OUString::number(nRow) +
943 ")";
944 rDoc.SetString(nCol, nRow + 4, 2, aIsTextFormula);
945 CPPUNIT_ASSERT_EQUAL(OUString("FALSE"), rDoc.GetString(nCol, nRow +4, 2));
949 xDocSh->DoClose();
953 void ScFiltersTest::testCachedMatrixFormulaResultsODS()
955 ScDocShellRef xDocSh = loadDoc(u"matrix.", FORMAT_ODS);
957 CPPUNIT_ASSERT_MESSAGE("Failed to load matrix.*", xDocSh.is());
958 ScDocument& rDoc = xDocSh->GetDocument();
960 //test matrix
961 OUString aCSVFileName;
962 createCSVPath("matrix.", aCSVFileName);
963 testFile(aCSVFileName, rDoc, 0);
964 //test matrices with special cases
965 createCSVPath("matrix2.", aCSVFileName);
966 testFile(aCSVFileName, rDoc, 1);
967 createCSVPath("matrix3.", aCSVFileName);
968 testFile(aCSVFileName, rDoc, 2);
969 //The above testFile() does not catch the below case.
970 //If a matrix formula has a matrix reference cell that is intended to have
971 //a blank text result, the matrix reference cell is actually saved(export)
972 //as a float cell with 0 as the value and an empty <text:p/>.
973 //Import works around this by setting these cells as text cells so that
974 //the blank text is used for display instead of the number 0.
975 //If this is working properly, the following cell should NOT have value data.
976 CPPUNIT_ASSERT_EQUAL(OUString(), rDoc.GetString(3,0,2));
978 // fdo#59293 with cached value import error formulas require special
979 // treatment
980 rDoc.SetString(2, 5, 2, "=ISERROR(A6)");
981 double nVal = rDoc.GetValue(2,5,2);
982 CPPUNIT_ASSERT_EQUAL(1.0, nVal);
984 xDocSh->DoClose();
987 void ScFiltersTest::testFormulaDepAcrossSheetsODS()
989 ScDocShellRef xDocSh = loadDoc(u"formula-across-sheets.", FORMAT_ODS);
990 CPPUNIT_ASSERT_MESSAGE("Failed to load the file.", xDocSh.is());
991 ScDocument& rDoc = xDocSh->GetDocument();
993 sc::AutoCalcSwitch aACSwitch(rDoc, true); // Make sure auto calc is turned on.
995 // Save the original values of A4:C4.
996 double fA4 = rDoc.GetValue(ScAddress(0,3,2));
997 double fB4 = rDoc.GetValue(ScAddress(1,3,2));
998 double fC4 = rDoc.GetValue(ScAddress(2,3,2));
1000 // Change the value of D4. This should trigger A4:C4 to be recalculated.
1001 double fD4 = rDoc.GetValue(ScAddress(3,3,2));
1002 rDoc.SetValue(ScAddress(3,3,2), fD4+1.0);
1004 CPPUNIT_ASSERT_MESSAGE("The value must differ from the original.", fA4 != rDoc.GetValue(ScAddress(0,3,2)));
1005 CPPUNIT_ASSERT_MESSAGE("The value must differ from the original.", fB4 != rDoc.GetValue(ScAddress(1,3,2)));
1006 CPPUNIT_ASSERT_MESSAGE("The value must differ from the original.", fC4 != rDoc.GetValue(ScAddress(2,3,2)));
1008 xDocSh->DoClose();
1011 void ScFiltersTest::testFormulaDepDeleteContentsODS()
1013 ScDocShellRef xDocSh = loadDoc(u"formula-delete-contents.", FORMAT_ODS, true);
1014 CPPUNIT_ASSERT_MESSAGE("Failed to load the file.", xDocSh.is());
1015 ScDocument& rDoc = xDocSh->GetDocument();
1017 sc::UndoSwitch aUndoSwitch(rDoc, true); // Enable undo.
1018 sc::AutoCalcSwitch aACSwitch(rDoc, true); // Make sure auto calc is turned on.
1020 CPPUNIT_ASSERT_EQUAL(195.0, rDoc.GetValue(ScAddress(3,15,0))); // formula in D16
1022 // Delete D2:D5.
1023 ScDocFunc& rFunc = xDocSh->GetDocFunc();
1024 ScRange aRange(3,1,0,3,4,0);
1025 ScMarkData aMark(rDoc.GetSheetLimits());
1026 aMark.SetMarkArea(aRange);
1027 aMark.MarkToMulti();
1028 bool bGood = rFunc.DeleteContents(aMark, InsertDeleteFlags::ALL, true, true);
1029 CPPUNIT_ASSERT(bGood);
1030 CPPUNIT_ASSERT_EQUAL(0.0, rDoc.GetValue(ScAddress(3,1,0)));
1031 CPPUNIT_ASSERT_EQUAL(0.0, rDoc.GetValue(ScAddress(3,2,0)));
1032 CPPUNIT_ASSERT_EQUAL(0.0, rDoc.GetValue(ScAddress(3,3,0)));
1033 CPPUNIT_ASSERT_EQUAL(0.0, rDoc.GetValue(ScAddress(3,4,0)));
1035 CPPUNIT_ASSERT_EQUAL(94.0, rDoc.GetValue(ScAddress(3,15,0))); // formula in D16
1037 SfxUndoManager* pUndoMgr = rDoc.GetUndoManager();
1038 CPPUNIT_ASSERT(pUndoMgr);
1039 pUndoMgr->Undo();
1040 CPPUNIT_ASSERT_EQUAL(195.0, rDoc.GetValue(ScAddress(3,15,0))); // formula in D16
1042 xDocSh->DoClose();
1045 namespace {
1047 void testDBRanges_Impl(ScDocument& rDoc, sal_Int32 nFormat)
1049 ScDBCollection* pDBCollection = rDoc.GetDBCollection();
1050 CPPUNIT_ASSERT_MESSAGE("no database collection", pDBCollection);
1052 ScDBData* pAnonDBData = rDoc.GetAnonymousDBData(0);
1053 CPPUNIT_ASSERT_MESSAGE("missing anonymous DB data in sheet 1", pAnonDBData);
1054 //control hidden rows
1055 bool bHidden;
1056 SCROW nRow1, nRow2;
1057 bHidden = rDoc.RowHidden(0, 0, &nRow1, &nRow2);
1058 CPPUNIT_ASSERT_MESSAGE("Sheet1: row 0 should be visible", !bHidden);
1059 CPPUNIT_ASSERT_EQUAL_MESSAGE("Sheet1: row 0 should be visible", SCROW(0), nRow1);
1060 CPPUNIT_ASSERT_EQUAL_MESSAGE("Sheet1: row 0 should be visible", SCROW(0), nRow2);
1061 bHidden = rDoc.RowHidden(1, 0, &nRow1, &nRow2);
1062 CPPUNIT_ASSERT_MESSAGE("Sheet1: rows 1-2 should be hidden", bHidden);
1063 CPPUNIT_ASSERT_EQUAL_MESSAGE("Sheet1: rows 1-2 should be hidden", SCROW(1), nRow1);
1064 CPPUNIT_ASSERT_EQUAL_MESSAGE("Sheet1: rows 1-2 should be hidden", SCROW(2), nRow2);
1065 bHidden = rDoc.RowHidden(3, 0, &nRow1, &nRow2);
1066 CPPUNIT_ASSERT_MESSAGE("Sheet1: row 3 should be visible", !bHidden);
1067 CPPUNIT_ASSERT_EQUAL_MESSAGE("Sheet1: row 3 should be visible", SCROW(3), nRow1);
1068 CPPUNIT_ASSERT_EQUAL_MESSAGE("Sheet1: row 3 should be visible", SCROW(3), nRow2);
1069 bHidden = rDoc.RowHidden(4, 0, &nRow1, &nRow2);
1070 CPPUNIT_ASSERT_MESSAGE("Sheet1: row 4-5 should be hidden", bHidden);
1071 CPPUNIT_ASSERT_EQUAL_MESSAGE("Sheet1: row 4-5 should be hidden", SCROW(4), nRow1);
1072 CPPUNIT_ASSERT_EQUAL_MESSAGE("Sheet1: row 4-5 should be hidden", SCROW(5), nRow2);
1073 bHidden = rDoc.RowHidden(6, 0, &nRow1, &nRow2);
1074 CPPUNIT_ASSERT_MESSAGE("Sheet1: row 6-end should be visible", !bHidden);
1075 CPPUNIT_ASSERT_EQUAL_MESSAGE("Sheet1: row 6-end should be visible", SCROW(6), nRow1);
1076 CPPUNIT_ASSERT_EQUAL_MESSAGE("Sheet1: row 6-end should be visible", MAXROW, nRow2);
1077 if (nFormat == FORMAT_ODS) //excel doesn't support named db ranges
1079 double aValue = rDoc.GetValue(0,10,1);
1080 CPPUNIT_ASSERT_EQUAL_MESSAGE("Sheet2: A11: formula result is incorrect", 4.0, aValue);
1081 aValue = rDoc.GetValue(1, 10, 1);
1082 CPPUNIT_ASSERT_EQUAL_MESSAGE("Sheet2: B11: formula result is incorrect", 2.0, aValue);
1084 double aValue = rDoc.GetValue(3,10,1);
1085 CPPUNIT_ASSERT_EQUAL_MESSAGE("Sheet2: D11: formula result is incorrect", 4.0, aValue);
1086 aValue = rDoc.GetValue(4, 10, 1);
1087 CPPUNIT_ASSERT_EQUAL_MESSAGE("Sheet2: E11: formula result is incorrect", 2.0, aValue);
1092 void ScFiltersTest::testDatabaseRangesODS()
1094 ScDocShellRef xDocSh = loadDoc(u"database.", FORMAT_ODS);
1095 xDocSh->DoHardRecalc();
1097 ScDocument& rDoc = xDocSh->GetDocument();
1099 testDBRanges_Impl(rDoc, FORMAT_ODS);
1100 xDocSh->DoClose();
1103 void ScFiltersTest::testDatabaseRangesXLS()
1105 ScDocShellRef xDocSh = loadDoc(u"database.", FORMAT_XLS);
1106 xDocSh->DoHardRecalc();
1108 ScDocument& rDoc = xDocSh->GetDocument();
1110 testDBRanges_Impl(rDoc, FORMAT_XLS);
1111 xDocSh->DoClose();
1114 void ScFiltersTest::testDatabaseRangesXLSX()
1116 ScDocShellRef xDocSh = loadDoc(u"database.", FORMAT_XLSX);
1117 xDocSh->DoHardRecalc();
1119 ScDocument& rDoc = xDocSh->GetDocument();
1121 testDBRanges_Impl(rDoc, FORMAT_XLSX);
1122 xDocSh->DoClose();
1125 void ScFiltersTest::testFormatsODS()
1127 ScDocShellRef xDocSh = loadDoc(u"formats.", FORMAT_ODS);
1128 xDocSh->DoHardRecalc();
1130 ScDocument& rDoc = xDocSh->GetDocument();
1132 testFormats(this, &rDoc, FORMAT_ODS);
1133 xDocSh->DoClose();
1136 // void ScFiltersTest::testFormatsXLS()
1137 // {
1138 // ScDocShellRef xDocSh = loadDoc("formats.", FORMAT_XLS);
1139 // xDocSh->DoHardRecalc();
1141 // ScDocument& rDoc = xDocSh->GetDocument();
1143 // testFormats(this, rDoc, FORMAT_XLS);
1144 // xDocSh->DoClose();
1145 // }
1147 // void ScFiltersTest::testFormatsXLSX()
1148 // {
1149 // ScDocShellRef xDocSh = loadDoc("formats.", FORMAT_XLSX);
1150 // xDocSh->DoHardRecalc();
1152 // ScDocument& rDoc = xDocSh->GetDocument();
1154 // testFormats(this, rDoc, FORMAT_XLSX);
1155 // xDocSh->DoClose();
1156 // }
1158 void ScFiltersTest::testMatrixODS()
1160 ScDocShellRef xDocSh = loadDoc(u"matrix.", FORMAT_ODS);
1161 xDocSh->DoHardRecalc();
1163 ScDocument& rDoc = xDocSh->GetDocument();
1165 OUString aCSVFileName;
1166 createCSVPath("matrix.", aCSVFileName);
1167 testFile(aCSVFileName, rDoc, 0);
1169 xDocSh->DoClose();
1172 void ScFiltersTest::testMatrixXLS()
1174 ScDocShellRef xDocSh = loadDoc(u"matrix.", FORMAT_XLS);
1175 xDocSh->DoHardRecalc();
1177 CPPUNIT_ASSERT_MESSAGE("Failed to load matrix.*", xDocSh.is());
1178 ScDocument& rDoc = xDocSh->GetDocument();
1180 OUString aCSVFileName;
1181 createCSVPath("matrix.", aCSVFileName);
1182 testFile(aCSVFileName, rDoc, 0);
1184 xDocSh->DoClose();
1187 void ScFiltersTest::testDoubleThinBorder()
1189 // double-thin borders created with size less than 1.15 where invisible (and subsequently lost) on round-trips.
1190 ScDocShellRef xDocSh = loadDoc(u"tdf88827_borderDoubleThin.", FORMAT_ODS);
1192 CPPUNIT_ASSERT_MESSAGE("Failed to load tdf88827_borderDoubleThin.*", xDocSh.is());
1193 ScDocument& rDoc = xDocSh->GetDocument();
1195 const editeng::SvxBorderLine* pLeft = nullptr;
1196 const editeng::SvxBorderLine* pTop = nullptr;
1197 const editeng::SvxBorderLine* pRight = nullptr;
1198 const editeng::SvxBorderLine* pBottom = nullptr;
1200 rDoc.GetBorderLines( 2, 2, 0, &pLeft, &pTop, &pRight, &pBottom );
1201 CPPUNIT_ASSERT(pTop);
1202 CPPUNIT_ASSERT(pRight);
1203 CPPUNIT_ASSERT_EQUAL( SvxBorderLineStyle::DOUBLE_THIN, pRight->GetBorderLineStyle() );
1204 xDocSh->DoClose();
1207 void ScFiltersTest::testBorderODS()
1209 ScDocShellRef xDocSh = loadDoc(u"border.", FORMAT_ODS);
1211 CPPUNIT_ASSERT_MESSAGE("Failed to load border.*", xDocSh.is());
1212 ScDocument& rDoc = xDocSh->GetDocument();
1214 const editeng::SvxBorderLine* pLeft = nullptr;
1215 const editeng::SvxBorderLine* pTop = nullptr;
1216 const editeng::SvxBorderLine* pRight = nullptr;
1217 const editeng::SvxBorderLine* pBottom = nullptr;
1219 rDoc.GetBorderLines( 0, 1, 0, &pLeft, &pTop, &pRight, &pBottom );
1220 CPPUNIT_ASSERT(!pLeft);
1221 CPPUNIT_ASSERT(!pTop);
1222 CPPUNIT_ASSERT(!pBottom);
1223 CPPUNIT_ASSERT(pRight);
1224 CPPUNIT_ASSERT_EQUAL(SvxBorderLineStyle::SOLID, pRight->GetBorderLineStyle());
1226 rDoc.GetBorderLines( 2, 1, 0, &pLeft, &pTop, &pRight, &pBottom );
1227 CPPUNIT_ASSERT(!pLeft);
1228 CPPUNIT_ASSERT(!pTop);
1229 CPPUNIT_ASSERT(!pBottom);
1231 CPPUNIT_ASSERT(pRight);
1232 CPPUNIT_ASSERT_EQUAL(SvxBorderLineStyle::SOLID, pRight->GetBorderLineStyle());
1233 CPPUNIT_ASSERT_EQUAL(tools::Long(20), pRight->GetWidth());
1235 rDoc.GetBorderLines( 2, 8, 0, &pLeft, &pTop, &pRight, &pBottom );
1237 CPPUNIT_ASSERT(pLeft);
1238 CPPUNIT_ASSERT(pTop);
1239 CPPUNIT_ASSERT(pBottom);
1240 CPPUNIT_ASSERT(pRight);
1241 CPPUNIT_ASSERT_EQUAL(SvxBorderLineStyle::SOLID, pRight->GetBorderLineStyle());
1242 CPPUNIT_ASSERT_EQUAL(tools::Long(5), pRight->GetWidth());
1243 CPPUNIT_ASSERT_EQUAL(COL_BLUE, pRight->GetColor());
1245 xDocSh->DoClose();
1248 namespace {
1250 struct Border
1252 sal_Int16 column;
1253 sal_Int32 row;
1254 tools::Long leftWidth;
1255 tools::Long topWidth;
1256 tools::Long rightWidth;
1257 tools::Long bottomWidth;
1258 sal_uInt16 lOutWidth;
1259 sal_uInt16 lInWidth;
1260 sal_uInt16 lDistance;
1261 sal_uInt16 tOutWidth;
1262 sal_uInt16 tInWidth;
1263 sal_uInt16 tDistance;
1264 sal_uInt16 rOutWidth;
1265 sal_uInt16 rInWidth;
1266 sal_uInt16 rDistance;
1267 sal_uInt16 bOutWidth;
1268 sal_uInt16 bInWidth;
1269 sal_uInt16 bDistance;
1270 SvxBorderLineStyle lStyle;
1271 SvxBorderLineStyle tStyle;
1272 SvxBorderLineStyle rStyle;
1273 SvxBorderLineStyle bStyle;
1274 // that's a monster
1275 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,
1276 sal_uInt16 lDist, sal_uInt16 tOutW, sal_uInt16 tInW, sal_uInt16 tDist, sal_uInt16 rOutW, sal_uInt16 rInW, sal_uInt16 rDist,
1277 sal_uInt16 bOutW, sal_uInt16 bInW, sal_uInt16 bDist, sal_Int16 lSt, sal_Int16 tSt, sal_Int16 rSt, sal_Int16 bSt):
1278 column(col), row(r), leftWidth(lW), topWidth(tW), rightWidth(rW), bottomWidth(bW), lOutWidth(lOutW), lInWidth(lInW), lDistance(lDist),
1279 tOutWidth(tOutW), tInWidth(tInW), tDistance(tDist), rOutWidth(rOutW), rInWidth(rInW), rDistance(rDist), bOutWidth(bOutW), bInWidth(bInW),
1280 bDistance(bDist),
1281 lStyle(static_cast<SvxBorderLineStyle>(lSt)), tStyle(static_cast<SvxBorderLineStyle>(tSt)), rStyle(static_cast<SvxBorderLineStyle>(rSt)), bStyle(static_cast<SvxBorderLineStyle>(bSt)) {};
1286 void ScFiltersTest::testBordersOoo33()
1288 std::vector<Border> borders;
1289 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);
1290 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);
1291 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);
1292 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);
1293 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);
1294 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);
1295 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);
1296 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);
1297 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);
1298 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);
1299 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);
1300 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);
1301 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);
1302 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);
1303 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);
1304 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);
1305 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);
1307 ScDocShellRef xDocSh = loadDoc(u"borders_ooo33.", FORMAT_ODS);
1309 CPPUNIT_ASSERT_MESSAGE("Failed to load borders_ooo33.*", xDocSh.is());
1310 ScDocument& rDoc = xDocSh->GetDocument();
1312 const editeng::SvxBorderLine* pLeft = nullptr;
1313 const editeng::SvxBorderLine* pTop = nullptr;
1314 const editeng::SvxBorderLine* pRight = nullptr;
1315 const editeng::SvxBorderLine* pBottom = nullptr;
1316 sal_Int16 temp = 0;
1317 for(sal_Int16 i = 0; i<6; ++i)
1319 for(sal_Int32 j = 0; j<22; ++j)
1321 rDoc.GetBorderLines( i, j, 0, &pLeft, &pTop, &pRight, &pBottom );
1322 if(pLeft!=nullptr && pTop!=nullptr && pRight!=nullptr && pBottom!=nullptr)
1324 CPPUNIT_ASSERT_EQUAL(borders[temp].column, i);
1325 CPPUNIT_ASSERT_EQUAL(borders[temp].row, j);
1326 CPPUNIT_ASSERT_EQUAL(borders[temp].leftWidth, pLeft->GetWidth());
1327 CPPUNIT_ASSERT_EQUAL(borders[temp].topWidth, pTop->GetWidth());
1328 CPPUNIT_ASSERT_EQUAL(borders[temp].rightWidth, pRight->GetWidth());
1329 CPPUNIT_ASSERT_EQUAL(borders[temp].bottomWidth, pBottom->GetWidth());
1330 CPPUNIT_ASSERT_EQUAL(borders[temp].lOutWidth, pLeft->GetOutWidth());
1331 CPPUNIT_ASSERT_EQUAL(borders[temp].lInWidth, pLeft->GetInWidth());
1332 CPPUNIT_ASSERT_EQUAL(borders[temp].lDistance, pLeft->GetDistance());
1333 CPPUNIT_ASSERT_EQUAL(borders[temp].tOutWidth, pTop->GetOutWidth());
1334 CPPUNIT_ASSERT_EQUAL(borders[temp].tInWidth, pTop->GetInWidth());
1335 CPPUNIT_ASSERT_EQUAL(borders[temp].tDistance, pTop->GetDistance());
1336 CPPUNIT_ASSERT_EQUAL(borders[temp].rOutWidth, pRight->GetOutWidth());
1337 CPPUNIT_ASSERT_EQUAL(borders[temp].rInWidth, pRight->GetInWidth());
1338 CPPUNIT_ASSERT_EQUAL(borders[temp].rDistance, pRight->GetDistance());
1339 CPPUNIT_ASSERT_EQUAL(borders[temp].bOutWidth, pBottom->GetOutWidth());
1340 CPPUNIT_ASSERT_EQUAL(borders[temp].bInWidth, pBottom->GetInWidth());
1341 CPPUNIT_ASSERT_EQUAL(borders[temp].bDistance, pBottom->GetDistance());
1342 SvxBorderLineStyle tempStyle = pLeft->GetBorderLineStyle();
1343 CPPUNIT_ASSERT_EQUAL(borders[temp].lStyle, tempStyle);
1344 tempStyle = pTop->GetBorderLineStyle();
1345 CPPUNIT_ASSERT_EQUAL(borders[temp].tStyle, tempStyle);
1346 tempStyle = pRight->GetBorderLineStyle();
1347 CPPUNIT_ASSERT_EQUAL(borders[temp].rStyle, tempStyle);
1348 tempStyle = pBottom->GetBorderLineStyle();
1349 CPPUNIT_ASSERT_EQUAL(borders[temp].bStyle, tempStyle);
1350 ++temp;
1355 xDocSh->DoClose();
1358 void ScFiltersTest::testBugFixesODS()
1360 ScDocShellRef xDocSh = loadDoc(u"bug-fixes.", FORMAT_ODS);
1361 CPPUNIT_ASSERT_MESSAGE("Failed to load bugFixes.ods", xDocSh.is());
1363 xDocSh->DoHardRecalc();
1364 ScDocument& rDoc = xDocSh->GetDocument();
1367 // fdo#40967
1368 OUString aCSVFileName;
1369 createCSVPath("bugFix_Sheet2.", aCSVFileName);
1370 testFile(aCSVFileName, rDoc, 1);
1374 // fdo#40426
1375 ScDBData* pDBData = rDoc.GetDBCollection()->getNamedDBs().findByUpperName("DBRANGE1");
1376 CPPUNIT_ASSERT(pDBData);
1377 CPPUNIT_ASSERT(pDBData->HasHeader());
1378 // no header
1379 pDBData = rDoc.GetDBCollection()->getNamedDBs().findByUpperName("DBRANGE2");
1380 CPPUNIT_ASSERT(pDBData);
1381 CPPUNIT_ASSERT(!pDBData->HasHeader());
1385 // fdo#59240
1386 OUString aCSVFileName;
1387 createCSVPath("bugFix_Sheet4.", aCSVFileName);
1388 testFile(aCSVFileName, rDoc, 3);
1391 xDocSh->DoClose();
1394 void ScFiltersTest::testBugFixesXLS()
1396 ScDocShellRef xDocSh = loadDoc(u"bug-fixes.", FORMAT_XLS);
1397 CPPUNIT_ASSERT_MESSAGE("Failed to load bugFixes.xls", xDocSh.is());
1399 xDocSh->DoHardRecalc();
1400 xDocSh->DoClose();
1403 void ScFiltersTest::testBugFixesXLSX()
1405 ScDocShellRef xDocSh = loadDoc(u"bug-fixes.", FORMAT_XLSX);
1406 CPPUNIT_ASSERT_MESSAGE("Failed to load bugFixes.xls", xDocSh.is());
1408 xDocSh->DoHardRecalc();
1409 xDocSh->DoClose();
1412 namespace {
1414 void checkMergedCells( ScDocument& rDoc, const ScAddress& rStartAddress,
1415 const ScAddress& rExpectedEndAddress )
1417 SCCOL nActualEndCol = rStartAddress.Col();
1418 SCROW nActualEndRow = rStartAddress.Row();
1419 rDoc.ExtendMerge( rStartAddress.Col(), rStartAddress.Row(),
1420 nActualEndCol, nActualEndRow, rStartAddress.Tab() );
1421 OString sTab = OString::number( rStartAddress.Tab() + 1 );
1422 OString msg = "Merged cells are not correctly imported on sheet" + sTab;
1423 OString msgCol = msg + "; end col";
1424 OString msgRow = msg + "; end row";
1425 CPPUNIT_ASSERT_EQUAL_MESSAGE( msgCol.pData->buffer, rExpectedEndAddress.Col(), nActualEndCol );
1426 CPPUNIT_ASSERT_EQUAL_MESSAGE( msgRow.pData->buffer, rExpectedEndAddress.Row(), nActualEndRow );
1431 void ScFiltersTest::testMergedCellsODS()
1433 ScDocShellRef xDocSh = loadDoc(u"merged.", FORMAT_ODS);
1434 ScDocument& rDoc = xDocSh->GetDocument();
1436 //check sheet1 content
1437 OUString aCSVFileName1;
1438 createCSVPath("merged1.", aCSVFileName1);
1439 testFile(aCSVFileName1, rDoc, 0);
1441 //check sheet1 merged cells
1442 checkMergedCells( rDoc, ScAddress( 0, 0, 0 ), ScAddress( 5, 11, 0 ) );
1443 checkMergedCells( rDoc, ScAddress( 7, 2, 0 ), ScAddress( 9, 12, 0 ) );
1444 checkMergedCells( rDoc, ScAddress( 3, 15, 0 ), ScAddress( 7, 23, 0 ) );
1446 //check sheet2 content
1447 OUString aCSVFileName2;
1448 createCSVPath("merged2.", aCSVFileName2);
1449 testFile(aCSVFileName2, rDoc, 1);
1451 //check sheet2 merged cells
1452 checkMergedCells( rDoc, ScAddress( 4, 3, 1 ), ScAddress( 6, 15, 1 ) );
1454 xDocSh->DoClose();
1457 void ScFiltersTest::testRepeatedColumnsODS()
1459 ScDocShellRef xDocSh = loadDoc(u"repeatedColumns.", FORMAT_ODS);
1460 ScDocument& rDoc = xDocSh->GetDocument();
1462 //text
1463 OUString aCSVFileName1;
1464 createCSVPath("repeatedColumns1.", aCSVFileName1);
1465 testFile(aCSVFileName1, rDoc, 0);
1467 //numbers
1468 OUString aCSVFileName2;
1469 createCSVPath("repeatedColumns2.", aCSVFileName2);
1470 testFile(aCSVFileName2, rDoc, 1);
1472 xDocSh->DoClose();
1475 namespace {
1477 //for cleaner passing of parameters
1478 struct ValDataTestParams
1480 ScValidationMode eValMode;
1481 ScConditionMode eCondOp;
1482 OUString aStrVal1;
1483 OUString aStrVal2;
1484 ScDocument& rDocument;
1485 ScAddress aPosition;
1486 OUString aErrorTitle;
1487 OUString aErrorMessage;
1488 ScValidErrorStyle eErrorStyle;
1489 sal_uLong nExpectedIndex;
1491 ValDataTestParams( ScValidationMode eMode, ScConditionMode eOp,
1492 const OUString& aExpr1, const OUString& aExpr2, ScDocument& rDoc,
1493 const ScAddress& aPos, const OUString& aETitle, const OUString& aEMsg,
1494 ScValidErrorStyle eEStyle, sal_uLong nIndex ):
1495 eValMode(eMode), eCondOp(eOp), aStrVal1(aExpr1),
1496 aStrVal2(aExpr2), rDocument(rDoc), aPosition(aPos),
1497 aErrorTitle(aETitle), aErrorMessage(aEMsg),
1498 eErrorStyle(eEStyle), nExpectedIndex(nIndex) { };
1501 void checkValiditationEntries( const ValDataTestParams& rVDTParams )
1503 ScDocument& rDoc = rVDTParams.rDocument;
1505 //create expected data validation entry
1506 ScValidationData aValData(
1507 rVDTParams.eValMode, rVDTParams.eCondOp, rVDTParams.aStrVal1,
1508 rVDTParams.aStrVal2, rDoc, rVDTParams.aPosition, OUString(),
1509 OUString(), rDoc.GetStorageGrammar(), rDoc.GetStorageGrammar()
1511 aValData.SetIgnoreBlank( true );
1512 aValData.SetListType( 1 );
1513 aValData.ResetInput();
1514 aValData.SetError( rVDTParams.aErrorTitle, rVDTParams.aErrorMessage, rVDTParams.eErrorStyle );
1515 aValData.SetSrcString( OUString() );
1517 //get actual data validation entry from document
1518 const ScValidationData* pValDataTest = rDoc.GetValidationEntry( rVDTParams.nExpectedIndex );
1520 sal_Int32 nCol( static_cast<sal_Int32>(rVDTParams.aPosition.Col()) );
1521 sal_Int32 nRow( static_cast<sal_Int32>(rVDTParams.aPosition.Row()) );
1522 sal_Int32 nTab( static_cast<sal_Int32>(rVDTParams.aPosition.Tab()) );
1523 OString aMsgPrefix = "Data Validation Entry with base-cell-address: (" +
1524 OString::number(nCol) + "," + OString::number(nRow) + "," + OString::number(nTab) + ") ";
1526 OString aMsg = aMsgPrefix + "did not get imported at all.";
1527 CPPUNIT_ASSERT_MESSAGE(aMsg.getStr(), pValDataTest);
1529 //check if expected and actual data validation entries are equal
1530 if (!aValData.EqualEntries(*pValDataTest))
1532 aMsg = aMsgPrefix + "got imported incorrectly.";
1533 CPPUNIT_FAIL(aMsg.getStr());
1537 void checkCellValidity( const ScAddress& rValBaseAddr, const ScRange& rRange, const ScDocument& rDoc )
1539 SCCOL nBCol( rValBaseAddr.Col() );
1540 SCROW nBRow( rValBaseAddr.Row() );
1541 SCTAB nTab( static_cast<sal_Int32>(rValBaseAddr.Tab()) );
1542 //get from the document the data validation entry we are checking against
1543 const SfxUInt32Item* pItem = rDoc.GetAttr(nBCol, nBRow, nTab, ATTR_VALIDDATA);
1544 const ScValidationData* pValData = rDoc.GetValidationEntry( pItem->GetValue() );
1545 CPPUNIT_ASSERT(pValData);
1547 //check that each cell in the expected range is associated with the data validation entry
1548 for(SCCOL i = rRange.aStart.Col(); i <= rRange.aEnd.Col(); ++i)
1550 for(SCROW j = rRange.aStart.Row(); j <= rRange.aEnd.Row(); ++j)
1552 const SfxUInt32Item* pItemTest = rDoc.GetAttr(i, j, nTab, ATTR_VALIDDATA);
1553 const ScValidationData* pValDataTest = rDoc.GetValidationEntry( pItemTest->GetValue() );
1554 //prevent string operations for occurring unnecessarily
1555 if(!(pValDataTest && pValData->GetKey() == pValDataTest->GetKey()))
1557 sal_Int32 nCol = static_cast<sal_Int32>(i);
1558 sal_Int32 nRow = static_cast<sal_Int32>(j);
1559 sal_Int32 nTab32 = static_cast<sal_Int32>(nTab);
1560 OString sMsg = "\nData validation entry base-cell-address: (" +
1561 OString::number( static_cast<sal_Int32>(nBCol) ) + "," +
1562 OString::number( static_cast<sal_Int32>(nBRow) ) + "," +
1563 OString::number( nTab32 ) + ")\n"
1564 "Cell: (" + OString::number(nCol) + "," +
1565 OString::number(nRow) + "," +
1566 OString::number(nTab32) + ")";
1567 sal_uInt32 expectedKey(pValData->GetKey());
1568 sal_uInt32 actualKey(0);
1569 if(pValDataTest)
1570 actualKey = pValDataTest->GetKey();
1571 CPPUNIT_ASSERT_EQUAL_MESSAGE(sMsg.getStr(), expectedKey, actualKey);
1579 void ScFiltersTest::testDataValidityODS()
1581 ScDocShellRef xDocSh = loadDoc(u"dataValidity.", FORMAT_ODS);
1582 ScDocument& rDoc = xDocSh->GetDocument();
1584 ScAddress aValBaseAddr1( 2,6,0 ); //sheet1
1585 ScAddress aValBaseAddr2( 2,3,1 ); //sheet2
1586 ScAddress aValBaseAddr3( 2,2,2 ); //sheet3
1588 //sheet1's expected Data Validation Entry values
1589 ValDataTestParams aVDTParams1(
1590 SC_VALID_DECIMAL, ScConditionMode::Greater, "3.14", OUString(), rDoc,
1591 aValBaseAddr1, "Too small",
1592 "The number you are trying to enter is not greater than 3.14! Are you sure you want to enter it anyway?",
1593 SC_VALERR_WARNING, 1
1595 //sheet2's expected Data Validation Entry values
1596 ValDataTestParams aVDTParams2(
1597 SC_VALID_WHOLE, ScConditionMode::Between, "1", "10", rDoc,
1598 aValBaseAddr2, "Error sheet 2",
1599 "Must be a whole number between 1 and 10.",
1600 SC_VALERR_STOP, 2
1602 //sheet3's expected Data Validation Entry values
1603 ValDataTestParams aVDTParams3(
1604 SC_VALID_CUSTOM, ScConditionMode::Direct, "ISTEXT(C3)", OUString(), rDoc,
1605 aValBaseAddr3, "Error sheet 3",
1606 "Must not be a numerical value.",
1607 SC_VALERR_STOP, 3
1609 //check each sheet's Data Validation Entries
1610 checkValiditationEntries( aVDTParams1 );
1611 checkValiditationEntries( aVDTParams2 );
1612 checkValiditationEntries( aVDTParams3 );
1614 //expected ranges to be associated with data validity
1615 ScRange aRange1( 2,2,0, 2,6,0 ); //sheet1
1616 ScRange aRange2( 2,3,1, 6,7,1 ); //sheet2
1617 ScRange aRange3( 2,2,2, 2,6,2 ); //sheet3
1619 //check each sheet's cells for data validity
1620 checkCellValidity( aValBaseAddr1, aRange1, rDoc );
1621 checkCellValidity( aValBaseAddr2, aRange2, rDoc );
1622 checkCellValidity( aValBaseAddr3, aRange3, rDoc );
1624 //check each sheet's content
1625 OUString aCSVFileName1;
1626 createCSVPath("dataValidity1.", aCSVFileName1);
1627 testFile(aCSVFileName1, rDoc, 0);
1629 OUString aCSVFileName2;
1630 createCSVPath("dataValidity2.", aCSVFileName2);
1631 testFile(aCSVFileName2, rDoc, 1);
1633 OUString aCSVFileName3;
1634 createCSVPath("dataValidity3.", aCSVFileName3);
1635 testFile(aCSVFileName3, rDoc, 2);
1637 xDocSh->DoClose();
1640 void ScFiltersTest::testDataValidityXLSX()
1642 ScDocShellRef xDocSh = loadDoc(u"dataValidity.", FORMAT_XLSX);
1643 ScDocument& rDoc = xDocSh->GetDocument();
1645 ScAddress aValBaseAddr1( 2,6,0 ); //sheet1
1646 ScAddress aValBaseAddr2( 2,3,1 ); //sheet2
1647 ScAddress aValBaseAddr3( 2,2,2 ); //sheet3
1649 //expected ranges to be associated with data validity
1650 ScRange aRange1( 2,2,0, 2,6,0 ); //sheet1
1651 ScRange aRange2( 2,3,1, 6,7,1 ); //sheet2
1652 ScRange aRange3( 2,2,2, 2,6,2 ); //sheet3
1654 //check each sheet's cells for data validity
1655 checkCellValidity( aValBaseAddr1, aRange1, rDoc );
1656 checkCellValidity( aValBaseAddr2, aRange2, rDoc );
1657 checkCellValidity( aValBaseAddr3, aRange3, rDoc );
1659 xDocSh->DoClose();
1662 void ScFiltersTest::testDataTableMortgageXLS()
1664 ScDocShellRef xDocSh = loadDoc(u"data-table/mortgage.", FORMAT_XLS);
1665 CPPUNIT_ASSERT_MESSAGE("Failed to load the document.", xDocSh.is());
1667 ScDocument& rDoc = xDocSh->GetDocument();
1669 // One-variable table
1671 ASSERT_FORMULA_EQUAL(rDoc, ScAddress(3,1,0), "PMT(B3/12,B4,-B5)", "Wrong formula!");
1672 ASSERT_FORMULA_EQUAL(rDoc, ScAddress(3,2,0), "MULTIPLE.OPERATIONS(D$2,$B$3,$C3)", "Wrong formula!");
1673 ASSERT_FORMULA_EQUAL(rDoc, ScAddress(3,3,0), "MULTIPLE.OPERATIONS(D$2,$B$3,$C4)", "Wrong formula!");
1674 ASSERT_FORMULA_EQUAL(rDoc, ScAddress(3,4,0), "MULTIPLE.OPERATIONS(D$2,$B$3,$C5)", "Wrong formula!");
1676 // Two-variable table
1678 ASSERT_FORMULA_EQUAL(rDoc, ScAddress(2,7,0), "PMT(B9/12,B10,-B11)", "Wrong formula!");
1679 ASSERT_FORMULA_EQUAL(rDoc, ScAddress(3,8,0), "MULTIPLE.OPERATIONS($C$8,$B$9,$C9,$B$10,D$8)", "Wrong formula!");
1680 ASSERT_FORMULA_EQUAL(rDoc, ScAddress(3,9,0), "MULTIPLE.OPERATIONS($C$8,$B$9,$C10,$B$10,D$8)", "Wrong formula!");
1681 ASSERT_FORMULA_EQUAL(rDoc, ScAddress(3,10,0), "MULTIPLE.OPERATIONS($C$8,$B$9,$C11,$B$10,D$8)", "Wrong formula!");
1682 ASSERT_FORMULA_EQUAL(rDoc, ScAddress(4,8,0), "MULTIPLE.OPERATIONS($C$8,$B$9,$C9,$B$10,E$8)", "Wrong formula!");
1683 ASSERT_FORMULA_EQUAL(rDoc, ScAddress(4,9,0), "MULTIPLE.OPERATIONS($C$8,$B$9,$C10,$B$10,E$8)", "Wrong formula!");
1684 ASSERT_FORMULA_EQUAL(rDoc, ScAddress(4,10,0), "MULTIPLE.OPERATIONS($C$8,$B$9,$C11,$B$10,E$8)", "Wrong formula!");
1686 xDocSh->DoClose();
1689 void ScFiltersTest::testDataTableOneVarXLSX()
1691 ScDocShellRef xDocSh = loadDoc(u"data-table/one-variable.", FORMAT_XLSX);
1692 CPPUNIT_ASSERT_MESSAGE("Failed to load the document.", xDocSh.is());
1694 ScDocument& rDoc = xDocSh->GetDocument();
1696 // Right now, we have a bug that prevents Calc from re-calculating these
1697 // cells automatically upon file load. We can remove this call if/when we
1698 // fix the aforementioned bug.
1699 rDoc.CalcAll();
1701 // B5:B11 should have multiple operations formula cells. Just check the
1702 // top and bottom cells.
1704 ASSERT_FORMULA_EQUAL(rDoc, ScAddress(1,4,0), "MULTIPLE.OPERATIONS(B$4,$A$2,$A5)", "Wrong formula!");
1706 CPPUNIT_ASSERT_EQUAL(2.0, rDoc.GetValue(ScAddress(1,4,0)));
1708 ASSERT_FORMULA_EQUAL(rDoc, ScAddress(1,10,0), "MULTIPLE.OPERATIONS(B$4,$A$2,$A11)", "Wrong formula!");
1710 CPPUNIT_ASSERT_EQUAL(14.0, rDoc.GetValue(ScAddress(1,10,0)));
1712 // Likewise, E5:I5 should have multiple operations formula cells. Just
1713 // check the left- and right-most cells.
1715 ASSERT_FORMULA_EQUAL(rDoc, ScAddress(4,4,0), "MULTIPLE.OPERATIONS($D5,$B$2,E$4)", "Wrong formula!");
1717 CPPUNIT_ASSERT_EQUAL(10.0, rDoc.GetValue(ScAddress(4,4,0)));
1719 ASSERT_FORMULA_EQUAL(rDoc, ScAddress(8,4,0), "MULTIPLE.OPERATIONS($D5,$B$2,I$4)", "Wrong formula!");
1721 CPPUNIT_ASSERT_EQUAL(50.0, rDoc.GetValue(ScAddress(8,4,0)));
1723 xDocSh->DoClose();
1726 void ScFiltersTest::testDataTableMultiTableXLSX()
1728 ScDocShellRef xDocSh = loadDoc(u"data-table/multi-table.", FORMAT_XLSX);
1729 CPPUNIT_ASSERT_MESSAGE("Failed to load the document.", xDocSh.is());
1731 ScDocument& rDoc = xDocSh->GetDocument();
1733 // Right now, we have a bug that prevents Calc from re-calculating these
1734 // cells automatically upon file load. We can remove this call if/when we
1735 // fix the aforementioned bug.
1736 rDoc.CalcAll();
1738 // B4:M15 should have multiple operations formula cells. We'll just check
1739 // the top-left and bottom-right ones.
1741 ASSERT_FORMULA_EQUAL(rDoc, ScAddress(1,3,0), "MULTIPLE.OPERATIONS($A$3,$E$1,$A4,$D$1,B$3)", "Wrong formula!");
1743 CPPUNIT_ASSERT_EQUAL(1.0, rDoc.GetValue(ScAddress(1,3,0)));
1745 ASSERT_FORMULA_EQUAL(rDoc, ScAddress(12,14,0), "MULTIPLE.OPERATIONS($A$3,$E$1,$A15,$D$1,M$3)", "Wrong formula!");
1747 CPPUNIT_ASSERT_EQUAL(144.0, rDoc.GetValue(ScAddress(12,14,0)));
1749 xDocSh->DoClose();
1752 void ScFiltersTest::testBrokenQuotesCSV()
1754 OUString aFileExtension(getFileFormats()[FORMAT_CSV].pName, strlen(getFileFormats()[FORMAT_CSV].pName), RTL_TEXTENCODING_UTF8 );
1755 OUString aFilterName(getFileFormats()[FORMAT_CSV].pFilterName, strlen(getFileFormats()[FORMAT_CSV].pFilterName), RTL_TEXTENCODING_UTF8) ;
1756 OUString aFileName;
1757 createFileURL(u"fdo48621_broken_quotes.", aFileExtension, aFileName);
1758 OUString aFilterType(getFileFormats()[FORMAT_CSV].pTypeName, strlen(getFileFormats()[FORMAT_CSV].pTypeName), RTL_TEXTENCODING_UTF8);
1759 std::cout << getFileFormats()[FORMAT_CSV].pName << " Test" << std::endl;
1761 SfxFilterFlags nFormatType = getFileFormats()[FORMAT_CSV].nFormatType;
1762 SotClipboardFormatId nClipboardId = bool(nFormatType) ? SotClipboardFormatId::STARCALC_8 : SotClipboardFormatId::NONE;
1763 ScDocShellRef xDocSh = ScBootstrapFixture::load(aFileName, aFilterName, OUString(), aFilterType,
1764 nFormatType, nClipboardId);
1766 CPPUNIT_ASSERT_MESSAGE("Failed to load fdo48621_broken_quotes.csv", xDocSh.is());
1767 ScDocument& rDoc = xDocSh->GetDocument();
1769 OUString aCSVPath;
1770 createCSVPath( "fdo48621_broken_quotes_exported.", aCSVPath );
1771 // fdo#48621
1772 testFile( aCSVPath, rDoc, 0, StringType::PureString);
1774 xDocSh->DoClose();
1777 void ScFiltersTest::testCellValueXLSX()
1779 static const OUStringLiteral aFileNameBase(u"cell-value.");
1780 OUString aFileExtension(getFileFormats()[FORMAT_XLSX].pName, strlen(getFileFormats()[FORMAT_XLSX].pName), RTL_TEXTENCODING_UTF8 );
1781 OUString aFilterName(getFileFormats()[FORMAT_XLSX].pFilterName, strlen(getFileFormats()[FORMAT_XLSX].pFilterName), RTL_TEXTENCODING_UTF8) ;
1782 OUString aFileName;
1783 createFileURL(aFileNameBase, aFileExtension, aFileName);
1784 OUString aFilterType(getFileFormats()[FORMAT_XLSX].pTypeName, strlen(getFileFormats()[FORMAT_XLSX].pTypeName), RTL_TEXTENCODING_UTF8);
1785 std::cout << getFileFormats()[FORMAT_XLSX].pName << " Test" << std::endl;
1787 SfxFilterFlags nFormatType = getFileFormats()[FORMAT_XLSX].nFormatType;
1788 SotClipboardFormatId nClipboardId = bool(nFormatType) ? SotClipboardFormatId::STARCALC_8 : SotClipboardFormatId::NONE;
1789 ScDocShellRef xDocSh = ScBootstrapFixture::load( aFileName, aFilterName, OUString(), aFilterType,
1790 nFormatType, nClipboardId);
1792 CPPUNIT_ASSERT_MESSAGE("Failed to load cell-value.xlsx", xDocSh.is());
1793 ScDocument& rDoc = xDocSh->GetDocument();
1795 OUString aCSVPath;
1796 createCSVPath( aFileNameBase, aCSVPath );
1797 testFile( aCSVPath, rDoc, 0 );
1799 xDocSh->DoClose();
1802 void ScFiltersTest::testRowIndex1BasedXLSX()
1804 ScDocShellRef xDocSh = loadDoc(u"row-index-1-based.", FORMAT_XLSX);
1805 CPPUNIT_ASSERT(xDocSh.is());
1806 ScDocument& rDoc = xDocSh->GetDocument();
1808 // A1
1809 OUString aStr = rDoc.GetString(ScAddress(0,0,0));
1810 CPPUNIT_ASSERT_EQUAL(OUString("Action Plan.Name"), aStr);
1812 // B1
1813 aStr = rDoc.GetString(ScAddress(1,0,0));
1814 CPPUNIT_ASSERT_EQUAL(OUString("Action Plan.Description"), aStr);
1816 // A2
1817 aStr = rDoc.GetString(ScAddress(0,1,0));
1818 CPPUNIT_ASSERT_EQUAL(OUString("Jerry"), aStr);
1820 // B2 - multi-line text.
1821 const EditTextObject* pText = rDoc.GetEditText(ScAddress(1,1,0));
1822 CPPUNIT_ASSERT(pText);
1823 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(3), pText->GetParagraphCount());
1824 aStr = pText->GetText(0);
1825 CPPUNIT_ASSERT_EQUAL(OUString("This is a longer Text."), aStr);
1826 aStr = pText->GetText(1);
1827 CPPUNIT_ASSERT_EQUAL(OUString("Second line."), aStr);
1828 aStr = pText->GetText(2);
1829 CPPUNIT_ASSERT_EQUAL(OUString("Third line."), aStr);
1831 xDocSh->DoClose();
1834 void ScFiltersTest::testImportCrash(std::u16string_view rFileName, sal_Int32 nFormat)
1836 ScDocShellRef xDocSh =loadDoc(rFileName, nFormat);
1837 CPPUNIT_ASSERT_MESSAGE(OString("Failed to load " + OUStringToOString(rFileName, RTL_TEXTENCODING_UTF8)).getStr(), xDocSh.is());
1839 ScDocument& rDoc = xDocSh->GetDocument();
1840 rDoc.CalcAll(); // perform hard re-calculation.
1842 xDocSh->DoClose();
1845 void ScFiltersTest::testPassword_Impl(std::u16string_view aFileNameBase)
1847 OUString aFileExtension(getFileFormats()[0].pName, strlen(getFileFormats()[0].pName), RTL_TEXTENCODING_UTF8 );
1848 OUString aFilterName(getFileFormats()[0].pFilterName, strlen(getFileFormats()[0].pFilterName), RTL_TEXTENCODING_UTF8) ;
1849 OUString aFileName;
1850 createFileURL(aFileNameBase, aFileExtension, aFileName);
1851 OUString aFilterType(getFileFormats()[0].pTypeName, strlen(getFileFormats()[0].pTypeName), RTL_TEXTENCODING_UTF8);
1853 SfxFilterFlags nFormatType = getFileFormats()[0].nFormatType;
1854 OUString aPass("test");
1855 ScDocShellRef xDocSh = ScBootstrapFixture::load(aFileName, aFilterName, OUString(), aFilterType,
1856 nFormatType, SotClipboardFormatId::STARCALC_8, SOFFICE_FILEFORMAT_CURRENT, &aPass);
1858 CPPUNIT_ASSERT_MESSAGE("Failed to load password.ods", xDocSh.is());
1859 xDocSh->DoClose();
1862 void ScFiltersTest::testPasswordNew()
1864 //tests opening a file with new password algorithm
1865 testPassword_Impl(u"password.");
1868 void ScFiltersTest::testPasswordOld()
1870 //tests opening a file with old password algorithm
1871 testPassword_Impl(u"passwordOld.");
1874 void ScFiltersTest::testPasswordWrongSHA()
1876 //tests opening a file wrongly using the new password algorithm
1877 //in a sxc with the key algorithm missing
1878 testPassword_Impl(u"passwordWrongSHA.");
1881 void ScFiltersTest::testControlImport()
1883 ScDocShellRef xDocSh = loadDoc(u"singlecontrol.", FORMAT_XLSX);
1884 CPPUNIT_ASSERT_MESSAGE("Failed to load singlecontrol.xlsx", xDocSh.is());
1886 uno::Reference< frame::XModel > xModel = xDocSh->GetModel();
1887 uno::Reference< sheet::XSpreadsheetDocument > xDoc(xModel, UNO_QUERY_THROW);
1888 uno::Reference< container::XIndexAccess > xIA(xDoc->getSheets(), UNO_QUERY_THROW);
1889 uno::Reference< drawing::XDrawPageSupplier > xDrawPageSupplier( xIA->getByIndex(0), UNO_QUERY_THROW);
1890 uno::Reference< container::XIndexAccess > xIA_DrawPage(xDrawPageSupplier->getDrawPage(), UNO_QUERY_THROW);
1891 uno::Reference< drawing::XControlShape > xControlShape(xIA_DrawPage->getByIndex(0), UNO_QUERY_THROW);
1893 xDocSh->DoClose();
1896 void ScFiltersTest::testActiveXOptionButtonGroup()
1898 ScDocShellRef xDocSh = loadDoc(u"tdf111980_radioButtons.", FORMAT_XLSX);
1899 CPPUNIT_ASSERT_MESSAGE("Failed to load tdf111980_radioButtons.xlsx", xDocSh.is());
1900 uno::Reference< frame::XModel > xModel = xDocSh->GetModel();
1901 uno::Reference< sheet::XSpreadsheetDocument > xDoc(xModel, UNO_QUERY_THROW);
1902 uno::Reference< container::XIndexAccess > xIA(xDoc->getSheets(), UNO_QUERY_THROW);
1903 uno::Reference< drawing::XDrawPageSupplier > xDrawPageSupplier( xIA->getByIndex(0), UNO_QUERY_THROW);
1904 uno::Reference< container::XIndexAccess > xIA_DrawPage(xDrawPageSupplier->getDrawPage(), UNO_QUERY_THROW);
1906 OUString sGroupName;
1907 uno::Reference< drawing::XControlShape > xControlShape(xIA_DrawPage->getByIndex(0), UNO_QUERY_THROW);
1908 uno::Reference<beans::XPropertySet> xPropertySet(xControlShape->getControl(), uno::UNO_QUERY_THROW);
1909 xPropertySet->getPropertyValue("GroupName") >>= sGroupName;
1910 CPPUNIT_ASSERT_EQUAL(OUString("Sheet1"), sGroupName);
1912 // Optionbuttons (without Group names) were not grouped.
1913 // The two optionbuttons should have the same auto-generated group name.
1914 OUString sGroupName2; //ActiveX controls
1915 xControlShape.set(xIA_DrawPage->getByIndex(2), uno::UNO_QUERY_THROW);
1916 xPropertySet.set(xControlShape->getControl(), uno::UNO_QUERY_THROW);
1917 xPropertySet->getPropertyValue("GroupName") >>= sGroupName2;
1918 CPPUNIT_ASSERT_EQUAL( false, sGroupName2.isEmpty() );
1920 OUString sGroupName3;
1921 xControlShape.set(xIA_DrawPage->getByIndex(3), uno::UNO_QUERY_THROW);
1922 xPropertySet.set(xControlShape->getControl(), uno::UNO_QUERY_THROW);
1923 xPropertySet->getPropertyValue("GroupName") >>= sGroupName3;
1924 CPPUNIT_ASSERT_EQUAL( sGroupName2, sGroupName3 );
1925 CPPUNIT_ASSERT( sGroupName != sGroupName3 );
1927 OUString sGroupName4; //Form controls
1928 xControlShape.set(xIA_DrawPage->getByIndex(4), uno::UNO_QUERY_THROW);
1929 xPropertySet.set(xControlShape->getControl(), uno::UNO_QUERY_THROW);
1930 xPropertySet->getPropertyValue("GroupName") >>= sGroupName4;
1931 CPPUNIT_ASSERT_EQUAL( false, sGroupName4.isEmpty() );
1933 OUString sGroupName5;
1934 xControlShape.set(xIA_DrawPage->getByIndex(5), uno::UNO_QUERY_THROW);
1935 xPropertySet.set(xControlShape->getControl(), uno::UNO_QUERY_THROW);
1936 xPropertySet->getPropertyValue("GroupName") >>= sGroupName5;
1937 CPPUNIT_ASSERT_EQUAL( sGroupName4, sGroupName5 );
1938 CPPUNIT_ASSERT( sGroupName2 != sGroupName5 );
1939 CPPUNIT_ASSERT( sGroupName != sGroupName5 );
1941 OUString sGroupName7; //Form radiobutton autogrouped by GroupBox
1942 xControlShape.set(xIA_DrawPage->getByIndex(7), uno::UNO_QUERY_THROW);
1943 xPropertySet.set(xControlShape->getControl(), uno::UNO_QUERY_THROW);
1944 xPropertySet->getPropertyValue("GroupName") >>= sGroupName7;
1945 CPPUNIT_ASSERT_EQUAL( OUString("autoGroup_Group Box 7"), sGroupName7 );
1947 OUString sGroupName8;
1948 xControlShape.set(xIA_DrawPage->getByIndex(8), uno::UNO_QUERY_THROW);
1949 xPropertySet.set(xControlShape->getControl(), uno::UNO_QUERY_THROW);
1950 xPropertySet->getPropertyValue("GroupName") >>= sGroupName8;
1951 CPPUNIT_ASSERT_EQUAL( sGroupName7, sGroupName8 );
1952 CPPUNIT_ASSERT( sGroupName4 != sGroupName8 );
1953 CPPUNIT_ASSERT( sGroupName2 != sGroupName8 );
1954 CPPUNIT_ASSERT( sGroupName != sGroupName8 );
1956 OUString sGroupName9; //Form radiobutton not fully inside GroupBox
1957 xControlShape.set(xIA_DrawPage->getByIndex(9), uno::UNO_QUERY_THROW);
1958 xPropertySet.set(xControlShape->getControl(), uno::UNO_QUERY_THROW);
1959 xPropertySet->getPropertyValue("GroupName") >>= sGroupName9;
1960 CPPUNIT_ASSERT_EQUAL( sGroupName4, sGroupName9 );
1962 OUString sGroupName10; //ActiveX unaffected by GroupBox
1963 xControlShape.set(xIA_DrawPage->getByIndex(10), uno::UNO_QUERY_THROW);
1964 xPropertySet.set(xControlShape->getControl(), uno::UNO_QUERY_THROW);
1965 xPropertySet->getPropertyValue("GroupName") >>= sGroupName10;
1966 CPPUNIT_ASSERT_EQUAL( sGroupName, sGroupName10 );
1968 xDocSh->DoClose();
1971 void ScFiltersTest::testChartImportODS()
1973 ScDocShellRef xDocSh = loadDoc(u"chart-import-basic.", FORMAT_ODS);
1974 CPPUNIT_ASSERT_MESSAGE("Failed to load chart-import-basic.ods.", xDocSh.is());
1976 ScDocument& rDoc = xDocSh->GetDocument();
1978 // Ensure that the document contains "Empty", "Chart", "Data" and "Title" sheets in this exact order.
1979 CPPUNIT_ASSERT_EQUAL_MESSAGE(
1980 "There should be 4 sheets in this document.", sal_Int16(4),
1981 rDoc.GetTableCount());
1982 OUString aName;
1983 rDoc.GetName(0, aName);
1984 CPPUNIT_ASSERT_EQUAL(OUString("Empty"), aName);
1985 rDoc.GetName(1, aName);
1986 CPPUNIT_ASSERT_EQUAL(OUString("Chart"), aName);
1987 rDoc.GetName(2, aName);
1988 CPPUNIT_ASSERT_EQUAL(OUString("Data"), aName);
1989 rDoc.GetName(3, aName);
1990 CPPUNIT_ASSERT_EQUAL(OUString("Title"), aName);
1992 // Retrieve the chart object instance from the 2nd page (for the 2nd sheet).
1993 const SdrOle2Obj* pOleObj = getSingleChartObject(rDoc, 1);
1994 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve a chart object from the 2nd sheet.", pOleObj);
1996 ScRangeList aRanges = getChartRanges(rDoc, *pOleObj);
1998 CPPUNIT_ASSERT_MESSAGE("Data series title cell not found.", aRanges.In(ScAddress(1,0,3))); // B1 on Title
1999 CPPUNIT_ASSERT_MESSAGE("Data series label range not found.", aRanges.In(ScRange(0,1,2,0,3,2))); // A2:A4 on Data
2000 CPPUNIT_ASSERT_MESSAGE("Data series value range not found.", aRanges.In(ScRange(1,1,2,1,3,2))); // B2:B4 on Data
2002 xDocSh->DoClose();
2005 #if HAVE_MORE_FONTS
2006 void ScFiltersTest::testChartImportXLS()
2008 ScDocShellRef xDocSh = loadDoc(u"chartx.", FORMAT_XLS);
2009 CPPUNIT_ASSERT_MESSAGE("Failed to load chartx.xls.", xDocSh.is());
2011 ScDocument& rDoc = xDocSh->GetDocument();
2013 // Retrieve the chart object instance from the 2nd page (for the 2nd sheet).
2014 const SdrOle2Obj* pOleObj = getSingleChartObject(rDoc, 0);
2015 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve a chart object from the 2nd sheet.", pOleObj);
2017 CPPUNIT_ASSERT_EQUAL(tools::Long(11137), pOleObj->GetLogicRect().getWidth());
2018 CPPUNIT_ASSERT(8640L > pOleObj->GetLogicRect().getHeight());
2020 xDocSh->DoClose();
2022 #endif
2024 void ScFiltersTest::testNumberFormatHTML()
2026 ScDocShellRef xDocSh = loadDoc(u"numberformat.", FORMAT_HTML);
2027 CPPUNIT_ASSERT_MESSAGE("Failed to load numberformat.html", xDocSh.is());
2029 ScDocument& rDoc = xDocSh->GetDocument();
2031 // Check the header just in case.
2032 CPPUNIT_ASSERT_EQUAL_MESSAGE(
2033 "Cell value is not as expected", OUString("Product"),
2034 rDoc.GetString(0, 0, 0));
2035 CPPUNIT_ASSERT_EQUAL_MESSAGE(
2036 "Cell value is not as expected", OUString("Price"),
2037 rDoc.GetString(1, 0, 0));
2038 CPPUNIT_ASSERT_EQUAL_MESSAGE(
2039 "Cell value is not as expected", OUString("Note"),
2040 rDoc.GetString(2, 0, 0));
2042 // B2 should be imported as a value cell.
2043 bool bHasValue = rDoc.HasValueData(1, 1, 0);
2044 CPPUNIT_ASSERT_MESSAGE("Fail to import number as a value cell.", bHasValue);
2045 CPPUNIT_ASSERT_EQUAL_MESSAGE(
2046 "Incorrect value.", 199.98, rDoc.GetValue(1, 1, 0));
2048 xDocSh->DoClose();
2051 void ScFiltersTest::testNumberFormatCSV()
2053 ScDocShellRef xDocSh = loadDoc(u"numberformat.", FORMAT_CSV);
2054 CPPUNIT_ASSERT_MESSAGE("Failed to load numberformat.csv", xDocSh.is());
2056 ScDocument& rDoc = xDocSh->GetDocument();
2058 // Check the header just in case.
2059 CPPUNIT_ASSERT_EQUAL_MESSAGE(
2060 "Cell value is not as expected", OUString("Product"),
2061 rDoc.GetString(0, 0, 0));
2062 CPPUNIT_ASSERT_EQUAL_MESSAGE(
2063 "Cell value is not as expected", OUString("Price"),
2064 rDoc.GetString(1, 0, 0));
2065 CPPUNIT_ASSERT_EQUAL_MESSAGE(
2066 "Cell value is not as expected", OUString("Note"),
2067 rDoc.GetString(2, 0, 0));
2069 // B2 should be imported as a value cell.
2070 bool bHasValue = rDoc.HasValueData(1, 1, 0);
2071 CPPUNIT_ASSERT_MESSAGE("Fail to import number as a value cell.", bHasValue);
2072 CPPUNIT_ASSERT_EQUAL_MESSAGE(
2073 "Incorrect value.", 199.98, rDoc.GetValue(1, 1, 0));
2075 xDocSh->DoClose();
2078 void ScFiltersTest::testCellAnchoredShapesODS()
2080 ScDocShellRef xDocSh = loadDoc(u"cell-anchored-shapes.", FORMAT_ODS);
2081 CPPUNIT_ASSERT_MESSAGE("Failed to load cell-anchored-shapes.ods", xDocSh.is());
2083 // There are two cell-anchored objects on the first sheet.
2084 ScDocument& rDoc = xDocSh->GetDocument();
2086 CPPUNIT_ASSERT_MESSAGE("There should be at least one sheet.", rDoc.GetTableCount() > 0);
2088 ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer();
2089 SdrPage* pPage = pDrawLayer->GetPage(0);
2090 CPPUNIT_ASSERT_MESSAGE("draw page for sheet 1 should exist.", pPage);
2091 const size_t nCount = pPage->GetObjCount();
2092 CPPUNIT_ASSERT_EQUAL_MESSAGE(
2093 "There should be 2 objects.", static_cast<size_t>(2), nCount);
2094 for (size_t i = 0; i < nCount; ++i)
2096 SdrObject* pObj = pPage->GetObj(i);
2097 CPPUNIT_ASSERT_MESSAGE("Failed to get drawing object.", pObj);
2098 ScDrawObjData* pData = ScDrawLayer::GetObjData(pObj);
2099 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve user data for this object.", pData);
2100 CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pData->getShapeRect().IsEmpty());
2103 xDocSh->DoClose();
2106 void ScFiltersTest::testCellAnchoredHiddenShapesXLSX()
2108 ScDocShellRef xDocSh = loadDoc(u"cell-anchored-hidden-shapes.", FORMAT_XLSX);
2109 CPPUNIT_ASSERT_MESSAGE("Failed to load cell-anchored-shapes.xlsx", xDocSh.is());
2111 // There are two cell-anchored objects on the first sheet.
2112 ScDocument& rDoc = xDocSh->GetDocument();
2114 CPPUNIT_ASSERT_MESSAGE("There should be at least one sheet.", rDoc.GetTableCount() > 0);
2116 ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer();
2117 SdrPage* pPage = pDrawLayer->GetPage(0);
2118 CPPUNIT_ASSERT_MESSAGE("draw page for sheet 1 should exist.", pPage);
2119 const size_t nCount = pPage->GetObjCount();
2120 CPPUNIT_ASSERT_MESSAGE("There should be 2 shapes.", !(nCount == 2));
2122 SdrObject* pObj = pPage->GetObj(1);
2123 CPPUNIT_ASSERT_MESSAGE("Failed to get drawing object.", pObj);
2124 CPPUNIT_ASSERT_MESSAGE("The shape having same twocellanchor from and to attribute values, is visible.", !pObj->IsVisible());
2126 xDocSh->DoClose();
2129 void ScFiltersTest::testRowHeightODS()
2131 ScDocShellRef xDocSh = loadDoc(u"row-height-import.", FORMAT_ODS);
2132 CPPUNIT_ASSERT_MESSAGE("Failed to load row-height-import.ods", xDocSh.is());
2134 SCTAB nTab = 0;
2135 SCROW nRow = 0;
2136 ScDocument& rDoc = xDocSh->GetDocument();
2138 // The first 3 rows have manual heights.
2139 int nHeight = rDoc.GetRowHeight(nRow, nTab, false);
2140 bool bManual = rDoc.IsManualRowHeight(nRow, nTab);
2141 CPPUNIT_ASSERT_EQUAL(600, nHeight);
2142 CPPUNIT_ASSERT_MESSAGE("this row should have a manual row height.", bManual);
2143 nHeight = rDoc.GetRowHeight(++nRow, nTab, false);
2144 bManual = rDoc.IsManualRowHeight(nRow, nTab);
2145 CPPUNIT_ASSERT_EQUAL(1200, nHeight);
2146 CPPUNIT_ASSERT_MESSAGE("this row should have a manual row height.", bManual);
2147 nHeight = rDoc.GetRowHeight(++nRow, nTab, false);
2148 bManual = rDoc.IsManualRowHeight(nRow, nTab);
2149 CPPUNIT_ASSERT_EQUAL(1800, nHeight);
2150 CPPUNIT_ASSERT_MESSAGE("this row should have a manual row height.", bManual);
2152 // This one should have an automatic row height.
2153 bManual = rDoc.IsManualRowHeight(++nRow, nTab);
2154 CPPUNIT_ASSERT_MESSAGE("Row should have an automatic height.", !bManual);
2156 // Followed by a row with manual height.
2157 nHeight = rDoc.GetRowHeight(++nRow, nTab, false);
2158 bManual = rDoc.IsManualRowHeight(nRow, nTab);
2159 CPPUNIT_ASSERT_EQUAL(2400, nHeight);
2160 CPPUNIT_ASSERT_MESSAGE("this row should have a manual row height.", bManual);
2162 // And all the rest should have automatic heights.
2163 bManual = rDoc.IsManualRowHeight(++nRow, nTab);
2164 CPPUNIT_ASSERT_MESSAGE("Row should have an automatic height.", !bManual);
2166 bManual = rDoc.IsManualRowHeight(MAXROW, nTab);
2167 CPPUNIT_ASSERT_MESSAGE("Row should have an automatic height.", !bManual);
2169 xDocSh->DoClose();
2172 void ScFiltersTest::testRichTextContentODS()
2174 ScDocShellRef xDocSh = loadDoc(u"rich-text-cells.", FORMAT_ODS);
2175 CPPUNIT_ASSERT_MESSAGE("Failed to load rich-text-cells.ods", xDocSh.is());
2176 ScDocument& rDoc = xDocSh->GetDocument();
2178 OUString aTabName;
2179 CPPUNIT_ASSERT_MESSAGE("Failed to get the name of the first sheet.", rDoc.GetName(0, aTabName));
2181 // All tested cells are in the first column.
2182 ScAddress aPos(0, 0, 0);
2184 // Normal simple string with no formatting.
2185 aPos.IncRow();
2186 CPPUNIT_ASSERT_EQUAL(CELLTYPE_STRING, rDoc.GetCellType(aPos));
2187 CPPUNIT_ASSERT_EQUAL(OUString("Normal"), rDoc.GetString(aPos.Col(), aPos.Row(), aPos.Tab()));
2189 // Normal string with bold applied to the whole cell.
2191 aPos.IncRow();
2192 CPPUNIT_ASSERT_EQUAL(CELLTYPE_STRING, rDoc.GetCellType(aPos));
2193 CPPUNIT_ASSERT_EQUAL(OUString("All bold"), rDoc.GetString(aPos.Col(), aPos.Row(), aPos.Tab()));
2194 const ScPatternAttr* pAttr = rDoc.GetPattern(aPos.Col(), aPos.Row(), aPos.Tab());
2195 CPPUNIT_ASSERT_MESSAGE("Failed to get cell attribute.", pAttr);
2196 const SvxWeightItem& rWeightItem = pAttr->GetItem(ATTR_FONT_WEIGHT);
2197 CPPUNIT_ASSERT_EQUAL(WEIGHT_BOLD, rWeightItem.GetWeight());
2200 // This cell has an unformatted but multi-line content. Multi-line text is
2201 // stored in edit cell even if it has no formatting applied.
2202 aPos.IncRow();
2203 CPPUNIT_ASSERT_EQUAL(CELLTYPE_EDIT, rDoc.GetCellType(aPos));
2204 const EditTextObject* pEditText = rDoc.GetEditText(aPos);
2205 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
2206 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(3), pEditText->GetParagraphCount());
2207 OUString aParaText = pEditText->GetText(0);
2208 CPPUNIT_ASSERT_EQUAL(OUString("one"), aParaText);
2209 aParaText = pEditText->GetText(1);
2210 CPPUNIT_ASSERT_EQUAL(OUString("two"), aParaText);
2211 aParaText = pEditText->GetText(2);
2212 CPPUNIT_ASSERT_EQUAL(OUString("three"), aParaText);
2214 // Cell with sheet name field item.
2215 aPos.IncRow();
2216 CPPUNIT_ASSERT_EQUAL(CELLTYPE_EDIT, rDoc.GetCellType(aPos));
2217 pEditText = rDoc.GetEditText(aPos);
2218 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
2219 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), pEditText->GetParagraphCount());
2220 aParaText = pEditText->GetText(0);
2221 CPPUNIT_ASSERT_MESSAGE("Unexpected text.", aParaText.startsWith("Sheet name is "));
2222 CPPUNIT_ASSERT_MESSAGE("Sheet name field item not found.", pEditText->HasField(text::textfield::Type::TABLE));
2223 CPPUNIT_ASSERT_EQUAL(OUString("Sheet name is Test."), ScEditUtil::GetString(*pEditText, &rDoc));
2224 CPPUNIT_ASSERT_EQUAL(OUString("Sheet name is ?."), ScEditUtil::GetString(*pEditText, nullptr));
2226 // Cell with URL field item.
2227 aPos.IncRow();
2228 CPPUNIT_ASSERT_EQUAL(CELLTYPE_EDIT, rDoc.GetCellType(aPos));
2229 pEditText = rDoc.GetEditText(aPos);
2230 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
2231 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), pEditText->GetParagraphCount());
2232 aParaText = pEditText->GetText(0);
2233 CPPUNIT_ASSERT_MESSAGE("Unexpected text.", aParaText.startsWith("URL: "));
2234 CPPUNIT_ASSERT_MESSAGE("URL field item not found.", pEditText->HasField(text::textfield::Type::URL));
2235 CPPUNIT_ASSERT_EQUAL(OUString("URL: http://libreoffice.org"), ScEditUtil::GetString(*pEditText, &rDoc));
2236 CPPUNIT_ASSERT_EQUAL(OUString("URL: http://libreoffice.org"), ScEditUtil::GetString(*pEditText, nullptr));
2238 // Cell with Date field item.
2239 aPos.IncRow();
2240 CPPUNIT_ASSERT_EQUAL(CELLTYPE_EDIT, rDoc.GetCellType(aPos));
2241 pEditText = rDoc.GetEditText(aPos);
2242 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
2243 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), pEditText->GetParagraphCount());
2244 aParaText = pEditText->GetText(0);
2245 CPPUNIT_ASSERT_MESSAGE("Unexpected text.", aParaText.startsWith("Date: "));
2246 CPPUNIT_ASSERT_MESSAGE("Date field item not found.", pEditText->HasField(text::textfield::Type::DATE));
2247 CPPUNIT_ASSERT_MESSAGE("Date field not resolved with rDoc.", ScEditUtil::GetString(*pEditText, &rDoc).indexOf("/20") > 0);
2248 CPPUNIT_ASSERT_MESSAGE("Date field not resolved with NULL.", ScEditUtil::GetString(*pEditText, nullptr).indexOf("/20") > 0);
2250 // Cell with DocInfo title field item.
2251 aPos.IncRow();
2252 CPPUNIT_ASSERT_EQUAL(CELLTYPE_EDIT, rDoc.GetCellType(aPos));
2253 pEditText = rDoc.GetEditText(aPos);
2254 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
2255 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), pEditText->GetParagraphCount());
2256 aParaText = pEditText->GetText(0);
2257 CPPUNIT_ASSERT_MESSAGE("Unexpected text.", aParaText.startsWith("Title: "));
2258 CPPUNIT_ASSERT_MESSAGE("DocInfo title field item not found.", pEditText->HasField(text::textfield::Type::DOCINFO_TITLE));
2259 CPPUNIT_ASSERT_EQUAL(OUString("Title: Test Document"), ScEditUtil::GetString(*pEditText, &rDoc));
2260 CPPUNIT_ASSERT_EQUAL(OUString("Title: ?"), ScEditUtil::GetString(*pEditText, nullptr));
2262 // Cell with sentence with both bold and italic sequences.
2263 aPos.IncRow();
2264 CPPUNIT_ASSERT_EQUAL(CELLTYPE_EDIT, rDoc.GetCellType(aPos));
2265 pEditText = rDoc.GetEditText(aPos);
2266 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
2267 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), pEditText->GetParagraphCount());
2268 aParaText = pEditText->GetText(0);
2269 CPPUNIT_ASSERT_EQUAL(OUString("Sentence with bold and italic."), aParaText);
2270 std::vector<EECharAttrib> aAttribs;
2271 pEditText->GetCharAttribs(0, aAttribs);
2273 bool bHasBold = false, bHasItalic = false;
2274 for (const auto& rAttrib : aAttribs)
2276 OUString aSeg = aParaText.copy(rAttrib.nStart, rAttrib.nEnd - rAttrib.nStart);
2277 const SfxPoolItem* pAttr = rAttrib.pAttr;
2278 if (aSeg == "bold" && pAttr->Which() == EE_CHAR_WEIGHT && !bHasBold)
2280 const SvxWeightItem& rItem = static_cast<const SvxWeightItem&>(*pAttr);
2281 bHasBold = (rItem.GetWeight() == WEIGHT_BOLD);
2283 else if (aSeg == "italic" && pAttr->Which() == EE_CHAR_ITALIC && !bHasItalic)
2285 const SvxPostureItem& rItem = static_cast<const SvxPostureItem&>(*pAttr);
2286 bHasItalic = (rItem.GetPosture() == ITALIC_NORMAL);
2289 CPPUNIT_ASSERT_MESSAGE("This sentence is expected to have both bold and italic sequences.", bHasBold);
2290 CPPUNIT_ASSERT_MESSAGE("This sentence is expected to have both bold and italic sequences.", bHasItalic);
2293 // Cell with multi-line content with formatting applied.
2294 aPos.IncRow();
2295 CPPUNIT_ASSERT_EQUAL(CELLTYPE_EDIT, rDoc.GetCellType(aPos));
2296 pEditText = rDoc.GetEditText(aPos);
2297 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
2298 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(3), pEditText->GetParagraphCount());
2299 aParaText = pEditText->GetText(0);
2300 CPPUNIT_ASSERT_EQUAL(OUString("bold"), aParaText);
2301 aParaText = pEditText->GetText(1);
2302 CPPUNIT_ASSERT_EQUAL(OUString("italic"), aParaText);
2303 aParaText = pEditText->GetText(2);
2304 CPPUNIT_ASSERT_EQUAL(OUString("underlined"), aParaText);
2306 // first line is bold.
2307 pEditText->GetCharAttribs(0, aAttribs);
2309 bool bHasBold = std::any_of(aAttribs.begin(), aAttribs.end(), [](const EECharAttrib& rAttrib) {
2310 return rAttrib.pAttr->Which() == EE_CHAR_WEIGHT &&
2311 static_cast<const SvxWeightItem&>(*rAttrib.pAttr).GetWeight() == WEIGHT_BOLD; });
2312 CPPUNIT_ASSERT_MESSAGE("First line should be bold.", bHasBold);
2315 // second line is italic.
2316 pEditText->GetCharAttribs(1, aAttribs);
2317 bool bHasItalic = std::any_of(aAttribs.begin(), aAttribs.end(), [](const EECharAttrib& rAttrib) {
2318 return rAttrib.pAttr->Which() == EE_CHAR_ITALIC &&
2319 static_cast<const SvxPostureItem&>(*rAttrib.pAttr).GetPosture() == ITALIC_NORMAL; });
2320 CPPUNIT_ASSERT_MESSAGE("Second line should be italic.", bHasItalic);
2322 // third line is underlined.
2323 pEditText->GetCharAttribs(2, aAttribs);
2324 bool bHasUnderline = std::any_of(aAttribs.begin(), aAttribs.end(), [](const EECharAttrib& rAttrib) {
2325 return rAttrib.pAttr->Which() == EE_CHAR_UNDERLINE &&
2326 static_cast<const SvxUnderlineItem&>(*rAttrib.pAttr).GetLineStyle() == LINESTYLE_SINGLE; });
2327 CPPUNIT_ASSERT_MESSAGE("Second line should be underlined.", bHasUnderline);
2329 // URL with formats applied. For now, we'll check whether or not the
2330 // field objects gets imported. Later we should add checks for the
2331 // formats.
2332 aPos.IncRow();
2333 pEditText = rDoc.GetEditText(aPos);
2334 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
2335 CPPUNIT_ASSERT_MESSAGE("URL field item not found.", pEditText->HasField(text::textfield::Type::URL));
2337 // Sheet name with formats applied.
2338 aPos.IncRow();
2339 pEditText = rDoc.GetEditText(aPos);
2340 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
2341 CPPUNIT_ASSERT_MESSAGE("Sheet name field item not found.", pEditText->HasField(text::textfield::Type::TABLE));
2343 // Date with formats applied.
2344 aPos.IncRow();
2345 pEditText = rDoc.GetEditText(aPos);
2346 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
2347 CPPUNIT_ASSERT_MESSAGE("Date field item not found.", pEditText->HasField(text::textfield::Type::DATE));
2349 // Document title with formats applied.
2350 aPos.IncRow();
2351 pEditText = rDoc.GetEditText(aPos);
2352 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
2353 CPPUNIT_ASSERT_MESSAGE("Date field item not found.", pEditText->HasField(text::textfield::Type::DOCINFO_TITLE));
2355 // URL for a file in the same directory. It should be converted into an absolute URL on import.
2356 aPos.IncRow();
2357 pEditText = rDoc.GetEditText(aPos);
2358 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
2359 const SvxFieldData* pData = pEditText->GetFieldData(0, 0, text::textfield::Type::URL);
2360 CPPUNIT_ASSERT_MESSAGE("Failed to get the URL data.", pData);
2361 CPPUNIT_ASSERT_EQUAL_MESSAGE("Failed to get the URL data.", text::textfield::Type::URL, pData->GetClassId());
2362 const SvxURLField* pURLData = static_cast<const SvxURLField*>(pData);
2363 CPPUNIT_ASSERT_MESSAGE("URL is not absolute with respect to the file system.", pURLData->GetURL().startsWith("file:///"));
2365 // Embedded spaces as <text:s text:c='4' />, normal text
2366 aPos.IncRow();
2367 CPPUNIT_ASSERT_EQUAL(CELLTYPE_STRING, rDoc.GetCellType(aPos));
2368 CPPUNIT_ASSERT_EQUAL(OUString("one two"), rDoc.GetString(aPos.Col(), aPos.Row(), aPos.Tab()));
2370 // Leading space as <text:s />.
2371 aPos.IncRow();
2372 CPPUNIT_ASSERT_EQUAL(CELLTYPE_STRING, rDoc.GetCellType(aPos));
2373 CPPUNIT_ASSERT_EQUAL(OUString(" =3+4"), rDoc.GetString(aPos.Col(), aPos.Row(), aPos.Tab()));
2375 // Embedded spaces with <text:s text:c='4' /> inside a <text:span>, text
2376 // partly bold.
2377 aPos.IncRow();
2378 CPPUNIT_ASSERT_EQUAL(CELLTYPE_EDIT, rDoc.GetCellType(aPos));
2379 pEditText = rDoc.GetEditText(aPos);
2380 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
2381 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), pEditText->GetParagraphCount());
2382 aParaText = pEditText->GetText(0);
2383 CPPUNIT_ASSERT_EQUAL(OUString("one two"), aParaText);
2384 pEditText->GetCharAttribs(0, aAttribs);
2386 auto it = std::find_if(aAttribs.begin(), aAttribs.end(), [](const EECharAttrib& rAttrib) {
2387 return rAttrib.pAttr->Which() == EE_CHAR_WEIGHT &&
2388 static_cast<const SvxWeightItem&>(*rAttrib.pAttr).GetWeight() == WEIGHT_BOLD; });
2389 bool bHasBold = (it != aAttribs.end());
2390 if (bHasBold)
2392 OUString aSeg = aParaText.copy(it->nStart, it->nEnd - it->nStart);
2393 CPPUNIT_ASSERT_EQUAL(OUString("e t"), aSeg);
2395 CPPUNIT_ASSERT_MESSAGE("Expected a bold sequence.", bHasBold);
2398 xDocSh->DoClose();
2401 void ScFiltersTest::testDataBarODS()
2403 ScDocShellRef xDocSh = loadDoc(u"databar.", FORMAT_ODS);
2404 CPPUNIT_ASSERT(xDocSh.is());
2406 ScDocument& rDoc = xDocSh->GetDocument();
2407 testDataBar_Impl(rDoc);
2409 xDocSh->DoClose();
2412 void ScFiltersTest::testDataBarXLSX()
2414 ScDocShellRef xDocSh = loadDoc(u"databar.", FORMAT_XLSX);
2415 CPPUNIT_ASSERT(xDocSh.is());
2417 ScDocument& rDoc = xDocSh->GetDocument();
2418 testDataBar_Impl(rDoc);
2420 xDocSh->DoClose();
2423 void ScFiltersTest::testColorScaleODS()
2425 ScDocShellRef xDocSh = loadDoc(u"colorscale.", FORMAT_ODS);
2426 CPPUNIT_ASSERT(xDocSh.is());
2427 ScDocument& rDoc = xDocSh->GetDocument();
2429 testColorScale2Entry_Impl(rDoc);
2430 testColorScale3Entry_Impl(rDoc);
2432 xDocSh->DoClose();
2435 void ScFiltersTest::testColorScaleXLSX()
2437 ScDocShellRef xDocSh = loadDoc(u"colorscale.", FORMAT_XLSX);
2438 CPPUNIT_ASSERT(xDocSh.is());
2439 ScDocument& rDoc = xDocSh->GetDocument();
2441 testColorScale2Entry_Impl(rDoc);
2442 testColorScale3Entry_Impl(rDoc);
2444 xDocSh->DoClose();
2447 void ScFiltersTest::testNewCondFormatODS()
2449 ScDocShellRef xDocSh = ScBootstrapFixture::loadDoc(u"new_cond_format_test.", FORMAT_ODS);
2451 CPPUNIT_ASSERT_MESSAGE("Failed to load new_cond_format_test.ods", xDocSh.is());
2453 ScDocument& rDoc = xDocSh->GetDocument();
2455 OUString aCSVPath;
2456 createCSVPath( "new_cond_format_test.", aCSVPath );
2457 testCondFile(aCSVPath, &rDoc, 0);
2459 xDocSh->DoClose();
2462 void ScFiltersTest::testNewCondFormatXLSX()
2464 ScDocShellRef xDocSh = ScBootstrapFixture::loadDoc(u"new_cond_format_test.", FORMAT_XLSX);
2466 CPPUNIT_ASSERT_MESSAGE("Failed to load new_cond_format_test.xlsx", xDocSh.is());
2468 ScDocument& rDoc = xDocSh->GetDocument();
2470 OUString aCSVPath;
2471 createCSVPath( "new_cond_format_test.", aCSVPath );
2472 testCondFile(aCSVPath, &rDoc, 0);
2474 xDocSh->DoClose();
2477 void ScFiltersTest::testCondFormatImportCellIs()
2479 ScDocShellRef xDocSh = ScBootstrapFixture::loadDoc(u"condFormat_cellis.", FORMAT_XLSX);
2480 CPPUNIT_ASSERT_MESSAGE("Failed to load condFormat_cellis.xlsx", xDocSh.is());
2482 ScDocument& rDoc = xDocSh->GetDocument();
2483 CPPUNIT_ASSERT_EQUAL(size_t(1), rDoc.GetCondFormList(0)->size());
2485 ScConditionalFormat* pFormat = rDoc.GetCondFormat(0, 0, 0);
2486 CPPUNIT_ASSERT(pFormat);
2488 const ScFormatEntry* pEntry = pFormat->GetEntry(0);
2489 CPPUNIT_ASSERT(pEntry);
2490 CPPUNIT_ASSERT_EQUAL(ScFormatEntry::Type::ExtCondition, pEntry->GetType());
2492 const ScCondFormatEntry* pCondition = static_cast<const ScCondFormatEntry*>(pEntry);
2493 CPPUNIT_ASSERT_EQUAL( ScConditionMode::Equal, pCondition->GetOperation());
2495 OUString aStr = pCondition->GetExpression(ScAddress(0, 0, 0), 0);
2496 CPPUNIT_ASSERT_EQUAL( OUString("$Sheet2.$A$2"), aStr );
2498 pEntry = pFormat->GetEntry(1);
2499 CPPUNIT_ASSERT(pEntry);
2500 CPPUNIT_ASSERT_EQUAL(ScFormatEntry::Type::ExtCondition, pEntry->GetType());
2502 pCondition = static_cast<const ScCondFormatEntry*>(pEntry);
2503 CPPUNIT_ASSERT_EQUAL( ScConditionMode::Equal, pCondition->GetOperation());
2505 aStr = pCondition->GetExpression(ScAddress(0, 0, 0), 0);
2506 CPPUNIT_ASSERT_EQUAL( OUString("$Sheet2.$A$1"), aStr );
2508 xDocSh->DoClose();
2511 void ScFiltersTest::testCondFormatThemeColorXLSX()
2513 ScDocShellRef xDocSh = ScBootstrapFixture::loadDoc(u"condformat_theme_color.", FORMAT_XLSX);
2515 CPPUNIT_ASSERT_MESSAGE("Failed to load condformat_theme_color.xlsx", xDocSh.is());
2517 ScDocument& rDoc = xDocSh->GetDocument();
2518 ScConditionalFormat* pFormat = rDoc.GetCondFormat(0, 0, 0);
2519 const ScFormatEntry* pEntry = pFormat->GetEntry(0);
2520 CPPUNIT_ASSERT(pEntry);
2521 CPPUNIT_ASSERT_EQUAL(ScFormatEntry::Type::Databar, pEntry->GetType());
2522 const ScDataBarFormat* pDataBar = static_cast<const ScDataBarFormat*>(pEntry);
2523 const ScDataBarFormatData* pDataBarFormatData = pDataBar->GetDataBarData();
2525 CPPUNIT_ASSERT_EQUAL(Color(157, 195, 230), pDataBarFormatData->maPositiveColor);
2526 CPPUNIT_ASSERT(pDataBarFormatData->mxNegativeColor);
2527 CPPUNIT_ASSERT_EQUAL(COL_LIGHTRED, *pDataBarFormatData->mxNegativeColor);
2529 CPPUNIT_ASSERT_EQUAL(size_t(1), rDoc.GetCondFormList(1)->size());
2530 pFormat = rDoc.GetCondFormat(0, 0, 1);
2531 CPPUNIT_ASSERT(pFormat);
2532 CPPUNIT_ASSERT_EQUAL(size_t(1), pFormat->size());
2533 pEntry = pFormat->GetEntry(0);
2534 CPPUNIT_ASSERT(pEntry);
2535 CPPUNIT_ASSERT_EQUAL(ScFormatEntry::Type::Colorscale, pEntry->GetType());
2536 const ScColorScaleFormat* pColorScale = static_cast<const ScColorScaleFormat*>(pEntry);
2537 CPPUNIT_ASSERT_EQUAL(size_t(2), pColorScale->size());
2538 const ScColorScaleEntry* pColorScaleEntry = pColorScale->GetEntry(0);
2539 CPPUNIT_ASSERT(pColorScaleEntry);
2540 CPPUNIT_ASSERT_EQUAL(Color(255, 230, 153), pColorScaleEntry->GetColor());
2542 pColorScaleEntry = pColorScale->GetEntry(1);
2543 CPPUNIT_ASSERT(pColorScaleEntry);
2544 CPPUNIT_ASSERT_EQUAL(Color(157, 195, 230), pColorScaleEntry->GetColor());
2546 xDocSh->DoClose();
2549 void ScFiltersTest::testCondFormatThemeColor2XLSX()
2551 ScDocShellRef xDocSh = ScBootstrapFixture::loadDoc(u"cond_format_theme_color2.", FORMAT_XLSX);
2553 CPPUNIT_ASSERT_MESSAGE("Failed to load cond_format_theme_color2.xlsx", xDocSh.is());
2555 ScDocument& rDoc = xDocSh->GetDocument();
2556 ScConditionalFormat* pFormat = rDoc.GetCondFormat(5, 5, 0);
2557 CPPUNIT_ASSERT(pFormat);
2558 const ScFormatEntry* pEntry = pFormat->GetEntry(0);
2559 CPPUNIT_ASSERT(pEntry);
2560 CPPUNIT_ASSERT_EQUAL(ScFormatEntry::Type::Databar, pEntry->GetType());
2561 const ScDataBarFormat* pDataBar = static_cast<const ScDataBarFormat*>(pEntry);
2562 const ScDataBarFormatData* pDataBarFormatData = pDataBar->GetDataBarData();
2564 CPPUNIT_ASSERT_EQUAL(Color(99, 142, 198), pDataBarFormatData->maPositiveColor);
2565 CPPUNIT_ASSERT(pDataBarFormatData->mxNegativeColor);
2566 CPPUNIT_ASSERT_EQUAL(Color(217, 217, 217), *pDataBarFormatData->mxNegativeColor);
2567 CPPUNIT_ASSERT_EQUAL(Color(197, 90, 17), pDataBarFormatData->maAxisColor);
2569 xDocSh->DoClose();
2572 namespace {
2574 void checkDatabarPositiveColor(const ScConditionalFormat* pFormat, const Color& rColor)
2576 CPPUNIT_ASSERT(pFormat);
2577 const ScFormatEntry* pEntry = pFormat->GetEntry(0);
2578 CPPUNIT_ASSERT(pEntry);
2579 CPPUNIT_ASSERT_EQUAL(ScFormatEntry::Type::Databar, pEntry->GetType());
2580 const ScDataBarFormat* pDataBar = static_cast<const ScDataBarFormat*>(pEntry);
2581 const ScDataBarFormatData* pDataBarFormatData = pDataBar->GetDataBarData();
2583 CPPUNIT_ASSERT_EQUAL(rColor, pDataBarFormatData->maPositiveColor);
2588 void ScFiltersTest::testCondFormatThemeColor3XLSX()
2590 ScDocShellRef xDocSh = ScBootstrapFixture::loadDoc(u"cond_format_theme_color3.", FORMAT_XLSX);
2592 CPPUNIT_ASSERT_MESSAGE("Failed to load document", xDocSh.is());
2594 ScDocument& rDoc = xDocSh->GetDocument();
2595 ScConditionalFormat* pFormat = rDoc.GetCondFormat(1, 3, 0);
2596 CPPUNIT_ASSERT(pFormat);
2597 const ScFormatEntry* pEntry = pFormat->GetEntry(0);
2598 CPPUNIT_ASSERT(pEntry);
2599 CPPUNIT_ASSERT_EQUAL(ScFormatEntry::Type::Colorscale, pEntry->GetType());
2600 const ScColorScaleFormat* pColorScale = static_cast<const ScColorScaleFormat*>(pEntry);
2602 CPPUNIT_ASSERT_EQUAL(size_t(2), pColorScale->size());
2603 const ScColorScaleEntry* pColorScaleEntry = pColorScale->GetEntry(0);
2604 CPPUNIT_ASSERT(pColorScaleEntry);
2605 CPPUNIT_ASSERT_EQUAL(Color(175, 171, 171), pColorScaleEntry->GetColor());
2607 pColorScaleEntry = pColorScale->GetEntry(1);
2608 CPPUNIT_ASSERT(pColorScaleEntry);
2609 CPPUNIT_ASSERT_EQUAL(Color(51, 63, 80), pColorScaleEntry->GetColor());
2611 pFormat = rDoc.GetCondFormat(3, 3, 0);
2612 checkDatabarPositiveColor(pFormat, Color(59, 56, 56));
2614 pFormat = rDoc.GetCondFormat(5, 3, 0);
2615 checkDatabarPositiveColor(pFormat, Color(173, 185, 202));
2617 pFormat = rDoc.GetCondFormat(7, 3, 0);
2618 checkDatabarPositiveColor(pFormat, Color(89, 89, 89));
2620 pFormat = rDoc.GetCondFormat(9, 3, 0);
2621 checkDatabarPositiveColor(pFormat, Color(217, 217, 217));
2623 xDocSh->DoClose();
2626 namespace {
2628 void testComplexIconSetsXLSX_Impl(const ScDocument& rDoc, SCCOL nCol, ScIconSetType eType)
2630 ScConditionalFormat* pFormat = rDoc.GetCondFormat(nCol, 1, 0);
2631 CPPUNIT_ASSERT(pFormat);
2632 CPPUNIT_ASSERT_EQUAL(size_t(1), pFormat->size());
2633 const ScFormatEntry* pEntry = pFormat->GetEntry(0);
2634 CPPUNIT_ASSERT(pEntry);
2635 CPPUNIT_ASSERT_EQUAL(ScFormatEntry::Type::Iconset, pEntry->GetType());
2636 const ScIconSetFormat* pIconSet = static_cast<const ScIconSetFormat*>(pEntry);
2637 CPPUNIT_ASSERT_EQUAL(eType, pIconSet->GetIconSetData()->eIconSetType);
2640 void testCustomIconSetsXLSX_Impl(const ScDocument& rDoc, SCCOL nCol, SCROW nRow, ScIconSetType eType, sal_Int32 nIndex)
2642 ScConditionalFormat* pFormat = rDoc.GetCondFormat(nCol, 1, 1);
2643 CPPUNIT_ASSERT(pFormat);
2644 CPPUNIT_ASSERT_EQUAL(size_t(1), pFormat->size());
2645 const ScFormatEntry* pEntry = pFormat->GetEntry(0);
2646 CPPUNIT_ASSERT(pEntry);
2647 CPPUNIT_ASSERT_EQUAL(ScFormatEntry::Type::Iconset, pEntry->GetType());
2648 const ScIconSetFormat* pIconSet = static_cast<const ScIconSetFormat*>(pEntry);
2649 std::unique_ptr<ScIconSetInfo> pInfo(pIconSet->GetIconSetInfo(ScAddress(nCol, nRow, 1)));
2650 if (nIndex == -1)
2651 CPPUNIT_ASSERT(!pInfo);
2652 else
2654 CPPUNIT_ASSERT(pInfo);
2655 CPPUNIT_ASSERT_EQUAL(nIndex, pInfo->nIconIndex);
2656 CPPUNIT_ASSERT_EQUAL(eType, pInfo->eIconSetType);
2662 void ScFiltersTest::testComplexIconSetsXLSX()
2664 ScDocShellRef xDocSh = ScBootstrapFixture::loadDoc(u"complex_icon_set.", FORMAT_XLSX);
2666 CPPUNIT_ASSERT_MESSAGE("Failed to load complex_icon_set.xlsx", xDocSh.is());
2668 ScDocument& rDoc = xDocSh->GetDocument();
2669 CPPUNIT_ASSERT_EQUAL(size_t(3), rDoc.GetCondFormList(0)->size());
2670 testComplexIconSetsXLSX_Impl(rDoc, 1, IconSet_3Triangles);
2671 testComplexIconSetsXLSX_Impl(rDoc, 3, IconSet_3Stars);
2672 testComplexIconSetsXLSX_Impl(rDoc, 5, IconSet_5Boxes);
2674 CPPUNIT_ASSERT_EQUAL(size_t(2), rDoc.GetCondFormList(1)->size());
2675 testCustomIconSetsXLSX_Impl(rDoc, 1, 1, IconSet_3ArrowsGray, 0);
2676 testCustomIconSetsXLSX_Impl(rDoc, 1, 2, IconSet_3ArrowsGray, -1);
2677 testCustomIconSetsXLSX_Impl(rDoc, 1, 3, IconSet_3Arrows, 1);
2678 testCustomIconSetsXLSX_Impl(rDoc, 1, 4, IconSet_3ArrowsGray, -1);
2679 testCustomIconSetsXLSX_Impl(rDoc, 1, 5, IconSet_3Arrows, 2);
2681 testCustomIconSetsXLSX_Impl(rDoc, 3, 1, IconSet_4RedToBlack, 3);
2682 testCustomIconSetsXLSX_Impl(rDoc, 3, 2, IconSet_3TrafficLights1, 1);
2683 testCustomIconSetsXLSX_Impl(rDoc, 3, 3, IconSet_3Arrows, 2);
2685 xDocSh->DoClose();
2688 void ScFiltersTest::testTdf101104()
2690 ScDocShellRef xDocSh = ScBootstrapFixture::loadDoc(u"tdf101104.", FORMAT_ODS);
2692 CPPUNIT_ASSERT_MESSAGE("Failed to load tdf101104.ods", xDocSh.is());
2694 ScDocument& rDoc = xDocSh->GetDocument();
2695 CPPUNIT_ASSERT_EQUAL(size_t(2), rDoc.GetCondFormList(0)->size());
2697 ScConditionalFormat* pFormat = rDoc.GetCondFormat(1, 1, 0);
2698 CPPUNIT_ASSERT(pFormat);
2699 CPPUNIT_ASSERT_EQUAL(size_t(1), pFormat->size());
2700 const ScFormatEntry* pEntry = pFormat->GetEntry(0);
2701 CPPUNIT_ASSERT(pEntry);
2702 CPPUNIT_ASSERT_EQUAL(ScFormatEntry::Type::Iconset, pEntry->GetType());
2703 const ScIconSetFormat* pIconSet = static_cast<const ScIconSetFormat*>(pEntry);
2705 for(size_t i = 1; i < 10; ++i)
2707 std::unique_ptr<ScIconSetInfo> pInfo(pIconSet->GetIconSetInfo(ScAddress(1, i, 0)));
2709 // Without the fix in place, this test would have failed here
2710 CPPUNIT_ASSERT(pInfo);
2711 CPPUNIT_ASSERT_EQUAL(sal_Int32(2), pInfo->nIconIndex);
2712 CPPUNIT_ASSERT_EQUAL(IconSet_3Arrows, pInfo->eIconSetType);
2716 xDocSh->DoClose();
2719 void ScFiltersTest::testTdf64401()
2721 ScDocShellRef xDocSh = ScBootstrapFixture::loadDoc(u"tdf64401.", FORMAT_ODS);
2723 CPPUNIT_ASSERT_MESSAGE("Failed to load tdf64401.ods", xDocSh.is());
2725 ScDocument& rDoc = xDocSh->GetDocument();
2726 CPPUNIT_ASSERT_EQUAL(size_t(1), rDoc.GetCondFormList(0)->size());
2728 ScConditionalFormat* pFormat = rDoc.GetCondFormat(0, 0, 0);
2729 CPPUNIT_ASSERT(pFormat);
2730 CPPUNIT_ASSERT_EQUAL(size_t(1), pFormat->size());
2731 const ScFormatEntry* pEntry = pFormat->GetEntry(0);
2732 CPPUNIT_ASSERT(pEntry);
2733 CPPUNIT_ASSERT_EQUAL(ScFormatEntry::Type::Iconset, pEntry->GetType());
2734 const ScIconSetFormat* pIconSet = static_cast<const ScIconSetFormat*>(pEntry);
2736 for(size_t i = 0; i < 10; ++i)
2738 sal_Int32 nIndex = 0;
2739 if ( i >= 7 ) // B5 = 8
2740 nIndex = 2;
2741 else if ( i >= 3 ) // B4 = 4
2742 nIndex = 1;
2744 std::unique_ptr<ScIconSetInfo> pInfo(pIconSet->GetIconSetInfo(ScAddress(0, i, 0)));
2745 CPPUNIT_ASSERT(pInfo);
2746 CPPUNIT_ASSERT_EQUAL(nIndex, pInfo->nIconIndex);
2747 CPPUNIT_ASSERT_EQUAL(IconSet_3Arrows, pInfo->eIconSetType);
2751 // Update values in B4 and B5
2752 rDoc.SetValue(ScAddress(1,3,0), 2.0);
2753 rDoc.SetValue(ScAddress(1,4,0), 9.0);
2755 for(size_t i = 0; i < 10; ++i)
2757 sal_Int32 nIndex = 0;
2758 if ( i >= 8 ) // B5 = 9
2759 nIndex = 2;
2760 else if ( i >= 1 ) // B4 = 2
2761 nIndex = 1;
2763 std::unique_ptr<ScIconSetInfo> pInfo(pIconSet->GetIconSetInfo(ScAddress(0, i, 0)));
2764 CPPUNIT_ASSERT(pInfo);
2765 CPPUNIT_ASSERT_EQUAL(nIndex, pInfo->nIconIndex);
2766 CPPUNIT_ASSERT_EQUAL(IconSet_3Arrows, pInfo->eIconSetType);
2770 xDocSh->DoClose();
2773 void ScFiltersTest::testCondFormatParentXLSX()
2775 ScDocShellRef xDocSh = ScBootstrapFixture::loadDoc(u"cond_parent.", FORMAT_XLSX);
2777 CPPUNIT_ASSERT_MESSAGE("Failed to load cond_parent.xlsx", xDocSh.is());
2779 ScDocument& rDoc = xDocSh->GetDocument();
2780 const SfxItemSet* pCondSet = rDoc.GetCondResult(2, 5, 0);
2781 const ScPatternAttr* pPattern = rDoc.GetPattern(2, 5, 0);
2782 const SfxPoolItem& rPoolItem = pPattern->GetItem(ATTR_VER_JUSTIFY, pCondSet);
2783 const SvxVerJustifyItem& rVerJustify = static_cast<const SvxVerJustifyItem&>(rPoolItem);
2784 CPPUNIT_ASSERT_EQUAL(SvxCellVerJustify::Top, rVerJustify.GetValue());
2786 xDocSh->DoClose();
2789 void ScFiltersTest::testColorScaleNumWithRefXLSX()
2791 ScDocShellRef xDocSh = ScBootstrapFixture::loadDoc(u"colorscale_num_with_ref.", FORMAT_XLSX);
2793 CPPUNIT_ASSERT_MESSAGE("Failed to load colorscale_num_with_ref.xlsx", xDocSh.is());
2795 ScDocument& rDoc = xDocSh->GetDocument();
2796 ScConditionalFormatList* pList = rDoc.GetCondFormList(0);
2797 CPPUNIT_ASSERT(pList);
2799 CPPUNIT_ASSERT_EQUAL(size_t(1), pList->size());
2801 ScConditionalFormat* pFormat = pList->begin()->get();
2802 CPPUNIT_ASSERT(pFormat);
2804 CPPUNIT_ASSERT_EQUAL(size_t(1), pFormat->size());
2805 const ScFormatEntry* pEntry = pFormat->GetEntry(0);
2806 CPPUNIT_ASSERT(pEntry);
2808 CPPUNIT_ASSERT_EQUAL(ScFormatEntry::Type::Colorscale, pEntry->GetType());
2810 const ScColorScaleFormat* pColorScale= dynamic_cast<const ScColorScaleFormat*>(pEntry);
2811 CPPUNIT_ASSERT(pColorScale);
2813 const ScColorScaleEntry* pColorScaleEntry = pColorScale->GetEntry(1);
2814 CPPUNIT_ASSERT_EQUAL(OUString("=$A$1"),
2815 pColorScaleEntry->GetFormula(formula::FormulaGrammar::GRAM_NATIVE));
2817 xDocSh->DoClose();
2820 void ScFiltersTest::testOrcusODSStyleInterface()
2822 ScDocument aDoc;
2823 OUString aFullUrl = m_directories.getURLFromSrc(u"sc/qa/unit/data/xml/styles.xml");
2825 /* This loop below trims file:// from the start because orcus doesn't accept such a URL */
2826 OUString aValidPath;
2827 osl::FileBase::getSystemPathFromFileURL(aFullUrl, aValidPath);
2829 ScOrcusFilters* pOrcus = ScFormatFilter::Get().GetOrcusFilters();
2830 CPPUNIT_ASSERT(pOrcus);
2832 pOrcus->importODS_Styles(aDoc, aValidPath);
2833 ScStyleSheetPool* pStyleSheetPool = aDoc.GetStyleSheetPool();
2835 /* Test cases for Style "Name1"
2836 * Has Border and Fill.
2838 ScStyleSheet* pStyleSheet = pStyleSheetPool->FindCaseIns("Name1", SfxStyleFamily::Para);
2839 const SfxPoolItem* pItem = nullptr;
2841 CPPUNIT_ASSERT_MESSAGE("Style Name1 : Doesn't have Attribute background, but it should have.",
2842 pStyleSheet->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem));
2843 const SvxBrushItem* pBackground = static_cast<const SvxBrushItem*>(pItem);
2844 CPPUNIT_ASSERT_EQUAL(Color(254, 255, 204), pBackground->GetColor());
2846 CPPUNIT_ASSERT_MESSAGE("Style Name1 : Doesn't have Attribute border, but it should have.",
2847 pStyleSheet->GetItemSet().HasItem(ATTR_BORDER, &pItem));
2848 const SvxBoxItem* pBoxItem = static_cast<const SvxBoxItem*>(pItem);
2849 CPPUNIT_ASSERT_EQUAL(Color(255, 204, 18), pBoxItem->GetLeft()->GetColor());
2850 CPPUNIT_ASSERT_EQUAL(Color(255, 204, 18), pBoxItem->GetRight()->GetColor());
2851 CPPUNIT_ASSERT_EQUAL(Color(255, 204, 18), pBoxItem->GetTop()->GetColor());
2852 CPPUNIT_ASSERT_EQUAL(Color(255, 204, 18), pBoxItem->GetBottom()->GetColor());
2853 CPPUNIT_ASSERT_EQUAL(SvxBorderLineStyle::DOTTED, pBoxItem->GetLeft()->GetBorderLineStyle());
2854 CPPUNIT_ASSERT_EQUAL(SvxBorderLineStyle::DOTTED, pBoxItem->GetRight()->GetBorderLineStyle());
2855 CPPUNIT_ASSERT_EQUAL(SvxBorderLineStyle::DOTTED, pBoxItem->GetTop()->GetBorderLineStyle());
2856 CPPUNIT_ASSERT_EQUAL(SvxBorderLineStyle::DOTTED, pBoxItem->GetBottom()->GetBorderLineStyle());
2857 ASSERT_DOUBLES_EQUAL_MESSAGE("Error with left width", 1, pBoxItem->GetLeft()->GetWidth());
2858 ASSERT_DOUBLES_EQUAL_MESSAGE("Error with right width", 1, pBoxItem->GetRight()->GetWidth());
2859 ASSERT_DOUBLES_EQUAL_MESSAGE("Error with top width", 1, pBoxItem->GetTop()->GetWidth());
2860 ASSERT_DOUBLES_EQUAL_MESSAGE("Error with bottom width", 1, pBoxItem->GetBottom()->GetWidth());
2862 CPPUNIT_ASSERT_MESSAGE("Style Name1 : Has Attribute Protection, but it shouldn't.",
2863 !pStyleSheet->GetItemSet().HasItem(ATTR_PROTECTION, &pItem));
2864 CPPUNIT_ASSERT_MESSAGE("Style Name1 : Has Attribute font, but it shouldn't.",
2865 !pStyleSheet->GetItemSet().HasItem(ATTR_FONT, &pItem));
2866 CPPUNIT_ASSERT_MESSAGE("Style Name1 : Has Attribute number format, but it shouldn't.",
2867 !pStyleSheet->GetItemSet().HasItem(ATTR_VALUE_FORMAT, &pItem));
2869 /* Test for Style "Name2"
2870 * Has 4 sided borders + Diagonal borders.
2872 pStyleSheet = pStyleSheetPool->FindCaseIns("Name2", SfxStyleFamily::Para);
2874 CPPUNIT_ASSERT_MESSAGE("Style Name2 : Doesn't have Attribute background, but it should have.",
2875 pStyleSheet->GetItemSet().HasItem(ATTR_BORDER, &pItem));
2877 pBoxItem = static_cast<const SvxBoxItem*>(pItem);
2878 CPPUNIT_ASSERT_EQUAL(Color(0, 0, 0), pBoxItem->GetLeft()->GetColor());
2879 CPPUNIT_ASSERT_EQUAL(Color(255, 0, 0), pBoxItem->GetRight()->GetColor());
2880 CPPUNIT_ASSERT_EQUAL(SvxBorderLineStyle::SOLID, pBoxItem->GetLeft()->GetBorderLineStyle());
2881 CPPUNIT_ASSERT_EQUAL(SvxBorderLineStyle::DOTTED, pBoxItem->GetRight()->GetBorderLineStyle());
2882 ASSERT_DOUBLES_EQUAL_MESSAGE("Error with left width", 0, pBoxItem->GetLeft()->GetWidth());
2883 ASSERT_DOUBLES_EQUAL_MESSAGE("Error with right width", 14, pBoxItem->GetRight()->GetWidth());
2885 CPPUNIT_ASSERT_MESSAGE("Style Name2 : Doesn't have Attribute diagonal(tl-br) border, but it should have.",
2886 pStyleSheet->GetItemSet().HasItem(ATTR_BORDER_TLBR, &pItem));
2888 const SvxLineItem* pTLBR= static_cast<const SvxLineItem*>(pItem);
2889 CPPUNIT_ASSERT_EQUAL(Color(18, 0, 0), pTLBR->GetLine()->GetColor());
2890 CPPUNIT_ASSERT_EQUAL(SvxBorderLineStyle::DASH_DOT, pTLBR->GetLine()->GetBorderLineStyle());
2891 ASSERT_DOUBLES_EQUAL_MESSAGE("Error with diagonal tl-br width", 14, pTLBR->GetLine()->GetWidth());
2893 CPPUNIT_ASSERT_MESSAGE("Style Name2 : Doesn't have Attribute diagonal(bl-tr) border, but it should have.",
2894 pStyleSheet->GetItemSet().HasItem(ATTR_BORDER_BLTR, &pItem));
2896 const SvxLineItem* pBLTR= static_cast<const SvxLineItem*>(pItem);
2897 CPPUNIT_ASSERT_EQUAL(Color(255, 204, 238), pBLTR->GetLine()->GetColor());
2898 CPPUNIT_ASSERT_EQUAL(SvxBorderLineStyle::DASHED, pBLTR->GetLine()->GetBorderLineStyle());
2899 ASSERT_DOUBLES_EQUAL_MESSAGE("Error with diagonal tl-br width", 34, pBLTR->GetLine()->GetWidth());
2901 CPPUNIT_ASSERT_MESSAGE("Style Name2 : Has Attribute background, but it shouldn't.",
2902 !pStyleSheet->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem));
2903 CPPUNIT_ASSERT_MESSAGE("Style Name2 : Has Attribute font, but it shouldn't.",
2904 !pStyleSheet->GetItemSet().HasItem(ATTR_FONT, &pItem));
2905 CPPUNIT_ASSERT_MESSAGE("Style Name2 : Has Attribute number format, but it shouldn't.",
2906 !pStyleSheet->GetItemSet().HasItem(ATTR_VALUE_FORMAT, &pItem));
2908 /* Test for Style "Name3"
2909 * Hidden, protected and content is printed.
2911 pStyleSheet = pStyleSheetPool->FindCaseIns("Name3", SfxStyleFamily::Para);
2912 CPPUNIT_ASSERT_MESSAGE("Style Name3 : Doesn't have Attribute Protection, but it should have.",
2913 pStyleSheet->GetItemSet().HasItem(ATTR_PROTECTION, &pItem));
2915 CPPUNIT_ASSERT_MESSAGE("Style Name 3 : Error with Protection attribute." ,bool(ScProtectionAttr(true, false, true, true) == *pItem));
2917 /* Test for Style "Name4"
2918 * Hidden, protected and content is printed.
2920 pStyleSheet = pStyleSheetPool->FindCaseIns("Name4", SfxStyleFamily::Para);
2921 CPPUNIT_ASSERT_MESSAGE("Style Name4 : Doesn't have Attribute Protection, but it should have.",
2922 pStyleSheet->GetItemSet().HasItem(ATTR_PROTECTION, &pItem));
2924 CPPUNIT_ASSERT_MESSAGE("Style Name 4 : Error with Protection attribute." ,bool(ScProtectionAttr(true, true, false, false) == *pItem));
2926 /* Test for Style "Name3"
2927 * Hidden, protected and content is printed.
2929 pStyleSheet = pStyleSheetPool->FindCaseIns("Name5", SfxStyleFamily::Para);
2930 CPPUNIT_ASSERT_MESSAGE("Style Name5 : Doesn't have Attribute Protection, but it should have.",
2931 pStyleSheet->GetItemSet().HasItem(ATTR_PROTECTION, &pItem));
2933 CPPUNIT_ASSERT_MESSAGE("Style Name 5 : Error with Protection attribute." ,bool(ScProtectionAttr(false, false, false, true) == *pItem));
2935 CPPUNIT_ASSERT_MESSAGE("Style Name5 : Has Attribute Border, but it shouldn't.",
2936 !pStyleSheet->GetItemSet().HasItem(ATTR_BORDER, &pItem));
2937 CPPUNIT_ASSERT_MESSAGE("Style Name5: Has Attribute background, but it shouldn't.",
2938 !pStyleSheet->GetItemSet().HasItem(ATTR_BACKGROUND, &pItem));
2939 CPPUNIT_ASSERT_MESSAGE("Style Name5 : Has Attribute font, but it shouldn't.",
2940 !pStyleSheet->GetItemSet().HasItem(ATTR_FONT, &pItem));
2941 CPPUNIT_ASSERT_MESSAGE("Style Name5 : Has Attribute number format, but it shouldn't.",
2942 !pStyleSheet->GetItemSet().HasItem(ATTR_VALUE_FORMAT, &pItem));
2944 /* Test for Style "Name6"
2945 * Has Font name, posture, weight, color, height
2947 pStyleSheet = pStyleSheetPool->FindCaseIns("Name6", SfxStyleFamily::Para);
2948 CPPUNIT_ASSERT_MESSAGE("Style Name6 : Doesn't have Attribute Font, but it should have.",
2949 pStyleSheet->GetItemSet().HasItem(ATTR_FONT, &pItem));
2951 const SvxFontItem* pFontItem= static_cast<const SvxFontItem*>(pItem);
2952 CPPUNIT_ASSERT_EQUAL_MESSAGE("Style Name6 :Error with Font name", OUString("Liberation Sans"), pFontItem->GetStyleName());
2954 CPPUNIT_ASSERT_MESSAGE("Style Name6 : Doesn't have Attribute Font Height, but it should have.",
2955 pStyleSheet->GetItemSet().HasItem(ATTR_FONT_HEIGHT, &pItem));
2957 const SvxFontHeightItem* pFontHeightItem= static_cast<const SvxFontHeightItem*>(pItem);
2958 CPPUNIT_ASSERT_EQUAL_MESSAGE("Style Name6 :Error with Font Height", static_cast<sal_uInt32>(480), pFontHeightItem->GetHeight());
2960 CPPUNIT_ASSERT_MESSAGE("Style Name6 : Doesn't have Attribute Font Posture, but it should have.",
2961 pStyleSheet->GetItemSet().HasItem(ATTR_FONT_POSTURE, &pItem));
2963 const SvxPostureItem* pFontPostureItem= static_cast<const SvxPostureItem*>(pItem);
2964 CPPUNIT_ASSERT_EQUAL_MESSAGE("Style Name6 :Error with Font Posture", ITALIC_NORMAL, pFontPostureItem->GetPosture());
2966 CPPUNIT_ASSERT_MESSAGE("Style Name6 : Doesn't have Attribute Font Weight, but it should have.",
2967 pStyleSheet->GetItemSet().HasItem(ATTR_FONT_WEIGHT, &pItem));
2969 const SvxWeightItem* pFontWeightItem= static_cast<const SvxWeightItem*>(pItem);
2970 CPPUNIT_ASSERT_EQUAL_MESSAGE("Style Name6 :Error with Font Weight", WEIGHT_BOLD, pFontWeightItem->GetWeight());
2972 CPPUNIT_ASSERT_MESSAGE("Style Name6 : Doesn't have Attribute Font Color, but it should have.",
2973 pStyleSheet->GetItemSet().HasItem(ATTR_FONT_COLOR, &pItem));
2975 const SvxColorItem* pFontColorItem= static_cast<const SvxColorItem*>(pItem);
2976 CPPUNIT_ASSERT_EQUAL_MESSAGE("Style Name6 :Error with Font Color", Color(128, 128, 128), pFontColorItem->GetValue());
2978 CPPUNIT_ASSERT_MESSAGE("Style Name6 : Doesn't have Attribute Underline, but it should have.",
2979 pStyleSheet->GetItemSet().HasItem(ATTR_FONT_UNDERLINE, &pItem));
2981 const SvxUnderlineItem* pUnderlineItem= static_cast<const SvxUnderlineItem*>(pItem);
2982 CPPUNIT_ASSERT_EQUAL_MESSAGE("Style Name6 :Error with Font Underline Style", LINESTYLE_SINGLE, pUnderlineItem->GetLineStyle());
2983 CPPUNIT_ASSERT_EQUAL_MESSAGE("Style Name6 :Error with Font Underline Color", Color(128, 128, 128), pUnderlineItem->GetColor());
2985 /* Test for Style Name "7"
2986 * Has strikethrough single
2988 pStyleSheet = pStyleSheetPool->FindCaseIns("Name7", SfxStyleFamily::Para);
2989 CPPUNIT_ASSERT_MESSAGE("Style Name7 : Doesn't have Attribute Strikeout, but it should have.",
2990 pStyleSheet->GetItemSet().HasItem(ATTR_FONT_CROSSEDOUT, &pItem));
2992 const SvxCrossedOutItem* pCrossedOutItem = static_cast<const SvxCrossedOutItem*>(pItem);
2993 CPPUNIT_ASSERT_EQUAL_MESSAGE("Style Name7 :Error with Strikeout", STRIKEOUT_SINGLE, pCrossedOutItem->GetStrikeout());
2995 /* Test for Style Name "8"
2996 * Has strikethrough bold
2998 pStyleSheet = pStyleSheetPool->FindCaseIns("Name8", SfxStyleFamily::Para);
2999 CPPUNIT_ASSERT_MESSAGE("Style Name8 : Doesn't have Attribute Strikeout, but it should have.",
3000 pStyleSheet->GetItemSet().HasItem(ATTR_FONT_CROSSEDOUT, &pItem));
3002 pCrossedOutItem = static_cast<const SvxCrossedOutItem*>(pItem);
3003 CPPUNIT_ASSERT_EQUAL_MESSAGE("Style Name7 :Error with Strikeout", STRIKEOUT_BOLD, pCrossedOutItem->GetStrikeout());
3005 /* Test for Style Name "9"
3006 * Has strikethrough slash
3008 pStyleSheet = pStyleSheetPool->FindCaseIns("Name9", SfxStyleFamily::Para);
3009 CPPUNIT_ASSERT_MESSAGE("Style Name9 : Doesn't have Attribute Strikeout, but it should have.",
3010 pStyleSheet->GetItemSet().HasItem(ATTR_FONT_CROSSEDOUT, &pItem));
3012 pCrossedOutItem = static_cast<const SvxCrossedOutItem*>(pItem);
3013 CPPUNIT_ASSERT_EQUAL_MESSAGE("Style Name9 :Error with Strikeout", STRIKEOUT_SLASH, pCrossedOutItem->GetStrikeout());
3015 /* Test for Style Name "10"
3016 * Has ver align, and hor align
3019 pStyleSheet = pStyleSheetPool->FindCaseIns("Name10", SfxStyleFamily::Para);
3020 CPPUNIT_ASSERT_MESSAGE("Style Name10 : Doesn't have Attribute hor justify, but it should have.",
3021 pStyleSheet->GetItemSet().HasItem(ATTR_HOR_JUSTIFY, &pItem));
3023 const SvxHorJustifyItem* pHorJustify = static_cast<const SvxHorJustifyItem*>(pItem);
3024 CPPUNIT_ASSERT_EQUAL_MESSAGE("Style Name10 :Error with hor justify", SvxCellHorJustify::Right, pHorJustify->GetValue());
3026 pStyleSheet = pStyleSheetPool->FindCaseIns("Name10", SfxStyleFamily::Para);
3027 CPPUNIT_ASSERT_MESSAGE("Style Name10 : Doesn't have Attribute ver justify, but it should have.",
3028 pStyleSheet->GetItemSet().HasItem(ATTR_VER_JUSTIFY, &pItem));
3030 const SvxVerJustifyItem* pVerJustify = static_cast<const SvxVerJustifyItem*>(pItem);
3031 CPPUNIT_ASSERT_EQUAL_MESSAGE("Style Name10 :Error with ver justify", SvxCellVerJustify::Center, pVerJustify->GetValue());
3035 void ScFiltersTest::testLiteralInFormulaXLS()
3037 ScDocShellRef xDocSh = loadDoc(u"shared-string/literal-in-formula.", FORMAT_XLS);
3038 CPPUNIT_ASSERT(xDocSh.is());
3040 ScDocument& rDoc = xDocSh->GetDocument();
3041 rDoc.CalcAll();
3043 CPPUNIT_ASSERT_EQUAL(2.0, rDoc.GetValue(ScAddress(0,0,0)));
3045 xDocSh->DoClose();
3048 void ScFiltersTest::testFormulaDependency()
3050 ScDocShellRef xDocSh = ScBootstrapFixture::loadDoc(u"dependencyTree.", FORMAT_ODS);
3052 ScDocument& rDoc = xDocSh->GetDocument();
3054 // check if formula in A1 changes value
3055 double nVal = rDoc.GetValue(0,0,0);
3056 CPPUNIT_ASSERT_DOUBLES_EQUAL(nVal, 1.0, 1e-10);
3057 rDoc.SetValue(0,1,0, 0.0);
3058 nVal = rDoc.GetValue(0,0,0);
3059 CPPUNIT_ASSERT_DOUBLES_EQUAL(nVal, 2.0, 1e-10);
3061 // check that the number format is implicitly inherited
3062 // CPPUNIT_ASSERT_EQUAL(rDoc.GetString(0,4,0), rDoc.GetString(0,5,0));
3064 xDocSh->DoClose();
3067 void ScFiltersTest::testTdf122643() { testImportCrash(u"tdf122643.", FORMAT_ODS); }
3069 void ScFiltersTest::testTdf132278() { testImportCrash(u"tdf132278.", FORMAT_ODS); }
3071 void ScFiltersTest::testTdf130959() { testImportCrash(u"tdf130959.", FORMAT_XLSX); }
3073 void ScFiltersTest::testTdf129410() { testImportCrash(u"tdf129410.", FORMAT_ODS); }
3075 void ScFiltersTest::testTdf138507() { testImportCrash(u"tdf138507.", FORMAT_ODS); }
3077 void ScFiltersTest::testTdf131380() { testImportCrash(u"tdf131380.", FORMAT_XLSX); }
3079 void ScFiltersTest::testTdf139782() { testImportCrash(u"tdf139782.", FORMAT_ODS); }
3081 void ScFiltersTest::testTdf129681()
3083 ScDocShellRef xDocSh = loadDoc(u"tdf129681.", FORMAT_ODS);
3084 CPPUNIT_ASSERT_MESSAGE("Failed to open doc", xDocSh.is());
3086 ScDocument& rDoc = xDocSh->GetDocument();
3088 CPPUNIT_ASSERT_EQUAL(OUString("Lamb"), rDoc.GetString(ScAddress(4, 2, 0)));
3089 CPPUNIT_ASSERT_EQUAL(OUString("Beef"), rDoc.GetString(ScAddress(4, 3, 0)));
3090 CPPUNIT_ASSERT_EQUAL(OUString("Pork"), rDoc.GetString(ScAddress(4, 4, 0)));
3091 CPPUNIT_ASSERT_EQUAL(OUString("Goat"), rDoc.GetString(ScAddress(4, 5, 0)));
3092 CPPUNIT_ASSERT_EQUAL(OUString("Goat"), rDoc.GetString(ScAddress(4, 6, 0)));
3093 CPPUNIT_ASSERT_EQUAL(OUString("#VALUE!"), rDoc.GetString(ScAddress(4, 7, 0)));
3094 CPPUNIT_ASSERT_EQUAL(OUString("#VALUE!"), rDoc.GetString(ScAddress(4, 8, 0)));
3095 CPPUNIT_ASSERT_EQUAL(OUString("Deer"), rDoc.GetString(ScAddress(4, 9, 0)));
3097 CPPUNIT_ASSERT_EQUAL(OUString("1"), rDoc.GetString(ScAddress(6, 2, 0)));
3098 CPPUNIT_ASSERT_EQUAL(OUString("2"), rDoc.GetString(ScAddress(6, 3, 0)));
3099 CPPUNIT_ASSERT_EQUAL(OUString("3"), rDoc.GetString(ScAddress(6, 4, 0)));
3100 CPPUNIT_ASSERT_EQUAL(OUString("5"), rDoc.GetString(ScAddress(6, 5, 0)));
3101 CPPUNIT_ASSERT_EQUAL(OUString("8"), rDoc.GetString(ScAddress(6, 6, 0)));
3102 CPPUNIT_ASSERT_EQUAL(OUString("#VALUE!"), rDoc.GetString(ScAddress(6, 7, 0)));
3103 CPPUNIT_ASSERT_EQUAL(OUString("#VALUE!"), rDoc.GetString(ScAddress(6, 8, 0)));
3104 CPPUNIT_ASSERT_EQUAL(OUString("#VALUE!"), rDoc.GetString(ScAddress(6, 9, 0)));
3106 xDocSh->DoClose();
3109 void ScFiltersTest::testTdf111974XLSM() { testImportCrash(u"tdf111974.", FORMAT_XLSM); }
3111 void ScFiltersTest::testEscapedUnicodeXLSX()
3113 ScDocShellRef xDocSh = loadDoc(u"escape-unicode.", FORMAT_XLSX);
3114 ScDocument& rDoc = xDocSh->GetDocument();
3116 // Without the fix, there would be "_x000D_" after every new-line char.
3117 CPPUNIT_ASSERT_EQUAL(OUString("Line 1\nLine 2\nLine 3\nLine 4"), rDoc.GetString(1, 1, 0));
3119 xDocSh->DoClose();
3122 void ScFiltersTest::testTdf144758_DBDataDefaultOrientation()
3124 ScDocShellRef xDocSh = loadDoc(u"tdf144758-dbdata-no-orientation.", FORMAT_FODS);
3125 CPPUNIT_ASSERT(xDocSh);
3126 ScDocument& rDoc = xDocSh->GetDocument();
3127 ScDBData* pAnonDBData = rDoc.GetAnonymousDBData(0);
3128 CPPUNIT_ASSERT(pAnonDBData);
3130 ScSortParam aSortParam;
3131 pAnonDBData->GetSortParam(aSortParam);
3133 // Without the fix, the default value for bByRow (in absence of 'table:orientation' attribute
3134 // in 'table:database-range' element) was false
3135 CPPUNIT_ASSERT(aSortParam.bByRow);
3137 xDocSh->DoClose();
3140 ScFiltersTest::ScFiltersTest()
3141 : ScBootstrapFixture( "sc/qa/unit/data" )
3145 void ScFiltersTest::setUp()
3147 test::BootstrapFixture::setUp();
3149 // This is a bit of a fudge, we do this to ensure that ScGlobals::ensure,
3150 // which is a private symbol to us, gets called
3151 m_xCalcComponent =
3152 getMultiServiceFactory()->createInstance("com.sun.star.comp.Calc.SpreadsheetDocument");
3153 CPPUNIT_ASSERT_MESSAGE("no calc component!", m_xCalcComponent.is());
3156 void ScFiltersTest::tearDown()
3158 uno::Reference< lang::XComponent >( m_xCalcComponent, UNO_QUERY_THROW )->dispose();
3159 test::BootstrapFixture::tearDown();
3162 CPPUNIT_TEST_SUITE_REGISTRATION(ScFiltersTest);
3164 CPPUNIT_PLUGIN_IMPLEMENT();
3166 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */