bump product version to 5.0.4.1
[LibreOffice.git] / sc / qa / unit / helper / qahelper.cxx
blob96307e1bf2b8badb9e69cf21d9355929e7514c4d
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 "qahelper.hxx"
11 #include "csv_handler.hxx"
12 #include "drwlayer.hxx"
13 #include "compiler.hxx"
14 #include "conditio.hxx"
15 #include "stlsheet.hxx"
16 #include "formulacell.hxx"
17 #include <svx/svdpage.hxx>
18 #include <svx/svdoole2.hxx>
19 #include <editeng/brushitem.hxx>
20 #include <editeng/justifyitem.hxx>
22 #include <config_orcus.h>
24 #if ENABLE_ORCUS
25 #if defined WNT
26 #define __ORCUS_STATIC_LIB
27 #endif
28 #include <orcus/csv_parser.hpp>
29 #endif
31 #include <fstream>
33 #include <com/sun/star/frame/XModel.hpp>
34 #include <com/sun/star/text/textfield/Type.hpp>
35 #include <com/sun/star/chart2/XChartDocument.hpp>
36 #include <com/sun/star/chart2/data/XDataReceiver.hpp>
37 #include <com/sun/star/document/MacroExecMode.hpp>
39 using namespace com::sun::star;
40 using namespace ::com::sun::star::uno;
42 // calc data structure pretty printer
43 std::ostream& operator<<(std::ostream& rStrm, const ScAddress& rAddr)
45 rStrm << "Col: " << rAddr.Col() << " Row: " << rAddr.Row() << " Tab: " << rAddr.Tab() << "\n";
46 return rStrm;
49 std::ostream& operator<<(std::ostream& rStrm, const ScRange& rRange)
51 rStrm << "ScRange: " << rRange.aStart << rRange.aEnd << "\n";
52 return rStrm;
55 std::ostream& operator<<(std::ostream& rStrm, const ScRangeList& rList)
57 rStrm << "ScRangeList: \n";
58 for(size_t i = 0; i < rList.size(); ++i)
59 rStrm << *rList[i];
60 return rStrm;
63 std::ostream& operator<<(std::ostream& rStrm, const Color& rColor)
65 rStrm << "Color: R:" << (int)rColor.GetRed() << " G:" << (int)rColor.GetGreen() << " B: " << (int)rColor.GetBlue();
66 return rStrm;
69 std::ostream& operator<<(std::ostream& rStrm, const OpCode& rCode)
71 rStrm << static_cast<sal_uInt16>(rCode);
72 return rStrm;
75 const FileFormat ScBootstrapFixture::aFileFormats[] = {
76 { "ods" , "calc8", "", ODS_FORMAT_TYPE },
77 { "xls" , "MS Excel 97", "calc_MS_EXCEL_97", XLS_FORMAT_TYPE },
78 { "xlsx", "Calc Office Open XML" , "Office Open XML Spreadsheet", XLSX_FORMAT_TYPE },
79 { "xlsm", "Calc Office Open XML" , "Office Open XML Spreadsheet", XLSX_FORMAT_TYPE },
80 { "csv" , "Text - txt - csv (StarCalc)", "generic_Text", CSV_FORMAT_TYPE },
81 { "html" , "calc_HTML_WebQuery", "generic_HTML", HTML_FORMAT_TYPE },
82 { "123" , "Lotus", "calc_Lotus", LOTUS123_FORMAT_TYPE },
83 { "dif", "DIF", "calc_DIF", DIF_FORMAT_TYPE },
84 { "xml", "MS Excel 2003 XML", "calc_MS_Excel_2003_XML", XLS_XML_FORMAT_TYPE },
85 { "xlsb", "Calc MS Excel 2007 Binary", "MS Excel 2007 Binary", XLSB_XML_FORMAT_TYPE }
88 bool testEqualsWithTolerance( long nVal1, long nVal2, long nTol )
90 return ( labs( nVal1 - nVal2 ) <= nTol );
93 void loadFile(const OUString& aFileName, std::string& aContent)
95 OString aOFileName = OUStringToOString(aFileName, RTL_TEXTENCODING_UTF8);
97 #ifdef ANDROID
98 size_t size;
99 if (strncmp(aOFileName.getStr(), "/assets/", sizeof("/assets/")-1) == 0) {
100 const char *contents = (const char *) lo_apkentry(aOFileName.getStr(), &size);
101 if (contents != 0) {
102 aContent = std::string(contents, size);
103 return;
106 #endif
108 std::ifstream aFile(aOFileName.getStr());
110 OStringBuffer aErrorMsg("Could not open csv file: ");
111 aErrorMsg.append(aOFileName);
112 CPPUNIT_ASSERT_MESSAGE(aErrorMsg.getStr(), aFile);
113 std::ostringstream aOStream;
114 aOStream << aFile.rdbuf();
115 aFile.close();
116 aContent = aOStream.str();
119 #if ENABLE_ORCUS
121 void testFile(OUString& aFileName, ScDocument& rDoc, SCTAB nTab, StringType aStringFormat)
123 csv_handler aHandler(&rDoc, nTab, aStringFormat);
124 orcus::csv::parser_config aConfig;
125 aConfig.delimiters.push_back(',');
126 aConfig.delimiters.push_back(';');
127 aConfig.text_qualifier = '"';
128 aConfig.trim_cell_value = false;
130 std::string aContent;
131 loadFile(aFileName, aContent);
132 orcus::csv_parser<csv_handler> parser ( &aContent[0], aContent.size() , aHandler, aConfig);
135 parser.parse();
137 catch (const orcus::csv::parse_error& e)
139 std::cout << "reading csv content file failed: " << e.what() << std::endl;
140 OStringBuffer aErrorMsg("csv parser error: ");
141 aErrorMsg.append(e.what());
142 CPPUNIT_ASSERT_MESSAGE(aErrorMsg.getStr(), false);
146 void testCondFile(OUString& aFileName, ScDocument* pDoc, SCTAB nTab)
148 conditional_format_handler aHandler(pDoc, nTab);
149 orcus::csv::parser_config aConfig;
150 aConfig.delimiters.push_back(',');
151 aConfig.delimiters.push_back(';');
152 aConfig.text_qualifier = '"';
153 std::string aContent;
154 loadFile(aFileName, aContent);
155 orcus::csv_parser<conditional_format_handler> parser ( &aContent[0], aContent.size() , aHandler, aConfig);
158 parser.parse();
160 catch (const orcus::csv::parse_error& e)
162 std::cout << "reading csv content file failed: " << e.what() << std::endl;
163 OStringBuffer aErrorMsg("csv parser error: ");
164 aErrorMsg.append(e.what());
165 CPPUNIT_ASSERT_MESSAGE(aErrorMsg.getStr(), false);
169 #else
171 void testFile(OUString&, ScDocument&, SCTAB, StringType) {}
172 void testCondFile(OUString&, ScDocument*, SCTAB) {}
174 #endif
176 void testFormats(ScBootstrapFixture* pTest, ScDocument* pDoc, sal_Int32 nFormat)
178 //test Sheet1 with csv file
179 OUString aCSVFileName;
180 pTest->createCSVPath(OUString("numberFormat."), aCSVFileName);
181 testFile(aCSVFileName, *pDoc, 0, PureString);
182 //need to test the color of B3
183 //it's not a font color!
184 //formatting for B5: # ??/100 gets lost during import
186 //test Sheet2
187 const ScPatternAttr* pPattern = NULL;
188 pPattern = pDoc->GetPattern(0,0,1);
189 vcl::Font aFont;
190 pPattern->GetFont(aFont,SC_AUTOCOL_RAW);
191 CPPUNIT_ASSERT_EQUAL_MESSAGE("font size should be 10", 200l, aFont.GetSize().getHeight());
192 CPPUNIT_ASSERT_EQUAL_MESSAGE("font color should be black", COL_AUTO, aFont.GetColor().GetColor());
193 pPattern = pDoc->GetPattern(0,1,1);
194 pPattern->GetFont(aFont, SC_AUTOCOL_RAW);
195 CPPUNIT_ASSERT_EQUAL_MESSAGE("font size should be 12", 240l, aFont.GetSize().getHeight());
196 pPattern = pDoc->GetPattern(0,2,1);
197 pPattern->GetFont(aFont, SC_AUTOCOL_RAW);
198 CPPUNIT_ASSERT_EQUAL_MESSAGE("font should be italic", ITALIC_NORMAL, aFont.GetItalic());
199 pPattern = pDoc->GetPattern(0,4,1);
200 pPattern->GetFont(aFont, SC_AUTOCOL_RAW);
201 CPPUNIT_ASSERT_EQUAL_MESSAGE("font should be bold", WEIGHT_BOLD, aFont.GetWeight());
202 pPattern = pDoc->GetPattern(1,0,1);
203 pPattern->GetFont(aFont, SC_AUTOCOL_RAW);
204 CPPUNIT_ASSERT_EQUAL_MESSAGE("font should be blue", COL_BLUE, aFont.GetColor().GetColor());
205 pPattern = pDoc->GetPattern(1,1,1);
206 pPattern->GetFont(aFont, SC_AUTOCOL_RAW);
207 CPPUNIT_ASSERT_EQUAL_MESSAGE("font should be striked out with a single line", STRIKEOUT_SINGLE, aFont.GetStrikeout());
208 //some tests on sheet2 only for ods
209 if (nFormat == ODS)
211 pPattern = pDoc->GetPattern(1,2,1);
212 pPattern->GetFont(aFont, SC_AUTOCOL_RAW);
213 CPPUNIT_ASSERT_EQUAL_MESSAGE("font should be striked out with a double line", STRIKEOUT_DOUBLE, aFont.GetStrikeout());
214 pPattern = pDoc->GetPattern(1,3,1);
215 pPattern->GetFont(aFont, SC_AUTOCOL_RAW);
216 CPPUNIT_ASSERT_EQUAL_MESSAGE("font should be underlined with a dotted line", UNDERLINE_DOTTED, aFont.GetUnderline());
217 //check row height import
218 //disable for now until we figure out cause of win tinderboxes test failures
219 //CPPUNIT_ASSERT_EQUAL( static_cast<sal_uInt16>(256), pDoc->GetRowHeight(0,1) ); //0.178in
220 //CPPUNIT_ASSERT_EQUAL( static_cast<sal_uInt16>(304), pDoc->GetRowHeight(1,1) ); //0.211in
221 //CPPUNIT_ASSERT_EQUAL( static_cast<sal_uInt16>(477), pDoc->GetRowHeight(5,1) ); //0.3311in
222 //check column width import
223 CPPUNIT_ASSERT_EQUAL( static_cast<sal_uInt16>(555), pDoc->GetColWidth(4,1) ); //0.3854in
224 CPPUNIT_ASSERT_EQUAL( static_cast<sal_uInt16>(1280), pDoc->GetColWidth(5,1) ); //0.889in
225 CPPUNIT_ASSERT_EQUAL( static_cast<sal_uInt16>(4153), pDoc->GetColWidth(6,1) ); //2.8839in
226 //test case for i53253 where a cell has text with different styles and space between the text.
227 OUString aTestStr = pDoc->GetString(3,0,1);
228 OUString aKnownGoodStr("text14 space");
229 CPPUNIT_ASSERT_EQUAL( aKnownGoodStr, aTestStr );
230 //test case for cell text with line breaks.
231 aTestStr = pDoc->GetString(3,5,1);
232 aKnownGoodStr = "Hello,\nCalc!";
233 CPPUNIT_ASSERT_EQUAL( aKnownGoodStr, aTestStr );
235 pPattern = pDoc->GetPattern(1,4,1);
236 Color aColor = static_cast<const SvxBrushItem&>(pPattern->GetItem(ATTR_BACKGROUND)).GetColor();
237 CPPUNIT_ASSERT_MESSAGE("background color should be green", aColor == COL_LIGHTGREEN);
238 pPattern = pDoc->GetPattern(2,0,1);
239 SvxCellHorJustify eHorJustify = static_cast<SvxCellHorJustify>(static_cast<const SvxHorJustifyItem&>(pPattern->GetItem(ATTR_HOR_JUSTIFY)).GetValue());
240 CPPUNIT_ASSERT_EQUAL_MESSAGE("cell content should be aligned centre horizontally", SVX_HOR_JUSTIFY_CENTER, eHorJustify);
241 //test alignment
242 pPattern = pDoc->GetPattern(2,1,1);
243 eHorJustify = static_cast<SvxCellHorJustify>(static_cast<const SvxHorJustifyItem&>(pPattern->GetItem(ATTR_HOR_JUSTIFY)).GetValue());
244 CPPUNIT_ASSERT_EQUAL_MESSAGE("cell content should be aligned right horizontally", SVX_HOR_JUSTIFY_RIGHT, eHorJustify);
245 pPattern = pDoc->GetPattern(2,2,1);
246 eHorJustify = static_cast<SvxCellHorJustify>(static_cast<const SvxHorJustifyItem&>(pPattern->GetItem(ATTR_HOR_JUSTIFY)).GetValue());
247 CPPUNIT_ASSERT_EQUAL_MESSAGE("cell content should be aligned block horizontally", SVX_HOR_JUSTIFY_BLOCK, eHorJustify);
249 //test Sheet3 only for ods and xlsx
250 if ( nFormat == ODS || nFormat == XLSX )
252 pTest->createCSVPath(OUString("conditionalFormatting."), aCSVFileName);
253 testCondFile(aCSVFileName, pDoc, 2);
254 // test parent cell style import ( fdo#55198 )
255 if ( nFormat == XLSX )
257 pPattern = pDoc->GetPattern(1,1,3);
258 ScStyleSheet* pStyleSheet = const_cast<ScStyleSheet*>(pPattern->GetStyleSheet());
259 // check parent style name
260 OUString sExpected("Excel Built-in Date");
261 OUString sResult = pStyleSheet->GetName();
262 CPPUNIT_ASSERT_EQUAL_MESSAGE("parent style for Sheet4.B2 is 'Excel Built-in Date'", sExpected, sResult);
263 // check align of style
264 SfxItemSet& rItemSet = pStyleSheet->GetItemSet();
265 eHorJustify = static_cast<SvxCellHorJustify>(static_cast< const SvxHorJustifyItem& >(rItemSet.Get( ATTR_HOR_JUSTIFY ) ).GetValue() );
266 CPPUNIT_ASSERT_EQUAL_MESSAGE("'Excel Built-in Date' style should be aligned centre horizontally", SVX_HOR_JUSTIFY_CENTER, eHorJustify);
267 // check date format ( should be just month e.g. 29 )
268 sResult =pDoc->GetString( 1,1,3 );
269 sExpected = "29";
270 CPPUNIT_ASSERT_EQUAL_MESSAGE("'Excel Built-in Date' style should just display month", sExpected, sResult );
272 // check actual align applied to cell, should be the same as
273 // the style
274 eHorJustify = static_cast<SvxCellHorJustify>(static_cast< const SvxHorJustifyItem& >(pPattern->GetItem( ATTR_HOR_JUSTIFY ) ).GetValue() );
275 CPPUNIT_ASSERT_EQUAL_MESSAGE("cell with 'Excel Built-in Date' style should be aligned centre horizontally", SVX_HOR_JUSTIFY_CENTER, eHorJustify);
279 ScConditionalFormat* pCondFormat = pDoc->GetCondFormat(0,0,2);
280 const ScRangeList& rRange = pCondFormat->GetRange();
281 CPPUNIT_ASSERT(rRange == ScRange(0,0,2,3,0,2));
283 pCondFormat = pDoc->GetCondFormat(0,1,2);
284 const ScRangeList& rRange2 = pCondFormat->GetRange();
285 CPPUNIT_ASSERT(rRange2 == ScRange(0,1,2,0,1,2));
287 pCondFormat = pDoc->GetCondFormat(1,1,2);
288 const ScRangeList& rRange3 = pCondFormat->GetRange();
289 CPPUNIT_ASSERT(rRange3 == ScRange(1,1,2,3,1,2));
292 const SdrOle2Obj* getSingleChartObject(ScDocument& rDoc, sal_uInt16 nPage)
294 // Retrieve the chart object instance from the 2nd page (for the 2nd sheet).
295 ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer();
296 if (!pDrawLayer)
298 cout << "Failed to retrieve the drawing layer object." << endl;
299 return NULL;
302 const SdrPage* pPage = pDrawLayer->GetPage(nPage);
303 if (!pPage)
305 cout << "Failed to retrieve the page object." << endl;
306 return NULL;
309 if (pPage->GetObjCount() != 1)
311 cout << "This page should contain one drawing object." << endl;
312 return NULL;
315 const SdrObject* pObj = pPage->GetObj(0);
316 if (!pObj)
318 cout << "Failed to retrieve the drawing object." << endl;
319 return NULL;
322 if (pObj->GetObjIdentifier() != OBJ_OLE2)
324 cout << "This is not an OLE2 object." << endl;
325 return NULL;
328 const SdrOle2Obj& rOleObj = static_cast<const SdrOle2Obj&>(*pObj);
329 if (!rOleObj.IsChart())
331 cout << "This should be a chart object." << endl;
332 return NULL;
335 return &rOleObj;
338 std::vector<OUString> getChartRangeRepresentations(const SdrOle2Obj& rChartObj)
340 std::vector<OUString> aRangeReps;
342 // Make sure the chart object has correct range references.
343 Reference<frame::XModel> xModel = rChartObj.getXModel();
344 if (!xModel.is())
346 cout << "Failed to get the embedded object interface." << endl;
347 return aRangeReps;
350 Reference<chart2::XChartDocument> xChartDoc(xModel, UNO_QUERY);
351 if (!xChartDoc.is())
353 cout << "Failed to get the chart document interface." << endl;
354 return aRangeReps;
357 Reference<chart2::data::XDataSource> xDataSource(xChartDoc, UNO_QUERY);
358 if (!xDataSource.is())
360 cout << "Failed to get the data source interface." << endl;
361 return aRangeReps;
364 Sequence<Reference<chart2::data::XLabeledDataSequence> > xDataSeqs = xDataSource->getDataSequences();
365 if (!xDataSeqs.getLength())
367 cout << "There should be at least one data sequences." << endl;
368 return aRangeReps;
371 Reference<chart2::data::XDataReceiver> xDataRec(xChartDoc, UNO_QUERY);
372 if (!xDataRec.is())
374 cout << "Failed to get the data receiver interface." << endl;
375 return aRangeReps;
378 Sequence<OUString> aRangeRepSeqs = xDataRec->getUsedRangeRepresentations();
379 for (sal_Int32 i = 0, n = aRangeRepSeqs.getLength(); i < n; ++i)
380 aRangeReps.push_back(aRangeRepSeqs[i]);
382 return aRangeReps;
385 ScRangeList getChartRanges(ScDocument& rDoc, const SdrOle2Obj& rChartObj)
387 std::vector<OUString> aRangeReps = getChartRangeRepresentations(rChartObj);
388 ScRangeList aRanges;
389 for (size_t i = 0, n = aRangeReps.size(); i < n; ++i)
391 ScRange aRange;
392 sal_uInt16 nRes = aRange.Parse(aRangeReps[i], &rDoc, rDoc.GetAddressConvention());
393 if (nRes & SCA_VALID)
394 // This is a range address.
395 aRanges.Append(aRange);
396 else
398 // Parse it as a single cell address.
399 ScAddress aAddr;
400 nRes = aAddr.Parse(aRangeReps[i], &rDoc, rDoc.GetAddressConvention());
401 CPPUNIT_ASSERT_MESSAGE("Failed to parse a range representation.", (nRes & SCA_VALID));
402 aRanges.Append(aAddr);
406 return aRanges;
409 namespace {
411 ScTokenArray* getTokens(ScDocument& rDoc, const ScAddress& rPos)
413 ScFormulaCell* pCell = rDoc.GetFormulaCell(rPos);
414 if (!pCell)
416 OUString aStr = rPos.Format(SCA_VALID);
417 cerr << aStr << " is not a formula cell." << endl;
418 return NULL;
421 return pCell->GetCode();
426 bool checkFormula(ScDocument& rDoc, const ScAddress& rPos, const char* pExpected)
428 ScTokenArray* pCode = getTokens(rDoc, rPos);
429 if (!pCode)
431 cerr << "Empty token array." << endl;
432 return false;
435 OUString aFormula = toString(rDoc, rPos, *pCode, rDoc.GetGrammar());
436 if (aFormula != OUString::createFromAscii(pExpected))
438 cerr << "Formula '" << pExpected << "' expected, but '" << aFormula << "' found" << endl;
439 return false;
442 return true;
445 bool checkFormulaPosition(ScDocument& rDoc, const ScAddress& rPos)
447 OUString aStr(rPos.Format(SCA_VALID));
448 const ScFormulaCell* pFC = rDoc.GetFormulaCell(rPos);
449 if (!pFC)
451 cerr << "Formula cell expected at " << aStr << " but not found." << endl;
452 return false;
455 if (pFC->aPos != rPos)
457 OUString aStr2(pFC->aPos.Format(SCA_VALID));
458 cerr << "Formula cell at " << aStr << " has incorrect position of " << aStr2 << endl;
459 return false;
462 return true;
465 bool checkFormulaPositions(
466 ScDocument& rDoc, SCTAB nTab, SCCOL nCol, const SCROW* pRows, size_t nRowCount)
468 ScAddress aPos(nCol, 0, nTab);
469 for (size_t i = 0; i < nRowCount; ++i)
471 SCROW nRow = pRows[i];
472 aPos.SetRow(nRow);
474 if (!checkFormulaPosition(rDoc, aPos))
476 OUString aStr(aPos.Format(SCA_VALID));
477 cerr << "Formula cell position failed at " << aStr << "." << endl;
478 return false;
481 return true;
484 ScTokenArray* compileFormula(
485 ScDocument* pDoc, const OUString& rFormula, const ScAddress* pPos,
486 formula::FormulaGrammar::Grammar eGram )
488 ScAddress aPos(0,0,0);
489 if (pPos)
490 aPos = *pPos;
491 ScCompiler aComp(pDoc, aPos);
492 aComp.SetGrammar(eGram);
493 return aComp.CompileString(rFormula);
496 void clearFormulaCellChangedFlag( ScDocument& rDoc, const ScRange& rRange )
498 const ScAddress& s = rRange.aStart;
499 const ScAddress& e = rRange.aEnd;
500 for (SCTAB nTab = s.Tab(); nTab <= e.Tab(); ++nTab)
502 for (SCCOL nCol = s.Col(); nCol <= e.Col(); ++nCol)
504 for (SCROW nRow = s.Row(); nRow <= e.Row(); ++nRow)
506 ScAddress aPos(nCol, nRow, nTab);
507 ScFormulaCell* pFC = rDoc.GetFormulaCell(aPos);
508 if (pFC)
509 pFC->SetChanged(false);
515 bool isFormulaWithoutError(ScDocument& rDoc, const ScAddress& rPos)
517 ScFormulaCell* pFC = rDoc.GetFormulaCell(rPos);
518 if (!pFC)
519 return false;
521 return pFC->GetErrCode() == 0;
524 OUString toString(
525 ScDocument& rDoc, const ScAddress& rPos, ScTokenArray& rArray, formula::FormulaGrammar::Grammar eGram)
527 ScCompiler aComp(&rDoc, rPos, rArray);
528 aComp.SetGrammar(eGram);
529 OUStringBuffer aBuf;
530 aComp.CreateStringFromTokenArray(aBuf);
531 return aBuf.makeStringAndClear();
534 ScDocShellRef ScBootstrapFixture::load( bool bReadWrite,
535 const OUString& rURL, const OUString& rFilter, const OUString &rUserData,
536 const OUString& rTypeName, SfxFilterFlags nFilterFlags, SotClipboardFormatId nClipboardID,
537 sal_uIntPtr nFilterVersion, const OUString* pPassword )
539 SfxFilter* pFilter = new SfxFilter(
540 rFilter,
541 OUString(), nFilterFlags, nClipboardID, rTypeName, 0, OUString(),
542 rUserData, OUString("private:factory/scalc*"));
543 pFilter->SetVersion(nFilterVersion);
545 ScDocShellRef xDocShRef = new ScDocShell;
546 xDocShRef->GetDocument().EnableUserInteraction(false);
547 SfxMedium* pSrcMed = new SfxMedium(rURL, bReadWrite ? STREAM_STD_READWRITE : STREAM_STD_READ );
548 pSrcMed->SetFilter(pFilter);
549 pSrcMed->UseInteractionHandler(false);
550 SfxItemSet* pSet = pSrcMed->GetItemSet();
551 if (pPassword)
553 pSet->Put(SfxStringItem(SID_PASSWORD, *pPassword));
555 pSet->Put(SfxUInt16Item(SID_MACROEXECMODE,::com::sun::star::document::MacroExecMode::ALWAYS_EXECUTE_NO_WARN));
556 SAL_INFO( "sc.qa", "about to load " << rURL );
557 if (!xDocShRef->DoLoad(pSrcMed))
559 xDocShRef->DoClose();
560 // load failed.
561 xDocShRef.Clear();
564 return xDocShRef;
567 ScDocShellRef ScBootstrapFixture::load(
568 const OUString& rURL, const OUString& rFilter, const OUString &rUserData,
569 const OUString& rTypeName, SfxFilterFlags nFilterFlags, SotClipboardFormatId nClipboardID,
570 sal_uIntPtr nFilterVersion, const OUString* pPassword )
572 return load( false, rURL, rFilter, rUserData, rTypeName, nFilterFlags, nClipboardID, nFilterVersion, pPassword );
575 ScDocShellRef ScBootstrapFixture::loadDoc(
576 const OUString& rFileName, sal_Int32 nFormat, bool bReadWrite )
578 OUString aFileExtension(aFileFormats[nFormat].pName, strlen(aFileFormats[nFormat].pName), RTL_TEXTENCODING_UTF8 );
579 OUString aFilterName(aFileFormats[nFormat].pFilterName, strlen(aFileFormats[nFormat].pFilterName), RTL_TEXTENCODING_UTF8) ;
580 OUString aFileName;
581 createFileURL( rFileName, aFileExtension, aFileName );
582 OUString aFilterType(aFileFormats[nFormat].pTypeName, strlen(aFileFormats[nFormat].pTypeName), RTL_TEXTENCODING_UTF8);
583 SfxFilterFlags nFormatType = aFileFormats[nFormat].nFormatType;
584 SotClipboardFormatId nClipboardId = SotClipboardFormatId::NONE;
585 if (nFormatType != SfxFilterFlags::NONE)
586 nClipboardId = SotClipboardFormatId::STARCALC_8;
588 return load(bReadWrite, aFileName, aFilterName, OUString(), aFilterType, nFormatType, nClipboardId, static_cast<sal_uIntPtr>(nFormatType));
591 ScBootstrapFixture::ScBootstrapFixture( const OUString& rsBaseString ) : m_aBaseString( rsBaseString ) {}
592 ScBootstrapFixture::~ScBootstrapFixture() {}
594 void ScBootstrapFixture::createFileURL(
595 const OUString& aFileBase, const OUString& aFileExtension, OUString& rFilePath)
597 OUString aSep("/");
598 OUStringBuffer aBuffer( getSrcRootURL() );
599 aBuffer.append(m_aBaseString).append(aSep).append(aFileExtension);
600 aBuffer.append(aSep).append(aFileBase).append(aFileExtension);
601 rFilePath = aBuffer.makeStringAndClear();
604 void ScBootstrapFixture::createCSVPath(const OUString& aFileBase, OUString& rCSVPath)
606 OUStringBuffer aBuffer( getSrcRootPath());
607 aBuffer.append(m_aBaseString).append("/contentCSV/");
608 aBuffer.append(aFileBase).append("csv");
609 rCSVPath = aBuffer.makeStringAndClear();
612 ScDocShellRef ScBootstrapFixture::saveAndReload(
613 ScDocShell* pShell, const OUString &rFilter,
614 const OUString &rUserData, const OUString& rTypeName, SfxFilterFlags nFormatType)
617 utl::TempFile aTempFile;
618 SfxMedium aStoreMedium( aTempFile.GetURL(), STREAM_STD_WRITE );
619 SotClipboardFormatId nExportFormat = SotClipboardFormatId::NONE;
620 if (nFormatType == ODS_FORMAT_TYPE)
621 nExportFormat = SotClipboardFormatId::STARCHART_8;
622 SfxFilter* pExportFilter = new SfxFilter(
623 rFilter,
624 OUString(), nFormatType, nExportFormat, rTypeName, 0, OUString(),
625 rUserData, OUString("private:factory/scalc*") );
626 pExportFilter->SetVersion(SOFFICE_FILEFORMAT_CURRENT);
627 aStoreMedium.SetFilter(pExportFilter);
628 pShell->DoSaveAs( aStoreMedium );
629 pShell->DoClose();
631 //std::cout << "File: " << aTempFile.GetURL() << std::endl;
633 SotClipboardFormatId nFormat = SotClipboardFormatId::NONE;
634 if (nFormatType == ODS_FORMAT_TYPE)
635 nFormat = SotClipboardFormatId::STARCALC_8;
637 ScDocShellRef xDocSh = load(aTempFile.GetURL(), rFilter, rUserData, rTypeName, nFormatType, nFormat );
638 if(nFormatType == XLSX_FORMAT_TYPE)
639 validate(aTempFile.GetFileName(), test::OOXML);
640 else if (nFormatType == ODS_FORMAT_TYPE)
641 validate(aTempFile.GetFileName(), test::ODF);
642 aTempFile.EnableKillingFile();
643 return xDocSh;
646 ScDocShellRef ScBootstrapFixture::saveAndReload( ScDocShell* pShell, sal_Int32 nFormat )
648 OUString aFilterName(aFileFormats[nFormat].pFilterName, strlen(aFileFormats[nFormat].pFilterName), RTL_TEXTENCODING_UTF8) ;
649 OUString aFilterType(aFileFormats[nFormat].pTypeName, strlen(aFileFormats[nFormat].pTypeName), RTL_TEXTENCODING_UTF8);
650 ScDocShellRef xDocSh = saveAndReload(pShell, aFilterName, OUString(), aFilterType, aFileFormats[nFormat].nFormatType);
652 CPPUNIT_ASSERT(xDocSh.Is());
653 return xDocSh;
656 boost::shared_ptr<utl::TempFile> ScBootstrapFixture::exportTo( ScDocShell* pShell, sal_Int32 nFormat )
658 OUString aFilterName(aFileFormats[nFormat].pFilterName, strlen(aFileFormats[nFormat].pFilterName), RTL_TEXTENCODING_UTF8) ;
659 OUString aFilterType(aFileFormats[nFormat].pTypeName, strlen(aFileFormats[nFormat].pTypeName), RTL_TEXTENCODING_UTF8);
661 boost::shared_ptr<utl::TempFile> pTempFile(new utl::TempFile());
662 pTempFile->EnableKillingFile();
663 SfxMedium aStoreMedium( pTempFile->GetURL(), STREAM_STD_WRITE );
664 SotClipboardFormatId nExportFormat = SotClipboardFormatId::NONE;
665 SfxFilterFlags nFormatType = aFileFormats[nFormat].nFormatType;
666 if (nFormatType == ODS_FORMAT_TYPE)
667 nExportFormat = SotClipboardFormatId::STARCHART_8;
668 SfxFilter* pExportFilter = new SfxFilter(
669 aFilterName,
670 OUString(), nFormatType, nExportFormat, aFilterType, 0, OUString(),
671 OUString(), OUString("private:factory/scalc*") );
672 pExportFilter->SetVersion(SOFFICE_FILEFORMAT_CURRENT);
673 aStoreMedium.SetFilter(pExportFilter);
674 pShell->DoSaveAs( aStoreMedium );
675 pShell->DoClose();
677 if(nFormatType == XLSX_FORMAT_TYPE)
678 validate(pTempFile->GetFileName(), test::OOXML);
679 else if (nFormatType == ODS_FORMAT_TYPE)
680 validate(pTempFile->GetFileName(), test::ODF);
682 return pTempFile;
685 void ScBootstrapFixture::miscRowHeightsTest( TestParam* aTestValues, unsigned int numElems )
687 for ( unsigned int index=0; index<numElems; ++index )
689 OUString sFileName = OUString::createFromAscii( aTestValues[ index ].sTestDoc );
690 SAL_INFO( "sc.qa", "aTestValues[" << index << "] " << sFileName );
691 int nImportType = aTestValues[ index ].nImportType;
692 int nExportType = aTestValues[ index ].nExportType;
693 ScDocShellRef xShell = loadDoc( sFileName, nImportType );
694 CPPUNIT_ASSERT(xShell.Is());
696 if ( nExportType != -1 )
697 xShell = saveAndReload(&(*xShell), nExportType );
699 CPPUNIT_ASSERT(xShell.Is());
701 ScDocument& rDoc = xShell->GetDocument();
703 for (int i=0; i<aTestValues[ index ].nRowData; ++i)
705 SCROW nRow = aTestValues[ index ].pData[ i].nStartRow;
706 SCROW nEndRow = aTestValues[ index ].pData[ i ].nEndRow;
707 SCTAB nTab = aTestValues[ index ].pData[ i ].nTab;
708 int nExpectedHeight = aTestValues[ index ].pData[ i ].nExpectedHeight;
709 if ( nExpectedHeight == -1 )
710 nExpectedHeight = sc::TwipsToHMM( ScGlobal::GetStandardRowHeight() );
711 bool bCheckOpt = ( ( aTestValues[ index ].pData[ i ].nCheck & CHECK_OPTIMAL ) == CHECK_OPTIMAL );
712 for ( ; nRow <= nEndRow; ++nRow )
714 SAL_INFO( "sc.qa", " checking row " << nRow << " for height " << nExpectedHeight );
715 int nHeight = sc::TwipsToHMM( rDoc.GetRowHeight(nRow, nTab, false) );
716 if ( bCheckOpt )
718 bool bOpt = !(rDoc.GetRowFlags( nRow, nTab ) & CR_MANUALSIZE);
719 CPPUNIT_ASSERT_EQUAL(aTestValues[ index ].pData[ i ].bOptimal, bOpt);
721 CPPUNIT_ASSERT_EQUAL(nExpectedHeight, nHeight);
724 xShell->DoClose();
728 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */