sc/inc/tokenstringcontext.hxx | 11 ++++++- sc/qa/unit/ucalc_formula.cxx | 30 ++++++++++++++++++-- sc/source/core/tool/token.cxx | 43 ++++++++++++++++++----------- sc/source/core/tool/tokenstringcontext.cxx | 18 +++++++++++- sc/source/filter/oox/formulabuffer.cxx | 12 ++++---- 5 files changed, 86 insertions(+), 28 deletions(-)
New commits: commit cf3977c605cca29e35a9079a3c5c118f4d22fc39 Author: Kohei Yoshida <[email protected]> Date: Fri Nov 15 10:37:26 2013 -0500 Handle global range names and use CreateString() during xlsx import. This makes the load speed slightly faster. Change-Id: I64e4d4b8c42a68577350539f3812cafdc0433f96 diff --git a/sc/inc/tokenstringcontext.hxx b/sc/inc/tokenstringcontext.hxx index e5bb01c..5bcc3b3 100644 --- a/sc/inc/tokenstringcontext.hxx +++ b/sc/inc/tokenstringcontext.hxx @@ -12,6 +12,10 @@ #include "compiler.hxx" +#include <boost/unordered_map.hpp> + +class ScDocument; + namespace sc { /** @@ -20,16 +24,19 @@ namespace sc { * between multiple CreateString() calls as long as the document content is * unmodified. */ -struct TokenStringContext +struct SC_DLLPUBLIC TokenStringContext { + typedef boost::unordered_map<sal_uInt16, OUString> IndexNameMapType; + formula::FormulaGrammar::Grammar meGram; formula::FormulaCompiler::OpCodeMapPtr mxOpCodeMap; const ScCompiler::Convention* mpRefConv; OUString maErrRef; std::vector<OUString> maTabNames; + IndexNameMapType maGlobalRangeNames; - TokenStringContext( formula::FormulaGrammar::Grammar eGram ); + TokenStringContext( const ScDocument* pDoc, formula::FormulaGrammar::Grammar eGram ); }; } diff --git a/sc/qa/unit/ucalc_formula.cxx b/sc/qa/unit/ucalc_formula.cxx index 1f867f1..43e0d1d 100644 --- a/sc/qa/unit/ucalc_formula.cxx +++ b/sc/qa/unit/ucalc_formula.cxx @@ -32,6 +32,7 @@ using namespace formula; void Test::testFormulaCreateStringFromTokens() { + // Insert sheets. OUString aTabName1("Test"); OUString aTabName2("Kevin's Data"); OUString aTabName3("Past Data"); @@ -41,19 +42,42 @@ void Test::testFormulaCreateStringFromTokens() m_pDoc->InsertTab(2, aTabName3); m_pDoc->InsertTab(3, aTabName4); + // Insert named ranges. + struct { + const char* pName; + const char* pExpr; + } aNames[] = { + { "x", "Test.H1" }, + { "y", "Test.H2" }, + { "z", "Test.H3" } + }; + + ScRangeName* pGlobalNames = m_pDoc->GetRangeName(); + CPPUNIT_ASSERT_MESSAGE("Failed to obtain global named expression object.", pGlobalNames); + + for (size_t i = 0, n = SAL_N_ELEMENTS(aNames); i < n; ++i) + { + ScRangeData* pName = new ScRangeData( + m_pDoc, OUString::createFromAscii(aNames[i].pName), OUString::createFromAscii(aNames[i].pExpr), + ScAddress(0,0,0), RT_NAME, formula::FormulaGrammar::GRAM_NATIVE); + + bool bInserted = pGlobalNames->insert(pName); + CPPUNIT_ASSERT_MESSAGE("Failed to insert a new name.", bInserted); + } + const char* aTests[] = { "1+2", "SUM(A1:A10;B1:B10;C5;D6)", "IF(Test.B10<>10;\"Good\";\"Bad\")", "AVERAGE('2013'.B10:C20)", "'Kevin''s Data'.B10", - "'Past Data'.B1+'2013'.B2*(1+'Kevin''s Data'.C10)" + "'Past Data'.B1+'2013'.B2*(1+'Kevin''s Data'.C10)", + "x+y*z" }; boost::scoped_ptr<ScTokenArray> pArray; - sc::TokenStringContext aCxt(formula::FormulaGrammar::GRAM_ENGLISH); - aCxt.maTabNames = m_pDoc->GetAllTableNames(); + sc::TokenStringContext aCxt(m_pDoc, formula::FormulaGrammar::GRAM_ENGLISH); ScAddress aPos(0,0,0); for (size_t i = 0, n = SAL_N_ELEMENTS(aTests); i < n; ++i) diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx index a226549..8984632 100644 --- a/sc/source/core/tool/token.cxx +++ b/sc/source/core/tool/token.cxx @@ -3222,7 +3222,22 @@ void appendTokenByType( sc::TokenStringContext& rCxt, OUStringBuffer& rBuf, cons // TODO : Implement this. break; case svIndex: - // TODO : Implement this. + { + sal_uInt16 nIndex = rToken.GetIndex(); + switch (eOp) + { + case ocName: + { + sc::TokenStringContext::IndexNameMapType::const_iterator it = rCxt.maGlobalRangeNames.find(nIndex); + if (it != rCxt.maGlobalRangeNames.end()) + rBuf.append(it->second); + } + break; + // TODO : Handle other name types. + default: + ; + } + } break; case svExternal: // TODO : Implement this. @@ -3284,23 +3299,19 @@ OUString ScTokenArray::CreateString( sc::TokenStringContext& rCxt, const ScAddre { const FormulaToken* pToken = *p; OpCode eOp = pToken->GetOpCode(); - switch (eOp) + bool bCheckType = true; + if (eOp == ocSpaces) { - case ocPush: - appendTokenByType(rCxt, aBuf, *pToken, rPos); - break; - case ocSpaces: - // TODO : Handle intersection operator '!!'. - aBuf.append(sal_Unicode(' ')); - break; - default: - { - if (eOp < rCxt.mxOpCodeMap->getSymbolCount()) - aBuf.append(rCxt.mxOpCodeMap->getSymbol(eOp)); - else - return OUString(); - } + // TODO : Handle intersection operator '!!'. + aBuf.append(' '); + continue; } + + if (eOp < rCxt.mxOpCodeMap->getSymbolCount()) + aBuf.append(rCxt.mxOpCodeMap->getSymbol(eOp)); + + if (bCheckType) + appendTokenByType(rCxt, aBuf, *pToken, rPos); } return aBuf.makeStringAndClear(); diff --git a/sc/source/core/tool/tokenstringcontext.cxx b/sc/source/core/tool/tokenstringcontext.cxx index 5fea0a9..b26d338 100644 --- a/sc/source/core/tool/tokenstringcontext.cxx +++ b/sc/source/core/tool/tokenstringcontext.cxx @@ -9,12 +9,13 @@ #include "tokenstringcontext.hxx" #include "compiler.hxx" +#include "document.hxx" using namespace com::sun::star; namespace sc { -TokenStringContext::TokenStringContext( formula::FormulaGrammar::Grammar eGram ) : +TokenStringContext::TokenStringContext( const ScDocument* pDoc, formula::FormulaGrammar::Grammar eGram ) : meGram(eGram), mpRefConv(ScCompiler::GetRefConvention(formula::FormulaGrammar::extractRefConvention(eGram))) { @@ -22,6 +23,21 @@ TokenStringContext::TokenStringContext( formula::FormulaGrammar::Grammar eGram ) mxOpCodeMap = aComp.GetOpCodeMap(formula::FormulaGrammar::extractFormulaLanguage(eGram)); if (mxOpCodeMap) maErrRef = mxOpCodeMap->getSymbol(ocErrRef); + + if (pDoc) + { + maTabNames = pDoc->GetAllTableNames(); + const ScRangeName* pNames = pDoc->GetRangeName(); + if (pNames) + { + ScRangeName::const_iterator it = pNames->begin(), itEnd = pNames->end(); + for (; it != itEnd; ++it) + { + const ScRangeData* pData = it->second; + maGlobalRangeNames.insert(IndexNameMapType::value_type(pData->GetIndex(), pData->GetName())); + } + } + } } } diff --git a/sc/source/filter/oox/formulabuffer.cxx b/sc/source/filter/oox/formulabuffer.cxx index 7472d3d..d1cf118 100644 --- a/sc/source/filter/oox/formulabuffer.cxx +++ b/sc/source/filter/oox/formulabuffer.cxx @@ -25,6 +25,7 @@ #include "tokenarray.hxx" #include "sharedformulagroups.hxx" #include "externalrefmgr.hxx" +#include "tokenstringcontext.hxx" #include "oox/token/tokens.hxx" using namespace com::sun::star; @@ -56,7 +57,8 @@ public: Item() : mnRow(-1), mpCell(NULL) {} }; - CachedTokenArray( ScDocument& rDoc ) : mrDoc(rDoc) {} + CachedTokenArray( ScDocument& rDoc ) : + mrDoc(rDoc), maCxt(&rDoc, formula::FormulaGrammar::GRAM_OOXML) {} ~CachedTokenArray() { @@ -73,11 +75,8 @@ public: return NULL; Item& rCached = *it->second; - ScCompiler aComp(&mrDoc, rPos, *rCached.mpCell->GetCode()); - aComp.SetGrammar(formula::FormulaGrammar::GRAM_OOXML); - OUStringBuffer aBuf; - aComp.CreateStringFromTokenArray(aBuf); - OUString aPredicted = aBuf.makeStringAndClear(); + const ScTokenArray& rCode = *rCached.mpCell->GetCode(); + OUString aPredicted = rCode.CreateString(maCxt, rPos); if (rFormula == aPredicted) return &rCached; @@ -108,6 +107,7 @@ private: typedef boost::unordered_map<SCCOL, Item*> ColCacheType; ColCacheType maCache; ScDocument& mrDoc; + sc::TokenStringContext maCxt; }; void applySharedFormulas( _______________________________________________ Libreoffice-commits mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
