Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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 : */
9 :
10 : #include <sal/config.h>
11 : #include <unotest/filters-test.hxx>
12 : #include <test/bootstrapfixture.hxx>
13 : #include <rtl/strbuf.hxx>
14 : #include <osl/file.hxx>
15 :
16 : #include <sfx2/app.hxx>
17 : #include <sfx2/docfilt.hxx>
18 : #include <sfx2/docfile.hxx>
19 : #include <sfx2/sfxmodelfactory.hxx>
20 : #include <svl/stritem.hxx>
21 : #include <svl/nfkeytab.hxx>
22 : #include <svl/zformat.hxx>
23 : #include <svx/svdograf.hxx>
24 :
25 : #include "drwlayer.hxx"
26 : #include <svx/svdpage.hxx>
27 : #include <svx/svdoole2.hxx>
28 : #include <editeng/wghtitem.hxx>
29 : #include <editeng/postitem.hxx>
30 : #include <editeng/crossedoutitem.hxx>
31 : #include <editeng/udlnitem.hxx>
32 : #include <editeng/editobj.hxx>
33 : #include <editeng/borderline.hxx>
34 : #include <editeng/flditem.hxx>
35 : #include <editeng/justifyitem.hxx>
36 : #include <dbdata.hxx>
37 : #include "validat.hxx"
38 : #include "formulacell.hxx"
39 : #include "userdat.hxx"
40 : #include "dpobject.hxx"
41 : #include "dpsave.hxx"
42 : #include "stlsheet.hxx"
43 : #include "docfunc.hxx"
44 : #include "markdata.hxx"
45 : #include "colorscale.hxx"
46 : #include "olinetab.hxx"
47 : #include "patattr.hxx"
48 : #include "scitems.hxx"
49 : #include "docsh.hxx"
50 : #include "editutil.hxx"
51 : #include "cellvalue.hxx"
52 : #include "attrib.hxx"
53 : #include "dpshttab.hxx"
54 : #include "tabvwsh.hxx"
55 : #include "fillinfo.hxx"
56 : #include <scopetools.hxx>
57 : #include <columnspanset.hxx>
58 : #include <tokenstringcontext.hxx>
59 : #include <formula/errorcodes.hxx>
60 : #include "externalrefmgr.hxx"
61 :
62 :
63 : #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
64 : #include <com/sun/star/drawing/XControlShape.hpp>
65 : #include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
66 : #include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
67 : #include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp>
68 : #include <com/sun/star/sheet/GeneralFunction.hpp>
69 : #include <com/sun/star/container/XIndexAccess.hpp>
70 : #include <com/sun/star/frame/Desktop.hpp>
71 : #include <com/sun/star/frame/XModel.hpp>
72 : #include <com/sun/star/frame/XModel2.hpp>
73 : #include <com/sun/star/text/textfield/Type.hpp>
74 : #include <com/sun/star/chart2/XChartDocument.hpp>
75 : #include <com/sun/star/chart2/data/XDataReceiver.hpp>
76 :
77 : #include "helper/qahelper.hxx"
78 : #include "helper/shared_test_impl.hxx"
79 : #include <algorithm>
80 :
81 : using namespace ::com::sun::star;
82 : using namespace ::com::sun::star::uno;
83 :
84 : /* Implementation of Filters test */
85 :
86 158 : class ScFiltersTest
87 : : public test::FiltersTest
88 : , public ScBootstrapFixture
89 : {
90 : public:
91 : ScFiltersTest();
92 :
93 : virtual bool load( const OUString &rFilter, const OUString &rURL,
94 : const OUString &rUserData, SfxFilterFlags nFilterFlags,
95 : SotClipboardFormatId nClipboardID, unsigned int nFilterVersion) SAL_OVERRIDE;
96 :
97 : virtual void setUp() SAL_OVERRIDE;
98 : virtual void tearDown() SAL_OVERRIDE;
99 :
100 : //ods, xls, xlsx filter tests
101 : void testBooleanFormatXLSX();
102 : void testBasicCellContentODS();
103 : void testRangeNameXLS();
104 : void testRangeNameLocalXLS();
105 : void testRangeNameXLSX();
106 : void testHyperlinksXLSX();
107 : void testHardRecalcODS();
108 : void testFunctionsODS();
109 : void testFunctionsExcel2010();
110 : void testCachedFormulaResultsODS();
111 : void testCachedMatrixFormulaResultsODS();
112 : void testFormulaDepAcrossSheetsODS();
113 : void testFormulaDepDeleteContentsODS();
114 : void testDatabaseRangesODS();
115 : void testDatabaseRangesXLS();
116 : void testDatabaseRangesXLSX();
117 : void testFormatsODS();
118 : // void testFormatsXLS();
119 : // void testFormatsXLSX();
120 : void testMatrixODS();
121 : void testMatrixXLS();
122 : void testBorderODS();
123 : void testBordersOoo33();
124 : void testBugFixesODS();
125 : void testBugFixesXLS();
126 : void testBugFixesXLSX();
127 : void testBrokenQuotesCSV();
128 : void testMergedCellsODS();
129 : void testRepeatedColumnsODS();
130 : void testDataValidityODS();
131 : void testDataTableMortgageXLS();
132 : void testDataTableOneVarXLSX();
133 : void testDataTableMultiTableXLSX();
134 :
135 : void testDataBarODS();
136 : void testDataBarXLSX();
137 : void testColorScaleODS();
138 : void testColorScaleXLSX();
139 : void testNewCondFormatODS();
140 : void testNewCondFormatXLSX();
141 : void testCondFormatThemeColorXLSX();
142 : void testCondFormatThemeColor2XLSX(); // negative bar color and axis color
143 : void testComplexIconSetsXLSX();
144 : void testCondFormatParentXLSX();
145 :
146 : void testLiteralInFormulaXLS();
147 :
148 : //change this test file only in excel and not in calc
149 : void testCellValueXLSX();
150 :
151 : /**
152 : * Test importing of xlsx document that previously had its row index off
153 : * by one. (fdo#76032)
154 : */
155 : void testRowIndex1BasedXLSX();
156 : void testErrorOnExternalReferences();
157 :
158 : //misc tests unrelated to the import filters
159 : #if !defined(MACOSX) && !defined(DRAGONFLY) && !defined(WNT)
160 : void testPasswordNew();
161 : void testPasswordOld();
162 : void testPasswordWrongSHA();
163 : #endif
164 :
165 : //test shape import
166 : void testControlImport();
167 : void testChartImportODS();
168 : void testChartImportXLS();
169 :
170 : void testNumberFormatHTML();
171 : void testNumberFormatCSV();
172 :
173 : void testCellAnchoredShapesODS();
174 :
175 : void testPivotTableBasicODS();
176 : void testPivotTableNamedRangeSourceODS();
177 : void testPivotTableSharedCacheGroupODS();
178 : void testGetPivotDataXLS();
179 :
180 : void testFormulaDependency();
181 :
182 : void testRowHeightODS();
183 : void testRichTextContentODS();
184 : void testMiscRowHeights();
185 : void testOptimalHeightReset();
186 :
187 : void testPrintRangeODS();
188 : void testOutlineODS();
189 :
190 : void testColumnStyleXLSX();
191 :
192 : void testSharedFormulaHorizontalXLS();
193 : void testSharedFormulaWrappedRefsXLS();
194 : void testSharedFormulaBIFF5();
195 : void testSharedFormulaXLSB();
196 : void testSharedFormulaXLS();
197 : void testExternalRefCacheXLSX();
198 : void testExternalRefCacheODS();
199 : void testHybridSharedStringODS();
200 : void testCopyMergedNumberFormats();
201 : void testVBAUserFunctionXLSM();
202 : void testEmbeddedImageXLS();
203 : void testEditEngStrikeThroughXLSX();
204 : void testRefStringXLSX();
205 :
206 2 : CPPUNIT_TEST_SUITE(ScFiltersTest);
207 1 : CPPUNIT_TEST(testBooleanFormatXLSX);
208 1 : CPPUNIT_TEST(testBasicCellContentODS);
209 1 : CPPUNIT_TEST(testRangeNameXLS);
210 1 : CPPUNIT_TEST(testRangeNameLocalXLS);
211 1 : CPPUNIT_TEST(testRangeNameXLSX);
212 1 : CPPUNIT_TEST(testHyperlinksXLSX);
213 1 : CPPUNIT_TEST(testHardRecalcODS);
214 1 : CPPUNIT_TEST(testFunctionsODS);
215 1 : CPPUNIT_TEST(testFunctionsExcel2010);
216 1 : CPPUNIT_TEST(testCachedFormulaResultsODS);
217 1 : CPPUNIT_TEST(testFormulaDepAcrossSheetsODS);
218 1 : CPPUNIT_TEST(testFormulaDepDeleteContentsODS);
219 1 : CPPUNIT_TEST(testCachedMatrixFormulaResultsODS);
220 1 : CPPUNIT_TEST(testDatabaseRangesODS);
221 1 : CPPUNIT_TEST(testDatabaseRangesXLS);
222 1 : CPPUNIT_TEST(testDatabaseRangesXLSX);
223 1 : CPPUNIT_TEST(testFormatsODS);
224 : // CPPUNIT_TEST(testFormatsXLS); TODO: Fix this
225 : // CPPUNIT_TEST(testFormatsXLSX); TODO: Fix this
226 1 : CPPUNIT_TEST(testMatrixODS);
227 1 : CPPUNIT_TEST(testMatrixXLS);
228 1 : CPPUNIT_TEST(testBorderODS);
229 1 : CPPUNIT_TEST(testBordersOoo33);
230 1 : CPPUNIT_TEST(testBugFixesODS);
231 1 : CPPUNIT_TEST(testBugFixesXLS);
232 1 : CPPUNIT_TEST(testBugFixesXLSX);
233 1 : CPPUNIT_TEST(testMergedCellsODS);
234 1 : CPPUNIT_TEST(testRepeatedColumnsODS);
235 1 : CPPUNIT_TEST(testDataValidityODS);
236 1 : CPPUNIT_TEST(testDataTableMortgageXLS);
237 1 : CPPUNIT_TEST(testDataTableOneVarXLSX);
238 1 : CPPUNIT_TEST(testDataTableMultiTableXLSX);
239 1 : CPPUNIT_TEST(testBrokenQuotesCSV);
240 1 : CPPUNIT_TEST(testCellValueXLSX);
241 1 : CPPUNIT_TEST(testRowIndex1BasedXLSX);
242 1 : CPPUNIT_TEST(testControlImport);
243 1 : CPPUNIT_TEST(testChartImportODS);
244 1 : CPPUNIT_TEST(testChartImportXLS);
245 :
246 1 : CPPUNIT_TEST(testDataBarODS);
247 1 : CPPUNIT_TEST(testDataBarXLSX);
248 1 : CPPUNIT_TEST(testColorScaleODS);
249 1 : CPPUNIT_TEST(testColorScaleXLSX);
250 1 : CPPUNIT_TEST(testNewCondFormatODS);
251 1 : CPPUNIT_TEST(testNewCondFormatXLSX);
252 1 : CPPUNIT_TEST(testCondFormatThemeColorXLSX);
253 1 : CPPUNIT_TEST(testCondFormatThemeColor2XLSX);
254 1 : CPPUNIT_TEST(testComplexIconSetsXLSX);
255 1 : CPPUNIT_TEST(testCondFormatParentXLSX);
256 1 : CPPUNIT_TEST(testLiteralInFormulaXLS);
257 :
258 1 : CPPUNIT_TEST(testNumberFormatHTML);
259 1 : CPPUNIT_TEST(testNumberFormatCSV);
260 :
261 1 : CPPUNIT_TEST(testCellAnchoredShapesODS);
262 :
263 1 : CPPUNIT_TEST(testPivotTableBasicODS);
264 1 : CPPUNIT_TEST(testPivotTableNamedRangeSourceODS);
265 1 : CPPUNIT_TEST(testPivotTableSharedCacheGroupODS);
266 1 : CPPUNIT_TEST(testGetPivotDataXLS);
267 1 : CPPUNIT_TEST(testRowHeightODS);
268 1 : CPPUNIT_TEST(testFormulaDependency);
269 1 : CPPUNIT_TEST(testRichTextContentODS);
270 :
271 : //disable testPassword on MacOSX due to problems with libsqlite3
272 : //also crashes on DragonFly due to problems with nss/nspr headers
273 : #if !defined(MACOSX) && !defined(DRAGONFLY) && !defined(WNT)
274 1 : CPPUNIT_TEST(testPasswordWrongSHA);
275 1 : CPPUNIT_TEST(testPasswordOld);
276 1 : CPPUNIT_TEST(testPasswordNew);
277 : #endif
278 :
279 1 : CPPUNIT_TEST(testMiscRowHeights);
280 1 : CPPUNIT_TEST(testOptimalHeightReset);
281 1 : CPPUNIT_TEST(testPrintRangeODS);
282 1 : CPPUNIT_TEST(testOutlineODS);
283 1 : CPPUNIT_TEST(testColumnStyleXLSX);
284 1 : CPPUNIT_TEST(testSharedFormulaHorizontalXLS);
285 1 : CPPUNIT_TEST(testSharedFormulaWrappedRefsXLS);
286 1 : CPPUNIT_TEST(testSharedFormulaBIFF5);
287 1 : CPPUNIT_TEST(testSharedFormulaXLSB);
288 1 : CPPUNIT_TEST(testSharedFormulaXLS);
289 1 : CPPUNIT_TEST(testExternalRefCacheXLSX);
290 1 : CPPUNIT_TEST(testExternalRefCacheODS);
291 1 : CPPUNIT_TEST(testHybridSharedStringODS);
292 1 : CPPUNIT_TEST(testCopyMergedNumberFormats);
293 1 : CPPUNIT_TEST(testVBAUserFunctionXLSM);
294 1 : CPPUNIT_TEST(testEmbeddedImageXLS);
295 1 : CPPUNIT_TEST(testErrorOnExternalReferences);
296 1 : CPPUNIT_TEST(testEditEngStrikeThroughXLSX);
297 1 : CPPUNIT_TEST(testRefStringXLSX);
298 5 : CPPUNIT_TEST_SUITE_END();
299 :
300 : private:
301 : #if !defined(MACOSX) && !defined(DRAGONFLY) && !defined(WNT)
302 : void testPassword_Impl(const OUString& rFileNameBase);
303 : #endif
304 :
305 : uno::Reference<uno::XInterface> m_xCalcComponent;
306 : };
307 :
308 0 : bool ScFiltersTest::load(const OUString &rFilter, const OUString &rURL,
309 : const OUString &rUserData, SfxFilterFlags nFilterFlags,
310 : SotClipboardFormatId nClipboardID, unsigned int nFilterVersion)
311 : {
312 : ScDocShellRef xDocShRef = ScBootstrapFixture::load( rURL, rFilter, rUserData,
313 0 : OUString(), nFilterFlags, nClipboardID, nFilterVersion);
314 0 : bool bLoaded = xDocShRef.Is();
315 : //reference counting of ScDocShellRef is very confused.
316 0 : if (bLoaded)
317 0 : xDocShRef->DoClose();
318 0 : return bLoaded;
319 : }
320 :
321 : namespace {
322 :
323 2 : void testRangeNameImpl(ScDocument& rDoc)
324 : {
325 : //check one range data per sheet and one global more detailed
326 : //add some more checks here
327 2 : ScRangeData* pRangeData = rDoc.GetRangeName()->findByUpperName(OUString("GLOBAL1"));
328 2 : CPPUNIT_ASSERT_MESSAGE("range name Global1 not found", pRangeData);
329 : double aValue;
330 2 : rDoc.GetValue(1,0,0,aValue);
331 2 : CPPUNIT_ASSERT_EQUAL_MESSAGE("range name Global1 should reference Sheet1.A1", 1.0, aValue);
332 2 : pRangeData = rDoc.GetRangeName(0)->findByUpperName(OUString("LOCAL1"));
333 2 : CPPUNIT_ASSERT_MESSAGE("range name Sheet1.Local1 not found", pRangeData);
334 2 : rDoc.GetValue(1,2,0,aValue);
335 2 : CPPUNIT_ASSERT_EQUAL_MESSAGE("range name Sheet1.Local1 should reference Sheet1.A3", 3.0, aValue);
336 2 : pRangeData = rDoc.GetRangeName(1)->findByUpperName(OUString("LOCAL2"));
337 2 : CPPUNIT_ASSERT_MESSAGE("range name Sheet2.Local2 not found", pRangeData);
338 2 : rDoc.GetValue(1,1,1,aValue);
339 2 : CPPUNIT_ASSERT_EQUAL_MESSAGE("range name Sheet2.Local2 should reference Sheet2.A2", 7.0, aValue);
340 : //check for correct results for the remaining formulas
341 2 : rDoc.GetValue(1,1,0, aValue);
342 2 : CPPUNIT_ASSERT_EQUAL_MESSAGE("=global2 should be 2", 2.0, aValue);
343 2 : rDoc.GetValue(1,3,0, aValue);
344 2 : CPPUNIT_ASSERT_EQUAL_MESSAGE("=local2 should be 4", 4.0, aValue);
345 2 : rDoc.GetValue(2,0,0, aValue);
346 2 : CPPUNIT_ASSERT_EQUAL_MESSAGE("=SUM(global3) should be 10", 10.0, aValue);
347 2 : rDoc.GetValue(1,0,1,aValue);
348 2 : CPPUNIT_ASSERT_EQUAL_MESSAGE("range name Sheet2.local1 should reference Sheet1.A5", 5.0, aValue);
349 : // Test if Global5 ( which depends on Global6 ) is evaluated
350 2 : rDoc.GetValue(0,5,1, aValue);
351 2 : CPPUNIT_ASSERT_EQUAL_MESSAGE("formula Global5 should reference Global6 ( which is evaluated as local1 )", 5.0, aValue);
352 2 : }
353 :
354 : }
355 :
356 1 : void ScFiltersTest::testBasicCellContentODS()
357 : {
358 1 : ScDocShellRef xDocSh = loadDoc("basic-cell-content.", ODS);
359 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load basic-cell-content.ods", xDocSh.Is());
360 :
361 1 : ScDocument& rDoc = xDocSh->GetDocument();
362 2 : OUString aStr = rDoc.GetString(1, 1, 0); // B2
363 1 : CPPUNIT_ASSERT_EQUAL(OUString("LibreOffice Calc"), aStr);
364 1 : double fVal = rDoc.GetValue(1, 2, 0); // B3
365 1 : CPPUNIT_ASSERT_EQUAL(12345.0, fVal);
366 1 : aStr = rDoc.GetString(1, 3, 0); // B4
367 1 : CPPUNIT_ASSERT_EQUAL(OUString("A < B"), aStr);
368 :
369 : // Numeric value of 0.
370 2 : ScRefCellValue aCell;
371 1 : aCell.assign(rDoc, ScAddress(1,4,0)); // B5
372 2 : CPPUNIT_ASSERT_EQUAL_MESSAGE(
373 1 : "This cell must be numeric.", CELLTYPE_VALUE, aCell.meType);
374 1 : CPPUNIT_ASSERT_EQUAL(0.0, aCell.mfValue);
375 :
376 2 : xDocSh->DoClose();
377 1 : }
378 :
379 1 : void ScFiltersTest::testBooleanFormatXLSX()
380 : {
381 1 : ScDocShellRef xDocSh = loadDoc("check-boolean.", XLSX);
382 1 : ScDocument& rDoc = xDocSh->GetDocument();
383 1 : SvNumberFormatter* pNumFormatter = rDoc.GetFormatTable();
384 2 : const OUString aBooleanTypeStr = "\"TRUE\";\"TRUE\";\"FALSE\"";
385 :
386 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load check-boolean.xlsx", xDocSh.Is());
387 : sal_uInt32 nNumberFormat;
388 :
389 3 : for (SCROW i = 0; i <= 1; i++)
390 : {
391 2 : rDoc.GetNumberFormat(0, i, 0, nNumberFormat);
392 2 : const SvNumberformat* pNumberFormat = pNumFormatter->GetEntry(nNumberFormat);
393 2 : const OUString& rFormatStr = pNumberFormat->GetFormatstring();
394 2 : CPPUNIT_ASSERT_EQUAL_MESSAGE("Number format != boolean", rFormatStr, aBooleanTypeStr);
395 : }
396 :
397 2 : xDocSh->DoClose();
398 1 : }
399 :
400 1 : void ScFiltersTest::testRangeNameXLS()
401 : {
402 1 : ScDocShellRef xDocSh = loadDoc("named-ranges-global.", XLS);
403 1 : xDocSh->DoHardRecalc(true);
404 :
405 1 : ScDocument& rDoc = xDocSh->GetDocument();
406 1 : testRangeNameImpl(rDoc);
407 :
408 2 : OUString aSheet2CSV("rangeExp_Sheet2.");
409 2 : OUString aCSVPath;
410 1 : createCSVPath( aSheet2CSV, aCSVPath );
411 : // fdo#44587
412 1 : testFile( aCSVPath, rDoc, 1);
413 :
414 2 : xDocSh->DoClose();
415 1 : }
416 :
417 1 : void ScFiltersTest::testRangeNameLocalXLS()
418 : {
419 1 : ScDocShellRef xDocSh = loadDoc("named-ranges-local.", XLS);
420 1 : xDocSh->DoHardRecalc(true);
421 :
422 1 : ScDocument& rDoc = xDocSh->GetDocument();
423 1 : ScRangeName* pRangeName = rDoc.GetRangeName(0);
424 1 : CPPUNIT_ASSERT(pRangeName);
425 1 : CPPUNIT_ASSERT_EQUAL(size_t(2), pRangeName->size());
426 :
427 2 : OUString aFormula;
428 1 : rDoc.GetFormula(3, 11, 0, aFormula);
429 1 : CPPUNIT_ASSERT_EQUAL(OUString("=SUM(local_name2)"), aFormula);
430 1 : ASSERT_DOUBLES_EQUAL(14.0, rDoc.GetValue(3, 11, 0));
431 :
432 1 : rDoc.GetFormula(6, 4, 0, aFormula);
433 1 : CPPUNIT_ASSERT_EQUAL(OUString("=local_name1"), aFormula);
434 :
435 2 : xDocSh->DoClose();
436 1 : }
437 :
438 1 : void ScFiltersTest::testRangeNameXLSX()
439 : {
440 1 : ScDocShellRef xDocSh = loadDoc("named-ranges-global.", XLSX);
441 1 : xDocSh->DoHardRecalc(true);
442 :
443 1 : ScDocument& rDoc = xDocSh->GetDocument();
444 1 : testRangeNameImpl(rDoc);
445 :
446 1 : xDocSh->DoClose();
447 1 : }
448 :
449 1 : void ScFiltersTest::testHyperlinksXLSX()
450 : {
451 1 : ScDocShellRef xDocSh = loadDoc("hyperlinks.", XLSX);
452 1 : ScDocument& rDoc = xDocSh->GetDocument();
453 :
454 1 : CPPUNIT_ASSERT_EQUAL(OUString("10:ABC10"), rDoc.GetString(ScAddress(0,1,0)));
455 1 : CPPUNIT_ASSERT_EQUAL(OUString("10:ABC11"), rDoc.GetString(ScAddress(0,2,0)));
456 1 : CPPUNIT_ASSERT_EQUAL(OUString("10:ABC12"), rDoc.GetString(ScAddress(0,3,0)));
457 :
458 1 : xDocSh->DoClose();
459 1 : }
460 :
461 1 : void ScFiltersTest::testHardRecalcODS()
462 : {
463 1 : ScDocShellRef xDocSh = loadDoc("hard-recalc.", ODS);
464 1 : xDocSh->DoHardRecalc(true);
465 :
466 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load hard-recalc.*", xDocSh.Is());
467 1 : ScDocument& rDoc = xDocSh->GetDocument();
468 2 : OUString aCSVFileName;
469 :
470 : //test hard recalc: document has an incorrect cached formula result
471 : //hard recalc should have updated to the correct result
472 1 : createCSVPath(OUString("hard-recalc."), aCSVFileName);
473 1 : testFile(aCSVFileName, rDoc, 0);
474 :
475 2 : xDocSh->DoClose();
476 1 : }
477 :
478 1 : void ScFiltersTest::testFunctionsODS()
479 : {
480 1 : ScDocShellRef xDocSh = loadDoc("functions.", ODS);
481 1 : xDocSh->DoHardRecalc(true);
482 :
483 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load functions.*", xDocSh.Is());
484 1 : ScDocument& rDoc = xDocSh->GetDocument();
485 2 : OUString aCSVFileName;
486 :
487 : //test logical functions
488 1 : createCSVPath(OUString("logical-functions."), aCSVFileName);
489 1 : testFile(aCSVFileName, rDoc, 0);
490 : //test spreadsheet functions
491 1 : createCSVPath(OUString("spreadsheet-functions."), aCSVFileName);
492 1 : testFile(aCSVFileName, rDoc, 1);
493 : //test mathematical functions
494 1 : createCSVPath(OUString("mathematical-functions."), aCSVFileName);
495 1 : testFile(aCSVFileName, rDoc, 2, PureString);
496 : //test information functions
497 1 : createCSVPath(OUString("information-functions."), aCSVFileName);
498 1 : testFile(aCSVFileName, rDoc, 3);
499 : // text functions
500 1 : createCSVPath(OUString("text-functions."), aCSVFileName);
501 1 : testFile(aCSVFileName, rDoc, 4, PureString);
502 : // statistical functions
503 0 : createCSVPath(OUString("statistical-functions."), aCSVFileName);
504 0 : testFile(aCSVFileName, rDoc, 5);
505 : // financial functions
506 0 : createCSVPath("financial-functions.", aCSVFileName);
507 0 : testFile(aCSVFileName, rDoc, 6);
508 :
509 0 : xDocSh->DoClose();
510 :
511 0 : xDocSh = loadDoc("database-functions.", ODS);
512 0 : CPPUNIT_ASSERT_MESSAGE("Failed to load functions.*", xDocSh.Is());
513 0 : xDocSh->DoHardRecalc(true);
514 0 : ScDocument& rDoc2 = xDocSh->GetDocument();
515 :
516 0 : createCSVPath("database-functions.", aCSVFileName);
517 0 : testFile(aCSVFileName, rDoc2, 0);
518 :
519 0 : xDocSh->DoClose();
520 :
521 0 : xDocSh = loadDoc("date-time-functions.", ODS);
522 0 : CPPUNIT_ASSERT_MESSAGE("Failed to load functions.*", xDocSh.Is());
523 0 : xDocSh->DoHardRecalc(true);
524 0 : ScDocument& rDoc3 = xDocSh->GetDocument();
525 0 : createCSVPath("date-time-functions.", aCSVFileName);
526 0 : testFile(aCSVFileName, rDoc3, 0, PureString);
527 :
528 1 : xDocSh->DoClose();
529 :
530 : // crashes at exit while unloading StarBasic code
531 : // xDocSh = loadDoc("user-defined-function.", ODS);
532 : // xDocSh->DoHardRecalc(true);
533 : // ScDocument& rDocUserDef = xDocSh->GetDocument();
534 : // createCSVPath("user-defined-function.", aCSVFileName);
535 : // testFile(aCSVFileName, rDocUserDef, 0);
536 0 : }
537 :
538 1 : void ScFiltersTest::testFunctionsExcel2010()
539 : {
540 1 : ScDocShellRef xDocSh = loadDoc("functions-excel-2010.", XLSX);
541 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load the document.", xDocSh.Is());
542 1 : ScDocument& rDoc = xDocSh->GetDocument();
543 1 : rDoc.CalcAll(); // perform hard re-calculation.
544 :
545 1 : testFunctionsExcel2010_Impl(rDoc);
546 :
547 1 : xDocSh->DoClose();
548 1 : }
549 :
550 1 : void ScFiltersTest::testCachedFormulaResultsODS()
551 : {
552 : {
553 1 : ScDocShellRef xDocSh = loadDoc("functions.", ODS);
554 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load functions.*", xDocSh.Is());
555 :
556 1 : ScDocument& rDoc = xDocSh->GetDocument();
557 2 : OUString aCSVFileName;
558 :
559 : //test cached formula results of logical functions
560 1 : createCSVPath(OUString("logical-functions."), aCSVFileName);
561 1 : testFile(aCSVFileName, rDoc, 0);
562 : //test cached formula results of spreadsheet functions
563 1 : createCSVPath(OUString("spreadsheet-functions."), aCSVFileName);
564 1 : testFile(aCSVFileName, rDoc, 1);
565 : //test cached formula results of mathematical functions
566 1 : createCSVPath(OUString("mathematical-functions."), aCSVFileName);
567 1 : testFile(aCSVFileName, rDoc, 2, PureString);
568 : //test cached formula results of information functions
569 1 : createCSVPath(OUString("information-functions."), aCSVFileName);
570 1 : testFile(aCSVFileName, rDoc, 3);
571 : // text functions
572 1 : createCSVPath(OUString("text-functions."), aCSVFileName);
573 1 : testFile(aCSVFileName, rDoc, 4, PureString);
574 :
575 2 : xDocSh->DoClose();
576 : }
577 :
578 : {
579 1 : ScDocShellRef xDocSh = loadDoc("cachedValue.", ODS);
580 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load cachedValue.*", xDocSh.Is());
581 :
582 1 : ScDocument& rDoc = xDocSh->GetDocument();
583 2 : OUString aCSVFileName;
584 1 : createCSVPath("cachedValue.", aCSVFileName);
585 1 : testFile(aCSVFileName, rDoc, 0);
586 :
587 : //we want to me sure that volatile functions are always recalculated
588 : //regardless of cached results. if you update the ods file, you must
589 : //update the values here.
590 : //if NOW() is recacluated, then it should never equal sTodayCache
591 2 : OUString sTodayCache("01/25/13 01:06 PM");
592 2 : OUString sTodayRecalc(rDoc.GetString(0,0,1));
593 :
594 1 : CPPUNIT_ASSERT(sTodayCache != sTodayRecalc);
595 :
596 2 : OUString sTodayRecalcRef(rDoc.GetString(1,0,1));
597 1 : CPPUNIT_ASSERT_EQUAL(sTodayRecalc, sTodayRecalcRef);
598 :
599 : // make sure that error values are not being treated as string values
600 5 : for(SCCOL nCol = 0; nCol < 4; ++nCol)
601 : {
602 12 : for(SCROW nRow = 0; nRow < 2; ++nRow)
603 : {
604 8 : OUStringBuffer aIsErrorFormula("=ISERROR(");
605 8 : aIsErrorFormula.append((char)('A'+nCol)).append(OUString::number(nRow));
606 8 : aIsErrorFormula.append(")");
607 16 : OUString aFormula = aIsErrorFormula.makeStringAndClear();
608 8 : rDoc.SetString(nCol, nRow + 2, 2, aFormula);
609 8 : CPPUNIT_ASSERT_EQUAL_MESSAGE(OUStringToOString(aFormula, RTL_TEXTENCODING_UTF8).getStr(), rDoc.GetString(nCol, nRow +2, 2), OUString("TRUE"));
610 :
611 16 : OUStringBuffer aIsTextFormula("=ISTEXT(");
612 8 : aIsTextFormula.append((char)('A'+nCol)).append(OUString::number(nRow));
613 8 : aIsTextFormula.append(")");
614 8 : rDoc.SetString(nCol, nRow + 4, 2, aIsTextFormula.makeStringAndClear());
615 8 : CPPUNIT_ASSERT_EQUAL_MESSAGE("", rDoc.GetString(nCol, nRow +4, 2), OUString("FALSE"));
616 8 : }
617 : }
618 :
619 2 : xDocSh->DoClose();
620 : }
621 1 : }
622 :
623 1 : void ScFiltersTest::testCachedMatrixFormulaResultsODS()
624 : {
625 1 : ScDocShellRef xDocSh = loadDoc("matrix.", ODS);
626 :
627 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load matrix.*", xDocSh.Is());
628 1 : ScDocument& rDoc = xDocSh->GetDocument();
629 :
630 : //test matrix
631 2 : OUString aCSVFileName;
632 1 : createCSVPath("matrix.", aCSVFileName);
633 1 : testFile(aCSVFileName, rDoc, 0);
634 : //test matrices with special cases
635 1 : createCSVPath("matrix2.", aCSVFileName);
636 1 : testFile(aCSVFileName, rDoc, 1);
637 1 : createCSVPath("matrix3.", aCSVFileName);
638 1 : testFile(aCSVFileName, rDoc, 2);
639 : //The above testFile() does not catch the below case.
640 : //If a matrix formula has a matrix reference cell that is intended to have
641 : //a blank text result, the matrix reference cell is actually saved(export)
642 : //as a float cell with 0 as the value and an empty <text:p/>.
643 : //Import works around this by setting these cells as text cells so that
644 : //the blank text is used for display instead of the number 0.
645 : //If this is working properly, the following cell should NOT have value data.
646 1 : CPPUNIT_ASSERT_EQUAL(OUString(), rDoc.GetString(3,0,2));
647 :
648 : // fdo#59293 with cached value import error formulas require special
649 : // treatment
650 1 : rDoc.SetString(2, 5, 2, "=ISERROR(A6)");
651 1 : double nVal = rDoc.GetValue(2,5,2);
652 1 : CPPUNIT_ASSERT_EQUAL(1.0, nVal);
653 :
654 2 : xDocSh->DoClose();
655 1 : }
656 :
657 1 : void ScFiltersTest::testFormulaDepAcrossSheetsODS()
658 : {
659 1 : ScDocShellRef xDocSh = loadDoc("formula-across-sheets.", ODS);
660 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load the file.", xDocSh.Is());
661 1 : ScDocument& rDoc = xDocSh->GetDocument();
662 :
663 2 : sc::AutoCalcSwitch aACSwitch(rDoc, true); // Make sure auto calc is turned on.
664 :
665 : // Save the original values of A4:C4.
666 1 : double fA4 = rDoc.GetValue(ScAddress(0,3,2));
667 1 : double fB4 = rDoc.GetValue(ScAddress(1,3,2));
668 1 : double fC4 = rDoc.GetValue(ScAddress(2,3,2));
669 :
670 : // Change the value of D4. This should trigger A4:C4 to be recalculated.
671 1 : double fD4 = rDoc.GetValue(ScAddress(3,3,2));
672 1 : rDoc.SetValue(ScAddress(3,3,2), fD4+1.0);
673 :
674 1 : CPPUNIT_ASSERT_MESSAGE("The value must differ from the original.", fA4 != rDoc.GetValue(ScAddress(0,3,2)));
675 1 : CPPUNIT_ASSERT_MESSAGE("The value must differ from the original.", fB4 != rDoc.GetValue(ScAddress(1,3,2)));
676 1 : CPPUNIT_ASSERT_MESSAGE("The value must differ from the original.", fC4 != rDoc.GetValue(ScAddress(2,3,2)));
677 :
678 2 : xDocSh->DoClose();
679 1 : }
680 :
681 1 : void ScFiltersTest::testFormulaDepDeleteContentsODS()
682 : {
683 1 : ScDocShellRef xDocSh = loadDoc("formula-delete-contents.", ODS, true);
684 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load the file.", xDocSh.Is());
685 1 : ScDocument& rDoc = xDocSh->GetDocument();
686 :
687 2 : sc::UndoSwitch aUndoSwitch(rDoc, true); // Enable undo.
688 2 : sc::AutoCalcSwitch aACSwitch(rDoc, true); // Make sure auto calc is turned on.
689 :
690 1 : CPPUNIT_ASSERT_EQUAL(195.0, rDoc.GetValue(ScAddress(3,15,0))); // formula in D16
691 :
692 : // Delete D2:D5.
693 1 : ScDocFunc& rFunc = xDocSh->GetDocFunc();
694 1 : ScRange aRange(3,1,0,3,4,0);
695 2 : ScMarkData aMark;
696 1 : aMark.SetMarkArea(aRange);
697 1 : aMark.MarkToMulti();
698 1 : bool bGood = rFunc.DeleteContents(aMark, IDF_ALL, true, true);
699 1 : CPPUNIT_ASSERT(bGood);
700 1 : CPPUNIT_ASSERT_EQUAL(0.0, rDoc.GetValue(ScAddress(3,1,0)));
701 1 : CPPUNIT_ASSERT_EQUAL(0.0, rDoc.GetValue(ScAddress(3,2,0)));
702 1 : CPPUNIT_ASSERT_EQUAL(0.0, rDoc.GetValue(ScAddress(3,3,0)));
703 1 : CPPUNIT_ASSERT_EQUAL(0.0, rDoc.GetValue(ScAddress(3,4,0)));
704 :
705 1 : CPPUNIT_ASSERT_EQUAL(94.0, rDoc.GetValue(ScAddress(3,15,0))); // formula in D16
706 :
707 1 : SfxUndoManager* pUndoMgr = rDoc.GetUndoManager();
708 1 : CPPUNIT_ASSERT(pUndoMgr);
709 1 : pUndoMgr->Undo();
710 1 : CPPUNIT_ASSERT_EQUAL(195.0, rDoc.GetValue(ScAddress(3,15,0))); // formula in D16
711 :
712 2 : xDocSh->DoClose();
713 1 : }
714 :
715 : namespace {
716 :
717 3 : void testDBRanges_Impl(ScDocument& rDoc, sal_Int32 nFormat)
718 : {
719 3 : ScDBCollection* pDBCollection = rDoc.GetDBCollection();
720 3 : CPPUNIT_ASSERT_MESSAGE("no database collection", pDBCollection);
721 :
722 3 : ScDBData* pAnonDBData = rDoc.GetAnonymousDBData(0);
723 3 : CPPUNIT_ASSERT_MESSAGE("missing anonymous DB data in sheet 1", pAnonDBData);
724 : //control hidden rows
725 : bool bHidden;
726 : SCROW nRow1, nRow2;
727 3 : bHidden = rDoc.RowHidden(0, 0, &nRow1, &nRow2);
728 3 : CPPUNIT_ASSERT_MESSAGE("Sheet1: row 0 should be visible", !bHidden && nRow1 == 0 && nRow2 == 0);
729 3 : bHidden = rDoc.RowHidden(1, 0, &nRow1, &nRow2);
730 3 : CPPUNIT_ASSERT_MESSAGE("Sheet1: rows 1-2 should be hidden", bHidden && nRow1 == 1 && nRow2 == 2);
731 3 : bHidden = rDoc.RowHidden(3, 0, &nRow1, &nRow2);
732 3 : CPPUNIT_ASSERT_MESSAGE("Sheet1: row 3 should be visible", !bHidden && nRow1 == 3 && nRow2 == 3);
733 3 : bHidden = rDoc.RowHidden(4, 0, &nRow1, &nRow2);
734 3 : CPPUNIT_ASSERT_MESSAGE("Sheet1: row 4-5 should be hidden", bHidden && nRow1 == 4 && nRow2 == 5);
735 3 : bHidden = rDoc.RowHidden(6, 0, &nRow1, &nRow2);
736 3 : CPPUNIT_ASSERT_MESSAGE("Sheet1: row 6-end should be visible", !bHidden && nRow1 == 6 && nRow2 == MAXROW);
737 3 : if(nFormat == ODS) //excel doesn't support named db ranges
738 : {
739 : double aValue;
740 1 : rDoc.GetValue(0,10,1, aValue);
741 1 : CPPUNIT_ASSERT_EQUAL_MESSAGE("Sheet2: A11: formula result is incorrect", 4.0, aValue);
742 1 : rDoc.GetValue(1, 10, 1, aValue);
743 1 : CPPUNIT_ASSERT_EQUAL_MESSAGE("Sheet2: B11: formula result is incorrect", 2.0, aValue);
744 : }
745 : double aValue;
746 3 : rDoc.GetValue(3,10,1, aValue);
747 3 : CPPUNIT_ASSERT_EQUAL_MESSAGE("Sheet2: D11: formula result is incorrect", 4.0, aValue);
748 3 : rDoc.GetValue(4, 10, 1, aValue);
749 3 : CPPUNIT_ASSERT_EQUAL_MESSAGE("Sheet2: E11: formula result is incorrect", 2.0, aValue);
750 :
751 3 : }
752 :
753 : }
754 :
755 1 : void ScFiltersTest::testDatabaseRangesODS()
756 : {
757 1 : ScDocShellRef xDocSh = loadDoc("database.", ODS);
758 1 : xDocSh->DoHardRecalc(true);
759 :
760 1 : ScDocument& rDoc = xDocSh->GetDocument();
761 :
762 1 : testDBRanges_Impl(rDoc, ODS);
763 1 : xDocSh->DoClose();
764 1 : }
765 :
766 1 : void ScFiltersTest::testDatabaseRangesXLS()
767 : {
768 1 : ScDocShellRef xDocSh = loadDoc("database.", XLS);
769 1 : xDocSh->DoHardRecalc(true);
770 :
771 1 : ScDocument& rDoc = xDocSh->GetDocument();
772 :
773 1 : testDBRanges_Impl(rDoc, XLS);
774 1 : xDocSh->DoClose();
775 1 : }
776 :
777 1 : void ScFiltersTest::testDatabaseRangesXLSX()
778 : {
779 1 : ScDocShellRef xDocSh = loadDoc("database.", XLSX);
780 1 : xDocSh->DoHardRecalc(true);
781 :
782 1 : ScDocument& rDoc = xDocSh->GetDocument();
783 :
784 1 : testDBRanges_Impl(rDoc, XLSX);
785 1 : xDocSh->DoClose();
786 1 : }
787 :
788 1 : void ScFiltersTest::testFormatsODS()
789 : {
790 1 : ScDocShellRef xDocSh = loadDoc("formats.", ODS);
791 1 : xDocSh->DoHardRecalc(true);
792 :
793 1 : ScDocument& rDoc = xDocSh->GetDocument();
794 :
795 1 : testFormats(this, &rDoc, ODS);
796 1 : xDocSh->DoClose();
797 1 : }
798 :
799 : // void ScFiltersTest::testFormatsXLS()
800 : // {
801 : // ScDocShellRef xDocSh = loadDoc("formats.", XLS);
802 : // xDocSh->DoHardRecalc(true);
803 : //
804 : // ScDocument& rDoc = xDocSh->GetDocument();
805 : //
806 : // testFormats(this, rDoc, XLS);
807 : // xDocSh->DoClose();
808 : // }
809 :
810 : // void ScFiltersTest::testFormatsXLSX()
811 : // {
812 : // ScDocShellRef xDocSh = loadDoc("formats.", XLSX);
813 : // xDocSh->DoHardRecalc(true);
814 : //
815 : // ScDocument& rDoc = xDocSh->GetDocument();
816 : //
817 : // testFormats(this, rDoc, XLSX);
818 : // xDocSh->DoClose();
819 : // }
820 :
821 1 : void ScFiltersTest::testMatrixODS()
822 : {
823 1 : ScDocShellRef xDocSh = loadDoc("matrix.", ODS);
824 1 : xDocSh->DoHardRecalc(true);
825 :
826 1 : ScDocument& rDoc = xDocSh->GetDocument();
827 :
828 2 : OUString aCSVFileName;
829 1 : createCSVPath(OUString("matrix."), aCSVFileName);
830 1 : testFile(aCSVFileName, rDoc, 0);
831 :
832 2 : xDocSh->DoClose();
833 1 : }
834 :
835 1 : void ScFiltersTest::testMatrixXLS()
836 : {
837 1 : ScDocShellRef xDocSh = loadDoc("matrix.", XLS);
838 1 : xDocSh->DoHardRecalc(true);
839 :
840 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load matrix.*", xDocSh.Is());
841 1 : ScDocument& rDoc = xDocSh->GetDocument();
842 :
843 2 : OUString aCSVFileName;
844 1 : createCSVPath(OUString("matrix."), aCSVFileName);
845 1 : testFile(aCSVFileName, rDoc, 0);
846 :
847 2 : xDocSh->DoClose();
848 1 : }
849 :
850 1 : void ScFiltersTest::testBorderODS()
851 : {
852 1 : ScDocShellRef xDocSh = loadDoc("border.", ODS);
853 :
854 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load border.*", xDocSh.Is());
855 1 : ScDocument& rDoc = xDocSh->GetDocument();
856 :
857 1 : const editeng::SvxBorderLine* pLeft = NULL;
858 1 : const editeng::SvxBorderLine* pTop = NULL;
859 1 : const editeng::SvxBorderLine* pRight = NULL;
860 1 : const editeng::SvxBorderLine* pBottom = NULL;
861 :
862 1 : rDoc.GetBorderLines( 0, 1, 0, &pLeft, &pTop, &pRight, &pBottom );
863 1 : CPPUNIT_ASSERT(!pLeft);
864 1 : CPPUNIT_ASSERT(!pTop);
865 1 : CPPUNIT_ASSERT(!pBottom);
866 1 : CPPUNIT_ASSERT(pRight);
867 2 : CPPUNIT_ASSERT_EQUAL(
868 1 : table::BorderLineStyle::SOLID, pRight->GetBorderLineStyle());
869 :
870 1 : rDoc.GetBorderLines( 2, 1, 0, &pLeft, &pTop, &pRight, &pBottom );
871 1 : CPPUNIT_ASSERT(!pLeft);
872 1 : CPPUNIT_ASSERT(!pTop);
873 1 : CPPUNIT_ASSERT(!pBottom);
874 :
875 1 : CPPUNIT_ASSERT(pRight);
876 2 : CPPUNIT_ASSERT_EQUAL(
877 1 : table::BorderLineStyle::SOLID, pRight->GetBorderLineStyle());
878 1 : CPPUNIT_ASSERT_EQUAL(20L, pRight->GetWidth());
879 :
880 1 : rDoc.GetBorderLines( 2, 8, 0, &pLeft, &pTop, &pRight, &pBottom );
881 :
882 1 : CPPUNIT_ASSERT(pLeft);
883 1 : CPPUNIT_ASSERT(pTop);
884 1 : CPPUNIT_ASSERT(pBottom);
885 1 : CPPUNIT_ASSERT(pRight);
886 2 : CPPUNIT_ASSERT_EQUAL(
887 1 : table::BorderLineStyle::SOLID, pRight->GetBorderLineStyle());
888 1 : CPPUNIT_ASSERT_EQUAL(5L, pRight->GetWidth());
889 1 : CPPUNIT_ASSERT(pRight->GetColor() == Color(COL_BLUE));
890 :
891 1 : xDocSh->DoClose();
892 1 : }
893 :
894 : struct Border
895 : {
896 : sal_Int16 column;
897 : sal_Int32 row;
898 : long leftWidth;
899 : long topWidth;
900 : long rightWidth;
901 : long bottomWidth;
902 : sal_uInt16 lOutWidth;
903 : sal_uInt16 lInWidth;
904 : sal_uInt16 lDistance;
905 : sal_uInt16 tOutWidth;
906 : sal_uInt16 tInWidth;
907 : sal_uInt16 tDistance;
908 : sal_uInt16 rOutWidth;
909 : sal_uInt16 rInWidth;
910 : sal_uInt16 rDistance;
911 : sal_uInt16 bOutWidth;
912 : sal_uInt16 bInWidth;
913 : sal_uInt16 bDistance;
914 : sal_Int32 lStyle;
915 : sal_Int32 tStyle;
916 : sal_Int32 rStyle;
917 : sal_Int32 bStyle;
918 : // that's a monstrum
919 17 : 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,
920 : sal_uInt16 lDist, sal_uInt16 tOutW, sal_uInt16 tInW, sal_uInt16 tDist, sal_uInt16 rOutW, sal_uInt16 rInW, sal_uInt16 rDist,
921 : sal_uInt16 bOutW, sal_uInt16 bInW, sal_uInt16 bDist, sal_Int32 lSt, sal_Int32 tSt, sal_Int32 rSt, sal_Int32 bSt):
922 : column(col), row(r), leftWidth(lW), topWidth(tW), rightWidth(rW), bottomWidth(bW), lOutWidth(lOutW), lInWidth(lInW), lDistance(lDist),
923 : tOutWidth(tOutW), tInWidth(tInW), tDistance(tDist), rOutWidth(rOutW), rInWidth(rInW), rDistance(rDist), bOutWidth(bOutW), bInWidth(bInW),
924 17 : bDistance(bDist), lStyle(lSt), tStyle(tSt), rStyle(rSt), bStyle(bSt) {};
925 : };
926 :
927 1 : void ScFiltersTest::testBordersOoo33()
928 : {
929 1 : std::vector<Border> borders;
930 1 : borders.push_back(Border(1, 1, 22, 22, 22, 22, 1, 1, 20, 1, 1, 20, 1, 1, 20, 1, 1, 20, 3, 3, 3, 3));
931 1 : borders.push_back(Border(1, 3, 52, 52, 52, 52, 1, 1, 50, 1, 1, 50, 1, 1, 50, 1, 1, 50, 3, 3, 3, 3));
932 1 : borders.push_back(Border(1, 5, 60, 60, 60, 60, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 3, 3, 3, 3));
933 1 : borders.push_back(Border(1, 7, 150, 150, 150, 150, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 3, 3, 3, 3));
934 1 : borders.push_back(Border(1, 9, 71, 71, 71, 71, 20, 1, 50, 20, 1, 50, 20, 1, 50, 20, 1, 50, 3, 3, 3, 3));
935 1 : borders.push_back(Border(1, 11, 101, 101, 101, 101, 50, 1, 50, 50, 1, 50, 50, 1, 50, 50, 1, 50, 3, 3, 3, 3));
936 1 : borders.push_back(Border(1, 13, 131, 131, 131, 131, 80, 1, 50, 80, 1, 50, 80, 1, 50, 80, 1, 50, 3, 3, 3, 3));
937 1 : borders.push_back(Border(1, 15, 120, 120, 120, 120, 50, 20, 50, 50, 20, 50, 50, 20, 50, 50, 20, 50, 3, 3, 3, 3));
938 1 : borders.push_back(Border(1, 17, 90, 90, 90, 90, 20, 50, 20, 20, 50, 20, 20, 50, 20, 20, 50, 20, 3, 3, 3, 3));
939 1 : borders.push_back(Border(1, 19, 180, 180, 180, 180, 80, 50, 50, 80, 50, 50, 80, 50, 50, 80, 50, 50, 3, 3, 3, 3));
940 1 : borders.push_back(Border(1, 21, 180, 180, 180, 180, 50, 80, 50, 50, 80, 50, 50, 80, 50, 50, 80, 50, 3, 3, 3, 3));
941 1 : borders.push_back(Border(4, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0));
942 1 : borders.push_back(Border(4, 3, 10, 10, 10, 10, 10, 0, 0, 10, 0, 0, 10, 0, 0, 10, 0, 0, 0, 0, 0, 0));
943 1 : borders.push_back(Border(4, 5, 20, 20, 20, 20, 20, 0, 0, 20, 0, 0, 20, 0, 0, 20, 0, 0, 0, 0, 0, 0));
944 1 : borders.push_back(Border(4, 7, 50, 50, 50, 50, 50, 0, 0, 50, 0, 0, 50, 0, 0, 50, 0, 0, 0, 0, 0, 0));
945 1 : borders.push_back(Border(4, 9, 80, 80, 80, 80, 80, 0, 0, 80, 0, 0, 80, 0, 0, 80, 0, 0, 0, 0, 0, 0));
946 1 : borders.push_back(Border(4, 11, 100, 100, 100, 100, 100, 0, 0, 100, 0, 0, 100, 0, 0, 100, 0, 0, 0, 0, 0, 0));
947 :
948 2 : ScDocShellRef xDocSh = loadDoc("borders_ooo33.", ODS);
949 :
950 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load borders_ooo33.*", xDocSh.Is());
951 1 : ScDocument& rDoc = xDocSh->GetDocument();
952 :
953 1 : const editeng::SvxBorderLine* pLeft = NULL;
954 1 : const editeng::SvxBorderLine* pTop = NULL;
955 1 : const editeng::SvxBorderLine* pRight = NULL;
956 1 : const editeng::SvxBorderLine* pBottom = NULL;
957 1 : sal_Int16 temp = 0;
958 7 : for(sal_Int16 i = 0; i<6; ++i)
959 : {
960 138 : for(sal_Int32 j = 0; j<22; ++j)
961 : {
962 132 : rDoc.GetBorderLines( i, j, 0, &pLeft, &pTop, &pRight, &pBottom );
963 132 : if(pLeft!=NULL && pTop!=NULL && pRight!=NULL && pBottom!=NULL)
964 : {
965 17 : CPPUNIT_ASSERT_EQUAL(borders[temp].column, i);
966 17 : CPPUNIT_ASSERT_EQUAL(borders[temp].row, j);
967 17 : CPPUNIT_ASSERT_EQUAL(borders[temp].leftWidth, pLeft->GetWidth());
968 17 : CPPUNIT_ASSERT_EQUAL(borders[temp].topWidth, pTop->GetWidth());
969 17 : CPPUNIT_ASSERT_EQUAL(borders[temp].rightWidth, pRight->GetWidth());
970 17 : CPPUNIT_ASSERT_EQUAL(borders[temp].bottomWidth, pBottom->GetWidth());
971 17 : CPPUNIT_ASSERT_EQUAL(borders[temp].lOutWidth, pLeft->GetOutWidth());
972 17 : CPPUNIT_ASSERT_EQUAL(borders[temp].lInWidth, pLeft->GetInWidth());
973 17 : CPPUNIT_ASSERT_EQUAL(borders[temp].lDistance, pLeft->GetDistance());
974 17 : CPPUNIT_ASSERT_EQUAL(borders[temp].tOutWidth, pTop->GetOutWidth());
975 17 : CPPUNIT_ASSERT_EQUAL(borders[temp].tInWidth, pTop->GetInWidth());
976 17 : CPPUNIT_ASSERT_EQUAL(borders[temp].tDistance, pTop->GetDistance());
977 17 : CPPUNIT_ASSERT_EQUAL(borders[temp].rOutWidth, pRight->GetOutWidth());
978 17 : CPPUNIT_ASSERT_EQUAL(borders[temp].rInWidth, pRight->GetInWidth());
979 17 : CPPUNIT_ASSERT_EQUAL(borders[temp].rDistance, pRight->GetDistance());
980 17 : CPPUNIT_ASSERT_EQUAL(borders[temp].bOutWidth, pBottom->GetOutWidth());
981 17 : CPPUNIT_ASSERT_EQUAL(borders[temp].bInWidth, pBottom->GetInWidth());
982 17 : CPPUNIT_ASSERT_EQUAL(borders[temp].bDistance, pBottom->GetDistance());
983 17 : sal_Int32 tempStyle = pLeft->GetBorderLineStyle();
984 17 : CPPUNIT_ASSERT_EQUAL(borders[temp].lStyle, tempStyle);
985 17 : tempStyle = pTop->GetBorderLineStyle();
986 17 : CPPUNIT_ASSERT_EQUAL(borders[temp].tStyle, tempStyle);
987 17 : tempStyle = pRight->GetBorderLineStyle();
988 17 : CPPUNIT_ASSERT_EQUAL(borders[temp].rStyle, tempStyle);
989 17 : tempStyle = pBottom->GetBorderLineStyle();
990 17 : CPPUNIT_ASSERT_EQUAL(borders[temp].bStyle, tempStyle);
991 17 : ++temp;
992 : }
993 : }
994 : }
995 :
996 2 : xDocSh->DoClose();
997 1 : }
998 :
999 1 : void ScFiltersTest::testBugFixesODS()
1000 : {
1001 1 : ScDocShellRef xDocSh = loadDoc("bug-fixes.", ODS);
1002 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load bugFixes.ods", xDocSh.Is());
1003 :
1004 1 : xDocSh->DoHardRecalc(true);
1005 1 : ScDocument& rDoc = xDocSh->GetDocument();
1006 :
1007 : {
1008 : // fdo#40967
1009 1 : OUString aCSVFileName;
1010 1 : createCSVPath(OUString("bugFix_Sheet2."), aCSVFileName);
1011 1 : testFile(aCSVFileName, rDoc, 1);
1012 : }
1013 :
1014 : {
1015 : // fdo#40426
1016 1 : ScDBData* pDBData = rDoc.GetDBCollection()->getNamedDBs().findByUpperName("DBRANGE1");
1017 1 : CPPUNIT_ASSERT(pDBData);
1018 1 : CPPUNIT_ASSERT(pDBData->HasHeader());
1019 : // no header
1020 1 : pDBData = rDoc.GetDBCollection()->getNamedDBs().findByUpperName("DBRANGE2");
1021 1 : CPPUNIT_ASSERT(pDBData);
1022 1 : CPPUNIT_ASSERT(!pDBData->HasHeader());
1023 : }
1024 :
1025 : {
1026 : // fdo#59240
1027 1 : OUString aCSVFileName;
1028 1 : createCSVPath("bugFix_Sheet4.", aCSVFileName);
1029 1 : testFile(aCSVFileName, rDoc, 3);
1030 : }
1031 :
1032 1 : xDocSh->DoClose();
1033 1 : }
1034 :
1035 1 : void ScFiltersTest::testBugFixesXLS()
1036 : {
1037 1 : ScDocShellRef xDocSh = loadDoc("bug-fixes.", XLS);
1038 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load bugFixes.xls", xDocSh.Is());
1039 :
1040 1 : xDocSh->DoHardRecalc(true);
1041 1 : xDocSh->GetDocument();
1042 1 : xDocSh->DoClose();
1043 1 : }
1044 :
1045 1 : void ScFiltersTest::testBugFixesXLSX()
1046 : {
1047 1 : ScDocShellRef xDocSh = loadDoc("bug-fixes.", XLSX);
1048 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load bugFixes.xls", xDocSh.Is());
1049 :
1050 1 : xDocSh->DoHardRecalc(true);
1051 1 : xDocSh->GetDocument();
1052 1 : xDocSh->DoClose();
1053 1 : }
1054 :
1055 : namespace {
1056 :
1057 4 : void checkMergedCells( ScDocument& rDoc, const ScAddress& rStartAddress,
1058 : const ScAddress& rExpectedEndAddress )
1059 : {
1060 4 : SCCOL nActualEndCol = rStartAddress.Col();
1061 4 : SCROW nActualEndRow = rStartAddress.Row();
1062 4 : rDoc.ExtendMerge( rStartAddress.Col(), rStartAddress.Row(),
1063 8 : nActualEndCol, nActualEndRow, rStartAddress.Tab(), false );
1064 4 : OString sTab = OString::number( rStartAddress.Tab() + 1 );
1065 8 : OString msg = "Merged cells are not correctly imported on sheet" + sTab;
1066 8 : OString msgCol = msg + "; end col";
1067 8 : OString msgRow = msg + "; end row";
1068 4 : CPPUNIT_ASSERT_EQUAL_MESSAGE( msgCol.pData->buffer, rExpectedEndAddress.Col(), nActualEndCol );
1069 8 : CPPUNIT_ASSERT_EQUAL_MESSAGE( msgRow.pData->buffer, rExpectedEndAddress.Row(), nActualEndRow );
1070 4 : }
1071 :
1072 : }
1073 :
1074 1 : void ScFiltersTest::testMergedCellsODS()
1075 : {
1076 1 : ScDocShellRef xDocSh = loadDoc("merged.", ODS);
1077 1 : ScDocument& rDoc = xDocSh->GetDocument();
1078 :
1079 : //check sheet1 content
1080 2 : OUString aCSVFileName1;
1081 1 : createCSVPath(OUString("merged1."), aCSVFileName1);
1082 1 : testFile(aCSVFileName1, rDoc, 0);
1083 :
1084 : //check sheet1 merged cells
1085 1 : checkMergedCells( rDoc, ScAddress( 0, 0, 0 ), ScAddress( 5, 11, 0 ) );
1086 1 : checkMergedCells( rDoc, ScAddress( 7, 2, 0 ), ScAddress( 9, 12, 0 ) );
1087 1 : checkMergedCells( rDoc, ScAddress( 3, 15, 0 ), ScAddress( 7, 23, 0 ) );
1088 :
1089 : //check sheet2 content
1090 2 : OUString aCSVFileName2;
1091 1 : createCSVPath(OUString("merged2."), aCSVFileName2);
1092 1 : testFile(aCSVFileName2, rDoc, 1);
1093 :
1094 : //check sheet2 merged cells
1095 1 : checkMergedCells( rDoc, ScAddress( 4, 3, 1 ), ScAddress( 6, 15, 1 ) );
1096 :
1097 2 : xDocSh->DoClose();
1098 1 : }
1099 :
1100 1 : void ScFiltersTest::testRepeatedColumnsODS()
1101 : {
1102 1 : ScDocShellRef xDocSh = loadDoc("repeatedColumns.", ODS);
1103 1 : ScDocument& rDoc = xDocSh->GetDocument();
1104 :
1105 : //text
1106 2 : OUString aCSVFileName1;
1107 1 : createCSVPath(OUString("repeatedColumns1."), aCSVFileName1);
1108 1 : testFile(aCSVFileName1, rDoc, 0);
1109 :
1110 : //numbers
1111 2 : OUString aCSVFileName2;
1112 1 : createCSVPath(OUString("repeatedColumns2."), aCSVFileName2);
1113 1 : testFile(aCSVFileName2, rDoc, 1);
1114 :
1115 2 : xDocSh->DoClose();
1116 1 : }
1117 :
1118 : namespace {
1119 :
1120 : //for cleaner passing of parameters
1121 2 : struct ValDataTestParams
1122 : {
1123 : ScValidationMode eValMode;
1124 : ScConditionMode eCondOp;
1125 : OUString aStrVal1;
1126 : OUString aStrVal2;
1127 : ScDocument& rDocument;
1128 : ScAddress aPosition;
1129 : OUString aErrorTitle;
1130 : OUString aErrorMessage;
1131 : ScValidErrorStyle eErrorStyle;
1132 : sal_uLong nExpectedIndex;
1133 :
1134 2 : ValDataTestParams( ScValidationMode eMode, ScConditionMode eOp,
1135 : const OUString& aExpr1, const OUString& aExpr2, ScDocument& rDoc,
1136 : ScAddress aPos, const OUString& aETitle, const OUString& aEMsg,
1137 : ScValidErrorStyle eEStyle, sal_uLong nIndex ):
1138 : eValMode(eMode), eCondOp(eOp), aStrVal1(aExpr1),
1139 : aStrVal2(aExpr2), rDocument(rDoc), aPosition(aPos),
1140 : aErrorTitle(aETitle), aErrorMessage(aEMsg),
1141 2 : eErrorStyle(eEStyle), nExpectedIndex(nIndex) { };
1142 : };
1143 :
1144 2 : void checkValiditationEntries( const ValDataTestParams& rVDTParams )
1145 : {
1146 2 : ScDocument& rDoc = rVDTParams.rDocument;
1147 :
1148 : //create expected data validation entry
1149 : ScValidationData aValData(
1150 : rVDTParams.eValMode, rVDTParams.eCondOp, rVDTParams.aStrVal1,
1151 2 : rVDTParams.aStrVal2, &rDoc, rVDTParams.aPosition, EMPTY_OUSTRING,
1152 2 : EMPTY_OUSTRING, rDoc.GetStorageGrammar(), rDoc.GetStorageGrammar()
1153 4 : );
1154 2 : aValData.SetIgnoreBlank( true );
1155 2 : aValData.SetListType( 1 );
1156 2 : aValData.ResetInput();
1157 2 : aValData.SetError( rVDTParams.aErrorTitle, rVDTParams.aErrorMessage, rVDTParams.eErrorStyle );
1158 2 : aValData.SetSrcString( EMPTY_OUSTRING );
1159 :
1160 : //get actual data validation entry from document
1161 2 : const ScValidationData* pValDataTest = rDoc.GetValidationEntry( rVDTParams.nExpectedIndex );
1162 :
1163 2 : sal_Int32 nCol( static_cast<sal_Int32>(rVDTParams.aPosition.Col()) );
1164 2 : sal_Int32 nRow( static_cast<sal_Int32>(rVDTParams.aPosition.Row()) );
1165 2 : sal_Int32 nTab( static_cast<sal_Int32>(rVDTParams.aPosition.Tab()) );
1166 4 : OStringBuffer sMsg("Data Validation Entry with base-cell-address: (");
1167 2 : sMsg.append(nCol).append(",").append(nRow).append(",").append(nTab).append(") ");
1168 4 : OString aMsgPrefix = sMsg.makeStringAndClear();
1169 :
1170 4 : OString aMsg = aMsgPrefix + "did not get imported at all.";
1171 2 : CPPUNIT_ASSERT_MESSAGE(aMsg.getStr(), pValDataTest);
1172 :
1173 : //check if expected and actual data validation entries are equal
1174 2 : if (!aValData.EqualEntries(*pValDataTest))
1175 : {
1176 0 : aMsg = aMsgPrefix + "got imported incorrectly.";
1177 0 : CPPUNIT_FAIL(aMsg.getStr());
1178 2 : }
1179 2 : }
1180 :
1181 2 : void checkCellValidity( const ScAddress& rValBaseAddr, const ScRange& rRange, const ScDocument& rDoc )
1182 : {
1183 2 : SCCOL nBCol( rValBaseAddr.Col() );
1184 2 : SCROW nBRow( rValBaseAddr.Row() );
1185 2 : SCTAB nTab( static_cast<const sal_Int32>(rValBaseAddr.Tab()) );
1186 : //get from the document the data validation entry we are checking against
1187 2 : const SfxUInt32Item* pItem = static_cast<const SfxUInt32Item*>(rDoc.GetAttr(nBCol, nBRow, nTab, ATTR_VALIDDATA) );
1188 2 : const ScValidationData* pValData = rDoc.GetValidationEntry( pItem->GetValue() );
1189 2 : CPPUNIT_ASSERT(pValData);
1190 :
1191 : //check that each cell in the expected range is associated with the data validation entry
1192 8 : for(SCCOL i = rRange.aStart.Col(); i <= rRange.aEnd.Col(); ++i)
1193 : {
1194 36 : for(SCROW j = rRange.aStart.Row(); j <= rRange.aEnd.Row(); ++j)
1195 : {
1196 30 : const SfxUInt32Item* pItemTest = static_cast<const SfxUInt32Item*>( rDoc.GetAttr(i, j, nTab, ATTR_VALIDDATA) );
1197 30 : const ScValidationData* pValDataTest = rDoc.GetValidationEntry( pItemTest->GetValue() );
1198 : //prevent string operations for occurring unnecessarily
1199 30 : if(!(pValDataTest && pValData->GetKey() == pValDataTest->GetKey()))
1200 : {
1201 0 : sal_Int32 nCol = static_cast<const sal_Int32>(i);
1202 0 : sal_Int32 nRow = static_cast<const sal_Int32>(j);
1203 0 : sal_Int32 nTab32 = static_cast<const sal_Int32>(nTab);
1204 0 : OStringBuffer sMsg("\nData validation entry base-cell-address: (");
1205 0 : sMsg.append( static_cast<const sal_Int32>(nBCol) ).append(",");
1206 0 : sMsg.append( static_cast<const sal_Int32>(nBRow) ).append(",");
1207 0 : sMsg.append( nTab32 ).append(")\n");
1208 0 : sMsg.append("Cell: (").append(nCol).append(",").append(nRow).append(",").append(nTab32).append(")");
1209 0 : sal_uInt32 expectedKey(pValData->GetKey());
1210 0 : sal_uInt32 actualKey(0);
1211 0 : if(pValDataTest)
1212 0 : actualKey = pValDataTest->GetKey();
1213 0 : CPPUNIT_ASSERT_EQUAL_MESSAGE(sMsg.getStr(), expectedKey, actualKey);
1214 : }
1215 : }
1216 : }
1217 2 : }
1218 :
1219 : }
1220 :
1221 1 : void ScFiltersTest::testDataValidityODS()
1222 : {
1223 1 : ScDocShellRef xDocSh = loadDoc("dataValidity.", ODS);
1224 1 : ScDocument& rDoc = xDocSh->GetDocument();
1225 :
1226 1 : ScAddress aValBaseAddr1( 2,6,0 ); //sheet1
1227 1 : ScAddress aValBaseAddr2( 2,3,1 ); //sheet2
1228 :
1229 : //sheet1's expected Data Validation Entry values
1230 : ValDataTestParams aVDTParams1(
1231 1 : SC_VALID_DECIMAL, SC_COND_GREATER, "3.14", EMPTY_OUSTRING, rDoc,
1232 : aValBaseAddr1, "Too small",
1233 : "The number you are trying to enter is not greater than 3.14! Are you sure you want to enter it anyway?",
1234 : SC_VALERR_WARNING, 1
1235 3 : );
1236 : //sheet2's expected Data Validation Entry values
1237 : ValDataTestParams aVDTParams2(
1238 : SC_VALID_WHOLE, SC_COND_BETWEEN, "1", "10", rDoc,
1239 : aValBaseAddr2, "Error sheet 2",
1240 : "Must be a whole number between 1 and 10.",
1241 : SC_VALERR_STOP, 2
1242 2 : );
1243 : //check each sheet's Data Validation Entries
1244 1 : checkValiditationEntries( aVDTParams1 );
1245 1 : checkValiditationEntries( aVDTParams2 );
1246 :
1247 : //expected ranges to be associated with data validity
1248 1 : ScRange aRange1( 2,2,0, 2,6,0 ); //sheet1
1249 1 : ScRange aRange2( 2,3,1, 6,7,1 ); //sheet2
1250 :
1251 : //check each sheet's cells for data validity
1252 1 : checkCellValidity( aValBaseAddr1, aRange1, rDoc );
1253 1 : checkCellValidity( aValBaseAddr2, aRange2, rDoc );
1254 :
1255 : //check each sheet's content
1256 2 : OUString aCSVFileName1;
1257 1 : createCSVPath(OUString("dataValidity1."), aCSVFileName1);
1258 1 : testFile(aCSVFileName1, rDoc, 0);
1259 :
1260 2 : OUString aCSVFileName2;
1261 1 : createCSVPath(OUString("dataValidity2."), aCSVFileName2);
1262 1 : testFile(aCSVFileName2, rDoc, 1);
1263 :
1264 2 : xDocSh->DoClose();
1265 1 : }
1266 :
1267 1 : void ScFiltersTest::testDataTableMortgageXLS()
1268 : {
1269 1 : ScDocShellRef xDocSh = loadDoc("data-table/mortgage.", XLS);
1270 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load the document.", xDocSh.Is());
1271 :
1272 2 : ScFormulaOptions aOptions;
1273 1 : aOptions.SetFormulaSepArg(",");
1274 1 : aOptions.SetFormulaSepArrayCol(",");
1275 1 : aOptions.SetFormulaSepArrayRow(";");
1276 1 : xDocSh->SetFormulaOptions(aOptions);
1277 :
1278 1 : ScDocument& rDoc = xDocSh->GetDocument();
1279 :
1280 : // One-variable table
1281 :
1282 1 : if (!checkFormula(rDoc, ScAddress(3,1,0), "PMT(B3/12,B4,-B5)"))
1283 0 : CPPUNIT_FAIL("Wrong formula!");
1284 :
1285 1 : if (!checkFormula(rDoc, ScAddress(3,2,0), "MULTIPLE.OPERATIONS(D$2,$B$3,$C3)"))
1286 0 : CPPUNIT_FAIL("Wrong formula!");
1287 :
1288 1 : if (!checkFormula(rDoc, ScAddress(3,3,0), "MULTIPLE.OPERATIONS(D$2,$B$3,$C4)"))
1289 0 : CPPUNIT_FAIL("Wrong formula!");
1290 :
1291 1 : if (!checkFormula(rDoc, ScAddress(3,4,0), "MULTIPLE.OPERATIONS(D$2,$B$3,$C5)"))
1292 0 : CPPUNIT_FAIL("Wrong formula!");
1293 :
1294 : // Two-variable table
1295 :
1296 1 : if (!checkFormula(rDoc, ScAddress(2,7,0), "PMT(B9/12,B10,-B11)"))
1297 0 : CPPUNIT_FAIL("Wrong formula!");
1298 :
1299 1 : if (!checkFormula(rDoc, ScAddress(3,8,0), "MULTIPLE.OPERATIONS($C$8,$B$9,$C9,$B$10,D$8)"))
1300 0 : CPPUNIT_FAIL("Wrong formula!");
1301 :
1302 1 : if (!checkFormula(rDoc, ScAddress(3,9,0), "MULTIPLE.OPERATIONS($C$8,$B$9,$C10,$B$10,D$8)"))
1303 0 : CPPUNIT_FAIL("Wrong formula!");
1304 :
1305 1 : if (!checkFormula(rDoc, ScAddress(3,10,0), "MULTIPLE.OPERATIONS($C$8,$B$9,$C11,$B$10,D$8)"))
1306 0 : CPPUNIT_FAIL("Wrong formula!");
1307 :
1308 1 : if (!checkFormula(rDoc, ScAddress(4,8,0), "MULTIPLE.OPERATIONS($C$8,$B$9,$C9,$B$10,E$8)"))
1309 0 : CPPUNIT_FAIL("Wrong formula!");
1310 :
1311 1 : if (!checkFormula(rDoc, ScAddress(4,9,0), "MULTIPLE.OPERATIONS($C$8,$B$9,$C10,$B$10,E$8)"))
1312 0 : CPPUNIT_FAIL("Wrong formula!");
1313 :
1314 1 : if (!checkFormula(rDoc, ScAddress(4,10,0), "MULTIPLE.OPERATIONS($C$8,$B$9,$C11,$B$10,E$8)"))
1315 0 : CPPUNIT_FAIL("Wrong formula!");
1316 :
1317 2 : xDocSh->DoClose();
1318 1 : }
1319 :
1320 1 : void ScFiltersTest::testDataTableOneVarXLSX()
1321 : {
1322 1 : ScDocShellRef xDocSh = loadDoc("data-table/one-variable.", XLSX);
1323 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load the document.", xDocSh.Is());
1324 :
1325 2 : ScFormulaOptions aOptions;
1326 1 : aOptions.SetFormulaSepArg(",");
1327 1 : aOptions.SetFormulaSepArrayCol(",");
1328 1 : aOptions.SetFormulaSepArrayRow(";");
1329 1 : xDocSh->SetFormulaOptions(aOptions);
1330 :
1331 1 : ScDocument& rDoc = xDocSh->GetDocument();
1332 :
1333 : // Right now, we have a bug that prevents Calc from re-calculating these
1334 : // cells automatically upon file load. We can remove this call if/when we
1335 : // fix the aforementioned bug.
1336 1 : rDoc.CalcAll();
1337 :
1338 : // B5:B11 should have multiple operations formula cells. Just check the
1339 : // top and bottom cells.
1340 :
1341 1 : if (!checkFormula(rDoc, ScAddress(1,4,0), "MULTIPLE.OPERATIONS(B$4,$A$2,$A5)"))
1342 0 : CPPUNIT_FAIL("Wrong formula!");
1343 :
1344 1 : CPPUNIT_ASSERT_EQUAL(2.0, rDoc.GetValue(ScAddress(1,4,0)));
1345 :
1346 1 : if (!checkFormula(rDoc, ScAddress(1,10,0), "MULTIPLE.OPERATIONS(B$4,$A$2,$A11)"))
1347 0 : CPPUNIT_FAIL("Wrong formula!");
1348 :
1349 1 : CPPUNIT_ASSERT_EQUAL(14.0, rDoc.GetValue(ScAddress(1,10,0)));
1350 :
1351 : // Likewise, E5:I5 should have multiple operations formula cells. Just
1352 : // check the left- and right-most cells.
1353 :
1354 1 : if (!checkFormula(rDoc, ScAddress(4,4,0), "MULTIPLE.OPERATIONS($D5,$B$2,E$4)"))
1355 0 : CPPUNIT_FAIL("Wrong formula!");
1356 :
1357 1 : CPPUNIT_ASSERT_EQUAL(10.0, rDoc.GetValue(ScAddress(4,4,0)));
1358 :
1359 1 : if (!checkFormula(rDoc, ScAddress(8,4,0), "MULTIPLE.OPERATIONS($D5,$B$2,I$4)"))
1360 0 : CPPUNIT_FAIL("Wrong formula!");
1361 :
1362 1 : CPPUNIT_ASSERT_EQUAL(50.0, rDoc.GetValue(ScAddress(8,4,0)));
1363 :
1364 2 : xDocSh->DoClose();
1365 1 : }
1366 :
1367 1 : void ScFiltersTest::testDataTableMultiTableXLSX()
1368 : {
1369 1 : ScDocShellRef xDocSh = loadDoc("data-table/multi-table.", XLSX);
1370 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load the document.", xDocSh.Is());
1371 :
1372 2 : ScFormulaOptions aOptions;
1373 1 : aOptions.SetFormulaSepArg(",");
1374 1 : aOptions.SetFormulaSepArrayCol(",");
1375 1 : aOptions.SetFormulaSepArrayRow(";");
1376 1 : xDocSh->SetFormulaOptions(aOptions);
1377 :
1378 1 : ScDocument& rDoc = xDocSh->GetDocument();
1379 :
1380 : // Right now, we have a bug that prevents Calc from re-calculating these
1381 : // cells automatically upon file load. We can remove this call if/when we
1382 : // fix the aforementioned bug.
1383 1 : rDoc.CalcAll();
1384 :
1385 : // B4:M15 should have multiple operations formula cells. We'll just check
1386 : // the top-left and bottom-right ones.
1387 :
1388 1 : if (!checkFormula(rDoc, ScAddress(1,3,0), "MULTIPLE.OPERATIONS($A$3,$E$1,$A4,$D$1,B$3)"))
1389 0 : CPPUNIT_FAIL("Wrong formula!");
1390 :
1391 1 : CPPUNIT_ASSERT_EQUAL(1.0, rDoc.GetValue(ScAddress(1,3,0)));
1392 :
1393 1 : if (!checkFormula(rDoc, ScAddress(12,14,0), "MULTIPLE.OPERATIONS($A$3,$E$1,$A15,$D$1,M$3)"))
1394 0 : CPPUNIT_FAIL("Wrong formula!");
1395 :
1396 1 : CPPUNIT_ASSERT_EQUAL(144.0, rDoc.GetValue(ScAddress(12,14,0)));
1397 :
1398 2 : xDocSh->DoClose();
1399 1 : }
1400 :
1401 1 : void ScFiltersTest::testBrokenQuotesCSV()
1402 : {
1403 1 : const OUString aFileNameBase("fdo48621_broken_quotes.");
1404 2 : OUString aFileExtension(getFileFormats()[CSV].pName, strlen(getFileFormats()[CSV].pName), RTL_TEXTENCODING_UTF8 );
1405 2 : OUString aFilterName(getFileFormats()[CSV].pFilterName, strlen(getFileFormats()[CSV].pFilterName), RTL_TEXTENCODING_UTF8) ;
1406 2 : OUString aFileName;
1407 1 : createFileURL(aFileNameBase, aFileExtension, aFileName);
1408 2 : OUString aFilterType(getFileFormats()[CSV].pTypeName, strlen(getFileFormats()[CSV].pTypeName), RTL_TEXTENCODING_UTF8);
1409 1 : std::cout << getFileFormats()[CSV].pName << " Test" << std::endl;
1410 :
1411 1 : SfxFilterFlags nFormatType = getFileFormats()[CSV].nFormatType;
1412 1 : SotClipboardFormatId nClipboardId = bool(nFormatType) ? SotClipboardFormatId::STARCALC_8 : SotClipboardFormatId::NONE;
1413 : ScDocShellRef xDocSh = ScBootstrapFixture::load(aFileName, aFilterName, OUString(), aFilterType,
1414 2 : nFormatType, nClipboardId, SOFFICE_FILEFORMAT_CURRENT);
1415 :
1416 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load fdo48621_broken_quotes.csv", xDocSh.Is());
1417 1 : ScDocument& rDoc = xDocSh->GetDocument();
1418 :
1419 2 : OUString aSheet2CSV("fdo48621_broken_quotes_exported.");
1420 2 : OUString aCSVPath;
1421 1 : createCSVPath( aSheet2CSV, aCSVPath );
1422 : // fdo#48621
1423 1 : testFile( aCSVPath, rDoc, 0, PureString);
1424 :
1425 2 : xDocSh->DoClose();
1426 1 : }
1427 :
1428 1 : void ScFiltersTest::testCellValueXLSX()
1429 : {
1430 1 : const OUString aFileNameBase("cell-value.");
1431 2 : OUString aFileExtension(getFileFormats()[XLSX].pName, strlen(getFileFormats()[XLSX].pName), RTL_TEXTENCODING_UTF8 );
1432 2 : OUString aFilterName(getFileFormats()[XLSX].pFilterName, strlen(getFileFormats()[XLSX].pFilterName), RTL_TEXTENCODING_UTF8) ;
1433 2 : OUString aFileName;
1434 1 : createFileURL(aFileNameBase, aFileExtension, aFileName);
1435 2 : OUString aFilterType(getFileFormats()[XLSX].pTypeName, strlen(getFileFormats()[XLSX].pTypeName), RTL_TEXTENCODING_UTF8);
1436 1 : std::cout << getFileFormats()[XLSX].pName << " Test" << std::endl;
1437 :
1438 1 : SfxFilterFlags nFormatType = getFileFormats()[XLSX].nFormatType;
1439 1 : SotClipboardFormatId nClipboardId = bool(nFormatType) ? SotClipboardFormatId::STARCALC_8 : SotClipboardFormatId::NONE;
1440 : ScDocShellRef xDocSh = ScBootstrapFixture::load( aFileName, aFilterName, OUString(), aFilterType,
1441 2 : nFormatType, nClipboardId, SOFFICE_FILEFORMAT_CURRENT);
1442 :
1443 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load cell-value.xlsx", xDocSh.Is());
1444 1 : ScDocument& rDoc = xDocSh->GetDocument();
1445 :
1446 2 : OUString aCSVPath;
1447 1 : createCSVPath( aFileNameBase, aCSVPath );
1448 1 : testFile( aCSVPath, rDoc, 0 );
1449 :
1450 2 : xDocSh->DoClose();
1451 1 : }
1452 :
1453 1 : void ScFiltersTest::testRowIndex1BasedXLSX()
1454 : {
1455 1 : ScDocShellRef xDocSh = loadDoc("row-index-1-based.", XLSX);
1456 1 : CPPUNIT_ASSERT(xDocSh.Is());
1457 1 : ScDocument& rDoc = xDocSh->GetDocument();
1458 :
1459 : // A1
1460 2 : OUString aStr = rDoc.GetString(ScAddress(0,0,0));
1461 1 : CPPUNIT_ASSERT_EQUAL(OUString("Action Plan.Name"), aStr);
1462 :
1463 : // B1
1464 1 : aStr = rDoc.GetString(ScAddress(1,0,0));
1465 1 : CPPUNIT_ASSERT_EQUAL(OUString("Action Plan.Description"), aStr);
1466 :
1467 : // A2
1468 1 : aStr = rDoc.GetString(ScAddress(0,1,0));
1469 1 : CPPUNIT_ASSERT_EQUAL(OUString("Jerry"), aStr);
1470 :
1471 : // B2 - multi-line text.
1472 1 : const EditTextObject* pText = rDoc.GetEditText(ScAddress(1,1,0));
1473 1 : CPPUNIT_ASSERT(pText);
1474 1 : CPPUNIT_ASSERT(pText->GetParagraphCount() == 3);
1475 1 : aStr = pText->GetText(0);
1476 1 : CPPUNIT_ASSERT_EQUAL(OUString("This is a longer Text."), aStr);
1477 1 : aStr = pText->GetText(1);
1478 1 : CPPUNIT_ASSERT_EQUAL(OUString("Second line."), aStr);
1479 1 : aStr = pText->GetText(2);
1480 1 : CPPUNIT_ASSERT_EQUAL(OUString("Third line."), aStr);
1481 :
1482 2 : xDocSh->DoClose();
1483 1 : }
1484 :
1485 : #if !defined(MACOSX) && !defined(DRAGONFLY) && !defined(WNT)
1486 3 : void ScFiltersTest::testPassword_Impl(const OUString& aFileNameBase)
1487 : {
1488 3 : OUString aFileExtension(getFileFormats()[0].pName, strlen(getFileFormats()[0].pName), RTL_TEXTENCODING_UTF8 );
1489 6 : OUString aFilterName(getFileFormats()[0].pFilterName, strlen(getFileFormats()[0].pFilterName), RTL_TEXTENCODING_UTF8) ;
1490 6 : OUString aFileName;
1491 3 : createFileURL(aFileNameBase, aFileExtension, aFileName);
1492 6 : OUString aFilterType(getFileFormats()[0].pTypeName, strlen(getFileFormats()[0].pTypeName), RTL_TEXTENCODING_UTF8);
1493 :
1494 3 : SotClipboardFormatId nFormat = SotClipboardFormatId::STARCALC_8;
1495 : SfxFilter* aFilter = new SfxFilter(
1496 : aFilterName,
1497 3 : OUString(), getFileFormats()[0].nFormatType, nFormat, aFilterType, 0, OUString(),
1498 6 : OUString(), OUString("private:factory/scalc*") );
1499 3 : aFilter->SetVersion(SOFFICE_FILEFORMAT_CURRENT);
1500 :
1501 6 : ScDocShellRef xDocSh = new ScDocShell;
1502 3 : SfxMedium* pMedium = new SfxMedium(aFileName, STREAM_STD_READWRITE);
1503 3 : SfxItemSet* pSet = pMedium->GetItemSet();
1504 3 : pSet->Put(SfxStringItem(SID_PASSWORD, OUString("test")));
1505 3 : pMedium->SetFilter(aFilter);
1506 3 : if (!xDocSh->DoLoad(pMedium))
1507 : {
1508 0 : xDocSh->DoClose();
1509 : // load failed.
1510 0 : xDocSh.Clear();
1511 : }
1512 :
1513 3 : CPPUNIT_ASSERT_MESSAGE("Failed to load password.ods", xDocSh.Is());
1514 3 : xDocSh->GetDocument();
1515 6 : xDocSh->DoClose();
1516 3 : }
1517 :
1518 1 : void ScFiltersTest::testPasswordNew()
1519 : {
1520 : //tests opening a file with new password algorithm
1521 1 : const OUString aFileNameBase("password.");
1522 1 : testPassword_Impl(aFileNameBase);
1523 1 : }
1524 :
1525 1 : void ScFiltersTest::testPasswordOld()
1526 : {
1527 : //tests opening a file with old password algorithm
1528 1 : const OUString aFileNameBase("passwordOld.");
1529 1 : testPassword_Impl(aFileNameBase);
1530 1 : }
1531 :
1532 1 : void ScFiltersTest::testPasswordWrongSHA()
1533 : {
1534 : //tests opening a file wrongly using the new password algorithm
1535 : //in a sxc with the key algorithm missing
1536 1 : const OUString aFileNameBase("passwordWrongSHA.");
1537 1 : testPassword_Impl(aFileNameBase);
1538 1 : }
1539 : #endif
1540 :
1541 1 : void ScFiltersTest::testControlImport()
1542 : {
1543 1 : ScDocShellRef xDocSh = loadDoc("singlecontrol.", XLSX);
1544 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load singlecontrol.xlsx", xDocSh.Is());
1545 :
1546 2 : uno::Reference< frame::XModel > xModel = xDocSh->GetModel();
1547 2 : uno::Reference< sheet::XSpreadsheetDocument > xDoc(xModel, UNO_QUERY_THROW);
1548 2 : uno::Reference< container::XIndexAccess > xIA(xDoc->getSheets(), UNO_QUERY_THROW);
1549 2 : uno::Reference< drawing::XDrawPageSupplier > xDrawPageSupplier( xIA->getByIndex(0), UNO_QUERY_THROW);
1550 2 : uno::Reference< container::XIndexAccess > xIA_DrawPage(xDrawPageSupplier->getDrawPage(), UNO_QUERY_THROW);
1551 2 : uno::Reference< drawing::XControlShape > xControlShape(xIA_DrawPage->getByIndex(0), UNO_QUERY_THROW);
1552 :
1553 1 : CPPUNIT_ASSERT(xControlShape.is());
1554 2 : xDocSh->DoClose();
1555 1 : }
1556 :
1557 1 : void ScFiltersTest::testChartImportODS()
1558 : {
1559 1 : ScDocShellRef xDocSh = loadDoc("chart-import-basic.", ODS);
1560 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load chart-import-basic.ods.", xDocSh.Is());
1561 :
1562 1 : ScDocument& rDoc = xDocSh->GetDocument();
1563 :
1564 : // Ensure that the document contains "Empty", "Chart", "Data" and "Title" sheets in this exact order.
1565 2 : CPPUNIT_ASSERT_EQUAL_MESSAGE(
1566 : "There should be 4 sheets in this document.", sal_Int16(4),
1567 1 : rDoc.GetTableCount());
1568 2 : OUString aName;
1569 1 : rDoc.GetName(0, aName);
1570 1 : CPPUNIT_ASSERT_EQUAL(OUString("Empty"), aName);
1571 1 : rDoc.GetName(1, aName);
1572 1 : CPPUNIT_ASSERT_EQUAL(OUString("Chart"), aName);
1573 1 : rDoc.GetName(2, aName);
1574 1 : CPPUNIT_ASSERT_EQUAL(OUString("Data"), aName);
1575 1 : rDoc.GetName(3, aName);
1576 1 : CPPUNIT_ASSERT_EQUAL(OUString("Title"), aName);
1577 :
1578 : // Retrieve the chart object instance from the 2nd page (for the 2nd sheet).
1579 1 : const SdrOle2Obj* pOleObj = getSingleChartObject(rDoc, 1);
1580 1 : CPPUNIT_ASSERT_MESSAGE("Failed to retrieve a chart object from the 2nd sheet.", pOleObj);
1581 :
1582 2 : ScRangeList aRanges = getChartRanges(rDoc, *pOleObj);
1583 :
1584 1 : CPPUNIT_ASSERT_MESSAGE("Data series title cell not found.", aRanges.In(ScAddress(1,0,3))); // B1 on Title
1585 1 : CPPUNIT_ASSERT_MESSAGE("Data series label range not found.", aRanges.In(ScRange(0,1,2,0,3,2))); // A2:A4 on Data
1586 1 : CPPUNIT_ASSERT_MESSAGE("Data series value range not found.", aRanges.In(ScRange(1,1,2,1,3,2))); // B2:B4 on Data
1587 :
1588 2 : xDocSh->DoClose();
1589 1 : }
1590 :
1591 1 : void ScFiltersTest::testChartImportXLS()
1592 : {
1593 1 : ScDocShellRef xDocSh = loadDoc("chartx.", XLS);
1594 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load chartx.xls.", xDocSh.Is());
1595 :
1596 1 : ScDocument& rDoc = xDocSh->GetDocument();
1597 :
1598 : // Retrieve the chart object instance from the 2nd page (for the 2nd sheet).
1599 1 : const SdrOle2Obj* pOleObj = getSingleChartObject(rDoc, 0);
1600 1 : CPPUNIT_ASSERT_MESSAGE("Failed to retrieve a chart object from the 2nd sheet.", pOleObj);
1601 :
1602 1 : CPPUNIT_ASSERT_EQUAL(11148L, pOleObj->GetLogicRect().getWidth());
1603 1 : CPPUNIT_ASSERT(8640L > pOleObj->GetLogicRect().getHeight());
1604 :
1605 1 : xDocSh->DoClose();
1606 1 : }
1607 :
1608 1 : void ScFiltersTest::testNumberFormatHTML()
1609 : {
1610 1 : ScDocShellRef xDocSh = loadDoc("numberformat.", HTML);
1611 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load numberformat.html", xDocSh.Is());
1612 :
1613 1 : ScDocument& rDoc = xDocSh->GetDocument();
1614 :
1615 : // Check the header just in case.
1616 2 : CPPUNIT_ASSERT_EQUAL_MESSAGE(
1617 : "Cell value is not as expected", OUString("Product"),
1618 1 : rDoc.GetString(0, 0, 0));
1619 2 : CPPUNIT_ASSERT_EQUAL_MESSAGE(
1620 : "Cell value is not as expected", OUString("Price"),
1621 1 : rDoc.GetString(1, 0, 0));
1622 2 : CPPUNIT_ASSERT_EQUAL_MESSAGE(
1623 : "Cell value is not as expected", OUString("Note"),
1624 1 : rDoc.GetString(2, 0, 0));
1625 :
1626 : // B2 should be imported as a value cell.
1627 1 : bool bHasValue = rDoc.HasValueData(1, 1, 0);
1628 1 : CPPUNIT_ASSERT_MESSAGE("Fail to import number as a value cell.", bHasValue);
1629 2 : CPPUNIT_ASSERT_EQUAL_MESSAGE(
1630 1 : "Incorrect value.", 199.98, rDoc.GetValue(1, 1, 0));
1631 :
1632 1 : xDocSh->DoClose();
1633 1 : }
1634 :
1635 1 : void ScFiltersTest::testNumberFormatCSV()
1636 : {
1637 1 : ScDocShellRef xDocSh = loadDoc("numberformat.", CSV);
1638 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load numberformat.csv", xDocSh.Is());
1639 :
1640 1 : ScDocument& rDoc = xDocSh->GetDocument();
1641 :
1642 : // Check the header just in case.
1643 2 : CPPUNIT_ASSERT_EQUAL_MESSAGE(
1644 : "Cell value is not as expected", OUString("Product"),
1645 1 : rDoc.GetString(0, 0, 0));
1646 2 : CPPUNIT_ASSERT_EQUAL_MESSAGE(
1647 : "Cell value is not as expected", OUString("Price"),
1648 1 : rDoc.GetString(1, 0, 0));
1649 2 : CPPUNIT_ASSERT_EQUAL_MESSAGE(
1650 : "Cell value is not as expected", OUString("Note"),
1651 1 : rDoc.GetString(2, 0, 0));
1652 :
1653 : // B2 should be imported as a value cell.
1654 1 : bool bHasValue = rDoc.HasValueData(1, 1, 0);
1655 1 : CPPUNIT_ASSERT_MESSAGE("Fail to import number as a value cell.", bHasValue);
1656 2 : CPPUNIT_ASSERT_EQUAL_MESSAGE(
1657 1 : "Incorrect value.", 199.98, rDoc.GetValue(1, 1, 0));
1658 :
1659 1 : xDocSh->DoClose();
1660 1 : }
1661 :
1662 1 : void ScFiltersTest::testCellAnchoredShapesODS()
1663 : {
1664 1 : ScDocShellRef xDocSh = loadDoc("cell-anchored-shapes.", ODS);
1665 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load cell-anchored-shapes.ods", xDocSh.Is());
1666 :
1667 : // There are two cell-anchored objects on the first sheet.
1668 1 : ScDocument& rDoc = xDocSh->GetDocument();
1669 :
1670 1 : CPPUNIT_ASSERT_MESSAGE("There should be at least one sheet.", rDoc.GetTableCount() > 0);
1671 :
1672 1 : ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer();
1673 1 : SdrPage* pPage = pDrawLayer->GetPage(0);
1674 1 : CPPUNIT_ASSERT_MESSAGE("draw page for sheet 1 should exist.", pPage);
1675 1 : const size_t nCount = pPage->GetObjCount();
1676 2 : CPPUNIT_ASSERT_EQUAL_MESSAGE(
1677 1 : "There should be 2 objects.", static_cast<size_t>(2), nCount);
1678 3 : for (size_t i = 0; i < nCount; ++i)
1679 : {
1680 2 : SdrObject* pObj = pPage->GetObj(i);
1681 2 : CPPUNIT_ASSERT_MESSAGE("Failed to get drawing object.", pObj);
1682 2 : ScDrawObjData* pData = ScDrawLayer::GetObjData(pObj, false);
1683 2 : CPPUNIT_ASSERT_MESSAGE("Failed to retrieve user data for this object.", pData);
1684 2 : CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pData->maLastRect.IsEmpty());
1685 : }
1686 :
1687 1 : xDocSh->DoClose();
1688 1 : }
1689 :
1690 : namespace {
1691 :
1692 42 : class FindDimByName : std::unary_function<const ScDPSaveDimension*, bool>
1693 : {
1694 : OUString maName;
1695 : public:
1696 6 : FindDimByName(const OUString& rName) : maName(rName) {}
1697 :
1698 9 : bool operator() (const ScDPSaveDimension* p) const
1699 : {
1700 9 : return p && p->GetName() == maName;
1701 : }
1702 : };
1703 :
1704 6 : bool hasDimension(const std::vector<const ScDPSaveDimension*>& rDims, const OUString& aName)
1705 : {
1706 6 : return std::any_of(rDims.begin(), rDims.end(), FindDimByName(aName));
1707 : }
1708 :
1709 : }
1710 :
1711 1 : void ScFiltersTest::testPivotTableBasicODS()
1712 : {
1713 1 : ScDocShellRef xDocSh = loadDoc("pivot-table-basic.", ODS);
1714 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load pivot-table-basic.ods", xDocSh.Is());
1715 :
1716 1 : ScDocument& rDoc = xDocSh->GetDocument();
1717 2 : CPPUNIT_ASSERT_EQUAL_MESSAGE(
1718 : "There should be exactly two sheets.", sal_Int16(2),
1719 1 : rDoc.GetTableCount());
1720 :
1721 1 : ScDPCollection* pDPs = rDoc.GetDPCollection();
1722 1 : CPPUNIT_ASSERT_MESSAGE("Failed to get a live ScDPCollection instance.", pDPs);
1723 2 : CPPUNIT_ASSERT_EQUAL_MESSAGE(
1724 : "There should be exactly one pivot table instance.", size_t(1),
1725 1 : pDPs->GetCount());
1726 :
1727 1 : const ScDPObject* pDPObj = (*pDPs)[0];
1728 1 : CPPUNIT_ASSERT_MESSAGE("Failed to get an pivot table object.", pDPObj);
1729 1 : const ScDPSaveData* pSaveData = pDPObj->GetSaveData();
1730 1 : CPPUNIT_ASSERT_MESSAGE("Failed to get ScDPSaveData instance.", pSaveData);
1731 2 : std::vector<const ScDPSaveDimension*> aDims;
1732 :
1733 : // Row fields
1734 1 : pSaveData->GetAllDimensionsByOrientation(sheet::DataPilotFieldOrientation_ROW, aDims);
1735 2 : CPPUNIT_ASSERT_EQUAL_MESSAGE(
1736 : ("There should be exactly 3 row fields (2 normal dimensions and 1"
1737 : " layout dimension)."),
1738 1 : std::vector<ScDPSaveDimension const *>::size_type(3), aDims.size());
1739 1 : CPPUNIT_ASSERT_MESSAGE("Dimension expected, but not found.", hasDimension(aDims, "Row1"));
1740 1 : CPPUNIT_ASSERT_MESSAGE("Dimension expected, but not found.", hasDimension(aDims, "Row2"));
1741 1 : const ScDPSaveDimension* pDataLayout = pSaveData->GetExistingDataLayoutDimension();
1742 2 : CPPUNIT_ASSERT_MESSAGE("There should be a data layout field as a row field.",
1743 1 : pDataLayout && pDataLayout->GetOrientation() == sheet::DataPilotFieldOrientation_ROW);
1744 :
1745 : // Column fields
1746 1 : pSaveData->GetAllDimensionsByOrientation(sheet::DataPilotFieldOrientation_COLUMN, aDims);
1747 2 : CPPUNIT_ASSERT_EQUAL_MESSAGE(
1748 : "There should be exactly 2 column fields.",
1749 1 : std::vector<ScDPSaveDimension const *>::size_type(2), aDims.size());
1750 1 : CPPUNIT_ASSERT_MESSAGE("Dimension expected, but not found.", hasDimension(aDims, "Col1"));
1751 1 : CPPUNIT_ASSERT_MESSAGE("Dimension expected, but not found.", hasDimension(aDims, "Col2"));
1752 :
1753 : // Page fields
1754 1 : pSaveData->GetAllDimensionsByOrientation(sheet::DataPilotFieldOrientation_PAGE, aDims);
1755 2 : CPPUNIT_ASSERT_EQUAL_MESSAGE(
1756 : "There should be exactly 2 page fields.",
1757 1 : std::vector<ScDPSaveDimension const *>::size_type(2), aDims.size());
1758 1 : CPPUNIT_ASSERT_MESSAGE("Dimension expected, but not found.", hasDimension(aDims, "Page1"));
1759 1 : CPPUNIT_ASSERT_MESSAGE("Dimension expected, but not found.", hasDimension(aDims, "Page2"));
1760 :
1761 : // Check the data field.
1762 1 : pSaveData->GetAllDimensionsByOrientation(sheet::DataPilotFieldOrientation_DATA, aDims);
1763 2 : CPPUNIT_ASSERT_EQUAL_MESSAGE(
1764 : "There should be exactly 1 data field.",
1765 1 : std::vector<ScDPSaveDimension const *>::size_type(1), aDims.size());
1766 1 : const ScDPSaveDimension* pDim = aDims.back();
1767 2 : CPPUNIT_ASSERT_EQUAL_MESSAGE(
1768 : "Function for the data field should be COUNT.",
1769 1 : sal_uInt16(sheet::GeneralFunction_COUNT), pDim->GetFunction());
1770 :
1771 2 : xDocSh->DoClose();
1772 1 : }
1773 :
1774 1 : void ScFiltersTest::testPivotTableNamedRangeSourceODS()
1775 : {
1776 1 : ScDocShellRef xDocSh = loadDoc("pivot-table-named-range-source.", ODS);
1777 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load pivot-table-named-range-source.ods", xDocSh.Is());
1778 :
1779 1 : ScDocument& rDoc = xDocSh->GetDocument();
1780 :
1781 1 : ScDPCollection* pDPs = rDoc.GetDPCollection();
1782 1 : CPPUNIT_ASSERT(pDPs->GetCount() == 1);
1783 :
1784 1 : ScDPObject* pDP = (*pDPs)[0];
1785 1 : CPPUNIT_ASSERT(pDP);
1786 :
1787 : // Make sure this pivot table is based on a named range source.
1788 1 : const ScSheetSourceDesc* pDesc = pDP->GetSheetDesc();
1789 1 : CPPUNIT_ASSERT(pDesc);
1790 1 : CPPUNIT_ASSERT_EQUAL(OUString("MyRange"), pDesc->GetRangeName());
1791 :
1792 : sal_uInt16 nOrient;
1793 1 : long nDim = pDP->GetHeaderDim(ScAddress(0,1,1), nOrient);
1794 1 : CPPUNIT_ASSERT_MESSAGE("Failed to detect header dimension.", nDim == 0);
1795 2 : CPPUNIT_ASSERT_MESSAGE("This dimension should be a page dimension.",
1796 1 : nOrient == sheet::DataPilotFieldOrientation_PAGE);
1797 :
1798 1 : xDocSh->DoClose();
1799 1 : }
1800 :
1801 : namespace {
1802 :
1803 2 : bool checkVisiblePageFieldMember( const ScDPSaveDimension::MemberList& rMembers, const OUString& rVisibleMember )
1804 : {
1805 2 : ScDPSaveDimension::MemberList::const_iterator it = rMembers.begin(), itEnd = rMembers.end();
1806 2 : bool bFound = false;
1807 30 : for (; it != itEnd; ++it)
1808 : {
1809 28 : const ScDPSaveMember* pMem = *it;
1810 28 : if (pMem->GetName() == rVisibleMember)
1811 : {
1812 2 : bFound = true;
1813 2 : if (!pMem->GetIsVisible())
1814 : // This member is supposed to be visible. Fail.
1815 0 : return false;
1816 : }
1817 : else
1818 : {
1819 26 : if (pMem->GetIsVisible())
1820 : // This member is supposed to be hidden. Not good.
1821 0 : return false;
1822 : }
1823 : }
1824 :
1825 2 : return bFound;
1826 : }
1827 :
1828 : }
1829 :
1830 1 : void ScFiltersTest::testPivotTableSharedCacheGroupODS()
1831 : {
1832 1 : ScDocShellRef xDocSh = loadDoc("pivot-table-shared-cache-with-group.", ODS);
1833 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load file", xDocSh.Is());
1834 1 : ScDocument& rDoc = xDocSh->GetDocument();
1835 :
1836 : // Make sure that page field's visibility settings are loaded correctly.
1837 :
1838 1 : ScDPObject* pDPObj = rDoc.GetDPAtCursor(0, 0, 1); // A1 on 2nd sheet
1839 1 : CPPUNIT_ASSERT_MESSAGE("There should be a pivot table here.", pDPObj);
1840 1 : ScDPSaveData* pSaveData = pDPObj->GetSaveData();
1841 1 : CPPUNIT_ASSERT_MESSAGE("Save data is expected.", pSaveData);
1842 1 : ScDPSaveDimension* pDim = pSaveData->GetExistingDimensionByName("Project Name");
1843 1 : CPPUNIT_ASSERT_MESSAGE("Failed to get page field named 'Project Name'.", pDim);
1844 1 : const ScDPSaveDimension::MemberList* pMembers = &pDim->GetMembers();
1845 1 : CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(14), pMembers->size());
1846 1 : CPPUNIT_ASSERT_MESSAGE("Incorrect member visibility.", checkVisiblePageFieldMember(*pMembers, "APL-01-1"));
1847 :
1848 1 : pDPObj = rDoc.GetDPAtCursor(0, 1, 2); // A2 on 3rd sheet
1849 1 : CPPUNIT_ASSERT_MESSAGE("There should be a pivot table here.", pDPObj);
1850 1 : pSaveData = pDPObj->GetSaveData();
1851 1 : CPPUNIT_ASSERT_MESSAGE("Save data is expected.", pSaveData);
1852 1 : pDim = pSaveData->GetExistingDimensionByName("Project Name");
1853 1 : CPPUNIT_ASSERT_MESSAGE("Failed to get page field named 'Project Name'.", pDim);
1854 1 : pMembers = &pDim->GetMembers();
1855 1 : CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(14), pMembers->size());
1856 1 : CPPUNIT_ASSERT_MESSAGE("Incorrect member visibility.", checkVisiblePageFieldMember(*pMembers, "VEN-01-1"));
1857 :
1858 : // These two pivot tables share the same data range. We should only have
1859 : // one pivot cache.
1860 1 : ScDPCollection* pDPs = rDoc.GetDPCollection();
1861 1 : ScDPCollection::SheetCaches& rSheetCaches = pDPs->GetSheetCaches();
1862 1 : CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rSheetCaches.size());
1863 :
1864 : // Make sure that the cache contains all group field data upon load.
1865 1 : const ScSheetSourceDesc* pDesc = pDPObj->GetSheetDesc();
1866 1 : CPPUNIT_ASSERT_MESSAGE("Failed to get the pivot source description instance.", pDesc);
1867 1 : const ScDPCache* pCache = rSheetCaches.getExistingCache(pDesc->GetSourceRange());
1868 1 : CPPUNIT_ASSERT_MESSAGE("Pivot cache should exist for this range.", pCache);
1869 :
1870 1 : CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(9), pCache->GetFieldCount());
1871 1 : CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), pCache->GetGroupFieldCount());
1872 :
1873 1 : SCCOL nDim = pCache->GetDimensionIndex("StartDate");
1874 1 : CPPUNIT_ASSERT_MESSAGE("Dimension 'StartDate' doesn't exist in the cache.", nDim >= 0);
1875 1 : sal_Int32 nGrpType = pCache->GetGroupType(nDim);
1876 1 : CPPUNIT_ASSERT_EQUAL(sheet::DataPilotFieldGroupBy::DAYS, nGrpType);
1877 1 : const ScDPNumGroupInfo* pInfo = pCache->GetNumGroupInfo(nDim);
1878 1 : CPPUNIT_ASSERT_MESSAGE("Number group info doesn't exist in cache for 'StartDate'.", pInfo);
1879 :
1880 : // We should have two additional group fields and one should be years and
1881 : // the other should be month. The order is not guaranteed.
1882 :
1883 1 : bool bHasYears = false;
1884 1 : bool bHasMonths = false;
1885 2 : std::vector<SCROW> aMemberIds;
1886 :
1887 3 : for (long nGrpDim = 9; nGrpDim <= 10; ++nGrpDim)
1888 : {
1889 2 : nGrpType = pCache->GetGroupType(nGrpDim);
1890 2 : switch (nGrpType)
1891 : {
1892 : case sheet::DataPilotFieldGroupBy::MONTHS:
1893 : {
1894 1 : bHasMonths = true;
1895 1 : aMemberIds.clear();
1896 1 : pCache->GetGroupDimMemberIds(nGrpDim, aMemberIds);
1897 :
1898 : // There should be a total of 14 items for the month group: 12
1899 : // months plus the start and end value items.
1900 :
1901 1 : CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(14), aMemberIds.size());
1902 :
1903 1 : std::vector<sal_Int32> aGrpValues;
1904 15 : for (size_t i = 0, n = aMemberIds.size(); i < n; ++i)
1905 : {
1906 14 : const ScDPItemData* pItem = pCache->GetItemDataById(nGrpDim, aMemberIds[i]);
1907 14 : CPPUNIT_ASSERT_MESSAGE("Failed to get pivot item.", pItem);
1908 14 : CPPUNIT_ASSERT_EQUAL(ScDPItemData::GroupValue, pItem->GetType());
1909 14 : ScDPItemData::GroupValueAttr aGrpVal = pItem->GetGroupValue();
1910 14 : CPPUNIT_ASSERT_EQUAL(sheet::DataPilotFieldGroupBy::MONTHS, aGrpVal.mnGroupType);
1911 14 : aGrpValues.push_back(aGrpVal.mnValue);
1912 : }
1913 :
1914 1 : std::sort(aGrpValues.begin(), aGrpValues.end());
1915 2 : std::vector<sal_Int32> aChecks;
1916 1 : aChecks.push_back(ScDPItemData::DateFirst);
1917 13 : for (sal_Int32 i = 1; i <= 12; ++i)
1918 12 : aChecks.push_back(i); // January through December.
1919 1 : aChecks.push_back(ScDPItemData::DateLast);
1920 2 : CPPUNIT_ASSERT_MESSAGE("Unexpected group values for the month group.", aGrpValues == aChecks);
1921 : }
1922 1 : break;
1923 : case sheet::DataPilotFieldGroupBy::YEARS:
1924 : {
1925 1 : bHasYears = true;
1926 1 : aMemberIds.clear();
1927 1 : pCache->GetGroupDimMemberIds(nGrpDim, aMemberIds);
1928 :
1929 : // There should be a total of 4 items and they should be 2012,
1930 : // 2013 and the start and end value items.
1931 :
1932 1 : CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(4), aMemberIds.size());
1933 :
1934 1 : std::vector<sal_Int32> aGrpValues;
1935 5 : for (size_t i = 0, n = aMemberIds.size(); i < n; ++i)
1936 : {
1937 4 : const ScDPItemData* pItem = pCache->GetItemDataById(nGrpDim, aMemberIds[i]);
1938 4 : CPPUNIT_ASSERT_MESSAGE("Failed to get pivot item.", pItem);
1939 4 : CPPUNIT_ASSERT_EQUAL(ScDPItemData::GroupValue, pItem->GetType());
1940 4 : ScDPItemData::GroupValueAttr aGrpVal = pItem->GetGroupValue();
1941 4 : CPPUNIT_ASSERT_EQUAL(sheet::DataPilotFieldGroupBy::YEARS, aGrpVal.mnGroupType);
1942 4 : aGrpValues.push_back(aGrpVal.mnValue);
1943 : }
1944 :
1945 1 : std::sort(aGrpValues.begin(), aGrpValues.end());
1946 2 : std::vector<sal_Int32> aChecks;
1947 1 : aChecks.push_back(ScDPItemData::DateFirst);
1948 1 : aChecks.push_back(2012);
1949 1 : aChecks.push_back(2013);
1950 1 : aChecks.push_back(ScDPItemData::DateLast);
1951 2 : CPPUNIT_ASSERT_MESSAGE("Unexpected group values for the year group.", aGrpValues == aChecks);
1952 : }
1953 1 : break;
1954 : default:
1955 : ;
1956 : }
1957 : }
1958 :
1959 1 : CPPUNIT_ASSERT_MESSAGE("Pivot cache doesn't have an additional year group.", bHasYears);
1960 1 : CPPUNIT_ASSERT_MESSAGE("Pivot cache doesn't have an additional month group.", bHasMonths);
1961 :
1962 2 : xDocSh->DoClose();
1963 1 : }
1964 :
1965 1 : void ScFiltersTest::testGetPivotDataXLS()
1966 : {
1967 1 : ScDocShellRef xDocSh = loadDoc("pivot-getpivotdata.", XLS);
1968 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load file", xDocSh.Is());
1969 1 : ScDocument& rDoc = xDocSh->GetDocument();
1970 1 : rDoc.CalcAll();
1971 :
1972 : // Check GETPIVOTDATA results in E3:E20. Expected results are given in
1973 : // F3:F20.
1974 :
1975 19 : for (SCROW nRow = 2; nRow <= 19; ++nRow)
1976 18 : CPPUNIT_ASSERT_EQUAL(rDoc.GetValue(ScAddress(4,nRow,1)), rDoc.GetValue(ScAddress(5,nRow,1)));
1977 :
1978 1 : xDocSh->DoClose();
1979 1 : }
1980 :
1981 1 : void ScFiltersTest::testRowHeightODS()
1982 : {
1983 1 : ScDocShellRef xDocSh = loadDoc("row-height-import.", ODS);
1984 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load row-height-import.ods", xDocSh.Is());
1985 :
1986 1 : SCTAB nTab = 0;
1987 1 : SCROW nRow = 0;
1988 1 : ScDocument& rDoc = xDocSh->GetDocument();
1989 :
1990 : // The first 3 rows have manual heights.
1991 1 : int nHeight = rDoc.GetRowHeight(nRow, nTab, false);
1992 1 : bool bManual = rDoc.IsManualRowHeight(nRow, nTab);
1993 1 : CPPUNIT_ASSERT_EQUAL(600, nHeight);
1994 1 : CPPUNIT_ASSERT_MESSAGE("this row should have a manual row height.", bManual);
1995 1 : nHeight = rDoc.GetRowHeight(++nRow, nTab, false);
1996 1 : bManual = rDoc.IsManualRowHeight(nRow, nTab);
1997 1 : CPPUNIT_ASSERT_EQUAL(1200, nHeight);
1998 1 : CPPUNIT_ASSERT_MESSAGE("this row should have a manual row height.", bManual);
1999 1 : nHeight = rDoc.GetRowHeight(++nRow, nTab, false);
2000 1 : bManual = rDoc.IsManualRowHeight(nRow, nTab);
2001 1 : CPPUNIT_ASSERT_EQUAL(1800, nHeight);
2002 1 : CPPUNIT_ASSERT_MESSAGE("this row should have a manual row height.", bManual);
2003 :
2004 : // This one should have an automatic row height.
2005 1 : bManual = rDoc.IsManualRowHeight(++nRow, nTab);
2006 1 : CPPUNIT_ASSERT_MESSAGE("Row should have an automatic height.", !bManual);
2007 :
2008 : // Followed by a row with manual height.
2009 1 : nHeight = rDoc.GetRowHeight(++nRow, nTab, false);
2010 1 : bManual = rDoc.IsManualRowHeight(nRow, nTab);
2011 1 : CPPUNIT_ASSERT_EQUAL(2400, nHeight);
2012 1 : CPPUNIT_ASSERT_MESSAGE("this row should have a manual row height.", bManual);
2013 :
2014 : // And all the rest should have automatic heights.
2015 1 : bManual = rDoc.IsManualRowHeight(++nRow, nTab);
2016 1 : CPPUNIT_ASSERT_MESSAGE("Row should have an automatic height.", !bManual);
2017 :
2018 1 : bManual = rDoc.IsManualRowHeight(MAXROW, nTab);
2019 1 : CPPUNIT_ASSERT_MESSAGE("Row should have an automatic height.", !bManual);
2020 :
2021 1 : xDocSh->DoClose();
2022 1 : }
2023 :
2024 1 : void ScFiltersTest::testRichTextContentODS()
2025 : {
2026 1 : ScDocShellRef xDocSh = loadDoc("rich-text-cells.", ODS);
2027 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load rich-text-cells.ods", xDocSh.Is());
2028 1 : ScDocument& rDoc = xDocSh->GetDocument();
2029 :
2030 2 : OUString aTabName;
2031 1 : CPPUNIT_ASSERT_MESSAGE("Failed to get the name of the first sheet.", rDoc.GetName(0, aTabName));
2032 :
2033 : // All tested cells are in the first column.
2034 1 : ScAddress aPos(0, 0, 0);
2035 :
2036 : // Normal simple string with no formatting.
2037 1 : aPos.IncRow();
2038 1 : CPPUNIT_ASSERT_EQUAL(CELLTYPE_STRING, rDoc.GetCellType(aPos));
2039 1 : CPPUNIT_ASSERT_EQUAL(OUString("Normal"), rDoc.GetString(aPos.Col(), aPos.Row(), aPos.Tab()));
2040 :
2041 : // Normal string with bold applied to the whole cell.
2042 : {
2043 1 : aPos.IncRow();
2044 1 : CPPUNIT_ASSERT_EQUAL(CELLTYPE_STRING, rDoc.GetCellType(aPos));
2045 1 : CPPUNIT_ASSERT_EQUAL(OUString("All bold"), rDoc.GetString(aPos.Col(), aPos.Row(), aPos.Tab()));
2046 1 : const ScPatternAttr* pAttr = rDoc.GetPattern(aPos.Col(), aPos.Row(), aPos.Tab());
2047 1 : CPPUNIT_ASSERT_MESSAGE("Failed to get cell attribute.", pAttr);
2048 : const SvxWeightItem& rWeightItem =
2049 1 : static_cast<const SvxWeightItem&>(pAttr->GetItem(ATTR_FONT_WEIGHT));
2050 1 : CPPUNIT_ASSERT_EQUAL(WEIGHT_BOLD, rWeightItem.GetWeight());
2051 : }
2052 :
2053 : // This cell has an unformatted but multi-line content. Multi-line text is
2054 : // stored in edit cell even if it has no formatting applied.
2055 1 : aPos.IncRow();
2056 1 : CPPUNIT_ASSERT_EQUAL(CELLTYPE_EDIT, rDoc.GetCellType(aPos));
2057 1 : const EditTextObject* pEditText = rDoc.GetEditText(aPos);
2058 1 : CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
2059 1 : CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(3), pEditText->GetParagraphCount());
2060 2 : OUString aParaText = pEditText->GetText(0);
2061 1 : CPPUNIT_ASSERT_EQUAL(OUString("one"), aParaText);
2062 1 : aParaText = pEditText->GetText(1);
2063 1 : CPPUNIT_ASSERT_EQUAL(OUString("two"), aParaText);
2064 1 : aParaText = pEditText->GetText(2);
2065 1 : CPPUNIT_ASSERT_EQUAL(OUString("three"), aParaText);
2066 :
2067 : // Cell with sheet name field item.
2068 1 : aPos.IncRow();
2069 1 : CPPUNIT_ASSERT_EQUAL(CELLTYPE_EDIT, rDoc.GetCellType(aPos));
2070 1 : pEditText = rDoc.GetEditText(aPos);
2071 1 : CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
2072 1 : CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), pEditText->GetParagraphCount());
2073 1 : aParaText = pEditText->GetText(0);
2074 1 : CPPUNIT_ASSERT_MESSAGE("Unexpected text.", aParaText.startsWith("Sheet name is "));
2075 1 : CPPUNIT_ASSERT_MESSAGE("Sheet name field item not found.", pEditText->HasField(text::textfield::Type::TABLE));
2076 1 : CPPUNIT_ASSERT_EQUAL(OUString("Sheet name is Test."), ScEditUtil::GetString(*pEditText, &rDoc));
2077 1 : CPPUNIT_ASSERT_EQUAL(OUString("Sheet name is ?."), ScEditUtil::GetString(*pEditText, NULL));
2078 :
2079 : // Cell with URL field item.
2080 1 : aPos.IncRow();
2081 1 : CPPUNIT_ASSERT_EQUAL(CELLTYPE_EDIT, rDoc.GetCellType(aPos));
2082 1 : pEditText = rDoc.GetEditText(aPos);
2083 1 : CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
2084 1 : CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), pEditText->GetParagraphCount());
2085 1 : aParaText = pEditText->GetText(0);
2086 1 : CPPUNIT_ASSERT_MESSAGE("Unexpected text.", aParaText.startsWith("URL: "));
2087 1 : CPPUNIT_ASSERT_MESSAGE("URL field item not found.", pEditText->HasField(text::textfield::Type::URL));
2088 1 : CPPUNIT_ASSERT_EQUAL(OUString("URL: http://libreoffice.org"), ScEditUtil::GetString(*pEditText, &rDoc));
2089 1 : CPPUNIT_ASSERT_EQUAL(OUString("URL: http://libreoffice.org"), ScEditUtil::GetString(*pEditText, NULL));
2090 :
2091 : // Cell with Date field item.
2092 1 : aPos.IncRow();
2093 1 : CPPUNIT_ASSERT_EQUAL(CELLTYPE_EDIT, rDoc.GetCellType(aPos));
2094 1 : pEditText = rDoc.GetEditText(aPos);
2095 1 : CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
2096 1 : CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), pEditText->GetParagraphCount());
2097 1 : aParaText = pEditText->GetText(0);
2098 1 : CPPUNIT_ASSERT_MESSAGE("Unexpected text.", aParaText.startsWith("Date: "));
2099 1 : CPPUNIT_ASSERT_MESSAGE("Date field item not found.", pEditText->HasField(text::textfield::Type::DATE));
2100 1 : CPPUNIT_ASSERT_MESSAGE("Date field not resolved with rDoc.", ScEditUtil::GetString(*pEditText, &rDoc).indexOf("/20") > 0);
2101 1 : CPPUNIT_ASSERT_MESSAGE("Date field not resolved with NULL.", ScEditUtil::GetString(*pEditText, NULL).indexOf("/20") > 0);
2102 :
2103 : // Cell with DocInfo title field item.
2104 1 : aPos.IncRow();
2105 1 : CPPUNIT_ASSERT_EQUAL(CELLTYPE_EDIT, rDoc.GetCellType(aPos));
2106 1 : pEditText = rDoc.GetEditText(aPos);
2107 1 : CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
2108 1 : CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), pEditText->GetParagraphCount());
2109 1 : aParaText = pEditText->GetText(0);
2110 1 : CPPUNIT_ASSERT_MESSAGE("Unexpected text.", aParaText.startsWith("Title: "));
2111 1 : CPPUNIT_ASSERT_MESSAGE("DocInfo title field item not found.", pEditText->HasField(text::textfield::Type::DOCINFO_TITLE));
2112 1 : CPPUNIT_ASSERT_EQUAL(OUString("Title: Test Document"), ScEditUtil::GetString(*pEditText, &rDoc));
2113 1 : CPPUNIT_ASSERT_EQUAL(OUString("Title: ?"), ScEditUtil::GetString(*pEditText, NULL));
2114 :
2115 : // Cell with sentence with both bold and italic sequences.
2116 1 : aPos.IncRow();
2117 1 : CPPUNIT_ASSERT_EQUAL(CELLTYPE_EDIT, rDoc.GetCellType(aPos));
2118 1 : pEditText = rDoc.GetEditText(aPos);
2119 1 : CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
2120 1 : CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), pEditText->GetParagraphCount());
2121 1 : aParaText = pEditText->GetText(0);
2122 1 : CPPUNIT_ASSERT_EQUAL(OUString("Sentence with bold and italic."), aParaText);
2123 2 : std::vector<EECharAttrib> aAttribs;
2124 1 : pEditText->GetCharAttribs(0, aAttribs);
2125 1 : std::vector<EECharAttrib>::const_iterator it = aAttribs.begin(), itEnd = aAttribs.end();
2126 : {
2127 1 : bool bHasBold = false, bHasItalic = false;
2128 7 : for (; it != itEnd; ++it)
2129 : {
2130 6 : OUString aSeg = aParaText.copy(it->nStart, it->nEnd - it->nStart);
2131 6 : const SfxPoolItem* pAttr = it->pAttr;
2132 6 : if (aSeg == "bold" && pAttr->Which() == EE_CHAR_WEIGHT && !bHasBold)
2133 : {
2134 1 : const SvxWeightItem& rItem = static_cast<const SvxWeightItem&>(*pAttr);
2135 1 : bHasBold = (rItem.GetWeight() == WEIGHT_BOLD);
2136 : }
2137 5 : else if (aSeg == "italic" && pAttr->Which() == EE_CHAR_ITALIC && !bHasItalic)
2138 : {
2139 1 : const SvxPostureItem& rItem = static_cast<const SvxPostureItem&>(*pAttr);
2140 1 : bHasItalic = (rItem.GetPosture() == ITALIC_NORMAL);
2141 :
2142 : }
2143 6 : }
2144 1 : CPPUNIT_ASSERT_MESSAGE("This sentence is expected to have both bold and italic sequences.", bHasBold && bHasItalic);
2145 : }
2146 :
2147 : // Cell with multi-line content with formatting applied.
2148 1 : aPos.IncRow();
2149 1 : CPPUNIT_ASSERT_EQUAL(CELLTYPE_EDIT, rDoc.GetCellType(aPos));
2150 1 : pEditText = rDoc.GetEditText(aPos);
2151 1 : CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
2152 1 : CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(3), pEditText->GetParagraphCount());
2153 1 : aParaText = pEditText->GetText(0);
2154 1 : CPPUNIT_ASSERT_EQUAL(OUString("bold"), aParaText);
2155 1 : aParaText = pEditText->GetText(1);
2156 1 : CPPUNIT_ASSERT_EQUAL(OUString("italic"), aParaText);
2157 1 : aParaText = pEditText->GetText(2);
2158 1 : CPPUNIT_ASSERT_EQUAL(OUString("underlined"), aParaText);
2159 :
2160 : // first line is bold.
2161 1 : pEditText->GetCharAttribs(0, aAttribs);
2162 : {
2163 1 : bool bHasBold = false;
2164 1 : for (it = aAttribs.begin(), itEnd = aAttribs.end(); it != itEnd; ++it)
2165 : {
2166 1 : if (it->pAttr->Which() == EE_CHAR_WEIGHT)
2167 : {
2168 1 : const SvxWeightItem& rItem = static_cast<const SvxWeightItem&>(*it->pAttr);
2169 1 : bHasBold = (rItem.GetWeight() == WEIGHT_BOLD);
2170 1 : if (bHasBold)
2171 1 : break;
2172 : }
2173 : }
2174 1 : CPPUNIT_ASSERT_MESSAGE("First line should be bold.", bHasBold);
2175 : }
2176 :
2177 : // second line is italic.
2178 1 : pEditText->GetCharAttribs(1, aAttribs);
2179 1 : bool bHasItalic = false;
2180 1 : for (it = aAttribs.begin(), itEnd = aAttribs.end(); it != itEnd; ++it)
2181 : {
2182 1 : if (it->pAttr->Which() == EE_CHAR_ITALIC)
2183 : {
2184 1 : const SvxPostureItem& rItem = static_cast<const SvxPostureItem&>(*it->pAttr);
2185 1 : bHasItalic = (rItem.GetPosture() == ITALIC_NORMAL);
2186 1 : if (bHasItalic)
2187 1 : break;
2188 : }
2189 : }
2190 1 : CPPUNIT_ASSERT_MESSAGE("Second line should be italic.", bHasItalic);
2191 :
2192 : // third line is underlined.
2193 1 : pEditText->GetCharAttribs(2, aAttribs);
2194 1 : bool bHasUnderline = false;
2195 1 : for (it = aAttribs.begin(), itEnd = aAttribs.end(); it != itEnd; ++it)
2196 : {
2197 1 : if (it->pAttr->Which() == EE_CHAR_UNDERLINE)
2198 : {
2199 1 : const SvxUnderlineItem& rItem = static_cast<const SvxUnderlineItem&>(*it->pAttr);
2200 1 : bHasUnderline = (rItem.GetLineStyle() == UNDERLINE_SINGLE);
2201 1 : if (bHasUnderline)
2202 1 : break;
2203 : }
2204 : }
2205 1 : CPPUNIT_ASSERT_MESSAGE("Second line should be underlined.", bHasUnderline);
2206 :
2207 : // URL with formats applied. For now, we'll check whether or not the
2208 : // field objects gets imported. Later we should add checks for the
2209 : // formats.
2210 1 : aPos.IncRow();
2211 1 : pEditText = rDoc.GetEditText(aPos);
2212 1 : CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
2213 1 : CPPUNIT_ASSERT_MESSAGE("URL field item not found.", pEditText->HasField(text::textfield::Type::URL));
2214 :
2215 : // Sheet name with formats applied.
2216 1 : aPos.IncRow();
2217 1 : pEditText = rDoc.GetEditText(aPos);
2218 1 : CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
2219 1 : CPPUNIT_ASSERT_MESSAGE("Sheet name field item not found.", pEditText->HasField(text::textfield::Type::TABLE));
2220 :
2221 : // Date with formats applied.
2222 1 : aPos.IncRow();
2223 1 : pEditText = rDoc.GetEditText(aPos);
2224 1 : CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
2225 1 : CPPUNIT_ASSERT_MESSAGE("Date field item not found.", pEditText->HasField(text::textfield::Type::DATE));
2226 :
2227 : // Document title with formats applied.
2228 1 : aPos.IncRow();
2229 1 : pEditText = rDoc.GetEditText(aPos);
2230 1 : CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
2231 1 : CPPUNIT_ASSERT_MESSAGE("Date field item not found.", pEditText->HasField(text::textfield::Type::DOCINFO_TITLE));
2232 :
2233 : // URL for a file in the same directory. It should be converted into an absolute URL on import.
2234 1 : aPos.IncRow();
2235 1 : pEditText = rDoc.GetEditText(aPos);
2236 1 : CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
2237 1 : const SvxFieldData* pData = pEditText->GetFieldData(0, 0, text::textfield::Type::URL);
2238 1 : CPPUNIT_ASSERT_MESSAGE("Failed to get the URL data.", pData && pData->GetClassId() == text::textfield::Type::URL);
2239 1 : const SvxURLField* pURLData = static_cast<const SvxURLField*>(pData);
2240 1 : CPPUNIT_ASSERT_MESSAGE("URL is not absolute with respect to the file system.", pURLData->GetURL().startsWith("file:///"));
2241 :
2242 : // Embedded spaces as <text:s text:c='4' />, normal text
2243 1 : aPos.IncRow();
2244 1 : CPPUNIT_ASSERT_EQUAL(CELLTYPE_STRING, rDoc.GetCellType(aPos));
2245 1 : CPPUNIT_ASSERT_EQUAL(OUString("one two"), rDoc.GetString(aPos.Col(), aPos.Row(), aPos.Tab()));
2246 :
2247 : // Leading space as <text:s />.
2248 1 : aPos.IncRow();
2249 1 : CPPUNIT_ASSERT_EQUAL(CELLTYPE_STRING, rDoc.GetCellType(aPos));
2250 1 : CPPUNIT_ASSERT_EQUAL(OUString(" =3+4"), rDoc.GetString(aPos.Col(), aPos.Row(), aPos.Tab()));
2251 :
2252 : // Embedded spaces with <text:s text:c='4' /> inside a <text:span>, text
2253 : // partly bold.
2254 1 : aPos.IncRow();
2255 1 : CPPUNIT_ASSERT_EQUAL(CELLTYPE_EDIT, rDoc.GetCellType(aPos));
2256 1 : pEditText = rDoc.GetEditText(aPos);
2257 1 : CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
2258 1 : CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), pEditText->GetParagraphCount());
2259 1 : aParaText = pEditText->GetText(0);
2260 1 : CPPUNIT_ASSERT_EQUAL(OUString("one two"), aParaText);
2261 1 : pEditText->GetCharAttribs(0, aAttribs);
2262 : {
2263 1 : bool bHasBold = false;
2264 1 : for (it = aAttribs.begin(), itEnd = aAttribs.end(); it != itEnd; ++it)
2265 : {
2266 1 : if (it->pAttr->Which() == EE_CHAR_WEIGHT)
2267 : {
2268 1 : const SvxWeightItem& rItem = static_cast<const SvxWeightItem&>(*it->pAttr);
2269 1 : bHasBold = (rItem.GetWeight() == WEIGHT_BOLD);
2270 1 : if (bHasBold)
2271 : {
2272 1 : OUString aSeg = aParaText.copy(it->nStart, it->nEnd - it->nStart);
2273 1 : CPPUNIT_ASSERT_EQUAL(OUString("e t"), aSeg);
2274 1 : break;
2275 : }
2276 : }
2277 : }
2278 1 : CPPUNIT_ASSERT_MESSAGE("Expected a bold sequence.", bHasBold);
2279 : }
2280 :
2281 2 : xDocSh->DoClose();
2282 1 : }
2283 :
2284 1 : void ScFiltersTest::testDataBarODS()
2285 : {
2286 1 : ScDocShellRef xDocSh = loadDoc("databar.", ODS);
2287 1 : CPPUNIT_ASSERT(xDocSh.Is());
2288 :
2289 1 : ScDocument& rDoc = xDocSh->GetDocument();
2290 1 : testDataBar_Impl(rDoc);
2291 :
2292 1 : xDocSh->DoClose();
2293 1 : }
2294 :
2295 1 : void ScFiltersTest::testDataBarXLSX()
2296 : {
2297 1 : ScDocShellRef xDocSh = loadDoc("databar.", XLSX);
2298 1 : CPPUNIT_ASSERT(xDocSh.Is());
2299 :
2300 1 : ScDocument& rDoc = xDocSh->GetDocument();
2301 1 : testDataBar_Impl(rDoc);
2302 :
2303 1 : xDocSh->DoClose();
2304 1 : }
2305 :
2306 1 : void ScFiltersTest::testColorScaleODS()
2307 : {
2308 1 : ScDocShellRef xDocSh = loadDoc("colorscale.", ODS);
2309 1 : CPPUNIT_ASSERT(xDocSh.Is());
2310 1 : ScDocument& rDoc = xDocSh->GetDocument();
2311 :
2312 1 : testColorScale2Entry_Impl(rDoc);
2313 1 : testColorScale3Entry_Impl(rDoc);
2314 :
2315 1 : xDocSh->DoClose();
2316 1 : }
2317 :
2318 1 : void ScFiltersTest::testColorScaleXLSX()
2319 : {
2320 1 : ScDocShellRef xDocSh = loadDoc("colorscale.", XLSX);
2321 1 : CPPUNIT_ASSERT(xDocSh.Is());
2322 1 : ScDocument& rDoc = xDocSh->GetDocument();
2323 :
2324 1 : testColorScale2Entry_Impl(rDoc);
2325 1 : testColorScale3Entry_Impl(rDoc);
2326 :
2327 1 : xDocSh->DoClose();
2328 1 : }
2329 :
2330 1 : void ScFiltersTest::testNewCondFormatODS()
2331 : {
2332 1 : ScDocShellRef xDocSh = ScBootstrapFixture::loadDoc( "new_cond_format_test.", ODS );
2333 :
2334 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load new_cond_format_test.ods", xDocSh.Is());
2335 :
2336 1 : ScDocument& rDoc = xDocSh->GetDocument();
2337 :
2338 2 : OUString aCSVFile("new_cond_format_test.");
2339 2 : OUString aCSVPath;
2340 1 : createCSVPath( aCSVFile, aCSVPath );
2341 1 : testCondFile(aCSVPath, &rDoc, 0);
2342 :
2343 2 : xDocSh->DoClose();
2344 1 : }
2345 :
2346 1 : void ScFiltersTest::testNewCondFormatXLSX()
2347 : {
2348 1 : ScDocShellRef xDocSh = ScBootstrapFixture::loadDoc( "new_cond_format_test.", XLSX );
2349 :
2350 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load new_cond_format_test.xlsx", xDocSh.Is());
2351 :
2352 1 : ScDocument& rDoc = xDocSh->GetDocument();
2353 :
2354 2 : OUString aCSVFile("new_cond_format_test.");
2355 2 : OUString aCSVPath;
2356 1 : createCSVPath( aCSVFile, aCSVPath );
2357 1 : testCondFile(aCSVPath, &rDoc, 0);
2358 :
2359 2 : xDocSh->DoClose();
2360 1 : }
2361 :
2362 1 : void ScFiltersTest::testCondFormatThemeColorXLSX()
2363 : {
2364 1 : ScDocShellRef xDocSh = ScBootstrapFixture::loadDoc( "condformat_theme_color.", XLSX );
2365 :
2366 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load condformat_theme_color.xlsx", xDocSh.Is());
2367 :
2368 1 : ScDocument& rDoc = xDocSh->GetDocument();
2369 1 : ScConditionalFormat* pFormat = rDoc.GetCondFormat(0, 0, 0);
2370 1 : const ScFormatEntry* pEntry = pFormat->GetEntry(0);
2371 1 : CPPUNIT_ASSERT(pEntry);
2372 1 : CPPUNIT_ASSERT_EQUAL(pEntry->GetType(), condformat::DATABAR);
2373 1 : const ScDataBarFormat* pDataBar = static_cast<const ScDataBarFormat*>(pEntry);
2374 1 : const ScDataBarFormatData* pDataBarFormatData = pDataBar->GetDataBarData();
2375 :
2376 1 : CPPUNIT_ASSERT_EQUAL(Color(157, 195, 230), pDataBarFormatData->maPositiveColor);
2377 1 : CPPUNIT_ASSERT(pDataBarFormatData->mpNegativeColor.get());
2378 1 : CPPUNIT_ASSERT_EQUAL(Color(COL_LIGHTRED), *pDataBarFormatData->mpNegativeColor.get());
2379 :
2380 1 : CPPUNIT_ASSERT_EQUAL(size_t(1), rDoc.GetCondFormList(1)->size());
2381 1 : pFormat = rDoc.GetCondFormat(0, 0, 1);
2382 1 : CPPUNIT_ASSERT(pFormat);
2383 1 : CPPUNIT_ASSERT_EQUAL(size_t(1), pFormat->size());
2384 1 : pEntry = pFormat->GetEntry(0);
2385 1 : CPPUNIT_ASSERT(pEntry);
2386 1 : CPPUNIT_ASSERT_EQUAL(pEntry->GetType(), condformat::COLORSCALE);
2387 1 : const ScColorScaleFormat* pColorScale = static_cast<const ScColorScaleFormat*>(pEntry);
2388 1 : CPPUNIT_ASSERT_EQUAL(size_t(2), pColorScale->size());
2389 1 : const ScColorScaleEntry* pColorScaleEntry = pColorScale->GetEntry(0);
2390 1 : CPPUNIT_ASSERT(pColorScaleEntry);
2391 1 : CPPUNIT_ASSERT_EQUAL(Color(255, 230, 153), pColorScaleEntry->GetColor());
2392 :
2393 1 : pColorScaleEntry = pColorScale->GetEntry(1);
2394 1 : CPPUNIT_ASSERT(pColorScaleEntry);
2395 1 : CPPUNIT_ASSERT_EQUAL(Color(157, 195, 230), pColorScaleEntry->GetColor());
2396 1 : }
2397 :
2398 1 : void ScFiltersTest::testCondFormatThemeColor2XLSX()
2399 : {
2400 1 : ScDocShellRef xDocSh = ScBootstrapFixture::loadDoc( "cond_format_theme_color2.", XLSX );
2401 :
2402 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load cond_format_theme_color2.xlsx", xDocSh.Is());
2403 :
2404 1 : ScDocument& rDoc = xDocSh->GetDocument();
2405 1 : ScConditionalFormat* pFormat = rDoc.GetCondFormat(5, 5, 0);
2406 1 : CPPUNIT_ASSERT(pFormat);
2407 1 : const ScFormatEntry* pEntry = pFormat->GetEntry(0);
2408 1 : CPPUNIT_ASSERT(pEntry);
2409 1 : CPPUNIT_ASSERT_EQUAL(pEntry->GetType(), condformat::DATABAR);
2410 1 : const ScDataBarFormat* pDataBar = static_cast<const ScDataBarFormat*>(pEntry);
2411 1 : const ScDataBarFormatData* pDataBarFormatData = pDataBar->GetDataBarData();
2412 :
2413 1 : CPPUNIT_ASSERT_EQUAL(Color(99, 142, 198), pDataBarFormatData->maPositiveColor);
2414 1 : CPPUNIT_ASSERT(pDataBarFormatData->mpNegativeColor.get());
2415 1 : CPPUNIT_ASSERT_EQUAL(Color(217, 217, 217), *pDataBarFormatData->mpNegativeColor.get());
2416 1 : CPPUNIT_ASSERT_EQUAL(Color(197, 90, 17), pDataBarFormatData->maAxisColor);
2417 1 : }
2418 :
2419 : namespace {
2420 :
2421 3 : void testComplexIconSetsXLSX_Impl(ScDocument& rDoc, SCCOL nCol, ScIconSetType eType)
2422 : {
2423 3 : ScConditionalFormat* pFormat = rDoc.GetCondFormat(nCol, 1, 0);
2424 3 : CPPUNIT_ASSERT(pFormat);
2425 3 : CPPUNIT_ASSERT_EQUAL(size_t(1), pFormat->size());
2426 3 : const ScFormatEntry* pEntry = pFormat->GetEntry(0);
2427 3 : CPPUNIT_ASSERT(pEntry);
2428 3 : CPPUNIT_ASSERT_EQUAL(condformat::ICONSET, pEntry->GetType());
2429 3 : const ScIconSetFormat* pIconSet = static_cast<const ScIconSetFormat*>(pEntry);
2430 3 : CPPUNIT_ASSERT_EQUAL(eType, pIconSet->GetIconSetData()->eIconSetType);
2431 3 : }
2432 :
2433 8 : void testCustomIconSetsXLSX_Impl(ScDocument& rDoc, SCCOL nCol, SCROW nRow, ScIconSetType eType, sal_Int32 nIndex)
2434 : {
2435 8 : ScConditionalFormat* pFormat = rDoc.GetCondFormat(nCol, 1, 1);
2436 8 : CPPUNIT_ASSERT(pFormat);
2437 8 : CPPUNIT_ASSERT_EQUAL(size_t(1), pFormat->size());
2438 8 : const ScFormatEntry* pEntry = pFormat->GetEntry(0);
2439 8 : CPPUNIT_ASSERT(pEntry);
2440 8 : CPPUNIT_ASSERT_EQUAL(condformat::ICONSET, pEntry->GetType());
2441 8 : const ScIconSetFormat* pIconSet = static_cast<const ScIconSetFormat*>(pEntry);
2442 8 : std::unique_ptr<ScIconSetInfo> pInfo(pIconSet->GetIconSetInfo(ScAddress(nCol, nRow, 1)));
2443 8 : if (nIndex == -1)
2444 2 : CPPUNIT_ASSERT(!pInfo);
2445 : else
2446 : {
2447 6 : CPPUNIT_ASSERT(pInfo);
2448 6 : CPPUNIT_ASSERT_EQUAL(nIndex, pInfo->nIconIndex);
2449 6 : CPPUNIT_ASSERT_EQUAL(eType, pInfo->eIconSetType);
2450 8 : }
2451 8 : }
2452 :
2453 : }
2454 :
2455 1 : void ScFiltersTest::testComplexIconSetsXLSX()
2456 : {
2457 1 : ScDocShellRef xDocSh = ScBootstrapFixture::loadDoc( "complex_icon_set.", XLSX );
2458 :
2459 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load complex_icon_set.xlsx", xDocSh.Is());
2460 :
2461 1 : ScDocument& rDoc = xDocSh->GetDocument();
2462 1 : CPPUNIT_ASSERT_EQUAL(size_t(3), rDoc.GetCondFormList(0)->size());
2463 1 : testComplexIconSetsXLSX_Impl(rDoc, 1, IconSet_3Triangles);
2464 1 : testComplexIconSetsXLSX_Impl(rDoc, 3, IconSet_3Stars);
2465 1 : testComplexIconSetsXLSX_Impl(rDoc, 5, IconSet_5Boxes);
2466 :
2467 1 : CPPUNIT_ASSERT_EQUAL(size_t(2), rDoc.GetCondFormList(1)->size());
2468 1 : testCustomIconSetsXLSX_Impl(rDoc, 1, 1, IconSet_3ArrowsGray, 0);
2469 1 : testCustomIconSetsXLSX_Impl(rDoc, 1, 2, IconSet_3ArrowsGray, -1);
2470 1 : testCustomIconSetsXLSX_Impl(rDoc, 1, 3, IconSet_3Arrows, 1);
2471 1 : testCustomIconSetsXLSX_Impl(rDoc, 1, 4, IconSet_3ArrowsGray, -1);
2472 1 : testCustomIconSetsXLSX_Impl(rDoc, 1, 5, IconSet_3Arrows, 2);
2473 :
2474 1 : testCustomIconSetsXLSX_Impl(rDoc, 3, 1, IconSet_4RedToBlack, 3);
2475 1 : testCustomIconSetsXLSX_Impl(rDoc, 3, 2, IconSet_3TrafficLights1, 1);
2476 1 : testCustomIconSetsXLSX_Impl(rDoc, 3, 3, IconSet_3Arrows, 2);
2477 1 : }
2478 :
2479 1 : void ScFiltersTest::testCondFormatParentXLSX()
2480 : {
2481 1 : ScDocShellRef xDocSh = ScBootstrapFixture::loadDoc( "cond_parent.", XLSX );
2482 :
2483 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load cond_parent.xlsx", xDocSh.Is());
2484 :
2485 1 : ScDocument& rDoc = xDocSh->GetDocument();
2486 1 : const SfxItemSet* pCondSet = rDoc.GetCondResult(2, 5, 0);
2487 1 : const ScPatternAttr* pPattern = rDoc.GetPattern(2, 5, 0);
2488 1 : const SfxPoolItem& rPoolItem = pPattern->GetItem(ATTR_VER_JUSTIFY, pCondSet);
2489 1 : const SvxVerJustifyItem& rVerJustify = static_cast<const SvxVerJustifyItem&>(rPoolItem);
2490 1 : CPPUNIT_ASSERT_EQUAL(SVX_VER_JUSTIFY_TOP, static_cast<SvxCellVerJustify>(rVerJustify.GetValue()));
2491 1 : }
2492 :
2493 1 : void ScFiltersTest::testLiteralInFormulaXLS()
2494 : {
2495 1 : ScDocShellRef xDocSh = loadDoc("shared-string/literal-in-formula.", XLS);
2496 1 : CPPUNIT_ASSERT(xDocSh.Is());
2497 :
2498 1 : ScDocument& rDoc = xDocSh->GetDocument();
2499 1 : rDoc.CalcAll();
2500 :
2501 1 : CPPUNIT_ASSERT_EQUAL(2.0, rDoc.GetValue(ScAddress(0,0,0)));
2502 :
2503 1 : xDocSh->DoClose();
2504 1 : }
2505 :
2506 1 : void ScFiltersTest::testFormulaDependency()
2507 : {
2508 1 : ScDocShellRef xDocSh = ScBootstrapFixture::loadDoc( "dependencyTree.", ODS );
2509 :
2510 1 : ScDocument& rDoc = xDocSh->GetDocument();
2511 :
2512 : // check if formula in A1 changes value
2513 1 : double nVal = rDoc.GetValue(0,0,0);
2514 1 : CPPUNIT_ASSERT_DOUBLES_EQUAL(nVal, 1.0, 1e-10);
2515 1 : rDoc.SetValue(0,1,0, 0.0);
2516 1 : nVal = rDoc.GetValue(0,0,0);
2517 1 : CPPUNIT_ASSERT_DOUBLES_EQUAL(nVal, 2.0, 1e-10);
2518 :
2519 : // check that the number format is implicity inherited
2520 : // CPPUNIT_ASSERT_EQUAL(rDoc.GetString(0,4,0), rDoc.GetString(0,5,0));
2521 :
2522 1 : xDocSh->DoClose();
2523 1 : }
2524 :
2525 1 : void ScFiltersTest::testMiscRowHeights()
2526 : {
2527 : TestParam::RowData DfltRowData[] =
2528 : {
2529 : // check rows at the beginning and end of document
2530 : // and make sure they are reported as the default row
2531 : // height ( indicated by -1 )
2532 : { 2, 4, 0, -1, 0, false },
2533 : { 1048573, 1048575, 0, -1, 0, false },
2534 1 : };
2535 :
2536 : TestParam::RowData MultiLineOptData[] =
2537 : {
2538 : // Row 0 is 12.63 mm and optimal flag is set
2539 : { 0, 0, 0, 1263, CHECK_OPTIMAL, true },
2540 : // Row 1 is 11.99 mm and optimal flag is NOT set
2541 : { 1, 1, 0, 1199, CHECK_OPTIMAL, false },
2542 1 : };
2543 :
2544 : TestParam aTestValues[] =
2545 : {
2546 : /* Checks that a document saved to ods with default rows does indeed
2547 : have default row heights ( there was a problem where the optimal
2548 : height was being calcuated after import if no hard height )
2549 : */
2550 : { "alldefaultheights.", ODS, -1, SAL_N_ELEMENTS(DfltRowData), DfltRowData },
2551 : /* Checks the imported height of some multiline input, additionally checks
2552 : that the optimal height flag is set ( or not )
2553 : */
2554 : { "multilineoptimal.", ODS, -1, SAL_N_ELEMENTS(MultiLineOptData), MultiLineOptData },
2555 1 : };
2556 1 : miscRowHeightsTest( aTestValues, SAL_N_ELEMENTS(aTestValues) );
2557 1 : }
2558 :
2559 : // regression test at least fdo#59193
2560 : // what we want to test here is that when cell contents are deleted
2561 : // and the optimal flag is set for that row that the row is actually resized
2562 :
2563 1 : void ScFiltersTest::testOptimalHeightReset()
2564 : {
2565 1 : ScDocShellRef xDocSh = loadDoc("multilineoptimal.", ODS, true);
2566 1 : SCTAB nTab = 0;
2567 1 : SCROW nRow = 0;
2568 1 : ScDocument& rDoc = xDocSh->GetDocument();
2569 1 : rDoc.EnableAdjustHeight( true );
2570 : // open document in read/write mode ( otherwise optimal height stuff won't
2571 : // be triggered ) *and* you can't delete cell contents.
2572 1 : int nHeight = sc::TwipsToHMM ( rDoc.GetRowHeight(nRow, nTab, false) );
2573 1 : CPPUNIT_ASSERT_EQUAL(1263, nHeight);
2574 :
2575 1 : ScDocFunc &rFunc = xDocSh->GetDocFunc();
2576 :
2577 : // delete content of A1
2578 1 : ScRange aDelRange(0,0,0,0,0,0);
2579 2 : ScMarkData aMark;
2580 1 : aMark.SetMarkArea(aDelRange);
2581 1 : bool bRet = rFunc.DeleteContents( aMark, IDF_ALL, false, true );
2582 1 : CPPUNIT_ASSERT_MESSAGE("DeleteContents failed", bRet);
2583 :
2584 : // get the new height of A1
2585 1 : nHeight = sc::TwipsToHMM( rDoc.GetRowHeight(nRow, nTab, false) );
2586 :
2587 : // set optimal height for empty row 2
2588 2 : std::vector<sc::ColRowSpan> aRowArr(1, sc::ColRowSpan(2,2));
2589 1 : rFunc.SetWidthOrHeight(false, aRowArr, nTab, SC_SIZE_OPTIMAL, 0, true, true);
2590 :
2591 : // retrieve optimal height
2592 1 : int nOptimalHeight = sc::TwipsToHMM( rDoc.GetRowHeight(aRowArr[0].mnStart, nTab, false) );
2593 :
2594 : // check if the new height of A1 ( after delete ) is now the optimal height of an empty cell
2595 1 : CPPUNIT_ASSERT_EQUAL(nOptimalHeight, nHeight );
2596 2 : xDocSh->DoClose();
2597 1 : }
2598 :
2599 1 : void ScFiltersTest::testPrintRangeODS()
2600 : {
2601 1 : ScDocShellRef xDocSh = loadDoc("print-range.", ODS);
2602 1 : ScDocument& rDoc = xDocSh->GetDocument();
2603 1 : const ScRange* pRange = rDoc.GetRepeatRowRange(0);
2604 1 : CPPUNIT_ASSERT(pRange);
2605 1 : CPPUNIT_ASSERT_EQUAL(ScRange(0,0,0,0,1,0), *pRange);
2606 :
2607 1 : pRange = rDoc.GetRepeatRowRange(1);
2608 1 : CPPUNIT_ASSERT(pRange);
2609 1 : CPPUNIT_ASSERT_EQUAL(ScRange(0,2,0,0,4,0), *pRange);
2610 :
2611 1 : xDocSh->DoClose();
2612 1 : }
2613 :
2614 1 : void ScFiltersTest::testOutlineODS()
2615 : {
2616 1 : ScDocShellRef xDocSh = loadDoc("outline.", ODS);
2617 1 : ScDocument& rDoc = xDocSh->GetDocument();
2618 :
2619 1 : const ScOutlineTable* pTable = rDoc.GetOutlineTable(0);
2620 1 : CPPUNIT_ASSERT(pTable);
2621 :
2622 1 : const ScOutlineArray& rArr = pTable->GetRowArray();
2623 1 : size_t nDepth = rArr.GetDepth();
2624 1 : CPPUNIT_ASSERT_EQUAL(size_t(4), nDepth);
2625 :
2626 5 : for(size_t i = 0; i < nDepth; ++i)
2627 : {
2628 4 : CPPUNIT_ASSERT_EQUAL(size_t(1), rArr.GetCount(i));
2629 : }
2630 :
2631 : struct OutlineData {
2632 : SCCOLROW nStart;
2633 : SCCOLROW nEnd;
2634 : bool bHidden;
2635 : bool bVisible;
2636 :
2637 : size_t nDepth;
2638 : size_t nIndex;
2639 : };
2640 :
2641 : OutlineData aRow[] =
2642 : {
2643 : { 1, 29, false, true, 0, 0 },
2644 : { 2, 26, false, true, 1, 0 },
2645 : { 4, 23, false, true, 2, 0 },
2646 : { 6, 20, true, true, 3, 0 }
2647 1 : };
2648 :
2649 5 : for(size_t i = 0; i < SAL_N_ELEMENTS(aRow); ++i)
2650 : {
2651 :
2652 4 : const ScOutlineEntry* pEntry = rArr.GetEntry(aRow[i].nDepth, aRow[i].nIndex);
2653 4 : SCCOLROW nStart = pEntry->GetStart();
2654 4 : CPPUNIT_ASSERT_EQUAL(aRow[i].nStart, nStart);
2655 :
2656 4 : SCCOLROW nEnd = pEntry->GetEnd();
2657 4 : CPPUNIT_ASSERT_EQUAL(aRow[i].nEnd, nEnd);
2658 :
2659 4 : bool bHidden = pEntry->IsHidden();
2660 4 : CPPUNIT_ASSERT_EQUAL(aRow[i].bHidden, bHidden);
2661 :
2662 4 : bool bVisible = pEntry->IsVisible();
2663 4 : CPPUNIT_ASSERT_EQUAL(aRow[i].bVisible, bVisible);
2664 : }
2665 :
2666 1 : xDocSh->DoClose();
2667 1 : }
2668 :
2669 1 : void ScFiltersTest::testColumnStyleXLSX()
2670 : {
2671 1 : ScDocShellRef xDocSh = loadDoc("column-style.", XLSX);
2672 1 : CPPUNIT_ASSERT(xDocSh.Is());
2673 1 : ScDocument& rDoc = xDocSh->GetDocument();
2674 :
2675 1 : const ScPatternAttr* pPattern = rDoc.GetPattern(0,0,0);
2676 1 : CPPUNIT_ASSERT(pPattern);
2677 :
2678 1 : const ScProtectionAttr& rAttr = static_cast<const ScProtectionAttr&>(pPattern->GetItem(ATTR_PROTECTION));
2679 1 : CPPUNIT_ASSERT(rAttr.GetProtection());
2680 :
2681 1 : pPattern = rDoc.GetPattern(0,1,0);
2682 1 : CPPUNIT_ASSERT(pPattern);
2683 :
2684 1 : const ScProtectionAttr& rAttrNew = static_cast<const ScProtectionAttr&>(pPattern->GetItem(ATTR_PROTECTION));
2685 1 : CPPUNIT_ASSERT(!rAttrNew.GetProtection());
2686 :
2687 1 : xDocSh->DoClose();
2688 1 : }
2689 :
2690 1 : void ScFiltersTest::testSharedFormulaHorizontalXLS()
2691 : {
2692 1 : ScDocShellRef xDocSh = loadDoc("shared-formula/horizontal.", XLS);
2693 1 : CPPUNIT_ASSERT(xDocSh.Is());
2694 1 : ScDocument& rDoc = xDocSh->GetDocument();
2695 :
2696 : // Make sure K2:S2 on the 2nd sheet are all formula cells.
2697 1 : ScAddress aPos(0, 1, 1);
2698 10 : for (SCCOL nCol = 10; nCol <= 18; ++nCol)
2699 : {
2700 9 : aPos.SetCol(nCol);
2701 9 : CPPUNIT_ASSERT_MESSAGE("Formula cell is expected here.", rDoc.GetCellType(aPos) == CELLTYPE_FORMULA);
2702 : }
2703 :
2704 : // Likewise, B3:J9 all should be formula cells.
2705 10 : for (SCCOL nCol = 1; nCol <= 9; ++nCol)
2706 : {
2707 9 : aPos.SetCol(nCol);
2708 72 : for (SCROW nRow = 2; nRow <= 8; ++nRow)
2709 : {
2710 63 : aPos.SetRow(nRow);
2711 63 : CPPUNIT_ASSERT_MESSAGE("Formula cell is expected here.", rDoc.GetCellType(aPos) == CELLTYPE_FORMULA);
2712 : }
2713 : }
2714 :
2715 : // B2:I2 too.
2716 1 : aPos.SetRow(1);
2717 9 : for (SCCOL nCol = 1; nCol <= 8; ++nCol)
2718 : {
2719 8 : aPos.SetCol(nCol);
2720 8 : CPPUNIT_ASSERT_MESSAGE("Formula cell is expected here.", rDoc.GetCellType(aPos) == CELLTYPE_FORMULA);
2721 : }
2722 :
2723 : // J2 has a string of "MW".
2724 1 : aPos.SetCol(9);
2725 1 : CPPUNIT_ASSERT_EQUAL(OUString("MW"), rDoc.GetString(aPos));
2726 :
2727 1 : xDocSh->DoClose();
2728 1 : }
2729 :
2730 1 : void ScFiltersTest::testSharedFormulaWrappedRefsXLS()
2731 : {
2732 1 : ScDocShellRef xDocSh = loadDoc("shared-formula/wrapped-refs.", XLS);
2733 1 : CPPUNIT_ASSERT(xDocSh.Is());
2734 1 : ScDocument& rDoc = xDocSh->GetDocument();
2735 1 : rDoc.CalcAll();
2736 :
2737 : // Check the values of H7:H10.
2738 1 : CPPUNIT_ASSERT_EQUAL(7.0, rDoc.GetValue(ScAddress(7,6,0)));
2739 1 : CPPUNIT_ASSERT_EQUAL(8.0, rDoc.GetValue(ScAddress(7,7,0)));
2740 1 : CPPUNIT_ASSERT_EQUAL(9.0, rDoc.GetValue(ScAddress(7,8,0)));
2741 1 : CPPUNIT_ASSERT_EQUAL(10.0, rDoc.GetValue(ScAddress(7,9,0)));
2742 :
2743 : // EM7:EM10 should reference H7:H10.
2744 1 : CPPUNIT_ASSERT_EQUAL(7.0, rDoc.GetValue(ScAddress(142,6,0)));
2745 1 : CPPUNIT_ASSERT_EQUAL(8.0, rDoc.GetValue(ScAddress(142,7,0)));
2746 1 : CPPUNIT_ASSERT_EQUAL(9.0, rDoc.GetValue(ScAddress(142,8,0)));
2747 1 : CPPUNIT_ASSERT_EQUAL(10.0, rDoc.GetValue(ScAddress(142,9,0)));
2748 :
2749 : // Make sure EM7:EM10 are grouped.
2750 1 : const ScFormulaCell *pFC = rDoc.GetFormulaCell(ScAddress(142,6,0));
2751 1 : CPPUNIT_ASSERT(pFC);
2752 1 : CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(6), pFC->GetSharedTopRow());
2753 1 : CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(4), pFC->GetSharedLength());
2754 :
2755 1 : xDocSh->DoClose();
2756 1 : }
2757 :
2758 1 : void ScFiltersTest::testSharedFormulaBIFF5()
2759 : {
2760 1 : ScDocShellRef xDocSh = loadDoc("shared-formula/biff5.", XLS);
2761 1 : CPPUNIT_ASSERT(xDocSh.Is());
2762 1 : ScDocument& rDoc = xDocSh->GetDocument();
2763 1 : rDoc.CalcAll();
2764 :
2765 : // E6:E376 should be all formulas, and they should belong to the same group.
2766 1 : const ScFormulaCell* pFC = rDoc.GetFormulaCell(ScAddress(4,5,0));
2767 1 : CPPUNIT_ASSERT(pFC);
2768 1 : CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(5), pFC->GetSharedTopRow());
2769 1 : CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(371), pFC->GetSharedLength());
2770 :
2771 1 : xDocSh->DoClose();
2772 1 : }
2773 :
2774 1 : void ScFiltersTest::testSharedFormulaXLSB()
2775 : {
2776 1 : ScDocShellRef xDocSh = loadDoc("shared_formula.", XLSB);
2777 1 : CPPUNIT_ASSERT(xDocSh.Is());
2778 1 : ScDocument& rDoc = xDocSh->GetDocument();
2779 1 : rDoc.CalcAll();
2780 :
2781 : // A1:A30 should be all formulas, and they should belong to the same group.
2782 1 : const ScFormulaCell* pFC = rDoc.GetFormulaCell(ScAddress(0,0,0));
2783 1 : CPPUNIT_ASSERT(pFC);
2784 1 : CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(0), pFC->GetSharedTopRow());
2785 1 : CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(30), pFC->GetSharedLength());
2786 :
2787 31 : for(SCROW nRow = 0; nRow < 30; ++nRow)
2788 : {
2789 30 : ASSERT_DOUBLES_EQUAL(3.0, rDoc.GetValue(0, nRow, 0));
2790 : }
2791 :
2792 1 : xDocSh->DoClose();
2793 1 : }
2794 :
2795 1 : void ScFiltersTest::testSharedFormulaXLS()
2796 : {
2797 : {
2798 : // fdo#80091
2799 1 : ScDocShellRef xDocSh = loadDoc("shared-formula/relative-refs1.", XLS);
2800 1 : CPPUNIT_ASSERT(xDocSh.Is());
2801 1 : ScDocument& rDoc = xDocSh->GetDocument();
2802 1 : rDoc.CalcAll();
2803 :
2804 : // A1:A30 should be all formulas, and they should belong to the same group.
2805 1 : const ScFormulaCell* pFC = rDoc.GetFormulaCell(ScAddress(0,1,0));
2806 1 : CPPUNIT_ASSERT(pFC);
2807 1 : CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(1), pFC->GetSharedTopRow());
2808 1 : CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(29), pFC->GetSharedLength());
2809 :
2810 31 : for(SCROW nRow = 0; nRow < 30; ++nRow)
2811 : {
2812 30 : ASSERT_DOUBLES_EQUAL(double(nRow+1), rDoc.GetValue(0, nRow, 0));
2813 : }
2814 :
2815 1 : xDocSh->DoClose();
2816 : }
2817 :
2818 : {
2819 : // fdo#84556 and some related tests
2820 1 : ScDocShellRef xDocSh = loadDoc("shared-formula/relative-refs2.", XLS);
2821 1 : CPPUNIT_ASSERT(xDocSh.Is());
2822 1 : ScDocument& rDoc = xDocSh->GetDocument();
2823 1 : rDoc.CalcAll();
2824 :
2825 : {
2826 1 : const ScFormulaCell* pFC = rDoc.GetFormulaCell(ScAddress(2,1,0));
2827 1 : CPPUNIT_ASSERT(pFC);
2828 1 : CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(1), pFC->GetSharedTopRow());
2829 1 : CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(10), pFC->GetSharedLength());
2830 :
2831 1 : pFC = rDoc.GetFormulaCell(ScAddress(2,10,0));
2832 1 : CPPUNIT_ASSERT(pFC);
2833 1 : CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(1), pFC->GetSharedTopRow());
2834 1 : CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(10), pFC->GetSharedLength());
2835 :
2836 1 : OUString aFormula;
2837 1 : rDoc.GetFormula(2, 1, 0, aFormula);
2838 1 : CPPUNIT_ASSERT_EQUAL(OUString("=SUM(B9:D9)"), aFormula);
2839 :
2840 1 : rDoc.GetFormula(2, 10, 0, aFormula);
2841 1 : CPPUNIT_ASSERT_EQUAL(OUString("=SUM(B18:D18)"), aFormula);
2842 : }
2843 :
2844 : {
2845 1 : const ScFormulaCell* pFC = rDoc.GetFormulaCell(ScAddress(4,8,0));
2846 1 : CPPUNIT_ASSERT(pFC);
2847 1 : CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(8), pFC->GetSharedTopRow());
2848 1 : CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(10), pFC->GetSharedLength());
2849 :
2850 1 : pFC = rDoc.GetFormulaCell(ScAddress(4,17,0));
2851 1 : CPPUNIT_ASSERT(pFC);
2852 1 : CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(8), pFC->GetSharedTopRow());
2853 1 : CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(10), pFC->GetSharedLength());
2854 :
2855 1 : OUString aFormula;
2856 1 : rDoc.GetFormula(4, 8, 0, aFormula);
2857 1 : CPPUNIT_ASSERT_EQUAL(OUString("=SUM(G9:EY9)"), aFormula);
2858 :
2859 1 : rDoc.GetFormula(4, 17, 0, aFormula);
2860 1 : CPPUNIT_ASSERT_EQUAL(OUString("=SUM(G18:EY18)"), aFormula);
2861 : }
2862 :
2863 : {
2864 1 : const ScFormulaCell* pFC = rDoc.GetFormulaCell(ScAddress(6,15,0));
2865 1 : CPPUNIT_ASSERT(pFC);
2866 1 : CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(15), pFC->GetSharedTopRow());
2867 1 : CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(10), pFC->GetSharedLength());
2868 :
2869 1 : pFC = rDoc.GetFormulaCell(ScAddress(6,24,0));
2870 1 : CPPUNIT_ASSERT(pFC);
2871 1 : CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(15), pFC->GetSharedTopRow());
2872 1 : CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(10), pFC->GetSharedLength());
2873 :
2874 1 : OUString aFormula;
2875 1 : rDoc.GetFormula(6, 15, 0, aFormula);
2876 1 : CPPUNIT_ASSERT_EQUAL(OUString("=SUM(A16:A40000)"), aFormula);
2877 :
2878 1 : rDoc.GetFormula(6, 24, 0, aFormula);
2879 1 : CPPUNIT_ASSERT_EQUAL(OUString("=SUM(A25:A40009)"), aFormula);
2880 : }
2881 :
2882 1 : xDocSh->DoClose();
2883 : }
2884 1 : }
2885 :
2886 1 : void ScFiltersTest::testExternalRefCacheXLSX()
2887 : {
2888 1 : ScDocShellRef xDocSh = loadDoc("external-refs.", XLSX);
2889 1 : CPPUNIT_ASSERT(xDocSh.Is());
2890 1 : ScDocument& rDoc = xDocSh->GetDocument();
2891 :
2892 : // These string values are cached external cell values.
2893 1 : CPPUNIT_ASSERT_EQUAL(OUString("Name"), rDoc.GetString(ScAddress(0,0,0)));
2894 1 : CPPUNIT_ASSERT_EQUAL(OUString("Andy"), rDoc.GetString(ScAddress(0,1,0)));
2895 1 : CPPUNIT_ASSERT_EQUAL(OUString("Bruce"), rDoc.GetString(ScAddress(0,2,0)));
2896 1 : CPPUNIT_ASSERT_EQUAL(OUString("Charlie"), rDoc.GetString(ScAddress(0,3,0)));
2897 :
2898 1 : xDocSh->DoClose();
2899 1 : }
2900 :
2901 1 : void ScFiltersTest::testExternalRefCacheODS()
2902 : {
2903 1 : ScDocShellRef xDocSh = loadDoc("external-ref-cache.", ODS);
2904 :
2905 1 : CPPUNIT_ASSERT(xDocSh.Is());
2906 1 : ScDocument& rDoc = xDocSh->GetDocument();
2907 :
2908 : // Cells B2:B4 have VLOOKUP with external references which should all show "text".
2909 1 : CPPUNIT_ASSERT_EQUAL(OUString("text"), rDoc.GetString(ScAddress(1,1,0)));
2910 1 : CPPUNIT_ASSERT_EQUAL(OUString("text"), rDoc.GetString(ScAddress(1,2,0)));
2911 1 : CPPUNIT_ASSERT_EQUAL(OUString("text"), rDoc.GetString(ScAddress(1,3,0)));
2912 :
2913 : // Both cells A6 and A7 should be registered with scExternalRefManager properly
2914 1 : CPPUNIT_ASSERT_EQUAL(true, rDoc.GetExternalRefManager()->hasCellExternalReference(ScAddress(0, 5, 0)));
2915 1 : CPPUNIT_ASSERT_EQUAL(true, rDoc.GetExternalRefManager()->hasCellExternalReference(ScAddress(0, 6, 0)));
2916 :
2917 1 : xDocSh->DoClose();
2918 1 : }
2919 :
2920 1 : void ScFiltersTest::testHybridSharedStringODS()
2921 : {
2922 1 : ScDocShellRef xDocSh = loadDoc("hybrid-shared-string.", ODS);
2923 :
2924 1 : CPPUNIT_ASSERT(xDocSh.Is());
2925 1 : ScDocument& rDoc = xDocSh->GetDocument();
2926 :
2927 : // A2 contains formula with MATCH function. The result must be 2, not #N/A!
2928 1 : CPPUNIT_ASSERT_EQUAL(2.0, rDoc.GetValue(ScAddress(0,1,0)));
2929 :
2930 1 : xDocSh->DoClose();
2931 1 : }
2932 :
2933 1 : void ScFiltersTest::testCopyMergedNumberFormats()
2934 : {
2935 1 : ScDocShellRef xDocSh = loadDoc("copy-merged-number-formats.", ODS);
2936 1 : CPPUNIT_ASSERT(xDocSh.Is());
2937 1 : ScDocument& rDoc = xDocSh->GetDocument();
2938 :
2939 : // Cells B1, C1 and D1 are formatted as dates.
2940 2 : OUString aStrB1 = rDoc.GetString(ScAddress(1,0,0));
2941 2 : OUString aStrC1 = rDoc.GetString(ScAddress(2,0,0));
2942 2 : OUString aStrD1 = rDoc.GetString(ScAddress(3,0,0));
2943 :
2944 2 : ScDocument aCopyDoc;
2945 1 : aCopyDoc.InsertTab(0, "CopyHere");
2946 1 : rDoc.CopyStaticToDocument(ScRange(1,0,0,3,0,0), 0, &aCopyDoc);
2947 :
2948 : // Make sure the date formats are copied to the new document.
2949 1 : CPPUNIT_ASSERT_EQUAL(aStrB1, aCopyDoc.GetString(ScAddress(1,0,0)));
2950 1 : CPPUNIT_ASSERT_EQUAL(aStrC1, aCopyDoc.GetString(ScAddress(2,0,0)));
2951 1 : CPPUNIT_ASSERT_EQUAL(aStrD1, aCopyDoc.GetString(ScAddress(3,0,0)));
2952 :
2953 2 : xDocSh->DoClose();
2954 1 : }
2955 :
2956 1 : void ScFiltersTest::testVBAUserFunctionXLSM()
2957 : {
2958 1 : ScDocShellRef xDocSh = loadDoc("vba-user-function.", XLSM);
2959 1 : CPPUNIT_ASSERT(xDocSh.Is());
2960 1 : ScDocument& rDoc = xDocSh->GetDocument();
2961 :
2962 : // A1 contains formula with user-defined function, and the function is defined in VBA.
2963 1 : ScFormulaCell* pFC = rDoc.GetFormulaCell(ScAddress(0,0,0));
2964 1 : CPPUNIT_ASSERT(pFC);
2965 :
2966 2 : sc::CompileFormulaContext aCxt(&rDoc);
2967 2 : OUString aFormula = pFC->GetFormula(aCxt);
2968 :
2969 1 : CPPUNIT_ASSERT_EQUAL(OUString("=MYFUNC()"), aFormula);
2970 :
2971 : // Check the formula state after the load.
2972 1 : sal_uInt16 nErrCode = pFC->GetErrCode();
2973 1 : CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt16>(0), nErrCode);
2974 :
2975 : // Check the result.
2976 1 : CPPUNIT_ASSERT_EQUAL(42.0, rDoc.GetValue(ScAddress(0,0,0)));
2977 :
2978 2 : xDocSh->DoClose();
2979 1 : }
2980 :
2981 1 : void ScFiltersTest::testEmbeddedImageXLS()
2982 : {
2983 : // The document has one embedded image on the first sheet. Make sure it's
2984 : // imported properly.
2985 :
2986 1 : ScDocShellRef xDocSh = loadDoc("file-with-png-image.", XLS);
2987 1 : CPPUNIT_ASSERT(xDocSh.Is());
2988 1 : ScDocument& rDoc = xDocSh->GetDocument();
2989 :
2990 1 : ScDrawLayer* pDL = rDoc.GetDrawLayer();
2991 1 : CPPUNIT_ASSERT(pDL);
2992 1 : const SdrPage* pPage = pDL->GetPage(0);
2993 1 : CPPUNIT_ASSERT(pPage);
2994 1 : const SdrObject* pObj = pPage->GetObj(0);
2995 1 : CPPUNIT_ASSERT(pObj);
2996 1 : const SdrGrafObj* pImageObj = dynamic_cast<const SdrGrafObj*>(pObj);
2997 1 : CPPUNIT_ASSERT(pImageObj);
2998 1 : const Graphic& rGrf = pImageObj->GetGraphic();
2999 2 : BitmapEx aBMP = rGrf.GetBitmapEx();
3000 1 : CPPUNIT_ASSERT_MESSAGE("Bitmap content should not be empty if the image has been properly imported.", !aBMP.IsEmpty());
3001 :
3002 2 : xDocSh->DoClose();
3003 1 : }
3004 :
3005 1 : void ScFiltersTest::testErrorOnExternalReferences()
3006 : {
3007 1 : ScDocShellRef xDocSh = loadDoc("blank.", ODS);
3008 1 : CPPUNIT_ASSERT_MESSAGE("Failed to open empty doc", xDocSh.Is());
3009 :
3010 1 : ScDocument& rDoc = xDocSh->GetDocument();
3011 :
3012 : // Test tdf#89330
3013 1 : rDoc.SetString(ScAddress(0,0,0), "='file:///Path/To/FileA.ods'#$Sheet1.A1A");
3014 :
3015 1 : ScFormulaCell* pFC = rDoc.GetFormulaCell(ScAddress(0,0,0));
3016 1 : CPPUNIT_ASSERT(pFC);
3017 1 : CPPUNIT_ASSERT_EQUAL(ScErrorCodes::errNoName, pFC->GetErrCode());
3018 :
3019 1 : if (!checkFormula(rDoc, ScAddress(0,0,0), "'file:///Path/To/FileA.ods'#$Sheet1.A1A"))
3020 0 : CPPUNIT_FAIL("Formula changed");
3021 :
3022 1 : xDocSh->DoClose();
3023 1 : }
3024 :
3025 1 : void ScFiltersTest::testEditEngStrikeThroughXLSX()
3026 : {
3027 1 : ScDocShellRef xDocSh = loadDoc("strike-through.", XLSX);
3028 1 : CPPUNIT_ASSERT_MESSAGE("Failed to open doc", xDocSh.Is());
3029 :
3030 1 : ScDocument& rDoc = xDocSh->GetDocument();
3031 :
3032 1 : const EditTextObject* pObj = rDoc.GetEditText(ScAddress(0, 0, 0));
3033 1 : CPPUNIT_ASSERT(pObj);
3034 1 : CPPUNIT_ASSERT_EQUAL(sal_Int32(1), pObj->GetParagraphCount());
3035 1 : CPPUNIT_ASSERT_EQUAL(OUString("this is strike through this not"), pObj->GetText(0));
3036 :
3037 2 : std::vector<EECharAttrib> aAttribs;
3038 1 : pObj->GetCharAttribs(0, aAttribs);
3039 18 : for (std::vector<EECharAttrib>::const_iterator itr = aAttribs.begin(); itr != aAttribs.end(); ++itr)
3040 : {
3041 17 : if (itr->pAttr->Which() == EE_CHAR_STRIKEOUT)
3042 : {
3043 2 : const SvxCrossedOutItem& rItem = static_cast<const SvxCrossedOutItem&>(*itr->pAttr);
3044 2 : if (itr->nStart == 0)
3045 : {
3046 1 : CPPUNIT_ASSERT(rItem.GetStrikeout() != STRIKEOUT_NONE);
3047 : }
3048 : else
3049 : {
3050 1 : CPPUNIT_ASSERT_EQUAL(STRIKEOUT_NONE, rItem.GetStrikeout());
3051 : }
3052 : }
3053 : }
3054 :
3055 2 : xDocSh->DoClose();
3056 1 : }
3057 :
3058 1 : void ScFiltersTest::testRefStringXLSX()
3059 : {
3060 1 : ScDocShellRef xDocSh = loadDoc("ref_string.", XLSX);
3061 1 : CPPUNIT_ASSERT_MESSAGE("Failed to open doc", xDocSh.Is());
3062 :
3063 1 : ScDocument& rDoc = xDocSh->GetDocument();
3064 :
3065 1 : double nVal = rDoc.GetValue(2, 2, 0);
3066 1 : ASSERT_DOUBLES_EQUAL(3.0, nVal);
3067 :
3068 1 : const ScCalcConfig& rCalcConfig = rDoc.GetCalcConfig();
3069 1 : CPPUNIT_ASSERT_EQUAL(formula::FormulaGrammar::CONV_XL_A1, rCalcConfig.meStringRefAddressSyntax);
3070 :
3071 1 : xDocSh->DoClose();
3072 1 : }
3073 :
3074 79 : ScFiltersTest::ScFiltersTest()
3075 79 : : ScBootstrapFixture( "sc/qa/unit/data" )
3076 : {
3077 79 : }
3078 :
3079 79 : void ScFiltersTest::setUp()
3080 : {
3081 79 : test::BootstrapFixture::setUp();
3082 :
3083 : // This is a bit of a fudge, we do this to ensure that ScGlobals::ensure,
3084 : // which is a private symbol to us, gets called
3085 158 : m_xCalcComponent =
3086 237 : getMultiServiceFactory()->createInstance("com.sun.star.comp.Calc.SpreadsheetDocument");
3087 79 : CPPUNIT_ASSERT_MESSAGE("no calc component!", m_xCalcComponent.is());
3088 79 : }
3089 :
3090 79 : void ScFiltersTest::tearDown()
3091 : {
3092 79 : uno::Reference< lang::XComponent >( m_xCalcComponent, UNO_QUERY_THROW )->dispose();
3093 79 : test::BootstrapFixture::tearDown();
3094 79 : }
3095 :
3096 1 : CPPUNIT_TEST_SUITE_REGISTRATION(ScFiltersTest);
3097 :
3098 4 : CPPUNIT_PLUGIN_IMPLEMENT();
3099 :
3100 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
3101 :
|