summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@collabora.com>2013-11-15 16:16:04 -0500
committerKohei Yoshida <kohei.yoshida@collabora.com>2013-11-18 17:25:39 -0500
commit62b36e800d650ede5d48d8a2b81a410578407b32 (patch)
tree7bbd9d20ea5d2791adff6dda30555251bdd424eb
parent24ddf0d93879cfa0d92b2144685960eed26116fb (diff)
Handle sheet-local range names too.
Change-Id: Ib1503c3b69d77946b4437bdc0e1bfa5ebacbb602
-rw-r--r--sc/inc/tokenstringcontext.hxx2
-rw-r--r--sc/qa/unit/ucalc_formula.cxx24
-rw-r--r--sc/source/core/data/documen3.cxx2
-rw-r--r--sc/source/core/tool/token.cxx37
-rw-r--r--sc/source/core/tool/tokenstringcontext.cxx80
5 files changed, 109 insertions, 36 deletions
diff --git a/sc/inc/tokenstringcontext.hxx b/sc/inc/tokenstringcontext.hxx
index 6015a5911813..7af90eb15458 100644
--- a/sc/inc/tokenstringcontext.hxx
+++ b/sc/inc/tokenstringcontext.hxx
@@ -27,6 +27,7 @@ namespace sc {
struct SC_DLLPUBLIC TokenStringContext
{
typedef boost::unordered_map<sal_uInt16, OUString> IndexNameMapType;
+ typedef boost::unordered_map<SCTAB, IndexNameMapType> TabIndexMapType;
formula::FormulaGrammar::Grammar meGram;
formula::FormulaCompiler::OpCodeMapPtr mxOpCodeMap;
@@ -35,6 +36,7 @@ struct SC_DLLPUBLIC TokenStringContext
std::vector<OUString> maTabNames;
IndexNameMapType maGlobalRangeNames;
+ TabIndexMapType maSheetRangeNames;
IndexNameMapType maNamedDBs;
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 35a35996db7e..91e4594d6803 100644
--- a/sc/qa/unit/ucalc_formula.cxx
+++ b/sc/qa/unit/ucalc_formula.cxx
@@ -45,16 +45,21 @@ void Test::testFormulaCreateStringFromTokens()
// Insert named ranges.
struct {
+ bool bGlobal;
const char* pName;
const char* pExpr;
} aNames[] = {
- { "x", "Test.H1" },
- { "y", "Test.H2" },
- { "z", "Test.H3" }
+ { true, "x", "Test.H1" },
+ { true, "y", "Test.H2" },
+ { true, "z", "Test.H3" },
+
+ { false, "sheetx", "Test.J1" }
};
ScRangeName* pGlobalNames = m_pDoc->GetRangeName();
+ ScRangeName* pSheetNames = m_pDoc->GetRangeName(0);
CPPUNIT_ASSERT_MESSAGE("Failed to obtain global named expression object.", pGlobalNames);
+ CPPUNIT_ASSERT_MESSAGE("Failed to obtain sheet-local named expression object.", pSheetNames);
for (size_t i = 0, n = SAL_N_ELEMENTS(aNames); i < n; ++i)
{
@@ -62,8 +67,16 @@ void Test::testFormulaCreateStringFromTokens()
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);
+ if (aNames[i].bGlobal)
+ {
+ bool bInserted = pGlobalNames->insert(pName);
+ CPPUNIT_ASSERT_MESSAGE("Failed to insert a new name.", bInserted);
+ }
+ else
+ {
+ bool bInserted = pSheetNames->insert(pName);
+ CPPUNIT_ASSERT_MESSAGE("Failed to insert a new name.", bInserted);
+ }
}
// Insert DB ranges.
@@ -99,6 +112,7 @@ void Test::testFormulaCreateStringFromTokens()
"'Kevin''s Data'.B10",
"'Past Data'.B1+'2013'.B2*(1+'Kevin''s Data'.C10)",
"x+y*z", // named ranges
+ "SUM(sheetx;x;y;z)", // sheet local and global named ranges mixed
"MAX(Table1)+MIN(Table2)*SUM(Table3)" // database ranges
};
diff --git a/sc/source/core/data/documen3.cxx b/sc/source/core/data/documen3.cxx
index 73f8d71598f8..e76b78ccd7dd 100644
--- a/sc/source/core/data/documen3.cxx
+++ b/sc/source/core/data/documen3.cxx
@@ -109,7 +109,7 @@ void ScDocument::GetAllTabRangeNames(ScRangeName::TabNameCopyMap& rNames) const
// no more tables to iterate through.
break;
- const ScRangeName* p = maTabs[i]->GetRangeName();
+ const ScRangeName* p = maTabs[i]->mpRangeName;
if (!p || p->empty())
// ignore empty ones.
continue;
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index 49663697399e..9506148827d7 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -3264,19 +3264,50 @@ void appendTokenByType( sc::TokenStringContext& rCxt, OUStringBuffer& rBuf, cons
break;
case svIndex:
{
+ typedef sc::TokenStringContext::IndexNameMapType NameType;
+
sal_uInt16 nIndex = rToken.GetIndex();
switch (eOp)
{
case ocName:
{
- sc::TokenStringContext::IndexNameMapType::const_iterator it = rCxt.maGlobalRangeNames.find(nIndex);
- if (it != rCxt.maGlobalRangeNames.end())
+ if (rToken.IsGlobal())
+ {
+ // global named range
+ NameType::const_iterator it = rCxt.maGlobalRangeNames.find(nIndex);
+ if (it == rCxt.maGlobalRangeNames.end())
+ {
+ rBuf.append(ScGlobal::GetRscString(STR_NO_NAME_REF));
+ break;
+ }
+
rBuf.append(it->second);
+ }
+ else
+ {
+ // sheet-local named range
+ sc::TokenStringContext::TabIndexMapType::const_iterator itTab = rCxt.maSheetRangeNames.find(rPos.Tab());
+ if (itTab == rCxt.maSheetRangeNames.end())
+ {
+ rBuf.append(ScGlobal::GetRscString(STR_NO_NAME_REF));
+ break;
+ }
+
+ const NameType& rNames = itTab->second;
+ NameType::const_iterator it = rNames.find(nIndex);
+ if (it == rNames.end())
+ {
+ rBuf.append(ScGlobal::GetRscString(STR_NO_NAME_REF));
+ break;
+ }
+
+ rBuf.append(it->second);
+ }
}
break;
case ocDBArea:
{
- sc::TokenStringContext::IndexNameMapType::const_iterator it = rCxt.maNamedDBs.find(nIndex);
+ NameType::const_iterator it = rCxt.maNamedDBs.find(nIndex);
if (it != rCxt.maNamedDBs.end())
rBuf.append(it->second);
}
diff --git a/sc/source/core/tool/tokenstringcontext.cxx b/sc/source/core/tool/tokenstringcontext.cxx
index 6eaf0ee3e52a..e3aea0ecdd1b 100644
--- a/sc/source/core/tool/tokenstringcontext.cxx
+++ b/sc/source/core/tool/tokenstringcontext.cxx
@@ -16,6 +16,21 @@ using namespace com::sun::star;
namespace sc {
+namespace {
+
+void insertAllNames( TokenStringContext::IndexNameMapType& rMap, const ScRangeName& rNames )
+{
+ ScRangeName::const_iterator it = rNames.begin(), itEnd = rNames.end();
+ for (; it != itEnd; ++it)
+ {
+ const ScRangeData* pData = it->second;
+ rMap.insert(
+ TokenStringContext::IndexNameMapType::value_type(pData->GetIndex(), pData->GetName()));
+ }
+}
+
+}
+
TokenStringContext::TokenStringContext( const ScDocument* pDoc, formula::FormulaGrammar::Grammar eGram ) :
meGram(eGram),
mpRefConv(ScCompiler::GetRefConvention(formula::FormulaGrammar::extractRefConvention(eGram)))
@@ -25,39 +40,50 @@ TokenStringContext::TokenStringContext( const ScDocument* pDoc, formula::Formula
if (mxOpCodeMap)
maErrRef = mxOpCodeMap->getSymbol(ocErrRef);
- if (pDoc)
+ if (!pDoc)
+ return;
+
+ // Fetch all sheet names.
+ maTabNames = pDoc->GetAllTableNames();
{
- // Fetch all sheet names.
- maTabNames = pDoc->GetAllTableNames();
- {
- std::vector<OUString>::iterator it = maTabNames.begin(), itEnd = maTabNames.end();
- for (; it != itEnd; ++it)
- ScCompiler::CheckTabQuotes(*it, formula::FormulaGrammar::extractRefConvention(eGram));
- }
+ std::vector<OUString>::iterator it = maTabNames.begin(), itEnd = maTabNames.end();
+ for (; it != itEnd; ++it)
+ ScCompiler::CheckTabQuotes(*it, formula::FormulaGrammar::extractRefConvention(eGram));
+ }
+
+ // Fetch all named range names.
+ const ScRangeName* pNames = pDoc->GetRangeName();
+ if (pNames)
+ // global names
+ insertAllNames(maGlobalRangeNames, *pNames);
- // Fetch all named range names.
- const ScRangeName* pNames = pDoc->GetRangeName();
- if (pNames)
+ {
+ ScRangeName::TabNameCopyMap aTabRangeNames;
+ pDoc->GetAllTabRangeNames(aTabRangeNames);
+ ScRangeName::TabNameCopyMap::const_iterator it = aTabRangeNames.begin(), itEnd = aTabRangeNames.end();
+ for (; it != itEnd; ++it)
{
- 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()));
- }
+ const ScRangeName* pSheetNames = it->second;
+ if (!pSheetNames)
+ continue;
+
+ SCTAB nTab = it->first;
+ IndexNameMapType aNames;
+ insertAllNames(aNames, *pSheetNames);
+ maSheetRangeNames.insert(TabIndexMapType::value_type(nTab, aNames));
}
+ }
- // Fetch all named database ranges names.
- const ScDBCollection* pDBs = pDoc->GetDBCollection();
- if (pDBs)
+ // Fetch all named database ranges names.
+ const ScDBCollection* pDBs = pDoc->GetDBCollection();
+ if (pDBs)
+ {
+ const ScDBCollection::NamedDBs& rNamedDBs = pDBs->getNamedDBs();
+ ScDBCollection::NamedDBs::const_iterator it = rNamedDBs.begin(), itEnd = rNamedDBs.end();
+ for (; it != itEnd; ++it)
{
- const ScDBCollection::NamedDBs& rNamedDBs = pDBs->getNamedDBs();
- ScDBCollection::NamedDBs::const_iterator it = rNamedDBs.begin(), itEnd = rNamedDBs.end();
- for (; it != itEnd; ++it)
- {
- const ScDBData& rData = *it;
- maNamedDBs.insert(IndexNameMapType::value_type(rData.GetIndex(), rData.GetName()));
- }
+ const ScDBData& rData = *it;
+ maNamedDBs.insert(IndexNameMapType::value_type(rData.GetIndex(), rData.GetName()));
}
}
}