LCOV - code coverage report
Current view: top level - sc/qa/unit - subsequent_export-test.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 1329 1531 86.8 %
Date: 2015-06-13 12:38:46 Functions: 92 94 97.9 %
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 <officecfg/Office/Common.hxx>
      11             : #include <sal/config.h>
      12             : #include <rtl/strbuf.hxx>
      13             : #include <osl/file.hxx>
      14             : 
      15             : #include <sfx2/app.hxx>
      16             : #include <sfx2/docfile.hxx>
      17             : #include <sfx2/frame.hxx>
      18             : #include <sfx2/sfxmodelfactory.hxx>
      19             : #include <svl/stritem.hxx>
      20             : 
      21             : #include "helper/qahelper.hxx"
      22             : #include "helper/xpath.hxx"
      23             : #include "helper/shared_test_impl.hxx"
      24             : 
      25             : #include "userdat.hxx"
      26             : #include "docsh.hxx"
      27             : #include "patattr.hxx"
      28             : #include "scitems.hxx"
      29             : #include "document.hxx"
      30             : #include "cellform.hxx"
      31             : #include "formulacell.hxx"
      32             : #include "tokenarray.hxx"
      33             : #include "editutil.hxx"
      34             : #include "scopetools.hxx"
      35             : #include "cellvalue.hxx"
      36             : #include "docfunc.hxx"
      37             : #include <postit.hxx>
      38             : #include <tokenstringcontext.hxx>
      39             : #include <chgtrack.hxx>
      40             : #include <dpcache.hxx>
      41             : #include <dpobject.hxx>
      42             : #include <dpsave.hxx>
      43             : #include <dputil.hxx>
      44             : 
      45             : #include <svx/svdoole2.hxx>
      46             : #include <svx/svdpage.hxx>
      47             : #include <svx/svdograf.hxx>
      48             : #include "tabprotection.hxx"
      49             : #include <editeng/wghtitem.hxx>
      50             : #include <editeng/postitem.hxx>
      51             : #include <editeng/editdata.hxx>
      52             : #include <editeng/eeitem.hxx>
      53             : #include <editeng/editobj.hxx>
      54             : #include <editeng/section.hxx>
      55             : #include <editeng/crossedoutitem.hxx>
      56             : #include <editeng/borderline.hxx>
      57             : #include <editeng/fontitem.hxx>
      58             : #include <editeng/udlnitem.hxx>
      59             : #include <formula/grammar.hxx>
      60             : #include <unotools/useroptions.hxx>
      61             : #include <tools/datetime.hxx>
      62             : 
      63             : #include <test/xmltesttools.hxx>
      64             : #include <comphelper/processfactory.hxx>
      65             : #include <com/sun/star/table/BorderLineStyle.hpp>
      66             : #include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
      67             : #include <com/sun/star/sheet/GeneralFunction.hpp>
      68             : #include <com/sun/star/drawing/XDrawPage.hpp>
      69             : #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
      70             : #include <com/sun/star/awt/XBitmap.hpp>
      71             : #include <com/sun/star/graphic/XGraphic.hpp>
      72             : 
      73             : using namespace ::com::sun::star;
      74             : using namespace ::com::sun::star::uno;
      75             : 
      76          96 : class ScExportTest : public ScBootstrapFixture, XmlTestTools
      77             : {
      78             : protected:
      79             :     virtual void registerNamespaces(xmlXPathContextPtr& pXmlXPathCtx) SAL_OVERRIDE;
      80             : public:
      81             :     ScExportTest();
      82             : 
      83             :     virtual void setUp() SAL_OVERRIDE;
      84             :     virtual void tearDown() SAL_OVERRIDE;
      85             : 
      86             : #if !defined MACOSX && !defined DRAGONFLY
      87             :     ScDocShellRef saveAndReloadPassword( ScDocShell*, const OUString&, const OUString&, const OUString&, SfxFilterFlags );
      88             : #endif
      89             : 
      90             :     void test();
      91             : #if !defined MACOSX && !defined DRAGONFLY
      92             :     void testPasswordExport();
      93             : #endif
      94             :     void testConditionalFormatExportODS();
      95             :     void testConditionalFormatExportXLSX();
      96             :     void testColorScaleExportODS();
      97             :     void testColorScaleExportXLSX();
      98             :     void testDataBarExportODS();
      99             :     void testDataBarExportXLSX();
     100             :     void testMiscRowHeightExport();
     101             :     void testNamedRangeBugfdo62729();
     102             :     void testRichTextExportODS();
     103             :     void testFormulaRefSheetNameODS();
     104             : 
     105             :     void testCellValuesExportODS();
     106             :     void testCellNoteExportODS();
     107             :     void testCellNoteExportXLS();
     108             :     void testFormatExportODS();
     109             : 
     110             :     void testInlineArrayXLS();
     111             :     void testEmbeddedChartXLS();
     112             :     void testFormulaReferenceXLS();
     113             :     void testSheetProtectionXLSX();
     114             : 
     115             :     void testCellBordersXLS();
     116             :     void testCellBordersXLSX();
     117             :     void testTrackChangesSimpleXLSX();
     118             :     void testSheetTabColorsXLSX();
     119             : 
     120             :     void testSharedFormulaExportXLS();
     121             :     void testSharedFormulaExportXLSX();
     122             :     void testSharedFormulaStringResultExportXLSX();
     123             : 
     124             :     void testFunctionsExcel2010( sal_uLong nFormatType );
     125             :     void testFunctionsExcel2010XLSX();
     126             :     void testFunctionsExcel2010XLS();
     127             :     void testFunctionsExcel2010ODS();
     128             : 
     129             :     void testRelativePaths();
     130             :     void testSheetProtection();
     131             : 
     132             :     void testPivotTableXLSX();
     133             :     void testPivotTableTwoDataFieldsXLSX();
     134             : 
     135             :     void testSwappedOutImageExport();
     136             :     void testLinkedGraphicRT();
     137             :     void testImageWithSpecialID();
     138             : 
     139             :     void testSupBookVirtualPath();
     140             :     void testSheetLocalRangeNameXLS();
     141             :     void testSheetTextBoxHyperlink();
     142             :     void testFontSize();
     143             :     void testSheetCharacterKerningSpace();
     144             :     void testSheetCondensedCharacterSpace();
     145             :     void testTextUnderlineColor();
     146             :     void testSheetRunParagraphProperty();
     147             :     void testHiddenShape();
     148             :     void testHyperlinkXLSX();
     149             :     void testMoveCellAnchoredShapes();
     150             : 
     151           2 :     CPPUNIT_TEST_SUITE(ScExportTest);
     152           1 :     CPPUNIT_TEST(test);
     153             : #if !defined(MACOSX) && !defined(DRAGONFLY)
     154           1 :     CPPUNIT_TEST(testPasswordExport);
     155             : #endif
     156           1 :     CPPUNIT_TEST(testConditionalFormatExportODS);
     157           1 :     CPPUNIT_TEST(testConditionalFormatExportXLSX);
     158           1 :     CPPUNIT_TEST(testColorScaleExportODS);
     159           1 :     CPPUNIT_TEST(testColorScaleExportXLSX);
     160           1 :     CPPUNIT_TEST(testDataBarExportODS);
     161           1 :     CPPUNIT_TEST(testDataBarExportXLSX);
     162           1 :     CPPUNIT_TEST(testMiscRowHeightExport);
     163           1 :     CPPUNIT_TEST(testNamedRangeBugfdo62729);
     164           1 :     CPPUNIT_TEST(testRichTextExportODS);
     165           1 :     CPPUNIT_TEST(testFormulaRefSheetNameODS);
     166           1 :     CPPUNIT_TEST(testCellValuesExportODS);
     167           1 :     CPPUNIT_TEST(testCellNoteExportODS);
     168           1 :     CPPUNIT_TEST(testCellNoteExportXLS);
     169           1 :     CPPUNIT_TEST(testFormatExportODS);
     170           1 :     CPPUNIT_TEST(testInlineArrayXLS);
     171           1 :     CPPUNIT_TEST(testEmbeddedChartXLS);
     172           1 :     CPPUNIT_TEST(testFormulaReferenceXLS);
     173           1 :     CPPUNIT_TEST(testSheetProtectionXLSX);
     174           1 :     CPPUNIT_TEST(testCellBordersXLS);
     175           1 :     CPPUNIT_TEST(testCellBordersXLSX);
     176           1 :     CPPUNIT_TEST(testTrackChangesSimpleXLSX);
     177           1 :     CPPUNIT_TEST(testSheetTabColorsXLSX);
     178           1 :     CPPUNIT_TEST(testSharedFormulaExportXLS);
     179           1 :     CPPUNIT_TEST(testSharedFormulaExportXLSX);
     180           1 :     CPPUNIT_TEST(testSharedFormulaStringResultExportXLSX);
     181           1 :     CPPUNIT_TEST(testFunctionsExcel2010XLSX);
     182           1 :     CPPUNIT_TEST(testFunctionsExcel2010XLS);
     183             : #if !defined(WNT)
     184           1 :     CPPUNIT_TEST(testRelativePaths);
     185             : #endif
     186           1 :     CPPUNIT_TEST(testSheetProtection);
     187           1 :     CPPUNIT_TEST(testPivotTableXLSX);
     188           1 :     CPPUNIT_TEST(testPivotTableTwoDataFieldsXLSX);
     189           1 :     CPPUNIT_TEST(testFunctionsExcel2010ODS);
     190             : #if !defined(WNT)
     191           1 :     CPPUNIT_TEST(testSupBookVirtualPath);
     192             : #endif
     193           1 :     CPPUNIT_TEST(testSwappedOutImageExport);
     194           1 :     CPPUNIT_TEST(testLinkedGraphicRT);
     195           1 :     CPPUNIT_TEST(testImageWithSpecialID);
     196           1 :     CPPUNIT_TEST(testSheetLocalRangeNameXLS);
     197           1 :     CPPUNIT_TEST(testSheetTextBoxHyperlink);
     198           1 :     CPPUNIT_TEST(testFontSize);
     199           1 :     CPPUNIT_TEST(testSheetCharacterKerningSpace);
     200           1 :     CPPUNIT_TEST(testSheetCondensedCharacterSpace);
     201           1 :     CPPUNIT_TEST(testTextUnderlineColor);
     202           1 :     CPPUNIT_TEST(testSheetRunParagraphProperty);
     203           1 :     CPPUNIT_TEST(testHiddenShape);
     204           1 :     CPPUNIT_TEST(testHyperlinkXLSX);
     205           1 :     CPPUNIT_TEST(testMoveCellAnchoredShapes);
     206             : 
     207           5 :     CPPUNIT_TEST_SUITE_END();
     208             : 
     209             : private:
     210             :     void testExcelCellBorders( sal_uLong nFormatType );
     211             : 
     212             :     uno::Reference<uno::XInterface> m_xCalcComponent;
     213             : 
     214             : };
     215             : 
     216           9 : void ScExportTest::registerNamespaces(xmlXPathContextPtr& pXmlXPathCtx)
     217             : {
     218             :     struct { xmlChar* pPrefix; xmlChar* pURI; } aNamespaces[] =
     219             :     {
     220             :         { BAD_CAST("w"), BAD_CAST("http://schemas.openxmlformats.org/wordprocessingml/2006/main") },
     221             :         { BAD_CAST("v"), BAD_CAST("urn:schemas-microsoft-com:vml") },
     222             :         { BAD_CAST("c"), BAD_CAST("http://schemas.openxmlformats.org/drawingml/2006/chart") },
     223             :         { BAD_CAST("a"), BAD_CAST("http://schemas.openxmlformats.org/drawingml/2006/main") },
     224             :         { BAD_CAST("mc"), BAD_CAST("http://schemas.openxmlformats.org/markup-compatibility/2006") },
     225             :         { BAD_CAST("wps"), BAD_CAST("http://schemas.microsoft.com/office/word/2010/wordprocessingShape") },
     226             :         { BAD_CAST("wpg"), BAD_CAST("http://schemas.microsoft.com/office/word/2010/wordprocessingGroup") },
     227             :         { BAD_CAST("wp"), BAD_CAST("http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing") },
     228             :         { BAD_CAST("office"), BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:office:1.0") },
     229             :         { BAD_CAST("table"), BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:table:1.0") },
     230             :         { BAD_CAST("text"), BAD_CAST("urn:oasis:names:tc:opendocument:xmlns:text:1.0") },
     231             :         { BAD_CAST("xlink"), BAD_CAST("http://www.w3c.org/1999/xlink") },
     232             :         { BAD_CAST("xdr"), BAD_CAST("http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing") },
     233             :         { BAD_CAST("x"), BAD_CAST("http://schemas.openxmlformats.org/spreadsheetml/2006/main") },
     234             :         { BAD_CAST("r"), BAD_CAST("http://schemas.openxmlformats.org/package/2006/relationships") }
     235           9 :     };
     236         144 :     for(size_t i = 0; i < SAL_N_ELEMENTS(aNamespaces); ++i)
     237             :     {
     238         135 :         xmlXPathRegisterNs(pXmlXPathCtx, aNamespaces[i].pPrefix, aNamespaces[i].pURI );
     239             :     }
     240           9 : }
     241             : 
     242             : #if !defined MACOSX && !defined DRAGONFLY
     243           1 : ScDocShellRef ScExportTest::saveAndReloadPassword(ScDocShell* pShell, const OUString &rFilter,
     244             :     const OUString &rUserData, const OUString& rTypeName, SfxFilterFlags nFormatType)
     245             : {
     246           1 :     utl::TempFile aTempFile;
     247           1 :     aTempFile.EnableKillingFile();
     248           2 :     SfxMedium aStoreMedium( aTempFile.GetURL(), STREAM_STD_WRITE );
     249           1 :     SotClipboardFormatId nExportFormat = SotClipboardFormatId::NONE;
     250           1 :     if (nFormatType == ODS_FORMAT_TYPE)
     251           1 :         nExportFormat = SotClipboardFormatId::STARCHART_8;
     252             :     SfxFilter* pExportFilter = new SfxFilter(
     253             :         rFilter,
     254             :         OUString(), nFormatType, nExportFormat, rTypeName, 0, OUString(),
     255           1 :         rUserData, OUString("private:factory/scalc*") );
     256           1 :     pExportFilter->SetVersion(SOFFICE_FILEFORMAT_CURRENT);
     257           1 :     aStoreMedium.SetFilter(pExportFilter);
     258           1 :     SfxItemSet* pExportSet = aStoreMedium.GetItemSet();
     259           2 :     uno::Sequence< beans::NamedValue > aEncryptionData = comphelper::OStorageHelper::CreatePackageEncryptionData( OUString("test") );
     260           2 :     uno::Any xEncryptionData;
     261           1 :     xEncryptionData <<= aEncryptionData;
     262           1 :     pExportSet->Put(SfxUnoAnyItem(SID_ENCRYPTIONDATA, xEncryptionData));
     263             : 
     264           2 :     uno::Reference< embed::XStorage > xMedStorage = aStoreMedium.GetStorage();
     265           1 :     ::comphelper::OStorageHelper::SetCommonStorageEncryptionData( xMedStorage, aEncryptionData );
     266             : 
     267           1 :     pShell->DoSaveAs( aStoreMedium );
     268           1 :     pShell->DoClose();
     269             : 
     270             :     //std::cout << "File: " << aTempFile.GetURL() << std::endl;
     271             : 
     272           1 :     SotClipboardFormatId nFormat = SotClipboardFormatId::NONE;
     273           1 :     if (nFormatType == ODS_FORMAT_TYPE)
     274           1 :         nFormat = SotClipboardFormatId::STARCALC_8;
     275             : 
     276           2 :     OUString aPass("test");
     277           2 :     return load(aTempFile.GetURL(), rFilter, rUserData, rTypeName, nFormatType, nFormat, SOFFICE_FILEFORMAT_CURRENT, &aPass);
     278             : }
     279             : #endif
     280             : 
     281           1 : void ScExportTest::test()
     282             : {
     283             :     ScDocShell* pShell = new ScDocShell(
     284             :         SfxModelFlags::EMBEDDED_OBJECT |
     285           2 :         SfxModelFlags::DISABLE_EMBEDDED_SCRIPTS |
     286           2 :         SfxModelFlags::DISABLE_DOCUMENT_RECOVERY);
     287           1 :     pShell->DoInitNew();
     288             : 
     289           1 :     ScDocument& rDoc = pShell->GetDocument();
     290             : 
     291           1 :     rDoc.SetValue(0,0,0, 1.0);
     292             : 
     293           1 :     ScDocShellRef xDocSh = saveAndReload( pShell, ODS );
     294             : 
     295           1 :     CPPUNIT_ASSERT(xDocSh.Is());
     296           1 :     ScDocument& rLoadedDoc = xDocSh->GetDocument();
     297           1 :     double aVal = rLoadedDoc.GetValue(0,0,0);
     298           1 :     ASSERT_DOUBLES_EQUAL(aVal, 1.0);
     299           1 :     xDocSh->DoClose();
     300           1 : }
     301             : 
     302             : #if !defined MACOSX && !defined DRAGONFLY
     303           1 : void ScExportTest::testPasswordExport()
     304             : {
     305             :     ScDocShell* pShell = new ScDocShell(
     306             :         SfxModelFlags::EMBEDDED_OBJECT |
     307           2 :         SfxModelFlags::DISABLE_EMBEDDED_SCRIPTS |
     308           2 :         SfxModelFlags::DISABLE_DOCUMENT_RECOVERY);
     309           1 :     pShell->DoInitNew();
     310             : 
     311           1 :     ScDocument& rDoc = pShell->GetDocument();
     312             : 
     313           1 :     rDoc.SetValue(0,0,0, 1.0);
     314             : 
     315           1 :     sal_Int32 nFormat = ODS;
     316           1 :     OUString aFilterName(getFileFormats()[nFormat].pFilterName, strlen(getFileFormats()[nFormat].pFilterName), RTL_TEXTENCODING_UTF8) ;
     317           2 :     OUString aFilterType(getFileFormats()[nFormat].pTypeName, strlen(getFileFormats()[nFormat].pTypeName), RTL_TEXTENCODING_UTF8);
     318           2 :     ScDocShellRef xDocSh = saveAndReloadPassword(pShell, aFilterName, OUString(), aFilterType, getFileFormats()[nFormat].nFormatType);
     319             : 
     320           1 :     CPPUNIT_ASSERT(xDocSh.Is());
     321           1 :     ScDocument& rLoadedDoc = xDocSh->GetDocument();
     322           1 :     double aVal = rLoadedDoc.GetValue(0,0,0);
     323           1 :     ASSERT_DOUBLES_EQUAL(aVal, 1.0);
     324             : 
     325           2 :     xDocSh->DoClose();
     326           1 : }
     327             : #endif
     328             : 
     329           1 : void ScExportTest::testConditionalFormatExportODS()
     330             : {
     331           1 :     ScDocShellRef xShell = loadDoc("new_cond_format_test.", ODS);
     332           1 :     CPPUNIT_ASSERT(xShell.Is());
     333             : 
     334           2 :     ScDocShellRef xDocSh = saveAndReload(&(*xShell), ODS);
     335           1 :     CPPUNIT_ASSERT(xDocSh.Is());
     336           1 :     ScDocument& rDoc = xDocSh->GetDocument();
     337           2 :     OUString aCSVFile("new_cond_format_test.");
     338           2 :     OUString aCSVPath;
     339           1 :     createCSVPath( aCSVFile, aCSVPath );
     340           1 :     testCondFile(aCSVPath, &rDoc, 0);
     341             : 
     342           2 :     xDocSh->DoClose();
     343           1 : }
     344             : 
     345           1 : void ScExportTest::testConditionalFormatExportXLSX()
     346             : {
     347           1 :     ScDocShellRef xShell = loadDoc("new_cond_format_test.", XLSX);
     348           1 :     CPPUNIT_ASSERT(xShell.Is());
     349             : 
     350           2 :     ScDocShellRef xDocSh = saveAndReload(&(*xShell), XLSX);
     351           1 :     CPPUNIT_ASSERT(xDocSh.Is());
     352           1 :     ScDocument& rDoc = xDocSh->GetDocument();
     353             :     {
     354           1 :         OUString aCSVFile("new_cond_format_test.");
     355           2 :         OUString aCSVPath;
     356           1 :         createCSVPath( aCSVFile, aCSVPath );
     357           2 :         testCondFile(aCSVPath, &rDoc, 0);
     358             :     }
     359             :     {
     360           1 :         OUString aCSVFile("new_cond_format_test_sheet2.");
     361           2 :         OUString aCSVPath;
     362           1 :         createCSVPath( aCSVFile, aCSVPath );
     363           2 :         testCondFile(aCSVPath, &rDoc, 1);
     364             :     }
     365             : 
     366           2 :     xDocSh->DoClose();
     367           1 : }
     368             : 
     369           1 : void ScExportTest::testColorScaleExportODS()
     370             : {
     371           1 :     ScDocShellRef xShell = loadDoc("colorscale.", ODS);
     372           1 :     CPPUNIT_ASSERT(xShell.Is());
     373             : 
     374           2 :     ScDocShellRef xDocSh = saveAndReload(xShell, ODS);
     375           1 :     CPPUNIT_ASSERT(xDocSh.Is());
     376             : 
     377           1 :     ScDocument& rDoc = xDocSh->GetDocument();
     378             : 
     379           1 :     testColorScale2Entry_Impl(rDoc);
     380           1 :     testColorScale3Entry_Impl(rDoc);
     381             : 
     382           2 :     xDocSh->DoClose();
     383           1 : }
     384             : 
     385           1 : void ScExportTest::testColorScaleExportXLSX()
     386             : {
     387           1 :     ScDocShellRef xShell = loadDoc("colorscale.", XLSX);
     388           1 :     CPPUNIT_ASSERT(xShell.Is());
     389             : 
     390           2 :     ScDocShellRef xDocSh = saveAndReload(xShell, XLSX);
     391           1 :     CPPUNIT_ASSERT(xDocSh.Is());
     392             : 
     393           1 :     ScDocument& rDoc = xDocSh->GetDocument();
     394             : 
     395           1 :     testColorScale2Entry_Impl(rDoc);
     396           1 :     testColorScale3Entry_Impl(rDoc);
     397             : 
     398           2 :     xDocSh->DoClose();
     399           1 : }
     400             : 
     401           1 : void ScExportTest::testDataBarExportODS()
     402             : {
     403           1 :     ScDocShellRef xShell = loadDoc("databar.", ODS);
     404           1 :     CPPUNIT_ASSERT(xShell.Is());
     405             : 
     406           2 :     ScDocShellRef xDocSh = saveAndReload(xShell, ODS);
     407           1 :     CPPUNIT_ASSERT(xDocSh.Is());
     408             : 
     409           1 :     ScDocument& rDoc = xDocSh->GetDocument();
     410             : 
     411           1 :     testDataBar_Impl(rDoc);
     412             : 
     413           2 :     xDocSh->DoClose();
     414           1 : }
     415             : 
     416           1 : void ScExportTest::testFormatExportODS()
     417             : {
     418           1 :     ScDocShellRef xShell = loadDoc("formats.", ODS);
     419           1 :     CPPUNIT_ASSERT(xShell.Is());
     420             : 
     421           2 :     ScDocShellRef xDocSh = saveAndReload(xShell, ODS);
     422           1 :     CPPUNIT_ASSERT(xDocSh.Is());
     423             : 
     424           1 :     ScDocument& rDoc = xDocSh->GetDocument();
     425             : 
     426           1 :     testFormats(this, &rDoc, ODS);
     427             : 
     428           2 :     xDocSh->DoClose();
     429           1 : }
     430             : 
     431           1 : void ScExportTest::testDataBarExportXLSX()
     432             : {
     433           1 :     ScDocShellRef xShell = loadDoc("databar.", XLSX);
     434           1 :     CPPUNIT_ASSERT(xShell.Is());
     435             : 
     436           2 :     ScDocShellRef xDocSh = saveAndReload(xShell, XLSX);
     437           1 :     CPPUNIT_ASSERT(xDocSh.Is());
     438             : 
     439           1 :     ScDocument& rDoc = xDocSh->GetDocument();
     440             : 
     441           1 :     testDataBar_Impl(rDoc);
     442             : 
     443           2 :     xDocSh->DoClose();
     444           1 : }
     445             : 
     446           1 : void ScExportTest::testMiscRowHeightExport()
     447             : {
     448             :     TestParam::RowData DfltRowData[] =
     449             :     {
     450             :         { 0, 4, 0, 529, 0, false },
     451             :         { 5, 10, 0, 1058, 0, false },
     452             :         { 17, 20, 0, 1767, 0, false },
     453             :         // check last couple of row in document to ensure
     454             :         // they are 5.29mm ( effective default row xlsx height )
     455             :         { 1048573, 1048575, 0, 529, 0, false },
     456           1 :     };
     457             : 
     458             :     TestParam::RowData EmptyRepeatRowData[] =
     459             :     {
     460             :         // rows 0-4, 5-10, 17-20 are all set at various
     461             :         // heights, there is no content in the rows, there
     462             :         // was a bug where only the first row ( of repeated rows )
     463             :         // was set after export
     464             :         { 0, 4, 0, 529, 0, false },
     465             :         { 5, 10, 0, 1058, 0, false },
     466             :         { 17, 20, 0, 1767, 0, false },
     467           1 :     };
     468             : 
     469             :     TestParam aTestValues[] =
     470             :     {
     471             :         // Checks that some distributed ( non-empty ) heights remain set after export (roundtrip)
     472             :         // additionally there is effectively a default row height ( 5.29 mm ). So we test the
     473             :         // unset rows at the end of the document to ensure the effective xlsx default height
     474             :         // is set there too.
     475             :         { "miscrowheights.", XLSX, XLSX, SAL_N_ELEMENTS(DfltRowData), DfltRowData },
     476             :         // Checks that some distributed ( non-empty ) heights remain set after export (to xls)
     477             :         { "miscrowheights.", XLSX, XLS, SAL_N_ELEMENTS(DfltRowData), DfltRowData },
     478             :         // Checks that repreated rows ( of various heights ) remain set after export ( to xlsx )
     479             :         { "miscemptyrepeatedrowheights.", ODS, XLSX, SAL_N_ELEMENTS(EmptyRepeatRowData), EmptyRepeatRowData },
     480             :         // Checks that repreated rows ( of various heights ) remain set after export ( to xls )
     481             :         { "miscemptyrepeatedrowheights.", ODS, XLS, SAL_N_ELEMENTS(EmptyRepeatRowData), EmptyRepeatRowData },
     482           1 :     };
     483           1 :     miscRowHeightsTest( aTestValues, SAL_N_ELEMENTS(aTestValues) );
     484           1 : }
     485             : 
     486             : namespace {
     487             : 
     488           5 : void setAttribute( ScFieldEditEngine& rEE, sal_Int32 nPara, sal_Int32 nStart, sal_Int32 nEnd, sal_uInt16 nType )
     489             : {
     490           5 :     ESelection aSel;
     491           5 :     aSel.nStartPara = aSel.nEndPara = nPara;
     492           5 :     aSel.nStartPos = nStart;
     493           5 :     aSel.nEndPos = nEnd;
     494             : 
     495           5 :     SfxItemSet aItemSet = rEE.GetEmptyItemSet();
     496           5 :     switch (nType)
     497             :     {
     498             :         case EE_CHAR_WEIGHT:
     499             :         {
     500           1 :             SvxWeightItem aWeight(WEIGHT_BOLD, nType);
     501           1 :             aItemSet.Put(aWeight);
     502           1 :             rEE.QuickSetAttribs(aItemSet, aSel);
     503             :         }
     504           1 :         break;
     505             :         case EE_CHAR_ITALIC:
     506             :         {
     507           1 :             SvxPostureItem aItalic(ITALIC_NORMAL, nType);
     508           1 :             aItemSet.Put(aItalic);
     509           1 :             rEE.QuickSetAttribs(aItemSet, aSel);
     510             :         }
     511           1 :         break;
     512             :         case EE_CHAR_STRIKEOUT:
     513             :         {
     514           1 :             SvxCrossedOutItem aCrossOut(STRIKEOUT_SINGLE, nType);
     515           1 :             aItemSet.Put(aCrossOut);
     516           1 :             rEE.QuickSetAttribs(aItemSet, aSel);
     517             :         }
     518           1 :         break;
     519             :         case EE_CHAR_OVERLINE:
     520             :         {
     521           1 :             SvxOverlineItem aItem(UNDERLINE_DOUBLE, nType);
     522           1 :             aItemSet.Put(aItem);
     523           1 :             rEE.QuickSetAttribs(aItemSet, aSel);
     524             :         }
     525           1 :         break;
     526             :         case EE_CHAR_UNDERLINE:
     527             :         {
     528           1 :             SvxUnderlineItem aItem(UNDERLINE_DOUBLE, nType);
     529           1 :             aItemSet.Put(aItem);
     530           1 :             rEE.QuickSetAttribs(aItemSet, aSel);
     531             :         }
     532           1 :         break;
     533             :         default:
     534             :             ;
     535           5 :     }
     536           5 : }
     537             : 
     538           2 : void setFont( ScFieldEditEngine& rEE, sal_Int32 nPara, sal_Int32 nStart, sal_Int32 nEnd, const OUString& rFontName )
     539             : {
     540           2 :     ESelection aSel;
     541           2 :     aSel.nStartPara = aSel.nEndPara = nPara;
     542           2 :     aSel.nStartPos = nStart;
     543           2 :     aSel.nEndPos = nEnd;
     544             : 
     545           2 :     SfxItemSet aItemSet = rEE.GetEmptyItemSet();
     546           4 :     SvxFontItem aItem(FAMILY_MODERN, rFontName, "", PITCH_VARIABLE, RTL_TEXTENCODING_UTF8, EE_CHAR_FONTINFO);
     547           2 :     aItemSet.Put(aItem);
     548           4 :     rEE.QuickSetAttribs(aItemSet, aSel);
     549           2 : }
     550             : 
     551             : }
     552             : 
     553           1 : void ScExportTest::testNamedRangeBugfdo62729()
     554             : {
     555           1 :     ScDocShellRef xShell = loadDoc("fdo62729.", ODS);
     556           1 :     CPPUNIT_ASSERT(xShell.Is());
     557           1 :     ScDocument& rDoc = xShell->GetDocument();
     558             : 
     559           1 :     ScRangeName* pNames = rDoc.GetRangeName();
     560             :     //should be just a single named range
     561           1 :     CPPUNIT_ASSERT(pNames->size() == 1 );
     562           1 :     rDoc.DeleteTab(0);
     563             :     //should be still a single named range
     564           1 :     CPPUNIT_ASSERT(pNames->size() == 1 );
     565           2 :     ScDocShellRef xDocSh = saveAndReload(xShell, ODS);
     566           1 :     xShell->DoClose();
     567             : 
     568           1 :     CPPUNIT_ASSERT(xDocSh.Is());
     569           1 :     ScDocument& rDoc2 = xDocSh->GetDocument();
     570             : 
     571           1 :     pNames = rDoc2.GetRangeName();
     572             :     //after reload should still have a named range
     573           1 :     CPPUNIT_ASSERT(pNames->size() == 1 );
     574             : 
     575           2 :     xDocSh->DoClose();
     576           1 : }
     577             : 
     578           1 : void ScExportTest::testRichTextExportODS()
     579             : {
     580             :     struct
     581             :     {
     582           3 :         static bool isBold(const editeng::Section& rAttr)
     583             :         {
     584           3 :             if (rAttr.maAttributes.empty())
     585           0 :                 return false;
     586             : 
     587           3 :             std::vector<const SfxPoolItem*>::const_iterator it = rAttr.maAttributes.begin(), itEnd = rAttr.maAttributes.end();
     588           3 :             for (; it != itEnd; ++it)
     589             :             {
     590           3 :                 const SfxPoolItem* p = *it;
     591           3 :                 if (p->Which() != EE_CHAR_WEIGHT)
     592           0 :                     continue;
     593             : 
     594           3 :                 return static_cast<const SvxWeightItem*>(p)->GetWeight() == WEIGHT_BOLD;
     595             :             }
     596           0 :             return false;
     597             :         }
     598             : 
     599           3 :         static bool isItalic(const editeng::Section& rAttr)
     600             :         {
     601           3 :             if (rAttr.maAttributes.empty())
     602           0 :                 return false;
     603             : 
     604           3 :             std::vector<const SfxPoolItem*>::const_iterator it = rAttr.maAttributes.begin(), itEnd = rAttr.maAttributes.end();
     605           3 :             for (; it != itEnd; ++it)
     606             :             {
     607           3 :                 const SfxPoolItem* p = *it;
     608           3 :                 if (p->Which() != EE_CHAR_ITALIC)
     609           0 :                     continue;
     610             : 
     611           3 :                 return static_cast<const SvxPostureItem*>(p)->GetPosture() == ITALIC_NORMAL;
     612             :             }
     613           0 :             return false;
     614             :         }
     615             : 
     616           2 :         static bool isStrikeOut(const editeng::Section& rAttr)
     617             :         {
     618           2 :             if (rAttr.maAttributes.empty())
     619           0 :                 return false;
     620             : 
     621           2 :             std::vector<const SfxPoolItem*>::const_iterator it = rAttr.maAttributes.begin(), itEnd = rAttr.maAttributes.end();
     622           2 :             for (; it != itEnd; ++it)
     623             :             {
     624           2 :                 const SfxPoolItem* p = *it;
     625           2 :                 if (p->Which() != EE_CHAR_STRIKEOUT)
     626           0 :                     continue;
     627             : 
     628           2 :                 return static_cast<const SvxCrossedOutItem*>(p)->GetStrikeout() == STRIKEOUT_SINGLE;
     629             :             }
     630           0 :             return false;
     631             :         }
     632             : 
     633           2 :         static bool isOverline(const editeng::Section& rAttr, FontUnderline eStyle)
     634             :         {
     635           2 :             if (rAttr.maAttributes.empty())
     636           0 :                 return false;
     637             : 
     638           2 :             std::vector<const SfxPoolItem*>::const_iterator it = rAttr.maAttributes.begin(), itEnd = rAttr.maAttributes.end();
     639           2 :             for (; it != itEnd; ++it)
     640             :             {
     641           2 :                 const SfxPoolItem* p = *it;
     642           2 :                 if (p->Which() != EE_CHAR_OVERLINE)
     643           0 :                     continue;
     644             : 
     645           2 :                 return static_cast<const SvxOverlineItem*>(p)->GetLineStyle() == eStyle;
     646             :             }
     647           0 :             return false;
     648             :         }
     649             : 
     650           2 :         static bool isUnderline(const editeng::Section& rAttr, FontUnderline eStyle)
     651             :         {
     652           2 :             if (rAttr.maAttributes.empty())
     653           0 :                 return false;
     654             : 
     655           2 :             std::vector<const SfxPoolItem*>::const_iterator it = rAttr.maAttributes.begin(), itEnd = rAttr.maAttributes.end();
     656           2 :             for (; it != itEnd; ++it)
     657             :             {
     658           2 :                 const SfxPoolItem* p = *it;
     659           2 :                 if (p->Which() != EE_CHAR_UNDERLINE)
     660           0 :                     continue;
     661             : 
     662           2 :                 return static_cast<const SvxUnderlineItem*>(p)->GetLineStyle() == eStyle;
     663             :             }
     664           0 :             return false;
     665             :         }
     666             : 
     667           4 :         static bool isFont(const editeng::Section& rAttr, const OUString& rFontName)
     668             :         {
     669           4 :             if (rAttr.maAttributes.empty())
     670           0 :                 return false;
     671             : 
     672           4 :             std::vector<const SfxPoolItem*>::const_iterator it = rAttr.maAttributes.begin(), itEnd = rAttr.maAttributes.end();
     673           4 :             for (; it != itEnd; ++it)
     674             :             {
     675           4 :                 const SfxPoolItem* p = *it;
     676           4 :                 if (p->Which() != EE_CHAR_FONTINFO)
     677           0 :                     continue;
     678             : 
     679           4 :                 return static_cast<const SvxFontItem*>(p)->GetFamilyName() == rFontName;
     680             :             }
     681           0 :             return false;
     682             :         }
     683             : 
     684           3 :         bool checkB2(const EditTextObject* pText) const
     685             :         {
     686           3 :             if (!pText)
     687           0 :                 return false;
     688             : 
     689           3 :             if (pText->GetParagraphCount() != 1)
     690           0 :                 return false;
     691             : 
     692           3 :             if (pText->GetText(0) != "Bold and Italic")
     693           0 :                 return false;
     694             : 
     695           3 :             std::vector<editeng::Section> aSecAttrs;
     696           3 :             pText->GetAllSections(aSecAttrs);
     697           3 :             if (aSecAttrs.size() != 3)
     698           0 :                 return false;
     699             : 
     700             :             // Check the first bold section.
     701           3 :             const editeng::Section* pAttr = &aSecAttrs[0];
     702           3 :             if (pAttr->mnParagraph != 0 ||pAttr->mnStart != 0 || pAttr->mnEnd != 4)
     703           0 :                 return false;
     704             : 
     705           3 :             if (pAttr->maAttributes.size() != 1 || !isBold(*pAttr))
     706           0 :                 return false;
     707             : 
     708             :             // The middle section should be unformatted.
     709           3 :             pAttr = &aSecAttrs[1];
     710           3 :             if (pAttr->mnParagraph != 0 ||pAttr->mnStart != 4 || pAttr->mnEnd != 9)
     711           0 :                 return false;
     712             : 
     713           3 :             if (!pAttr->maAttributes.empty())
     714           0 :                 return false;
     715             : 
     716             :             // The last section should be italic.
     717           3 :             pAttr = &aSecAttrs[2];
     718           3 :             if (pAttr->mnParagraph != 0 ||pAttr->mnStart != 9 || pAttr->mnEnd != 15)
     719           0 :                 return false;
     720             : 
     721           3 :             if (pAttr->maAttributes.size() != 1 || !isItalic(*pAttr))
     722           0 :                 return false;
     723             : 
     724           3 :             return true;
     725             :         }
     726             : 
     727           3 :         bool checkB4(const EditTextObject* pText) const
     728             :         {
     729           3 :             if (!pText)
     730           0 :                 return false;
     731             : 
     732           3 :             if (pText->GetParagraphCount() != 3)
     733           0 :                 return false;
     734             : 
     735           3 :             if (pText->GetText(0) != "One")
     736           0 :                 return false;
     737             : 
     738           3 :             if (pText->GetText(1) != "Two")
     739           0 :                 return false;
     740             : 
     741           3 :             if (pText->GetText(2) != "Three")
     742           0 :                 return false;
     743             : 
     744           3 :             return true;
     745             :         }
     746             : 
     747           2 :         bool checkB5(const EditTextObject* pText) const
     748             :         {
     749           2 :             if (!pText)
     750           0 :                 return false;
     751             : 
     752           2 :             if (pText->GetParagraphCount() != 6)
     753           0 :                 return false;
     754             : 
     755           2 :             if (!pText->GetText(0).isEmpty())
     756           0 :                 return false;
     757             : 
     758           2 :             if (pText->GetText(1) != "Two")
     759           0 :                 return false;
     760             : 
     761           2 :             if (pText->GetText(2) != "Three")
     762           0 :                 return false;
     763             : 
     764           2 :             if (!pText->GetText(3).isEmpty())
     765           0 :                 return false;
     766             : 
     767           2 :             if (pText->GetText(4) != "Five")
     768           0 :                 return false;
     769             : 
     770           2 :             if (!pText->GetText(5).isEmpty())
     771           0 :                 return false;
     772             : 
     773           2 :             return true;
     774             :         }
     775             : 
     776           2 :         bool checkB6(const EditTextObject* pText) const
     777             :         {
     778           2 :             if (!pText)
     779           0 :                 return false;
     780             : 
     781           2 :             if (pText->GetParagraphCount() != 1)
     782           0 :                 return false;
     783             : 
     784           2 :             if (pText->GetText(0) != "Strike Me")
     785           0 :                 return false;
     786             : 
     787           2 :             std::vector<editeng::Section> aSecAttrs;
     788           2 :             pText->GetAllSections(aSecAttrs);
     789           2 :             if (aSecAttrs.size() != 2)
     790           0 :                 return false;
     791             : 
     792             :             // Check the first strike-out section.
     793           2 :             const editeng::Section* pAttr = &aSecAttrs[0];
     794           2 :             if (pAttr->mnParagraph != 0 ||pAttr->mnStart != 0 || pAttr->mnEnd != 6)
     795           0 :                 return false;
     796             : 
     797           2 :             if (pAttr->maAttributes.size() != 1 || !isStrikeOut(*pAttr))
     798           0 :                 return false;
     799             : 
     800             :             // The last section should be unformatted.
     801           2 :             pAttr = &aSecAttrs[1];
     802           2 :             if (pAttr->mnParagraph != 0 ||pAttr->mnStart != 6 || pAttr->mnEnd != 9)
     803           0 :                 return false;
     804             : 
     805           2 :             return true;
     806             :         }
     807             : 
     808           2 :         bool checkB7(const EditTextObject* pText) const
     809             :         {
     810           2 :             if (!pText)
     811           0 :                 return false;
     812             : 
     813           2 :             if (pText->GetParagraphCount() != 1)
     814           0 :                 return false;
     815             : 
     816           2 :             if (pText->GetText(0) != "Font1 and Font2")
     817           0 :                 return false;
     818             : 
     819           2 :             std::vector<editeng::Section> aSecAttrs;
     820           2 :             pText->GetAllSections(aSecAttrs);
     821           2 :             if (aSecAttrs.size() != 3)
     822           0 :                 return false;
     823             : 
     824             :             // First section should have "Courier" font applied.
     825           2 :             const editeng::Section* pAttr = &aSecAttrs[0];
     826           2 :             if (pAttr->mnParagraph != 0 ||pAttr->mnStart != 0 || pAttr->mnEnd != 5)
     827           0 :                 return false;
     828             : 
     829           2 :             if (pAttr->maAttributes.size() != 1 || !isFont(*pAttr, "Courier"))
     830           0 :                 return false;
     831             : 
     832             :             // Last section should have "Luxi Mono" applied.
     833           2 :             pAttr = &aSecAttrs[2];
     834           2 :             if (pAttr->mnParagraph != 0 ||pAttr->mnStart != 10 || pAttr->mnEnd != 15)
     835           0 :                 return false;
     836             : 
     837           2 :             if (pAttr->maAttributes.size() != 1 || !isFont(*pAttr, "Luxi Mono"))
     838           0 :                 return false;
     839             : 
     840           2 :             return true;
     841             :         }
     842             : 
     843           2 :         bool checkB8(const EditTextObject* pText) const
     844             :         {
     845           2 :             if (!pText)
     846           0 :                 return false;
     847             : 
     848           2 :             if (pText->GetParagraphCount() != 1)
     849           0 :                 return false;
     850             : 
     851           2 :             if (pText->GetText(0) != "Over and Under")
     852           0 :                 return false;
     853             : 
     854           2 :             std::vector<editeng::Section> aSecAttrs;
     855           2 :             pText->GetAllSections(aSecAttrs);
     856           2 :             if (aSecAttrs.size() != 3)
     857           0 :                 return false;
     858             : 
     859             :             // First section shoul have overline applied.
     860           2 :             const editeng::Section* pAttr = &aSecAttrs[0];
     861           2 :             if (pAttr->mnParagraph != 0 ||pAttr->mnStart != 0 || pAttr->mnEnd != 4)
     862           0 :                 return false;
     863             : 
     864           2 :             if (pAttr->maAttributes.size() != 1 || !isOverline(*pAttr, UNDERLINE_DOUBLE))
     865           0 :                 return false;
     866             : 
     867             :             // Last section should have underline applied.
     868           2 :             pAttr = &aSecAttrs[2];
     869           2 :             if (pAttr->mnParagraph != 0 ||pAttr->mnStart != 9 || pAttr->mnEnd != 14)
     870           0 :                 return false;
     871             : 
     872           2 :             if (pAttr->maAttributes.size() != 1 || !isUnderline(*pAttr, UNDERLINE_DOUBLE))
     873           0 :                 return false;
     874             : 
     875           2 :             return true;
     876             :         }
     877             : 
     878             :     } aCheckFunc;
     879             : 
     880             :     // Start with an empty document, put one edit text cell, and make sure it
     881             :     // survives the save and reload.
     882           1 :     ScDocShellRef xOrigDocSh = loadDoc("empty.", ODS, true);
     883             :     const EditTextObject* pEditText;
     884             :     {
     885           1 :         ScDocument& rDoc = xOrigDocSh->GetDocument();
     886           1 :         CPPUNIT_ASSERT_MESSAGE("This document should at least have one sheet.", rDoc.GetTableCount() > 0);
     887             : 
     888             :         // Insert an edit text cell.
     889           1 :         ScFieldEditEngine* pEE = &rDoc.GetEditEngine();
     890           1 :         pEE->SetText("Bold and Italic");
     891             :         // Set the 'Bold' part bold.
     892           1 :         setAttribute(*pEE, 0, 0, 4, EE_CHAR_WEIGHT);
     893             :         // Set the 'Italic' part italic.
     894           1 :         setAttribute(*pEE, 0, 9, 15, EE_CHAR_ITALIC);
     895           1 :         ESelection aSel;
     896           1 :         aSel.nStartPara = aSel.nEndPara = 0;
     897             : 
     898             :         // Set this edit text to cell B2.
     899           1 :         rDoc.SetEditText(ScAddress(1,1,0), pEE->CreateTextObject());
     900           1 :         pEditText = rDoc.GetEditText(ScAddress(1,1,0));
     901           1 :         CPPUNIT_ASSERT_MESSAGE("Incorret B2 value.", aCheckFunc.checkB2(pEditText));
     902             :     }
     903             : 
     904             :     // Now, save and reload this document.
     905           2 :     ScDocShellRef xNewDocSh = saveAndReload(xOrigDocSh, ODS);
     906             :     {
     907           1 :         xOrigDocSh->DoClose();
     908           1 :         CPPUNIT_ASSERT(xNewDocSh.Is());
     909           1 :         ScDocument& rDoc2 = xNewDocSh->GetDocument();
     910           1 :         CPPUNIT_ASSERT_MESSAGE("Reloaded document should at least have one sheet.", rDoc2.GetTableCount() > 0);
     911           1 :         ScFieldEditEngine* pEE = &rDoc2.GetEditEngine();
     912             : 
     913             :         // Make sure the content of B2 is still intact.
     914           1 :         CPPUNIT_ASSERT_MESSAGE("Incorret B2 value.", aCheckFunc.checkB2(pEditText));
     915             : 
     916             :         // Insert a multi-line content to B4.
     917           1 :         pEE->Clear();
     918           1 :         pEE->SetText("One\nTwo\nThree");
     919           1 :         rDoc2.SetEditText(ScAddress(1,3,0), pEE->CreateTextObject());
     920           1 :         pEditText = rDoc2.GetEditText(ScAddress(1,3,0));
     921           1 :         CPPUNIT_ASSERT_MESSAGE("Incorrect B4 value.", aCheckFunc.checkB4(pEditText));
     922             :     }
     923             : 
     924             :     // Reload the doc again, and check the content of B2 and B4.
     925           2 :     ScDocShellRef xNewDocSh2 = saveAndReload(xNewDocSh, ODS);
     926             :     {
     927           1 :         ScDocument& rDoc3 = xNewDocSh2->GetDocument();
     928           1 :         ScFieldEditEngine* pEE = &rDoc3.GetEditEngine();
     929           1 :         xNewDocSh->DoClose();
     930             : 
     931           1 :         pEditText = rDoc3.GetEditText(ScAddress(1,1,0));
     932           1 :         CPPUNIT_ASSERT_MESSAGE("B2 should be an edit text.", pEditText);
     933           1 :         pEditText = rDoc3.GetEditText(ScAddress(1,3,0));
     934           1 :         CPPUNIT_ASSERT_MESSAGE("Incorrect B4 value.", aCheckFunc.checkB4(pEditText));
     935             : 
     936             :         // Insert a multi-line content to B5, but this time, set some empty paragraphs.
     937           1 :         pEE->Clear();
     938           1 :         pEE->SetText("\nTwo\nThree\n\nFive\n");
     939           1 :         rDoc3.SetEditText(ScAddress(1,4,0), pEE->CreateTextObject());
     940           1 :         pEditText = rDoc3.GetEditText(ScAddress(1,4,0));
     941           1 :         CPPUNIT_ASSERT_MESSAGE("Incorrect B5 value.", aCheckFunc.checkB5(pEditText));
     942             : 
     943             :         // Insert a text with strikethrough in B6.
     944           1 :         pEE->Clear();
     945           1 :         pEE->SetText("Strike Me");
     946             :         // Set the 'Strike' part strikethrough.
     947           1 :         setAttribute(*pEE, 0, 0, 6, EE_CHAR_STRIKEOUT);
     948           1 :         rDoc3.SetEditText(ScAddress(1,5,0), pEE->CreateTextObject());
     949           1 :         pEditText = rDoc3.GetEditText(ScAddress(1,5,0));
     950           1 :         CPPUNIT_ASSERT_MESSAGE("Incorrect B6 value.", aCheckFunc.checkB6(pEditText));
     951             : 
     952             :         // Insert a text with different font segments in B7.
     953           1 :         pEE->Clear();
     954           1 :         pEE->SetText("Font1 and Font2");
     955           1 :         setFont(*pEE, 0, 0, 5, "Courier");
     956           1 :         setFont(*pEE, 0, 10, 15, "Luxi Mono");
     957           1 :         rDoc3.SetEditText(ScAddress(1,6,0), pEE->CreateTextObject());
     958           1 :         pEditText = rDoc3.GetEditText(ScAddress(1,6,0));
     959           1 :         CPPUNIT_ASSERT_MESSAGE("Incorrect B7 value.", aCheckFunc.checkB7(pEditText));
     960             : 
     961             :         // Insert a text with overline and underline in B8.
     962           1 :         pEE->Clear();
     963           1 :         pEE->SetText("Over and Under");
     964           1 :         setAttribute(*pEE, 0, 0, 4, EE_CHAR_OVERLINE);
     965           1 :         setAttribute(*pEE, 0, 9, 14, EE_CHAR_UNDERLINE);
     966           1 :         rDoc3.SetEditText(ScAddress(1,7,0), pEE->CreateTextObject());
     967           1 :         pEditText = rDoc3.GetEditText(ScAddress(1,7,0));
     968           1 :         CPPUNIT_ASSERT_MESSAGE("Incorrect B8 value.", aCheckFunc.checkB8(pEditText));
     969             :     }
     970             : 
     971             :     // Reload the doc again, and check the content of B2, B4, B6 and B7.
     972           2 :     ScDocShellRef xNewDocSh3 = saveAndReload(xNewDocSh2, ODS);
     973           1 :     ScDocument& rDoc4 = xNewDocSh3->GetDocument();
     974           1 :     xNewDocSh2->DoClose();
     975             : 
     976           1 :     pEditText = rDoc4.GetEditText(ScAddress(1,1,0));
     977           1 :     CPPUNIT_ASSERT_MESSAGE("Incorrect B2 value after save and reload.", aCheckFunc.checkB2(pEditText));
     978           1 :     pEditText = rDoc4.GetEditText(ScAddress(1,3,0));
     979           1 :     CPPUNIT_ASSERT_MESSAGE("Incorrect B4 value after save and reload.", aCheckFunc.checkB4(pEditText));
     980           1 :     pEditText = rDoc4.GetEditText(ScAddress(1,4,0));
     981           1 :     CPPUNIT_ASSERT_MESSAGE("Incorrect B5 value after save and reload.", aCheckFunc.checkB5(pEditText));
     982           1 :     pEditText = rDoc4.GetEditText(ScAddress(1,5,0));
     983           1 :     CPPUNIT_ASSERT_MESSAGE("Incorrect B6 value after save and reload.", aCheckFunc.checkB6(pEditText));
     984           1 :     pEditText = rDoc4.GetEditText(ScAddress(1,6,0));
     985           1 :     CPPUNIT_ASSERT_MESSAGE("Incorrect B7 value after save and reload.", aCheckFunc.checkB7(pEditText));
     986           1 :     pEditText = rDoc4.GetEditText(ScAddress(1,7,0));
     987           1 :     CPPUNIT_ASSERT_MESSAGE("Incorrect B8 value after save and reload.", aCheckFunc.checkB8(pEditText));
     988             : 
     989           2 :     xNewDocSh3->DoClose();
     990           1 : }
     991             : 
     992           1 : void ScExportTest::testFormulaRefSheetNameODS()
     993             : {
     994           1 :     ScDocShellRef xDocSh = loadDoc("formula-quote-in-sheet-name.", ODS, true);
     995             :     {
     996           1 :         ScDocument& rDoc = xDocSh->GetDocument();
     997             : 
     998           1 :         sc::AutoCalcSwitch aACSwitch(rDoc, true); // turn on auto calc.
     999           1 :         rDoc.SetString(ScAddress(1,1,0), "='90''s Data'.B2");
    1000           1 :         CPPUNIT_ASSERT_EQUAL(1.1, rDoc.GetValue(ScAddress(1,1,0)));
    1001           1 :         if (!checkFormula(rDoc, ScAddress(1,1,0), "'90''s Data'.B2"))
    1002           0 :             CPPUNIT_FAIL("Wrong formula");
    1003             :     }
    1004             :     // Now, save and reload this document.
    1005           2 :     ScDocShellRef xNewDocSh = saveAndReload(xDocSh, ODS);
    1006           1 :     xDocSh->DoClose();
    1007             : 
    1008           1 :     ScDocument& rDoc = xNewDocSh->GetDocument();
    1009           1 :     rDoc.CalcAll();
    1010           1 :     CPPUNIT_ASSERT_EQUAL(1.1, rDoc.GetValue(ScAddress(1,1,0)));
    1011           1 :     if (!checkFormula(rDoc, ScAddress(1,1,0), "'90''s Data'.B2"))
    1012           0 :         CPPUNIT_FAIL("Wrong formula");
    1013             : 
    1014           2 :     xNewDocSh->DoClose();
    1015           1 : }
    1016             : 
    1017           1 : void ScExportTest::testCellValuesExportODS()
    1018             : {
    1019             :     // Start with an empty document
    1020           1 :     ScDocShellRef xOrigDocSh = loadDoc("empty.", ODS);
    1021             :     {
    1022           1 :         ScDocument& rDoc = xOrigDocSh->GetDocument();
    1023           1 :         CPPUNIT_ASSERT_MESSAGE("This document should at least have one sheet.", rDoc.GetTableCount() > 0);
    1024             : 
    1025             :         // set a value double
    1026           1 :         rDoc.SetValue(ScAddress(0,0,0), 2.0); // A1
    1027             : 
    1028             :         // set a formula
    1029           1 :         rDoc.SetValue(ScAddress(2,0,0), 3.0); // C1
    1030           1 :         rDoc.SetValue(ScAddress(3,0,0), 3); // D1
    1031           1 :         rDoc.SetString(ScAddress(4,0,0), "=10*C1/4"); // E1
    1032           1 :         rDoc.SetValue(ScAddress(5,0,0), 3.0); // F1
    1033           1 :         rDoc.SetString(ScAddress(7,0,0), "=SUM(C1:F1)"); //H1
    1034             : 
    1035             :         // set a string
    1036           1 :         rDoc.SetString(ScAddress(0,2,0), "a simple line"); //A3
    1037             : 
    1038             :         // set a digit string
    1039           1 :         rDoc.SetString(ScAddress(0,4,0), "'12"); //A5
    1040             :         // set a contiguous value
    1041           1 :         rDoc.SetValue(ScAddress(0,5,0), 12.0); //A6
    1042             :         // set acontiguous string
    1043           1 :         rDoc.SetString(ScAddress(0,6,0), "a string"); //A7
    1044             :         // set a contiguous formula
    1045           1 :         rDoc.SetString(ScAddress(0,7,0), "=$A$6"); //A8
    1046             :     }
    1047             :     // save and reload
    1048           2 :     ScDocShellRef xNewDocSh = saveAndReload(xOrigDocSh, ODS);
    1049           1 :     xOrigDocSh->DoClose();
    1050           1 :     CPPUNIT_ASSERT(xNewDocSh.Is());
    1051           1 :     ScDocument& rDoc = xNewDocSh->GetDocument();
    1052           1 :     CPPUNIT_ASSERT_MESSAGE("Reloaded document should at least have one sheet.", rDoc.GetTableCount() > 0);
    1053             : 
    1054             :     // check value
    1055           1 :     CPPUNIT_ASSERT_EQUAL(2.0, rDoc.GetValue(0,0,0));
    1056           1 :     CPPUNIT_ASSERT_EQUAL(3.0, rDoc.GetValue(2,0,0));
    1057           1 :     CPPUNIT_ASSERT_EQUAL(3.0, rDoc.GetValue(3,0,0));
    1058           1 :     CPPUNIT_ASSERT_EQUAL(7.5, rDoc.GetValue(4,0,0));
    1059           1 :     CPPUNIT_ASSERT_EQUAL(3.0, rDoc.GetValue(5,0,0));
    1060             : 
    1061             :     // check formula
    1062           1 :     if (!checkFormula(rDoc, ScAddress(4,0,0), "10*C1/4"))
    1063           0 :         CPPUNIT_FAIL("Wrong formula =10*C1/4");
    1064           1 :     if (!checkFormula(rDoc, ScAddress(7,0,0), "SUM(C1:F1)"))
    1065           0 :         CPPUNIT_FAIL("Wrong formula =SUM(C1:F1)");
    1066           1 :     CPPUNIT_ASSERT_EQUAL(16.5, rDoc.GetValue(7,0,0));
    1067             : 
    1068             :     // check string
    1069           2 :     ScRefCellValue aCell;
    1070           1 :     aCell.assign(rDoc, ScAddress(0,2,0));
    1071           1 :     CPPUNIT_ASSERT_EQUAL( CELLTYPE_STRING, aCell.meType );
    1072             : 
    1073             :     // check for an empty cell
    1074           1 :     aCell.assign(rDoc, ScAddress(0,3,0));
    1075           1 :     CPPUNIT_ASSERT_EQUAL( CELLTYPE_NONE, aCell.meType);
    1076             : 
    1077             :     // check a digit string
    1078           1 :     aCell.assign(rDoc, ScAddress(0,4,0));
    1079           1 :     CPPUNIT_ASSERT_EQUAL( CELLTYPE_STRING, aCell.meType);
    1080             : 
    1081             :     //check contiguous values
    1082           1 :     CPPUNIT_ASSERT_EQUAL( 12.0, rDoc.GetValue(0,5,0) );
    1083           1 :     CPPUNIT_ASSERT_EQUAL( OUString("a string"), rDoc.GetString(0,6,0) );
    1084           1 :     if (!checkFormula(rDoc, ScAddress(0,7,0), "$A$6"))
    1085           0 :         CPPUNIT_FAIL("Wrong formula =$A$6");
    1086           1 :     CPPUNIT_ASSERT_EQUAL( rDoc.GetValue(0,5,0), rDoc.GetValue(0,7,0) );
    1087             : 
    1088           2 :     xNewDocSh->DoClose();
    1089           1 : }
    1090             : 
    1091           1 : void ScExportTest::testCellNoteExportODS()
    1092             : {
    1093           1 :     ScDocShellRef xOrigDocSh = loadDoc("single-note.", ODS);
    1094           1 :     ScAddress aPos(0,0,0); // Start with A1.
    1095             :     {
    1096           1 :         ScDocument& rDoc = xOrigDocSh->GetDocument();
    1097             : 
    1098           1 :         CPPUNIT_ASSERT_MESSAGE("There should be a note at A1.", rDoc.HasNote(aPos));
    1099             : 
    1100           1 :         aPos.IncRow(); // Move to A2.
    1101           1 :         ScPostIt* pNote = rDoc.GetOrCreateNote(aPos);
    1102           1 :         pNote->SetText(aPos, "Note One");
    1103           1 :         pNote->SetAuthor("Author One");
    1104           1 :         CPPUNIT_ASSERT_MESSAGE("There should be a note at A2.", rDoc.HasNote(aPos));
    1105             :     }
    1106             :     // save and reload
    1107           2 :     ScDocShellRef xNewDocSh = saveAndReload(xOrigDocSh, ODS);
    1108           1 :     xOrigDocSh->DoClose();
    1109           1 :     CPPUNIT_ASSERT(xNewDocSh.Is());
    1110           1 :     ScDocument& rDoc = xNewDocSh->GetDocument();
    1111             : 
    1112           1 :     aPos.SetRow(0); // Move back to A1.
    1113           1 :     CPPUNIT_ASSERT_MESSAGE("There should be a note at A1.", rDoc.HasNote(aPos));
    1114           1 :     aPos.IncRow(); // Move to A2.
    1115           1 :     CPPUNIT_ASSERT_MESSAGE("There should be a note at A2.", rDoc.HasNote(aPos));
    1116             : 
    1117           2 :     xNewDocSh->DoClose();
    1118           1 : }
    1119             : 
    1120           1 : void ScExportTest::testCellNoteExportXLS()
    1121             : {
    1122             :     // Start with an empty document.s
    1123           1 :     ScDocShellRef xOrigDocSh = loadDoc("notes-on-3-sheets.", ODS);
    1124             :     {
    1125           1 :         ScDocument& rDoc = xOrigDocSh->GetDocument();
    1126           1 :         CPPUNIT_ASSERT_MESSAGE("This document should have 3 sheets.", rDoc.GetTableCount() == 3);
    1127             : 
    1128             :         // Check note's presence.
    1129           1 :         CPPUNIT_ASSERT( rDoc.HasNote(ScAddress(0,0,0)));
    1130           1 :         CPPUNIT_ASSERT(!rDoc.HasNote(ScAddress(0,1,0)));
    1131           1 :         CPPUNIT_ASSERT(!rDoc.HasNote(ScAddress(0,2,0)));
    1132             : 
    1133           1 :         CPPUNIT_ASSERT(!rDoc.HasNote(ScAddress(0,0,1)));
    1134           1 :         CPPUNIT_ASSERT( rDoc.HasNote(ScAddress(0,1,1)));
    1135           1 :         CPPUNIT_ASSERT(!rDoc.HasNote(ScAddress(0,2,1)));
    1136             : 
    1137           1 :         CPPUNIT_ASSERT(!rDoc.HasNote(ScAddress(0,0,2)));
    1138           1 :         CPPUNIT_ASSERT(!rDoc.HasNote(ScAddress(0,1,2)));
    1139           1 :         CPPUNIT_ASSERT( rDoc.HasNote(ScAddress(0,2,2)));
    1140             :     }
    1141             :     // save and reload as XLS.
    1142           2 :     ScDocShellRef xNewDocSh = saveAndReload(xOrigDocSh, XLS);
    1143             :     {
    1144           1 :         xOrigDocSh->DoClose();
    1145           1 :         CPPUNIT_ASSERT(xNewDocSh.Is());
    1146           1 :         ScDocument& rDoc = xNewDocSh->GetDocument();
    1147           1 :         CPPUNIT_ASSERT_MESSAGE("This document should have 3 sheets.", rDoc.GetTableCount() == 3);
    1148             : 
    1149             :         // Check note's presence again.
    1150           1 :         CPPUNIT_ASSERT( rDoc.HasNote(ScAddress(0,0,0)));
    1151           1 :         CPPUNIT_ASSERT(!rDoc.HasNote(ScAddress(0,1,0)));
    1152           1 :         CPPUNIT_ASSERT(!rDoc.HasNote(ScAddress(0,2,0)));
    1153             : 
    1154           1 :         CPPUNIT_ASSERT(!rDoc.HasNote(ScAddress(0,0,1)));
    1155           1 :         CPPUNIT_ASSERT( rDoc.HasNote(ScAddress(0,1,1)));
    1156           1 :         CPPUNIT_ASSERT(!rDoc.HasNote(ScAddress(0,2,1)));
    1157             : 
    1158           1 :         CPPUNIT_ASSERT(!rDoc.HasNote(ScAddress(0,0,2)));
    1159           1 :         CPPUNIT_ASSERT(!rDoc.HasNote(ScAddress(0,1,2)));
    1160           1 :         CPPUNIT_ASSERT( rDoc.HasNote(ScAddress(0,2,2)));
    1161             : 
    1162           1 :         xNewDocSh->DoClose();
    1163           1 :     }
    1164           1 : }
    1165             : 
    1166             : namespace {
    1167             : 
    1168           3 : void checkMatrixRange(ScDocument& rDoc, const ScRange& rRange)
    1169             : {
    1170           3 :     ScRange aMatRange;
    1171           3 :     ScAddress aMatOrigin;
    1172          10 :     for (SCCOL nCol = rRange.aStart.Col(); nCol <= rRange.aEnd.Col(); ++nCol)
    1173             :     {
    1174          23 :         for (SCROW nRow = rRange.aStart.Row(); nRow <= rRange.aEnd.Row(); ++nRow)
    1175             :         {
    1176          16 :             ScAddress aPos(nCol, nRow, rRange.aStart.Tab());
    1177          16 :             bool bIsMatrix = rDoc.GetMatrixFormulaRange(aPos, aMatRange);
    1178          16 :             CPPUNIT_ASSERT_MESSAGE("Matrix expected, but not found.", bIsMatrix);
    1179          16 :             CPPUNIT_ASSERT_MESSAGE("Wrong matrix range.", rRange == aMatRange);
    1180          16 :             const ScFormulaCell* pCell = rDoc.GetFormulaCell(aPos);
    1181          16 :             CPPUNIT_ASSERT_MESSAGE("This must be a formula cell.", pCell);
    1182             : 
    1183          16 :             bIsMatrix = pCell->GetMatrixOrigin(aMatOrigin);
    1184          16 :             CPPUNIT_ASSERT_MESSAGE("Not a part of matrix formula.", bIsMatrix);
    1185          16 :             CPPUNIT_ASSERT_MESSAGE("Wrong matrix origin.", aMatOrigin == aMatRange.aStart);
    1186             :         }
    1187             :     }
    1188           3 : }
    1189             : 
    1190             : }
    1191             : 
    1192           1 : void ScExportTest::testInlineArrayXLS()
    1193             : {
    1194           1 :     ScDocShellRef xShell = loadDoc("inline-array.", XLS);
    1195           1 :     CPPUNIT_ASSERT(xShell.Is());
    1196             : 
    1197           2 :     ScDocShellRef xDocSh = saveAndReload(xShell, XLS);
    1198           1 :     xShell->DoClose();
    1199           1 :     CPPUNIT_ASSERT(xDocSh.Is());
    1200             : 
    1201           1 :     ScDocument& rDoc = xDocSh->GetDocument();
    1202             : 
    1203             :     // B2:C3 contains a matrix.
    1204           1 :     checkMatrixRange(rDoc, ScRange(1,1,0,2,2,0));
    1205             : 
    1206             :     // B5:D6 contains a matrix.
    1207           1 :     checkMatrixRange(rDoc, ScRange(1,4,0,3,5,0));
    1208             : 
    1209             :     // B8:C10 as well.
    1210           1 :     checkMatrixRange(rDoc, ScRange(1,7,0,2,9,0));
    1211             : 
    1212           2 :     xDocSh->DoClose();
    1213           1 : }
    1214             : 
    1215           1 : void ScExportTest::testEmbeddedChartXLS()
    1216             : {
    1217           1 :     ScDocShellRef xShell = loadDoc("embedded-chart.", XLS);
    1218           1 :     CPPUNIT_ASSERT(xShell.Is());
    1219             : 
    1220           2 :     ScDocShellRef xDocSh = saveAndReload(xShell, XLS);
    1221           1 :     xShell->DoClose();
    1222           1 :     CPPUNIT_ASSERT(xDocSh.Is());
    1223             : 
    1224           1 :     ScDocument& rDoc = xDocSh->GetDocument();
    1225             : 
    1226             :     // Make sure the 2nd sheet is named 'Chart1'.
    1227           2 :     OUString aName;
    1228           1 :     rDoc.GetName(1, aName);
    1229           1 :     CPPUNIT_ASSERT_EQUAL(OUString("Chart1"), aName);
    1230             : 
    1231           1 :     const SdrOle2Obj* pOleObj = getSingleChartObject(rDoc, 1);
    1232           1 :     CPPUNIT_ASSERT_MESSAGE("Failed to retrieve a chart object from the 2nd sheet.", pOleObj);
    1233             : 
    1234           2 :     ScRangeList aRanges = getChartRanges(rDoc, *pOleObj);
    1235           1 :     CPPUNIT_ASSERT_MESSAGE("Label range (B3:B5) not found.", aRanges.In(ScRange(1,2,1,1,4,1)));
    1236           1 :     CPPUNIT_ASSERT_MESSAGE("Data label (C2) not found.", aRanges.In(ScAddress(2,1,1)));
    1237           1 :     CPPUNIT_ASSERT_MESSAGE("Data range (C3:C5) not found.", aRanges.In(ScRange(2,2,1,2,4,1)));
    1238             : 
    1239           2 :     xDocSh->DoClose();
    1240           1 : }
    1241             : 
    1242           1 : void ScExportTest::testFormulaReferenceXLS()
    1243             : {
    1244           1 :     ScDocShellRef xShell = loadDoc("formula-reference.", XLS);
    1245           1 :     CPPUNIT_ASSERT(xShell.Is());
    1246             : 
    1247           2 :     ScDocShellRef xDocSh = saveAndReload(xShell, XLS);
    1248           1 :     xShell->DoClose();
    1249           1 :     CPPUNIT_ASSERT(xDocSh.Is());
    1250             : 
    1251           1 :     ScDocument& rDoc = xDocSh->GetDocument();
    1252             : 
    1253           1 :     if (!checkFormula(rDoc, ScAddress(3,1,0), "$A$2+$B$2+$C$2"))
    1254           0 :         CPPUNIT_FAIL("Wrong formula in D2");
    1255             : 
    1256           1 :     if (!checkFormula(rDoc, ScAddress(3,2,0), "A3+B3+C3"))
    1257           0 :         CPPUNIT_FAIL("Wrong formula in D3");
    1258             : 
    1259           1 :     if (!checkFormula(rDoc, ScAddress(3,5,0), "SUM($A$6:$C$6)"))
    1260           0 :         CPPUNIT_FAIL("Wrong formula in D6");
    1261             : 
    1262           1 :     if (!checkFormula(rDoc, ScAddress(3,6,0), "SUM(A7:C7)"))
    1263           0 :         CPPUNIT_FAIL("Wrong formula in D7");
    1264             : 
    1265           1 :     if (!checkFormula(rDoc, ScAddress(3,9,0), "$Two.$A$2+$Two.$B$2+$Two.$C$2"))
    1266           0 :         CPPUNIT_FAIL("Wrong formula in D10");
    1267             : 
    1268           1 :     if (!checkFormula(rDoc, ScAddress(3,10,0), "$Two.A3+$Two.B3+$Two.C3"))
    1269           0 :         CPPUNIT_FAIL("Wrong formula in D11");
    1270             : 
    1271           1 :     if (!checkFormula(rDoc, ScAddress(3,13,0), "MIN($Two.$A$2:$C$2)"))
    1272           0 :         CPPUNIT_FAIL("Wrong formula in D14");
    1273             : 
    1274           1 :     if (!checkFormula(rDoc, ScAddress(3,14,0), "MAX($Two.A3:C3)"))
    1275           0 :         CPPUNIT_FAIL("Wrong formula in D15");
    1276             : 
    1277           2 :     xDocSh->DoClose();
    1278           1 : }
    1279             : 
    1280           1 : void ScExportTest::testSheetProtectionXLSX()
    1281             : {
    1282           1 :     ScDocShellRef xShell = loadDoc("ProtecteSheet1234Pass.", XLSX);
    1283           1 :     CPPUNIT_ASSERT(xShell.Is());
    1284             : 
    1285           2 :     ScDocShellRef xDocSh = saveAndReload(xShell, XLSX);
    1286           1 :     CPPUNIT_ASSERT(xDocSh.Is());
    1287             : 
    1288           1 :     ScDocument& rDoc = xDocSh->GetDocument();
    1289           1 :     const ScTableProtection* pTabProtect = rDoc.GetTabProtection(0);
    1290           1 :     CPPUNIT_ASSERT(pTabProtect);
    1291           1 :     if ( pTabProtect )
    1292             :     {
    1293           1 :         Sequence<sal_Int8> aHash = pTabProtect->getPasswordHash(PASSHASH_XL);
    1294             :         // check has
    1295           1 :         if (aHash.getLength() >= 2)
    1296             :         {
    1297           1 :             CPPUNIT_ASSERT( (sal_uInt8)aHash[0] == 204 );
    1298           1 :             CPPUNIT_ASSERT( (sal_uInt8)aHash[1] == 61 );
    1299             :         }
    1300             :         // we could flesh out this check I guess
    1301           1 :         CPPUNIT_ASSERT ( !pTabProtect->isOptionEnabled( ScTableProtection::OBJECTS ) );
    1302           1 :         CPPUNIT_ASSERT ( !pTabProtect->isOptionEnabled( ScTableProtection::SCENARIOS ) );
    1303             :     }
    1304           2 :     xDocSh->DoClose();
    1305           1 : }
    1306             : 
    1307             : namespace {
    1308             : 
    1309          96 : const char* toBorderName( sal_Int16 eStyle )
    1310             : {
    1311          96 :     switch (eStyle)
    1312             :     {
    1313          32 :         case table::BorderLineStyle::SOLID: return "SOLID";
    1314           8 :         case table::BorderLineStyle::DOTTED: return "DOTTED";
    1315           8 :         case table::BorderLineStyle::DASHED: return "DASHED";
    1316          16 :         case table::BorderLineStyle::DASH_DOT: return "DASH_DOT";
    1317          16 :         case table::BorderLineStyle::DASH_DOT_DOT: return "DASH_DOT_DOT";
    1318           8 :         case table::BorderLineStyle::DOUBLE_THIN: return "DOUBLE_THIN";
    1319           8 :         case table::BorderLineStyle::FINE_DASHED: return "FINE_DASHED";
    1320             :         default:
    1321             :             ;
    1322             :     }
    1323             : 
    1324           0 :     return "";
    1325             : }
    1326             : 
    1327             : }
    1328             : 
    1329           2 : void ScExportTest::testExcelCellBorders( sal_uLong nFormatType )
    1330             : {
    1331             :     struct
    1332             :     {
    1333             :         SCROW mnRow;
    1334             :         sal_Int16 mnStyle;
    1335             :         long mnWidth;
    1336             :     } aChecks[] = {
    1337             :         {  1, table::BorderLineStyle::SOLID,         1L }, // hair
    1338             :         {  3, table::BorderLineStyle::DOTTED,       15L }, // dotted
    1339             :         {  5, table::BorderLineStyle::DASH_DOT_DOT, 15L }, // dash dot dot
    1340             :         {  7, table::BorderLineStyle::DASH_DOT,     15L }, // dash dot
    1341             :         {  9, table::BorderLineStyle::FINE_DASHED,  15L }, // dashed
    1342             :         { 11, table::BorderLineStyle::SOLID,        15L }, // thin
    1343             :         { 13, table::BorderLineStyle::DASH_DOT_DOT, 35L }, // medium dash dot dot
    1344             :         { 17, table::BorderLineStyle::DASH_DOT,     35L }, // medium dash dot
    1345             :         { 19, table::BorderLineStyle::DASHED,       35L }, // medium dashed
    1346             :         { 21, table::BorderLineStyle::SOLID,        35L }, // medium
    1347             :         { 23, table::BorderLineStyle::SOLID,        50L }, // thick
    1348             :         { 25, table::BorderLineStyle::DOUBLE_THIN,  -1L }, // double (don't check width)
    1349           2 :     };
    1350             : 
    1351           2 :     ScDocShellRef xDocSh = loadDoc("cell-borders.", nFormatType);
    1352           2 :     CPPUNIT_ASSERT_MESSAGE("Failed to load file", xDocSh.Is());
    1353             :     {
    1354           2 :         ScDocument& rDoc = xDocSh->GetDocument();
    1355             : 
    1356          26 :         for (size_t i = 0; i < SAL_N_ELEMENTS(aChecks); ++i)
    1357             :         {
    1358          24 :             const editeng::SvxBorderLine* pLine = NULL;
    1359          24 :             rDoc.GetBorderLines(2, aChecks[i].mnRow, 0, NULL, &pLine, NULL, NULL);
    1360          24 :             CPPUNIT_ASSERT(pLine);
    1361          24 :             CPPUNIT_ASSERT_EQUAL(toBorderName(aChecks[i].mnStyle), toBorderName(pLine->GetBorderLineStyle()));
    1362          24 :             if (aChecks[i].mnWidth >= 0)
    1363          22 :                 CPPUNIT_ASSERT_EQUAL(aChecks[i].mnWidth, pLine->GetWidth());
    1364             :         }
    1365             :     }
    1366             : 
    1367           4 :     ScDocShellRef xNewDocSh = saveAndReload(xDocSh, nFormatType);
    1368           2 :     xDocSh->DoClose();
    1369           2 :     ScDocument& rDoc = xNewDocSh->GetDocument();
    1370          26 :     for (size_t i = 0; i < SAL_N_ELEMENTS(aChecks); ++i)
    1371             :     {
    1372          24 :         const editeng::SvxBorderLine* pLine = NULL;
    1373          24 :         rDoc.GetBorderLines(2, aChecks[i].mnRow, 0, NULL, &pLine, NULL, NULL);
    1374          24 :         CPPUNIT_ASSERT(pLine);
    1375          24 :         CPPUNIT_ASSERT_EQUAL(toBorderName(aChecks[i].mnStyle), toBorderName(pLine->GetBorderLineStyle()));
    1376          24 :         if (aChecks[i].mnWidth >= 0)
    1377          22 :             CPPUNIT_ASSERT_EQUAL(aChecks[i].mnWidth, pLine->GetWidth());
    1378             :     }
    1379             : 
    1380           4 :     xNewDocSh->DoClose();
    1381           2 : }
    1382             : 
    1383           1 : void ScExportTest::testCellBordersXLS()
    1384             : {
    1385           1 :     testExcelCellBorders(XLS);
    1386           1 : }
    1387             : 
    1388           1 : void ScExportTest::testCellBordersXLSX()
    1389             : {
    1390           1 :     testExcelCellBorders(XLSX);
    1391           1 : }
    1392             : 
    1393           0 : OUString toString( const ScBigRange& rRange )
    1394             : {
    1395           0 :     OUStringBuffer aBuf;
    1396           0 :     aBuf.appendAscii("(columns:");
    1397           0 :     aBuf.append(rRange.aStart.Col());
    1398           0 :     aBuf.append('-');
    1399           0 :     aBuf.append(rRange.aEnd.Col());
    1400           0 :     aBuf.appendAscii(";rows:");
    1401           0 :     aBuf.append(rRange.aStart.Row());
    1402           0 :     aBuf.append('-');
    1403           0 :     aBuf.append(rRange.aEnd.Row());
    1404           0 :     aBuf.appendAscii(";sheets:");
    1405           0 :     aBuf.append(rRange.aStart.Tab());
    1406           0 :     aBuf.append('-');
    1407           0 :     aBuf.append(rRange.aEnd.Tab());
    1408           0 :     aBuf.append(')');
    1409             : 
    1410           0 :     return aBuf.makeStringAndClear();
    1411             : }
    1412             : 
    1413           1 : void ScExportTest::testTrackChangesSimpleXLSX()
    1414             : {
    1415             :     struct CheckItem
    1416             :     {
    1417             :         sal_uLong mnActionId;
    1418             :         ScChangeActionType meType;
    1419             : 
    1420             :         sal_Int32 mnStartCol;
    1421             :         sal_Int32 mnStartRow;
    1422             :         sal_Int32 mnStartTab;
    1423             :         sal_Int32 mnEndCol;
    1424             :         sal_Int32 mnEndRow;
    1425             :         sal_Int32 mnEndTab;
    1426             : 
    1427             :         bool mbRowInsertedAtBottom;
    1428             :     };
    1429             : 
    1430             :     struct
    1431             :     {
    1432          52 :         bool checkRange( ScChangeActionType eType, const ScBigRange& rExpected, const ScBigRange& rActual )
    1433             :         {
    1434          52 :             ScBigRange aExpected(rExpected), aActual(rActual);
    1435             : 
    1436          52 :             switch (eType)
    1437             :             {
    1438             :                 case SC_CAT_INSERT_ROWS:
    1439             :                 {
    1440             :                     // Ignore columns.
    1441          24 :                     aExpected.aStart.SetCol(0);
    1442          24 :                     aExpected.aEnd.SetCol(0);
    1443          24 :                     aActual.aStart.SetCol(0);
    1444          24 :                     aActual.aEnd.SetCol(0);
    1445             :                 }
    1446          24 :                 break;
    1447             :                 default:
    1448             :                     ;
    1449             :             }
    1450             : 
    1451          52 :             return aExpected == aActual;
    1452             :         }
    1453             : 
    1454           4 :         bool check( ScDocument& rDoc )
    1455             :         {
    1456             :             CheckItem aChecks[] =
    1457             :             {
    1458             :                 {  1, SC_CAT_CONTENT     , 1, 1, 0, 1, 1, 0, false },
    1459             :                 {  2, SC_CAT_INSERT_ROWS , 0, 2, 0, 0, 2, 0, true },
    1460             :                 {  3, SC_CAT_CONTENT     , 1, 2, 0, 1, 2, 0, false },
    1461             :                 {  4, SC_CAT_INSERT_ROWS , 0, 3, 0, 0, 3, 0, true  },
    1462             :                 {  5, SC_CAT_CONTENT     , 1, 3, 0, 1, 3, 0, false },
    1463             :                 {  6, SC_CAT_INSERT_ROWS , 0, 4, 0, 0, 4, 0, true  },
    1464             :                 {  7, SC_CAT_CONTENT     , 1, 4, 0, 1, 4, 0, false },
    1465             :                 {  8, SC_CAT_INSERT_ROWS , 0, 5, 0, 0, 5, 0, true  },
    1466             :                 {  9, SC_CAT_CONTENT     , 1, 5, 0, 1, 5, 0, false },
    1467             :                 { 10, SC_CAT_INSERT_ROWS , 0, 6, 0, 0, 6, 0, true  },
    1468             :                 { 11, SC_CAT_CONTENT     , 1, 6, 0, 1, 6, 0, false },
    1469             :                 { 12, SC_CAT_INSERT_ROWS , 0, 7, 0, 0, 7, 0, true  },
    1470             :                 { 13, SC_CAT_CONTENT     , 1, 7, 0, 1, 7, 0, false },
    1471           4 :             };
    1472             : 
    1473           4 :             ScChangeTrack* pCT = rDoc.GetChangeTrack();
    1474           4 :             if (!pCT)
    1475             :             {
    1476           0 :                 cerr << "Change track instance doesn't exist." << endl;
    1477           0 :                 return false;
    1478             :             }
    1479             : 
    1480           4 :             sal_uLong nActionMax = pCT->GetActionMax();
    1481           4 :             if (nActionMax != 13)
    1482             :             {
    1483           0 :                 cerr << "Unexpected highest action ID value." << endl;
    1484           0 :                 return false;
    1485             :             }
    1486             : 
    1487         112 :             for (size_t i = 0, n = SAL_N_ELEMENTS(aChecks); i < n; ++i)
    1488             :             {
    1489          52 :                 sal_uInt16 nActId = aChecks[i].mnActionId;
    1490          52 :                 const ScChangeAction* pAction = pCT->GetAction(nActId);
    1491          52 :                 if (!pAction)
    1492             :                 {
    1493           0 :                     cerr << "No action for action number " << nActId << " found." << endl;
    1494           0 :                     return false;
    1495             :                 }
    1496             : 
    1497          52 :                 if (pAction->GetType() != aChecks[i].meType)
    1498             :                 {
    1499           0 :                     cerr << "Unexpected action type for action number " << nActId << "." << endl;
    1500           0 :                     return false;
    1501             :                 }
    1502             : 
    1503          52 :                 const ScBigRange& rRange = pAction->GetBigRange();
    1504             :                 ScBigRange aCheck(aChecks[i].mnStartCol, aChecks[i].mnStartRow, aChecks[i].mnStartTab,
    1505          52 :                                   aChecks[i].mnEndCol, aChecks[i].mnEndRow, aChecks[i].mnEndTab);
    1506             : 
    1507          52 :                 if (!checkRange(pAction->GetType(), aCheck, rRange))
    1508             :                 {
    1509           0 :                     cerr << "Unexpected range for action number " << nActId
    1510           0 :                         << ": expected=" << toString(aCheck) << " actual=" << toString(rRange) << endl;
    1511           0 :                     return false;
    1512             :                 }
    1513             : 
    1514          52 :                 switch (pAction->GetType())
    1515             :                 {
    1516             :                     case SC_CAT_INSERT_ROWS:
    1517             :                     {
    1518          24 :                         const ScChangeActionIns* p = static_cast<const ScChangeActionIns*>(pAction);
    1519          24 :                         if (p->IsEndOfList() != aChecks[i].mbRowInsertedAtBottom)
    1520             :                         {
    1521           0 :                             cerr << "Unexpected end-of-list flag for action number " << nActId << "." << endl;
    1522           0 :                             return false;
    1523             :                         }
    1524             :                     }
    1525          24 :                     break;
    1526             :                     default:
    1527             :                         ;
    1528             :                 }
    1529             :             }
    1530             : 
    1531           4 :             return true;
    1532             :         }
    1533             : 
    1534           2 :         bool checkRevisionUserAndTime( ScDocument& rDoc, const OUString& rOwnerName )
    1535             :         {
    1536           2 :             ScChangeTrack* pCT = rDoc.GetChangeTrack();
    1537           2 :             if (!pCT)
    1538             :             {
    1539           0 :                 cerr << "Change track instance doesn't exist." << endl;
    1540           0 :                 return false;
    1541             :             }
    1542             : 
    1543           2 :             ScChangeAction* pAction = pCT->GetLast();
    1544           2 :             if (pAction->GetUser() != "Kohei Yoshida")
    1545             :             {
    1546           0 :                 cerr << "Wrong user name." << endl;
    1547           0 :                 return false;
    1548             :             }
    1549             : 
    1550           2 :             DateTime aDT = pAction->GetDateTime();
    1551           2 :             if (aDT.GetYear() != 2014 || aDT.GetMonth() != 7 || aDT.GetDay() != 11)
    1552             :             {
    1553           0 :                 cerr << "Wrong time stamp." << endl;
    1554           0 :                 return false;
    1555             :             }
    1556             : 
    1557             :             // Insert a new record to make sure the user and date-time are correct.
    1558           2 :             rDoc.SetString(ScAddress(1,8,0), "New String");
    1559           2 :             ScCellValue aEmpty;
    1560           2 :             pCT->AppendContent(ScAddress(1,8,0), aEmpty);
    1561           2 :             pAction = pCT->GetLast();
    1562           2 :             if (!pAction)
    1563             :             {
    1564           0 :                 cerr << "Failed to retrieve last revision." << endl;
    1565           0 :                 return false;
    1566             :             }
    1567             : 
    1568           2 :             if (rOwnerName != pAction->GetUser())
    1569             :             {
    1570           0 :                 cerr << "Wrong user name." << endl;
    1571           0 :                 return false;
    1572             :             }
    1573             : 
    1574           2 :             DateTime aDTNew = pAction->GetDateTime();
    1575           2 :             if (aDTNew <= aDT)
    1576             :             {
    1577           0 :                 cerr << "Time stamp of the new revision should be more recent than that of the last revision." << endl;
    1578           0 :                 return false;
    1579             :             }
    1580             : 
    1581           2 :             return true;
    1582             :         }
    1583             : 
    1584             :     } aTest;
    1585             : 
    1586           1 :     SvtUserOptions& rUserOpt = SC_MOD()->GetUserOptions();
    1587           1 :     rUserOpt.SetToken(UserOptToken::FirstName, "Export");
    1588           1 :     rUserOpt.SetToken(UserOptToken::LastName, "Test");
    1589             : 
    1590           1 :     OUString aOwnerName = rUserOpt.GetFirstName() + " " + rUserOpt.GetLastName();
    1591             : 
    1592             :     // First, test the xls variant.
    1593             : 
    1594           2 :     ScDocShellRef xDocSh = loadDoc("track-changes/simple-cell-changes.", XLS);
    1595           1 :     CPPUNIT_ASSERT(xDocSh.Is());
    1596           1 :     ScDocument* pDoc = &xDocSh->GetDocument();
    1597           1 :     bool bGood = aTest.check(*pDoc);
    1598           1 :     CPPUNIT_ASSERT_MESSAGE("Initial check failed (xls).", bGood);
    1599             : 
    1600           2 :     ScDocShellRef xDocSh2 = saveAndReload(xDocSh, XLS);
    1601           1 :     xDocSh->DoClose();
    1602           1 :     pDoc = &xDocSh2->GetDocument();
    1603           1 :     bGood = aTest.check(*pDoc);
    1604           1 :     CPPUNIT_ASSERT_MESSAGE("Check after reload failed (xls).", bGood);
    1605             : 
    1606             :     // fdo#81445 : Check the blank value string to make sure it's "<empty>".
    1607           1 :     ScChangeTrack* pCT = pDoc->GetChangeTrack();
    1608           1 :     CPPUNIT_ASSERT(pCT);
    1609           1 :     ScChangeAction* pAction = pCT->GetAction(1);
    1610           1 :     CPPUNIT_ASSERT(pAction);
    1611           2 :     OUString aDesc;
    1612           1 :     pAction->GetDescription(aDesc, pDoc);
    1613           1 :     CPPUNIT_ASSERT_EQUAL(OUString("Cell B2 changed from '<empty>' to '1'"), aDesc);
    1614             : 
    1615           1 :     bGood = aTest.checkRevisionUserAndTime(*pDoc, aOwnerName);
    1616           1 :     CPPUNIT_ASSERT_MESSAGE("Check revision and time failed after reload (xls).", bGood);
    1617             : 
    1618           1 :     xDocSh2->DoClose();
    1619             : 
    1620             :     // Now, test the xlsx variant the same way.
    1621             : 
    1622           1 :     xDocSh = loadDoc("track-changes/simple-cell-changes.", XLSX);
    1623           1 :     CPPUNIT_ASSERT(xDocSh.Is());
    1624           1 :     pDoc = &xDocSh->GetDocument();
    1625           1 :     aTest.check(*pDoc);
    1626           1 :     CPPUNIT_ASSERT_MESSAGE("Initial check failed (xlsx).", bGood);
    1627             : 
    1628           1 :     xDocSh2 = saveAndReload(xDocSh, XLSX);
    1629           1 :     xDocSh->DoClose();
    1630           1 :     pDoc = &xDocSh2->GetDocument();
    1631           1 :     bGood = aTest.check(*pDoc);
    1632           1 :     CPPUNIT_ASSERT_MESSAGE("Check after reload failed (xlsx).", bGood);
    1633             : 
    1634           1 :     bGood = aTest.checkRevisionUserAndTime(*pDoc, aOwnerName);
    1635           1 :     CPPUNIT_ASSERT_MESSAGE("Check revision and time failed after reload (xlsx).", bGood);
    1636             : 
    1637           2 :     xDocSh2->DoClose();
    1638           1 : }
    1639             : 
    1640           1 : void ScExportTest::testSheetTabColorsXLSX()
    1641             : {
    1642             :     struct
    1643             :     {
    1644           2 :         bool checkContent( ScDocument& rDoc )
    1645             :         {
    1646             : 
    1647           2 :             std::vector<OUString> aTabNames = rDoc.GetAllTableNames();
    1648             : 
    1649             :             // green, red, blue, yellow (from left to right).
    1650           2 :             if (aTabNames.size() != 4)
    1651             :             {
    1652           0 :                 cerr << "There should be exactly 4 sheets." << endl;
    1653           0 :                 return false;
    1654             :             }
    1655             : 
    1656           2 :             const char* pNames[] = { "Green", "Red", "Blue", "Yellow" };
    1657          10 :             for (size_t i = 0, n = SAL_N_ELEMENTS(pNames); i < n; ++i)
    1658             :             {
    1659           8 :                 OUString aExpected = OUString::createFromAscii(pNames[i]);
    1660           8 :                 if (aExpected != aTabNames[i])
    1661             :                 {
    1662           0 :                     cerr << "incorrect sheet name: expected='" << aExpected <<"', actual='" << aTabNames[i] << "'" << endl;
    1663           0 :                     return false;
    1664             :                 }
    1665           8 :             }
    1666             : 
    1667             :             const ColorData aXclColors[] =
    1668             :             {
    1669             :                 0x0000B050, // green
    1670             :                 0x00FF0000, // red
    1671             :                 0x000070C0, // blue
    1672             :                 0x00FFFF00, // yellow
    1673           2 :             };
    1674             : 
    1675          10 :             for (size_t i = 0, n = SAL_N_ELEMENTS(aXclColors); i < n; ++i)
    1676             :             {
    1677           8 :                 if (aXclColors[i] != rDoc.GetTabBgColor(i).GetColor())
    1678             :                 {
    1679           0 :                     cerr << "wrong sheet color for sheet " << i << endl;
    1680           0 :                     return false;
    1681             :                 }
    1682             :             }
    1683             : 
    1684           2 :             return true;
    1685             :         }
    1686             : 
    1687             :     } aTest;
    1688             : 
    1689           1 :     ScDocShellRef xDocSh = loadDoc("sheet-tab-color.", XLSX);
    1690             :     {
    1691           1 :         CPPUNIT_ASSERT_MESSAGE("Failed to load file.", xDocSh.Is());
    1692           1 :         ScDocument& rDoc = xDocSh->GetDocument();
    1693           1 :         bool bRes = aTest.checkContent(rDoc);
    1694           1 :         CPPUNIT_ASSERT_MESSAGE("Failed on the initial content check.", bRes);
    1695             :     }
    1696             : 
    1697           2 :     ScDocShellRef xDocSh2 = saveAndReload(xDocSh, XLSX);
    1698           1 :     CPPUNIT_ASSERT_MESSAGE("Failed to reload file.", xDocSh2.Is());
    1699           1 :     xDocSh->DoClose();
    1700           1 :     ScDocument& rDoc = xDocSh2->GetDocument();
    1701           1 :     bool bRes = aTest.checkContent(rDoc);
    1702           1 :     CPPUNIT_ASSERT_MESSAGE("Failed on the content check after reload.", bRes);
    1703             : 
    1704           2 :     xDocSh2->DoClose();
    1705           1 : }
    1706             : 
    1707           1 : void ScExportTest::testSharedFormulaExportXLS()
    1708             : {
    1709             :     struct
    1710             :     {
    1711           2 :         bool checkContent( ScDocument& rDoc )
    1712             :         {
    1713           2 :             formula::FormulaGrammar::Grammar eGram = formula::FormulaGrammar::GRAM_ENGLISH_XL_R1C1;
    1714           2 :             rDoc.SetGrammar(eGram);
    1715           2 :             sc::TokenStringContext aCxt(&rDoc, eGram);
    1716             : 
    1717             :             // Check the title row.
    1718             : 
    1719           4 :             OUString aActual = rDoc.GetString(0,1,0);
    1720           4 :             OUString aExpected = "Response";
    1721           2 :             if (aActual != aExpected)
    1722             :             {
    1723           0 :                 cerr << "Wrong content in A2: expected='" << aExpected << "', actual='" << aActual << "'" << endl;
    1724           0 :                 return false;
    1725             :             }
    1726             : 
    1727           2 :             aActual = rDoc.GetString(1,1,0);
    1728           2 :             aExpected = "Response";
    1729           2 :             if (aActual != aExpected)
    1730             :             {
    1731           0 :                 cerr << "Wrong content in B2: expected='" << aExpected << "', actual='" << aActual << "'" << endl;
    1732           0 :                 return false;
    1733             :             }
    1734             : 
    1735             :             // A3:A12 and B3:B12 are numbers from 1 to 10.
    1736          44 :             for (SCROW i = 0; i <= 9; ++i)
    1737             :             {
    1738          20 :                 double fExpected = i + 1.0;
    1739          20 :                 ScAddress aPos(0,i+2,0);
    1740          20 :                 double fActual = rDoc.GetValue(aPos);
    1741          20 :                 if (fExpected != fActual)
    1742             :                 {
    1743           0 :                     cerr << "Wrong value in A" << (i+2) << ": expected=" << fExpected << ", actual=" << fActual << endl;
    1744           0 :                     return false;
    1745             :                 }
    1746             : 
    1747          20 :                 aPos.IncCol();
    1748          20 :                 ScFormulaCell* pFC = rDoc.GetFormulaCell(aPos);
    1749          20 :                 if (!pFC)
    1750             :                 {
    1751           0 :                     cerr << "B" << (i+2) << " should be a formula cell." << endl;
    1752           0 :                     return false;
    1753             :                 }
    1754             : 
    1755          20 :                 OUString aFormula = pFC->GetCode()->CreateString(aCxt, aPos);
    1756          20 :                 aExpected = "Coefficients!RC[-1]";
    1757          20 :                 if (aFormula != aExpected)
    1758             :                 {
    1759           0 :                     cerr << "Wrong formula in B" << (i+2) << ": expected='" << aExpected << "', actual='" << aFormula << "'" << endl;
    1760           0 :                     return false;
    1761             :                 }
    1762             : 
    1763          20 :                 fActual = rDoc.GetValue(aPos);
    1764          20 :                 if (fExpected != fActual)
    1765             :                 {
    1766           0 :                     cerr << "Wrong value in B" << (i+2) << ": expected=" << fExpected << ", actual=" << fActual << endl;
    1767           0 :                     return false;
    1768             :                 }
    1769          20 :             }
    1770             : 
    1771           4 :             return true;
    1772             :         }
    1773             : 
    1774             :     } aTest;
    1775             : 
    1776           1 :     ScDocShellRef xDocSh = loadDoc("shared-formula/3d-reference.", ODS);
    1777             :     {
    1778           1 :         CPPUNIT_ASSERT_MESSAGE("Failed to load file.", xDocSh.Is());
    1779           1 :         ScDocument& rDoc = xDocSh->GetDocument();
    1780             : 
    1781             :         // Check the content of the original.
    1782           1 :         bool bRes = aTest.checkContent(rDoc);
    1783           1 :         CPPUNIT_ASSERT_MESSAGE("Content check on the original document failed.", bRes);
    1784             :     }
    1785             : 
    1786           2 :     ScDocShellRef xDocSh2 = saveAndReload(xDocSh, XLS);
    1787           1 :     xDocSh->DoClose();
    1788           1 :     CPPUNIT_ASSERT_MESSAGE("Failed to reload file.", xDocSh2.Is());
    1789             : 
    1790           1 :     ScDocument& rDoc = xDocSh2->GetDocument();
    1791             : 
    1792             :     // Check the content of the reloaded. This should be identical.
    1793           1 :     bool bRes = aTest.checkContent(rDoc);
    1794           1 :     CPPUNIT_ASSERT_MESSAGE("Content check on the reloaded document failed.", bRes);
    1795             : 
    1796           2 :     xDocSh2->DoClose();
    1797           1 : }
    1798             : 
    1799           1 : void ScExportTest::testSharedFormulaExportXLSX()
    1800             : {
    1801             :     struct
    1802             :     {
    1803           3 :         bool checkContent( ScDocument& rDoc )
    1804             :         {
    1805           3 :             SCTAB nTabCount = rDoc.GetTableCount();
    1806           3 :             if (nTabCount != 2)
    1807             :             {
    1808           0 :                 cerr << "Document should have exactly 2 sheets.  " << nTabCount << " found." << endl;
    1809           0 :                 return false;
    1810             :             }
    1811             : 
    1812             :             // Make sure the sheet tab colors are not set.
    1813           9 :             for (SCROW i = 0; i <= 1; ++i)
    1814             :             {
    1815           6 :                 Color aTabBgColor = rDoc.GetTabBgColor(i);
    1816           6 :                 if (aTabBgColor != Color(COL_AUTO))
    1817             :                 {
    1818           0 :                     cerr << "The tab color of Sheet " << (i+1) << " should not be explicitly set." << endl;
    1819           0 :                     return false;
    1820             :                 }
    1821             :             }
    1822             : 
    1823             :             // B2:B7 should show 1,2,3,4,5,6.
    1824           3 :             double fExpected = 1.0;
    1825          21 :             for (SCROW i = 1; i <= 6; ++i, ++fExpected)
    1826             :             {
    1827          18 :                 ScAddress aPos(1,i,0);
    1828          18 :                 double fVal = rDoc.GetValue(aPos);
    1829          18 :                 if (fVal != fExpected)
    1830             :                 {
    1831           0 :                     cerr << "Wrong value in B" << (i+1) << ": expected=" << fExpected << ", actual=" << fVal << endl;
    1832           0 :                     return false;
    1833             :                 }
    1834             :             }
    1835             : 
    1836             :             // C2:C7 should show 10,20,....,60.
    1837           3 :             fExpected = 10.0;
    1838          21 :             for (SCROW i = 1; i <= 6; ++i, fExpected+=10.0)
    1839             :             {
    1840          18 :                 ScAddress aPos(2,i,0);
    1841          18 :                 double fVal = rDoc.GetValue(aPos);
    1842          18 :                 if (fVal != fExpected)
    1843             :                 {
    1844           0 :                     cerr << "Wrong value in C" << (i+1) << ": expected=" << fExpected << ", actual=" << fVal << endl;
    1845           0 :                     return false;
    1846             :                 }
    1847             :             }
    1848             : 
    1849             :             // D2:D7 should show 1,2,...,6.
    1850           3 :             fExpected = 1.0;
    1851          21 :             for (SCROW i = 1; i <= 6; ++i, ++fExpected)
    1852             :             {
    1853          18 :                 ScAddress aPos(3,i,0);
    1854          18 :                 double fVal = rDoc.GetValue(aPos);
    1855          18 :                 if (fVal != fExpected)
    1856             :                 {
    1857           0 :                     cerr << "Wrong value in D" << (i+1) << ": expected=" << fExpected << ", actual=" << fVal << endl;
    1858           0 :                     return false;
    1859             :                 }
    1860             :             }
    1861             : 
    1862           3 :             return true;
    1863             :         }
    1864             : 
    1865             :     } aTest;
    1866             : 
    1867           1 :     ScDocShellRef xDocSh = loadDoc("shared-formula/3d-reference.", XLSX);
    1868             :     {
    1869           1 :         CPPUNIT_ASSERT_MESSAGE("Failed to load file.", xDocSh.Is());
    1870           1 :         ScDocument& rDoc = xDocSh->GetDocument();
    1871             : 
    1872           1 :         bool bRes = aTest.checkContent(rDoc);
    1873           1 :         CPPUNIT_ASSERT_MESSAGE("Content check on the initial document failed.", bRes);
    1874             : 
    1875           1 :         rDoc.CalcAll(); // Recalculate to flush all cached results.
    1876           1 :         bRes = aTest.checkContent(rDoc);
    1877           1 :         CPPUNIT_ASSERT_MESSAGE("Content check on the initial recalculated document failed.", bRes);
    1878             :     }
    1879             : 
    1880             :     // Save and reload, and check the content again.
    1881           2 :     ScDocShellRef xDocSh2 = saveAndReload(xDocSh, XLSX);
    1882           1 :     xDocSh->DoClose();
    1883             : 
    1884           1 :     CPPUNIT_ASSERT_MESSAGE("Failed to load file.", xDocSh2.Is());
    1885           1 :     ScDocument& rDoc = xDocSh2->GetDocument();
    1886           1 :     rDoc.CalcAll(); // Recalculate to flush all cached results.
    1887             : 
    1888           1 :     bool bRes = aTest.checkContent(rDoc);
    1889           1 :     CPPUNIT_ASSERT_MESSAGE("Content check on the reloaded document failed.", bRes);
    1890             : 
    1891           2 :     xDocSh2->DoClose();
    1892           1 : }
    1893             : 
    1894           1 : void ScExportTest::testSharedFormulaStringResultExportXLSX()
    1895             : {
    1896             :     struct
    1897             :     {
    1898           3 :         bool checkContent( ScDocument& rDoc )
    1899             :         {
    1900             :             {
    1901             :                 // B2:B7 should show A,B,....,F.
    1902           3 :                 const char* expected[] = { "A", "B", "C", "D", "E", "F" };
    1903          21 :                 for (SCROW i = 0; i <= 5; ++i)
    1904             :                 {
    1905          18 :                     ScAddress aPos(1,i+1,0);
    1906          18 :                     OUString aStr = rDoc.GetString(aPos);
    1907          36 :                     OUString aExpected = OUString::createFromAscii(expected[i]);
    1908          18 :                     if (aStr != aExpected)
    1909             :                     {
    1910           0 :                         cerr << "Wrong value in B" << (i+2) << ": expected='" << aExpected << "', actual='" << aStr << "'" << endl;
    1911           0 :                         return false;
    1912             :                     }
    1913          18 :                 }
    1914             :             }
    1915             : 
    1916             :             {
    1917             :                 // C2:C7 should show AA,BB,....,FF.
    1918           3 :                 const char* expected[] = { "AA", "BB", "CC", "DD", "EE", "FF" };
    1919          21 :                 for (SCROW i = 0; i <= 5; ++i)
    1920             :                 {
    1921          18 :                     ScAddress aPos(2,i+1,0);
    1922          18 :                     OUString aStr = rDoc.GetString(aPos);
    1923          36 :                     OUString aExpected = OUString::createFromAscii(expected[i]);
    1924          18 :                     if (aStr != aExpected)
    1925             :                     {
    1926           0 :                         cerr << "Wrong value in C" << (i+2) << ": expected='" << aExpected << "', actual='" << aStr << "'" << endl;
    1927           0 :                         return false;
    1928             :                     }
    1929          18 :                 }
    1930             :             }
    1931             : 
    1932           3 :             return true;
    1933             :         }
    1934             : 
    1935             :     } aTest;
    1936             : 
    1937           1 :     ScDocShellRef xDocSh = loadDoc("shared-formula/text-results.", XLSX);
    1938             :     {
    1939           1 :         CPPUNIT_ASSERT_MESSAGE("Failed to load file.", xDocSh.Is());
    1940           1 :         ScDocument& rDoc = xDocSh->GetDocument();
    1941             : 
    1942             :         // Check content without re-calculation, to test cached formula results.
    1943           1 :         bool bRes = aTest.checkContent(rDoc);
    1944           1 :         CPPUNIT_ASSERT_MESSAGE("Content check on the initial document failed.", bRes);
    1945             : 
    1946             :         // Now, re-calculate and check the results.
    1947           1 :         rDoc.CalcAll();
    1948           1 :         bRes = aTest.checkContent(rDoc);
    1949           1 :         CPPUNIT_ASSERT_MESSAGE("Content check on the initial recalculated document failed.", bRes);
    1950             :     }
    1951             :     // Reload and check again.
    1952           2 :     ScDocShellRef xDocSh2 = saveAndReload(xDocSh, XLSX);
    1953           1 :     xDocSh->DoClose();
    1954           1 :     CPPUNIT_ASSERT_MESSAGE("Failed to re-load file.", xDocSh2.Is());
    1955           1 :     ScDocument& rDoc = xDocSh2->GetDocument();
    1956             : 
    1957           1 :     bool bRes = aTest.checkContent(rDoc);
    1958           1 :     CPPUNIT_ASSERT_MESSAGE("Content check on the reloaded document failed.", bRes);
    1959             : 
    1960           2 :     xDocSh2->DoClose();
    1961           1 : }
    1962             : 
    1963           2 : void ScExportTest::testFunctionsExcel2010( sal_uLong nFormatType )
    1964             : {
    1965           2 :     ScDocShellRef xShell = loadDoc("functions-excel-2010.", XLSX);
    1966           2 :     CPPUNIT_ASSERT_MESSAGE("Failed to load the document.", xShell.Is());
    1967             : 
    1968           4 :     ScDocShellRef xDocSh = saveAndReload(xShell, nFormatType);
    1969           2 :     ScDocument& rDoc = xDocSh->GetDocument();
    1970           2 :     rDoc.CalcAll(); // perform hard re-calculation.
    1971             : 
    1972           2 :     testFunctionsExcel2010_Impl(rDoc);
    1973             : 
    1974           4 :     xDocSh->DoClose();
    1975           2 : }
    1976             : 
    1977           1 : void ScExportTest::testFunctionsExcel2010XLSX()
    1978             : {
    1979           1 :     testFunctionsExcel2010(XLSX);
    1980           1 : }
    1981             : 
    1982           1 : void ScExportTest::testFunctionsExcel2010XLS()
    1983             : {
    1984           1 :     testFunctionsExcel2010(XLS);
    1985           1 : }
    1986             : 
    1987           1 : void ScExportTest::testRelativePaths()
    1988             : {
    1989           1 :     ScDocShellRef xDocSh = loadDoc("fdo79305.", ODS);
    1990           1 :     CPPUNIT_ASSERT(xDocSh.Is());
    1991             : 
    1992           1 :     xmlDocPtr pDoc = XPathHelper::parseExport(&(*xDocSh), m_xSFactory, "content.xml", ODS);
    1993           1 :     CPPUNIT_ASSERT(pDoc);
    1994             :     OUString aURL = getXPath(pDoc,
    1995           2 :             "/office:document-content/office:body/office:spreadsheet/table:table/table:table-row[2]/table:table-cell[2]/text:p/text:a", "href");
    1996             :     // make sure that the URL is relative
    1997           2 :     CPPUNIT_ASSERT(aURL.startsWith(".."));
    1998           1 : }
    1999             : 
    2000             : namespace {
    2001             : 
    2002           2 : void testSheetProtection_Impl(ScDocument& rDoc)
    2003             : {
    2004           2 :     CPPUNIT_ASSERT(rDoc.IsTabProtected(0));
    2005           2 :     ScTableProtection* pTabProtection = rDoc.GetTabProtection(0);
    2006           2 :     CPPUNIT_ASSERT(pTabProtection);
    2007           2 :     CPPUNIT_ASSERT(pTabProtection->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS));
    2008           2 :     CPPUNIT_ASSERT(!pTabProtection->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS));
    2009           2 : }
    2010             : 
    2011             : }
    2012             : 
    2013           1 : void ScExportTest::testSheetProtection()
    2014             : {
    2015           1 :     ScDocShellRef xDocSh = loadDoc("sheet-protection.", ODS);
    2016           1 :     CPPUNIT_ASSERT(xDocSh.Is());
    2017             : 
    2018             :     {
    2019           1 :         ScDocument& rDoc = xDocSh->GetDocument();
    2020           1 :         testSheetProtection_Impl(rDoc);
    2021             :     }
    2022             : 
    2023           2 :     ScDocShellRef xDocSh2 = saveAndReload(xDocSh, ODS);
    2024             :     {
    2025           1 :         ScDocument& rDoc = xDocSh2->GetDocument();
    2026           1 :         testSheetProtection_Impl(rDoc);
    2027             :     }
    2028             : 
    2029           2 :     xDocSh2->DoClose();
    2030           1 : }
    2031             : 
    2032           1 : void ScExportTest::testPivotTableXLSX()
    2033             : {
    2034             :     struct
    2035             :     {
    2036           2 :         bool check( const ScDocument& rDoc )
    2037             :         {
    2038           2 :             if (!rDoc.HasPivotTable())
    2039             :             {
    2040           0 :                 cerr << "The document should have pivot table." << endl;
    2041           0 :                 return false;
    2042             :             }
    2043             : 
    2044           2 :             const ScDPCollection* pDPs = rDoc.GetDPCollection();
    2045           2 :             if (!pDPs)
    2046             :             {
    2047           0 :                 cerr << "Pivot table container should exist." << endl;
    2048           0 :                 return false;
    2049             :             }
    2050             : 
    2051           2 :             ScRange aSrcRange(0,0,0,9,2,0); // A1:J3 on Sheet1.
    2052           2 :             const ScDPCache* pCache = pDPs->GetSheetCaches().getExistingCache(aSrcRange);
    2053           2 :             if (!pCache)
    2054             :             {
    2055           0 :                 cerr << "The document should have a pivot cache for A1:J3 on Sheet1." << endl;
    2056           0 :                 return false;
    2057             :             }
    2058             : 
    2059             :             // Cache should have fields from F1 through F10.
    2060             : 
    2061             :             const char* pNames[] = {
    2062             :                 "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10"
    2063           2 :             };
    2064             : 
    2065           2 :             size_t nCount = pCache->GetFieldCount();
    2066           2 :             if (nCount != SAL_N_ELEMENTS(pNames))
    2067             :             {
    2068           0 :                 cout << "Incorrect number of fields in pivot cache." << endl;
    2069           0 :                 return false;
    2070             :             }
    2071             : 
    2072          22 :             for (size_t i = 0; i < nCount; ++i)
    2073             :             {
    2074          20 :                 OUString aCacheName = pCache->GetDimensionName(i);
    2075          20 :                 if (aCacheName != OUString::createFromAscii(pNames[i]))
    2076             :                 {
    2077           0 :                     cerr << "Field " << i << " has label '" << aCacheName << "' but expected '" << pNames[i] << "'" << endl;
    2078           0 :                     return false;
    2079             :                 }
    2080          20 :             }
    2081             : 
    2082           2 :             const ScDPObject* pDPObj = rDoc.GetDPAtCursor(0,10,0); // A11
    2083           2 :             if (!pDPObj)
    2084             :             {
    2085           0 :                 cerr << "A pivot table should exist over A11." << endl;
    2086           0 :                 return false;
    2087             :             }
    2088             : 
    2089             :             // Output range should be A8:D15.
    2090           2 :             ScRange aOutRange = pDPObj->GetOutRange();
    2091           2 :             if (ScRange(0,7,0,3,14,0) != aOutRange)
    2092             :             {
    2093           0 :                 cerr << "Incorrect output range." << endl;
    2094           0 :                 return false;
    2095             :             }
    2096             : 
    2097             :             // Row field - F1
    2098             :             // Column field - F4
    2099             :             // Page fields - F7 and F6
    2100             :             // Data field - F10
    2101             : 
    2102           2 :             const ScDPSaveData* pSaveData = pDPObj->GetSaveData();
    2103           2 :             if (!pSaveData)
    2104             :             {
    2105           0 :                 cerr << "Save data should exist in each pivot table object." << endl;
    2106           0 :                 return false;
    2107             :             }
    2108             : 
    2109           2 :             std::vector<const ScDPSaveDimension*> aDims;
    2110           2 :             pSaveData->GetAllDimensionsByOrientation(sheet::DataPilotFieldOrientation_ROW, aDims);
    2111           2 :             if (aDims.size() != 1 || aDims[0]->GetName() != "F1")
    2112             :             {
    2113           0 :                 cerr << "Pivot table should have one row field labeld 'F1'" << endl;
    2114           0 :                 return false;
    2115             :             }
    2116             : 
    2117           2 :             pSaveData->GetAllDimensionsByOrientation(sheet::DataPilotFieldOrientation_COLUMN, aDims);
    2118           2 :             if (aDims.size() != 1 || aDims[0]->GetName() != "F4")
    2119             :             {
    2120           0 :                 cerr << "Pivot table should have one column field labeld 'F4'" << endl;
    2121           0 :                 return false;
    2122             :             }
    2123             : 
    2124           2 :             pSaveData->GetAllDimensionsByOrientation(sheet::DataPilotFieldOrientation_PAGE, aDims);
    2125           2 :             if (aDims.size() != 2 || aDims[0]->GetName() != "F7" || aDims[1]->GetName() != "F6")
    2126             :             {
    2127           0 :                 cerr << "Pivot table should have two page fields labeld 'F7' and 'F6' in this order." << endl;
    2128           0 :                 return false;
    2129             :             }
    2130             : 
    2131           2 :             pSaveData->GetAllDimensionsByOrientation(sheet::DataPilotFieldOrientation_DATA, aDims);
    2132           2 :             if (aDims.size() != 1 || aDims[0]->GetName() != "F10")
    2133             :             {
    2134           0 :                 cerr << "Pivot table should have one data field labeld 'F10'" << endl;
    2135           0 :                 return false;
    2136             :             }
    2137             : 
    2138           2 :             const ScDPSaveDimension* pDim = aDims[0];
    2139           2 :             if (pDim->GetFunction() != sheet::GeneralFunction_SUM)
    2140             :             {
    2141           0 :                 cerr << "Data field should have SUM function." << endl;
    2142           0 :                 return false;
    2143             :             }
    2144             : 
    2145           2 :             return true;
    2146             :         }
    2147             : 
    2148             :     } aTest;
    2149             : 
    2150           1 :     ScDocShellRef xDocSh = loadDoc("pivot-table/many-fields-in-cache.", XLSX);
    2151           1 :     CPPUNIT_ASSERT(xDocSh.Is());
    2152           1 :     ScDocument* pDoc = &xDocSh->GetDocument();
    2153             : 
    2154             :     // Initial check.
    2155           1 :     bool bCheck = aTest.check(*pDoc);
    2156           1 :     CPPUNIT_ASSERT_MESSAGE("Initial check failed.", bCheck);
    2157             : 
    2158           2 :     ScDocShellRef xDocSh2 = saveAndReload(xDocSh, XLSX);
    2159           1 :     xDocSh->DoClose();
    2160           1 :     CPPUNIT_ASSERT(xDocSh2.Is());
    2161           1 :     pDoc = &xDocSh2->GetDocument();
    2162             : 
    2163             :     // Reload check.
    2164           1 :     bCheck = aTest.check(*pDoc);
    2165           1 :     CPPUNIT_ASSERT_MESSAGE("Reload check failed.", bCheck);
    2166             : 
    2167           2 :     xDocSh2->DoClose();
    2168           1 : }
    2169             : 
    2170           1 : void ScExportTest::testPivotTableTwoDataFieldsXLSX()
    2171             : {
    2172             :     struct
    2173             :     {
    2174           2 :         bool check( const ScDocument& rDoc )
    2175             :         {
    2176           2 :             if (!rDoc.HasPivotTable())
    2177             :             {
    2178           0 :                 cerr << "The document should have pivot table." << endl;
    2179           0 :                 return false;
    2180             :             }
    2181             : 
    2182           2 :             const ScDPCollection* pDPs = rDoc.GetDPCollection();
    2183           2 :             if (!pDPs)
    2184             :             {
    2185           0 :                 cerr << "Pivot table container should exist." << endl;
    2186           0 :                 return false;
    2187             :             }
    2188             : 
    2189           2 :             ScRange aSrcRange(1,1,1,2,8,1); // B2:C9 on the 2nd sheet.
    2190           2 :             const ScDPCache* pCache = pDPs->GetSheetCaches().getExistingCache(aSrcRange);
    2191           2 :             if (!pCache)
    2192             :             {
    2193           0 :                 cerr << "The document should have a pivot cache for B2:C9 on 'Src'." << endl;
    2194           0 :                 return false;
    2195             :             }
    2196             : 
    2197           2 :             const char* pNames[] = { "Name", "Value" };
    2198             :             (void) pNames;
    2199             : 
    2200           2 :             size_t nCount = pCache->GetFieldCount();
    2201           2 :             if (nCount != SAL_N_ELEMENTS(pNames))
    2202             :             {
    2203           0 :                 cout << "Incorrect number of fields in pivot cache." << endl;
    2204           0 :                 return false;
    2205             :             }
    2206             : 
    2207           2 :             const ScDPObject* pDPObj = rDoc.GetDPAtCursor(0,2,0); // A3
    2208           2 :             if (!pDPObj)
    2209             :             {
    2210           0 :                 cerr << "A pivot table should exist over A3." << endl;
    2211           0 :                 return false;
    2212             :             }
    2213             : 
    2214             :             // Output range should be A3:C12.
    2215           2 :             ScRange aOutRange = pDPObj->GetOutRange();
    2216           2 :             if (ScRange(0,2,0,2,11,0) != aOutRange)
    2217             :             {
    2218           0 :                 cerr << "Incorrect output range." << endl;
    2219           0 :                 return false;
    2220             :             }
    2221             : 
    2222           2 :             const ScDPSaveData* pSaveData = pDPObj->GetSaveData();
    2223           2 :             if (!pSaveData)
    2224             :             {
    2225           0 :                 cerr << "Save data should exist in each pivot table object." << endl;
    2226           0 :                 return false;
    2227             :             }
    2228             : 
    2229           2 :             std::vector<const ScDPSaveDimension*> aDims;
    2230           2 :             pSaveData->GetAllDimensionsByOrientation(sheet::DataPilotFieldOrientation_ROW, aDims);
    2231           2 :             if (aDims.size() != 1 || aDims[0]->GetName() != "Name")
    2232             :             {
    2233           0 :                 cerr << "Pivot table should have one row field labeld 'Name'" << endl;
    2234           0 :                 return false;
    2235             :             }
    2236             : 
    2237           2 :             pSaveData->GetAllDimensionsByOrientation(sheet::DataPilotFieldOrientation_DATA, aDims);
    2238          10 :             if (aDims.size() != 2 ||
    2239          14 :                 ScDPUtil::getSourceDimensionName(aDims[0]->GetName()) != "Value" ||
    2240           6 :                 ScDPUtil::getSourceDimensionName(aDims[1]->GetName()) != "Value")
    2241             :             {
    2242           0 :                 cerr << "Pivot table should have two duplicated data fields both of which are named 'Value'." << endl;
    2243           0 :                 return false;
    2244             :             }
    2245             : 
    2246           2 :             if (aDims[0]->GetFunction() != sheet::GeneralFunction_SUM)
    2247             :             {
    2248           0 :                 cerr << "First data field should be SUM." << endl;
    2249           0 :                 return false;
    2250             :             }
    2251             : 
    2252           2 :             if (aDims[1]->GetFunction() != sheet::GeneralFunction_COUNT)
    2253             :             {
    2254           0 :                 cerr << "First data field should be COUNT." << endl;
    2255           0 :                 return false;
    2256             :             }
    2257             : 
    2258           2 :             pSaveData->GetAllDimensionsByOrientation(sheet::DataPilotFieldOrientation_COLUMN, aDims);
    2259           2 :             if (aDims.size() != 1 || !aDims[0]->IsDataLayout())
    2260             :             {
    2261           0 :                 cerr << "Pivot table should have one column field which is a data layout field." << endl;
    2262           0 :                 return false;
    2263             :             }
    2264             : 
    2265           2 :             return true;
    2266             :         }
    2267             : 
    2268             :     } aTest;
    2269             : 
    2270           1 :     ScDocShellRef xDocSh = loadDoc("pivot-table/two-data-fields.", XLSX);
    2271           1 :     CPPUNIT_ASSERT(xDocSh.Is());
    2272           1 :     ScDocument* pDoc = &xDocSh->GetDocument();
    2273             : 
    2274             :     // Initial check.
    2275           1 :     bool bCheck = aTest.check(*pDoc);
    2276           1 :     CPPUNIT_ASSERT_MESSAGE("Initial check failed.", bCheck);
    2277             : 
    2278           2 :     ScDocShellRef xDocSh2 = saveAndReload(xDocSh, XLSX);
    2279           1 :     xDocSh->DoClose();
    2280           1 :     CPPUNIT_ASSERT(xDocSh2.Is());
    2281           1 :     pDoc = &xDocSh2->GetDocument();
    2282             : 
    2283             :     // Reload check.
    2284           1 :     bCheck = aTest.check(*pDoc);
    2285           1 :     CPPUNIT_ASSERT_MESSAGE("Reload check failed.", bCheck);
    2286             : 
    2287           2 :     xDocSh2->DoClose();
    2288           1 : }
    2289             : 
    2290           1 : void ScExportTest::testFunctionsExcel2010ODS()
    2291             : {
    2292             :     //testFunctionsExcel2010(ODS);
    2293           1 : }
    2294             : 
    2295           1 : void ScExportTest::testSwappedOutImageExport()
    2296             : {
    2297             :     const char* aFilterNames[] = {
    2298             :         "calc8",
    2299             :         "MS Excel 97",
    2300             :         "Calc Office Open XML",
    2301             :         "generic_HTML",
    2302           1 :     };
    2303             : 
    2304             :     // Set cache size to a very small value to make sure one of the images is swapped out
    2305           1 :     std::shared_ptr< comphelper::ConfigurationChanges > xBatch(comphelper::ConfigurationChanges::create());
    2306           1 :     officecfg::Office::Common::Cache::GraphicManager::TotalCacheSize::set(sal_Int32(1), xBatch);
    2307           1 :     xBatch->commit();
    2308             : 
    2309           5 :     for( size_t nFilter = 0; nFilter < SAL_N_ELEMENTS(aFilterNames); ++nFilter )
    2310             :     {
    2311             :         // Check whether the export code swaps in the image which was swapped out before.
    2312           4 :         ScDocShellRef xDocSh = loadDoc("document_with_two_images.", ODS);
    2313             : 
    2314           8 :         const OString sFailedMessage = OString("Failed on filter: ") + aFilterNames[nFilter];
    2315           4 :         CPPUNIT_ASSERT_MESSAGE(sFailedMessage.getStr(), xDocSh.Is());
    2316             : 
    2317             :         // Export the document and import again for a check
    2318           8 :         ScDocShellRef xDocSh2 = saveAndReload(xDocSh, nFilter);
    2319           4 :         xDocSh->DoClose();
    2320             : 
    2321             :         // Check whether graphic exported well after it was swapped out
    2322           8 :         uno::Reference< frame::XModel > xModel = xDocSh2->GetModel();
    2323           8 :         uno::Reference< sheet::XSpreadsheetDocument > xDoc(xModel, UNO_QUERY_THROW);
    2324           8 :         uno::Reference< container::XIndexAccess > xIA(xDoc->getSheets(), UNO_QUERY_THROW);
    2325           8 :         uno::Reference< drawing::XDrawPageSupplier > xDrawPageSupplier( xIA->getByIndex(0), UNO_QUERY_THROW);
    2326           8 :         uno::Reference< container::XIndexAccess > xDraws(xDrawPageSupplier->getDrawPage(), UNO_QUERY_THROW);
    2327           4 :         CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), static_cast<sal_Int32>(2), xDraws->getCount());
    2328             : 
    2329           8 :         uno::Reference<drawing::XShape> xImage(xDraws->getByIndex(0), uno::UNO_QUERY);
    2330           8 :         uno::Reference< beans::XPropertySet > XPropSet( xImage, uno::UNO_QUERY_THROW );
    2331             :         // Check URL
    2332             :         {
    2333           4 :             OUString sURL;
    2334           4 :             XPropSet->getPropertyValue("GraphicURL") >>= sURL;
    2335           4 :             CPPUNIT_ASSERT_MESSAGE(sFailedMessage.getStr(), sURL != "vnd.sun.star.GraphicObject:00000000000000000000000000000000");
    2336             :         }
    2337             :         // Check size
    2338             :         {
    2339           4 :             uno::Reference<graphic::XGraphic> xGraphic;
    2340           4 :             XPropSet->getPropertyValue("Graphic") >>= xGraphic;
    2341           8 :             uno::Reference<awt::XBitmap> xBitmap(xGraphic, uno::UNO_QUERY);
    2342           4 :             CPPUNIT_ASSERT_MESSAGE(sFailedMessage.getStr(), xBitmap.is());
    2343           4 :             CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), static_cast<sal_Int32>(610), xBitmap->getSize().Width );
    2344           8 :             CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), static_cast<sal_Int32>(381), xBitmap->getSize().Height );
    2345             :         }
    2346             :         // Second Image
    2347           4 :         xImage.set(xDraws->getByIndex(1), uno::UNO_QUERY);
    2348           4 :         XPropSet.set( xImage, uno::UNO_QUERY_THROW );
    2349             :         // Check URL
    2350             :         {
    2351           4 :             OUString sURL;
    2352           4 :             XPropSet->getPropertyValue("GraphicURL") >>= sURL;
    2353           4 :             CPPUNIT_ASSERT_MESSAGE(sFailedMessage.getStr(), sURL != "vnd.sun.star.GraphicObject:00000000000000000000000000000000");
    2354             :         }
    2355             :         // Check size
    2356             :         {
    2357           4 :             uno::Reference<graphic::XGraphic> xGraphic;
    2358           4 :             XPropSet->getPropertyValue("Graphic") >>= xGraphic;
    2359           8 :             uno::Reference<awt::XBitmap> xBitmap(xGraphic, uno::UNO_QUERY);
    2360           4 :             CPPUNIT_ASSERT_MESSAGE(sFailedMessage.getStr(), xBitmap.is());
    2361           4 :             CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), static_cast<sal_Int32>(900), xBitmap->getSize().Width );
    2362           8 :             CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), static_cast<sal_Int32>(600), xBitmap->getSize().Height );
    2363             :         }
    2364           4 :         xDocSh2->DoClose();
    2365           5 :     }
    2366           1 : }
    2367             : 
    2368          48 : ScExportTest::ScExportTest()
    2369          48 :       : ScBootstrapFixture("/sc/qa/unit/data")
    2370             : {
    2371          48 : }
    2372             : 
    2373          48 : void ScExportTest::setUp()
    2374             : {
    2375          48 :     test::BootstrapFixture::setUp();
    2376             : 
    2377             :     // This is a bit of a fudge, we do this to ensure that ScGlobals::ensure,
    2378             :     // which is a private symbol to us, gets called
    2379          96 :     m_xCalcComponent =
    2380         144 :         getMultiServiceFactory()->createInstance("com.sun.star.comp.Calc.SpreadsheetDocument");
    2381          48 :     CPPUNIT_ASSERT_MESSAGE("no calc component!", m_xCalcComponent.is());
    2382          48 : }
    2383             : 
    2384          48 : void ScExportTest::tearDown()
    2385             : {
    2386          48 :     uno::Reference< lang::XComponent >( m_xCalcComponent, UNO_QUERY_THROW )->dispose();
    2387          48 :     test::BootstrapFixture::tearDown();
    2388          48 : }
    2389             : 
    2390           1 : void ScExportTest::testSupBookVirtualPath()
    2391             : {
    2392           1 :     ScDocShellRef xShell = loadDoc("external-ref.", XLS);
    2393           1 :     CPPUNIT_ASSERT(xShell.Is());
    2394             : 
    2395           2 :     ScDocShellRef xDocSh = saveAndReload(xShell, XLS);
    2396           1 :     xShell->DoClose();
    2397           1 :     CPPUNIT_ASSERT(xDocSh.Is());
    2398             : 
    2399           1 :     ScDocument& rDoc = xDocSh->GetDocument();
    2400             : 
    2401           1 :     if (!checkFormula(rDoc, ScAddress(0,0,0), "'file:///home/timar/Documents/external.xls'#$Sheet1.A1"))
    2402           0 :         CPPUNIT_FAIL("Wrong SupBook VirtualPath URL");
    2403             : 
    2404           2 :     xDocSh->DoClose();
    2405           1 : }
    2406             : 
    2407           1 : void ScExportTest::testLinkedGraphicRT()
    2408             : {
    2409             :     // Problem was with linked images
    2410             :     const char* aFilterNames[] = {
    2411             :         "calc8",
    2412             :         "MS Excel 97",
    2413             :         "Calc Office Open XML",
    2414             :         "generic_HTML",
    2415           1 :     };
    2416             : 
    2417           5 :     for( size_t nFilter = 0; nFilter < SAL_N_ELEMENTS(aFilterNames); ++nFilter )
    2418             :     {
    2419             :         // Load the original file with one image
    2420           4 :         ScDocShellRef xDocSh = loadDoc("document_with_linked_graphic.", ODS);
    2421           8 :         const OString sFailedMessage = OString("Failed on filter: ") + aFilterNames[nFilter];
    2422             : 
    2423             :         // Export the document and import again for a check
    2424           8 :         ScDocShellRef xDocSh2 = saveAndReload(xDocSh, nFilter);
    2425           4 :         xDocSh->DoClose();
    2426             : 
    2427             :         // Check whether graphic imported well after export
    2428           4 :         ScDocument& rDoc = xDocSh->GetDocument();
    2429           4 :         ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer();
    2430           4 :         CPPUNIT_ASSERT_MESSAGE( sFailedMessage.getStr(), pDrawLayer != NULL );
    2431           4 :         const SdrPage *pPage = pDrawLayer->GetPage(0);
    2432           4 :         CPPUNIT_ASSERT_MESSAGE( sFailedMessage.getStr(), pPage != NULL );
    2433           4 :         SdrGrafObj* pObject = dynamic_cast<SdrGrafObj*>(pPage->GetObj(0));
    2434           4 :         CPPUNIT_ASSERT_MESSAGE( sFailedMessage.getStr(), pObject != NULL );
    2435           4 :         CPPUNIT_ASSERT_MESSAGE( sFailedMessage.getStr(), pObject->IsLinkedGraphic() );
    2436             : 
    2437           4 :         const GraphicObject& rGraphicObj = pObject->GetGraphicObject(true);
    2438           4 :         CPPUNIT_ASSERT_MESSAGE( sFailedMessage.getStr(), !rGraphicObj.IsSwappedOut());
    2439           4 :         CPPUNIT_ASSERT_EQUAL_MESSAGE( sFailedMessage.getStr(), GRAPHIC_BITMAP, rGraphicObj.GetGraphic().GetType());
    2440           4 :         CPPUNIT_ASSERT_EQUAL_MESSAGE( sFailedMessage.getStr(), sal_uLong(864900), rGraphicObj.GetSizeBytes());
    2441             : 
    2442           4 :         xDocSh2->DoClose();
    2443           4 :     }
    2444           1 : }
    2445             : 
    2446           1 : void ScExportTest::testImageWithSpecialID()
    2447             : {
    2448             :     const char* aFilterNames[] = {
    2449             :         "calc8",
    2450             :         "MS Excel 97",
    2451             :         "Calc Office Open XML",
    2452             :         "generic_HTML",
    2453           1 :     };
    2454             : 
    2455             :     // Trigger swap out mechanism to test swapped state factor too.
    2456           1 :     std::shared_ptr< comphelper::ConfigurationChanges > batch(comphelper::ConfigurationChanges::create());
    2457           1 :     officecfg::Office::Common::Cache::GraphicManager::TotalCacheSize::set(sal_Int32(1), batch);
    2458           1 :     batch->commit();
    2459             : 
    2460           5 :     for( size_t nFilter = 0; nFilter < SAL_N_ELEMENTS(aFilterNames); ++nFilter )
    2461             :     {
    2462           4 :         ScDocShellRef xDocSh = loadDoc("images_with_special_IDs.", ODS);
    2463             : 
    2464           8 :         const OString sFailedMessage = OString("Failed on filter: ") + aFilterNames[nFilter];
    2465           4 :         CPPUNIT_ASSERT_MESSAGE(sFailedMessage.getStr(), xDocSh.Is());
    2466             : 
    2467             :         // Export the document and import again for a check
    2468           8 :         ScDocShellRef xDocSh2 = saveAndReload(xDocSh, nFilter);
    2469           4 :         xDocSh->DoClose();
    2470             : 
    2471             :         // Check whether graphic was exported well
    2472           8 :         uno::Reference< frame::XModel > xModel = xDocSh2->GetModel();
    2473           8 :         uno::Reference< sheet::XSpreadsheetDocument > xDoc(xModel, UNO_QUERY_THROW);
    2474           8 :         uno::Reference< container::XIndexAccess > xIA(xDoc->getSheets(), UNO_QUERY_THROW);
    2475           8 :         uno::Reference< drawing::XDrawPageSupplier > xDrawPageSupplier( xIA->getByIndex(0), UNO_QUERY_THROW);
    2476           8 :         uno::Reference< container::XIndexAccess > xDraws(xDrawPageSupplier->getDrawPage(), UNO_QUERY_THROW);
    2477           4 :         CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), static_cast<sal_Int32>(2), xDraws->getCount());
    2478             : 
    2479           8 :         uno::Reference<drawing::XShape> xImage(xDraws->getByIndex(0), uno::UNO_QUERY);
    2480           8 :         uno::Reference< beans::XPropertySet > XPropSet( xImage, uno::UNO_QUERY_THROW );
    2481             :         // Check URL
    2482             :         {
    2483           4 :             OUString sURL;
    2484           4 :             XPropSet->getPropertyValue("GraphicURL") >>= sURL;
    2485           4 :             CPPUNIT_ASSERT_MESSAGE(sFailedMessage.getStr(), sURL != "vnd.sun.star.GraphicObject:00000000000000000000000000000000");
    2486             :         }
    2487             :         // Check size
    2488             :         {
    2489           4 :             uno::Reference<graphic::XGraphic> xGraphic;
    2490           4 :             XPropSet->getPropertyValue("Graphic") >>= xGraphic;
    2491           8 :             uno::Reference<awt::XBitmap> xBitmap(xGraphic, uno::UNO_QUERY);
    2492           4 :             CPPUNIT_ASSERT_MESSAGE(sFailedMessage.getStr(), xBitmap.is());
    2493           4 :             CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), static_cast<sal_Int32>(610), xBitmap->getSize().Width );
    2494           8 :             CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), static_cast<sal_Int32>(381), xBitmap->getSize().Height );
    2495             :         }
    2496             :         // Second Image
    2497           4 :         xImage.set(xDraws->getByIndex(1), uno::UNO_QUERY);
    2498           4 :         XPropSet.set( xImage, uno::UNO_QUERY_THROW );
    2499             :         // Check URL
    2500             :         {
    2501           4 :             OUString sURL;
    2502           4 :             XPropSet->getPropertyValue("GraphicURL") >>= sURL;
    2503           4 :             CPPUNIT_ASSERT_MESSAGE(sFailedMessage.getStr(), sURL != "vnd.sun.star.GraphicObject:00000000000000000000000000000000");
    2504             :         }
    2505             :         // Check size
    2506             :         {
    2507           4 :             uno::Reference<graphic::XGraphic> xGraphic;
    2508           4 :             XPropSet->getPropertyValue("Graphic") >>= xGraphic;
    2509           8 :             uno::Reference<awt::XBitmap> xBitmap(xGraphic, uno::UNO_QUERY);
    2510           4 :             CPPUNIT_ASSERT_MESSAGE(sFailedMessage.getStr(), xBitmap.is());
    2511           4 :             CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), static_cast<sal_Int32>(900), xBitmap->getSize().Width );
    2512           8 :             CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), static_cast<sal_Int32>(600), xBitmap->getSize().Height );
    2513             :         }
    2514           4 :         xDocSh2->DoClose();
    2515           5 :     }
    2516           1 : }
    2517             : 
    2518           1 : void ScExportTest::testSheetLocalRangeNameXLS()
    2519             : {
    2520           1 :     ScDocShellRef xDocSh = loadDoc("named-ranges-local.", XLS);
    2521           1 :     xDocSh->DoHardRecalc(true);
    2522           2 :     ScDocShellRef xDocSh2 = saveAndReload(xDocSh, XLS);
    2523           1 :     xDocSh->DoClose();
    2524           1 :     xDocSh2->DoHardRecalc(true);
    2525             : 
    2526           1 :     ScDocument& rDoc = xDocSh2->GetDocument();
    2527           1 :     ScRangeName* pRangeName = rDoc.GetRangeName(0);
    2528           1 :     CPPUNIT_ASSERT(pRangeName);
    2529           1 :     CPPUNIT_ASSERT_EQUAL(size_t(2), pRangeName->size());
    2530             : 
    2531           2 :     OUString aFormula;
    2532           1 :     rDoc.GetFormula(3, 11, 0, aFormula);
    2533           1 :     CPPUNIT_ASSERT_EQUAL(OUString("=SUM(local_name2)"), aFormula);
    2534           1 :     ASSERT_DOUBLES_EQUAL(14.0, rDoc.GetValue(3, 11, 0));
    2535             : 
    2536           1 :     rDoc.GetFormula(6, 4, 0, aFormula);
    2537           1 :     CPPUNIT_ASSERT_EQUAL(OUString("=local_name1"), aFormula);
    2538             : 
    2539           2 :     xDocSh2->DoClose();
    2540           1 : }
    2541             : 
    2542           1 : void ScExportTest::testSheetTextBoxHyperlink()
    2543             : {
    2544           1 :     ScDocShellRef xShell = loadDoc("textbox-hyperlink.", XLSX);
    2545           1 :     CPPUNIT_ASSERT(xShell.Is());
    2546             : 
    2547           2 :     ScDocShellRef xDocSh = saveAndReload(&(*xShell), XLSX);
    2548           1 :     CPPUNIT_ASSERT(xDocSh.Is());
    2549             : 
    2550           1 :     xmlDocPtr pDoc = XPathHelper::parseExport(&(*xDocSh), m_xSFactory, "xl/drawings/drawing1.xml", XLSX);
    2551           1 :     CPPUNIT_ASSERT(pDoc);
    2552             : 
    2553           1 :     assertXPath(pDoc, "/xdr:wsDr[1]/xdr:twoCellAnchor[1]/xdr:sp[1]/xdr:nvSpPr[1]/xdr:cNvPr[1]/a:hlinkClick[1]", 1);
    2554             : 
    2555           2 :     xDocSh->DoClose();
    2556           1 : }
    2557             : 
    2558           1 : void ScExportTest::testFontSize()
    2559             : {
    2560           1 :     ScDocShellRef xDocSh = loadDoc("fontSize.", XLSX);
    2561           1 :     CPPUNIT_ASSERT(xDocSh.Is());
    2562             : 
    2563           1 :     xmlDocPtr pDoc = XPathHelper::parseExport(&(*xDocSh), m_xSFactory, "xl/drawings/drawing1.xml", XLSX);
    2564           1 :     CPPUNIT_ASSERT(pDoc);
    2565             :     OUString fontSize = getXPath(pDoc,
    2566           2 :                 "/xdr:wsDr/xdr:twoCellAnchor/xdr:sp[1]/xdr:txBody/a:p[1]/a:r[1]/a:rPr", "sz");
    2567             :     // make sure that the font size is 18
    2568           2 :     CPPUNIT_ASSERT_EQUAL(OUString("1800"), fontSize);
    2569           1 : }
    2570             : 
    2571           1 : void ScExportTest::testSheetCharacterKerningSpace()
    2572             : {
    2573           1 :     ScDocShellRef xShell = loadDoc("textbox-CharKerningSpace.", XLSX);
    2574           1 :     CPPUNIT_ASSERT(xShell.Is());
    2575             : 
    2576           2 :     ScDocShellRef xDocSh = saveAndReload(&(*xShell), XLSX);
    2577           1 :     CPPUNIT_ASSERT(xDocSh.Is());
    2578             : 
    2579           1 :     xmlDocPtr pDoc = XPathHelper::parseExport(&(*xDocSh), m_xSFactory, "xl/drawings/drawing1.xml", XLSX);
    2580           1 :     CPPUNIT_ASSERT(pDoc);
    2581             : 
    2582             :     OUString CharKerningSpace = getXPath(pDoc,
    2583           2 :         "/xdr:wsDr[1]/xdr:twoCellAnchor[1]/xdr:sp[1]/xdr:txBody[1]/a:p[1]/a:r[1]/a:rPr[1]","spc");
    2584             : 
    2585             :     // make sure that the CharKerning is 1997.
    2586           1 :     CPPUNIT_ASSERT_EQUAL(OUString("1997"), CharKerningSpace);
    2587             : 
    2588           2 :     xDocSh->DoClose();
    2589           1 : }
    2590             : 
    2591           1 : void ScExportTest::testSheetCondensedCharacterSpace()
    2592             : {
    2593           1 :     ScDocShellRef xShell = loadDoc("textbox-CondensedCharacterSpace.", XLSX);
    2594           1 :     CPPUNIT_ASSERT(xShell.Is());
    2595             : 
    2596           2 :     ScDocShellRef xDocSh = saveAndReload(&(*xShell), XLSX);
    2597           1 :     CPPUNIT_ASSERT(xDocSh.Is());
    2598             : 
    2599           1 :     xmlDocPtr pDoc = XPathHelper::parseExport(&(*xDocSh), m_xSFactory, "xl/drawings/drawing1.xml", XLSX);
    2600           1 :     CPPUNIT_ASSERT(pDoc);
    2601             : 
    2602             :     OUString CondensedCharSpace = getXPath(pDoc,
    2603           2 :         "/xdr:wsDr[1]/xdr:twoCellAnchor[1]/xdr:sp[1]/xdr:txBody[1]/a:p[1]/a:r[1]/a:rPr[1]","spc");
    2604             : 
    2605             :     // make sure that the CondensedCharSpace is -996.
    2606           1 :     CPPUNIT_ASSERT_EQUAL(OUString("-996"), CondensedCharSpace);
    2607             : 
    2608           2 :     xDocSh->DoClose();
    2609           1 : }
    2610             : 
    2611           1 : void ScExportTest::testTextUnderlineColor()
    2612             : {
    2613             : 
    2614           1 :     ScDocShellRef xDocSh = loadDoc("underlineColor.", XLSX);
    2615           1 :     CPPUNIT_ASSERT(xDocSh.Is());
    2616             : 
    2617           1 :     xmlDocPtr pDoc = XPathHelper::parseExport(&(*xDocSh), m_xSFactory, "xl/drawings/drawing1.xml", XLSX);
    2618           1 :     CPPUNIT_ASSERT(pDoc);
    2619             :     OUString color = getXPath(pDoc,
    2620           2 :             "/xdr:wsDr/xdr:twoCellAnchor/xdr:sp[1]/xdr:txBody/a:p[1]/a:r[1]/a:rPr/a:uFill/a:solidFill/a:srgbClr", "val");
    2621             :     // make sure that the underline color is RED
    2622           2 :     CPPUNIT_ASSERT_EQUAL(OUString("ff0000"), color);
    2623           1 : }
    2624             : 
    2625           1 : void ScExportTest::testSheetRunParagraphProperty()
    2626             : {
    2627           1 :     ScDocShellRef xShell = loadDoc("TextColor.", XLSX);
    2628           1 :     CPPUNIT_ASSERT(xShell.Is());
    2629             : 
    2630           2 :     ScDocShellRef xDocSh = saveAndReload(&(*xShell), XLSX);
    2631           1 :     CPPUNIT_ASSERT(xDocSh.Is());
    2632             : 
    2633           1 :     xmlDocPtr pDoc = XPathHelper::parseExport(&(*xDocSh), m_xSFactory, "xl/sharedStrings.xml", XLSX);
    2634           1 :     CPPUNIT_ASSERT(pDoc);
    2635             : 
    2636           1 :     assertXPath(pDoc, "/x:sst/x:si/x:r[1]/x:rPr[1]", 1);
    2637             : 
    2638           2 :     xDocSh->DoClose();
    2639           1 : }
    2640             : 
    2641           1 : void ScExportTest::testHiddenShape()
    2642             : {
    2643           1 :     ScDocShellRef xDocSh = loadDoc("hiddenShape.", XLSX);
    2644           1 :     CPPUNIT_ASSERT(xDocSh.Is());
    2645             : 
    2646           1 :     xmlDocPtr pDoc = XPathHelper::parseExport(&(*xDocSh), m_xSFactory, "xl/drawings/drawing1.xml", XLSX);
    2647           1 :     CPPUNIT_ASSERT(pDoc);
    2648           1 :     assertXPath(pDoc, "/xdr:wsDr/xdr:twoCellAnchor/xdr:sp[1]/xdr:nvSpPr/xdr:cNvPr", "hidden", "1");
    2649           1 : }
    2650             : 
    2651           1 : void ScExportTest::testHyperlinkXLSX()
    2652             : {
    2653           1 :     ScDocShellRef xDocSh = loadDoc("hyperlink.", XLSX);
    2654           1 :     CPPUNIT_ASSERT(xDocSh.Is());
    2655             : 
    2656           1 :     xmlDocPtr pDoc = XPathHelper::parseExport(&(*xDocSh), m_xSFactory, "xl/drawings/_rels/drawing1.xml.rels", XLSX);
    2657           1 :     CPPUNIT_ASSERT(pDoc);
    2658           1 :     assertXPath(pDoc, "/r:Relationships/r:Relationship", "Target", "#Sheet2!A1");
    2659           1 : }
    2660             : 
    2661           1 : void ScExportTest::testMoveCellAnchoredShapes()
    2662             : {
    2663           1 :     ScDocShellRef xDocSh = loadDoc("move-cell-anchored-shapes.", ODS);
    2664           1 :     CPPUNIT_ASSERT_MESSAGE("Failed to load move-cell-anchored-shapes.ods", xDocSh.Is());
    2665             : 
    2666             :     // There are two cell-anchored objects on the first sheet.
    2667           1 :     ScDocument& rDoc = xDocSh->GetDocument();
    2668             : 
    2669           1 :     CPPUNIT_ASSERT_MESSAGE("There should be at least one sheet.", rDoc.GetTableCount() > 0);
    2670             : 
    2671           1 :     ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer();
    2672           1 :     SdrPage* pPage = pDrawLayer->GetPage(0);
    2673           1 :     CPPUNIT_ASSERT_MESSAGE("draw page for sheet 1 should exist.", pPage);
    2674           1 :     SdrObject* pObj = pPage->GetObj(0);
    2675           1 :     CPPUNIT_ASSERT_MESSAGE("Failed to get drawing object.", pObj);
    2676             : 
    2677             :     // Check cell anchor state
    2678           1 :     ScAnchorType oldType = ScDrawLayer::GetAnchorType(*pObj);
    2679           1 :     CPPUNIT_ASSERT_MESSAGE( "Failed to get anchor type", oldType == SCA_CELL );
    2680             : 
    2681             :     // Get anchor data
    2682           1 :     ScDrawObjData* pData = ScDrawLayer::GetObjData(pObj, false);
    2683           1 :     CPPUNIT_ASSERT_MESSAGE("Failed to retrieve user data for this object.", pData);
    2684           1 :     CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pData->maLastRect.IsEmpty());
    2685             : 
    2686           1 :     ScAddress aDataStart = pData->maStart;
    2687           1 :     ScAddress aDataEnd   = pData->maEnd;
    2688             : 
    2689             :     // Get non rotated anchor data
    2690           1 :     ScDrawObjData* pNData = ScDrawLayer::GetNonRotatedObjData( pObj );
    2691           1 :     CPPUNIT_ASSERT_MESSAGE("Failed to retrieve non rotated user data for this object.", pNData);
    2692           1 :     CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pNData->maLastRect.IsEmpty());
    2693             : 
    2694           1 :     ScAddress aNDataStart = pNData->maStart;
    2695           1 :     ScAddress aNDataEnd   = pNData->maEnd;
    2696           1 :     CPPUNIT_ASSERT_EQUAL(aDataStart, aNDataStart);
    2697           1 :     CPPUNIT_ASSERT_EQUAL(aDataEnd , aNDataEnd);
    2698             : 
    2699             :     // Insert 2 rows.
    2700           1 :     rDoc.InsertRow(ScRange( 0, aDataStart.Row() - 1, 0, MAXCOL, aDataStart.Row(), 0));
    2701             : 
    2702             :     // Get anchor data
    2703           1 :     pData = ScDrawLayer::GetObjData(pObj, false);
    2704           1 :     CPPUNIT_ASSERT_MESSAGE("Failed to retrieve user data for this object.", pData);
    2705           1 :     CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pData->maLastRect.IsEmpty());
    2706             : 
    2707             :     // Get non rotated anchor data
    2708           1 :     pNData = ScDrawLayer::GetNonRotatedObjData( pObj );
    2709           1 :     CPPUNIT_ASSERT_MESSAGE("Failed to retrieve non rotated user data for this object.", pNData);
    2710           1 :     CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pNData->maLastRect.IsEmpty());
    2711             : 
    2712             :     // Check if data has moved to new rows
    2713           1 :     CPPUNIT_ASSERT_EQUAL( pData->maStart.Row(), aDataStart.Row() + 2 );
    2714           1 :     CPPUNIT_ASSERT_EQUAL( pData->maEnd.Row(), aDataEnd.Row() + 2 );
    2715             : 
    2716           1 :     CPPUNIT_ASSERT_EQUAL( pNData->maStart.Row(), aNDataStart.Row() + 2 );
    2717           1 :     CPPUNIT_ASSERT_EQUAL( pNData->maEnd.Row(), aNDataEnd.Row() + 2 );
    2718             : 
    2719             :     // Save the anchor data
    2720           1 :     aDataStart = pData->maStart;
    2721           1 :     aDataEnd   = pData->maEnd;
    2722           1 :     aNDataStart = pNData->maStart;
    2723           1 :     aNDataEnd   = pNData->maEnd;
    2724             : 
    2725             :     // Save the document and load again to check anchor persist
    2726           2 :     ScDocShellRef xDocSh1 = saveAndReload(&(*xDocSh), ODS);
    2727             : 
    2728             :     // There are two cell-anchored objects on the first sheet.
    2729           1 :     ScDocument& rDoc1 = xDocSh1->GetDocument();
    2730             : 
    2731           1 :     CPPUNIT_ASSERT_MESSAGE("There should be at least one sheet.", rDoc1.GetTableCount() > 0);
    2732             : 
    2733           1 :     pDrawLayer = rDoc1.GetDrawLayer();
    2734           1 :     pPage = pDrawLayer->GetPage(0);
    2735           1 :     CPPUNIT_ASSERT_MESSAGE("draw page for sheet 1 should exist.", pPage);
    2736           1 :     pObj = pPage->GetObj(0);
    2737           1 :     CPPUNIT_ASSERT_MESSAGE("Failed to get drawing object.", pObj);
    2738             : 
    2739             :     // Check cell anchor state
    2740           1 :     oldType = ScDrawLayer::GetAnchorType(*pObj);
    2741           1 :     CPPUNIT_ASSERT_MESSAGE( "Failed to get anchor type", oldType == SCA_CELL );
    2742             : 
    2743             :     // Get anchor data
    2744           1 :     pData = ScDrawLayer::GetObjData(pObj, false);
    2745           1 :     CPPUNIT_ASSERT_MESSAGE("Failed to retrieve user data for this object.", pData);
    2746           1 :     CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pData->maLastRect.IsEmpty());
    2747             : 
    2748             :     // Get non rotated anchor data
    2749           1 :     pNData = ScDrawLayer::GetNonRotatedObjData( pObj );
    2750           1 :     CPPUNIT_ASSERT_MESSAGE("Failed to retrieve non rotated user data for this object.", pNData);
    2751           1 :     CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pNData->maLastRect.IsEmpty());
    2752             : 
    2753             :     // Check if data after save it
    2754           1 :     CPPUNIT_ASSERT_EQUAL(pData->maStart, aDataStart);
    2755           1 :     CPPUNIT_ASSERT_EQUAL(pData->maEnd , aDataEnd);
    2756             : 
    2757           1 :     CPPUNIT_ASSERT_EQUAL(pNData->maStart, aNDataStart);
    2758           1 :     CPPUNIT_ASSERT_EQUAL(pNData->maEnd , aNDataEnd);
    2759             : 
    2760             :     // Insert a column.
    2761           1 :     rDoc1.InsertCol(ScRange( aDataStart.Col(), 0 , 0 , aDataStart.Col(), MAXROW, 0 ));
    2762             : 
    2763             :     // Get anchor data
    2764           1 :     pData = ScDrawLayer::GetObjData(pObj, false);
    2765           1 :     CPPUNIT_ASSERT_MESSAGE("Failed to retrieve user data for this object.", pData);
    2766           1 :     CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pData->maLastRect.IsEmpty());
    2767             : 
    2768             :     // Get non rotated anchor data
    2769           1 :     pNData = ScDrawLayer::GetNonRotatedObjData( pObj );
    2770           1 :     CPPUNIT_ASSERT_MESSAGE("Failed to retrieve non rotated user data for this object.", pNData);
    2771           1 :     CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pNData->maLastRect.IsEmpty());
    2772             : 
    2773             :     // Check if data has moved to new rows
    2774           1 :     CPPUNIT_ASSERT_EQUAL(pData->maStart.Col(), SCCOL(aDataStart.Col() + 1));
    2775           1 :     CPPUNIT_ASSERT_EQUAL(pData->maEnd.Col() , SCCOL(aDataEnd.Col() + 1));
    2776             : 
    2777           1 :     CPPUNIT_ASSERT_EQUAL(pNData->maStart.Col(), SCCOL(aNDataStart.Col() + 1));
    2778           1 :     CPPUNIT_ASSERT_EQUAL(pNData->maEnd.Col() , SCCOL(aNDataEnd.Col() + 1));
    2779             : 
    2780             :     // Save the anchor data
    2781           1 :     aDataStart = pData->maStart;
    2782           1 :     aDataEnd   = pData->maEnd;
    2783           1 :     aNDataStart = pNData->maStart;
    2784           1 :     aNDataEnd   = pNData->maEnd;
    2785             : 
    2786             :     // Save the document and load again to check anchor persist
    2787           2 :     ScDocShellRef xDocSh2 = saveAndReload(&(*xDocSh1), ODS);
    2788             : 
    2789             :     // There are two cell-anchored objects on the first sheet.
    2790           1 :     ScDocument& rDoc2 = xDocSh2->GetDocument();
    2791             : 
    2792           1 :     CPPUNIT_ASSERT_MESSAGE("There should be at least one sheet.", rDoc2.GetTableCount() > 0);
    2793             : 
    2794           1 :     pDrawLayer = rDoc2.GetDrawLayer();
    2795           1 :     pPage = pDrawLayer->GetPage(0);
    2796           1 :     CPPUNIT_ASSERT_MESSAGE("draw page for sheet 1 should exist.", pPage);
    2797           1 :     pObj = pPage->GetObj(0);
    2798           1 :     CPPUNIT_ASSERT_MESSAGE("Failed to get drawing object.", pObj);
    2799             : 
    2800             :     // Check cell anchor state
    2801           1 :     oldType = ScDrawLayer::GetAnchorType(*pObj);
    2802           1 :     CPPUNIT_ASSERT_MESSAGE( "Failed to get anchor type", oldType == SCA_CELL );
    2803             : 
    2804             :     // Get anchor data
    2805           1 :     pData = ScDrawLayer::GetObjData(pObj, false);
    2806           1 :     CPPUNIT_ASSERT_MESSAGE("Failed to retrieve user data for this object.", pData);
    2807           1 :     CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pData->maLastRect.IsEmpty());
    2808             : 
    2809             :     // Get non rotated anchor data
    2810           1 :     pNData = ScDrawLayer::GetNonRotatedObjData( pObj );
    2811           1 :     CPPUNIT_ASSERT_MESSAGE("Failed to retrieve non rotated user data for this object.", pNData);
    2812           1 :     CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pNData->maLastRect.IsEmpty());
    2813             : 
    2814             :     // Check if data after save it
    2815           1 :     CPPUNIT_ASSERT_EQUAL(pData->maStart, aDataStart);
    2816           1 :     CPPUNIT_ASSERT_EQUAL(pData->maEnd , aDataEnd);
    2817             : 
    2818           1 :     CPPUNIT_ASSERT_EQUAL(pNData->maStart, aNDataStart);
    2819           1 :     CPPUNIT_ASSERT_EQUAL(pNData->maEnd , aNDataEnd);
    2820             : 
    2821           2 :     xDocSh2->DoClose();
    2822           1 : }
    2823             : 
    2824           1 : CPPUNIT_TEST_SUITE_REGISTRATION(ScExportTest);
    2825             : 
    2826           4 : CPPUNIT_PLUGIN_IMPLEMENT();
    2827             : 
    2828             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11