[Libreoffice-commits] core.git: 4 commits - sc/qa sc/source

Kohei Yoshida kohei.yoshida at collabora.com
Mon Mar 10 14:30:29 PDT 2014


 sc/qa/unit/data/xlsx/shared-formula/text-results.xlsx |binary
 sc/qa/unit/subsequent_export-test.cxx                 |   75 +++++++++++++++++-
 sc/source/filter/excel/xestream.cxx                   |   40 ++-------
 sc/source/filter/inc/formulabuffer.hxx                |   15 ++-
 sc/source/filter/inc/worksheethelper.hxx              |    5 -
 sc/source/filter/oox/formulabuffer.cxx                |   44 ++++++++--
 sc/source/filter/oox/sheetdatacontext.cxx             |    4 
 sc/source/filter/oox/worksheethelper.cxx              |    6 -
 8 files changed, 139 insertions(+), 50 deletions(-)

New commits:
commit c1dc7576c18cc534e1934459f5fb210091a5b484
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Mon Mar 10 17:25:34 2014 -0400

    fdo#74747: Correctly inspect formula result value for xlsx export.
    
    Change-Id: I757a8eb371b432970885e2fbd6aea9dd965ab5c0

diff --git a/sc/source/filter/excel/xestream.cxx b/sc/source/filter/excel/xestream.cxx
index 290bd6d..6c3aa3b 100644
--- a/sc/source/filter/excel/xestream.cxx
+++ b/sc/source/filter/excel/xestream.cxx
@@ -679,45 +679,27 @@ static const char* lcl_GetErrorString( sal_uInt16 nScErrCode )
 
 void XclXmlUtils::GetFormulaTypeAndValue( ScFormulaCell& rCell, const char*& rsType, OUString& rsValue )
 {
-    sal_uInt16 nScErrCode = rCell.GetErrCode();
-    if( nScErrCode )
-    {
-        rsType = "e";
-        rsValue = ToOUString( lcl_GetErrorString( nScErrCode ) );
+    sc::FormulaResultValue aResValue = rCell.GetResult();
 
-        return;
-    }
-
-    switch( rCell.GetFormatType() )
+    switch (aResValue.meType)
     {
-        case NUMBERFORMAT_NUMBER:
-        {
-            // either value or error code
+        case sc::FormulaResultValue::Error:
+            rsType = "e";
+            rsValue = ToOUString(lcl_GetErrorString(aResValue.mnError));
+        break;
+        case sc::FormulaResultValue::Value:
             rsType = "n";
-            rsValue = OUString::number( rCell.GetValue() );
-        }
+            rsValue = OUString::number(aResValue.mfValue);
         break;
-
-        case NUMBERFORMAT_TEXT:
-        {
+        case sc::FormulaResultValue::String:
             rsType = "str";
             rsValue = rCell.GetString().getString();
-        }
-        break;
-
-        case NUMBERFORMAT_LOGICAL:
-        {
-            rsType = "b";
-            rsValue = ToOUString( rCell.GetValue() == 0.0 ? "0" : "1" );
-        }
         break;
-
+        case sc::FormulaResultValue::Invalid:
         default:
-        {
+            // TODO : double-check this to see if this is correct.
             rsType = "inlineStr";
             rsValue = rCell.GetString().getString();
-        }
-        break;
     }
 }
 
commit aa5ad7b8096cd15a55c467b1a23d03849aeb870d
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Mon Mar 10 17:03:52 2014 -0400

    fdo#74747: Make use of cached string formula results.
    
    Just like we do with cached numeric formula results.
    
    Change-Id: Ib8b311b540caeb47d8c2162a456f7490c5882ad5

diff --git a/sc/source/filter/inc/formulabuffer.hxx b/sc/source/filter/inc/formulabuffer.hxx
index 6be0a25..5fdc248 100644
--- a/sc/source/filter/inc/formulabuffer.hxx
+++ b/sc/source/filter/inc/formulabuffer.hxx
@@ -77,13 +77,19 @@ public:
         TokenRangeAddressItem( const TokenAddressItem& rTokenAndAddress, const ::com::sun::star::table::CellRangeAddress& rCellRangeAddress ) : maTokenAndAddress( rTokenAndAddress ), maCellRangeAddress( rCellRangeAddress ) {}
     };
 
