LCOV - code coverage report
Current view: top level - sc/qa/unit/helper - qahelper.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 318 408 77.9 %
Date: 2015-06-13 12:38:46 Functions: 29 36 80.6 %
Legend: Lines: hit not hit

          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 "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>
      21             : 
      22             : #include <config_orcus.h>
      23             : 
      24             : #if ENABLE_ORCUS
      25             : #if defined WNT
      26             : #define __ORCUS_STATIC_LIB
      27             : #endif
      28             : #include <orcus/csv_parser.hpp>
      29             : #endif
      30             : 
      31             : #include <fstream>
      32             : 
      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>
      38             : 
      39             : using namespace com::sun::star;
      40             : using namespace ::com::sun::star::uno;
      41             : 
      42             : // calc data structure pretty printer
      43           0 : std::ostream& operator<<(std::ostream& rStrm, const ScAddress& rAddr)
      44             : {
      45           0 :     rStrm << "Col: " << rAddr.Col() << " Row: " << rAddr.Row() << " Tab: " << rAddr.Tab() << "\n";
      46           0 :     return rStrm;
      47             : }
      48             : 
      49           0 : std::ostream& operator<<(std::ostream& rStrm, const ScRange& rRange)
      50             : {
      51           0 :     rStrm << "ScRange: " << rRange.aStart << rRange.aEnd << "\n";
      52           0 :     return rStrm;
      53             : }
      54             : 
      55           0 : std::ostream& operator<<(std::ostream& rStrm, const ScRangeList& rList)
      56             : {
      57           0 :     rStrm << "ScRangeList: \n";
      58           0 :     for(size_t i = 0; i < rList.size(); ++i)
      59           0 :         rStrm << *rList[i];
      60           0 :     return rStrm;
      61             : }
      62             : 
      63           0 : std::ostream& operator<<(std::ostream& rStrm, const Color& rColor)
      64             : {
      65           0 :     rStrm << "Color: R:" << (int)rColor.GetRed() << " G:" << (int)rColor.GetGreen() << " B: " << (int)rColor.GetBlue();
      66           0 :     return rStrm;
      67             : }
      68             : 
      69           0 : std::ostream& operator<<(std::ostream& rStrm, const OpCode& rCode)
      70             : {
      71           0 :     rStrm << static_cast<sal_uInt16>(rCode);
      72           0 :     return rStrm;
      73             : }
      74             : 
      75             : const FileFormat ScBootstrapFixture::aFileFormats[] = {
      76          20 :     { "ods" , "calc8", "", ODS_FORMAT_TYPE },
      77          20 :     { "xls" , "MS Excel 97", "calc_MS_EXCEL_97", XLS_FORMAT_TYPE },
      78          20 :     { "xlsx", "Calc Office Open XML" , "Office Open XML Spreadsheet", XLSX_FORMAT_TYPE },
      79          20 :     { "xlsm", "Calc Office Open XML" , "Office Open XML Spreadsheet", XLSX_FORMAT_TYPE },
      80          20 :     { "csv" , "Text - txt - csv (StarCalc)", "generic_Text", CSV_FORMAT_TYPE },
      81          20 :     { "html" , "calc_HTML_WebQuery", "generic_HTML", HTML_FORMAT_TYPE },
      82          20 :     { "123" , "Lotus", "calc_Lotus", LOTUS123_FORMAT_TYPE },
      83          20 :     { "dif", "DIF", "calc_DIF", DIF_FORMAT_TYPE },
      84          20 :     { "xml", "MS Excel 2003 XML", "calc_MS_Excel_2003_XML", XLS_XML_FORMAT_TYPE },
      85          20 :     { "xlsb", "Calc MS Excel 2007 Binary", "MS Excel 2007 Binary", XLSB_XML_FORMAT_TYPE }
      86         100 : };
      87             : 
      88          26 : bool testEqualsWithTolerance( long nVal1, long nVal2, long nTol )
      89             : {
      90          26 :     return ( labs( nVal1 - nVal2 ) <= nTol );
      91             : }
      92             : 
      93          41 : void loadFile(const OUString& aFileName, std::string& aContent)
      94             : {
      95          41 :     OString aOFileName = OUStringToOString(aFileName, RTL_TEXTENCODING_UTF8);
      96             : 
      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;
     104             :         }
     105             :     }
     106             : #endif
     107             : 
     108          82 :     std::ifstream aFile(aOFileName.getStr());
     109             : 
     110          82 :     OStringBuffer aErrorMsg("Could not open csv file: ");
     111          41 :     aErrorMsg.append(aOFileName);
     112          41 :     CPPUNIT_ASSERT_MESSAGE(aErrorMsg.getStr(), aFile);
     113          82 :     std::ostringstream aOStream;
     114          41 :     aOStream << aFile.rdbuf();
     115          41 :     aFile.close();
     116          82 :     aContent = aOStream.str();
     117          41 : }
     118             : 
     119             : #if ENABLE_ORCUS
     120             : 
     121          34 : void testFile(OUString& aFileName, ScDocument& rDoc, SCTAB nTab, StringType aStringFormat)
     122             : {
     123          34 :     csv_handler aHandler(&rDoc, nTab, aStringFormat);
     124          34 :     orcus::csv::parser_config aConfig;
     125          34 :     aConfig.delimiters.push_back(',');
     126          34 :     aConfig.delimiters.push_back(';');
     127          34 :     aConfig.text_qualifier = '"';
     128          34 :     aConfig.trim_cell_value = false;
     129             : 
     130          68 :     std::string aContent;
     131          34 :     loadFile(aFileName, aContent);
     132          68 :     orcus::csv_parser<csv_handler> parser ( &aContent[0], aContent.size() , aHandler, aConfig);
     133             :     try
     134             :     {
     135          34 :         parser.parse();
     136             :     }
     137           0 :     catch (const orcus::csv::parse_error& e)
     138             :     {
     139           0 :         std::cout << "reading csv content file failed: " << e.what() << std::endl;
     140           0 :         OStringBuffer aErrorMsg("csv parser error: ");
     141           0 :         aErrorMsg.append(e.what());
     142           0 :         CPPUNIT_ASSERT_MESSAGE(aErrorMsg.getStr(), false);
     143          34 :     }
     144          33 : }
     145             : 
     146           7 : void testCondFile(OUString& aFileName, ScDocument* pDoc, SCTAB nTab)
     147             : {
     148           7 :     conditional_format_handler aHandler(pDoc, nTab);
     149           7 :     orcus::csv::parser_config aConfig;
     150           7 :     aConfig.delimiters.push_back(',');
     151           7 :     aConfig.delimiters.push_back(';');
     152           7 :     aConfig.text_qualifier = '"';
     153          14 :     std::string aContent;
     154           7 :     loadFile(aFileName, aContent);
     155          14 :     orcus::csv_parser<conditional_format_handler> parser ( &aContent[0], aContent.size() , aHandler, aConfig);
     156             :     try
     157             :     {
     158           7 :         parser.parse();
     159             :     }
     160           0 :     catch (const orcus::csv::parse_error& e)
     161             :     {
     162           0 :         std::cout << "reading csv content file failed: " << e.what() << std::endl;
     163           0 :         OStringBuffer aErrorMsg("csv parser error: ");
     164           0 :         aErrorMsg.append(e.what());
     165           0 :         CPPUNIT_ASSERT_MESSAGE(aErrorMsg.getStr(), false);
     166           7 :     }
     167           7 : }
     168             : 
     169             : #else
     170             : 
     171             : void testFile(OUString&, ScDocument&, SCTAB, StringType) {}
     172             : void testCondFile(OUString&, ScDocument*, SCTAB) {}
     173             : 
     174             : #endif
     175             : 
     176           2 : void testFormats(ScBootstrapFixture* pTest, ScDocument* pDoc, sal_Int32 nFormat)
     177             : {
     178             :     //test Sheet1 with csv file
     179           2 :     OUString aCSVFileName;
     180           2 :     pTest->createCSVPath(OUString("numberFormat."), aCSVFileName);
     181           2 :     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
     185             : 
     186             :     //test Sheet2
     187           2 :     const ScPatternAttr* pPattern = NULL;
     188           2 :     pPattern = pDoc->GetPattern(0,0,1);
     189           4 :     vcl::Font aFont;
     190           2 :     pPattern->GetFont(aFont,SC_AUTOCOL_RAW);
     191           2 :     CPPUNIT_ASSERT_EQUAL_MESSAGE("font size should be 10", 200l, aFont.GetSize().getHeight());
     192           2 :     CPPUNIT_ASSERT_EQUAL_MESSAGE("font color should be black", COL_AUTO, aFont.GetColor().GetColor());
     193           2 :     pPattern = pDoc->GetPattern(0,1,1);
     194           2 :     pPattern->GetFont(aFont, SC_AUTOCOL_RAW);
     195           2 :     CPPUNIT_ASSERT_EQUAL_MESSAGE("font size should be 12", 240l, aFont.GetSize().getHeight());
     196           2 :     pPattern = pDoc->GetPattern(0,2,1);
     197           2 :     pPattern->GetFont(aFont, SC_AUTOCOL_RAW);
     198           2 :     CPPUNIT_ASSERT_EQUAL_MESSAGE("font should be italic", ITALIC_NORMAL, aFont.GetItalic());
     199           2 :     pPattern = pDoc->GetPattern(0,4,1);
     200           2 :     pPattern->GetFont(aFont, SC_AUTOCOL_RAW);
     201           2 :     CPPUNIT_ASSERT_EQUAL_MESSAGE("font should be bold", WEIGHT_BOLD, aFont.GetWeight());
     202           2 :     pPattern = pDoc->GetPattern(1,0,1);
     203           2 :     pPattern->GetFont(aFont, SC_AUTOCOL_RAW);
     204           2 :     CPPUNIT_ASSERT_EQUAL_MESSAGE("font should be blue", COL_BLUE, aFont.GetColor().GetColor());
     205           2 :     pPattern = pDoc->GetPattern(1,1,1);
     206           2 :     pPattern->GetFont(aFont, SC_AUTOCOL_RAW);
     207           2 :     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           2 :     if (nFormat == ODS)
     210             :     {
     211           2 :         pPattern = pDoc->GetPattern(1,2,1);
     212           2 :         pPattern->GetFont(aFont, SC_AUTOCOL_RAW);
     213           2 :         CPPUNIT_ASSERT_EQUAL_MESSAGE("font should be striked out with a double line", STRIKEOUT_DOUBLE, aFont.GetStrikeout());
     214           2 :         pPattern = pDoc->GetPattern(1,3,1);
     215           2 :         pPattern->GetFont(aFont, SC_AUTOCOL_RAW);
     216           2 :         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           2 :         CPPUNIT_ASSERT_EQUAL( static_cast<sal_uInt16>(555), pDoc->GetColWidth(4,1) );  //0.3854in
     224           2 :         CPPUNIT_ASSERT_EQUAL( static_cast<sal_uInt16>(1280), pDoc->GetColWidth(5,1) ); //0.889in
     225           2 :         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           2 :         OUString aTestStr = pDoc->GetString(3,0,1);
     228           4 :         OUString aKnownGoodStr("text14 space");
     229           2 :         CPPUNIT_ASSERT_EQUAL( aKnownGoodStr, aTestStr );
     230             :         //test case for cell text with line breaks.
     231           2 :         aTestStr = pDoc->GetString(3,5,1);
     232           2 :         aKnownGoodStr = "Hello,\nCalc!";
     233           4 :         CPPUNIT_ASSERT_EQUAL( aKnownGoodStr, aTestStr );
     234             :     }
     235           2 :     pPattern = pDoc->GetPattern(1,4,1);
     236           2 :     Color aColor = static_cast<const SvxBrushItem&>(pPattern->GetItem(ATTR_BACKGROUND)).GetColor();
     237           2 :     CPPUNIT_ASSERT_MESSAGE("background color should be green", aColor == COL_LIGHTGREEN);
     238           2 :     pPattern = pDoc->GetPattern(2,0,1);
     239           2 :     SvxCellHorJustify eHorJustify = static_cast<SvxCellHorJustify>(static_cast<const SvxHorJustifyItem&>(pPattern->GetItem(ATTR_HOR_JUSTIFY)).GetValue());
     240           2 :     CPPUNIT_ASSERT_EQUAL_MESSAGE("cell content should be aligned centre horizontally", SVX_HOR_JUSTIFY_CENTER, eHorJustify);
     241             :     //test alignment
     242           2 :     pPattern = pDoc->GetPattern(2,1,1);
     243           2 :     eHorJustify = static_cast<SvxCellHorJustify>(static_cast<const SvxHorJustifyItem&>(pPattern->GetItem(ATTR_HOR_JUSTIFY)).GetValue());
     244           2 :     CPPUNIT_ASSERT_EQUAL_MESSAGE("cell content should be aligned right horizontally", SVX_HOR_JUSTIFY_RIGHT, eHorJustify);
     245           2 :     pPattern = pDoc->GetPattern(2,2,1);
     246           2 :     eHorJustify = static_cast<SvxCellHorJustify>(static_cast<const SvxHorJustifyItem&>(pPattern->GetItem(ATTR_HOR_JUSTIFY)).GetValue());
     247           2 :     CPPUNIT_ASSERT_EQUAL_MESSAGE("cell content should be aligned block horizontally", SVX_HOR_JUSTIFY_BLOCK, eHorJustify);
     248             : 
     249             :     //test Sheet3 only for ods and xlsx
     250           2 :     if ( nFormat == ODS || nFormat == XLSX )
     251             :     {
     252           2 :         pTest->createCSVPath(OUString("conditionalFormatting."), aCSVFileName);
     253           2 :         testCondFile(aCSVFileName, pDoc, 2);
     254             :         // test parent cell style import ( fdo#55198 )
     255           2 :         if ( nFormat == XLSX )
     256             :         {
     257           0 :             pPattern = pDoc->GetPattern(1,1,3);
     258           0 :             ScStyleSheet* pStyleSheet = const_cast<ScStyleSheet*>(pPattern->GetStyleSheet());
     259             :             // check parent style name
     260           0 :             OUString sExpected("Excel Built-in Date");
     261           0 :             OUString sResult = pStyleSheet->GetName();
     262           0 :             CPPUNIT_ASSERT_EQUAL_MESSAGE("parent style for Sheet4.B2 is 'Excel Built-in Date'", sExpected, sResult);
     263             :             // check  align of style
     264           0 :             SfxItemSet& rItemSet = pStyleSheet->GetItemSet();
     265           0 :             eHorJustify = static_cast<SvxCellHorJustify>(static_cast< const SvxHorJustifyItem& >(rItemSet.Get( ATTR_HOR_JUSTIFY ) ).GetValue() );
     266           0 :             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           0 :             sResult =pDoc->GetString( 1,1,3 );
     269           0 :             sExpected = "29";
     270           0 :             CPPUNIT_ASSERT_EQUAL_MESSAGE("'Excel Built-in Date' style should just display month", sExpected, sResult );
     271             : 
     272             :             // check actual align applied to cell, should be the same as
     273             :             // the style
     274           0 :             eHorJustify = static_cast<SvxCellHorJustify>(static_cast< const SvxHorJustifyItem& >(pPattern->GetItem( ATTR_HOR_JUSTIFY ) ).GetValue() );
     275           0 :             CPPUNIT_ASSERT_EQUAL_MESSAGE("cell with 'Excel Built-in Date' style should be aligned centre horizontally", SVX_HOR_JUSTIFY_CENTER, eHorJustify);
     276             :         }
     277             :     }
     278             : 
     279           2 :     ScConditionalFormat* pCondFormat = pDoc->GetCondFormat(0,0,2);
     280           2 :     const ScRangeList& rRange = pCondFormat->GetRange();
     281           2 :     CPPUNIT_ASSERT(rRange == ScRange(0,0,2,3,0,2));
     282             : 
     283           2 :     pCondFormat = pDoc->GetCondFormat(0,1,2);
     284           2 :     const ScRangeList& rRange2 = pCondFormat->GetRange();
     285           2 :     CPPUNIT_ASSERT(rRange2 == ScRange(0,1,2,0,1,2));
     286             : 
     287           2 :     pCondFormat = pDoc->GetCondFormat(1,1,2);
     288           2 :     const ScRangeList& rRange3 = pCondFormat->GetRange();
     289           4 :     CPPUNIT_ASSERT(rRange3 == ScRange(1,1,2,3,1,2));
     290           2 : }
     291             : 
     292           3 : const SdrOle2Obj* getSingleChartObject(ScDocument& rDoc, sal_uInt16 nPage)
     293             : {
     294             :     // Retrieve the chart object instance from the 2nd page (for the 2nd sheet).
     295           3 :     ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer();
     296           3 :     if (!pDrawLayer)
     297             :     {
     298           0 :         cout << "Failed to retrieve the drawing layer object." << endl;
     299           0 :         return NULL;
     300             :     }
     301             : 
     302           3 :     const SdrPage* pPage = pDrawLayer->GetPage(nPage);
     303           3 :     if (!pPage)
     304             :     {
     305           0 :         cout << "Failed to retrieve the page object." << endl;
     306           0 :         return NULL;
     307             :     }
     308             : 
     309           3 :     if (pPage->GetObjCount() != 1)
     310             :     {
     311           0 :         cout << "This page should contain one drawing object." << endl;
     312           0 :         return NULL;
     313             :     }
     314             : 
     315           3 :     const SdrObject* pObj = pPage->GetObj(0);
     316           3 :     if (!pObj)
     317             :     {
     318           0 :         cout << "Failed to retrieve the drawing object." << endl;
     319           0 :         return NULL;
     320             :     }
     321             : 
     322           3 :     if (pObj->GetObjIdentifier() != OBJ_OLE2)
     323             :     {
     324           0 :         cout << "This is not an OLE2 object." << endl;
     325           0 :         return NULL;
     326             :     }
     327             : 
     328           3 :     const SdrOle2Obj& rOleObj = static_cast<const SdrOle2Obj&>(*pObj);
     329           3 :     if (!rOleObj.IsChart())
     330             :     {
     331           0 :         cout << "This should be a chart object." << endl;
     332           0 :         return NULL;
     333             :     }
     334             : 
     335           3 :     return &rOleObj;
     336             : }
     337             : 
     338           2 : std::vector<OUString> getChartRangeRepresentations(const SdrOle2Obj& rChartObj)
     339             : {
     340           2 :     std::vector<OUString> aRangeReps;
     341             : 
     342             :     // Make sure the chart object has correct range references.
     343           4 :     Reference<frame::XModel> xModel = rChartObj.getXModel();
     344           2 :     if (!xModel.is())
     345             :     {
     346           0 :         cout << "Failed to get the embedded object interface." << endl;
     347           0 :         return aRangeReps;
     348             :     }
     349             : 
     350           4 :     Reference<chart2::XChartDocument> xChartDoc(xModel, UNO_QUERY);
     351           2 :     if (!xChartDoc.is())
     352             :     {
     353           0 :         cout << "Failed to get the chart document interface." << endl;
     354           0 :         return aRangeReps;
     355             :     }
     356             : 
     357           4 :     Reference<chart2::data::XDataSource> xDataSource(xChartDoc, UNO_QUERY);
     358           2 :     if (!xDataSource.is())
     359             :     {
     360           0 :         cout << "Failed to get the data source interface." << endl;
     361           0 :         return aRangeReps;
     362             :     }
     363             : 
     364           4 :     Sequence<Reference<chart2::data::XLabeledDataSequence> > xDataSeqs = xDataSource->getDataSequences();
     365           2 :     if (!xDataSeqs.getLength())
     366             :     {
     367           0 :         cout << "There should be at least one data sequences." << endl;
     368           0 :         return aRangeReps;
     369             :     }
     370             : 
     371           4 :     Reference<chart2::data::XDataReceiver> xDataRec(xChartDoc, UNO_QUERY);
     372           2 :     if (!xDataRec.is())
     373             :     {
     374           0 :         cout << "Failed to get the data receiver interface." << endl;
     375           0 :         return aRangeReps;
     376             :     }
     377             : 
     378           4 :     Sequence<OUString> aRangeRepSeqs = xDataRec->getUsedRangeRepresentations();
     379           8 :     for (sal_Int32 i = 0, n = aRangeRepSeqs.getLength(); i < n; ++i)
     380           6 :         aRangeReps.push_back(aRangeRepSeqs[i]);
     381             : 
     382           2 :     return aRangeReps;
     383             : }
     384             : 
     385           2 : ScRangeList getChartRanges(ScDocument& rDoc, const SdrOle2Obj& rChartObj)
     386             : {
     387           2 :     std::vector<OUString> aRangeReps = getChartRangeRepresentations(rChartObj);
     388           2 :     ScRangeList aRanges;
     389           8 :     for (size_t i = 0, n = aRangeReps.size(); i < n; ++i)
     390             :     {
     391           6 :         ScRange aRange;
     392           6 :         sal_uInt16 nRes = aRange.Parse(aRangeReps[i], &rDoc, rDoc.GetAddressConvention());
     393           6 :         if (nRes & SCA_VALID)
     394             :             // This is a range address.
     395           4 :             aRanges.Append(aRange);
     396             :         else
     397             :         {
     398             :             // Parse it as a single cell address.
     399           2 :             ScAddress aAddr;
     400           2 :             nRes = aAddr.Parse(aRangeReps[i], &rDoc, rDoc.GetAddressConvention());
     401           2 :             CPPUNIT_ASSERT_MESSAGE("Failed to parse a range representation.", (nRes & SCA_VALID));
     402           2 :             aRanges.Append(aAddr);
     403             :         }
     404             :     }
     405             : 
     406           2 :     return aRanges;
     407             : }
     408             : 
     409             : namespace {
     410             : 
     411         454 : ScTokenArray* getTokens(ScDocument& rDoc, const ScAddress& rPos)
     412             : {
     413         454 :     ScFormulaCell* pCell = rDoc.GetFormulaCell(rPos);
     414         454 :     if (!pCell)
     415             :     {
     416           0 :         OUString aStr = rPos.Format(SCA_VALID);
     417           0 :         cerr << aStr << " is not a formula cell." << endl;
     418           0 :         return NULL;
     419             :     }
     420             : 
     421         454 :     return pCell->GetCode();
     422             : }
     423             : 
     424             : }
     425             : 
     426         454 : bool checkFormula(ScDocument& rDoc, const ScAddress& rPos, const char* pExpected)
     427             : {
     428         454 :     ScTokenArray* pCode = getTokens(rDoc, rPos);
     429         454 :     if (!pCode)
     430             :     {
     431           0 :         cerr << "Empty token array." << endl;
     432           0 :         return false;
     433             :     }
     434             : 
     435         454 :     OUString aFormula = toString(rDoc, rPos, *pCode, rDoc.GetGrammar());
     436         454 :     if (aFormula != OUString::createFromAscii(pExpected))
     437             :     {
     438           0 :         cerr << "Formula '" << pExpected << "' expected, but '" << aFormula << "' found" << endl;
     439           0 :         return false;
     440             :     }
     441             : 
     442         454 :     return true;
     443             : }
     444             : 
     445           6 : bool checkFormulaPosition(ScDocument& rDoc, const ScAddress& rPos)
     446             : {
     447           6 :     OUString aStr(rPos.Format(SCA_VALID));
     448           6 :     const ScFormulaCell* pFC = rDoc.GetFormulaCell(rPos);
     449           6 :     if (!pFC)
     450             :     {
     451           0 :         cerr << "Formula cell expected at " << aStr << " but not found." << endl;
     452           0 :         return false;
     453             :     }
     454             : 
     455           6 :     if (pFC->aPos != rPos)
     456             :     {
     457           0 :         OUString aStr2(pFC->aPos.Format(SCA_VALID));
     458           0 :         cerr << "Formula cell at " << aStr << " has incorrect position of " << aStr2 << endl;
     459           0 :         return false;
     460             :     }
     461             : 
     462           6 :     return true;
     463             : }
     464             : 
     465           2 : bool checkFormulaPositions(
     466             :     ScDocument& rDoc, SCTAB nTab, SCCOL nCol, const SCROW* pRows, size_t nRowCount)
     467             : {
     468           2 :     ScAddress aPos(nCol, 0, nTab);
     469           8 :     for (size_t i = 0; i < nRowCount; ++i)
     470             :     {
     471           6 :         SCROW nRow = pRows[i];
     472           6 :         aPos.SetRow(nRow);
     473             : 
     474           6 :         if (!checkFormulaPosition(rDoc, aPos))
     475             :         {
     476           0 :             OUString aStr(aPos.Format(SCA_VALID));
     477           0 :             cerr << "Formula cell position failed at " << aStr << "." << endl;
     478           0 :             return false;
     479             :         }
     480             :     }
     481           2 :     return true;
     482             : }
     483             : 
     484           5 : ScTokenArray* compileFormula(
     485             :     ScDocument* pDoc, const OUString& rFormula, const ScAddress* pPos,
     486             :     formula::FormulaGrammar::Grammar eGram )
     487             : {
     488           5 :     ScAddress aPos(0,0,0);
     489           5 :     if (pPos)
     490           0 :         aPos = *pPos;
     491           5 :     ScCompiler aComp(pDoc, aPos);
     492           5 :     aComp.SetGrammar(eGram);
     493           5 :     return aComp.CompileString(rFormula);
     494             : }
     495             : 
     496           0 : void clearFormulaCellChangedFlag( ScDocument& rDoc, const ScRange& rRange )
     497             : {
     498           0 :     const ScAddress& s = rRange.aStart;
     499           0 :     const ScAddress& e = rRange.aEnd;
     500           0 :     for (SCTAB nTab = s.Tab(); nTab <= e.Tab(); ++nTab)
     501             :     {
     502           0 :         for (SCCOL nCol = s.Col(); nCol <= e.Col(); ++nCol)
     503             :         {
     504           0 :             for (SCROW nRow = s.Row(); nRow <= e.Row(); ++nRow)
     505             :             {
     506           0 :                 ScAddress aPos(nCol, nRow, nTab);
     507           0 :                 ScFormulaCell* pFC = rDoc.GetFormulaCell(aPos);
     508           0 :                 if (pFC)
     509           0 :                     pFC->SetChanged(false);
     510             :             }
     511             :         }
     512             :     }
     513           0 : }
     514             : 
     515         228 : bool isFormulaWithoutError(ScDocument& rDoc, const ScAddress& rPos)
     516             : {
     517         228 :     ScFormulaCell* pFC = rDoc.GetFormulaCell(rPos);
     518         228 :     if (!pFC)
     519           0 :         return false;
     520             : 
     521         228 :     return pFC->GetErrCode() == 0;
     522             : }
     523             : 
     524         458 : OUString toString(
     525             :     ScDocument& rDoc, const ScAddress& rPos, ScTokenArray& rArray, formula::FormulaGrammar::Grammar eGram)
     526             : {
     527         458 :     ScCompiler aComp(&rDoc, rPos, rArray);
     528         458 :     aComp.SetGrammar(eGram);
     529         916 :     OUStringBuffer aBuf;
     530         458 :     aComp.CreateStringFromTokenArray(aBuf);
     531         916 :     return aBuf.makeStringAndClear();
     532             : }
     533             : 
     534         246 : 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 )
     538             : {
     539             :     SfxFilter* pFilter = new SfxFilter(
     540             :         rFilter,
     541             :         OUString(), nFilterFlags, nClipboardID, rTypeName, 0, OUString(),
     542         246 :         rUserData, OUString("private:factory/scalc*"));
     543         246 :     pFilter->SetVersion(nFilterVersion);
     544             : 
     545         246 :     ScDocShellRef xDocShRef = new ScDocShell;
     546         246 :     xDocShRef->GetDocument().EnableUserInteraction(false);
     547         246 :     SfxMedium* pSrcMed = new SfxMedium(rURL, bReadWrite ? STREAM_STD_READWRITE : STREAM_STD_READ );
     548         246 :     pSrcMed->SetFilter(pFilter);
     549         246 :     pSrcMed->UseInteractionHandler(false);
     550         246 :     SfxItemSet* pSet = pSrcMed->GetItemSet();
     551         246 :     if (pPassword)
     552             :     {
     553           1 :         pSet->Put(SfxStringItem(SID_PASSWORD, *pPassword));
     554             :     }
     555         246 :     pSet->Put(SfxUInt16Item(SID_MACROEXECMODE,::com::sun::star::document::MacroExecMode::ALWAYS_EXECUTE_NO_WARN));
     556             :     SAL_INFO( "sc.qa", "about to load " << rURL );
     557         246 :     if (!xDocShRef->DoLoad(pSrcMed))
     558             :     {
     559           4 :         xDocShRef->DoClose();
     560             :         // load failed.
     561           4 :         xDocShRef.Clear();
     562             :     }
     563             : 
     564         246 :     return xDocShRef;
     565             : }
     566             : 
     567          87 : 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 )
     571             : {
     572          87 :     return load( false, rURL, rFilter, rUserData, rTypeName, nFilterFlags, nClipboardID,  nFilterVersion, pPassword );
     573             : }
     574             : 
     575         159 : ScDocShellRef ScBootstrapFixture::loadDoc(
     576             :     const OUString& rFileName, sal_Int32 nFormat, bool bReadWrite )
     577             : {
     578         159 :     OUString aFileExtension(aFileFormats[nFormat].pName, strlen(aFileFormats[nFormat].pName), RTL_TEXTENCODING_UTF8 );
     579         318 :     OUString aFilterName(aFileFormats[nFormat].pFilterName, strlen(aFileFormats[nFormat].pFilterName), RTL_TEXTENCODING_UTF8) ;
     580         318 :     OUString aFileName;
     581         159 :     createFileURL( rFileName, aFileExtension, aFileName );
     582         318 :     OUString aFilterType(aFileFormats[nFormat].pTypeName, strlen(aFileFormats[nFormat].pTypeName), RTL_TEXTENCODING_UTF8);
     583         159 :     SfxFilterFlags nFormatType = aFileFormats[nFormat].nFormatType;
     584         159 :     SotClipboardFormatId nClipboardId = SotClipboardFormatId::NONE;
     585         159 :     if (nFormatType != SfxFilterFlags::NONE)
     586         159 :         nClipboardId = SotClipboardFormatId::STARCALC_8;
     587             : 
     588         318 :     return load(bReadWrite, aFileName, aFilterName, OUString(), aFilterType, nFormatType, nClipboardId, static_cast<sal_uIntPtr>(nFormatType));
     589             : }
     590             : 
     591         372 : ScBootstrapFixture::ScBootstrapFixture( const OUString& rsBaseString ) : m_aBaseString( rsBaseString ) {}
     592         372 : ScBootstrapFixture::~ScBootstrapFixture() {}
     593             : 
     594             : namespace {
     595         576 : OUString EnsureSeparator(const OUStringBuffer& rFilePath)
     596             : {
     597        1152 :     return (rFilePath.getLength() == 0) || (rFilePath[rFilePath.getLength() - 1] != '/') ?
     598             :         OUString("/") :
     599        1564 :         OUString("");
     600             : }
     601             : }
     602             : 
     603         164 : void ScBootstrapFixture::createFileURL(
     604             :     const OUString& aFileBase, const OUString& aFileExtension, OUString& rFilePath)
     605             : {
     606         164 :     OUStringBuffer aBuffer( getSrcRootURL() );
     607         164 :     aBuffer.append(EnsureSeparator(aBuffer)).append(m_aBaseString);
     608         164 :     aBuffer.append(EnsureSeparator(aBuffer)).append(aFileExtension);
     609         164 :     aBuffer.append(EnsureSeparator(aBuffer)).append(aFileBase).append(aFileExtension);
     610         164 :     rFilePath = aBuffer.makeStringAndClear();
     611         164 : }
     612             : 
     613          42 : void ScBootstrapFixture::createCSVPath(const OUString& aFileBase, OUString& rCSVPath)
     614             : {
     615          42 :     OUStringBuffer aBuffer( getSrcRootPath());
     616          42 :     aBuffer.append(EnsureSeparator(aBuffer)).append(m_aBaseString);
     617          42 :     aBuffer.append(EnsureSeparator(aBuffer)).append("contentCSV/").append(aFileBase).append("csv");
     618          42 :     rCSVPath = aBuffer.makeStringAndClear();
     619          42 : }
     620             : 
     621          59 : ScDocShellRef ScBootstrapFixture::saveAndReload(
     622             :     ScDocShell* pShell, const OUString &rFilter,
     623             :     const OUString &rUserData, const OUString& rTypeName, SfxFilterFlags nFormatType)
     624             : {
     625             : 
     626          59 :     utl::TempFile aTempFile;
     627         118 :     SfxMedium aStoreMedium( aTempFile.GetURL(), STREAM_STD_WRITE );
     628          59 :     SotClipboardFormatId nExportFormat = SotClipboardFormatId::NONE;
     629          59 :     if (nFormatType == ODS_FORMAT_TYPE)
     630          20 :         nExportFormat = SotClipboardFormatId::STARCHART_8;
     631             :     SfxFilter* pExportFilter = new SfxFilter(
     632             :         rFilter,
     633             :         OUString(), nFormatType, nExportFormat, rTypeName, 0, OUString(),
     634          59 :         rUserData, OUString("private:factory/scalc*") );
     635          59 :     pExportFilter->SetVersion(SOFFICE_FILEFORMAT_CURRENT);
     636          59 :     aStoreMedium.SetFilter(pExportFilter);
     637          59 :     pShell->DoSaveAs( aStoreMedium );
     638          59 :     pShell->DoClose();
     639             : 
     640             :     //std::cout << "File: " << aTempFile.GetURL() << std::endl;
     641             : 
     642          59 :     SotClipboardFormatId nFormat = SotClipboardFormatId::NONE;
     643          59 :     if (nFormatType == ODS_FORMAT_TYPE)
     644          20 :         nFormat = SotClipboardFormatId::STARCALC_8;
     645             : 
     646          59 :     ScDocShellRef xDocSh = load(aTempFile.GetURL(), rFilter, rUserData, rTypeName, nFormatType, nFormat );
     647          59 :     if(nFormatType == XLSX_FORMAT_TYPE)
     648          24 :         validate(aTempFile.GetFileName(), test::OOXML);
     649          35 :     else if (nFormatType == ODS_FORMAT_TYPE)
     650          20 :         validate(aTempFile.GetFileName(), test::ODF);
     651          59 :     aTempFile.EnableKillingFile();
     652         118 :     return xDocSh;
     653             : }
     654             : 
     655          59 : ScDocShellRef ScBootstrapFixture::saveAndReload( ScDocShell* pShell, sal_Int32 nFormat )
     656             : {
     657          59 :     OUString aFilterName(aFileFormats[nFormat].pFilterName, strlen(aFileFormats[nFormat].pFilterName), RTL_TEXTENCODING_UTF8) ;
     658         118 :     OUString aFilterType(aFileFormats[nFormat].pTypeName, strlen(aFileFormats[nFormat].pTypeName), RTL_TEXTENCODING_UTF8);
     659          59 :     ScDocShellRef xDocSh = saveAndReload(pShell, aFilterName, OUString(), aFilterType, aFileFormats[nFormat].nFormatType);
     660             : 
     661          59 :     CPPUNIT_ASSERT(xDocSh.Is());
     662         118 :     return xDocSh;
     663             : }
     664             : 
     665           9 : boost::shared_ptr<utl::TempFile> ScBootstrapFixture::exportTo( ScDocShell* pShell, sal_Int32 nFormat )
     666             : {
     667           9 :     OUString aFilterName(aFileFormats[nFormat].pFilterName, strlen(aFileFormats[nFormat].pFilterName), RTL_TEXTENCODING_UTF8) ;
     668          18 :     OUString aFilterType(aFileFormats[nFormat].pTypeName, strlen(aFileFormats[nFormat].pTypeName), RTL_TEXTENCODING_UTF8);
     669             : 
     670           9 :     boost::shared_ptr<utl::TempFile> pTempFile(new utl::TempFile());
     671           9 :     pTempFile->EnableKillingFile();
     672          18 :     SfxMedium aStoreMedium( pTempFile->GetURL(), STREAM_STD_WRITE );
     673           9 :     SotClipboardFormatId nExportFormat = SotClipboardFormatId::NONE;
     674           9 :     SfxFilterFlags nFormatType = aFileFormats[nFormat].nFormatType;
     675           9 :     if (nFormatType == ODS_FORMAT_TYPE)
     676           1 :         nExportFormat = SotClipboardFormatId::STARCHART_8;
     677             :     SfxFilter* pExportFilter = new SfxFilter(
     678             :         aFilterName,
     679             :         OUString(), nFormatType, nExportFormat, aFilterType, 0, OUString(),
     680           9 :         OUString(), OUString("private:factory/scalc*") );
     681           9 :     pExportFilter->SetVersion(SOFFICE_FILEFORMAT_CURRENT);
     682           9 :     aStoreMedium.SetFilter(pExportFilter);
     683           9 :     pShell->DoSaveAs( aStoreMedium );
     684           9 :     pShell->DoClose();
     685             : 
     686           9 :     if(nFormatType == XLSX_FORMAT_TYPE)
     687           8 :         validate(pTempFile->GetFileName(), test::OOXML);
     688           1 :     else if (nFormatType == ODS_FORMAT_TYPE)
     689           1 :         validate(pTempFile->GetFileName(), test::ODF);
     690             : 
     691          18 :     return pTempFile;
     692             : }
     693             : 
     694           2 : void ScBootstrapFixture::miscRowHeightsTest( TestParam* aTestValues, unsigned int numElems )
     695             : {
     696           8 :     for ( unsigned int index=0; index<numElems; ++index )
     697             :     {
     698           6 :         OUString sFileName = OUString::createFromAscii( aTestValues[ index ].sTestDoc );
     699             :         SAL_INFO( "sc.qa", "aTestValues[" << index << "] " << sFileName );
     700           6 :         int nImportType =  aTestValues[ index ].nImportType;
     701           6 :         int nExportType =  aTestValues[ index ].nExportType;
     702          12 :         ScDocShellRef xShell = loadDoc( sFileName, nImportType );
     703           6 :         CPPUNIT_ASSERT(xShell.Is());
     704             : 
     705           6 :         if ( nExportType != -1 )
     706           4 :             xShell = saveAndReload(&(*xShell), nExportType );
     707             : 
     708           6 :         CPPUNIT_ASSERT(xShell.Is());
     709             : 
     710           6 :         ScDocument& rDoc = xShell->GetDocument();
     711             : 
     712          24 :         for (int i=0; i<aTestValues[ index ].nRowData; ++i)
     713             :         {
     714          18 :             SCROW nRow = aTestValues[ index ].pData[ i].nStartRow;
     715          18 :             SCROW nEndRow = aTestValues[ index ].pData[ i ].nEndRow;
     716          18 :             SCTAB nTab = aTestValues[ index ].pData[ i ].nTab;
     717          18 :             int nExpectedHeight = aTestValues[ index ].pData[ i ].nExpectedHeight;
     718          18 :             if ( nExpectedHeight == -1 )
     719           2 :                 nExpectedHeight =  sc::TwipsToHMM( ScGlobal::GetStandardRowHeight() );
     720          18 :             bool bCheckOpt = ( ( aTestValues[ index ].pData[ i ].nCheck & CHECK_OPTIMAL ) == CHECK_OPTIMAL );
     721          92 :             for ( ; nRow <= nEndRow; ++nRow )
     722             :             {
     723             :                 SAL_INFO( "sc.qa", " checking row " << nRow << " for height " << nExpectedHeight );
     724          74 :                 int nHeight = sc::TwipsToHMM( rDoc.GetRowHeight(nRow, nTab, false) );
     725          74 :                 if ( bCheckOpt )
     726             :                 {
     727           2 :                     bool bOpt = !(rDoc.GetRowFlags( nRow, nTab ) & CR_MANUALSIZE);
     728           2 :                     CPPUNIT_ASSERT_EQUAL(aTestValues[ index ].pData[ i ].bOptimal, bOpt);
     729             :                 }
     730          74 :                 CPPUNIT_ASSERT_EQUAL(nExpectedHeight, nHeight);
     731             :             }
     732             :         }
     733           6 :         xShell->DoClose();
     734           6 :     }
     735          32 : }
     736             : 
     737             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11