summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@collabora.com>2013-11-15 10:37:26 -0500
committerKohei Yoshida <kohei.yoshida@collabora.com>2013-11-18 17:25:37 -0500
commitb8d4d3a59d022ee56b37a835ddb3a282344814e6 (patch)
tree8412075a484fd589b30a35bfd741094bf877ca75
parentb7fd06bf98fea63aab368b4d0968811bdec395c6 (diff)
Handle global range names and use CreateString() during xlsx import.
This makes the load speed slightly faster. Change-Id: I64e4d4b8c42a68577350539f3812cafdc0433f96
-rw-r--r--sc/inc/tokenstringcontext.hxx11
-rw-r--r--sc/qa/unit/ucalc_formula.cxx30
-rw-r--r--sc/source/core/tool/token.cxx43
-rw-r--r--sc/source/core/tool/tokenstringcontext.cxx18
-rw-r--r--sc/source/filter/oox/formulabuffer.cxx12
5 files changed, 86 insertions, 28 deletions
diff --git a/sc/inc/tokenstringcontext.hxx b/sc/inc/tokenstringcontext.hxx
index e5bb01c3ccc9..5bcc3b3ef735 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 1f867f172ed7..43e0d1d0ab41 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 5dc92e61b984..60b4fb3be475 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -3262,7 +3262,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.
@@ -3324,23 +3339,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 5fea0a9837d9..b26d338df278 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 7472d3d78255..d1cf118d13d2 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(