From 62b36e800d650ede5d48d8a2b81a410578407b32 Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Fri, 15 Nov 2013 16:16:04 -0500 Subject: Handle sheet-local range names too. Change-Id: Ib1503c3b69d77946b4437bdc0e1bfa5ebacbb602 --- sc/inc/tokenstringcontext.hxx | 2 + sc/qa/unit/ucalc_formula.cxx | 24 +++++++-- sc/source/core/data/documen3.cxx | 2 +- sc/source/core/tool/token.cxx | 37 ++++++++++++-- sc/source/core/tool/tokenstringcontext.cxx | 80 ++++++++++++++++++++---------- 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 IndexNameMapType; + typedef boost::unordered_map TabIndexMapType; formula::FormulaGrammar::Grammar meGram; formula::FormulaCompiler::OpCodeMapPtr mxOpCodeMap; @@ -35,6 +36,7 @@ struct SC_DLLPUBLIC TokenStringContext std::vector 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::iterator it = maTabNames.begin(), itEnd = maTabNames.end(); - for (; it != itEnd; ++it) - ScCompiler::CheckTabQuotes(*it, formula::FormulaGrammar::extractRefConvention(eGram)); - } + std::vector::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())); } } } -- cgit v1.2.3