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 @@
#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 );
};
}
......
......@@ -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)
......
......@@ -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:
{
aBuf.append(' ');
continue;
}
if (eOp < rCxt.mxOpCodeMap->getSymbolCount())
aBuf.append(rCxt.mxOpCodeMap->getSymbol(eOp));
else
return OUString();
}
}
if (bCheckType)
appendTokenByType(rCxt, aBuf, *pToken, rPos);
}
return aBuf.makeStringAndClear();
......
......@@ -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()));
}
}
}
}
}
......
......@@ -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(
......
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