update credits
[LibreOffice.git] / sc / qa / unit / subsequent_filters-test.cxx
blob662c802c5d6c6fa4d702766d6b8dd67c349f9174
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #include <sal/config.h>
11 #include <unotest/filters-test.hxx>
12 #include <test/bootstrapfixture.hxx>
13 #include <rtl/strbuf.hxx>
14 #include <osl/file.hxx>
16 #include <sfx2/app.hxx>
17 #include <sfx2/docfilt.hxx>
18 #include <sfx2/docfile.hxx>
19 #include <sfx2/sfxmodelfactory.hxx>
20 #include <svl/stritem.hxx>
21 #include "svx/svdpage.hxx"
22 #include "svx/svdoole2.hxx"
24 #include "editeng/wghtitem.hxx"
25 #include "editeng/postitem.hxx"
26 #include "editeng/udlnitem.hxx"
27 #include "editeng/editobj.hxx"
28 #include <editeng/brushitem.hxx>
29 #include <editeng/justifyitem.hxx>
30 #include <editeng/borderline.hxx>
31 #include "editeng/flditem.hxx"
32 #include <dbdata.hxx>
33 #include "validat.hxx"
34 #include "formulacell.hxx"
35 #include "drwlayer.hxx"
36 #include "userdat.hxx"
37 #include "dpobject.hxx"
38 #include "dpsave.hxx"
39 #include "stlsheet.hxx"
40 #include "docfunc.hxx"
41 #include "markdata.hxx"
42 #include "colorscale.hxx"
43 #include "editutil.hxx"
45 #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
46 #include <com/sun/star/drawing/XControlShape.hpp>
47 #include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
48 #include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
49 #include <com/sun/star/sheet/GeneralFunction.hpp>
50 #include <com/sun/star/container/XIndexAccess.hpp>
51 #include <com/sun/star/frame/XModel.hpp>
52 #include <com/sun/star/text/textfield/Type.hpp>
53 #include <com/sun/star/chart2/XChartDocument.hpp>
54 #include <com/sun/star/chart2/data/XDataReceiver.hpp>
56 #define CALC_DEBUG_OUTPUT 0
57 #define TEST_BUG_FILES 0
59 #include "helper/qahelper.hxx"
60 #include "helper/shared_test_impl.hxx"
62 using namespace ::com::sun::star;
63 using namespace ::com::sun::star::uno;
65 /* Implementation of Filters test */
67 class ScFiltersTest
68 : public test::FiltersTest
69 , public ScBootstrapFixture
71 public:
72 ScFiltersTest();
74 virtual bool load( const OUString &rFilter, const OUString &rURL,
75 const OUString &rUserData, unsigned int nFilterFlags,
76 unsigned int nClipboardID, unsigned int nFilterVersion);
78 virtual void setUp();
79 virtual void tearDown();
81 //ods, xls, xlsx filter tests
82 void testBasicCellContentODS();
83 void testRangeNameXLS();
84 void testRangeNameXLSX();
85 void testHardRecalcODS();
86 void testFunctionsODS();
87 void testCachedFormulaResultsODS();
88 void testCachedMatrixFormulaResultsODS();
89 void testDatabaseRangesODS();
90 void testDatabaseRangesXLS();
91 void testDatabaseRangesXLSX();
92 void testFormatsODS();
93 void testFormatsXLS();
94 void testFormatsXLSX();
95 void testMatrixODS();
96 void testMatrixXLS();
97 void testBorderODS();
98 void testBorderXLS();
99 void testBorderXLSX();
100 void testBordersOoo33();
101 void testBugFixesODS();
102 void testBugFixesXLS();
103 void testBugFixesXLSX();
104 void testBrokenQuotesCSV();
105 void testMergedCellsODS();
106 void testRepeatedColumnsODS();
107 void testDataValidityODS();
109 void testDataBarODS();
110 void testDataBarXLSX();
111 void testColorScaleODS();
112 void testColorScaleXLSX();
113 void testNewCondFormatODS();
114 void testNewCondFormatXLSX();
116 //change this test file only in excel and not in calc
117 void testSharedFormulaXLSX();
118 void testCellValueXLSX();
120 //misc tests unrelated to the import filters
121 void testPasswordNew();
122 void testPasswordOld();
123 void testPasswordWrongSHA();
125 //test shape import
126 void testControlImport();
127 void testChartImportODS();
129 void testNumberFormatHTML();
130 void testNumberFormatCSV();
132 void testCellAnchoredShapesODS();
134 void testPivotTableBasicODS();
135 void testFormulaDependency();
137 void testRowHeightODS();
138 void testRichTextContentODS();
139 void testMiscRowHeights();
140 void testOptimalHeightReset();
142 CPPUNIT_TEST_SUITE(ScFiltersTest);
143 CPPUNIT_TEST(testBasicCellContentODS);
144 CPPUNIT_TEST(testRangeNameXLS);
145 CPPUNIT_TEST(testRangeNameXLSX);
146 CPPUNIT_TEST(testHardRecalcODS);
147 CPPUNIT_TEST(testFunctionsODS);
148 CPPUNIT_TEST(testCachedFormulaResultsODS);
149 CPPUNIT_TEST(testCachedMatrixFormulaResultsODS);
150 CPPUNIT_TEST(testDatabaseRangesODS);
151 CPPUNIT_TEST(testDatabaseRangesXLS);
152 CPPUNIT_TEST(testDatabaseRangesXLSX);
153 CPPUNIT_TEST(testFormatsODS);
154 // CPPUNIT_TEST(testFormatsXLS); TODO: Fix this
155 // CPPUNIT_TEST(testFormatsXLSX); TODO: Fix this
156 CPPUNIT_TEST(testMatrixODS);
157 CPPUNIT_TEST(testMatrixXLS);
158 CPPUNIT_TEST(testBorderODS);
159 CPPUNIT_TEST(testBorderXLS);
160 CPPUNIT_TEST(testBorderXLSX);
161 CPPUNIT_TEST(testBordersOoo33);
162 CPPUNIT_TEST(testBugFixesODS);
163 CPPUNIT_TEST(testBugFixesXLS);
164 CPPUNIT_TEST(testBugFixesXLSX);
165 CPPUNIT_TEST(testMergedCellsODS);
166 CPPUNIT_TEST(testRepeatedColumnsODS);
167 CPPUNIT_TEST(testDataValidityODS);
168 CPPUNIT_TEST(testBrokenQuotesCSV);
169 CPPUNIT_TEST(testSharedFormulaXLSX);
170 CPPUNIT_TEST(testCellValueXLSX);
171 CPPUNIT_TEST(testControlImport);
172 CPPUNIT_TEST(testChartImportODS);
174 CPPUNIT_TEST(testDataBarODS);
175 CPPUNIT_TEST(testDataBarXLSX);
176 CPPUNIT_TEST(testColorScaleODS);
177 CPPUNIT_TEST(testColorScaleXLSX);
178 CPPUNIT_TEST(testNewCondFormatODS);
179 CPPUNIT_TEST(testNewCondFormatXLSX);
181 CPPUNIT_TEST(testNumberFormatHTML);
182 CPPUNIT_TEST(testNumberFormatCSV);
184 CPPUNIT_TEST(testCellAnchoredShapesODS);
186 CPPUNIT_TEST(testPivotTableBasicODS);
187 CPPUNIT_TEST(testRowHeightODS);
188 CPPUNIT_TEST(testFormulaDependency);
189 CPPUNIT_TEST(testRichTextContentODS);
191 //disable testPassword on MacOSX due to problems with libsqlite3
192 //also crashes on DragonFly due to problems with nss/nspr headers
193 #if !defined(MACOSX) && !defined(DRAGONFLY) && !defined(WNT)
194 CPPUNIT_TEST(testPasswordWrongSHA);
195 CPPUNIT_TEST(testPasswordOld);
196 CPPUNIT_TEST(testPasswordNew);
197 #endif
199 #if TEST_BUG_FILES
200 CPPUNIT_TEST(testBugFiles);
201 CPPUNIT_TEST(testBugFilesXLS);
202 CPPUNIT_TEST(testBugFilesXLSX);
203 #endif
204 CPPUNIT_TEST(testMiscRowHeights);
205 CPPUNIT_TEST(testOptimalHeightReset);
206 CPPUNIT_TEST_SUITE_END();
208 private:
209 void testPassword_Impl(const OUString& rFileNameBase);
210 void testBorderImpl( sal_uLong nFormatType );
211 uno::Reference<uno::XInterface> m_xCalcComponent;
214 bool ScFiltersTest::load(const OUString &rFilter, const OUString &rURL,
215 const OUString &rUserData, unsigned int nFilterFlags,
216 unsigned int nClipboardID, unsigned int nFilterVersion)
218 ScDocShellRef xDocShRef = ScBootstrapFixture::load( rURL, rFilter, rUserData,
219 OUString(), nFilterFlags, nClipboardID, nFilterVersion);
220 bool bLoaded = xDocShRef.Is();
221 //reference counting of ScDocShellRef is very confused.
222 if (bLoaded)
223 xDocShRef->DoClose();
224 return bLoaded;
228 namespace {
230 void testRangeNameImpl(ScDocument* pDoc)
232 //check one range data per sheet and one global more detailed
233 //add some more checks here
234 ScRangeData* pRangeData = pDoc->GetRangeName()->findByUpperName(OUString("GLOBAL1"));
235 CPPUNIT_ASSERT_MESSAGE("range name Global1 not found", pRangeData);
236 double aValue;
237 pDoc->GetValue(1,0,0,aValue);
238 CPPUNIT_ASSERT_EQUAL_MESSAGE("range name Global1 should reference Sheet1.A1", 1.0, aValue);
239 pRangeData = pDoc->GetRangeName(0)->findByUpperName(OUString("LOCAL1"));
240 CPPUNIT_ASSERT_MESSAGE("range name Sheet1.Local1 not found", pRangeData);
241 pDoc->GetValue(1,2,0,aValue);
242 CPPUNIT_ASSERT_EQUAL_MESSAGE("range name Sheet1.Local1 should reference Sheet1.A3", 3.0, aValue);
243 pRangeData = pDoc->GetRangeName(1)->findByUpperName(OUString("LOCAL2"));
244 CPPUNIT_ASSERT_MESSAGE("range name Sheet2.Local2 not found", pRangeData);
245 pDoc->GetValue(1,1,1,aValue);
246 CPPUNIT_ASSERT_EQUAL_MESSAGE("range name Sheet2.Local2 should reference Sheet2.A2", 7.0, aValue);
247 //check for correct results for the remaining formulas
248 pDoc->GetValue(1,1,0, aValue);
249 CPPUNIT_ASSERT_EQUAL_MESSAGE("=global2 should be 2", 2.0, aValue);
250 pDoc->GetValue(1,3,0, aValue);
251 CPPUNIT_ASSERT_EQUAL_MESSAGE("=local2 should be 4", 4.0, aValue);
252 pDoc->GetValue(2,0,0, aValue);
253 CPPUNIT_ASSERT_EQUAL_MESSAGE("=SUM(global3) should be 10", 10.0, aValue);
254 pDoc->GetValue(1,0,1,aValue);
255 CPPUNIT_ASSERT_EQUAL_MESSAGE("range name Sheet2.local1 should reference Sheet1.A5", 5.0, aValue);
256 // Test if Global5 ( which depends on Global6 ) is evaluated
257 pDoc->GetValue(0,5,1, aValue);
258 CPPUNIT_ASSERT_EQUAL_MESSAGE("formula Global5 should reference Global6 ( which is evaluated as local1 )", 5.0, aValue);
263 void ScFiltersTest::testBasicCellContentODS()
265 ScDocShellRef xDocSh = loadDoc("basic-cell-content.", ODS);
266 CPPUNIT_ASSERT_MESSAGE("Failed to load basic-cell-content.ods", xDocSh.Is());
268 ScDocument* pDoc = xDocSh->GetDocument();
269 OUString aStr = pDoc->GetString(1, 1, 0); // B2
270 CPPUNIT_ASSERT_EQUAL(OUString("LibreOffice Calc"), aStr);
271 double fVal = pDoc->GetValue(1, 2, 0); // B3
272 CPPUNIT_ASSERT_EQUAL(12345.0, fVal);
273 aStr = pDoc->GetString(1, 3, 0); // B4
274 CPPUNIT_ASSERT_EQUAL(OUString("A < B"), aStr);
276 xDocSh->DoClose();
279 void ScFiltersTest::testRangeNameXLS()
281 ScDocShellRef xDocSh = loadDoc("named-ranges-global.", XLS);
282 xDocSh->DoHardRecalc(true);
284 ScDocument* pDoc = xDocSh->GetDocument();
285 testRangeNameImpl(pDoc);
287 OUString aSheet2CSV("rangeExp_Sheet2.");
288 OUString aCSVPath;
289 createCSVPath( aSheet2CSV, aCSVPath );
290 // fdo#44587
291 testFile( aCSVPath, pDoc, 1);
293 xDocSh->DoClose();
296 void ScFiltersTest::testRangeNameXLSX()
298 ScDocShellRef xDocSh = loadDoc("named-ranges-global.", XLSX);
299 xDocSh->DoHardRecalc(true);
301 ScDocument* pDoc = xDocSh->GetDocument();
302 testRangeNameImpl(pDoc);
304 xDocSh->DoClose();
307 void ScFiltersTest::testHardRecalcODS()
309 ScDocShellRef xDocSh = loadDoc("hard-recalc.", ODS);
310 xDocSh->DoHardRecalc(true);
312 CPPUNIT_ASSERT_MESSAGE("Failed to load hard-recalc.*", xDocSh.Is());
313 ScDocument* pDoc = xDocSh->GetDocument();
314 OUString aCSVFileName;
316 //test hard recalc: document has an incorrect cached formula result
317 //hard recalc should have updated to the correct result
318 createCSVPath(OUString("hard-recalc."), aCSVFileName);
319 testFile(aCSVFileName, pDoc, 0);
321 xDocSh->DoClose();
324 void ScFiltersTest::testFunctionsODS()
326 ScDocShellRef xDocSh = loadDoc("functions.", ODS);
327 xDocSh->DoHardRecalc(true);
329 CPPUNIT_ASSERT_MESSAGE("Failed to load functions.*", xDocSh.Is());
330 ScDocument* pDoc = xDocSh->GetDocument();
331 OUString aCSVFileName;
333 //test logical functions
334 createCSVPath(OUString("logical-functions."), aCSVFileName);
335 testFile(aCSVFileName, pDoc, 0);
336 //test spreadsheet functions
337 createCSVPath(OUString("spreadsheet-functions."), aCSVFileName);
338 testFile(aCSVFileName, pDoc, 1);
339 //test mathematical functions
340 createCSVPath(OUString("mathematical-functions."), aCSVFileName);
341 testFile(aCSVFileName, pDoc, 2, PureString);
342 //test information functions
343 createCSVPath(OUString("information-functions."), aCSVFileName);
344 testFile(aCSVFileName, pDoc, 3);
346 xDocSh->DoClose();
349 void ScFiltersTest::testCachedFormulaResultsODS()
352 ScDocShellRef xDocSh = loadDoc("functions.", ODS);
353 CPPUNIT_ASSERT_MESSAGE("Failed to load functions.*", xDocSh.Is());
355 ScDocument* pDoc = xDocSh->GetDocument();
356 OUString aCSVFileName;
358 //test cached formula results of logical functions
359 createCSVPath(OUString("logical-functions."), aCSVFileName);
360 testFile(aCSVFileName, pDoc, 0);
361 //test cached formula results of spreadsheet functions
362 createCSVPath(OUString("spreadsheet-functions."), aCSVFileName);
363 testFile(aCSVFileName, pDoc, 1);
364 //test cached formula results of mathematical functions
365 createCSVPath(OUString("mathematical-functions."), aCSVFileName);
366 testFile(aCSVFileName, pDoc, 2, PureString);
367 //test cached formula results of information functions
368 createCSVPath(OUString("information-functions."), aCSVFileName);
369 testFile(aCSVFileName, pDoc, 3);
371 xDocSh->DoClose();
375 ScDocShellRef xDocSh = loadDoc("cachedValue.", ODS);
376 CPPUNIT_ASSERT_MESSAGE("Failed to load cachedValue.*", xDocSh.Is());
378 ScDocument* pDoc = xDocSh->GetDocument();
379 OUString aCSVFileName;
380 createCSVPath("cachedValue.", aCSVFileName);
381 testFile(aCSVFileName, pDoc, 0);
383 //we want to me sure that volatile functions are always recalculated
384 //regardless of cached results. if you update the ods file, you must
385 //update the values here.
386 //if NOW() is recacluated, then it should never equal sTodayCache
387 OUString sTodayCache("01/25/13 01:06 PM");
388 OUString sTodayRecalc(pDoc->GetString(0,0,1));
390 CPPUNIT_ASSERT(sTodayCache != sTodayRecalc);
392 OUString sTodayRecalcRef(pDoc->GetString(1,0,1));
393 CPPUNIT_ASSERT_EQUAL(sTodayRecalc, sTodayRecalcRef);
395 // make sure that error values are not being treated as string values
396 for(SCCOL nCol = 0; nCol < 4; ++nCol)
398 for(SCROW nRow = 0; nRow < 2; ++nRow)
400 OUStringBuffer aIsErrorFormula("=ISERROR(");
401 aIsErrorFormula.append((char)('A'+nCol)).append(OUString::number(nRow));
402 aIsErrorFormula.append(")");
403 OUString aFormula = aIsErrorFormula.makeStringAndClear();
404 pDoc->SetString(nCol, nRow + 2, 2, aFormula);
405 CPPUNIT_ASSERT_EQUAL_MESSAGE(OUStringToOString(aFormula, RTL_TEXTENCODING_UTF8).getStr(), pDoc->GetString(nCol, nRow +2, 2), OUString("TRUE"));
407 OUStringBuffer aIsTextFormula("=ISTEXT(");
408 aIsTextFormula.append((char)('A'+nCol)).append(OUString::number(nRow));
409 aIsTextFormula.append(")");
410 pDoc->SetString(nCol, nRow + 4, 2, aIsTextFormula.makeStringAndClear());
411 CPPUNIT_ASSERT_EQUAL_MESSAGE("", pDoc->GetString(nCol, nRow +4, 2), OUString("FALSE"));
415 xDocSh->DoClose();
419 void ScFiltersTest::testCachedMatrixFormulaResultsODS()
421 ScDocShellRef xDocSh = loadDoc("matrix.", ODS);
423 CPPUNIT_ASSERT_MESSAGE("Failed to load matrix.*", xDocSh.Is());
424 ScDocument* pDoc = xDocSh->GetDocument();
426 //test matrix
427 OUString aCSVFileName;
428 createCSVPath("matrix.", aCSVFileName);
429 testFile(aCSVFileName, pDoc, 0);
430 //test matrices with special cases
431 createCSVPath("matrix2.", aCSVFileName);
432 testFile(aCSVFileName, pDoc, 1);
433 createCSVPath("matrix3.", aCSVFileName);
434 testFile(aCSVFileName, pDoc, 2);
435 //The above testFile() does not catch the below case.
436 //If a matrix formula has a matrix reference cell that is intended to have
437 //a blank text result, the matrix reference cell is actually saved(export)
438 //as a float cell with 0 as the value and an empty <text:p/>.
439 //Import works around this by setting these cells as text cells so that
440 //the blank text is used for display instead of the number 0.
441 //If this is working properly, the following cell should NOT have value data.
442 CPPUNIT_ASSERT_EQUAL(pDoc->GetString(3,0,2), OUString());
444 // fdo#59293 with cached value import error formulas require special
445 // treatment
446 pDoc->SetString(2, 5, 2, "=ISERROR(A6)");
447 double nVal = pDoc->GetValue(2,5,2);
448 CPPUNIT_ASSERT_EQUAL(1.0, nVal);
450 xDocSh->DoClose();
453 namespace {
455 void testDBRanges_Impl(ScDocument* pDoc, sal_Int32 nFormat)
457 ScDBCollection* pDBCollection = pDoc->GetDBCollection();
458 CPPUNIT_ASSERT_MESSAGE("no database collection", pDBCollection);
460 ScDBData* pAnonDBData = pDoc->GetAnonymousDBData(0);
461 CPPUNIT_ASSERT_MESSAGE("missing anonymous DB data in sheet 1", pAnonDBData);
462 //control hidden rows
463 bool bHidden;
464 SCROW nRow1, nRow2;
465 bHidden = pDoc->RowHidden(0, 0, &nRow1, &nRow2);
466 CPPUNIT_ASSERT_MESSAGE("Sheet1: row 0 should be visible", !bHidden && nRow1 == 0 && nRow2 == 0);
467 bHidden = pDoc->RowHidden(1, 0, &nRow1, &nRow2);
468 CPPUNIT_ASSERT_MESSAGE("Sheet1: rows 1-2 should be hidden", bHidden && nRow1 == 1 && nRow2 == 2);
469 bHidden = pDoc->RowHidden(3, 0, &nRow1, &nRow2);
470 CPPUNIT_ASSERT_MESSAGE("Sheet1: row 3 should be visible", !bHidden && nRow1 == 3 && nRow2 == 3);
471 bHidden = pDoc->RowHidden(4, 0, &nRow1, &nRow2);
472 CPPUNIT_ASSERT_MESSAGE("Sheet1: row 4-5 should be hidden", bHidden && nRow1 == 4 && nRow2 == 5);
473 bHidden = pDoc->RowHidden(6, 0, &nRow1, &nRow2);
474 CPPUNIT_ASSERT_MESSAGE("Sheet1: row 6-end should be visible", !bHidden && nRow1 == 6 && nRow2 == MAXROW);
475 if(nFormat == ODS) //excel doesn't support named db ranges
477 double aValue;
478 pDoc->GetValue(0,10,1, aValue);
479 CPPUNIT_ASSERT_EQUAL_MESSAGE("Sheet2: A11: formula result is incorrect", 4.0, aValue);
480 pDoc->GetValue(1, 10, 1, aValue);
481 CPPUNIT_ASSERT_EQUAL_MESSAGE("Sheet2: B11: formula result is incorrect", 2.0, aValue);
483 double aValue;
484 pDoc->GetValue(3,10,1, aValue);
485 CPPUNIT_ASSERT_EQUAL_MESSAGE("Sheet2: D11: formula result is incorrect", 4.0, aValue);
486 pDoc->GetValue(4, 10, 1, aValue);
487 CPPUNIT_ASSERT_EQUAL_MESSAGE("Sheet2: E11: formula result is incorrect", 2.0, aValue);
493 void ScFiltersTest::testDatabaseRangesODS()
495 ScDocShellRef xDocSh = loadDoc("database.", ODS);
496 xDocSh->DoHardRecalc(true);
498 ScDocument* pDoc = xDocSh->GetDocument();
500 testDBRanges_Impl(pDoc, ODS);
501 xDocSh->DoClose();
504 void ScFiltersTest::testDatabaseRangesXLS()
506 ScDocShellRef xDocSh = loadDoc("database.", XLS);
507 xDocSh->DoHardRecalc(true);
509 ScDocument* pDoc = xDocSh->GetDocument();
511 testDBRanges_Impl(pDoc, XLS);
512 xDocSh->DoClose();
515 void ScFiltersTest::testDatabaseRangesXLSX()
517 ScDocShellRef xDocSh = loadDoc("database.", XLSX);
518 xDocSh->DoHardRecalc(true);
520 ScDocument* pDoc = xDocSh->GetDocument();
522 testDBRanges_Impl(pDoc, XLSX);
523 xDocSh->DoClose();
526 namespace {
528 void testFormats_Impl(ScFiltersTest* pFiltersTest, ScDocument* pDoc, sal_Int32 nFormat)
530 //test Sheet1 with csv file
531 OUString aCSVFileName;
532 pFiltersTest->createCSVPath(OUString("numberFormat."), aCSVFileName);
533 testFile(aCSVFileName, pDoc, 0, PureString);
534 //need to test the color of B3
535 //it's not a font color!
536 //formatting for B5: # ??/100 gets lost during import
538 //test Sheet2
539 const ScPatternAttr* pPattern = NULL;
540 pPattern = pDoc->GetPattern(0,0,1);
541 Font aFont;
542 pPattern->GetFont(aFont,SC_AUTOCOL_RAW);
543 CPPUNIT_ASSERT_EQUAL_MESSAGE("font size should be 10", 200l, aFont.GetSize().getHeight());
544 CPPUNIT_ASSERT_EQUAL_MESSAGE("font color should be black", COL_AUTO, aFont.GetColor().GetColor());
545 pPattern = pDoc->GetPattern(0,1,1);
546 pPattern->GetFont(aFont, SC_AUTOCOL_RAW);
547 CPPUNIT_ASSERT_EQUAL_MESSAGE("font size should be 12", 240l, aFont.GetSize().getHeight());
548 pPattern = pDoc->GetPattern(0,2,1);
549 pPattern->GetFont(aFont, SC_AUTOCOL_RAW);
550 CPPUNIT_ASSERT_EQUAL_MESSAGE("font should be italic", ITALIC_NORMAL, aFont.GetItalic());
551 pPattern = pDoc->GetPattern(0,4,1);
552 pPattern->GetFont(aFont, SC_AUTOCOL_RAW);
553 CPPUNIT_ASSERT_EQUAL_MESSAGE("font should be bold", WEIGHT_BOLD, aFont.GetWeight());
554 pPattern = pDoc->GetPattern(1,0,1);
555 pPattern->GetFont(aFont, SC_AUTOCOL_RAW);
556 CPPUNIT_ASSERT_EQUAL_MESSAGE("font should be blue", COL_BLUE, aFont.GetColor().GetColor());
557 pPattern = pDoc->GetPattern(1,1,1);
558 pPattern->GetFont(aFont, SC_AUTOCOL_RAW);
559 CPPUNIT_ASSERT_EQUAL_MESSAGE("font should be striked out with a single line", STRIKEOUT_SINGLE, aFont.GetStrikeout());
560 //some tests on sheet2 only for ods
561 if (nFormat == ODS)
563 pPattern = pDoc->GetPattern(1,2,1);
564 pPattern->GetFont(aFont, SC_AUTOCOL_RAW);
565 CPPUNIT_ASSERT_EQUAL_MESSAGE("font should be striked out with a double line", STRIKEOUT_DOUBLE, aFont.GetStrikeout());
566 pPattern = pDoc->GetPattern(1,3,1);
567 pPattern->GetFont(aFont, SC_AUTOCOL_RAW);
568 CPPUNIT_ASSERT_EQUAL_MESSAGE("font should be underlined with a dotted line", UNDERLINE_DOTTED, aFont.GetUnderline());
569 //check row height import
570 //disable for now until we figure out cause of win tinderboxes test failures
571 //CPPUNIT_ASSERT_EQUAL( static_cast<sal_uInt16>(256), pDoc->GetRowHeight(0,1) ); //0.178in
572 //CPPUNIT_ASSERT_EQUAL( static_cast<sal_uInt16>(304), pDoc->GetRowHeight(1,1) ); //0.211in
573 //CPPUNIT_ASSERT_EQUAL( static_cast<sal_uInt16>(477), pDoc->GetRowHeight(5,1) ); //0.3311in
574 //check column width import
575 CPPUNIT_ASSERT_EQUAL( static_cast<sal_uInt16>(555), pDoc->GetColWidth(4,1) ); //0.3854in
576 CPPUNIT_ASSERT_EQUAL( static_cast<sal_uInt16>(1280), pDoc->GetColWidth(5,1) ); //0.889in
577 CPPUNIT_ASSERT_EQUAL( static_cast<sal_uInt16>(4153), pDoc->GetColWidth(6,1) ); //2.8839in
578 //test case for i53253 where a cell has text with different styles and space between the text.
579 OUString aTestStr = pDoc->GetString(3,0,1);
580 OUString aKnownGoodStr("text14 space");
581 CPPUNIT_ASSERT_EQUAL( aKnownGoodStr, aTestStr );
582 //test case for cell text with line breaks.
583 aTestStr = pDoc->GetString(3,5,1);
584 aKnownGoodStr = "Hello,\nCalc!";
585 CPPUNIT_ASSERT_EQUAL( aKnownGoodStr, aTestStr );
587 pPattern = pDoc->GetPattern(1,4,1);
588 Color aColor = static_cast<const SvxBrushItem&>(pPattern->GetItem(ATTR_BACKGROUND)).GetColor();
589 CPPUNIT_ASSERT_MESSAGE("background color should be green", aColor == COL_LIGHTGREEN);
590 pPattern = pDoc->GetPattern(2,0,1);
591 SvxCellHorJustify eHorJustify = static_cast<SvxCellHorJustify>(static_cast<const SvxHorJustifyItem&>(pPattern->GetItem(ATTR_HOR_JUSTIFY)).GetValue());
592 CPPUNIT_ASSERT_EQUAL_MESSAGE("cell content should be aligned centre horizontally", SVX_HOR_JUSTIFY_CENTER, eHorJustify);
593 //test alignment
594 pPattern = pDoc->GetPattern(2,1,1);
595 eHorJustify = static_cast<SvxCellHorJustify>(static_cast<const SvxHorJustifyItem&>(pPattern->GetItem(ATTR_HOR_JUSTIFY)).GetValue());
596 CPPUNIT_ASSERT_EQUAL_MESSAGE("cell content should be aligned right horizontally", SVX_HOR_JUSTIFY_RIGHT, eHorJustify);
597 pPattern = pDoc->GetPattern(2,2,1);
598 eHorJustify = static_cast<SvxCellHorJustify>(static_cast<const SvxHorJustifyItem&>(pPattern->GetItem(ATTR_HOR_JUSTIFY)).GetValue());
599 CPPUNIT_ASSERT_EQUAL_MESSAGE("cell content should be aligned block horizontally", SVX_HOR_JUSTIFY_BLOCK, eHorJustify);
601 //test Sheet3 only for ods
602 if ( nFormat == ODS || nFormat == XLSX )
604 pFiltersTest->createCSVPath(OUString("conditionalFormatting."), aCSVFileName);
605 testCondFile(aCSVFileName, pDoc, 2);
606 // test parent cell style import ( fdo#55198 )
607 if ( nFormat == XLSX )
609 pPattern = pDoc->GetPattern(1,1,3);
610 ScStyleSheet* pStyleSheet = (ScStyleSheet*)pPattern->GetStyleSheet();
611 // check parent style name
612 OUString sExpected("Excel Built-in Date");
613 OUString sResult = pStyleSheet->GetName();
614 CPPUNIT_ASSERT_EQUAL_MESSAGE("parent style for Sheet4.B2 is 'Excel Built-in Date'", sExpected, sResult);
615 // check align of style
616 SfxItemSet& rItemSet = pStyleSheet->GetItemSet();
617 eHorJustify = static_cast<SvxCellHorJustify>(static_cast< const SvxHorJustifyItem& >(rItemSet.Get( ATTR_HOR_JUSTIFY ) ).GetValue() );
618 CPPUNIT_ASSERT_EQUAL_MESSAGE("'Excel Built-in Date' style should be aligned centre horizontally", SVX_HOR_JUSTIFY_CENTER, eHorJustify);
619 // check date format ( should be just month e.g. 29 )
620 sResult =pDoc->GetString( 1,1,3 );
621 sExpected = OUString("29");
622 CPPUNIT_ASSERT_EQUAL_MESSAGE("'Excel Built-in Date' style should just display month", sExpected, sResult );
624 // check actual align applied to cell, should be the same as
625 // the style
626 eHorJustify = static_cast<SvxCellHorJustify>(static_cast< const SvxHorJustifyItem& >(pPattern->GetItem( ATTR_HOR_JUSTIFY ) ).GetValue() );
627 CPPUNIT_ASSERT_EQUAL_MESSAGE("cell with 'Excel Built-in Date' style should be aligned centre horizontally", SVX_HOR_JUSTIFY_CENTER, eHorJustify);
631 ScConditionalFormat* pCondFormat = pDoc->GetCondFormat(0,0,2);
632 const ScRangeList& rRange = pCondFormat->GetRange();
633 CPPUNIT_ASSERT(rRange == ScRange(0,0,2,3,0,2));
635 pCondFormat = pDoc->GetCondFormat(0,1,2);
636 const ScRangeList& rRange2 = pCondFormat->GetRange();
637 CPPUNIT_ASSERT(rRange2 == ScRange(0,1,2,0,1,2));
639 pCondFormat = pDoc->GetCondFormat(1,1,2);
640 const ScRangeList& rRange3 = pCondFormat->GetRange();
641 CPPUNIT_ASSERT(rRange3 == ScRange(1,1,2,3,1,2));
646 void ScFiltersTest::testFormatsODS()
648 ScDocShellRef xDocSh = loadDoc("formats.", ODS);
649 xDocSh->DoHardRecalc(true);
651 ScDocument* pDoc = xDocSh->GetDocument();
653 testFormats_Impl(this, pDoc, ODS);
654 xDocSh->DoClose();
657 void ScFiltersTest::testFormatsXLS()
659 ScDocShellRef xDocSh = loadDoc("formats.", XLS);
660 xDocSh->DoHardRecalc(true);
662 ScDocument* pDoc = xDocSh->GetDocument();
664 testFormats_Impl(this, pDoc, XLS);
665 xDocSh->DoClose();
668 void ScFiltersTest::testFormatsXLSX()
670 ScDocShellRef xDocSh = loadDoc("formats.", XLSX);
671 xDocSh->DoHardRecalc(true);
673 ScDocument* pDoc = xDocSh->GetDocument();
675 testFormats_Impl(this, pDoc, XLSX);
676 xDocSh->DoClose();
679 void ScFiltersTest::testMatrixODS()
681 ScDocShellRef xDocSh = loadDoc("matrix.", ODS);
682 xDocSh->DoHardRecalc(true);
684 ScDocument* pDoc = xDocSh->GetDocument();
686 OUString aCSVFileName;
687 createCSVPath(OUString("matrix."), aCSVFileName);
688 testFile(aCSVFileName, pDoc, 0);
690 xDocSh->DoClose();
693 void ScFiltersTest::testMatrixXLS()
695 ScDocShellRef xDocSh = loadDoc("matrix.", XLS);
696 xDocSh->DoHardRecalc(true);
698 CPPUNIT_ASSERT_MESSAGE("Failed to load matrix.*", xDocSh.Is());
699 ScDocument* pDoc = xDocSh->GetDocument();
701 OUString aCSVFileName;
702 createCSVPath(OUString("matrix."), aCSVFileName);
703 testFile(aCSVFileName, pDoc, 0);
705 xDocSh->DoClose();
708 void ScFiltersTest::testBorderODS()
710 ScDocShellRef xDocSh = loadDoc("border.", ODS);
712 CPPUNIT_ASSERT_MESSAGE("Failed to load border.*", xDocSh.Is());
713 ScDocument* pDoc = xDocSh->GetDocument();
715 const editeng::SvxBorderLine* pLeft = NULL;
716 const editeng::SvxBorderLine* pTop = NULL;
717 const editeng::SvxBorderLine* pRight = NULL;
718 const editeng::SvxBorderLine* pBottom = NULL;
720 pDoc->GetBorderLines( 0, 1, 0, &pLeft, &pTop, &pRight, &pBottom );
721 CPPUNIT_ASSERT(!pLeft);
722 CPPUNIT_ASSERT(!pTop);
723 CPPUNIT_ASSERT(!pBottom);
724 CPPUNIT_ASSERT(pRight);
725 CPPUNIT_ASSERT_EQUAL(pRight->GetBorderLineStyle(),
726 table::BorderLineStyle::SOLID);
728 pDoc->GetBorderLines( 2, 1, 0, &pLeft, &pTop, &pRight, &pBottom );
729 CPPUNIT_ASSERT(!pLeft);
730 CPPUNIT_ASSERT(!pTop);
731 CPPUNIT_ASSERT(!pBottom);
733 CPPUNIT_ASSERT(pRight);
734 CPPUNIT_ASSERT_EQUAL(pRight->GetBorderLineStyle(),
735 table::BorderLineStyle::SOLID);
736 CPPUNIT_ASSERT_EQUAL(pRight->GetWidth(),20L);
738 pDoc->GetBorderLines( 2, 8, 0, &pLeft, &pTop, &pRight, &pBottom );
740 CPPUNIT_ASSERT(pLeft);
741 CPPUNIT_ASSERT(pTop);
742 CPPUNIT_ASSERT(pBottom);
743 CPPUNIT_ASSERT(pRight);
744 CPPUNIT_ASSERT_EQUAL(pRight->GetBorderLineStyle(),
745 table::BorderLineStyle::SOLID);
746 CPPUNIT_ASSERT_EQUAL(pRight->GetWidth(),5L);
747 CPPUNIT_ASSERT(pRight->GetColor() == Color(COL_BLUE));
749 xDocSh->DoClose();
752 void ScFiltersTest::testBorderImpl( sal_uLong nFormatType )
754 ScDocShellRef xDocSh = loadDoc("border.", nFormatType );
756 CPPUNIT_ASSERT_MESSAGE("Failed to load border.xls", xDocSh.Is());
757 ScDocument* pDoc = xDocSh->GetDocument();
759 const editeng::SvxBorderLine* pLeft = NULL;
760 const editeng::SvxBorderLine* pTop = NULL;
761 const editeng::SvxBorderLine* pRight = NULL;
762 const editeng::SvxBorderLine* pBottom = NULL;
764 pDoc->GetBorderLines( 2, 3, 0, &pLeft, &pTop, &pRight, &pBottom );
765 CPPUNIT_ASSERT(pRight);
766 CPPUNIT_ASSERT_EQUAL(pRight->GetBorderLineStyle(),
767 table::BorderLineStyle::SOLID);
768 CPPUNIT_ASSERT_EQUAL(pRight->GetWidth(),1L);
770 pDoc->GetBorderLines( 3, 5, 0, &pLeft, &pTop, &pRight, &pBottom );
771 CPPUNIT_ASSERT(pRight);
772 CPPUNIT_ASSERT_EQUAL(pRight->GetBorderLineStyle(),
773 table::BorderLineStyle::SOLID);
774 CPPUNIT_ASSERT_EQUAL(pRight->GetWidth(),20L);
776 pDoc->GetBorderLines( 5, 7, 0, &pLeft, &pTop, &pRight, &pBottom );
777 CPPUNIT_ASSERT(pRight);
778 CPPUNIT_ASSERT_EQUAL(pRight->GetBorderLineStyle(),
779 table::BorderLineStyle::SOLID);
780 CPPUNIT_ASSERT_EQUAL(pRight->GetWidth(),30L);
782 pDoc->GetBorderLines( 7, 9, 0, &pLeft, &pTop, &pRight, &pBottom );
783 CPPUNIT_ASSERT(pRight);
784 CPPUNIT_ASSERT_EQUAL(pRight->GetBorderLineStyle(),
785 table::BorderLineStyle::FINE_DASHED);
786 CPPUNIT_ASSERT_EQUAL(pRight->GetWidth(),1L);
789 void ScFiltersTest::testBorderXLS()
791 testBorderImpl( XLS );
794 void ScFiltersTest::testBorderXLSX()
796 testBorderImpl( XLSX );
799 struct Border
801 sal_Int16 column;
802 sal_Int32 row;
803 long leftWidth;
804 long topWidth;
805 long rightWidth;
806 long bottomWidth;
807 sal_uInt16 lOutWidth;
808 sal_uInt16 lInWidth;
809 sal_uInt16 lDistance;
810 sal_uInt16 tOutWidth;
811 sal_uInt16 tInWidth;
812 sal_uInt16 tDistance;
813 sal_uInt16 rOutWidth;
814 sal_uInt16 rInWidth;
815 sal_uInt16 rDistance;
816 sal_uInt16 bOutWidth;
817 sal_uInt16 bInWidth;
818 sal_uInt16 bDistance;
819 sal_Int32 lStyle;
820 sal_Int32 tStyle;
821 sal_Int32 rStyle;
822 sal_Int32 bStyle;
823 // that's a monstrum
824 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,
825 sal_uInt16 lDist, sal_uInt16 tOutW, sal_uInt16 tInW, sal_uInt16 tDist, sal_uInt16 rOutW, sal_uInt16 rInW, sal_uInt16 rDist,
826 sal_uInt16 bOutW, sal_uInt16 bInW, sal_uInt16 bDist, sal_Int32 lSt, sal_Int32 tSt, sal_Int32 rSt, sal_Int32 bSt):
827 column(col), row(r), leftWidth(lW), topWidth(tW), rightWidth(rW), bottomWidth(bW), lOutWidth(lOutW), lInWidth(lInW), lDistance(lDist),
828 tOutWidth(tOutW), tInWidth(tInW), tDistance(tDist), rOutWidth(rOutW), rInWidth(rInW), rDistance(rDist), bOutWidth(bOutW), bInWidth(bInW),
829 bDistance(bDist), lStyle(lSt), tStyle(tSt), rStyle(rSt), bStyle(bSt) {};
832 void ScFiltersTest::testBordersOoo33()
834 std::vector<Border> borders;
835 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));
836 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));
837 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));
838 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));
839 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));
840 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));
841 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));
842 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));
843 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));
844 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));
845 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));
846 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));
847 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));
848 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));
849 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));
850 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));
851 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));
853 ScDocShellRef xDocSh = loadDoc("borders_ooo33.", ODS);
855 CPPUNIT_ASSERT_MESSAGE("Failed to load borders_ooo33.*", xDocSh.Is());
856 ScDocument* pDoc = xDocSh->GetDocument();
858 const editeng::SvxBorderLine* pLeft = NULL;
859 const editeng::SvxBorderLine* pTop = NULL;
860 const editeng::SvxBorderLine* pRight = NULL;
861 const editeng::SvxBorderLine* pBottom = NULL;
862 sal_Int16 temp = 0;
863 for(sal_Int16 i = 0; i<6; ++i)
865 for(sal_Int32 j = 0; j<22; ++j)
867 pDoc->GetBorderLines( i, j, 0, &pLeft, &pTop, &pRight, &pBottom );
868 if(pLeft!=NULL && pTop!=NULL && pRight!=NULL && pBottom!=NULL)
870 CPPUNIT_ASSERT_EQUAL(borders[temp].column, i);
871 CPPUNIT_ASSERT_EQUAL(borders[temp].row, j);
872 CPPUNIT_ASSERT_EQUAL(borders[temp].leftWidth, pLeft->GetWidth());
873 CPPUNIT_ASSERT_EQUAL(borders[temp].topWidth, pTop->GetWidth());
874 CPPUNIT_ASSERT_EQUAL(borders[temp].rightWidth, pRight->GetWidth());
875 CPPUNIT_ASSERT_EQUAL(borders[temp].bottomWidth, pBottom->GetWidth());
876 CPPUNIT_ASSERT_EQUAL(borders[temp].lOutWidth, pLeft->GetOutWidth());
877 CPPUNIT_ASSERT_EQUAL(borders[temp].lInWidth, pLeft->GetInWidth());
878 CPPUNIT_ASSERT_EQUAL(borders[temp].lDistance, pLeft->GetDistance());
879 CPPUNIT_ASSERT_EQUAL(borders[temp].tOutWidth, pTop->GetOutWidth());
880 CPPUNIT_ASSERT_EQUAL(borders[temp].tInWidth, pTop->GetInWidth());
881 CPPUNIT_ASSERT_EQUAL(borders[temp].tDistance, pTop->GetDistance());
882 CPPUNIT_ASSERT_EQUAL(borders[temp].rOutWidth, pRight->GetOutWidth());
883 CPPUNIT_ASSERT_EQUAL(borders[temp].rInWidth, pRight->GetInWidth());
884 CPPUNIT_ASSERT_EQUAL(borders[temp].rDistance, pRight->GetDistance());
885 CPPUNIT_ASSERT_EQUAL(borders[temp].bOutWidth, pBottom->GetOutWidth());
886 CPPUNIT_ASSERT_EQUAL(borders[temp].bInWidth, pBottom->GetInWidth());
887 CPPUNIT_ASSERT_EQUAL(borders[temp].bDistance, pBottom->GetDistance());
888 sal_Int32 tempStyle = pLeft->GetBorderLineStyle();
889 CPPUNIT_ASSERT_EQUAL(borders[temp].lStyle, tempStyle);
890 tempStyle = pTop->GetBorderLineStyle();
891 CPPUNIT_ASSERT_EQUAL(borders[temp].tStyle, tempStyle);
892 tempStyle = pRight->GetBorderLineStyle();
893 CPPUNIT_ASSERT_EQUAL(borders[temp].rStyle, tempStyle);
894 tempStyle = pBottom->GetBorderLineStyle();
895 CPPUNIT_ASSERT_EQUAL(borders[temp].bStyle, tempStyle);
896 ++temp;
901 xDocSh->DoClose();
904 void ScFiltersTest::testBugFixesODS()
906 ScDocShellRef xDocSh = loadDoc("bug-fixes.", ODS);
907 CPPUNIT_ASSERT_MESSAGE("Failed to load bugFixes.ods", xDocSh.Is());
909 xDocSh->DoHardRecalc(true);
910 ScDocument* pDoc = xDocSh->GetDocument();
913 // fdo#40967
914 OUString aCSVFileName;
915 createCSVPath(OUString("bugFix_Sheet2."), aCSVFileName);
916 testFile(aCSVFileName, pDoc, 1);
920 // fdo#40426
921 ScDBData* pDBData = pDoc->GetDBCollection()->getNamedDBs().findByUpperName("DBRANGE1");
922 CPPUNIT_ASSERT(pDBData);
923 CPPUNIT_ASSERT(pDBData->HasHeader());
924 // no header
925 pDBData = pDoc->GetDBCollection()->getNamedDBs().findByUpperName("DBRANGE2");
926 CPPUNIT_ASSERT(pDBData);
927 CPPUNIT_ASSERT(!pDBData->HasHeader());
931 // fdo#59240
932 OUString aCSVFileName;
933 createCSVPath("bugFix_Sheet4.", aCSVFileName);
934 testFile(aCSVFileName, pDoc, 3);
937 xDocSh->DoClose();
940 void ScFiltersTest::testBugFixesXLS()
942 ScDocShellRef xDocSh = loadDoc("bug-fixes.", XLS);
943 CPPUNIT_ASSERT_MESSAGE("Failed to load bugFixes.xls", xDocSh.Is());
945 xDocSh->DoHardRecalc(true);
946 ScDocument* pDoc = xDocSh->GetDocument();
947 CPPUNIT_ASSERT_MESSAGE("No Document", pDoc); //remove with first test
948 xDocSh->DoClose();
951 void ScFiltersTest::testBugFixesXLSX()
953 ScDocShellRef xDocSh = loadDoc("bug-fixes.", XLSX);
954 CPPUNIT_ASSERT_MESSAGE("Failed to load bugFixes.xls", xDocSh.Is());
956 xDocSh->DoHardRecalc(true);
957 ScDocument* pDoc = xDocSh->GetDocument();
958 CPPUNIT_ASSERT_MESSAGE("No Document", pDoc); //remove with first test
959 xDocSh->DoClose();
962 namespace {
964 void checkMergedCells( ScDocument* pDoc, const ScAddress& rStartAddress,
965 const ScAddress& rExpectedEndAddress )
967 SCCOL nActualEndCol = rStartAddress.Col();
968 SCROW nActualEndRow = rStartAddress.Row();
969 pDoc->ExtendMerge( rStartAddress.Col(), rStartAddress.Row(),
970 nActualEndCol, nActualEndRow, rStartAddress.Tab(), false );
971 OString sTab = OString::valueOf( static_cast<sal_Int32>(rStartAddress.Tab() + 1) );
972 OString msg = "Merged cells are not correctly imported on sheet" + sTab;
973 OString msgCol = msg + "; end col";
974 OString msgRow = msg + "; end row";
975 CPPUNIT_ASSERT_EQUAL_MESSAGE( msgCol.pData->buffer, rExpectedEndAddress.Col(), nActualEndCol );
976 CPPUNIT_ASSERT_EQUAL_MESSAGE( msgRow.pData->buffer, rExpectedEndAddress.Row(), nActualEndRow );
981 void ScFiltersTest::testMergedCellsODS()
983 ScDocShellRef xDocSh = loadDoc("merged.", ODS);
984 ScDocument* pDoc = xDocSh->GetDocument();
986 //check sheet1 content
987 OUString aCSVFileName1;
988 createCSVPath(OUString("merged1."), aCSVFileName1);
989 testFile(aCSVFileName1, pDoc, 0);
991 //check sheet1 merged cells
992 checkMergedCells( pDoc, ScAddress( 0, 0, 0 ), ScAddress( 5, 11, 0 ) );
993 checkMergedCells( pDoc, ScAddress( 7, 2, 0 ), ScAddress( 9, 12, 0 ) );
994 checkMergedCells( pDoc, ScAddress( 3, 15, 0 ), ScAddress( 7, 23, 0 ) );
996 //check sheet2 content
997 OUString aCSVFileName2;
998 createCSVPath(OUString("merged2."), aCSVFileName2);
999 testFile(aCSVFileName2, pDoc, 1);
1001 //check sheet2 merged cells
1002 checkMergedCells( pDoc, ScAddress( 4, 3, 1 ), ScAddress( 6, 15, 1 ) );
1004 xDocSh->DoClose();
1007 void ScFiltersTest::testRepeatedColumnsODS()
1009 ScDocShellRef xDocSh = loadDoc("repeatedColumns.", ODS);
1010 ScDocument* pDoc = xDocSh->GetDocument();
1012 //text
1013 OUString aCSVFileName1;
1014 createCSVPath(OUString("repeatedColumns1."), aCSVFileName1);
1015 testFile(aCSVFileName1, pDoc, 0);
1017 //numbers
1018 OUString aCSVFileName2;
1019 createCSVPath(OUString("repeatedColumns2."), aCSVFileName2);
1020 testFile(aCSVFileName2, pDoc, 1);
1022 xDocSh->DoClose();
1025 namespace {
1027 //for cleaner passing of parameters
1028 struct ValDataTestParams
1030 ScValidationMode eValMode;
1031 ScConditionMode eCondOp;
1032 String aStrVal1, aStrVal2;
1033 ScDocument* pDocument;
1034 ScAddress aPosition;
1035 String aErrorTitle, aErrorMessage;
1036 ScValidErrorStyle eErrorStyle;
1037 sal_uLong nExpectedIndex;
1039 ValDataTestParams( ScValidationMode eMode, ScConditionMode eOp,
1040 String aExpr1, String aExpr2, ScDocument* pDoc,
1041 ScAddress aPos, String aETitle, String aEMsg,
1042 ScValidErrorStyle eEStyle, sal_uLong nIndex ):
1043 eValMode(eMode), eCondOp(eOp), aStrVal1(aExpr1),
1044 aStrVal2(aExpr2), pDocument(pDoc), aPosition(aPos),
1045 aErrorTitle(aETitle), aErrorMessage(aEMsg),
1046 eErrorStyle(eEStyle), nExpectedIndex(nIndex) { };
1049 void checkValiditationEntries( const ValDataTestParams& rVDTParams )
1051 ScDocument* pDoc = rVDTParams.pDocument;
1053 //create expected data validation entry
1054 ScValidationData aValData(
1055 rVDTParams.eValMode, rVDTParams.eCondOp, rVDTParams.aStrVal1,
1056 rVDTParams.aStrVal2, pDoc, rVDTParams.aPosition, EMPTY_STRING,
1057 EMPTY_STRING, pDoc->GetStorageGrammar(), pDoc->GetStorageGrammar()
1059 aValData.SetIgnoreBlank( true );
1060 aValData.SetListType( 1 );
1061 aValData.ResetInput();
1062 aValData.SetError( rVDTParams.aErrorTitle, rVDTParams.aErrorMessage, rVDTParams.eErrorStyle );
1063 aValData.SetSrcString( EMPTY_STRING );
1065 //get actual data validation entry from document
1066 const ScValidationData* pValDataTest = pDoc->GetValidationEntry( rVDTParams.nExpectedIndex );
1068 sal_Int32 nCol( static_cast<sal_Int32>(rVDTParams.aPosition.Col()) );
1069 sal_Int32 nRow( static_cast<sal_Int32>(rVDTParams.aPosition.Row()) );
1070 sal_Int32 nTab( static_cast<sal_Int32>(rVDTParams.aPosition.Tab()) );
1071 OStringBuffer sMsg("Data Validation Entry with base-cell-address: (");
1072 sMsg.append(nCol).append(",").append(nRow).append(",").append(nTab).append(") was not imported correctly.");
1073 //check if expected and actual data validation entries are equal
1074 CPPUNIT_ASSERT_MESSAGE( sMsg.getStr(), pValDataTest && aValData.EqualEntries(*pValDataTest) );
1077 void checkCellValidity( const ScAddress& rValBaseAddr, const ScRange& rRange, const ScDocument* pDoc )
1079 SCCOL nBCol( rValBaseAddr.Col() );
1080 SCROW nBRow( rValBaseAddr.Row() );
1081 SCTAB nTab( static_cast<const sal_Int32>(rValBaseAddr.Tab()) );
1082 //get from the document the data validation entry we are checking against
1083 const SfxUInt32Item* pItem = static_cast<const SfxUInt32Item*>(pDoc->GetAttr(nBCol, nBRow, nTab, ATTR_VALIDDATA) );
1084 const ScValidationData* pValData = pDoc->GetValidationEntry( pItem->GetValue() );
1086 //check that each cell in the expected range is associated with the data validation entry
1087 for(SCCOL i = rRange.aStart.Col(); i <= rRange.aEnd.Col(); ++i)
1089 for(SCROW j = rRange.aStart.Row(); j <= rRange.aEnd.Row(); ++j)
1091 const SfxUInt32Item* pItemTest = static_cast<const SfxUInt32Item*>( pDoc->GetAttr(i, j, nTab, ATTR_VALIDDATA) );
1092 const ScValidationData* pValDataTest = pDoc->GetValidationEntry( pItemTest->GetValue() );
1093 //prevent string operations for occurring unnecessarily
1094 if(!(pValDataTest && pValData->GetKey() == pValDataTest->GetKey()))
1096 sal_Int32 nCol = static_cast<const sal_Int32>(i);
1097 sal_Int32 nRow = static_cast<const sal_Int32>(j);
1098 sal_Int32 nTab32 = static_cast<const sal_Int32>(nTab);
1099 OStringBuffer sMsg("\nData validation entry base-cell-address: (");
1100 sMsg.append( static_cast<const sal_Int32>(nBCol) ).append(",");
1101 sMsg.append( static_cast<const sal_Int32>(nBRow) ).append(",");
1102 sMsg.append( nTab32 ).append(")\n");
1103 sMsg.append("Cell: (").append(nCol).append(",").append(nRow).append(",").append(nTab32).append(")");
1104 sal_uInt32 expectedKey(pValData->GetKey());
1105 sal_uInt32 actualKey(-1);
1106 if(pValDataTest)
1107 actualKey = pValDataTest->GetKey();
1108 CPPUNIT_ASSERT_EQUAL_MESSAGE(sMsg.getStr(), expectedKey, actualKey);
1116 void ScFiltersTest::testDataValidityODS()
1118 ScDocShellRef xDocSh = loadDoc("dataValidity.", ODS);
1119 ScDocument* pDoc = xDocSh->GetDocument();
1121 ScAddress aValBaseAddr1( 2,6,0 ); //sheet1
1122 ScAddress aValBaseAddr2( 2,3,1 ); //sheet2
1124 //sheet1's expected Data Validation Entry values
1125 ValDataTestParams aVDTParams1(
1126 SC_VALID_DECIMAL, SC_COND_GREATER, String("3.14"), EMPTY_STRING, pDoc,
1127 aValBaseAddr1, String("Too small"),
1128 String("The number you are trying to enter is not greater than 3.14! Are you sure you want to enter it anyway?"),
1129 SC_VALERR_WARNING, 1
1131 //sheet2's expected Data Validation Entry values
1132 ValDataTestParams aVDTParams2(
1133 SC_VALID_WHOLE, SC_COND_BETWEEN, String("1"), String("10"), pDoc,
1134 aValBaseAddr2, String("Error sheet 2"),
1135 String("Must be a whole number between 1 and 10."),
1136 SC_VALERR_STOP, 2
1138 //check each sheet's Data Validation Entries
1139 checkValiditationEntries( aVDTParams1 );
1140 checkValiditationEntries( aVDTParams2 );
1142 //expected ranges to be associated with data validity
1143 ScRange aRange1( 2,2,0, 2,6,0 ); //sheet1
1144 ScRange aRange2( 2,3,1, 6,7,1 ); //sheet2
1146 //check each sheet's cells for data validity
1147 checkCellValidity( aValBaseAddr1, aRange1, pDoc );
1148 checkCellValidity( aValBaseAddr2, aRange2, pDoc );
1150 //check each sheet's content
1151 OUString aCSVFileName1;
1152 createCSVPath(OUString("dataValidity1."), aCSVFileName1);
1153 testFile(aCSVFileName1, pDoc, 0);
1155 OUString aCSVFileName2;
1156 createCSVPath(OUString("dataValidity2."), aCSVFileName2);
1157 testFile(aCSVFileName2, pDoc, 1);
1159 xDocSh->DoClose();
1162 void ScFiltersTest::testBrokenQuotesCSV()
1164 const OUString aFileNameBase("fdo48621_broken_quotes.");
1165 OUString aFileExtension(aFileFormats[CSV].pName, strlen(aFileFormats[CSV].pName), RTL_TEXTENCODING_UTF8 );
1166 OUString aFilterName(aFileFormats[CSV].pFilterName, strlen(aFileFormats[CSV].pFilterName), RTL_TEXTENCODING_UTF8) ;
1167 OUString aFileName;
1168 createFileURL(aFileNameBase, aFileExtension, aFileName);
1169 OUString aFilterType(aFileFormats[CSV].pTypeName, strlen(aFileFormats[CSV].pTypeName), RTL_TEXTENCODING_UTF8);
1170 std::cout << aFileFormats[CSV].pName << " Test" << std::endl;
1172 unsigned int nFormatType = aFileFormats[CSV].nFormatType;
1173 unsigned int nClipboardId = nFormatType ? SFX_FILTER_IMPORT | SFX_FILTER_USESOPTIONS : 0;
1174 ScDocShellRef xDocSh = ScBootstrapFixture::load(aFileName, aFilterName, OUString(), aFilterType,
1175 nFormatType, nClipboardId, SOFFICE_FILEFORMAT_CURRENT);
1177 CPPUNIT_ASSERT_MESSAGE("Failed to load fdo48621_broken_quotes.csv", xDocSh.Is());
1178 ScDocument* pDoc = xDocSh->GetDocument();
1179 CPPUNIT_ASSERT_MESSAGE("No Document", pDoc); //remove with first test
1181 OUString aSheet2CSV("fdo48621_broken_quotes_exported.");
1182 OUString aCSVPath;
1183 createCSVPath( aSheet2CSV, aCSVPath );
1184 // fdo#48621
1185 testFile( aCSVPath, pDoc, 0, PureString);
1187 xDocSh->DoClose();
1190 void ScFiltersTest::testSharedFormulaXLSX()
1192 const OUString aFileNameBase("shared-formula.");
1193 OUString aFileExtension(aFileFormats[XLSX].pName, strlen(aFileFormats[XLSX].pName), RTL_TEXTENCODING_UTF8 );
1194 OUString aFilterName(aFileFormats[XLSX].pFilterName, strlen(aFileFormats[XLSX].pFilterName), RTL_TEXTENCODING_UTF8) ;
1195 OUString aFileName;
1196 createFileURL(aFileNameBase, aFileExtension, aFileName);
1197 OUString aFilterType(aFileFormats[XLSX].pTypeName, strlen(aFileFormats[XLSX].pTypeName), RTL_TEXTENCODING_UTF8);
1198 std::cout << aFileFormats[XLSX].pName << " Test" << std::endl;
1200 unsigned int nFormatType = aFileFormats[XLSX].nFormatType;
1201 unsigned int nClipboardId = nFormatType ? SFX_FILTER_IMPORT | SFX_FILTER_USESOPTIONS : 0;
1202 ScDocShellRef xDocSh = ScBootstrapFixture::load(aFileName, aFilterName, OUString(), aFilterType,
1203 nFormatType, nClipboardId, SOFFICE_FILEFORMAT_CURRENT);
1205 xDocSh->DoHardRecalc(true);
1207 CPPUNIT_ASSERT_MESSAGE("Failed to load shared-formula.xlsx", xDocSh.Is());
1208 ScDocument* pDoc = xDocSh->GetDocument();
1209 CPPUNIT_ASSERT_MESSAGE("No Document", pDoc); //remove with first test
1211 OUString aCSVPath;
1212 createCSVPath( aFileNameBase, aCSVPath );
1213 testFile( aCSVPath, pDoc, 0 );
1215 //test some additional properties
1216 ScRangeName* pName = pDoc->GetRangeName();
1217 for (ScRangeName::iterator itr = pName->begin(); itr != pName->end(); ++itr)
1219 CPPUNIT_ASSERT(itr->second->GetType() & RT_SHARED);
1222 xDocSh->DoClose();
1225 void ScFiltersTest::testCellValueXLSX()
1227 const OUString aFileNameBase("cell-value.");
1228 OUString aFileExtension(aFileFormats[XLSX].pName, strlen(aFileFormats[XLSX].pName), RTL_TEXTENCODING_UTF8 );
1229 OUString aFilterName(aFileFormats[XLSX].pFilterName, strlen(aFileFormats[XLSX].pFilterName), RTL_TEXTENCODING_UTF8) ;
1230 OUString aFileName;
1231 createFileURL(aFileNameBase, aFileExtension, aFileName);
1232 OUString aFilterType(aFileFormats[XLSX].pTypeName, strlen(aFileFormats[XLSX].pTypeName), RTL_TEXTENCODING_UTF8);
1233 std::cout << aFileFormats[XLSX].pName << " Test" << std::endl;
1235 unsigned int nFormatType = aFileFormats[XLSX].nFormatType;
1236 unsigned int nClipboardId = nFormatType ? SFX_FILTER_IMPORT | SFX_FILTER_USESOPTIONS : 0;
1237 ScDocShellRef xDocSh = ScBootstrapFixture::load( aFileName, aFilterName, OUString(), aFilterType,
1238 nFormatType, nClipboardId, SOFFICE_FILEFORMAT_CURRENT);
1240 CPPUNIT_ASSERT_MESSAGE("Failed to load cell-value.xlsx", xDocSh.Is());
1241 ScDocument* pDoc = xDocSh->GetDocument();
1242 CPPUNIT_ASSERT_MESSAGE("No Document", pDoc); //remove with first test
1244 OUString aCSVPath;
1245 createCSVPath( aFileNameBase, aCSVPath );
1246 testFile( aCSVPath, pDoc, 0 );
1248 xDocSh->DoClose();
1251 void ScFiltersTest::testPassword_Impl(const OUString& aFileNameBase)
1253 OUString aFileExtension(aFileFormats[0].pName, strlen(aFileFormats[0].pName), RTL_TEXTENCODING_UTF8 );
1254 OUString aFilterName(aFileFormats[0].pFilterName, strlen(aFileFormats[0].pFilterName), RTL_TEXTENCODING_UTF8) ;
1255 OUString aFileName;
1256 createFileURL(aFileNameBase, aFileExtension, aFileName);
1257 OUString aFilterType(aFileFormats[0].pTypeName, strlen(aFileFormats[0].pTypeName), RTL_TEXTENCODING_UTF8);
1259 sal_uInt32 nFormat = SFX_FILTER_IMPORT | SFX_FILTER_USESOPTIONS;
1260 SfxFilter* aFilter = new SfxFilter(
1261 aFilterName,
1262 OUString(), aFileFormats[0].nFormatType, nFormat, aFilterType, 0, OUString(),
1263 OUString(), OUString("private:factory/scalc*") );
1264 aFilter->SetVersion(SOFFICE_FILEFORMAT_CURRENT);
1266 ScDocShellRef xDocSh = new ScDocShell;
1267 SfxMedium* pMedium = new SfxMedium(aFileName, STREAM_STD_READWRITE);
1268 SfxItemSet* pSet = pMedium->GetItemSet();
1269 pSet->Put(SfxStringItem(SID_PASSWORD, OUString("test")));
1270 pMedium->SetFilter(aFilter);
1271 if (!xDocSh->DoLoad(pMedium))
1273 xDocSh->DoClose();
1274 // load failed.
1275 xDocSh.Clear();
1278 CPPUNIT_ASSERT_MESSAGE("Failed to load password.ods", xDocSh.Is());
1279 ScDocument* pDoc = xDocSh->GetDocument();
1280 CPPUNIT_ASSERT_MESSAGE("No Document", pDoc); //remove with first test
1281 xDocSh->DoClose();
1285 void ScFiltersTest::testPasswordNew()
1287 //tests opening a file with new password algorithm
1288 const OUString aFileNameBase("password.");
1289 testPassword_Impl(aFileNameBase);
1292 void ScFiltersTest::testPasswordOld()
1294 //tests opening a file with old password algorithm
1295 const OUString aFileNameBase("passwordOld.");
1296 testPassword_Impl(aFileNameBase);
1299 void ScFiltersTest::testPasswordWrongSHA()
1301 //tests opening a file wrongly using the new password algorithm
1302 //in a sxc with the key algorithm missing
1303 const OUString aFileNameBase("passwordWrongSHA.");
1304 testPassword_Impl(aFileNameBase);
1307 void ScFiltersTest::testControlImport()
1309 ScDocShellRef xDocSh = loadDoc("singlecontrol.", XLSX);
1310 CPPUNIT_ASSERT_MESSAGE("Failed to load singlecontrol.xlsx", xDocSh.Is());
1312 uno::Reference< frame::XModel > xModel = xDocSh->GetModel();
1313 uno::Reference< sheet::XSpreadsheetDocument > xDoc(xModel, UNO_QUERY_THROW);
1314 uno::Reference< container::XIndexAccess > xIA(xDoc->getSheets(), UNO_QUERY_THROW);
1315 uno::Reference< drawing::XDrawPageSupplier > xDrawPageSupplier( xIA->getByIndex(0), UNO_QUERY_THROW);
1316 uno::Reference< container::XIndexAccess > xIA_DrawPage(xDrawPageSupplier->getDrawPage(), UNO_QUERY_THROW);
1317 uno::Reference< drawing::XControlShape > xControlShape(xIA_DrawPage->getByIndex(0), UNO_QUERY_THROW);
1319 CPPUNIT_ASSERT(xControlShape.is());
1320 xDocSh->DoClose();
1323 void ScFiltersTest::testChartImportODS()
1325 ScDocShellRef xDocSh = loadDoc("chart-import-basic.", ODS);
1326 CPPUNIT_ASSERT_MESSAGE("Failed to load chart-import-basic.ods.", xDocSh.Is());
1328 ScDocument* pDoc = xDocSh->GetDocument();
1330 // Ensure that the document contains "Empty", "Chart", "Data" and "Title" sheets in this exact order.
1331 CPPUNIT_ASSERT_MESSAGE("There should be 4 sheets in this document.", pDoc->GetTableCount() == 4);
1332 OUString aName;
1333 pDoc->GetName(0, aName);
1334 CPPUNIT_ASSERT_EQUAL(OUString("Empty"), aName);
1335 pDoc->GetName(1, aName);
1336 CPPUNIT_ASSERT_EQUAL(OUString("Chart"), aName);
1337 pDoc->GetName(2, aName);
1338 CPPUNIT_ASSERT_EQUAL(OUString("Data"), aName);
1339 pDoc->GetName(3, aName);
1340 CPPUNIT_ASSERT_EQUAL(OUString("Title"), aName);
1342 // Retrieve the chart object instance from the 2nd page (for the 2nd sheet).
1343 ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
1344 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve the drawing layer object.", pDrawLayer);
1345 const SdrPage* pPage = pDrawLayer->GetPage(1); // for the 2nd sheet.
1346 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve the page object.", pPage);
1347 CPPUNIT_ASSERT_MESSAGE("This page should contain one drawing object.", pPage->GetObjCount() == 1);
1348 const SdrObject* pObj = pPage->GetObj(0);
1349 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve the drawing object.", pObj);
1350 CPPUNIT_ASSERT_MESSAGE("This is not an OLE2 object.", pObj->GetObjIdentifier() == OBJ_OLE2);
1351 const SdrOle2Obj& rOleObj = static_cast<const SdrOle2Obj&>(*pObj);
1352 CPPUNIT_ASSERT_MESSAGE("This should be a chart object.", rOleObj.IsChart());
1354 // Make sure the chart object has correct range references.
1355 Reference<frame::XModel> xModel = rOleObj.getXModel();
1356 CPPUNIT_ASSERT_MESSAGE("Failed to get the embedded object interface.", xModel.is());
1357 Reference<chart2::XChartDocument> xChartDoc(xModel, UNO_QUERY);
1358 CPPUNIT_ASSERT_MESSAGE("Failed to get the chart document interface.", xChartDoc.is());
1359 Reference<chart2::data::XDataSource> xDataSource(xChartDoc, UNO_QUERY);
1360 CPPUNIT_ASSERT_MESSAGE("Failed to get the data source interface.", xDataSource.is());
1361 Sequence<Reference<chart2::data::XLabeledDataSequence> > xDataSeqs = xDataSource->getDataSequences();
1362 CPPUNIT_ASSERT_MESSAGE("There should be at least one data sequences.", xDataSeqs.getLength() > 0);
1363 Reference<chart2::data::XDataReceiver> xDataRec(xChartDoc, UNO_QUERY);
1364 CPPUNIT_ASSERT_MESSAGE("Failed to get the data receiver interface.", xDataRec.is());
1365 Sequence<OUString> aRangeReps = xDataRec->getUsedRangeRepresentations();
1366 CPPUNIT_ASSERT_MESSAGE("There should be at least one range representations.", aRangeReps.getLength() > 0);
1368 ScRangeList aRanges;
1369 for (sal_Int32 i = 0, n = aRangeReps.getLength(); i < n; ++i)
1371 ScRange aRange;
1372 sal_uInt16 nRes = aRange.Parse(aRangeReps[i], pDoc, pDoc->GetAddressConvention());
1373 if (nRes & SCA_VALID)
1374 // This is a range address.
1375 aRanges.Append(aRange);
1376 else
1378 // Parse it as a single cell address.
1379 ScAddress aAddr;
1380 nRes = aAddr.Parse(aRangeReps[i], pDoc, pDoc->GetAddressConvention());
1381 CPPUNIT_ASSERT_MESSAGE("Failed to parse a range representation.", (nRes & SCA_VALID));
1382 aRanges.Append(aAddr);
1386 CPPUNIT_ASSERT_MESSAGE("Data series title cell not found.", aRanges.In(ScAddress(1,0,3))); // B1 on Title
1387 CPPUNIT_ASSERT_MESSAGE("Data series label range not found.", aRanges.In(ScRange(0,1,2,0,3,2))); // A2:A4 on Data
1388 CPPUNIT_ASSERT_MESSAGE("Data series value range not found.", aRanges.In(ScRange(1,1,2,1,3,2))); // B2:B4 on Data
1390 xDocSh->DoClose();
1393 void ScFiltersTest::testNumberFormatHTML()
1395 ScDocShellRef xDocSh = loadDoc("numberformat.", HTML);
1396 CPPUNIT_ASSERT_MESSAGE("Failed to load numberformat.html", xDocSh.Is());
1398 ScDocument* pDoc = xDocSh->GetDocument();
1400 // Check the header just in case.
1401 CPPUNIT_ASSERT_MESSAGE("Cell value is not as expected", pDoc->GetString(0, 0, 0) == "Product");
1402 CPPUNIT_ASSERT_MESSAGE("Cell value is not as expected", pDoc->GetString(1, 0, 0) == "Price");
1403 CPPUNIT_ASSERT_MESSAGE("Cell value is not as expected", pDoc->GetString(2, 0, 0) == "Note");
1405 // B2 should be imported as a value cell.
1406 bool bHasValue = pDoc->HasValueData(1, 1, 0);
1407 CPPUNIT_ASSERT_MESSAGE("Fail to import number as a value cell.", bHasValue);
1408 CPPUNIT_ASSERT_MESSAGE("Incorrect value.", pDoc->GetValue(1, 1, 0) == 199.98);
1410 xDocSh->DoClose();
1413 void ScFiltersTest::testNumberFormatCSV()
1415 ScDocShellRef xDocSh = loadDoc("numberformat.", CSV);
1416 CPPUNIT_ASSERT_MESSAGE("Failed to load numberformat.csv", xDocSh.Is());
1418 ScDocument* pDoc = xDocSh->GetDocument();
1420 // Check the header just in case.
1421 CPPUNIT_ASSERT_MESSAGE("Cell value is not as expected", pDoc->GetString(0, 0, 0) == "Product");
1422 CPPUNIT_ASSERT_MESSAGE("Cell value is not as expected", pDoc->GetString(1, 0, 0) == "Price");
1423 CPPUNIT_ASSERT_MESSAGE("Cell value is not as expected", pDoc->GetString(2, 0, 0) == "Note");
1425 // B2 should be imported as a value cell.
1426 bool bHasValue = pDoc->HasValueData(1, 1, 0);
1427 CPPUNIT_ASSERT_MESSAGE("Fail to import number as a value cell.", bHasValue);
1428 CPPUNIT_ASSERT_MESSAGE("Incorrect value.", pDoc->GetValue(1, 1, 0) == 199.98);
1430 xDocSh->DoClose();
1433 void ScFiltersTest::testCellAnchoredShapesODS()
1435 ScDocShellRef xDocSh = loadDoc("cell-anchored-shapes.", ODS);
1436 CPPUNIT_ASSERT_MESSAGE("Failed to load cell-anchored-shapes.ods", xDocSh.Is());
1438 // There are two cell-anchored objects on the first sheet.
1439 ScDocument* pDoc = xDocSh->GetDocument();
1441 CPPUNIT_ASSERT_MESSAGE("There should be at least one sheet.", pDoc->GetTableCount() > 0);
1443 ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
1444 SdrPage* pPage = pDrawLayer->GetPage(0);
1445 CPPUNIT_ASSERT_MESSAGE("draw page for sheet 1 should exist.", pPage);
1446 sal_uIntPtr nCount = pPage->GetObjCount();
1447 CPPUNIT_ASSERT_MESSAGE("There should be 2 objects.", nCount == 2);
1448 for (sal_uIntPtr i = 0; i < nCount; ++i)
1450 SdrObject* pObj = pPage->GetObj(i);
1451 CPPUNIT_ASSERT_MESSAGE("Failed to get drawing object.", pObj);
1452 ScDrawObjData* pData = ScDrawLayer::GetObjData(pObj, false);
1453 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve user data for this object.", pData);
1454 CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pData->maLastRect.IsEmpty());
1457 xDocSh->DoClose();
1460 namespace {
1462 class FindDimByName : std::unary_function<const ScDPSaveDimension*, bool>
1464 OUString maName;
1465 public:
1466 FindDimByName(const OUString& rName) : maName(rName) {}
1468 bool operator() (const ScDPSaveDimension* p) const
1470 return p && p->GetName() == maName;
1474 bool hasDimension(const std::vector<const ScDPSaveDimension*>& rDims, const OUString& aName)
1476 return std::find_if(rDims.begin(), rDims.end(), FindDimByName(aName)) != rDims.end();
1481 void ScFiltersTest::testPivotTableBasicODS()
1483 ScDocShellRef xDocSh = loadDoc("pivot-table-basic.", ODS);
1484 CPPUNIT_ASSERT_MESSAGE("Failed to load pivot-table-basic.ods", xDocSh.Is());
1486 ScDocument* pDoc = xDocSh->GetDocument();
1487 CPPUNIT_ASSERT_MESSAGE("There should be exactly two sheets.", pDoc->GetTableCount() == 2);
1489 ScDPCollection* pDPs = pDoc->GetDPCollection();
1490 CPPUNIT_ASSERT_MESSAGE("Failed to get a live ScDPCollection instance.", pDPs);
1491 CPPUNIT_ASSERT_MESSAGE("There should be exactly one pivot table instance.", pDPs->GetCount() == 1);
1493 const ScDPObject* pDPObj = (*pDPs)[0];
1494 CPPUNIT_ASSERT_MESSAGE("Failed to get an pivot table object.", pDPObj);
1495 const ScDPSaveData* pSaveData = pDPObj->GetSaveData();
1496 CPPUNIT_ASSERT_MESSAGE("Failed to get ScDPSaveData instance.", pSaveData);
1497 std::vector<const ScDPSaveDimension*> aDims;
1499 // Row fields
1500 pSaveData->GetAllDimensionsByOrientation(sheet::DataPilotFieldOrientation_ROW, aDims);
1501 CPPUNIT_ASSERT_MESSAGE("There should be exactly 3 row fields (2 normal dimensions and 1 layout dimension).", aDims.size() == 3);
1502 CPPUNIT_ASSERT_MESSAGE("Dimension expected, but not found.", hasDimension(aDims, "Row1"));
1503 CPPUNIT_ASSERT_MESSAGE("Dimension expected, but not found.", hasDimension(aDims, "Row2"));
1504 const ScDPSaveDimension* pDataLayout = pSaveData->GetExistingDataLayoutDimension();
1505 CPPUNIT_ASSERT_MESSAGE("There should be a data layout field as a row field.",
1506 pDataLayout && pDataLayout->GetOrientation() == sheet::DataPilotFieldOrientation_ROW);
1508 // Column fields
1509 pSaveData->GetAllDimensionsByOrientation(sheet::DataPilotFieldOrientation_COLUMN, aDims);
1510 CPPUNIT_ASSERT_MESSAGE("There should be exactly 2 column fields.", aDims.size() == 2);
1511 CPPUNIT_ASSERT_MESSAGE("Dimension expected, but not found.", hasDimension(aDims, "Col1"));
1512 CPPUNIT_ASSERT_MESSAGE("Dimension expected, but not found.", hasDimension(aDims, "Col2"));
1514 // Page fields
1515 pSaveData->GetAllDimensionsByOrientation(sheet::DataPilotFieldOrientation_PAGE, aDims);
1516 CPPUNIT_ASSERT_MESSAGE("There should be exactly 2 page fields.", aDims.size() == 2);
1517 CPPUNIT_ASSERT_MESSAGE("Dimension expected, but not found.", hasDimension(aDims, "Page1"));
1518 CPPUNIT_ASSERT_MESSAGE("Dimension expected, but not found.", hasDimension(aDims, "Page2"));
1520 // Check the data field.
1521 pSaveData->GetAllDimensionsByOrientation(sheet::DataPilotFieldOrientation_DATA, aDims);
1522 CPPUNIT_ASSERT_MESSAGE("There should be exactly 1 data field.", aDims.size() == 1);
1523 const ScDPSaveDimension* pDim = aDims.back();
1524 CPPUNIT_ASSERT_MESSAGE("Function for the data field should be COUNT.", pDim->GetFunction() == sheet::GeneralFunction_COUNT);
1526 xDocSh->DoClose();
1529 void ScFiltersTest::testRowHeightODS()
1531 ScDocShellRef xDocSh = loadDoc("row-height-import.", ODS);
1532 CPPUNIT_ASSERT_MESSAGE("Failed to load row-height-import.ods", xDocSh.Is());
1534 SCTAB nTab = 0;
1535 SCROW nRow = 0;
1536 ScDocument* pDoc = xDocSh->GetDocument();
1538 // The first 3 rows have manual heights.
1539 int nHeight = pDoc->GetRowHeight(nRow, nTab, false);
1540 bool bManual = pDoc->IsManualRowHeight(nRow, nTab);
1541 CPPUNIT_ASSERT_EQUAL(600, nHeight);
1542 CPPUNIT_ASSERT_MESSAGE("this row should have a manual row height.", bManual);
1543 nHeight = pDoc->GetRowHeight(++nRow, nTab, false);
1544 bManual = pDoc->IsManualRowHeight(nRow, nTab);
1545 CPPUNIT_ASSERT_EQUAL(1200, nHeight);
1546 CPPUNIT_ASSERT_MESSAGE("this row should have a manual row height.", bManual);
1547 nHeight = pDoc->GetRowHeight(++nRow, nTab, false);
1548 bManual = pDoc->IsManualRowHeight(nRow, nTab);
1549 CPPUNIT_ASSERT_EQUAL(1800, nHeight);
1550 CPPUNIT_ASSERT_MESSAGE("this row should have a manual row height.", bManual);
1552 // This one should have an automatic row height.
1553 bManual = pDoc->IsManualRowHeight(++nRow, nTab);
1554 CPPUNIT_ASSERT_MESSAGE("Row should have an automatic height.", !bManual);
1556 // Followed by a row with manual height.
1557 nHeight = pDoc->GetRowHeight(++nRow, nTab, false);
1558 bManual = pDoc->IsManualRowHeight(nRow, nTab);
1559 CPPUNIT_ASSERT_EQUAL(2400, nHeight);
1560 CPPUNIT_ASSERT_MESSAGE("this row should have a manual row height.", bManual);
1562 // And all the rest should have automatic heights.
1563 bManual = pDoc->IsManualRowHeight(++nRow, nTab);
1564 CPPUNIT_ASSERT_MESSAGE("Row should have an automatic height.", !bManual);
1566 bManual = pDoc->IsManualRowHeight(MAXROW, nTab);
1567 CPPUNIT_ASSERT_MESSAGE("Row should have an automatic height.", !bManual);
1569 xDocSh->DoClose();
1572 void ScFiltersTest::testRichTextContentODS()
1574 ScDocShellRef xDocSh = loadDoc("rich-text-cells.", ODS);
1575 CPPUNIT_ASSERT_MESSAGE("Failed to load rich-text-cells.ods", xDocSh.Is());
1576 ScDocument* pDoc = xDocSh->GetDocument();
1578 OUString aTabName;
1579 CPPUNIT_ASSERT_MESSAGE("Failed to get the name of the first sheet.", pDoc->GetName(0, aTabName));
1581 // All tested cells are in the first column.
1582 ScAddress aPos(0, 0, 0);
1584 // Normal simple string with no formatting.
1585 aPos.IncRow();
1586 CPPUNIT_ASSERT_EQUAL(CELLTYPE_STRING, pDoc->GetCellType(aPos));
1587 CPPUNIT_ASSERT_EQUAL(OUString("Normal"), pDoc->GetString(aPos.Col(), aPos.Row(), aPos.Tab()));
1589 // Normal string with bold applied to the whole cell.
1591 aPos.IncRow();
1592 CPPUNIT_ASSERT_EQUAL(CELLTYPE_STRING, pDoc->GetCellType(aPos));
1593 CPPUNIT_ASSERT_EQUAL(OUString("All bold"), pDoc->GetString(aPos.Col(), aPos.Row(), aPos.Tab()));
1594 const ScPatternAttr* pAttr = pDoc->GetPattern(aPos.Col(), aPos.Row(), aPos.Tab());
1595 CPPUNIT_ASSERT_MESSAGE("Failed to get cell attribute.", pAttr);
1596 const SvxWeightItem& rWeightItem =
1597 static_cast<const SvxWeightItem&>(pAttr->GetItem(ATTR_FONT_WEIGHT));
1598 CPPUNIT_ASSERT_EQUAL(WEIGHT_BOLD, rWeightItem.GetWeight());
1601 // This cell has an unformatted but multi-line content. Multi-line text is
1602 // stored in edit cell even if it has no formatting applied.
1603 aPos.IncRow();
1604 CPPUNIT_ASSERT_EQUAL(CELLTYPE_EDIT, pDoc->GetCellType(aPos));
1605 const EditTextObject* pEditText = pDoc->GetEditText(aPos);
1606 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
1607 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(3), pEditText->GetParagraphCount());
1608 OUString aParaText = pEditText->GetText(0);
1609 CPPUNIT_ASSERT_EQUAL(OUString("one"), aParaText);
1610 aParaText = pEditText->GetText(1);
1611 CPPUNIT_ASSERT_EQUAL(OUString("two"), aParaText);
1612 aParaText = pEditText->GetText(2);
1613 CPPUNIT_ASSERT_EQUAL(OUString("three"), aParaText);
1615 // Cell with sheet name field item.
1616 aPos.IncRow();
1617 CPPUNIT_ASSERT_EQUAL(CELLTYPE_EDIT, pDoc->GetCellType(aPos));
1618 pEditText = pDoc->GetEditText(aPos);
1619 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
1620 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), pEditText->GetParagraphCount());
1621 aParaText = pEditText->GetText(0);
1622 CPPUNIT_ASSERT_MESSAGE("Unexpected text.", aParaText.indexOf("Sheet name is ") == 0);
1623 CPPUNIT_ASSERT_MESSAGE("Sheet name field item not found.", pEditText->HasField(text::textfield::Type::TABLE));
1624 CPPUNIT_ASSERT_EQUAL(OUString("Sheet name is Test."), ScEditUtil::GetString(*pEditText, pDoc));
1625 CPPUNIT_ASSERT_EQUAL(OUString("Sheet name is ?."), ScEditUtil::GetString(*pEditText, NULL));
1627 // Cell with URL field item.
1628 aPos.IncRow();
1629 CPPUNIT_ASSERT_EQUAL(CELLTYPE_EDIT, pDoc->GetCellType(aPos));
1630 pEditText = pDoc->GetEditText(aPos);
1631 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
1632 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), pEditText->GetParagraphCount());
1633 aParaText = pEditText->GetText(0);
1634 CPPUNIT_ASSERT_MESSAGE("Unexpected text.", aParaText.indexOf("URL: ") == 0);
1635 CPPUNIT_ASSERT_MESSAGE("URL field item not found.", pEditText->HasField(text::textfield::Type::URL));
1636 CPPUNIT_ASSERT_EQUAL(OUString("URL: http://libreoffice.org"), ScEditUtil::GetString(*pEditText, pDoc));
1637 CPPUNIT_ASSERT_EQUAL(OUString("URL: http://libreoffice.org"), ScEditUtil::GetString(*pEditText, NULL));
1639 // Cell with Date field item.
1640 aPos.IncRow();
1641 CPPUNIT_ASSERT_EQUAL(CELLTYPE_EDIT, pDoc->GetCellType(aPos));
1642 pEditText = pDoc->GetEditText(aPos);
1643 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
1644 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), pEditText->GetParagraphCount());
1645 aParaText = pEditText->GetText(0);
1646 CPPUNIT_ASSERT_MESSAGE("Unexpected text.", aParaText.indexOf("Date: ") == 0);
1647 CPPUNIT_ASSERT_MESSAGE("Date field item not found.", pEditText->HasField(text::textfield::Type::DATE));
1648 CPPUNIT_ASSERT_MESSAGE("Date field not resolved with pDoc.", ScEditUtil::GetString(*pEditText, pDoc).indexOf("/20") > 0);
1649 CPPUNIT_ASSERT_MESSAGE("Date field not resolved with NULL.", ScEditUtil::GetString(*pEditText, NULL).indexOf("/20") > 0);
1651 // Cell with DocInfo title field item.
1652 aPos.IncRow();
1653 CPPUNIT_ASSERT_EQUAL(CELLTYPE_EDIT, pDoc->GetCellType(aPos));
1654 pEditText = pDoc->GetEditText(aPos);
1655 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
1656 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), pEditText->GetParagraphCount());
1657 aParaText = pEditText->GetText(0);
1658 CPPUNIT_ASSERT_MESSAGE("Unexpected text.", aParaText.indexOf("Title: ") == 0);
1659 CPPUNIT_ASSERT_MESSAGE("DocInfo title field item not found.", pEditText->HasField(text::textfield::Type::DOCINFO_TITLE));
1660 CPPUNIT_ASSERT_EQUAL(OUString("Title: Test Document"), ScEditUtil::GetString(*pEditText, pDoc));
1661 CPPUNIT_ASSERT_EQUAL(OUString("Title: ?"), ScEditUtil::GetString(*pEditText, NULL));
1663 // Cell with sentence with both bold and italic sequences.
1664 aPos.IncRow();
1665 CPPUNIT_ASSERT_EQUAL(CELLTYPE_EDIT, pDoc->GetCellType(aPos));
1666 pEditText = pDoc->GetEditText(aPos);
1667 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
1668 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), pEditText->GetParagraphCount());
1669 aParaText = pEditText->GetText(0);
1670 CPPUNIT_ASSERT_EQUAL(OUString("Sentence with bold and italic."), aParaText);
1671 std::vector<EECharAttrib> aAttribs;
1672 pEditText->GetCharAttribs(0, aAttribs);
1673 std::vector<EECharAttrib>::const_iterator it = aAttribs.begin(), itEnd = aAttribs.end();
1675 bool bHasBold = false, bHasItalic = false;
1676 for (; it != itEnd; ++it)
1678 OUString aSeg = aParaText.copy(it->nStart, it->nEnd - it->nStart);
1679 const SfxPoolItem* pAttr = it->pAttr;
1680 if (aSeg == "bold" && pAttr->Which() == EE_CHAR_WEIGHT && !bHasBold)
1682 const SvxWeightItem& rItem = static_cast<const SvxWeightItem&>(*pAttr);
1683 bHasBold = (rItem.GetWeight() == WEIGHT_BOLD);
1685 else if (aSeg == "italic" && pAttr->Which() == EE_CHAR_ITALIC && !bHasItalic)
1687 const SvxPostureItem& rItem = static_cast<const SvxPostureItem&>(*pAttr);
1688 bHasItalic = (rItem.GetPosture() == ITALIC_NORMAL);
1692 CPPUNIT_ASSERT_MESSAGE("This sentence is expected to have both bold and italic sequences.", bHasBold && bHasItalic);
1695 // Cell with multi-line content with formatting applied.
1696 aPos.IncRow();
1697 CPPUNIT_ASSERT_EQUAL(CELLTYPE_EDIT, pDoc->GetCellType(aPos));
1698 pEditText = pDoc->GetEditText(aPos);
1699 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
1700 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(3), pEditText->GetParagraphCount());
1701 aParaText = pEditText->GetText(0);
1702 CPPUNIT_ASSERT_EQUAL(OUString("bold"), aParaText);
1703 aParaText = pEditText->GetText(1);
1704 CPPUNIT_ASSERT_EQUAL(OUString("italic"), aParaText);
1705 aParaText = pEditText->GetText(2);
1706 CPPUNIT_ASSERT_EQUAL(OUString("underlined"), aParaText);
1708 // first line is bold.
1709 pEditText->GetCharAttribs(0, aAttribs);
1711 bool bHasBold = false;
1712 for (it = aAttribs.begin(), itEnd = aAttribs.end(); it != itEnd; ++it)
1714 if (it->pAttr->Which() == EE_CHAR_WEIGHT)
1716 const SvxWeightItem& rItem = static_cast<const SvxWeightItem&>(*it->pAttr);
1717 bHasBold = (rItem.GetWeight() == WEIGHT_BOLD);
1718 if (bHasBold)
1719 break;
1722 CPPUNIT_ASSERT_MESSAGE("First line should be bold.", bHasBold);
1725 // second line is italic.
1726 pEditText->GetCharAttribs(1, aAttribs);
1727 bool bHasItalic = false;
1728 for (it = aAttribs.begin(), itEnd = aAttribs.end(); it != itEnd; ++it)
1730 if (it->pAttr->Which() == EE_CHAR_ITALIC)
1732 const SvxPostureItem& rItem = static_cast<const SvxPostureItem&>(*it->pAttr);
1733 bHasItalic = (rItem.GetPosture() == ITALIC_NORMAL);
1734 if (bHasItalic)
1735 break;
1738 CPPUNIT_ASSERT_MESSAGE("Second line should be italic.", bHasItalic);
1740 // third line is underlined.
1741 pEditText->GetCharAttribs(2, aAttribs);
1742 bool bHasUnderline = false;
1743 for (it = aAttribs.begin(), itEnd = aAttribs.end(); it != itEnd; ++it)
1745 if (it->pAttr->Which() == EE_CHAR_UNDERLINE)
1747 const SvxUnderlineItem& rItem = static_cast<const SvxUnderlineItem&>(*it->pAttr);
1748 bHasUnderline = (rItem.GetLineStyle() == UNDERLINE_SINGLE);
1749 if (bHasUnderline)
1750 break;
1753 CPPUNIT_ASSERT_MESSAGE("Second line should be underlined.", bHasUnderline);
1755 // URL with formats applied. For now, we'll check whether or not the
1756 // field objects gets imported. Later we should add checks for the
1757 // formats.
1758 aPos.IncRow();
1759 pEditText = pDoc->GetEditText(aPos);
1760 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
1761 CPPUNIT_ASSERT_MESSAGE("URL field item not found.", pEditText->HasField(text::textfield::Type::URL));
1763 // Sheet name with formats applied.
1764 aPos.IncRow();
1765 pEditText = pDoc->GetEditText(aPos);
1766 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
1767 CPPUNIT_ASSERT_MESSAGE("Sheet name field item not found.", pEditText->HasField(text::textfield::Type::TABLE));
1769 // Date with formats applied.
1770 aPos.IncRow();
1771 pEditText = pDoc->GetEditText(aPos);
1772 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
1773 CPPUNIT_ASSERT_MESSAGE("Date field item not found.", pEditText->HasField(text::textfield::Type::DATE));
1775 // Document title with formats applied.
1776 aPos.IncRow();
1777 pEditText = pDoc->GetEditText(aPos);
1778 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
1779 CPPUNIT_ASSERT_MESSAGE("Date field item not found.", pEditText->HasField(text::textfield::Type::DOCINFO_TITLE));
1781 // URL for a file in the same directory. It should be converted into an absolute URL on import.
1782 aPos.IncRow();
1783 pEditText = pDoc->GetEditText(aPos);
1784 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
1785 const SvxFieldData* pData = pEditText->GetFieldData(0, 0, text::textfield::Type::URL);
1786 CPPUNIT_ASSERT_MESSAGE("Failed to get the URL data.", pData && pData->GetClassId() == text::textfield::Type::URL);
1787 const SvxURLField* pURLData = static_cast<const SvxURLField*>(pData);
1788 CPPUNIT_ASSERT_MESSAGE("URL is not absolute with respect to the file system.", pURLData->GetURL().startsWith("file:///"));
1790 // Embedded spaces as <text:s text:c='4' />, normal text
1791 aPos.IncRow();
1792 CPPUNIT_ASSERT_EQUAL(CELLTYPE_STRING, pDoc->GetCellType(aPos));
1793 CPPUNIT_ASSERT_EQUAL(OUString("one two"), pDoc->GetString(aPos.Col(), aPos.Row(), aPos.Tab()));
1795 // Leading space as <text:s />.
1796 aPos.IncRow();
1797 CPPUNIT_ASSERT_EQUAL(CELLTYPE_STRING, pDoc->GetCellType(aPos));
1798 CPPUNIT_ASSERT_EQUAL(OUString(" =3+4"), pDoc->GetString(aPos.Col(), aPos.Row(), aPos.Tab()));
1800 // Embedded spaces with <text:s text:c='4' /> inside a <text:span>, text
1801 // partly bold.
1802 aPos.IncRow();
1803 CPPUNIT_ASSERT_EQUAL(CELLTYPE_EDIT, pDoc->GetCellType(aPos));
1804 pEditText = pDoc->GetEditText(aPos);
1805 CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
1806 CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), pEditText->GetParagraphCount());
1807 aParaText = pEditText->GetText(0);
1808 CPPUNIT_ASSERT_EQUAL(OUString("one two"), aParaText);
1809 pEditText->GetCharAttribs(0, aAttribs);
1811 bool bHasBold = false;
1812 for (it = aAttribs.begin(), itEnd = aAttribs.end(); it != itEnd; ++it)
1814 if (it->pAttr->Which() == EE_CHAR_WEIGHT)
1816 const SvxWeightItem& rItem = static_cast<const SvxWeightItem&>(*it->pAttr);
1817 bHasBold = (rItem.GetWeight() == WEIGHT_BOLD);
1818 if (bHasBold)
1820 OUString aSeg = aParaText.copy(it->nStart, it->nEnd - it->nStart);
1821 CPPUNIT_ASSERT_EQUAL(OUString("e t"), aSeg);
1822 break;
1826 CPPUNIT_ASSERT_MESSAGE("Expected a bold sequence.", bHasBold);
1829 xDocSh->DoClose();
1832 void ScFiltersTest::testDataBarODS()
1834 ScDocShellRef xDocSh = loadDoc("databar.", ODS);
1835 CPPUNIT_ASSERT(xDocSh.Is());
1837 ScDocument* pDoc = xDocSh->GetDocument();
1838 CPPUNIT_ASSERT(pDoc);
1839 testDataBar_Impl(pDoc);
1841 xDocSh->DoClose();
1844 void ScFiltersTest::testDataBarXLSX()
1846 ScDocShellRef xDocSh = loadDoc("databar.", XLSX);
1847 CPPUNIT_ASSERT(xDocSh.Is());
1849 ScDocument* pDoc = xDocSh->GetDocument();
1850 CPPUNIT_ASSERT(pDoc);
1851 testDataBar_Impl(pDoc);
1853 xDocSh->DoClose();
1856 void ScFiltersTest::testColorScaleODS()
1858 ScDocShellRef xDocSh = loadDoc("colorscale.", ODS);
1859 CPPUNIT_ASSERT(xDocSh.Is());
1860 ScDocument* pDoc = xDocSh->GetDocument();
1861 CPPUNIT_ASSERT(pDoc);
1863 testColorScale2Entry_Impl(pDoc);
1864 testColorScale3Entry_Impl(pDoc);
1866 xDocSh->DoClose();
1869 void ScFiltersTest::testColorScaleXLSX()
1871 ScDocShellRef xDocSh = loadDoc("colorscale.", XLSX);
1872 CPPUNIT_ASSERT(xDocSh.Is());
1873 ScDocument* pDoc = xDocSh->GetDocument();
1874 CPPUNIT_ASSERT(pDoc);
1876 testColorScale2Entry_Impl(pDoc);
1877 testColorScale3Entry_Impl(pDoc);
1879 xDocSh->DoClose();
1882 void ScFiltersTest::testNewCondFormatODS()
1884 ScDocShellRef xDocSh = ScBootstrapFixture::loadDoc( "new_cond_format_test.", ODS );
1886 CPPUNIT_ASSERT_MESSAGE("Failed to load new_cond_format_test.xlsx", xDocSh.Is());
1888 ScDocument* pDoc = xDocSh->GetDocument();
1890 OUString aCSVFile("new_cond_format_test.");
1891 OUString aCSVPath;
1892 createCSVPath( aCSVFile, aCSVPath );
1893 testCondFile(aCSVPath, pDoc, 0);
1895 xDocSh->DoClose();
1898 void ScFiltersTest::testNewCondFormatXLSX()
1900 ScDocShellRef xDocSh = ScBootstrapFixture::loadDoc( "new_cond_format_test.", XLSX );
1902 CPPUNIT_ASSERT_MESSAGE("Failed to load new_cond_format_test.xlsx", xDocSh.Is());
1904 ScDocument* pDoc = xDocSh->GetDocument();
1906 OUString aCSVFile("new_cond_format_test.");
1907 OUString aCSVPath;
1908 createCSVPath( aCSVFile, aCSVPath );
1909 testCondFile(aCSVPath, pDoc, 0);
1911 xDocSh->DoClose();
1914 void ScFiltersTest::testFormulaDependency()
1916 ScDocShellRef xDocSh = ScBootstrapFixture::loadDoc( "dependencyTree.", ODS );
1918 ScDocument* pDoc = xDocSh->GetDocument();
1920 // check if formula in A1 changes value
1921 double nVal = pDoc->GetValue(0,0,0);
1922 CPPUNIT_ASSERT_DOUBLES_EQUAL(nVal, 1.0, 1e-10);
1923 pDoc->SetValue(0,1,0, 0.0);
1924 nVal = pDoc->GetValue(0,0,0);
1925 CPPUNIT_ASSERT_DOUBLES_EQUAL(nVal, 2.0, 1e-10);
1927 // check that the number format is implicity inherited
1928 // CPPUNIT_ASSERT_EQUAL(pDoc->GetString(0,4,0), pDoc->GetString(0,5,0));
1930 xDocSh->DoClose();
1933 void ScFiltersTest::testMiscRowHeights()
1935 TestParam::RowData DfltRowData[] =
1937 // check rows at the beginning and end of document
1938 // and make sure they are reported as the default row
1939 // height ( indicated by -1 )
1940 { 2, 4, 0, -1, 0, false },
1941 { 1048573, 1048575, 0, -1, 0, false },
1944 TestParam::RowData MultiLineOptData[] =
1946 // Row 0 is 12.63 mm and optimal flag is set
1947 { 0, 0, 0, 1263, CHECK_OPTIMAL, true },
1948 // Row 1 is 11.99 mm and optimal flag is NOT set
1949 { 1, 1, 0, 1199, CHECK_OPTIMAL, false },
1952 TestParam aTestValues[] =
1954 /* Checks that a document saved to ods with default rows does indeed
1955 have default row heights ( there was a problem where the optimal
1956 height was being calcuated after import if no hard height )
1958 { "alldefaultheights.", ODS, -1, SAL_N_ELEMENTS(DfltRowData), DfltRowData },
1959 /* Checks the imported height of some multiline input, additionally checks
1960 that the optimal height flag is set ( or not )
1962 { "multilineoptimal.", ODS, -1, SAL_N_ELEMENTS(MultiLineOptData), MultiLineOptData },
1964 miscRowHeightsTest( aTestValues, SAL_N_ELEMENTS(aTestValues) );
1967 // regression test at least fdo#59193
1968 // what we want to test here is that when cell contents are deleted
1969 // and the optimal flag is set for that row that the row is actually resized
1971 void ScFiltersTest::testOptimalHeightReset()
1973 ScDocShellRef xDocSh = loadDoc("multilineoptimal.", ODS, true);
1974 SCTAB nTab = 0;
1975 SCROW nRow = 0;
1976 ScDocument* pDoc = xDocSh->GetDocument();
1977 pDoc->EnableAdjustHeight( true );
1978 // open document in read/write mode ( otherwise optimal height stuff won't
1979 // be triggered ) *and* you can't delete cell contents.
1980 int nHeight = sc::TwipsToHMM ( pDoc->GetRowHeight(nRow, nTab, false) );
1981 CPPUNIT_ASSERT_EQUAL(1263, nHeight);
1983 ScDocFunc &rFunc = xDocSh->GetDocFunc();
1985 // delete content of A1
1986 ScRange aDelRange(0,0,0,0,0,0);
1987 ScMarkData aMark;
1988 aMark.SetMarkArea(aDelRange);
1989 rFunc.DeleteContents( aMark, IDF_ALL, false, true );
1991 // get the new height of A1
1992 nHeight = sc::TwipsToHMM( pDoc->GetRowHeight(nRow, nTab, false) );
1994 // set optimal height for empty row 2
1995 SCCOLROW nRowArr[2];
1996 nRowArr[0] = nRowArr[1] = 2;
1997 rFunc.SetWidthOrHeight( false, 1, nRowArr, nTab, SC_SIZE_OPTIMAL, 0, sal_True, sal_True );
1999 // retrieve optimal height
2000 int nOptimalHeight = sc::TwipsToHMM( pDoc->GetRowHeight( nRowArr[0], nTab, false) );
2002 // check if the new height of A1 ( after delete ) is now the optimal height of an empty cell
2003 CPPUNIT_ASSERT_EQUAL(nOptimalHeight, nHeight );
2004 xDocSh->DoClose();
2007 ScFiltersTest::ScFiltersTest()
2008 : ScBootstrapFixture( "/sc/qa/unit/data" )
2012 void ScFiltersTest::setUp()
2014 test::BootstrapFixture::setUp();
2016 // This is a bit of a fudge, we do this to ensure that ScGlobals::ensure,
2017 // which is a private symbol to us, gets called
2018 m_xCalcComponent =
2019 getMultiServiceFactory()->createInstance(OUString("com.sun.star.comp.Calc.SpreadsheetDocument"));
2020 CPPUNIT_ASSERT_MESSAGE("no calc component!", m_xCalcComponent.is());
2023 void ScFiltersTest::tearDown()
2025 uno::Reference< lang::XComponent >( m_xCalcComponent, UNO_QUERY_THROW )->dispose();
2026 test::BootstrapFixture::tearDown();
2029 CPPUNIT_TEST_SUITE_REGISTRATION(ScFiltersTest);
2031 CPPUNIT_PLUGIN_IMPLEMENT();
2033 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */