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