+    struct FormulaValue
+    {
+        com::sun::star::table::CellAddress maCellAddress;
+        OUString maValueStr;
+        sal_Int32 mnCellType;
+    };
     typedef std::pair<com::sun::star::table::CellAddress, double> ValueAddressPair;
 
     struct SheetItem
     {
         std::vector<TokenAddressItem>* mpCellFormulas;
         std::vector<TokenRangeAddressItem>* mpArrayFormulas;
-        std::vector<ValueAddressPair>* mpCellFormulaValues;
+        std::vector<FormulaValue>* mpCellFormulaValues;
         std::vector<SharedFormulaEntry>* mpSharedFormulaEntries;
         std::vector<SharedFormulaDesc>* mpSharedFormulaIDs;
 
@@ -98,7 +104,7 @@ private:
     typedef ::std::vector< std::vector<SharedFormulaDesc> > SheetToSharedFormulaid;
     // sheet -> stuff needed to create shared formulae
     typedef ::std::vector< std::vector<SharedFormulaEntry> >  SheetToFormulaEntryArray;
-    typedef ::std::vector< std::vector<ValueAddressPair> > FormulaValueArray;
+    typedef ::std::vector< std::vector<FormulaValue> > FormulaValueArray;
 
     osl::Mutex maMtxData;
     FormulaDataArray         maCellFormulas;
@@ -118,8 +124,9 @@ public:
         const ::com::sun::star::table::CellAddress& rAddress, sal_Int32 nSharedId,
         const OUString& rCellValue, sal_Int32 nValueType );
 
-    void                setCellFormulaValue( const ::css::table::CellAddress& rAddress,
-                                             double fValue );
+    void setCellFormulaValue(
+        const css::table::CellAddress& rAddress, const OUString& rValueStr, sal_Int32 nCellType );
+
     void                setCellArrayFormula( const ::css::table::CellRangeAddress& rRangeAddress,
                                              const ::css::table::CellAddress& rTokenAddress,
                                              const OUString& );
diff --git a/sc/source/filter/inc/worksheethelper.hxx b/sc/source/filter/inc/worksheethelper.hxx
index 07f3b73..aa0f239 100644
--- a/sc/source/filter/inc/worksheethelper.hxx
+++ b/sc/source/filter/inc/worksheethelper.hxx
@@ -325,8 +325,9 @@ public:
         const com::sun::star::table::CellRangeAddress& rRange,
         sal_Int32 nSharedId, const OUString& rTokens );
 
-    void                setCellFormulaValue( const ::com::sun::star::table::CellAddress& rAddress,
-                            double fValue  );
+    void setCellFormulaValue(
+        const css::table::CellAddress& rAddress, const OUString& rValueStr, sal_Int32 nCellType );
+
 private:
     WorksheetGlobals&   mrSheetGlob;
 };
diff --git a/sc/source/filter/oox/formulabuffer.cxx b/sc/source/filter/oox/formulabuffer.cxx
index ca241a6..e5a2874 100644
--- a/sc/source/filter/oox/formulabuffer.cxx
+++ b/sc/source/filter/oox/formulabuffer.cxx
@@ -28,6 +28,7 @@
 #include "externalrefmgr.hxx"
 #include "tokenstringcontext.hxx"
 #include "oox/token/tokens.hxx"
+#include <svl/sharedstringpool.hxx>
 
 using namespace com::sun::star;
 using namespace ::com::sun::star::uno;
@@ -256,19 +257,39 @@ void applyArrayFormulas(
 }
 
 void applyCellFormulaValues(
-    ScDocumentImport& rDoc, const std::vector<FormulaBuffer::ValueAddressPair>& rVector )
+    ScDocumentImport& rDoc, const std::vector<FormulaBuffer::FormulaValue>& rVector )
 {
-    std::vector<FormulaBuffer::ValueAddressPair>::const_iterator it = rVector.begin(), itEnd = rVector.end();
+    svl::SharedStringPool& rStrPool = rDoc.getDoc().GetSharedStringPool();
+
+    std::vector<FormulaBuffer::FormulaValue>::const_iterator it = rVector.begin(), itEnd = rVector.end();
     for (; it != itEnd; ++it)
     {
         ScAddress aCellPos;
-        ScUnoConversion::FillScAddress(aCellPos, it->first);
+        ScUnoConversion::FillScAddress(aCellPos, it->maCellAddress);
         ScFormulaCell* pCell = rDoc.getDoc().GetFormulaCell(aCellPos);
-        if (pCell)
+        const OUString& rValueStr = it->maValueStr;
+        if (!pCell)
+            continue;
+
+        switch (it->mnCellType)
         {
-            pCell->SetHybridDouble(it->second);
-            pCell->ResetDirty();
-            pCell->SetChanged(false);
+            case XML_n:
+            {
+                pCell->SetResultDouble(rValueStr.toDouble());
+                pCell->ResetDirty();
+                pCell->SetChanged(false);
+            }
+            break;
+            case XML_str:
+            {
+                svl::SharedString aSS = rStrPool.intern(rValueStr);
+                pCell->SetResultToken(new formula::FormulaStringToken(aSS));
+                pCell->ResetDirty();
+                pCell->SetChanged(false);
+            }
+            break;
+            default:
+                ;
         }
     }
 }
@@ -470,10 +491,15 @@ void FormulaBuffer::setCellArrayFormula( const ::com::sun::star::table::CellRang
     maCellArrayFormulas[ rRangeAddress.Sheet ].push_back( TokenRangeAddressItem( tokenPair, rRangeAddress ) );
 }
 
-void FormulaBuffer::setCellFormulaValue( const ::com::sun::star::table::CellAddress& rAddress, double fValue )
+void FormulaBuffer::setCellFormulaValue(
+        const css::table::CellAddress& rAddress, const OUString& rValueStr, sal_Int32 nCellType )
 {
     assert( rAddress.Sheet >= 0 && (size_t)rAddress.Sheet < maCellFormulaValues.size() );
-    maCellFormulaValues[ rAddress.Sheet ].push_back( ValueAddressPair( rAddress, fValue ) );
+    FormulaValue aVal;
+    aVal.maCellAddress = rAddress;
+    aVal.maValueStr = rValueStr;
+    aVal.mnCellType = nCellType;
+    maCellFormulaValues[rAddress.Sheet].push_back(aVal);
 }
 
 }}
diff --git a/sc/source/filter/oox/sheetdatacontext.cxx b/sc/source/filter/oox/sheetdatacontext.cxx
index 43c15bb..9628e78 100644
--- a/sc/source/filter/oox/sheetdatacontext.cxx
+++ b/sc/source/filter/oox/sheetdatacontext.cxx
@@ -161,8 +161,8 @@ void SheetDataContext::onEndElement()
 
                 // If a number cell has some preloaded value, stick it into the buffer
                 // but do this only for real cell formulas (not array, shared etc.)
-                if( !( maCellValue.isEmpty() ) && ( maCellData.mnCellType == XML_n ) )
-                    setCellFormulaValue( maCellData.maCellAddr, maCellValue.toDouble() );
+                if (!maCellValue.isEmpty())
+                    setCellFormulaValue(maCellData.maCellAddr, maCellValue, maCellData.mnCellType);
                 break;
 
             case XML_shared:
diff --git a/sc/source/filter/oox/worksheethelper.cxx b/sc/source/filter/oox/worksheethelper.cxx
index 32cff08..2dceb6c 100644
--- a/sc/source/filter/oox/worksheethelper.cxx
+++ b/sc/source/filter/oox/worksheethelper.cxx
@@ -1567,10 +1567,10 @@ void WorksheetHelper::putValue( const CellAddress& rAddress, double fValue )
     getDocImport().setNumericCell(aAddress, fValue);
 }
 
-void WorksheetHelper::setCellFormulaValue( const ::com::sun::star::table::CellAddress& rAddress,
-                            double fValue  )
+void WorksheetHelper::setCellFormulaValue(
+    const css::table::CellAddress& rAddress, const OUString& rValueStr, sal_Int32 nCellType )
 {
-    getFormulaBuffer().setCellFormulaValue( rAddress, fValue );
+    getFormulaBuffer().setCellFormulaValue(rAddress, rValueStr, nCellType);
 }
 
 void WorksheetHelper::putString( const CellAddress& rAddress, const OUString& rText )
commit 304e6144c66affd7adcea66f72fb5757eddfb12f
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Mon Mar 10 15:37:46 2014 -0400

    fdo#74747: Test cached numeric results too just to be safe.
    
    Change-Id: I00c68694859fdb9a2f31f50cb3c63984ed146146

diff --git a/sc/qa/unit/subsequent_export-test.cxx b/sc/qa/unit/subsequent_export-test.cxx
index b0011b3..90da87c 100644
--- a/sc/qa/unit/subsequent_export-test.cxx
+++ b/sc/qa/unit/subsequent_export-test.cxx
@@ -1232,11 +1232,14 @@ void ScExportTest::testSharedFormulaExportXLSX()
     ScDocShellRef xDocSh = loadDoc("shared-formula/3d-reference.", XLSX);
     CPPUNIT_ASSERT_MESSAGE("Failed to load file.", xDocSh.Is());
     ScDocument* pDoc = xDocSh->GetDocument();
-    pDoc->CalcAll(); // Recalculate to flush all cached results.
 
     bool bRes = aTest.checkContent(pDoc);
     CPPUNIT_ASSERT_MESSAGE("Content check on the initial document failed.", bRes);
 
+    pDoc->CalcAll(); // Recalculate to flush all cached results.
+    bRes = aTest.checkContent(pDoc);
+    CPPUNIT_ASSERT_MESSAGE("Content check on the initial recalculated document failed.", bRes);
+
     // Save and reload, and check the content again.
     ScDocShellRef xDocSh2 = saveAndReload(xDocSh, XLSX);
     xDocSh->DoClose();
commit c59b3d6c5c8096486730007d9b9b053793b90b1e
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Mon Mar 10 15:32:33 2014 -0400

    fdo#74747: Write test for this first.
    
    Change-Id: Ia528904405cbb698b9cf08d4a8531c60780e0d9e

diff --git a/sc/qa/unit/data/xlsx/shared-formula/text-results.xlsx b/sc/qa/unit/data/xlsx/shared-formula/text-results.xlsx
new file mode 100644
index 0000000..3f59bc3
Binary files /dev/null and b/sc/qa/unit/data/xlsx/shared-formula/text-results.xlsx differ
diff --git a/sc/qa/unit/subsequent_export-test.cxx b/sc/qa/unit/subsequent_export-test.cxx
index 5eb4eca..b0011b3 100644
--- a/sc/qa/unit/subsequent_export-test.cxx
+++ b/sc/qa/unit/subsequent_export-test.cxx
@@ -89,6 +89,7 @@ public:
 
     void testSharedFormulaExportXLS();
     void testSharedFormulaExportXLSX();
+    void testSharedFormulaStringResultExportXLSX();
 
     CPPUNIT_TEST_SUITE(ScExportTest);
     CPPUNIT_TEST(test);
@@ -115,6 +116,7 @@ public:
     CPPUNIT_TEST(testCellBordersXLSX);
     CPPUNIT_TEST(testSharedFormulaExportXLS);
     CPPUNIT_TEST(testSharedFormulaExportXLSX);
+    CPPUNIT_TEST(testSharedFormulaStringResultExportXLSX);
 
     CPPUNIT_TEST_SUITE_END();
 
@@ -1249,6 +1251,74 @@ void ScExportTest::testSharedFormulaExportXLSX()
     xDocSh2->DoClose();
 }
 
+void ScExportTest::testSharedFormulaStringResultExportXLSX()
+{
+    struct
+    {
+        bool checkContent( ScDocument* pDoc )
+        {
+            {
+                // B2:B7 should show A,B,....,F.
+                const char* expected[] = { "A", "B", "C", "D", "E", "F" };
+                for (SCROW i = 0; i <= 5; ++i)
+                {
+                    ScAddress aPos(1,i+1,0);
+                    OUString aStr = pDoc->GetString(aPos);
+                    OUString aExpected = OUString::createFromAscii(expected[i]);
+                    if (aStr != aExpected)
+                    {
+                        cerr << "Wrong value in B" << (i+2) << ": expected='" << aExpected << "', actual='" << aStr << "'" << endl;
+                        return false;
+                    }
+                }
+            }
+
+            {
+                // C2:C7 should show AA,BB,....,FF.
+                const char* expected[] = { "AA", "BB", "CC", "DD", "EE", "FF" };
+                for (SCROW i = 0; i <= 5; ++i)
+                {
+                    ScAddress aPos(2,i+1,0);
+                    OUString aStr = pDoc->GetString(aPos);
+                    OUString aExpected = OUString::createFromAscii(expected[i]);
+                    if (aStr != aExpected)
+                    {
+                        cerr << "Wrong value in C" << (i+2) << ": expected='" << aExpected << "', actual='" << aStr << "'" << endl;
+                        return false;
+                    }
+                }
+            }
+
+            return true;
+        }
+
+    } aTest;
+
+    ScDocShellRef xDocSh = loadDoc("shared-formula/text-results.", XLSX);
+    CPPUNIT_ASSERT_MESSAGE("Failed to load file.", xDocSh.Is());
+    ScDocument* pDoc = xDocSh->GetDocument();
+
+    // Check content without re-calculation, to test cached formula results.
+    bool bRes = aTest.checkContent(pDoc);
+    CPPUNIT_ASSERT_MESSAGE("Content check on the initial document failed.", bRes);
+
+    // Now, re-calculate and check the results.
+    pDoc->CalcAll();
+    bRes = aTest.checkContent(pDoc);
+    CPPUNIT_ASSERT_MESSAGE("Content check on the initial recalculated document failed.", bRes);
+
+    // Reload and check again.
+    ScDocShellRef xDocSh2 = saveAndReload(xDocSh, XLSX);
+    xDocSh->DoClose();
+    CPPUNIT_ASSERT_MESSAGE("Failed to re-load file.", xDocSh2.Is());
+    pDoc = xDocSh2->GetDocument();
+
+    bRes = aTest.checkContent(pDoc);
+    CPPUNIT_ASSERT_MESSAGE("Content check on the reloaded document failed.", bRes);
+
+    xDocSh2->DoClose();
+}
+
 ScExportTest::ScExportTest()
       : ScBootstrapFixture("/sc/qa/unit/data")
 {


More information about the Libreoffice-commits mailing list