[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