1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/.
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>
26 #define __ORCUS_STATIC_LIB
28 #include <orcus/csv_parser.hpp>
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";
49 std::ostream
& operator<<(std::ostream
& rStrm
, const ScRange
& rRange
)
51 rStrm
<< "ScRange: " << rRange
.aStart
<< rRange
.aEnd
<< "\n";
55 std::ostream
& operator<<(std::ostream
& rStrm
, const ScRangeList
& rList
)
57 rStrm
<< "ScRangeList: \n";
58 for(size_t i
= 0; i
< rList
.size(); ++i
)
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();
69 std::ostream
& operator<<(std::ostream
& rStrm
, const OpCode
& rCode
)
71 rStrm
<< static_cast<sal_uInt16
>(rCode
);
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
);
99 if (strncmp(aOFileName
.getStr(), "/assets/", sizeof("/assets/")-1) == 0) {
100 const char *contents
= (const char *) lo_apkentry(aOFileName
.getStr(), &size
);
102 aContent
= std::string(contents
, size
);
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();
116 aContent
= aOStream
.str();
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
);
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
);
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);
171 void testFile(OUString
&, ScDocument
&, SCTAB
, StringType
) {}
172 void testCondFile(OUString
&, ScDocument
*, SCTAB
) {}
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
187 const ScPatternAttr
* pPattern
= NULL
;
188 pPattern
= pDoc
->GetPattern(0,0,1);
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
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
);
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 );
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
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();
298 cout
<< "Failed to retrieve the drawing layer object." << endl
;
302 const SdrPage
* pPage
= pDrawLayer
->GetPage(nPage
);
305 cout
<< "Failed to retrieve the page object." << endl
;
309 if (pPage
->GetObjCount() != 1)
311 cout
<< "This page should contain one drawing object." << endl
;
315 const SdrObject
* pObj
= pPage
->GetObj(0);
318 cout
<< "Failed to retrieve the drawing object." << endl
;
322 if (pObj
->GetObjIdentifier() != OBJ_OLE2
)
324 cout
<< "This is not an OLE2 object." << endl
;
328 const SdrOle2Obj
& rOleObj
= static_cast<const SdrOle2Obj
&>(*pObj
);
329 if (!rOleObj
.IsChart())
331 cout
<< "This should be a chart object." << endl
;
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();
346 cout
<< "Failed to get the embedded object interface." << endl
;
350 Reference
<chart2::XChartDocument
> xChartDoc(xModel
, UNO_QUERY
);
353 cout
<< "Failed to get the chart document interface." << endl
;
357 Reference
<chart2::data::XDataSource
> xDataSource(xChartDoc
, UNO_QUERY
);
358 if (!xDataSource
.is())
360 cout
<< "Failed to get the data source interface." << endl
;
364 Sequence
<Reference
<chart2::data::XLabeledDataSequence
> > xDataSeqs
= xDataSource
->getDataSequences();
365 if (!xDataSeqs
.getLength())
367 cout
<< "There should be at least one data sequences." << endl
;
371 Reference
<chart2::data::XDataReceiver
> xDataRec(xChartDoc
, UNO_QUERY
);
374 cout
<< "Failed to get the data receiver interface." << endl
;
378 Sequence
<OUString
> aRangeRepSeqs
= xDataRec
->getUsedRangeRepresentations();
379 for (sal_Int32 i
= 0, n
= aRangeRepSeqs
.getLength(); i
< n
; ++i
)
380 aRangeReps
.push_back(aRangeRepSeqs
[i
]);
385 ScRangeList
getChartRanges(ScDocument
& rDoc
, const SdrOle2Obj
& rChartObj
)
387 std::vector
<OUString
> aRangeReps
= getChartRangeRepresentations(rChartObj
);
389 for (size_t i
= 0, n
= aRangeReps
.size(); i
< n
; ++i
)
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
);
398 // Parse it as a single cell address.
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
);
411 ScTokenArray
* getTokens(ScDocument
& rDoc
, const ScAddress
& rPos
)
413 ScFormulaCell
* pCell
= rDoc
.GetFormulaCell(rPos
);
416 OUString aStr
= rPos
.Format(SCA_VALID
);
417 cerr
<< aStr
<< " is not a formula cell." << endl
;
421 return pCell
->GetCode();
426 bool checkFormula(ScDocument
& rDoc
, const ScAddress
& rPos
, const char* pExpected
)
428 ScTokenArray
* pCode
= getTokens(rDoc
, rPos
);
431 cerr
<< "Empty token array." << endl
;
435 OUString aFormula
= toString(rDoc
, rPos
, *pCode
, rDoc
.GetGrammar());
436 if (aFormula
!= OUString::createFromAscii(pExpected
))
438 cerr
<< "Formula '" << pExpected
<< "' expected, but '" << aFormula
<< "' found" << endl
;
445 bool checkFormulaPosition(ScDocument
& rDoc
, const ScAddress
& rPos
)
447 OUString
aStr(rPos
.Format(SCA_VALID
));
448 const ScFormulaCell
* pFC
= rDoc
.GetFormulaCell(rPos
);
451 cerr
<< "Formula cell expected at " << aStr
<< " but not found." << endl
;
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
;
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
];
474 if (!checkFormulaPosition(rDoc
, aPos
))
476 OUString
aStr(aPos
.Format(SCA_VALID
));
477 cerr
<< "Formula cell position failed at " << aStr
<< "." << endl
;
484 ScTokenArray
* compileFormula(
485 ScDocument
* pDoc
, const OUString
& rFormula
, const ScAddress
* pPos
,
486 formula::FormulaGrammar::Grammar eGram
)
488 ScAddress
aPos(0,0,0);
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
);
509 pFC
->SetChanged(false);
515 bool isFormulaWithoutError(ScDocument
& rDoc
, const ScAddress
& rPos
)
517 ScFormulaCell
* pFC
= rDoc
.GetFormulaCell(rPos
);
521 return pFC
->GetErrCode() == 0;
525 ScDocument
& rDoc
, const ScAddress
& rPos
, ScTokenArray
& rArray
, formula::FormulaGrammar::Grammar eGram
)
527 ScCompiler
aComp(&rDoc
, rPos
, rArray
);
528 aComp
.SetGrammar(eGram
);
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(
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();
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();
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
) ;
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
)
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(
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
);
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();
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());
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(
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
);
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
);
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) );
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
);
728 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */