Kaydet (Commit) b8d4d3a5 authored tarafından Kohei Yoshida's avatar Kohei Yoshida

Handle global range names and use CreateString() during xlsx import.

This makes the load speed slightly faster.

Change-Id: I64e4d4b8c42a68577350539f3812cafdc0433f96
üst b7fd06bf
...@@ -12,6 +12,10 @@ ...@@ -12,6 +12,10 @@
#include "compiler.hxx" #include "compiler.hxx"
#include <boost/unordered_map.hpp>
class ScDocument;
namespace sc { namespace sc {
/** /**
...@@ -20,16 +24,19 @@ namespace sc { ...@@ -20,16 +24,19 @@ namespace sc {
* between multiple CreateString() calls as long as the document content is * between multiple CreateString() calls as long as the document content is
* unmodified. * unmodified.
*/ */
struct TokenStringContext struct SC_DLLPUBLIC TokenStringContext
{ {
typedef boost::unordered_map<sal_uInt16, OUString> IndexNameMapType;
formula::FormulaGrammar::Grammar meGram; formula::FormulaGrammar::Grammar meGram;
formula::FormulaCompiler::OpCodeMapPtr mxOpCodeMap; formula::FormulaCompiler::OpCodeMapPtr mxOpCodeMap;
const ScCompiler::Convention* mpRefConv; const ScCompiler::Convention* mpRefConv;
OUString maErrRef; OUString maErrRef;
std::vector<OUString> maTabNames; std::vector<OUString> maTabNames;
IndexNameMapType maGlobalRangeNames;
TokenStringContext( formula::FormulaGrammar::Grammar eGram ); TokenStringContext( const ScDocument* pDoc, formula::FormulaGrammar::Grammar eGram );
}; };
} }
......
...@@ -32,6 +32,7 @@ using namespace formula; ...@@ -32,6 +32,7 @@ using namespace formula;
void Test::testFormulaCreateStringFromTokens() void Test::testFormulaCreateStringFromTokens()
{ {
// Insert sheets.
OUString aTabName1("Test"); OUString aTabName1("Test");
OUString aTabName2("Kevin's Data"); OUString aTabName2("Kevin's Data");
OUString aTabName3("Past Data"); OUString aTabName3("Past Data");
...@@ -41,19 +42,42 @@ void Test::testFormulaCreateStringFromTokens() ...@@ -41,19 +42,42 @@ void Test::testFormulaCreateStringFromTokens()
m_pDoc->InsertTab(2, aTabName3); m_pDoc->InsertTab(2, aTabName3);
m_pDoc->InsertTab(3, aTabName4); 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[] = { const char* aTests[] = {
"1+2", "1+2",
"SUM(A1:A10;B1:B10;C5;D6)", "SUM(A1:A10;B1:B10;C5;D6)",
"IF(Test.B10<>10;\"Good\";\"Bad\")", "IF(Test.B10<>10;\"Good\";\"Bad\")",
"AVERAGE('2013'.B10:C20)", "AVERAGE('2013'.B10:C20)",
"'Kevin''s Data'.B10", "'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; boost::scoped_ptr<ScTokenArray> pArray;
sc::TokenStringContext aCxt(formula::FormulaGrammar::GRAM_ENGLISH); sc::TokenStringContext aCxt(m_pDoc, formula::FormulaGrammar::GRAM_ENGLISH);
aCxt.maTabNames = m_pDoc->GetAllTableNames();
ScAddress aPos(0,0,0); ScAddress aPos(0,0,0);
for (size_t i = 0, n = SAL_N_ELEMENTS(aTests); i < n; ++i) for (size_t i = 0, n = SAL_N_ELEMENTS(aTests); i < n; ++i)
......
...@@ -3262,7 +3262,22 @@ void appendTokenByType( sc::TokenStringContext& rCxt, OUStringBuffer& rBuf, cons ...@@ -3262,7 +3262,22 @@ void appendTokenByType( sc::TokenStringContext& rCxt, OUStringBuffer& rBuf, cons
// TODO : Implement this. // TODO : Implement this.
break; break;
case svIndex: 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; break;
case svExternal: case svExternal:
// TODO : Implement this. // TODO : Implement this.
...@@ -3324,23 +3339,19 @@ OUString ScTokenArray::CreateString( sc::TokenStringContext& rCxt, const ScAddre ...@@ -3324,23 +3339,19 @@ OUString ScTokenArray::CreateString( sc::TokenStringContext& rCxt, const ScAddre
{ {
const FormulaToken* pToken = *p; const FormulaToken* pToken = *p;
OpCode eOp = pToken->GetOpCode(); OpCode eOp = pToken->GetOpCode();
switch (eOp) bool bCheckType = true;
if (eOp == ocSpaces)
{ {
case ocPush: // TODO : Handle intersection operator '!!'.
appendTokenByType(rCxt, aBuf, *pToken, rPos); aBuf.append(' ');
break; continue;
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();
}
} }
if (eOp < rCxt.mxOpCodeMap->getSymbolCount())
aBuf.append(rCxt.mxOpCodeMap->getSymbol(eOp));
if (bCheckType)
appendTokenByType(rCxt, aBuf, *pToken, rPos);
} }
return aBuf.makeStringAndClear(); return aBuf.makeStringAndClear();
......
...@@ -9,12 +9,13 @@ ...@@ -9,12 +9,13 @@
#include "tokenstringcontext.hxx" #include "tokenstringcontext.hxx"
#include "compiler.hxx" #include "compiler.hxx"
#include "document.hxx"
using namespace com::sun::star; using namespace com::sun::star;
namespace sc { namespace sc {
TokenStringContext::TokenStringContext( formula::FormulaGrammar::Grammar eGram ) : TokenStringContext::TokenStringContext( const ScDocument* pDoc, formula::FormulaGrammar::Grammar eGram ) :
meGram(eGram), meGram(eGram),
mpRefConv(ScCompiler::GetRefConvention(formula::FormulaGrammar::extractRefConvention(eGram))) mpRefConv(ScCompiler::GetRefConvention(formula::FormulaGrammar::extractRefConvention(eGram)))
{ {
...@@ -22,6 +23,21 @@ TokenStringContext::TokenStringContext( formula::FormulaGrammar::Grammar eGram ) ...@@ -22,6 +23,21 @@ TokenStringContext::TokenStringContext( formula::FormulaGrammar::Grammar eGram )
mxOpCodeMap = aComp.GetOpCodeMap(formula::FormulaGrammar::extractFormulaLanguage(eGram)); mxOpCodeMap = aComp.GetOpCodeMap(formula::FormulaGrammar::extractFormulaLanguage(eGram));
if (mxOpCodeMap) if (mxOpCodeMap)
maErrRef = mxOpCodeMap->getSymbol(ocErrRef); 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()));
}
}
}
} }
} }
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include "tokenarray.hxx" #include "tokenarray.hxx"
#include "sharedformulagroups.hxx" #include "sharedformulagroups.hxx"
#include "externalrefmgr.hxx" #include "externalrefmgr.hxx"
#include "tokenstringcontext.hxx"
#include "oox/token/tokens.hxx" #include "oox/token/tokens.hxx"
using namespace com::sun::star; using namespace com::sun::star;
...@@ -56,7 +57,8 @@ public: ...@@ -56,7 +57,8 @@ public:
Item() : mnRow(-1), mpCell(NULL) {} Item() : mnRow(-1), mpCell(NULL) {}
}; };
CachedTokenArray( ScDocument& rDoc ) : mrDoc(rDoc) {} CachedTokenArray( ScDocument& rDoc ) :
mrDoc(rDoc), maCxt(&rDoc, formula::FormulaGrammar::GRAM_OOXML) {}
~CachedTokenArray() ~CachedTokenArray()
{ {
...@@ -73,11 +75,8 @@ public: ...@@ -73,11 +75,8 @@ public:
return NULL; return NULL;
Item& rCached = *it->second; Item& rCached = *it->second;
ScCompiler aComp(&mrDoc, rPos, *rCached.mpCell->GetCode()); const ScTokenArray& rCode = *rCached.mpCell->GetCode();
aComp.SetGrammar(formula::FormulaGrammar::GRAM_OOXML); OUString aPredicted = rCode.CreateString(maCxt, rPos);
OUStringBuffer aBuf;
aComp.CreateStringFromTokenArray(aBuf);
OUString aPredicted = aBuf.makeStringAndClear();
if (rFormula == aPredicted) if (rFormula == aPredicted)
return &rCached; return &rCached;
...@@ -108,6 +107,7 @@ private: ...@@ -108,6 +107,7 @@ private:
typedef boost::unordered_map<SCCOL, Item*> ColCacheType; typedef boost::unordered_map<SCCOL, Item*> ColCacheType;
ColCacheType maCache; ColCacheType maCache;
ScDocument& mrDoc; ScDocument& mrDoc;
sc::TokenStringContext maCxt;
}; };
void applySharedFormulas( void applySharedFormulas(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment