Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : */
9 :
10 : #include <sal/config.h>
11 : #include <unotest/filters-test.hxx>
12 : #include <test/bootstrapfixture.hxx>
13 : #include <rtl/strbuf.hxx>
14 : #include <osl/file.hxx>
15 :
16 : #include <sfx2/app.hxx>
17 : #include <sfx2/docfilt.hxx>
18 : #include <sfx2/docfile.hxx>
19 : #include <sfx2/sfxmodelfactory.hxx>
20 : #include <svl/stritem.hxx>
21 : #include "svx/svdpage.hxx"
22 : #include "svx/svdoole2.hxx"
23 :
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 "olinetab.hxx"
44 :
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>
55 :
56 : #define CALC_DEBUG_OUTPUT 0
57 : #define TEST_BUG_FILES 0
58 :
59 : #include "helper/qahelper.hxx"
60 : #include "helper/shared_test_impl.hxx"
61 :
62 : using namespace ::com::sun::star;
63 : using namespace ::com::sun::star::uno;
64 :
65 : /* Implementation of Filters test */
66 :
67 92 : class ScFiltersTest
68 : : public test::FiltersTest
69 : , public ScBootstrapFixture
70 : {
71 : public:
72 : ScFiltersTest();
73 :
74 : virtual bool load( const OUString &rFilter, const OUString &rURL,
75 : const OUString &rUserData, unsigned int nFilterFlags,
76 : unsigned int nClipboardID, unsigned int nFilterVersion);
77 :
78 : virtual void setUp();
79 : virtual void tearDown();
80 :
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();
108 :
109 : void testDataBarODS();
110 : void testDataBarXLSX();
111 : void testColorScaleODS();
112 : void testColorScaleXLSX();
113 : void testNewCondFormatODS();
114 : void testNewCondFormatXLSX();
115 :
116 : //change this test file only in excel and not in calc
117 : void testCellValueXLSX();
118 :
119 : //misc tests unrelated to the import filters
120 : void testPasswordNew();
121 : void testPasswordOld();
122 :
123 : //test shape import
124 : void testControlImport();
125 : void testChartImportODS();
126 :
127 : void testNumberFormatHTML();
128 : void testNumberFormatCSV();
129 :
130 : void testCellAnchoredShapesODS();
131 :
132 : void testPivotTableBasicODS();
133 : void testFormulaDependency();
134 :
135 : void testRowHeightODS();
136 : void testRichTextContentODS();
137 : void testMiscRowHeights();
138 : void testOptimalHeightReset();
139 :
140 : void testPrintRangeODS();
141 : void testOutlineODS();
142 :
143 2 : CPPUNIT_TEST_SUITE(ScFiltersTest);
144 1 : CPPUNIT_TEST(testBasicCellContentODS);
145 1 : CPPUNIT_TEST(testRangeNameXLS);
146 1 : CPPUNIT_TEST(testRangeNameXLSX);
147 1 : CPPUNIT_TEST(testHardRecalcODS);
148 1 : CPPUNIT_TEST(testFunctionsODS);
149 1 : CPPUNIT_TEST(testCachedFormulaResultsODS);
150 1 : CPPUNIT_TEST(testCachedMatrixFormulaResultsODS);
151 1 : CPPUNIT_TEST(testDatabaseRangesODS);
152 1 : CPPUNIT_TEST(testDatabaseRangesXLS);
153 1 : CPPUNIT_TEST(testDatabaseRangesXLSX);
154 1 : CPPUNIT_TEST(testFormatsODS);
155 : // CPPUNIT_TEST(testFormatsXLS); TODO: Fix this
156 : // CPPUNIT_TEST(testFormatsXLSX); TODO: Fix this
157 1 : CPPUNIT_TEST(testMatrixODS);
158 1 : CPPUNIT_TEST(testMatrixXLS);
159 1 : CPPUNIT_TEST(testBorderODS);
160 1 : CPPUNIT_TEST(testBorderXLS);
161 1 : CPPUNIT_TEST(testBorderXLSX);
162 1 : CPPUNIT_TEST(testBordersOoo33);
163 1 : CPPUNIT_TEST(testBugFixesODS);
164 1 : CPPUNIT_TEST(testBugFixesXLS);
165 1 : CPPUNIT_TEST(testBugFixesXLSX);
166 1 : CPPUNIT_TEST(testMergedCellsODS);
167 1 : CPPUNIT_TEST(testRepeatedColumnsODS);
168 1 : CPPUNIT_TEST(testDataValidityODS);
169 1 : CPPUNIT_TEST(testBrokenQuotesCSV);
170 1 : CPPUNIT_TEST(testCellValueXLSX);
171 1 : CPPUNIT_TEST(testControlImport);
172 1 : CPPUNIT_TEST(testChartImportODS);
173 :
174 1 : CPPUNIT_TEST(testDataBarODS);
175 1 : CPPUNIT_TEST(testDataBarXLSX);
176 1 : CPPUNIT_TEST(testColorScaleODS);
177 1 : CPPUNIT_TEST(testColorScaleXLSX);
178 1 : CPPUNIT_TEST(testNewCondFormatODS);
179 1 : CPPUNIT_TEST(testNewCondFormatXLSX);
180 :
181 1 : CPPUNIT_TEST(testNumberFormatHTML);
182 1 : CPPUNIT_TEST(testNumberFormatCSV);
183 :
184 1 : CPPUNIT_TEST(testCellAnchoredShapesODS);
185 :
186 1 : CPPUNIT_TEST(testPivotTableBasicODS);
187 1 : CPPUNIT_TEST(testRowHeightODS);
188 1 : CPPUNIT_TEST(testFormulaDependency);
189 1 : CPPUNIT_TEST(testRichTextContentODS);
190 :
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 1 : CPPUNIT_TEST(testPasswordOld);
195 1 : CPPUNIT_TEST(testPasswordNew);
196 : #endif
197 :
198 : #if TEST_BUG_FILES
199 : CPPUNIT_TEST(testBugFiles);
200 : CPPUNIT_TEST(testBugFilesXLS);
201 : CPPUNIT_TEST(testBugFilesXLSX);
202 : #endif
203 1 : CPPUNIT_TEST(testMiscRowHeights);
204 1 : CPPUNIT_TEST(testOptimalHeightReset);
205 1 : CPPUNIT_TEST(testPrintRangeODS);
206 1 : CPPUNIT_TEST(testOutlineODS);
207 2 : CPPUNIT_TEST_SUITE_END();
208 :
209 : private:
210 : void testPassword_Impl(const OUString& rFileNameBase);
211 : void testBorderImpl( sal_uLong nFormatType );
212 : uno::Reference<uno::XInterface> m_xCalcComponent;
213 : };
214 :
215 0 : bool ScFiltersTest::load(const OUString &rFilter, const OUString &rURL,
216 : const OUString &rUserData, unsigned int nFilterFlags,
217 : unsigned int nClipboardID, unsigned int nFilterVersion)
218 : {
219 : ScDocShellRef xDocShRef = ScBootstrapFixture::load( rURL, rFilter, rUserData,
220 0 : OUString(), nFilterFlags, nClipboardID, nFilterVersion);
221 0 : bool bLoaded = xDocShRef.Is();
222 : //reference counting of ScDocShellRef is very confused.
223 0 : if (bLoaded)
224 0 : xDocShRef->DoClose();
225 0 : return bLoaded;
226 : }
227 :
228 :
229 : namespace {
230 :
231 2 : void testRangeNameImpl(ScDocument* pDoc)
232 : {
233 : //check one range data per sheet and one global more detailed
234 : //add some more checks here
235 2 : ScRangeData* pRangeData = pDoc->GetRangeName()->findByUpperName(OUString("GLOBAL1"));
236 2 : CPPUNIT_ASSERT_MESSAGE("range name Global1 not found", pRangeData);
237 : double aValue;
238 2 : pDoc->GetValue(1,0,0,aValue);
239 2 : CPPUNIT_ASSERT_EQUAL_MESSAGE("range name Global1 should reference Sheet1.A1", 1.0, aValue);
240 2 : pRangeData = pDoc->GetRangeName(0)->findByUpperName(OUString("LOCAL1"));
241 2 : CPPUNIT_ASSERT_MESSAGE("range name Sheet1.Local1 not found", pRangeData);
242 2 : pDoc->GetValue(1,2,0,aValue);
243 2 : CPPUNIT_ASSERT_EQUAL_MESSAGE("range name Sheet1.Local1 should reference Sheet1.A3", 3.0, aValue);
244 2 : pRangeData = pDoc->GetRangeName(1)->findByUpperName(OUString("LOCAL2"));
245 2 : CPPUNIT_ASSERT_MESSAGE("range name Sheet2.Local2 not found", pRangeData);
246 2 : pDoc->GetValue(1,1,1,aValue);
247 2 : CPPUNIT_ASSERT_EQUAL_MESSAGE("range name Sheet2.Local2 should reference Sheet2.A2", 7.0, aValue);
248 : //check for correct results for the remaining formulas
249 2 : pDoc->GetValue(1,1,0, aValue);
250 2 : CPPUNIT_ASSERT_EQUAL_MESSAGE("=global2 should be 2", 2.0, aValue);
251 2 : pDoc->GetValue(1,3,0, aValue);
252 2 : CPPUNIT_ASSERT_EQUAL_MESSAGE("=local2 should be 4", 4.0, aValue);
253 2 : pDoc->GetValue(2,0,0, aValue);
254 2 : CPPUNIT_ASSERT_EQUAL_MESSAGE("=SUM(global3) should be 10", 10.0, aValue);
255 2 : pDoc->GetValue(1,0,1,aValue);
256 2 : CPPUNIT_ASSERT_EQUAL_MESSAGE("range name Sheet2.local1 should reference Sheet1.A5", 5.0, aValue);
257 : // Test if Global5 ( which depends on Global6 ) is evaluated
258 2 : pDoc->GetValue(0,5,1, aValue);
259 2 : CPPUNIT_ASSERT_EQUAL_MESSAGE("formula Global5 should reference Global6 ( which is evaluated as local1 )", 5.0, aValue);
260 2 : }
261 :
262 : }
263 :
264 1 : void ScFiltersTest::testBasicCellContentODS()
265 : {
266 1 : ScDocShellRef xDocSh = loadDoc("basic-cell-content.", ODS);
267 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load basic-cell-content.ods", xDocSh.Is());
268 :
269 1 : ScDocument* pDoc = xDocSh->GetDocument();
270 2 : OUString aStr = pDoc->GetString(1, 1, 0); // B2
271 1 : CPPUNIT_ASSERT_EQUAL(OUString("LibreOffice Calc"), aStr);
272 1 : double fVal = pDoc->GetValue(1, 2, 0); // B3
273 1 : CPPUNIT_ASSERT_EQUAL(12345.0, fVal);
274 1 : aStr = pDoc->GetString(1, 3, 0); // B4
275 1 : CPPUNIT_ASSERT_EQUAL(OUString("A < B"), aStr);
276 :
277 2 : xDocSh->DoClose();
278 1 : }
279 :
280 1 : void ScFiltersTest::testRangeNameXLS()
281 : {
282 1 : ScDocShellRef xDocSh = loadDoc("named-ranges-global.", XLS);
283 1 : xDocSh->DoHardRecalc(true);
284 :
285 1 : ScDocument* pDoc = xDocSh->GetDocument();
286 1 : testRangeNameImpl(pDoc);
287 :
288 2 : OUString aSheet2CSV("rangeExp_Sheet2.");
289 2 : OUString aCSVPath;
290 1 : createCSVPath( aSheet2CSV, aCSVPath );
291 : // fdo#44587
292 1 : testFile( aCSVPath, pDoc, 1);
293 :
294 2 : xDocSh->DoClose();
295 1 : }
296 :
297 1 : void ScFiltersTest::testRangeNameXLSX()
298 : {
299 1 : ScDocShellRef xDocSh = loadDoc("named-ranges-global.", XLSX);
300 1 : xDocSh->DoHardRecalc(true);
301 :
302 1 : ScDocument* pDoc = xDocSh->GetDocument();
303 1 : testRangeNameImpl(pDoc);
304 :
305 1 : xDocSh->DoClose();
306 1 : }
307 :
308 1 : void ScFiltersTest::testHardRecalcODS()
309 : {
310 1 : ScDocShellRef xDocSh = loadDoc("hard-recalc.", ODS);
311 1 : xDocSh->DoHardRecalc(true);
312 :
313 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load hard-recalc.*", xDocSh.Is());
314 1 : ScDocument* pDoc = xDocSh->GetDocument();
315 2 : OUString aCSVFileName;
316 :
317 : //test hard recalc: document has an incorrect cached formula result
318 : //hard recalc should have updated to the correct result
319 1 : createCSVPath(OUString("hard-recalc."), aCSVFileName);
320 1 : testFile(aCSVFileName, pDoc, 0);
321 :
322 2 : xDocSh->DoClose();
323 1 : }
324 :
325 1 : void ScFiltersTest::testFunctionsODS()
326 : {
327 1 : ScDocShellRef xDocSh = loadDoc("functions.", ODS);
328 1 : xDocSh->DoHardRecalc(true);
329 :
330 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load functions.*", xDocSh.Is());
331 1 : ScDocument* pDoc = xDocSh->GetDocument();
332 2 : OUString aCSVFileName;
333 :
334 : //test logical functions
335 1 : createCSVPath(OUString("logical-functions."), aCSVFileName);
336 1 : testFile(aCSVFileName, pDoc, 0);
337 : //test spreadsheet functions
338 1 : createCSVPath(OUString("spreadsheet-functions."), aCSVFileName);
339 1 : testFile(aCSVFileName, pDoc, 1);
340 : //test mathematical functions
341 1 : createCSVPath(OUString("mathematical-functions."), aCSVFileName);
342 1 : testFile(aCSVFileName, pDoc, 2, PureString);
343 : //test information functions
344 1 : createCSVPath(OUString("information-functions."), aCSVFileName);
345 1 : testFile(aCSVFileName, pDoc, 3);
346 :
347 2 : xDocSh->DoClose();
348 1 : }
349 :
350 1 : void ScFiltersTest::testCachedFormulaResultsODS()
351 : {
352 : {
353 1 : ScDocShellRef xDocSh = loadDoc("functions.", ODS);
354 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load functions.*", xDocSh.Is());
355 :
356 1 : ScDocument* pDoc = xDocSh->GetDocument();
357 2 : OUString aCSVFileName;
358 :
359 : //test cached formula results of logical functions
360 1 : createCSVPath(OUString("logical-functions."), aCSVFileName);
361 1 : testFile(aCSVFileName, pDoc, 0);
362 : //test cached formula results of spreadsheet functions
363 1 : createCSVPath(OUString("spreadsheet-functions."), aCSVFileName);
364 1 : testFile(aCSVFileName, pDoc, 1);
365 : //test cached formula results of mathematical functions
366 1 : createCSVPath(OUString("mathematical-functions."), aCSVFileName);
367 1 : testFile(aCSVFileName, pDoc, 2, PureString);
368 : //test cached formula results of information functions
369 1 : createCSVPath(OUString("information-functions."), aCSVFileName);
370 1 : testFile(aCSVFileName, pDoc, 3);
371 :
372 2 : xDocSh->DoClose();
373 : }
374 :
375 : {
376 1 : ScDocShellRef xDocSh = loadDoc("cachedValue.", ODS);
377 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load cachedValue.*", xDocSh.Is());
378 :
379 1 : ScDocument* pDoc = xDocSh->GetDocument();
380 2 : OUString aCSVFileName;
381 1 : createCSVPath("cachedValue.", aCSVFileName);
382 1 : testFile(aCSVFileName, pDoc, 0);
383 :
384 : //we want to me sure that volatile functions are always recalculated
385 : //regardless of cached results. if you update the ods file, you must
386 : //update the values here.
387 : //if NOW() is recacluated, then it should never equal sTodayCache
388 2 : OUString sTodayCache("01/25/13 01:06 PM");
389 2 : OUString sTodayRecalc(pDoc->GetString(0,0,1));
390 :
391 1 : CPPUNIT_ASSERT(sTodayCache != sTodayRecalc);
392 :
393 2 : OUString sTodayRecalcRef(pDoc->GetString(1,0,1));
394 1 : CPPUNIT_ASSERT_EQUAL(sTodayRecalc, sTodayRecalcRef);
395 :
396 : // make sure that error values are not being treated as string values
397 5 : for(SCCOL nCol = 0; nCol < 4; ++nCol)
398 : {
399 12 : for(SCROW nRow = 0; nRow < 2; ++nRow)
400 : {
401 8 : OUStringBuffer aIsErrorFormula("=ISERROR(");
402 8 : aIsErrorFormula.append((char)('A'+nCol)).append(OUString::number(nRow));
403 8 : aIsErrorFormula.append(")");
404 16 : OUString aFormula = aIsErrorFormula.makeStringAndClear();
405 8 : pDoc->SetString(nCol, nRow + 2, 2, aFormula);
406 8 : CPPUNIT_ASSERT_EQUAL_MESSAGE(OUStringToOString(aFormula, RTL_TEXTENCODING_UTF8).getStr(), pDoc->GetString(nCol, nRow +2, 2), OUString("TRUE"));
407 :
408 16 : OUStringBuffer aIsTextFormula("=ISTEXT(");
409 8 : aIsTextFormula.append((char)('A'+nCol)).append(OUString::number(nRow));
410 8 : aIsTextFormula.append(")");
411 8 : pDoc->SetString(nCol, nRow + 4, 2, aIsTextFormula.makeStringAndClear());
412 8 : CPPUNIT_ASSERT_EQUAL_MESSAGE("", pDoc->GetString(nCol, nRow +4, 2), OUString("FALSE"));
413 8 : }
414 : }
415 :
416 2 : xDocSh->DoClose();
417 : }
418 1 : }
419 :
420 1 : void ScFiltersTest::testCachedMatrixFormulaResultsODS()
421 : {
422 1 : ScDocShellRef xDocSh = loadDoc("matrix.", ODS);
423 :
424 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load matrix.*", xDocSh.Is());
425 1 : ScDocument* pDoc = xDocSh->GetDocument();
426 :
427 : //test matrix
428 2 : OUString aCSVFileName;
429 1 : createCSVPath("matrix.", aCSVFileName);
430 1 : testFile(aCSVFileName, pDoc, 0);
431 : //test matrices with special cases
432 1 : createCSVPath("matrix2.", aCSVFileName);
433 1 : testFile(aCSVFileName, pDoc, 1);
434 1 : createCSVPath("matrix3.", aCSVFileName);
435 1 : testFile(aCSVFileName, pDoc, 2);
436 : //The above testFile() does not catch the below case.
437 : //If a matrix formula has a matrix reference cell that is intended to have
438 : //a blank text result, the matrix reference cell is actually saved(export)
439 : //as a float cell with 0 as the value and an empty <text:p/>.
440 : //Import works around this by setting these cells as text cells so that
441 : //the blank text is used for display instead of the number 0.
442 : //If this is working properly, the following cell should NOT have value data.
443 1 : CPPUNIT_ASSERT_EQUAL(pDoc->GetString(3,0,2), OUString());
444 :
445 : // fdo#59293 with cached value import error formulas require special
446 : // treatment
447 1 : pDoc->SetString(2, 5, 2, "=ISERROR(A6)");
448 1 : double nVal = pDoc->GetValue(2,5,2);
449 1 : CPPUNIT_ASSERT_EQUAL(1.0, nVal);
450 :
451 2 : xDocSh->DoClose();
452 1 : }
453 :
454 : namespace {
455 :
456 3 : void testDBRanges_Impl(ScDocument* pDoc, sal_Int32 nFormat)
457 : {
458 3 : ScDBCollection* pDBCollection = pDoc->GetDBCollection();
459 3 : CPPUNIT_ASSERT_MESSAGE("no database collection", pDBCollection);
460 :
461 3 : ScDBData* pAnonDBData = pDoc->GetAnonymousDBData(0);
462 3 : CPPUNIT_ASSERT_MESSAGE("missing anonymous DB data in sheet 1", pAnonDBData);
463 : //control hidden rows
464 : bool bHidden;
465 : SCROW nRow1, nRow2;
466 3 : bHidden = pDoc->RowHidden(0, 0, &nRow1, &nRow2);
467 3 : CPPUNIT_ASSERT_MESSAGE("Sheet1: row 0 should be visible", !bHidden && nRow1 == 0 && nRow2 == 0);
468 3 : bHidden = pDoc->RowHidden(1, 0, &nRow1, &nRow2);
469 3 : CPPUNIT_ASSERT_MESSAGE("Sheet1: rows 1-2 should be hidden", bHidden && nRow1 == 1 && nRow2 == 2);
470 3 : bHidden = pDoc->RowHidden(3, 0, &nRow1, &nRow2);
471 3 : CPPUNIT_ASSERT_MESSAGE("Sheet1: row 3 should be visible", !bHidden && nRow1 == 3 && nRow2 == 3);
472 3 : bHidden = pDoc->RowHidden(4, 0, &nRow1, &nRow2);
473 3 : CPPUNIT_ASSERT_MESSAGE("Sheet1: row 4-5 should be hidden", bHidden && nRow1 == 4 && nRow2 == 5);
474 3 : bHidden = pDoc->RowHidden(6, 0, &nRow1, &nRow2);
475 3 : CPPUNIT_ASSERT_MESSAGE("Sheet1: row 6-end should be visible", !bHidden && nRow1 == 6 && nRow2 == MAXROW);
476 3 : if(nFormat == ODS) //excel doesn't support named db ranges
477 : {
478 : double aValue;
479 1 : pDoc->GetValue(0,10,1, aValue);
480 1 : CPPUNIT_ASSERT_EQUAL_MESSAGE("Sheet2: A11: formula result is incorrect", 4.0, aValue);
481 1 : pDoc->GetValue(1, 10, 1, aValue);
482 1 : CPPUNIT_ASSERT_EQUAL_MESSAGE("Sheet2: B11: formula result is incorrect", 2.0, aValue);
483 : }
484 : double aValue;
485 3 : pDoc->GetValue(3,10,1, aValue);
486 3 : CPPUNIT_ASSERT_EQUAL_MESSAGE("Sheet2: D11: formula result is incorrect", 4.0, aValue);
487 3 : pDoc->GetValue(4, 10, 1, aValue);
488 3 : CPPUNIT_ASSERT_EQUAL_MESSAGE("Sheet2: E11: formula result is incorrect", 2.0, aValue);
489 :
490 3 : }
491 :
492 : }
493 :
494 1 : void ScFiltersTest::testDatabaseRangesODS()
495 : {
496 1 : ScDocShellRef xDocSh = loadDoc("database.", ODS);
497 1 : xDocSh->DoHardRecalc(true);
498 :
499 1 : ScDocument* pDoc = xDocSh->GetDocument();
500 :
501 1 : testDBRanges_Impl(pDoc, ODS);
502 1 : xDocSh->DoClose();
503 1 : }
504 :
505 1 : void ScFiltersTest::testDatabaseRangesXLS()
506 : {
507 1 : ScDocShellRef xDocSh = loadDoc("database.", XLS);
508 1 : xDocSh->DoHardRecalc(true);
509 :
510 1 : ScDocument* pDoc = xDocSh->GetDocument();
511 :
512 1 : testDBRanges_Impl(pDoc, XLS);
513 1 : xDocSh->DoClose();
514 1 : }
515 :
516 1 : void ScFiltersTest::testDatabaseRangesXLSX()
517 : {
518 1 : ScDocShellRef xDocSh = loadDoc("database.", XLSX);
519 1 : xDocSh->DoHardRecalc(true);
520 :
521 1 : ScDocument* pDoc = xDocSh->GetDocument();
522 :
523 1 : testDBRanges_Impl(pDoc, XLSX);
524 1 : xDocSh->DoClose();
525 1 : }
526 :
527 : namespace {
528 :
529 1 : void testFormats_Impl(ScFiltersTest* pFiltersTest, ScDocument* pDoc, sal_Int32 nFormat)
530 : {
531 : //test Sheet1 with csv file
532 1 : OUString aCSVFileName;
533 1 : pFiltersTest->createCSVPath(OUString("numberFormat."), aCSVFileName);
534 1 : testFile(aCSVFileName, pDoc, 0, PureString);
535 : //need to test the color of B3
536 : //it's not a font color!
537 : //formatting for B5: # ??/100 gets lost during import
538 :
539 : //test Sheet2
540 1 : const ScPatternAttr* pPattern = NULL;
541 1 : pPattern = pDoc->GetPattern(0,0,1);
542 2 : Font aFont;
543 1 : pPattern->GetFont(aFont,SC_AUTOCOL_RAW);
544 1 : CPPUNIT_ASSERT_EQUAL_MESSAGE("font size should be 10", 200l, aFont.GetSize().getHeight());
545 1 : CPPUNIT_ASSERT_EQUAL_MESSAGE("font color should be black", COL_AUTO, aFont.GetColor().GetColor());
546 1 : pPattern = pDoc->GetPattern(0,1,1);
547 1 : pPattern->GetFont(aFont, SC_AUTOCOL_RAW);
548 1 : CPPUNIT_ASSERT_EQUAL_MESSAGE("font size should be 12", 240l, aFont.GetSize().getHeight());
549 1 : pPattern = pDoc->GetPattern(0,2,1);
550 1 : pPattern->GetFont(aFont, SC_AUTOCOL_RAW);
551 1 : CPPUNIT_ASSERT_EQUAL_MESSAGE("font should be italic", ITALIC_NORMAL, aFont.GetItalic());
552 1 : pPattern = pDoc->GetPattern(0,4,1);
553 1 : pPattern->GetFont(aFont, SC_AUTOCOL_RAW);
554 1 : CPPUNIT_ASSERT_EQUAL_MESSAGE("font should be bold", WEIGHT_BOLD, aFont.GetWeight());
555 1 : pPattern = pDoc->GetPattern(1,0,1);
556 1 : pPattern->GetFont(aFont, SC_AUTOCOL_RAW);
557 1 : CPPUNIT_ASSERT_EQUAL_MESSAGE("font should be blue", COL_BLUE, aFont.GetColor().GetColor());
558 1 : pPattern = pDoc->GetPattern(1,1,1);
559 1 : pPattern->GetFont(aFont, SC_AUTOCOL_RAW);
560 1 : CPPUNIT_ASSERT_EQUAL_MESSAGE("font should be striked out with a single line", STRIKEOUT_SINGLE, aFont.GetStrikeout());
561 : //some tests on sheet2 only for ods
562 1 : if (nFormat == ODS)
563 : {
564 1 : pPattern = pDoc->GetPattern(1,2,1);
565 1 : pPattern->GetFont(aFont, SC_AUTOCOL_RAW);
566 1 : CPPUNIT_ASSERT_EQUAL_MESSAGE("font should be striked out with a double line", STRIKEOUT_DOUBLE, aFont.GetStrikeout());
567 1 : pPattern = pDoc->GetPattern(1,3,1);
568 1 : pPattern->GetFont(aFont, SC_AUTOCOL_RAW);
569 1 : CPPUNIT_ASSERT_EQUAL_MESSAGE("font should be underlined with a dotted line", UNDERLINE_DOTTED, aFont.GetUnderline());
570 : //check row height import
571 : //disable for now until we figure out cause of win tinderboxes test failures
572 : //CPPUNIT_ASSERT_EQUAL( static_cast<sal_uInt16>(256), pDoc->GetRowHeight(0,1) ); //0.178in
573 : //CPPUNIT_ASSERT_EQUAL( static_cast<sal_uInt16>(304), pDoc->GetRowHeight(1,1) ); //0.211in
574 : //CPPUNIT_ASSERT_EQUAL( static_cast<sal_uInt16>(477), pDoc->GetRowHeight(5,1) ); //0.3311in
575 : //check column width import
576 1 : CPPUNIT_ASSERT_EQUAL( static_cast<sal_uInt16>(555), pDoc->GetColWidth(4,1) ); //0.3854in
577 1 : CPPUNIT_ASSERT_EQUAL( static_cast<sal_uInt16>(1280), pDoc->GetColWidth(5,1) ); //0.889in
578 1 : CPPUNIT_ASSERT_EQUAL( static_cast<sal_uInt16>(4153), pDoc->GetColWidth(6,1) ); //2.8839in
579 : //test case for i53253 where a cell has text with different styles and space between the text.
580 1 : OUString aTestStr = pDoc->GetString(3,0,1);
581 2 : OUString aKnownGoodStr("text14 space");
582 1 : CPPUNIT_ASSERT_EQUAL( aKnownGoodStr, aTestStr );
583 : //test case for cell text with line breaks.
584 1 : aTestStr = pDoc->GetString(3,5,1);
585 1 : aKnownGoodStr = "Hello,\nCalc!";
586 2 : CPPUNIT_ASSERT_EQUAL( aKnownGoodStr, aTestStr );
587 : }
588 1 : pPattern = pDoc->GetPattern(1,4,1);
589 1 : Color aColor = static_cast<const SvxBrushItem&>(pPattern->GetItem(ATTR_BACKGROUND)).GetColor();
590 1 : CPPUNIT_ASSERT_MESSAGE("background color should be green", aColor == COL_LIGHTGREEN);
591 1 : pPattern = pDoc->GetPattern(2,0,1);
592 1 : SvxCellHorJustify eHorJustify = static_cast<SvxCellHorJustify>(static_cast<const SvxHorJustifyItem&>(pPattern->GetItem(ATTR_HOR_JUSTIFY)).GetValue());
593 1 : CPPUNIT_ASSERT_EQUAL_MESSAGE("cell content should be aligned centre horizontally", SVX_HOR_JUSTIFY_CENTER, eHorJustify);
594 : //test alignment
595 1 : pPattern = pDoc->GetPattern(2,1,1);
596 1 : eHorJustify = static_cast<SvxCellHorJustify>(static_cast<const SvxHorJustifyItem&>(pPattern->GetItem(ATTR_HOR_JUSTIFY)).GetValue());
597 1 : CPPUNIT_ASSERT_EQUAL_MESSAGE("cell content should be aligned right horizontally", SVX_HOR_JUSTIFY_RIGHT, eHorJustify);
598 1 : pPattern = pDoc->GetPattern(2,2,1);
599 1 : eHorJustify = static_cast<SvxCellHorJustify>(static_cast<const SvxHorJustifyItem&>(pPattern->GetItem(ATTR_HOR_JUSTIFY)).GetValue());
600 1 : CPPUNIT_ASSERT_EQUAL_MESSAGE("cell content should be aligned block horizontally", SVX_HOR_JUSTIFY_BLOCK, eHorJustify);
601 :
602 : //test Sheet3 only for ods
603 1 : if ( nFormat == ODS || nFormat == XLSX )
604 : {
605 1 : pFiltersTest->createCSVPath(OUString("conditionalFormatting."), aCSVFileName);
606 1 : testCondFile(aCSVFileName, pDoc, 2);
607 : // test parent cell style import ( fdo#55198 )
608 1 : if ( nFormat == XLSX )
609 : {
610 0 : pPattern = pDoc->GetPattern(1,1,3);
611 0 : ScStyleSheet* pStyleSheet = (ScStyleSheet*)pPattern->GetStyleSheet();
612 : // check parent style name
613 0 : OUString sExpected("Excel Built-in Date");
614 0 : OUString sResult = pStyleSheet->GetName();
615 0 : CPPUNIT_ASSERT_EQUAL_MESSAGE("parent style for Sheet4.B2 is 'Excel Built-in Date'", sExpected, sResult);
616 : // check align of style
617 0 : SfxItemSet& rItemSet = pStyleSheet->GetItemSet();
618 0 : eHorJustify = static_cast<SvxCellHorJustify>(static_cast< const SvxHorJustifyItem& >(rItemSet.Get( ATTR_HOR_JUSTIFY ) ).GetValue() );
619 0 : CPPUNIT_ASSERT_EQUAL_MESSAGE("'Excel Built-in Date' style should be aligned centre horizontally", SVX_HOR_JUSTIFY_CENTER, eHorJustify);
620 : // check date format ( should be just month e.g. 29 )
621 0 : sResult =pDoc->GetString( 1,1,3 );
622 0 : sExpected = OUString("29");
623 0 : CPPUNIT_ASSERT_EQUAL_MESSAGE("'Excel Built-in Date' style should just display month", sExpected, sResult );
624 :
625 : // check actual align applied to cell, should be the same as
626 : // the style
627 0 : eHorJustify = static_cast<SvxCellHorJustify>(static_cast< const SvxHorJustifyItem& >(pPattern->GetItem( ATTR_HOR_JUSTIFY ) ).GetValue() );
628 0 : CPPUNIT_ASSERT_EQUAL_MESSAGE("cell with 'Excel Built-in Date' style should be aligned centre horizontally", SVX_HOR_JUSTIFY_CENTER, eHorJustify);
629 : }
630 : }
631 :
632 1 : ScConditionalFormat* pCondFormat = pDoc->GetCondFormat(0,0,2);
633 1 : const ScRangeList& rRange = pCondFormat->GetRange();
634 1 : CPPUNIT_ASSERT(rRange == ScRange(0,0,2,3,0,2));
635 :
636 1 : pCondFormat = pDoc->GetCondFormat(0,1,2);
637 1 : const ScRangeList& rRange2 = pCondFormat->GetRange();
638 1 : CPPUNIT_ASSERT(rRange2 == ScRange(0,1,2,0,1,2));
639 :
640 1 : pCondFormat = pDoc->GetCondFormat(1,1,2);
641 1 : const ScRangeList& rRange3 = pCondFormat->GetRange();
642 2 : CPPUNIT_ASSERT(rRange3 == ScRange(1,1,2,3,1,2));
643 1 : }
644 :
645 : }
646 :
647 1 : void ScFiltersTest::testFormatsODS()
648 : {
649 1 : ScDocShellRef xDocSh = loadDoc("formats.", ODS);
650 1 : xDocSh->DoHardRecalc(true);
651 :
652 1 : ScDocument* pDoc = xDocSh->GetDocument();
653 :
654 1 : testFormats_Impl(this, pDoc, ODS);
655 1 : xDocSh->DoClose();
656 1 : }
657 :
658 0 : void ScFiltersTest::testFormatsXLS()
659 : {
660 0 : ScDocShellRef xDocSh = loadDoc("formats.", XLS);
661 0 : xDocSh->DoHardRecalc(true);
662 :
663 0 : ScDocument* pDoc = xDocSh->GetDocument();
664 :
665 0 : testFormats_Impl(this, pDoc, XLS);
666 0 : xDocSh->DoClose();
667 0 : }
668 :
669 0 : void ScFiltersTest::testFormatsXLSX()
670 : {
671 0 : ScDocShellRef xDocSh = loadDoc("formats.", XLSX);
672 0 : xDocSh->DoHardRecalc(true);
673 :
674 0 : ScDocument* pDoc = xDocSh->GetDocument();
675 :
676 0 : testFormats_Impl(this, pDoc, XLSX);
677 0 : xDocSh->DoClose();
678 0 : }
679 :
680 1 : void ScFiltersTest::testMatrixODS()
681 : {
682 1 : ScDocShellRef xDocSh = loadDoc("matrix.", ODS);
683 1 : xDocSh->DoHardRecalc(true);
684 :
685 1 : ScDocument* pDoc = xDocSh->GetDocument();
686 :
687 2 : OUString aCSVFileName;
688 1 : createCSVPath(OUString("matrix."), aCSVFileName);
689 1 : testFile(aCSVFileName, pDoc, 0);
690 :
691 2 : xDocSh->DoClose();
692 1 : }
693 :
694 1 : void ScFiltersTest::testMatrixXLS()
695 : {
696 1 : ScDocShellRef xDocSh = loadDoc("matrix.", XLS);
697 1 : xDocSh->DoHardRecalc(true);
698 :
699 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load matrix.*", xDocSh.Is());
700 1 : ScDocument* pDoc = xDocSh->GetDocument();
701 :
702 2 : OUString aCSVFileName;
703 1 : createCSVPath(OUString("matrix."), aCSVFileName);
704 1 : testFile(aCSVFileName, pDoc, 0);
705 :
706 2 : xDocSh->DoClose();
707 1 : }
708 :
709 1 : void ScFiltersTest::testBorderODS()
710 : {
711 1 : ScDocShellRef xDocSh = loadDoc("border.", ODS);
712 :
713 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load border.*", xDocSh.Is());
714 1 : ScDocument* pDoc = xDocSh->GetDocument();
715 :
716 1 : const editeng::SvxBorderLine* pLeft = NULL;
717 1 : const editeng::SvxBorderLine* pTop = NULL;
718 1 : const editeng::SvxBorderLine* pRight = NULL;
719 1 : const editeng::SvxBorderLine* pBottom = NULL;
720 :
721 1 : pDoc->GetBorderLines( 0, 1, 0, &pLeft, &pTop, &pRight, &pBottom );
722 1 : CPPUNIT_ASSERT(!pLeft);
723 1 : CPPUNIT_ASSERT(!pTop);
724 1 : CPPUNIT_ASSERT(!pBottom);
725 1 : CPPUNIT_ASSERT(pRight);
726 2 : CPPUNIT_ASSERT_EQUAL(pRight->GetBorderLineStyle(),
727 1 : table::BorderLineStyle::SOLID);
728 :
729 1 : pDoc->GetBorderLines( 2, 1, 0, &pLeft, &pTop, &pRight, &pBottom );
730 1 : CPPUNIT_ASSERT(!pLeft);
731 1 : CPPUNIT_ASSERT(!pTop);
732 1 : CPPUNIT_ASSERT(!pBottom);
733 :
734 1 : CPPUNIT_ASSERT(pRight);
735 2 : CPPUNIT_ASSERT_EQUAL(pRight->GetBorderLineStyle(),
736 1 : table::BorderLineStyle::SOLID);
737 1 : CPPUNIT_ASSERT_EQUAL(pRight->GetWidth(),20L);
738 :
739 1 : pDoc->GetBorderLines( 2, 8, 0, &pLeft, &pTop, &pRight, &pBottom );
740 :
741 1 : CPPUNIT_ASSERT(pLeft);
742 1 : CPPUNIT_ASSERT(pTop);
743 1 : CPPUNIT_ASSERT(pBottom);
744 1 : CPPUNIT_ASSERT(pRight);
745 2 : CPPUNIT_ASSERT_EQUAL(pRight->GetBorderLineStyle(),
746 1 : table::BorderLineStyle::SOLID);
747 1 : CPPUNIT_ASSERT_EQUAL(pRight->GetWidth(),5L);
748 1 : CPPUNIT_ASSERT(pRight->GetColor() == Color(COL_BLUE));
749 :
750 1 : xDocSh->DoClose();
751 1 : }
752 :
753 2 : void ScFiltersTest::testBorderImpl( sal_uLong nFormatType )
754 : {
755 2 : ScDocShellRef xDocSh = loadDoc("border.", nFormatType );
756 :
757 2 : CPPUNIT_ASSERT_MESSAGE("Failed to load border.xls", xDocSh.Is());
758 2 : ScDocument* pDoc = xDocSh->GetDocument();
759 :
760 2 : const editeng::SvxBorderLine* pLeft = NULL;
761 2 : const editeng::SvxBorderLine* pTop = NULL;
762 2 : const editeng::SvxBorderLine* pRight = NULL;
763 2 : const editeng::SvxBorderLine* pBottom = NULL;
764 :
765 2 : pDoc->GetBorderLines( 2, 3, 0, &pLeft, &pTop, &pRight, &pBottom );
766 2 : CPPUNIT_ASSERT(pRight);
767 4 : CPPUNIT_ASSERT_EQUAL(pRight->GetBorderLineStyle(),
768 2 : table::BorderLineStyle::SOLID);
769 2 : CPPUNIT_ASSERT_EQUAL(pRight->GetWidth(),1L);
770 :
771 2 : pDoc->GetBorderLines( 3, 5, 0, &pLeft, &pTop, &pRight, &pBottom );
772 2 : CPPUNIT_ASSERT(pRight);
773 4 : CPPUNIT_ASSERT_EQUAL(pRight->GetBorderLineStyle(),
774 2 : table::BorderLineStyle::SOLID);
775 2 : CPPUNIT_ASSERT_EQUAL(pRight->GetWidth(),20L);
776 :
777 2 : pDoc->GetBorderLines( 5, 7, 0, &pLeft, &pTop, &pRight, &pBottom );
778 2 : CPPUNIT_ASSERT(pRight);
779 4 : CPPUNIT_ASSERT_EQUAL(pRight->GetBorderLineStyle(),
780 2 : table::BorderLineStyle::SOLID);
781 2 : CPPUNIT_ASSERT_EQUAL(pRight->GetWidth(),30L);
782 :
783 2 : pDoc->GetBorderLines( 7, 9, 0, &pLeft, &pTop, &pRight, &pBottom );
784 2 : CPPUNIT_ASSERT(pRight);
785 4 : CPPUNIT_ASSERT_EQUAL(pRight->GetBorderLineStyle(),
786 2 : table::BorderLineStyle::FINE_DASHED);
787 2 : CPPUNIT_ASSERT_EQUAL(pRight->GetWidth(),1L);
788 2 : }
789 :
790 1 : void ScFiltersTest::testBorderXLS()
791 : {
792 1 : testBorderImpl( XLS );
793 1 : }
794 :
795 1 : void ScFiltersTest::testBorderXLSX()
796 : {
797 1 : testBorderImpl( XLSX );
798 1 : }
799 :
800 : struct Border
801 : {
802 : sal_Int16 column;
803 : sal_Int32 row;
804 : long leftWidth;
805 : long topWidth;
806 : long rightWidth;
807 : long bottomWidth;
808 : sal_uInt16 lOutWidth;
809 : sal_uInt16 lInWidth;
810 : sal_uInt16 lDistance;
811 : sal_uInt16 tOutWidth;
812 : sal_uInt16 tInWidth;
813 : sal_uInt16 tDistance;
814 : sal_uInt16 rOutWidth;
815 : sal_uInt16 rInWidth;
816 : sal_uInt16 rDistance;
817 : sal_uInt16 bOutWidth;
818 : sal_uInt16 bInWidth;
819 : sal_uInt16 bDistance;
820 : sal_Int32 lStyle;
821 : sal_Int32 tStyle;
822 : sal_Int32 rStyle;
823 : sal_Int32 bStyle;
824 : // that's a monstrum
825 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,
826 : sal_uInt16 lDist, sal_uInt16 tOutW, sal_uInt16 tInW, sal_uInt16 tDist, sal_uInt16 rOutW, sal_uInt16 rInW, sal_uInt16 rDist,
827 : sal_uInt16 bOutW, sal_uInt16 bInW, sal_uInt16 bDist, sal_Int32 lSt, sal_Int32 tSt, sal_Int32 rSt, sal_Int32 bSt):
828 : column(col), row(r), leftWidth(lW), topWidth(tW), rightWidth(rW), bottomWidth(bW), lOutWidth(lOutW), lInWidth(lInW), lDistance(lDist),
829 : tOutWidth(tOutW), tInWidth(tInW), tDistance(tDist), rOutWidth(rOutW), rInWidth(rInW), rDistance(rDist), bOutWidth(bOutW), bInWidth(bInW),
830 17 : bDistance(bDist), lStyle(lSt), tStyle(tSt), rStyle(rSt), bStyle(bSt) {};
831 : };
832 :
833 1 : void ScFiltersTest::testBordersOoo33()
834 : {
835 1 : std::vector<Border> borders;
836 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));
837 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));
838 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));
839 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));
840 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));
841 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));
842 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));
843 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));
844 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));
845 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));
846 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));
847 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));
848 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));
849 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));
850 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));
851 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));
852 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));
853 :
854 2 : ScDocShellRef xDocSh = loadDoc("borders_ooo33.", ODS);
855 :
856 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load borders_ooo33.*", xDocSh.Is());
857 1 : ScDocument* pDoc = xDocSh->GetDocument();
858 :
859 1 : const editeng::SvxBorderLine* pLeft = NULL;
860 1 : const editeng::SvxBorderLine* pTop = NULL;
861 1 : const editeng::SvxBorderLine* pRight = NULL;
862 1 : const editeng::SvxBorderLine* pBottom = NULL;
863 1 : sal_Int16 temp = 0;
864 7 : for(sal_Int16 i = 0; i<6; ++i)
865 : {
866 138 : for(sal_Int32 j = 0; j<22; ++j)
867 : {
868 132 : pDoc->GetBorderLines( i, j, 0, &pLeft, &pTop, &pRight, &pBottom );
869 132 : if(pLeft!=NULL && pTop!=NULL && pRight!=NULL && pBottom!=NULL)
870 : {
871 17 : CPPUNIT_ASSERT_EQUAL(borders[temp].column, i);
872 17 : CPPUNIT_ASSERT_EQUAL(borders[temp].row, j);
873 17 : CPPUNIT_ASSERT_EQUAL(borders[temp].leftWidth, pLeft->GetWidth());
874 17 : CPPUNIT_ASSERT_EQUAL(borders[temp].topWidth, pTop->GetWidth());
875 17 : CPPUNIT_ASSERT_EQUAL(borders[temp].rightWidth, pRight->GetWidth());
876 17 : CPPUNIT_ASSERT_EQUAL(borders[temp].bottomWidth, pBottom->GetWidth());
877 17 : CPPUNIT_ASSERT_EQUAL(borders[temp].lOutWidth, pLeft->GetOutWidth());
878 17 : CPPUNIT_ASSERT_EQUAL(borders[temp].lInWidth, pLeft->GetInWidth());
879 17 : CPPUNIT_ASSERT_EQUAL(borders[temp].lDistance, pLeft->GetDistance());
880 17 : CPPUNIT_ASSERT_EQUAL(borders[temp].tOutWidth, pTop->GetOutWidth());
881 17 : CPPUNIT_ASSERT_EQUAL(borders[temp].tInWidth, pTop->GetInWidth());
882 17 : CPPUNIT_ASSERT_EQUAL(borders[temp].tDistance, pTop->GetDistance());
883 17 : CPPUNIT_ASSERT_EQUAL(borders[temp].rOutWidth, pRight->GetOutWidth());
884 17 : CPPUNIT_ASSERT_EQUAL(borders[temp].rInWidth, pRight->GetInWidth());
885 17 : CPPUNIT_ASSERT_EQUAL(borders[temp].rDistance, pRight->GetDistance());
886 17 : CPPUNIT_ASSERT_EQUAL(borders[temp].bOutWidth, pBottom->GetOutWidth());
887 17 : CPPUNIT_ASSERT_EQUAL(borders[temp].bInWidth, pBottom->GetInWidth());
888 17 : CPPUNIT_ASSERT_EQUAL(borders[temp].bDistance, pBottom->GetDistance());
889 17 : sal_Int32 tempStyle = pLeft->GetBorderLineStyle();
890 17 : CPPUNIT_ASSERT_EQUAL(borders[temp].lStyle, tempStyle);
891 17 : tempStyle = pTop->GetBorderLineStyle();
892 17 : CPPUNIT_ASSERT_EQUAL(borders[temp].tStyle, tempStyle);
893 17 : tempStyle = pRight->GetBorderLineStyle();
894 17 : CPPUNIT_ASSERT_EQUAL(borders[temp].rStyle, tempStyle);
895 17 : tempStyle = pBottom->GetBorderLineStyle();
896 17 : CPPUNIT_ASSERT_EQUAL(borders[temp].bStyle, tempStyle);
897 17 : ++temp;
898 : }
899 : }
900 : }
901 :
902 2 : xDocSh->DoClose();
903 1 : }
904 :
905 1 : void ScFiltersTest::testBugFixesODS()
906 : {
907 1 : ScDocShellRef xDocSh = loadDoc("bug-fixes.", ODS);
908 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load bugFixes.ods", xDocSh.Is());
909 :
910 1 : xDocSh->DoHardRecalc(true);
911 1 : ScDocument* pDoc = xDocSh->GetDocument();
912 :
913 : {
914 : // fdo#40967
915 1 : OUString aCSVFileName;
916 1 : createCSVPath(OUString("bugFix_Sheet2."), aCSVFileName);
917 1 : testFile(aCSVFileName, pDoc, 1);
918 : }
919 :
920 : {
921 : // fdo#40426
922 1 : ScDBData* pDBData = pDoc->GetDBCollection()->getNamedDBs().findByUpperName("DBRANGE1");
923 1 : CPPUNIT_ASSERT(pDBData);
924 1 : CPPUNIT_ASSERT(pDBData->HasHeader());
925 : // no header
926 1 : pDBData = pDoc->GetDBCollection()->getNamedDBs().findByUpperName("DBRANGE2");
927 1 : CPPUNIT_ASSERT(pDBData);
928 1 : CPPUNIT_ASSERT(!pDBData->HasHeader());
929 : }
930 :
931 : {
932 : // fdo#59240
933 1 : OUString aCSVFileName;
934 1 : createCSVPath("bugFix_Sheet4.", aCSVFileName);
935 1 : testFile(aCSVFileName, pDoc, 3);
936 : }
937 :
938 1 : xDocSh->DoClose();
939 1 : }
940 :
941 1 : void ScFiltersTest::testBugFixesXLS()
942 : {
943 1 : ScDocShellRef xDocSh = loadDoc("bug-fixes.", XLS);
944 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load bugFixes.xls", xDocSh.Is());
945 :
946 1 : xDocSh->DoHardRecalc(true);
947 1 : ScDocument* pDoc = xDocSh->GetDocument();
948 1 : CPPUNIT_ASSERT_MESSAGE("No Document", pDoc); //remove with first test
949 1 : xDocSh->DoClose();
950 1 : }
951 :
952 1 : void ScFiltersTest::testBugFixesXLSX()
953 : {
954 1 : ScDocShellRef xDocSh = loadDoc("bug-fixes.", XLSX);
955 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load bugFixes.xls", xDocSh.Is());
956 :
957 1 : xDocSh->DoHardRecalc(true);
958 1 : ScDocument* pDoc = xDocSh->GetDocument();
959 1 : CPPUNIT_ASSERT_MESSAGE("No Document", pDoc); //remove with first test
960 1 : xDocSh->DoClose();
961 1 : }
962 :
963 : namespace {
964 :
965 4 : void checkMergedCells( ScDocument* pDoc, const ScAddress& rStartAddress,
966 : const ScAddress& rExpectedEndAddress )
967 : {
968 4 : SCCOL nActualEndCol = rStartAddress.Col();
969 4 : SCROW nActualEndRow = rStartAddress.Row();
970 4 : pDoc->ExtendMerge( rStartAddress.Col(), rStartAddress.Row(),
971 8 : nActualEndCol, nActualEndRow, rStartAddress.Tab(), false );
972 4 : OString sTab = OString::valueOf( static_cast<sal_Int32>(rStartAddress.Tab() + 1) );
973 8 : OString msg = "Merged cells are not correctly imported on sheet" + sTab;
974 8 : OString msgCol = msg + "; end col";
975 8 : OString msgRow = msg + "; end row";
976 4 : CPPUNIT_ASSERT_EQUAL_MESSAGE( msgCol.pData->buffer, rExpectedEndAddress.Col(), nActualEndCol );
977 8 : CPPUNIT_ASSERT_EQUAL_MESSAGE( msgRow.pData->buffer, rExpectedEndAddress.Row(), nActualEndRow );
978 4 : }
979 :
980 : }
981 :
982 1 : void ScFiltersTest::testMergedCellsODS()
983 : {
984 1 : ScDocShellRef xDocSh = loadDoc("merged.", ODS);
985 1 : ScDocument* pDoc = xDocSh->GetDocument();
986 :
987 : //check sheet1 content
988 2 : OUString aCSVFileName1;
989 1 : createCSVPath(OUString("merged1."), aCSVFileName1);
990 1 : testFile(aCSVFileName1, pDoc, 0);
991 :
992 : //check sheet1 merged cells
993 1 : checkMergedCells( pDoc, ScAddress( 0, 0, 0 ), ScAddress( 5, 11, 0 ) );
994 1 : checkMergedCells( pDoc, ScAddress( 7, 2, 0 ), ScAddress( 9, 12, 0 ) );
995 1 : checkMergedCells( pDoc, ScAddress( 3, 15, 0 ), ScAddress( 7, 23, 0 ) );
996 :
997 : //check sheet2 content
998 2 : OUString aCSVFileName2;
999 1 : createCSVPath(OUString("merged2."), aCSVFileName2);
1000 1 : testFile(aCSVFileName2, pDoc, 1);
1001 :
1002 : //check sheet2 merged cells
1003 1 : checkMergedCells( pDoc, ScAddress( 4, 3, 1 ), ScAddress( 6, 15, 1 ) );
1004 :
1005 2 : xDocSh->DoClose();
1006 1 : }
1007 :
1008 1 : void ScFiltersTest::testRepeatedColumnsODS()
1009 : {
1010 1 : ScDocShellRef xDocSh = loadDoc("repeatedColumns.", ODS);
1011 1 : ScDocument* pDoc = xDocSh->GetDocument();
1012 :
1013 : //text
1014 2 : OUString aCSVFileName1;
1015 1 : createCSVPath(OUString("repeatedColumns1."), aCSVFileName1);
1016 1 : testFile(aCSVFileName1, pDoc, 0);
1017 :
1018 : //numbers
1019 2 : OUString aCSVFileName2;
1020 1 : createCSVPath(OUString("repeatedColumns2."), aCSVFileName2);
1021 1 : testFile(aCSVFileName2, pDoc, 1);
1022 :
1023 2 : xDocSh->DoClose();
1024 1 : }
1025 :
1026 : namespace {
1027 :
1028 : //for cleaner passing of parameters
1029 2 : struct ValDataTestParams
1030 : {
1031 : ScValidationMode eValMode;
1032 : ScConditionMode eCondOp;
1033 : String aStrVal1, aStrVal2;
1034 : ScDocument* pDocument;
1035 : ScAddress aPosition;
1036 : String aErrorTitle, aErrorMessage;
1037 : ScValidErrorStyle eErrorStyle;
1038 : sal_uLong nExpectedIndex;
1039 :
1040 2 : ValDataTestParams( ScValidationMode eMode, ScConditionMode eOp,
1041 : String aExpr1, String aExpr2, ScDocument* pDoc,
1042 : ScAddress aPos, String aETitle, String aEMsg,
1043 : ScValidErrorStyle eEStyle, sal_uLong nIndex ):
1044 : eValMode(eMode), eCondOp(eOp), aStrVal1(aExpr1),
1045 : aStrVal2(aExpr2), pDocument(pDoc), aPosition(aPos),
1046 : aErrorTitle(aETitle), aErrorMessage(aEMsg),
1047 2 : eErrorStyle(eEStyle), nExpectedIndex(nIndex) { };
1048 : };
1049 :
1050 2 : void checkValiditationEntries( const ValDataTestParams& rVDTParams )
1051 : {
1052 2 : ScDocument* pDoc = rVDTParams.pDocument;
1053 :
1054 : //create expected data validation entry
1055 : ScValidationData aValData(
1056 : rVDTParams.eValMode, rVDTParams.eCondOp, rVDTParams.aStrVal1,
1057 2 : rVDTParams.aStrVal2, pDoc, rVDTParams.aPosition, EMPTY_STRING,
1058 2 : EMPTY_STRING, pDoc->GetStorageGrammar(), pDoc->GetStorageGrammar()
1059 4 : );
1060 2 : aValData.SetIgnoreBlank( true );
1061 2 : aValData.SetListType( 1 );
1062 2 : aValData.ResetInput();
1063 2 : aValData.SetError( rVDTParams.aErrorTitle, rVDTParams.aErrorMessage, rVDTParams.eErrorStyle );
1064 2 : aValData.SetSrcString( EMPTY_STRING );
1065 :
1066 : //get actual data validation entry from document
1067 2 : const ScValidationData* pValDataTest = pDoc->GetValidationEntry( rVDTParams.nExpectedIndex );
1068 :
1069 2 : sal_Int32 nCol( static_cast<sal_Int32>(rVDTParams.aPosition.Col()) );
1070 2 : sal_Int32 nRow( static_cast<sal_Int32>(rVDTParams.aPosition.Row()) );
1071 2 : sal_Int32 nTab( static_cast<sal_Int32>(rVDTParams.aPosition.Tab()) );
1072 4 : OStringBuffer sMsg("Data Validation Entry with base-cell-address: (");
1073 2 : sMsg.append(nCol).append(",").append(nRow).append(",").append(nTab).append(") was not imported correctly.");
1074 : //check if expected and actual data validation entries are equal
1075 4 : CPPUNIT_ASSERT_MESSAGE( sMsg.getStr(), pValDataTest && aValData.EqualEntries(*pValDataTest) );
1076 2 : }
1077 :
1078 2 : void checkCellValidity( const ScAddress& rValBaseAddr, const ScRange& rRange, const ScDocument* pDoc )
1079 : {
1080 2 : SCCOL nBCol( rValBaseAddr.Col() );
1081 2 : SCROW nBRow( rValBaseAddr.Row() );
1082 2 : SCTAB nTab( static_cast<const sal_Int32>(rValBaseAddr.Tab()) );
1083 : //get from the document the data validation entry we are checking against
1084 2 : const SfxUInt32Item* pItem = static_cast<const SfxUInt32Item*>(pDoc->GetAttr(nBCol, nBRow, nTab, ATTR_VALIDDATA) );
1085 2 : const ScValidationData* pValData = pDoc->GetValidationEntry( pItem->GetValue() );
1086 :
1087 : //check that each cell in the expected range is associated with the data validation entry
1088 8 : for(SCCOL i = rRange.aStart.Col(); i <= rRange.aEnd.Col(); ++i)
1089 : {
1090 36 : for(SCROW j = rRange.aStart.Row(); j <= rRange.aEnd.Row(); ++j)
1091 : {
1092 30 : const SfxUInt32Item* pItemTest = static_cast<const SfxUInt32Item*>( pDoc->GetAttr(i, j, nTab, ATTR_VALIDDATA) );
1093 30 : const ScValidationData* pValDataTest = pDoc->GetValidationEntry( pItemTest->GetValue() );
1094 : //prevent string operations for occurring unnecessarily
1095 30 : if(!(pValDataTest && pValData->GetKey() == pValDataTest->GetKey()))
1096 : {
1097 0 : sal_Int32 nCol = static_cast<const sal_Int32>(i);
1098 0 : sal_Int32 nRow = static_cast<const sal_Int32>(j);
1099 0 : sal_Int32 nTab32 = static_cast<const sal_Int32>(nTab);
1100 0 : OStringBuffer sMsg("\nData validation entry base-cell-address: (");
1101 0 : sMsg.append( static_cast<const sal_Int32>(nBCol) ).append(",");
1102 0 : sMsg.append( static_cast<const sal_Int32>(nBRow) ).append(",");
1103 0 : sMsg.append( nTab32 ).append(")\n");
1104 0 : sMsg.append("Cell: (").append(nCol).append(",").append(nRow).append(",").append(nTab32).append(")");
1105 0 : sal_uInt32 expectedKey(pValData->GetKey());
1106 0 : sal_uInt32 actualKey(-1);
1107 0 : if(pValDataTest)
1108 0 : actualKey = pValDataTest->GetKey();
1109 0 : CPPUNIT_ASSERT_EQUAL_MESSAGE(sMsg.getStr(), expectedKey, actualKey);
1110 : }
1111 : }
1112 : }
1113 2 : }
1114 :
1115 : }
1116 :
1117 1 : void ScFiltersTest::testDataValidityODS()
1118 : {
1119 1 : ScDocShellRef xDocSh = loadDoc("dataValidity.", ODS);
1120 1 : ScDocument* pDoc = xDocSh->GetDocument();
1121 :
1122 1 : ScAddress aValBaseAddr1( 2,6,0 ); //sheet1
1123 1 : ScAddress aValBaseAddr2( 2,3,1 ); //sheet2
1124 :
1125 : //sheet1's expected Data Validation Entry values
1126 : ValDataTestParams aVDTParams1(
1127 1 : SC_VALID_DECIMAL, SC_COND_GREATER, String("3.14"), EMPTY_STRING, pDoc,
1128 : aValBaseAddr1, String("Too small"),
1129 : String("The number you are trying to enter is not greater than 3.14! Are you sure you want to enter it anyway?"),
1130 : SC_VALERR_WARNING, 1
1131 3 : );
1132 : //sheet2's expected Data Validation Entry values
1133 : ValDataTestParams aVDTParams2(
1134 : SC_VALID_WHOLE, SC_COND_BETWEEN, String("1"), String("10"), pDoc,
1135 : aValBaseAddr2, String("Error sheet 2"),
1136 : String("Must be a whole number between 1 and 10."),
1137 : SC_VALERR_STOP, 2
1138 2 : );
1139 : //check each sheet's Data Validation Entries
1140 1 : checkValiditationEntries( aVDTParams1 );
1141 1 : checkValiditationEntries( aVDTParams2 );
1142 :
1143 : //expected ranges to be associated with data validity
1144 1 : ScRange aRange1( 2,2,0, 2,6,0 ); //sheet1
1145 1 : ScRange aRange2( 2,3,1, 6,7,1 ); //sheet2
1146 :
1147 : //check each sheet's cells for data validity
1148 1 : checkCellValidity( aValBaseAddr1, aRange1, pDoc );
1149 1 : checkCellValidity( aValBaseAddr2, aRange2, pDoc );
1150 :
1151 : //check each sheet's content
1152 2 : OUString aCSVFileName1;
1153 1 : createCSVPath(OUString("dataValidity1."), aCSVFileName1);
1154 1 : testFile(aCSVFileName1, pDoc, 0);
1155 :
1156 2 : OUString aCSVFileName2;
1157 1 : createCSVPath(OUString("dataValidity2."), aCSVFileName2);
1158 1 : testFile(aCSVFileName2, pDoc, 1);
1159 :
1160 2 : xDocSh->DoClose();
1161 1 : }
1162 :
1163 1 : void ScFiltersTest::testBrokenQuotesCSV()
1164 : {
1165 1 : const OUString aFileNameBase("fdo48621_broken_quotes.");
1166 2 : OUString aFileExtension(aFileFormats[CSV].pName, strlen(aFileFormats[CSV].pName), RTL_TEXTENCODING_UTF8 );
1167 2 : OUString aFilterName(aFileFormats[CSV].pFilterName, strlen(aFileFormats[CSV].pFilterName), RTL_TEXTENCODING_UTF8) ;
1168 2 : OUString aFileName;
1169 1 : createFileURL(aFileNameBase, aFileExtension, aFileName);
1170 2 : OUString aFilterType(aFileFormats[CSV].pTypeName, strlen(aFileFormats[CSV].pTypeName), RTL_TEXTENCODING_UTF8);
1171 1 : std::cout << aFileFormats[CSV].pName << " Test" << std::endl;
1172 :
1173 1 : unsigned int nFormatType = aFileFormats[CSV].nFormatType;
1174 1 : unsigned int nClipboardId = nFormatType ? SFX_FILTER_IMPORT | SFX_FILTER_USESOPTIONS : 0;
1175 : ScDocShellRef xDocSh = ScBootstrapFixture::load(aFileName, aFilterName, OUString(), aFilterType,
1176 2 : nFormatType, nClipboardId, SOFFICE_FILEFORMAT_CURRENT);
1177 :
1178 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load fdo48621_broken_quotes.csv", xDocSh.Is());
1179 1 : ScDocument* pDoc = xDocSh->GetDocument();
1180 1 : CPPUNIT_ASSERT_MESSAGE("No Document", pDoc); //remove with first test
1181 :
1182 2 : OUString aSheet2CSV("fdo48621_broken_quotes_exported.");
1183 2 : OUString aCSVPath;
1184 1 : createCSVPath( aSheet2CSV, aCSVPath );
1185 : // fdo#48621
1186 1 : testFile( aCSVPath, pDoc, 0, PureString);
1187 :
1188 2 : xDocSh->DoClose();
1189 1 : }
1190 :
1191 1 : void ScFiltersTest::testCellValueXLSX()
1192 : {
1193 1 : const OUString aFileNameBase("cell-value.");
1194 2 : OUString aFileExtension(aFileFormats[XLSX].pName, strlen(aFileFormats[XLSX].pName), RTL_TEXTENCODING_UTF8 );
1195 2 : OUString aFilterName(aFileFormats[XLSX].pFilterName, strlen(aFileFormats[XLSX].pFilterName), RTL_TEXTENCODING_UTF8) ;
1196 2 : OUString aFileName;
1197 1 : createFileURL(aFileNameBase, aFileExtension, aFileName);
1198 2 : OUString aFilterType(aFileFormats[XLSX].pTypeName, strlen(aFileFormats[XLSX].pTypeName), RTL_TEXTENCODING_UTF8);
1199 1 : std::cout << aFileFormats[XLSX].pName << " Test" << std::endl;
1200 :
1201 1 : unsigned int nFormatType = aFileFormats[XLSX].nFormatType;
1202 1 : unsigned int nClipboardId = nFormatType ? SFX_FILTER_IMPORT | SFX_FILTER_USESOPTIONS : 0;
1203 : ScDocShellRef xDocSh = ScBootstrapFixture::load( aFileName, aFilterName, OUString(), aFilterType,
1204 2 : nFormatType, nClipboardId, SOFFICE_FILEFORMAT_CURRENT);
1205 :
1206 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load cell-value.xlsx", xDocSh.Is());
1207 1 : ScDocument* pDoc = xDocSh->GetDocument();
1208 1 : CPPUNIT_ASSERT_MESSAGE("No Document", pDoc); //remove with first test
1209 :
1210 2 : OUString aCSVPath;
1211 1 : createCSVPath( aFileNameBase, aCSVPath );
1212 1 : testFile( aCSVPath, pDoc, 0 );
1213 :
1214 2 : xDocSh->DoClose();
1215 1 : }
1216 :
1217 2 : void ScFiltersTest::testPassword_Impl(const OUString& aFileNameBase)
1218 : {
1219 2 : OUString aFileExtension(aFileFormats[0].pName, strlen(aFileFormats[0].pName), RTL_TEXTENCODING_UTF8 );
1220 4 : OUString aFilterName(aFileFormats[0].pFilterName, strlen(aFileFormats[0].pFilterName), RTL_TEXTENCODING_UTF8) ;
1221 4 : OUString aFileName;
1222 2 : createFileURL(aFileNameBase, aFileExtension, aFileName);
1223 4 : OUString aFilterType(aFileFormats[0].pTypeName, strlen(aFileFormats[0].pTypeName), RTL_TEXTENCODING_UTF8);
1224 :
1225 2 : sal_uInt32 nFormat = SFX_FILTER_IMPORT | SFX_FILTER_USESOPTIONS;
1226 : SfxFilter* aFilter = new SfxFilter(
1227 : aFilterName,
1228 : OUString(), aFileFormats[0].nFormatType, nFormat, aFilterType, 0, OUString(),
1229 2 : OUString(), OUString("private:factory/scalc*") );
1230 2 : aFilter->SetVersion(SOFFICE_FILEFORMAT_CURRENT);
1231 :
1232 4 : ScDocShellRef xDocSh = new ScDocShell;
1233 2 : SfxMedium* pMedium = new SfxMedium(aFileName, STREAM_STD_READWRITE);
1234 2 : SfxItemSet* pSet = pMedium->GetItemSet();
1235 2 : pSet->Put(SfxStringItem(SID_PASSWORD, OUString("test")));
1236 2 : pMedium->SetFilter(aFilter);
1237 2 : if (!xDocSh->DoLoad(pMedium))
1238 : {
1239 0 : xDocSh->DoClose();
1240 : // load failed.
1241 0 : xDocSh.Clear();
1242 : }
1243 :
1244 2 : CPPUNIT_ASSERT_MESSAGE("Failed to load password.ods", xDocSh.Is());
1245 2 : ScDocument* pDoc = xDocSh->GetDocument();
1246 2 : CPPUNIT_ASSERT_MESSAGE("No Document", pDoc); //remove with first test
1247 4 : xDocSh->DoClose();
1248 :
1249 2 : }
1250 :
1251 1 : void ScFiltersTest::testPasswordNew()
1252 : {
1253 : //tests opening a file with new password algorithm
1254 1 : const OUString aFileNameBase("password.");
1255 1 : testPassword_Impl(aFileNameBase);
1256 1 : }
1257 :
1258 1 : void ScFiltersTest::testPasswordOld()
1259 : {
1260 : //tests opening a file with old password algorithm
1261 1 : const OUString aFileNameBase("passwordOld.");
1262 1 : testPassword_Impl(aFileNameBase);
1263 1 : }
1264 :
1265 1 : void ScFiltersTest::testControlImport()
1266 : {
1267 1 : ScDocShellRef xDocSh = loadDoc("singlecontrol.", XLSX);
1268 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load singlecontrol.xlsx", xDocSh.Is());
1269 :
1270 2 : uno::Reference< frame::XModel > xModel = xDocSh->GetModel();
1271 2 : uno::Reference< sheet::XSpreadsheetDocument > xDoc(xModel, UNO_QUERY_THROW);
1272 2 : uno::Reference< container::XIndexAccess > xIA(xDoc->getSheets(), UNO_QUERY_THROW);
1273 2 : uno::Reference< drawing::XDrawPageSupplier > xDrawPageSupplier( xIA->getByIndex(0), UNO_QUERY_THROW);
1274 2 : uno::Reference< container::XIndexAccess > xIA_DrawPage(xDrawPageSupplier->getDrawPage(), UNO_QUERY_THROW);
1275 2 : uno::Reference< drawing::XControlShape > xControlShape(xIA_DrawPage->getByIndex(0), UNO_QUERY_THROW);
1276 :
1277 1 : CPPUNIT_ASSERT(xControlShape.is());
1278 2 : xDocSh->DoClose();
1279 1 : }
1280 :
1281 1 : void ScFiltersTest::testChartImportODS()
1282 : {
1283 1 : ScDocShellRef xDocSh = loadDoc("chart-import-basic.", ODS);
1284 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load chart-import-basic.ods.", xDocSh.Is());
1285 :
1286 1 : ScDocument* pDoc = xDocSh->GetDocument();
1287 :
1288 : // Ensure that the document contains "Empty", "Chart", "Data" and "Title" sheets in this exact order.
1289 1 : CPPUNIT_ASSERT_MESSAGE("There should be 4 sheets in this document.", pDoc->GetTableCount() == 4);
1290 2 : OUString aName;
1291 1 : pDoc->GetName(0, aName);
1292 1 : CPPUNIT_ASSERT_EQUAL(OUString("Empty"), aName);
1293 1 : pDoc->GetName(1, aName);
1294 1 : CPPUNIT_ASSERT_EQUAL(OUString("Chart"), aName);
1295 1 : pDoc->GetName(2, aName);
1296 1 : CPPUNIT_ASSERT_EQUAL(OUString("Data"), aName);
1297 1 : pDoc->GetName(3, aName);
1298 1 : CPPUNIT_ASSERT_EQUAL(OUString("Title"), aName);
1299 :
1300 : // Retrieve the chart object instance from the 2nd page (for the 2nd sheet).
1301 1 : ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
1302 1 : CPPUNIT_ASSERT_MESSAGE("Failed to retrieve the drawing layer object.", pDrawLayer);
1303 1 : const SdrPage* pPage = pDrawLayer->GetPage(1); // for the 2nd sheet.
1304 1 : CPPUNIT_ASSERT_MESSAGE("Failed to retrieve the page object.", pPage);
1305 1 : CPPUNIT_ASSERT_MESSAGE("This page should contain one drawing object.", pPage->GetObjCount() == 1);
1306 1 : const SdrObject* pObj = pPage->GetObj(0);
1307 1 : CPPUNIT_ASSERT_MESSAGE("Failed to retrieve the drawing object.", pObj);
1308 1 : CPPUNIT_ASSERT_MESSAGE("This is not an OLE2 object.", pObj->GetObjIdentifier() == OBJ_OLE2);
1309 1 : const SdrOle2Obj& rOleObj = static_cast<const SdrOle2Obj&>(*pObj);
1310 1 : CPPUNIT_ASSERT_MESSAGE("This should be a chart object.", rOleObj.IsChart());
1311 :
1312 : // Make sure the chart object has correct range references.
1313 2 : Reference<frame::XModel> xModel = rOleObj.getXModel();
1314 1 : CPPUNIT_ASSERT_MESSAGE("Failed to get the embedded object interface.", xModel.is());
1315 2 : Reference<chart2::XChartDocument> xChartDoc(xModel, UNO_QUERY);
1316 1 : CPPUNIT_ASSERT_MESSAGE("Failed to get the chart document interface.", xChartDoc.is());
1317 2 : Reference<chart2::data::XDataSource> xDataSource(xChartDoc, UNO_QUERY);
1318 1 : CPPUNIT_ASSERT_MESSAGE("Failed to get the data source interface.", xDataSource.is());
1319 2 : Sequence<Reference<chart2::data::XLabeledDataSequence> > xDataSeqs = xDataSource->getDataSequences();
1320 1 : CPPUNIT_ASSERT_MESSAGE("There should be at least one data sequences.", xDataSeqs.getLength() > 0);
1321 2 : Reference<chart2::data::XDataReceiver> xDataRec(xChartDoc, UNO_QUERY);
1322 1 : CPPUNIT_ASSERT_MESSAGE("Failed to get the data receiver interface.", xDataRec.is());
1323 2 : Sequence<OUString> aRangeReps = xDataRec->getUsedRangeRepresentations();
1324 1 : CPPUNIT_ASSERT_MESSAGE("There should be at least one range representations.", aRangeReps.getLength() > 0);
1325 :
1326 2 : ScRangeList aRanges;
1327 4 : for (sal_Int32 i = 0, n = aRangeReps.getLength(); i < n; ++i)
1328 : {
1329 3 : ScRange aRange;
1330 3 : sal_uInt16 nRes = aRange.Parse(aRangeReps[i], pDoc, pDoc->GetAddressConvention());
1331 3 : if (nRes & SCA_VALID)
1332 : // This is a range address.
1333 2 : aRanges.Append(aRange);
1334 : else
1335 : {
1336 : // Parse it as a single cell address.
1337 1 : ScAddress aAddr;
1338 1 : nRes = aAddr.Parse(aRangeReps[i], pDoc, pDoc->GetAddressConvention());
1339 1 : CPPUNIT_ASSERT_MESSAGE("Failed to parse a range representation.", (nRes & SCA_VALID));
1340 1 : aRanges.Append(aAddr);
1341 : }
1342 : }
1343 :
1344 1 : CPPUNIT_ASSERT_MESSAGE("Data series title cell not found.", aRanges.In(ScAddress(1,0,3))); // B1 on Title
1345 1 : CPPUNIT_ASSERT_MESSAGE("Data series label range not found.", aRanges.In(ScRange(0,1,2,0,3,2))); // A2:A4 on Data
1346 1 : CPPUNIT_ASSERT_MESSAGE("Data series value range not found.", aRanges.In(ScRange(1,1,2,1,3,2))); // B2:B4 on Data
1347 :
1348 2 : xDocSh->DoClose();
1349 1 : }
1350 :
1351 1 : void ScFiltersTest::testNumberFormatHTML()
1352 : {
1353 1 : ScDocShellRef xDocSh = loadDoc("numberformat.", HTML);
1354 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load numberformat.html", xDocSh.Is());
1355 :
1356 1 : ScDocument* pDoc = xDocSh->GetDocument();
1357 :
1358 : // Check the header just in case.
1359 1 : CPPUNIT_ASSERT_MESSAGE("Cell value is not as expected", pDoc->GetString(0, 0, 0) == "Product");
1360 1 : CPPUNIT_ASSERT_MESSAGE("Cell value is not as expected", pDoc->GetString(1, 0, 0) == "Price");
1361 1 : CPPUNIT_ASSERT_MESSAGE("Cell value is not as expected", pDoc->GetString(2, 0, 0) == "Note");
1362 :
1363 : // B2 should be imported as a value cell.
1364 1 : bool bHasValue = pDoc->HasValueData(1, 1, 0);
1365 1 : CPPUNIT_ASSERT_MESSAGE("Fail to import number as a value cell.", bHasValue);
1366 1 : CPPUNIT_ASSERT_MESSAGE("Incorrect value.", pDoc->GetValue(1, 1, 0) == 199.98);
1367 :
1368 1 : xDocSh->DoClose();
1369 1 : }
1370 :
1371 1 : void ScFiltersTest::testNumberFormatCSV()
1372 : {
1373 1 : ScDocShellRef xDocSh = loadDoc("numberformat.", CSV);
1374 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load numberformat.csv", xDocSh.Is());
1375 :
1376 1 : ScDocument* pDoc = xDocSh->GetDocument();
1377 :
1378 : // Check the header just in case.
1379 1 : CPPUNIT_ASSERT_MESSAGE("Cell value is not as expected", pDoc->GetString(0, 0, 0) == "Product");
1380 1 : CPPUNIT_ASSERT_MESSAGE("Cell value is not as expected", pDoc->GetString(1, 0, 0) == "Price");
1381 1 : CPPUNIT_ASSERT_MESSAGE("Cell value is not as expected", pDoc->GetString(2, 0, 0) == "Note");
1382 :
1383 : // B2 should be imported as a value cell.
1384 1 : bool bHasValue = pDoc->HasValueData(1, 1, 0);
1385 1 : CPPUNIT_ASSERT_MESSAGE("Fail to import number as a value cell.", bHasValue);
1386 1 : CPPUNIT_ASSERT_MESSAGE("Incorrect value.", pDoc->GetValue(1, 1, 0) == 199.98);
1387 :
1388 1 : xDocSh->DoClose();
1389 1 : }
1390 :
1391 1 : void ScFiltersTest::testCellAnchoredShapesODS()
1392 : {
1393 1 : ScDocShellRef xDocSh = loadDoc("cell-anchored-shapes.", ODS);
1394 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load cell-anchored-shapes.ods", xDocSh.Is());
1395 :
1396 : // There are two cell-anchored objects on the first sheet.
1397 1 : ScDocument* pDoc = xDocSh->GetDocument();
1398 :
1399 1 : CPPUNIT_ASSERT_MESSAGE("There should be at least one sheet.", pDoc->GetTableCount() > 0);
1400 :
1401 1 : ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
1402 1 : SdrPage* pPage = pDrawLayer->GetPage(0);
1403 1 : CPPUNIT_ASSERT_MESSAGE("draw page for sheet 1 should exist.", pPage);
1404 1 : sal_uIntPtr nCount = pPage->GetObjCount();
1405 1 : CPPUNIT_ASSERT_MESSAGE("There should be 2 objects.", nCount == 2);
1406 3 : for (sal_uIntPtr i = 0; i < nCount; ++i)
1407 : {
1408 2 : SdrObject* pObj = pPage->GetObj(i);
1409 2 : CPPUNIT_ASSERT_MESSAGE("Failed to get drawing object.", pObj);
1410 2 : ScDrawObjData* pData = ScDrawLayer::GetObjData(pObj, false);
1411 2 : CPPUNIT_ASSERT_MESSAGE("Failed to retrieve user data for this object.", pData);
1412 2 : CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pData->maLastRect.IsEmpty());
1413 : }
1414 :
1415 1 : xDocSh->DoClose();
1416 1 : }
1417 :
1418 : namespace {
1419 :
1420 18 : class FindDimByName : std::unary_function<const ScDPSaveDimension*, bool>
1421 : {
1422 : OUString maName;
1423 : public:
1424 6 : FindDimByName(const OUString& rName) : maName(rName) {}
1425 :
1426 9 : bool operator() (const ScDPSaveDimension* p) const
1427 : {
1428 9 : return p && p->GetName() == maName;
1429 : }
1430 : };
1431 :
1432 6 : bool hasDimension(const std::vector<const ScDPSaveDimension*>& rDims, const OUString& aName)
1433 : {
1434 6 : return std::find_if(rDims.begin(), rDims.end(), FindDimByName(aName)) != rDims.end();
1435 : }
1436 :
1437 : }
1438 :
1439 1 : void ScFiltersTest::testPivotTableBasicODS()
1440 : {
1441 1 : ScDocShellRef xDocSh = loadDoc("pivot-table-basic.", ODS);
1442 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load pivot-table-basic.ods", xDocSh.Is());
1443 :
1444 1 : ScDocument* pDoc = xDocSh->GetDocument();
1445 1 : CPPUNIT_ASSERT_MESSAGE("There should be exactly two sheets.", pDoc->GetTableCount() == 2);
1446 :
1447 1 : ScDPCollection* pDPs = pDoc->GetDPCollection();
1448 1 : CPPUNIT_ASSERT_MESSAGE("Failed to get a live ScDPCollection instance.", pDPs);
1449 1 : CPPUNIT_ASSERT_MESSAGE("There should be exactly one pivot table instance.", pDPs->GetCount() == 1);
1450 :
1451 1 : const ScDPObject* pDPObj = (*pDPs)[0];
1452 1 : CPPUNIT_ASSERT_MESSAGE("Failed to get an pivot table object.", pDPObj);
1453 1 : const ScDPSaveData* pSaveData = pDPObj->GetSaveData();
1454 1 : CPPUNIT_ASSERT_MESSAGE("Failed to get ScDPSaveData instance.", pSaveData);
1455 2 : std::vector<const ScDPSaveDimension*> aDims;
1456 :
1457 : // Row fields
1458 1 : pSaveData->GetAllDimensionsByOrientation(sheet::DataPilotFieldOrientation_ROW, aDims);
1459 1 : CPPUNIT_ASSERT_MESSAGE("There should be exactly 3 row fields (2 normal dimensions and 1 layout dimension).", aDims.size() == 3);
1460 1 : CPPUNIT_ASSERT_MESSAGE("Dimension expected, but not found.", hasDimension(aDims, "Row1"));
1461 1 : CPPUNIT_ASSERT_MESSAGE("Dimension expected, but not found.", hasDimension(aDims, "Row2"));
1462 1 : const ScDPSaveDimension* pDataLayout = pSaveData->GetExistingDataLayoutDimension();
1463 2 : CPPUNIT_ASSERT_MESSAGE("There should be a data layout field as a row field.",
1464 1 : pDataLayout && pDataLayout->GetOrientation() == sheet::DataPilotFieldOrientation_ROW);
1465 :
1466 : // Column fields
1467 1 : pSaveData->GetAllDimensionsByOrientation(sheet::DataPilotFieldOrientation_COLUMN, aDims);
1468 1 : CPPUNIT_ASSERT_MESSAGE("There should be exactly 2 column fields.", aDims.size() == 2);
1469 1 : CPPUNIT_ASSERT_MESSAGE("Dimension expected, but not found.", hasDimension(aDims, "Col1"));
1470 1 : CPPUNIT_ASSERT_MESSAGE("Dimension expected, but not found.", hasDimension(aDims, "Col2"));
1471 :
1472 : // Page fields
1473 1 : pSaveData->GetAllDimensionsByOrientation(sheet::DataPilotFieldOrientation_PAGE, aDims);
1474 1 : CPPUNIT_ASSERT_MESSAGE("There should be exactly 2 page fields.", aDims.size() == 2);
1475 1 : CPPUNIT_ASSERT_MESSAGE("Dimension expected, but not found.", hasDimension(aDims, "Page1"));
1476 1 : CPPUNIT_ASSERT_MESSAGE("Dimension expected, but not found.", hasDimension(aDims, "Page2"));
1477 :
1478 : // Check the data field.
1479 1 : pSaveData->GetAllDimensionsByOrientation(sheet::DataPilotFieldOrientation_DATA, aDims);
1480 1 : CPPUNIT_ASSERT_MESSAGE("There should be exactly 1 data field.", aDims.size() == 1);
1481 1 : const ScDPSaveDimension* pDim = aDims.back();
1482 1 : CPPUNIT_ASSERT_MESSAGE("Function for the data field should be COUNT.", pDim->GetFunction() == sheet::GeneralFunction_COUNT);
1483 :
1484 2 : xDocSh->DoClose();
1485 1 : }
1486 :
1487 1 : void ScFiltersTest::testRowHeightODS()
1488 : {
1489 1 : ScDocShellRef xDocSh = loadDoc("row-height-import.", ODS);
1490 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load row-height-import.ods", xDocSh.Is());
1491 :
1492 1 : SCTAB nTab = 0;
1493 1 : SCROW nRow = 0;
1494 1 : ScDocument* pDoc = xDocSh->GetDocument();
1495 :
1496 : // The first 3 rows have manual heights.
1497 1 : int nHeight = pDoc->GetRowHeight(nRow, nTab, false);
1498 1 : bool bManual = pDoc->IsManualRowHeight(nRow, nTab);
1499 1 : CPPUNIT_ASSERT_EQUAL(600, nHeight);
1500 1 : CPPUNIT_ASSERT_MESSAGE("this row should have a manual row height.", bManual);
1501 1 : nHeight = pDoc->GetRowHeight(++nRow, nTab, false);
1502 1 : bManual = pDoc->IsManualRowHeight(nRow, nTab);
1503 1 : CPPUNIT_ASSERT_EQUAL(1200, nHeight);
1504 1 : CPPUNIT_ASSERT_MESSAGE("this row should have a manual row height.", bManual);
1505 1 : nHeight = pDoc->GetRowHeight(++nRow, nTab, false);
1506 1 : bManual = pDoc->IsManualRowHeight(nRow, nTab);
1507 1 : CPPUNIT_ASSERT_EQUAL(1800, nHeight);
1508 1 : CPPUNIT_ASSERT_MESSAGE("this row should have a manual row height.", bManual);
1509 :
1510 : // This one should have an automatic row height.
1511 1 : bManual = pDoc->IsManualRowHeight(++nRow, nTab);
1512 1 : CPPUNIT_ASSERT_MESSAGE("Row should have an automatic height.", !bManual);
1513 :
1514 : // Followed by a row with manual height.
1515 1 : nHeight = pDoc->GetRowHeight(++nRow, nTab, false);
1516 1 : bManual = pDoc->IsManualRowHeight(nRow, nTab);
1517 1 : CPPUNIT_ASSERT_EQUAL(2400, nHeight);
1518 1 : CPPUNIT_ASSERT_MESSAGE("this row should have a manual row height.", bManual);
1519 :
1520 : // And all the rest should have automatic heights.
1521 1 : bManual = pDoc->IsManualRowHeight(++nRow, nTab);
1522 1 : CPPUNIT_ASSERT_MESSAGE("Row should have an automatic height.", !bManual);
1523 :
1524 1 : bManual = pDoc->IsManualRowHeight(MAXROW, nTab);
1525 1 : CPPUNIT_ASSERT_MESSAGE("Row should have an automatic height.", !bManual);
1526 :
1527 1 : xDocSh->DoClose();
1528 1 : }
1529 :
1530 1 : void ScFiltersTest::testRichTextContentODS()
1531 : {
1532 1 : ScDocShellRef xDocSh = loadDoc("rich-text-cells.", ODS);
1533 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load rich-text-cells.ods", xDocSh.Is());
1534 1 : ScDocument* pDoc = xDocSh->GetDocument();
1535 :
1536 2 : OUString aTabName;
1537 1 : CPPUNIT_ASSERT_MESSAGE("Failed to get the name of the first sheet.", pDoc->GetName(0, aTabName));
1538 :
1539 : // All tested cells are in the first column.
1540 1 : ScAddress aPos(0, 0, 0);
1541 :
1542 : // Normal simple string with no formatting.
1543 1 : aPos.IncRow();
1544 1 : CPPUNIT_ASSERT_EQUAL(CELLTYPE_STRING, pDoc->GetCellType(aPos));
1545 1 : CPPUNIT_ASSERT_EQUAL(OUString("Normal"), pDoc->GetString(aPos.Col(), aPos.Row(), aPos.Tab()));
1546 :
1547 : // Normal string with bold applied to the whole cell.
1548 : {
1549 1 : aPos.IncRow();
1550 1 : CPPUNIT_ASSERT_EQUAL(CELLTYPE_STRING, pDoc->GetCellType(aPos));
1551 1 : CPPUNIT_ASSERT_EQUAL(OUString("All bold"), pDoc->GetString(aPos.Col(), aPos.Row(), aPos.Tab()));
1552 1 : const ScPatternAttr* pAttr = pDoc->GetPattern(aPos.Col(), aPos.Row(), aPos.Tab());
1553 1 : CPPUNIT_ASSERT_MESSAGE("Failed to get cell attribute.", pAttr);
1554 : const SvxWeightItem& rWeightItem =
1555 1 : static_cast<const SvxWeightItem&>(pAttr->GetItem(ATTR_FONT_WEIGHT));
1556 1 : CPPUNIT_ASSERT_EQUAL(WEIGHT_BOLD, rWeightItem.GetWeight());
1557 : }
1558 :
1559 : // This cell has an unformatted but multi-line content. Multi-line text is
1560 : // stored in edit cell even if it has no formatting applied.
1561 1 : aPos.IncRow();
1562 1 : CPPUNIT_ASSERT_EQUAL(CELLTYPE_EDIT, pDoc->GetCellType(aPos));
1563 1 : const EditTextObject* pEditText = pDoc->GetEditText(aPos);
1564 1 : CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
1565 1 : CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(3), pEditText->GetParagraphCount());
1566 2 : OUString aParaText = pEditText->GetText(0);
1567 1 : CPPUNIT_ASSERT_EQUAL(OUString("one"), aParaText);
1568 1 : aParaText = pEditText->GetText(1);
1569 1 : CPPUNIT_ASSERT_EQUAL(OUString("two"), aParaText);
1570 1 : aParaText = pEditText->GetText(2);
1571 1 : CPPUNIT_ASSERT_EQUAL(OUString("three"), aParaText);
1572 :
1573 : // Cell with sheet name field item.
1574 1 : aPos.IncRow();
1575 1 : CPPUNIT_ASSERT_EQUAL(CELLTYPE_EDIT, pDoc->GetCellType(aPos));
1576 1 : pEditText = pDoc->GetEditText(aPos);
1577 1 : CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
1578 1 : CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), pEditText->GetParagraphCount());
1579 1 : aParaText = pEditText->GetText(0);
1580 1 : CPPUNIT_ASSERT_MESSAGE("Unexpected text.", aParaText.indexOf("Sheet name is ") == 0);
1581 1 : CPPUNIT_ASSERT_MESSAGE("Sheet name field item not found.", pEditText->HasField(text::textfield::Type::TABLE));
1582 :
1583 : // Cell with URL field item.
1584 1 : aPos.IncRow();
1585 1 : CPPUNIT_ASSERT_EQUAL(CELLTYPE_EDIT, pDoc->GetCellType(aPos));
1586 1 : pEditText = pDoc->GetEditText(aPos);
1587 1 : CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
1588 1 : CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), pEditText->GetParagraphCount());
1589 1 : aParaText = pEditText->GetText(0);
1590 1 : CPPUNIT_ASSERT_MESSAGE("Unexpected text.", aParaText.indexOf("URL: ") == 0);
1591 1 : CPPUNIT_ASSERT_MESSAGE("URL field item not found.", pEditText->HasField(text::textfield::Type::URL));
1592 :
1593 : // Cell with Date field item.
1594 1 : aPos.IncRow();
1595 1 : CPPUNIT_ASSERT_EQUAL(CELLTYPE_EDIT, pDoc->GetCellType(aPos));
1596 1 : pEditText = pDoc->GetEditText(aPos);
1597 1 : CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
1598 1 : CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), pEditText->GetParagraphCount());
1599 1 : aParaText = pEditText->GetText(0);
1600 1 : CPPUNIT_ASSERT_MESSAGE("Unexpected text.", aParaText.indexOf("Date: ") == 0);
1601 1 : CPPUNIT_ASSERT_MESSAGE("Date field item not found.", pEditText->HasField(text::textfield::Type::DATE));
1602 :
1603 : // Cell with DocInfo title field item.
1604 1 : aPos.IncRow();
1605 1 : CPPUNIT_ASSERT_EQUAL(CELLTYPE_EDIT, pDoc->GetCellType(aPos));
1606 1 : pEditText = pDoc->GetEditText(aPos);
1607 1 : CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
1608 1 : CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), pEditText->GetParagraphCount());
1609 1 : aParaText = pEditText->GetText(0);
1610 1 : CPPUNIT_ASSERT_MESSAGE("Unexpected text.", aParaText.indexOf("Title: ") == 0);
1611 1 : CPPUNIT_ASSERT_MESSAGE("DocInfo title field item not found.", pEditText->HasField(text::textfield::Type::DOCINFO_TITLE));
1612 :
1613 : // Cell with sentence with both bold and italic sequences.
1614 1 : aPos.IncRow();
1615 1 : CPPUNIT_ASSERT_EQUAL(CELLTYPE_EDIT, pDoc->GetCellType(aPos));
1616 1 : pEditText = pDoc->GetEditText(aPos);
1617 1 : CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
1618 1 : CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), pEditText->GetParagraphCount());
1619 1 : aParaText = pEditText->GetText(0);
1620 1 : CPPUNIT_ASSERT_EQUAL(OUString("Sentence with bold and italic."), aParaText);
1621 2 : std::vector<EECharAttrib> aAttribs;
1622 1 : pEditText->GetCharAttribs(0, aAttribs);
1623 1 : std::vector<EECharAttrib>::const_iterator it = aAttribs.begin(), itEnd = aAttribs.end();
1624 : {
1625 1 : bool bHasBold = false, bHasItalic = false;
1626 7 : for (; it != itEnd; ++it)
1627 : {
1628 6 : OUString aSeg = aParaText.copy(it->nStart, it->nEnd - it->nStart);
1629 6 : const SfxPoolItem* pAttr = it->pAttr;
1630 6 : if (aSeg == "bold" && pAttr->Which() == EE_CHAR_WEIGHT && !bHasBold)
1631 : {
1632 1 : const SvxWeightItem& rItem = static_cast<const SvxWeightItem&>(*pAttr);
1633 1 : bHasBold = (rItem.GetWeight() == WEIGHT_BOLD);
1634 : }
1635 5 : else if (aSeg == "italic" && pAttr->Which() == EE_CHAR_ITALIC && !bHasItalic)
1636 : {
1637 1 : const SvxPostureItem& rItem = static_cast<const SvxPostureItem&>(*pAttr);
1638 1 : bHasItalic = (rItem.GetPosture() == ITALIC_NORMAL);
1639 :
1640 : }
1641 6 : }
1642 1 : CPPUNIT_ASSERT_MESSAGE("This sentence is expected to have both bold and italic sequences.", bHasBold && bHasItalic);
1643 : }
1644 :
1645 : // Cell with multi-line content with formatting applied.
1646 1 : aPos.IncRow();
1647 1 : CPPUNIT_ASSERT_EQUAL(CELLTYPE_EDIT, pDoc->GetCellType(aPos));
1648 1 : pEditText = pDoc->GetEditText(aPos);
1649 1 : CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
1650 1 : CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(3), pEditText->GetParagraphCount());
1651 1 : aParaText = pEditText->GetText(0);
1652 1 : CPPUNIT_ASSERT_EQUAL(OUString("bold"), aParaText);
1653 1 : aParaText = pEditText->GetText(1);
1654 1 : CPPUNIT_ASSERT_EQUAL(OUString("italic"), aParaText);
1655 1 : aParaText = pEditText->GetText(2);
1656 1 : CPPUNIT_ASSERT_EQUAL(OUString("underlined"), aParaText);
1657 :
1658 : // first line is bold.
1659 1 : pEditText->GetCharAttribs(0, aAttribs);
1660 1 : bool bHasBold = false;
1661 1 : for (it = aAttribs.begin(), itEnd = aAttribs.end(); it != itEnd; ++it)
1662 : {
1663 1 : if (it->pAttr->Which() == EE_CHAR_WEIGHT)
1664 : {
1665 1 : const SvxWeightItem& rItem = static_cast<const SvxWeightItem&>(*it->pAttr);
1666 1 : bHasBold = (rItem.GetWeight() == WEIGHT_BOLD);
1667 1 : if (bHasBold)
1668 1 : break;
1669 : }
1670 : }
1671 1 : CPPUNIT_ASSERT_MESSAGE("First line should be bold.", bHasBold);
1672 :
1673 : // second line is italic.
1674 1 : pEditText->GetCharAttribs(1, aAttribs);
1675 1 : bool bHasItalic = false;
1676 1 : for (it = aAttribs.begin(), itEnd = aAttribs.end(); it != itEnd; ++it)
1677 : {
1678 1 : if (it->pAttr->Which() == EE_CHAR_ITALIC)
1679 : {
1680 1 : const SvxPostureItem& rItem = static_cast<const SvxPostureItem&>(*it->pAttr);
1681 1 : bHasItalic = (rItem.GetPosture() == ITALIC_NORMAL);
1682 1 : if (bHasItalic)
1683 1 : break;
1684 : }
1685 : }
1686 1 : CPPUNIT_ASSERT_MESSAGE("Second line should be italic.", bHasItalic);
1687 :
1688 : // third line is underlined.
1689 1 : pEditText->GetCharAttribs(2, aAttribs);
1690 1 : bool bHasUnderline = false;
1691 1 : for (it = aAttribs.begin(), itEnd = aAttribs.end(); it != itEnd; ++it)
1692 : {
1693 1 : if (it->pAttr->Which() == EE_CHAR_UNDERLINE)
1694 : {
1695 1 : const SvxUnderlineItem& rItem = static_cast<const SvxUnderlineItem&>(*it->pAttr);
1696 1 : bHasUnderline = (rItem.GetLineStyle() == UNDERLINE_SINGLE);
1697 1 : if (bHasUnderline)
1698 1 : break;
1699 : }
1700 : }
1701 1 : CPPUNIT_ASSERT_MESSAGE("Second line should be underlined.", bHasUnderline);
1702 :
1703 : // URL with formats applied. For now, we'll check whether or not the
1704 : // field objects gets imported. Later we should add checks for the
1705 : // formats.
1706 1 : aPos.IncRow();
1707 1 : pEditText = pDoc->GetEditText(aPos);
1708 1 : CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
1709 1 : CPPUNIT_ASSERT_MESSAGE("URL field item not found.", pEditText->HasField(text::textfield::Type::URL));
1710 :
1711 : // Sheet name with formats applied.
1712 1 : aPos.IncRow();
1713 1 : pEditText = pDoc->GetEditText(aPos);
1714 1 : CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
1715 1 : CPPUNIT_ASSERT_MESSAGE("Sheet name field item not found.", pEditText->HasField(text::textfield::Type::TABLE));
1716 :
1717 : // Date with formats applied.
1718 1 : aPos.IncRow();
1719 1 : pEditText = pDoc->GetEditText(aPos);
1720 1 : CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
1721 1 : CPPUNIT_ASSERT_MESSAGE("Date field item not found.", pEditText->HasField(text::textfield::Type::DATE));
1722 :
1723 : // Document title with formats applied.
1724 1 : aPos.IncRow();
1725 1 : pEditText = pDoc->GetEditText(aPos);
1726 1 : CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
1727 1 : CPPUNIT_ASSERT_MESSAGE("Date field item not found.", pEditText->HasField(text::textfield::Type::DOCINFO_TITLE));
1728 :
1729 : // URL for a file in the same directory. It should be converted into an absolute URL on import.
1730 1 : aPos.IncRow();
1731 1 : pEditText = pDoc->GetEditText(aPos);
1732 1 : CPPUNIT_ASSERT_MESSAGE("Failed to retrieve edit text object.", pEditText);
1733 1 : const SvxFieldData* pData = pEditText->GetFieldData(0, 0, text::textfield::Type::URL);
1734 1 : CPPUNIT_ASSERT_MESSAGE("Failed to get the URL data.", pData && pData->GetClassId() == text::textfield::Type::URL);
1735 1 : const SvxURLField* pURLData = static_cast<const SvxURLField*>(pData);
1736 1 : CPPUNIT_ASSERT_MESSAGE("URL is not absolute with respect to the file system.", pURLData->GetURL().startsWith("file:///"));
1737 :
1738 2 : xDocSh->DoClose();
1739 1 : }
1740 :
1741 1 : void ScFiltersTest::testDataBarODS()
1742 : {
1743 1 : ScDocShellRef xDocSh = loadDoc("databar.", ODS);
1744 1 : CPPUNIT_ASSERT(xDocSh.Is());
1745 :
1746 1 : ScDocument* pDoc = xDocSh->GetDocument();
1747 1 : CPPUNIT_ASSERT(pDoc);
1748 1 : testDataBar_Impl(pDoc);
1749 :
1750 1 : xDocSh->DoClose();
1751 1 : }
1752 :
1753 1 : void ScFiltersTest::testDataBarXLSX()
1754 : {
1755 1 : ScDocShellRef xDocSh = loadDoc("databar.", XLSX);
1756 1 : CPPUNIT_ASSERT(xDocSh.Is());
1757 :
1758 1 : ScDocument* pDoc = xDocSh->GetDocument();
1759 1 : CPPUNIT_ASSERT(pDoc);
1760 1 : testDataBar_Impl(pDoc);
1761 :
1762 1 : xDocSh->DoClose();
1763 1 : }
1764 :
1765 1 : void ScFiltersTest::testColorScaleODS()
1766 : {
1767 1 : ScDocShellRef xDocSh = loadDoc("colorscale.", ODS);
1768 1 : CPPUNIT_ASSERT(xDocSh.Is());
1769 1 : ScDocument* pDoc = xDocSh->GetDocument();
1770 1 : CPPUNIT_ASSERT(pDoc);
1771 :
1772 1 : testColorScale2Entry_Impl(pDoc);
1773 1 : testColorScale3Entry_Impl(pDoc);
1774 :
1775 1 : xDocSh->DoClose();
1776 1 : }
1777 :
1778 1 : void ScFiltersTest::testColorScaleXLSX()
1779 : {
1780 1 : ScDocShellRef xDocSh = loadDoc("colorscale.", XLSX);
1781 1 : CPPUNIT_ASSERT(xDocSh.Is());
1782 1 : ScDocument* pDoc = xDocSh->GetDocument();
1783 1 : CPPUNIT_ASSERT(pDoc);
1784 :
1785 1 : testColorScale2Entry_Impl(pDoc);
1786 1 : testColorScale3Entry_Impl(pDoc);
1787 :
1788 1 : xDocSh->DoClose();
1789 1 : }
1790 :
1791 1 : void ScFiltersTest::testNewCondFormatODS()
1792 : {
1793 1 : ScDocShellRef xDocSh = ScBootstrapFixture::loadDoc( "new_cond_format_test.", ODS );
1794 :
1795 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load new_cond_format_test.xlsx", xDocSh.Is());
1796 :
1797 1 : ScDocument* pDoc = xDocSh->GetDocument();
1798 :
1799 2 : OUString aCSVFile("new_cond_format_test.");
1800 2 : OUString aCSVPath;
1801 1 : createCSVPath( aCSVFile, aCSVPath );
1802 1 : testCondFile(aCSVPath, pDoc, 0);
1803 :
1804 2 : xDocSh->DoClose();
1805 1 : }
1806 :
1807 1 : void ScFiltersTest::testNewCondFormatXLSX()
1808 : {
1809 1 : ScDocShellRef xDocSh = ScBootstrapFixture::loadDoc( "new_cond_format_test.", XLSX );
1810 :
1811 1 : CPPUNIT_ASSERT_MESSAGE("Failed to load new_cond_format_test.xlsx", xDocSh.Is());
1812 :
1813 1 : ScDocument* pDoc = xDocSh->GetDocument();
1814 :
1815 2 : OUString aCSVFile("new_cond_format_test.");
1816 2 : OUString aCSVPath;
1817 1 : createCSVPath( aCSVFile, aCSVPath );
1818 1 : testCondFile(aCSVPath, pDoc, 0);
1819 :
1820 2 : xDocSh->DoClose();
1821 1 : }
1822 :
1823 1 : void ScFiltersTest::testFormulaDependency()
1824 : {
1825 1 : ScDocShellRef xDocSh = ScBootstrapFixture::loadDoc( "dependencyTree.", ODS );
1826 :
1827 1 : ScDocument* pDoc = xDocSh->GetDocument();
1828 :
1829 : // check if formula in A1 changes value
1830 1 : double nVal = pDoc->GetValue(0,0,0);
1831 1 : CPPUNIT_ASSERT_DOUBLES_EQUAL(nVal, 1.0, 1e-10);
1832 1 : pDoc->SetValue(0,1,0, 0.0);
1833 1 : nVal = pDoc->GetValue(0,0,0);
1834 1 : CPPUNIT_ASSERT_DOUBLES_EQUAL(nVal, 2.0, 1e-10);
1835 :
1836 : // check that the number format is implicity inherited
1837 : // CPPUNIT_ASSERT_EQUAL(pDoc->GetString(0,4,0), pDoc->GetString(0,5,0));
1838 :
1839 1 : xDocSh->DoClose();
1840 1 : }
1841 :
1842 1 : void ScFiltersTest::testMiscRowHeights()
1843 : {
1844 : TestParam::RowData DfltRowData[] =
1845 : {
1846 : // check rows at the beginning and end of document
1847 : // and make sure they are reported as the default row
1848 : // height ( indicated by -1 )
1849 : { 2, 4, 0, -1, 0, false },
1850 : { 1048573, 1048575, 0, -1, 0, false },
1851 1 : };
1852 :
1853 : TestParam::RowData MultiLineOptData[] =
1854 : {
1855 : // Row 0 is 12.63 mm and optimal flag is set
1856 : { 0, 0, 0, 1263, CHECK_OPTIMAL, true },
1857 : // Row 1 is 11.99 mm and optimal flag is NOT set
1858 : { 1, 1, 0, 1199, CHECK_OPTIMAL, false },
1859 1 : };
1860 :
1861 : TestParam aTestValues[] =
1862 : {
1863 : /* Checks that a document saved to ods with default rows does indeed
1864 : have default row heights ( there was a problem where the optimal
1865 : height was being calcuated after import if no hard height )
1866 : */
1867 : { "alldefaultheights.", ODS, -1, SAL_N_ELEMENTS(DfltRowData), DfltRowData },
1868 : /* Checks the imported height of some multiline input, additionally checks
1869 : that the optimal height flag is set ( or not )
1870 : */
1871 : { "multilineoptimal.", ODS, -1, SAL_N_ELEMENTS(MultiLineOptData), MultiLineOptData },
1872 1 : };
1873 1 : miscRowHeightsTest( aTestValues, SAL_N_ELEMENTS(aTestValues) );
1874 1 : }
1875 :
1876 : // regression test at least fdo#59193
1877 : // what we want to test here is that when cell contents are deleted
1878 : // and the optimal flag is set for that row that the row is actually resized
1879 :
1880 1 : void ScFiltersTest::testOptimalHeightReset()
1881 : {
1882 1 : ScDocShellRef xDocSh = loadDoc("multilineoptimal.", ODS, true);
1883 1 : SCTAB nTab = 0;
1884 1 : SCROW nRow = 0;
1885 1 : ScDocument* pDoc = xDocSh->GetDocument();
1886 1 : pDoc->EnableAdjustHeight( true );
1887 : // open document in read/write mode ( otherwise optimal height stuff won't
1888 : // be triggered ) *and* you can't delete cell contents.
1889 1 : int nHeight = sc::TwipsToHMM ( pDoc->GetRowHeight(nRow, nTab, false) );
1890 1 : CPPUNIT_ASSERT_EQUAL(1263, nHeight);
1891 :
1892 1 : ScDocFunc &rFunc = xDocSh->GetDocFunc();
1893 :
1894 : // delete content of A1
1895 1 : ScRange aDelRange(0,0,0,0,0,0);
1896 2 : ScMarkData aMark;
1897 1 : aMark.SetMarkArea(aDelRange);
1898 1 : rFunc.DeleteContents( aMark, IDF_ALL, false, true );
1899 :
1900 : // get the new height of A1
1901 1 : nHeight = sc::TwipsToHMM( pDoc->GetRowHeight(nRow, nTab, false) );
1902 :
1903 : // set optimal height for empty row 2
1904 : SCCOLROW nRowArr[2];
1905 1 : nRowArr[0] = nRowArr[1] = 2;
1906 1 : rFunc.SetWidthOrHeight( false, 1, nRowArr, nTab, SC_SIZE_OPTIMAL, 0, sal_True, sal_True );
1907 :
1908 : // retrieve optimal height
1909 1 : int nOptimalHeight = sc::TwipsToHMM( pDoc->GetRowHeight( nRowArr[0], nTab, false) );
1910 :
1911 : // check if the new height of A1 ( after delete ) is now the optimal height of an empty cell
1912 1 : CPPUNIT_ASSERT_EQUAL(nOptimalHeight, nHeight );
1913 2 : xDocSh->DoClose();
1914 1 : }
1915 :
1916 1 : void ScFiltersTest::testPrintRangeODS()
1917 : {
1918 1 : ScDocShellRef xDocSh = loadDoc("print-range.", ODS);
1919 1 : ScDocument* pDoc = xDocSh->GetDocument();
1920 1 : const ScRange* pRange = pDoc->GetRepeatRowRange(0);
1921 1 : CPPUNIT_ASSERT(pRange);
1922 1 : CPPUNIT_ASSERT_EQUAL(ScRange(0,0,0,0,1,0), *pRange);
1923 :
1924 1 : pRange = pDoc->GetRepeatRowRange(1);
1925 1 : CPPUNIT_ASSERT(pRange);
1926 1 : CPPUNIT_ASSERT_EQUAL(ScRange(0,2,0,0,4,0), *pRange);
1927 1 : }
1928 :
1929 1 : void ScFiltersTest::testOutlineODS()
1930 : {
1931 1 : ScDocShellRef xDocSh = loadDoc("outline.", ODS);
1932 1 : ScDocument* pDoc = xDocSh->GetDocument();
1933 :
1934 1 : const ScOutlineTable* pTable = pDoc->GetOutlineTable(0);
1935 1 : CPPUNIT_ASSERT(pTable);
1936 :
1937 1 : const ScOutlineArray* pArr = pTable->GetRowArray();
1938 1 : size_t nDepth = pArr->GetDepth();
1939 1 : CPPUNIT_ASSERT_EQUAL(size_t(4), nDepth);
1940 :
1941 5 : for(size_t i = 0; i < nDepth; ++i)
1942 : {
1943 4 : CPPUNIT_ASSERT_EQUAL(size_t(1), pArr->GetCount(i));
1944 : }
1945 :
1946 : struct OutlineData {
1947 : SCCOLROW nStart;
1948 : SCCOLROW nEnd;
1949 : bool bHidden;
1950 : bool bVisible;
1951 :
1952 : size_t nDepth;
1953 : size_t nIndex;
1954 : };
1955 :
1956 : OutlineData aRow[] =
1957 : {
1958 : { 1, 29, false, true, 0, 0 },
1959 : { 2, 26, false, true, 1, 0 },
1960 : { 4, 23, false, true, 2, 0 },
1961 : { 6, 20, true, true, 3, 0 }
1962 1 : };
1963 :
1964 5 : for(size_t i = 0; i < SAL_N_ELEMENTS(aRow); ++i)
1965 : {
1966 :
1967 4 : const ScOutlineEntry* pEntry = pArr->GetEntry(aRow[i].nDepth, aRow[i].nIndex);
1968 4 : SCCOLROW nStart = pEntry->GetStart();
1969 4 : CPPUNIT_ASSERT_EQUAL(aRow[i].nStart, nStart);
1970 :
1971 4 : SCCOLROW nEnd = pEntry->GetEnd();
1972 4 : CPPUNIT_ASSERT_EQUAL(aRow[i].nEnd, nEnd);
1973 :
1974 4 : bool bHidden = pEntry->IsHidden();
1975 4 : CPPUNIT_ASSERT_EQUAL(aRow[i].bHidden, bHidden);
1976 :
1977 4 : bool bVisible = pEntry->IsVisible();
1978 4 : CPPUNIT_ASSERT_EQUAL(aRow[i].bVisible, bVisible);
1979 1 : }
1980 1 : }
1981 :
1982 46 : ScFiltersTest::ScFiltersTest()
1983 46 : : ScBootstrapFixture( "/sc/qa/unit/data" )
1984 : {
1985 46 : }
1986 :
1987 46 : void ScFiltersTest::setUp()
1988 : {
1989 46 : test::BootstrapFixture::setUp();
1990 :
1991 : // This is a bit of a fudge, we do this to ensure that ScGlobals::ensure,
1992 : // which is a private symbol to us, gets called
1993 92 : m_xCalcComponent =
1994 138 : getMultiServiceFactory()->createInstance("com.sun.star.comp.Calc.SpreadsheetDocument");
1995 46 : CPPUNIT_ASSERT_MESSAGE("no calc component!", m_xCalcComponent.is());
1996 46 : }
1997 :
1998 46 : void ScFiltersTest::tearDown()
1999 : {
2000 46 : uno::Reference< lang::XComponent >( m_xCalcComponent, UNO_QUERY_THROW )->dispose();
2001 46 : test::BootstrapFixture::tearDown();
2002 46 : }
2003 :
2004 1 : CPPUNIT_TEST_SUITE_REGISTRATION(ScFiltersTest);
2005 :
2006 4 : CPPUNIT_PLUGIN_IMPLEMENT();
2007 :
2008 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|