sc/inc/compiler.hxx | 13 +-- sc/inc/tokenstringcontext.hxx | 3 sc/qa/unit/ucalc_formula.cxx | 53 +++++++++++++-- sc/source/core/data/documen3.cxx | 2 sc/source/core/tool/compiler.cxx | 99 ++++++++++++++++------------- sc/source/core/tool/token.cxx | 50 ++++++++++++-- sc/source/core/tool/tokenstringcontext.cxx | 68 ++++++++++++++++--- 7 files changed, 213 insertions(+), 75 deletions(-)
New commits: commit f5f9aa53d74d94153189c8f4d4349a0bff3dca0a Author: Kohei Yoshida <[email protected]> Date: Fri Nov 15 18:28:32 2013 -0500 Let's have makeRefStr() take individual parameters again. And remove use of TokenStringContext from ScCompiler. Change-Id: Ib0636e2437a64edd372623a7176dab462eed831b diff --git a/sc/inc/compiler.hxx b/sc/inc/compiler.hxx index ee3c689..0fed5cb 100644 --- a/sc/inc/compiler.hxx +++ b/sc/inc/compiler.hxx @@ -78,12 +78,6 @@ class ScRangeData; class ScExternalRefManager; class ScTokenArray; -namespace sc { - -struct TokenStringContext; - -} - // constants and data types internal to compiler /* @@ -241,7 +235,10 @@ public: virtual ~Convention(); virtual void makeRefStr( - OUStringBuffer& rBuffer, const ScAddress& rPos, const sc::TokenStringContext& rCxt, + OUStringBuffer& rBuffer, + formula::FormulaGrammar::Grammar eGram, + const ScAddress& rPos, + const OUString& rErrRef, const std::vector<OUString>& rTabNames, const ScComplexRefData& rRef, bool bSingleRef ) const = 0; virtual ::com::sun::star::i18n::ParseResult @@ -338,7 +335,7 @@ private: bool mbCloseBrackets; // whether to close open brackets automatically, default TRUE bool mbRewind; // whether symbol is to be rewound to some step during lexical analysis std::vector<sal_uInt16> maExternalFiles; - mutable sc::TokenStringContext* mpTokenStringCxt; + std::vector<OUString> maTabNames; bool NextNewToken(bool bInArray = false); diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx index a9d17d6..39b4987 100644 --- a/sc/source/core/tool/compiler.cxx +++ b/sc/source/core/tool/compiler.cxx @@ -67,7 +67,6 @@ #include "formulaparserpool.hxx" #include "tokenarray.hxx" #include "scmatrix.hxx" -#include "tokenstringcontext.hxx" using namespace formula; using namespace ::com::sun::star; @@ -728,19 +727,20 @@ struct ConventionOOO_A1 : public Convention_A1 ConventionOOO_A1() : Convention_A1 (FormulaGrammar::CONV_OOO) { } ConventionOOO_A1( FormulaGrammar::AddressConvention eConv ) : Convention_A1 (eConv) { } - static OUString MakeTabStr( const sc::TokenStringContext& rCxt, SCTAB nTab ) + static OUString MakeTabStr( const std::vector<OUString>& rTabNames, SCTAB nTab ) { OUString aString; - if (static_cast<size_t>(nTab) >= rCxt.maTabNames.size()) + if (static_cast<size_t>(nTab) >= rTabNames.size()) aString = ScGlobal::GetRscString(STR_NO_REF_TABLE); else - aString = rCxt.maTabNames[nTab]; + aString = rTabNames[nTab]; aString += "."; return aString; } void MakeOneRefStrImpl( - OUStringBuffer& rBuffer, const sc::TokenStringContext& rCxt, + OUStringBuffer& rBuffer, + const OUString& rErrRef, const std::vector<OUString>& rTabNames, const ScSingleRefData& rRef, const ScAddress& rAbsRef, bool bForceTab, bool bODF ) const { @@ -750,12 +750,12 @@ struct ConventionOOO_A1 : public Convention_A1 { if (!rRef.IsTabRel()) rBuffer.append('$'); - rBuffer.append(rCxt.maErrRef); + rBuffer.append(rErrRef); rBuffer.append('.'); } else { - OUString aRefStr(MakeTabStr(rCxt, rAbsRef.Tab())); + OUString aRefStr(MakeTabStr(rTabNames, rAbsRef.Tab())); if (!rRef.IsTabRel()) rBuffer.append('$'); rBuffer.append(aRefStr); @@ -766,20 +766,21 @@ struct ConventionOOO_A1 : public Convention_A1 if (!rRef.IsColRel()) rBuffer.append('$'); if (!ValidCol(rAbsRef.Col())) - rBuffer.append(rCxt.maErrRef); + rBuffer.append(rErrRef); else MakeColStr(rBuffer, rAbsRef.Col()); if (!rRef.IsRowRel()) rBuffer.append('$'); if (!ValidRow(rAbsRef.Row())) - rBuffer.append(rCxt.maErrRef); + rBuffer.append(rErrRef); else MakeRowStr(rBuffer, rAbsRef.Row()); } void makeRefStr( OUStringBuffer& rBuffer, + formula::FormulaGrammar::Grammar /*eGram*/, const ScAddress& rPos, - const sc::TokenStringContext& rCxt, + const OUString& rErrRef, const std::vector<OUString>& rTabNames, const ScComplexRefData& rRef, bool bSingleRef ) const { @@ -790,11 +791,11 @@ struct ConventionOOO_A1 : public Convention_A1 if( !bSingleRef ) aAbs2 = aRef.Ref2.toAbs(rPos); - MakeOneRefStrImpl(rBuffer, rCxt, aRef.Ref1, aAbs1, false, false); + MakeOneRefStrImpl(rBuffer, rErrRef, rTabNames, aRef.Ref1, aAbs1, false, false); if (!bSingleRef) { rBuffer.append(':'); - MakeOneRefStrImpl(rBuffer, rCxt, aRef.Ref2, aAbs2, aAbs1.Tab() != aAbs2.Tab(), false); + MakeOneRefStrImpl(rBuffer, rErrRef, rTabNames, aRef.Ref2, aAbs2, aAbs1.Tab() != aAbs2.Tab(), false); } } @@ -969,8 +970,9 @@ struct ConventionOOO_A1_ODF : public ConventionOOO_A1 { ConventionOOO_A1_ODF() : ConventionOOO_A1 (FormulaGrammar::CONV_ODF) { } void makeRefStr( OUStringBuffer& rBuffer, + formula::FormulaGrammar::Grammar eGram, const ScAddress& rPos, - const sc::TokenStringContext& rCxt, + const OUString& rErrRef, const std::vector<OUString>& rTabNames, const ScComplexRefData& rRef, bool bSingleRef ) const { @@ -982,20 +984,20 @@ struct ConventionOOO_A1_ODF : public ConventionOOO_A1 if( !bSingleRef ) aAbs2 = aRef.Ref2.toAbs(rPos); - if (FormulaGrammar::isODFF(rCxt.meGram) && (!ValidAddress(aAbs1) || !ValidAddress(aAbs2))) + if (FormulaGrammar::isODFF(eGram) && (!ValidAddress(aAbs1) || !ValidAddress(aAbs2))) { - rBuffer.append(rCxt.maErrRef); + rBuffer.append(rErrRef); // For ODFF write [#REF!], but not for PODF so apps reading ODF // 1.0/1.1 may have a better chance if they implemented the old // form. } else { - MakeOneRefStrImpl(rBuffer, rCxt, aRef.Ref1, aAbs1, false, true); + MakeOneRefStrImpl(rBuffer, rErrRef, rTabNames, aRef.Ref1, aAbs1, false, true); if (!bSingleRef) { rBuffer.append(sal_Unicode(':')); - MakeOneRefStrImpl(rBuffer, rCxt, aRef.Ref2, aAbs2, aAbs1.Tab() != aAbs2.Tab(), true); + MakeOneRefStrImpl(rBuffer, rErrRef, rTabNames, aRef.Ref2, aAbs2, aAbs1.Tab() != aAbs2.Tab(), true); } } rBuffer.append(sal_Unicode(']')); @@ -1027,21 +1029,21 @@ const ScCompiler::Convention * const ScCompiler::pConvOOO_A1_ODF = &ConvOOO_A1_O struct ConventionXL { static void GetTab( - const ScAddress& rPos, const sc::TokenStringContext& rCxt, + const ScAddress& rPos, const std::vector<OUString>& rTabNames, const ScSingleRefData& rRef, OUString& rTabName ) { ScAddress aAbs = rRef.toAbs(rPos); - if (rRef.IsTabDeleted() || static_cast<size_t>(aAbs.Tab()) >= rCxt.maTabNames.size()) + if (rRef.IsTabDeleted() || static_cast<size_t>(aAbs.Tab()) >= rTabNames.size()) { rTabName = ScGlobal::GetRscString( STR_NO_REF_TABLE ); return; } - rTabName = rCxt.maTabNames[aAbs.Tab()]; + rTabName = rTabNames[aAbs.Tab()]; } static void MakeTabStr( OUStringBuffer& rBuf, const ScAddress& rPos, - const sc::TokenStringContext& rCxt, + const std::vector<OUString>& rTabNames, const ScComplexRefData& rRef, bool bSingleRef ) { @@ -1049,11 +1051,11 @@ struct ConventionXL { OUString aStartTabName, aEndTabName; - GetTab(rPos, rCxt, rRef.Ref1, aStartTabName); + GetTab(rPos, rTabNames, rRef.Ref1, aStartTabName); if( !bSingleRef && rRef.Ref2.IsFlag3D() ) { - GetTab(rPos, rCxt, rRef.Ref2, aEndTabName); + GetTab(rPos, rTabNames, rRef.Ref2, aEndTabName); } rBuf.append( aStartTabName ); @@ -1211,8 +1213,9 @@ struct ConventionXL_A1 : public Convention_A1, public ConventionXL } void makeRefStr( OUStringBuffer& rBuf, + formula::FormulaGrammar::Grammar /*eGram*/, const ScAddress& rPos, - const sc::TokenStringContext& rCxt, + const OUString& /*rErrRef*/, const std::vector<OUString>& rTabNames, const ScComplexRefData& rRef, bool bSingleRef ) const { @@ -1222,7 +1225,7 @@ struct ConventionXL_A1 : public Convention_A1, public ConventionXL // Foo!A1:#REF! versus #REF! at this point ScAddress aAbs1 = aRef.Ref1.toAbs(rPos), aAbs2; - MakeTabStr(rBuf, rPos, rCxt, aRef, bSingleRef); + MakeTabStr(rBuf, rPos, rTabNames, aRef, bSingleRef); if (!ValidAddress(aAbs1)) { @@ -1401,15 +1404,16 @@ struct ConventionXL_R1C1 : public ScCompiler::Convention, public ConventionXL { ConventionXL_R1C1() : ScCompiler::Convention( FormulaGrammar::CONV_XL_R1C1 ) { } void makeRefStr( OUStringBuffer& rBuf, + formula::FormulaGrammar::Grammar /*eGram*/, const ScAddress& rPos, - const sc::TokenStringContext& rCxt, + const OUString& /*rErrRef*/, const std::vector<OUString>& rTabNames, const ScComplexRefData& rRef, bool bSingleRef ) const { ScRange aAbsRef = rRef.toAbs(rPos); ScComplexRefData aRef( rRef ); - MakeTabStr(rBuf, rPos, rCxt, aRef, bSingleRef); + MakeTabStr(rBuf, rPos, rTabNames, aRef, bSingleRef); // Play fast and loose with invalid refs. There is not much point in producing // Foo!A1:#REF! versus #REF! at this point @@ -1606,10 +1610,19 @@ ScCompiler::ScCompiler( ScDocument* pDocument, const ScAddress& rPos,ScTokenArra meEncodeUrlMode( ENCODE_BY_GRAMMAR ), meExtendedErrorDetection( EXTENDED_ERROR_DETECTION_NONE ), mbCloseBrackets( true ), - mbRewind( false ), - mpTokenStringCxt(NULL) + mbRewind( false ) { nMaxTab = pDoc ? pDoc->GetTableCount() - 1 : 0; + + if (pDoc) + { + maTabNames = pDoc->GetAllTableNames(); + { + std::vector<OUString>::iterator it = maTabNames.begin(), itEnd = maTabNames.end(); + for (; it != itEnd; ++it) + ScCompiler::CheckTabQuotes(*it, formula::FormulaGrammar::extractRefConvention(meGrammar)); + } + } } ScCompiler::ScCompiler( ScDocument* pDocument, const ScAddress& rPos) @@ -1624,15 +1637,23 @@ ScCompiler::ScCompiler( ScDocument* pDocument, const ScAddress& rPos) meEncodeUrlMode( ENCODE_BY_GRAMMAR ), meExtendedErrorDetection( EXTENDED_ERROR_DETECTION_NONE ), mbCloseBrackets( true ), - mbRewind( false ), - mpTokenStringCxt(NULL) + mbRewind( false ) { nMaxTab = pDoc ? pDoc->GetTableCount() - 1 : 0; + + if (pDoc) + { + maTabNames = pDoc->GetAllTableNames(); + { + std::vector<OUString>::iterator it = maTabNames.begin(), itEnd = maTabNames.end(); + for (; it != itEnd; ++it) + ScCompiler::CheckTabQuotes(*it, formula::FormulaGrammar::extractRefConvention(meGrammar)); + } + } } ScCompiler::~ScCompiler() { - delete mpTokenStringCxt; } void ScCompiler::CheckTabQuotes( OUString& rString, @@ -4172,9 +4193,7 @@ void ScCompiler::CreateStringFromMatrix( void ScCompiler::CreateStringFromSingleRef(OUStringBuffer& rBuffer,FormulaToken* _pTokenP) const { - if (!mpTokenStringCxt) - mpTokenStringCxt = new sc::TokenStringContext(pDoc, meGrammar); - + OUString aErrRef = GetCurrentOpCodeMap()->getSymbol(ocErrRef); const OpCode eOp = _pTokenP->GetOpCode(); const ScSingleRefData& rRef = static_cast<const ScToken*>(_pTokenP)->GetSingleRef(); ScComplexRefData aRef; @@ -4191,19 +4210,17 @@ void ScCompiler::CreateStringFromSingleRef(OUStringBuffer& rBuffer,FormulaToken* else { rBuffer.append(ScGlobal::GetRscString(STR_NO_NAME_REF)); - pConv->makeRefStr(rBuffer, aPos, *mpTokenStringCxt, aRef, true); + pConv->makeRefStr(rBuffer, meGrammar, aPos, aErrRef, maTabNames, aRef, true); } } else - pConv->makeRefStr(rBuffer, aPos, *mpTokenStringCxt, aRef, true); + pConv->makeRefStr(rBuffer, meGrammar, aPos, aErrRef, maTabNames, aRef, true); } void ScCompiler::CreateStringFromDoubleRef(OUStringBuffer& rBuffer,FormulaToken* _pTokenP) const { - if (!mpTokenStringCxt) - mpTokenStringCxt = new sc::TokenStringContext(pDoc, meGrammar); - - pConv->makeRefStr(rBuffer, aPos, *mpTokenStringCxt, static_cast<ScToken*>(_pTokenP)->GetDoubleRef(), false); + OUString aErrRef = GetCurrentOpCodeMap()->getSymbol(ocErrRef); + pConv->makeRefStr(rBuffer, meGrammar, aPos, aErrRef, maTabNames, static_cast<ScToken*>(_pTokenP)->GetDoubleRef(), false); } void ScCompiler::CreateStringFromIndex(OUStringBuffer& rBuffer,FormulaToken* _pTokenP) const diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx index a291ed3..b60d77a 100644 --- a/sc/source/core/tool/token.cxx +++ b/sc/source/core/tool/token.cxx @@ -3202,7 +3202,7 @@ void appendTokenByType( sc::TokenStringContext& rCxt, OUStringBuffer& rBuf, cons ScComplexRefData aRef; aRef.Ref1 = rRef; aRef.Ref2 = rRef; - rCxt.mpRefConv->makeRefStr(rBuf, rPos, rCxt, aRef, true); + rCxt.mpRefConv->makeRefStr(rBuf, rCxt.meGram, rPos, rCxt.maErrRef, rCxt.maTabNames, aRef, true); } else rBuf.append(rCxt.maErrRef); @@ -3213,7 +3213,7 @@ void appendTokenByType( sc::TokenStringContext& rCxt, OUStringBuffer& rBuf, cons if (rCxt.mpRefConv) { const ScComplexRefData& rRef = static_cast<const ScToken&>(rToken).GetDoubleRef(); - rCxt.mpRefConv->makeRefStr(rBuf, rPos, rCxt, rRef, false); + rCxt.mpRefConv->makeRefStr(rBuf, rCxt.meGram, rPos, rCxt.maErrRef, rCxt.maTabNames, rRef, false); } else rBuf.append(rCxt.maErrRef); commit b1ff85e295b8924ff75307c8b524e4e3b00ef259 Author: Kohei Yoshida <[email protected]> Date: Fri Nov 15 16:16:04 2013 -0500 Handle sheet-local range names too. Change-Id: Ib1503c3b69d77946b4437bdc0e1bfa5ebacbb602 diff --git a/sc/inc/tokenstringcontext.hxx b/sc/inc/tokenstringcontext.hxx index 6015a59..7af90eb 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 35a3599..91e4594 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 73f8d71..e76b78c 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 3a780e3..a291ed3 100644 --- a/sc/source/core/tool/token.cxx +++ b/sc/source/core/tool/token.cxx @@ -3224,19 +3224,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 6eaf0ee..e3aea0e 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())); } } } commit f559e7a42dc678c6a2298c161d1810cc667b36b8 Author: Kohei Yoshida <[email protected]> Date: Fri Nov 15 15:21:18 2013 -0500 Handle named database ranges in CreateString(). Change-Id: I6904b9de0f7d711252797bb2e33ba4c462476b2d diff --git a/sc/inc/tokenstringcontext.hxx b/sc/inc/tokenstringcontext.hxx index 5bcc3b3..6015a59 100644 --- a/sc/inc/tokenstringcontext.hxx +++ b/sc/inc/tokenstringcontext.hxx @@ -35,6 +35,7 @@ struct SC_DLLPUBLIC TokenStringContext std::vector<OUString> maTabNames; IndexNameMapType maGlobalRangeNames; + 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 43e0d1d..35a3599 100644 --- a/sc/qa/unit/ucalc_formula.cxx +++ b/sc/qa/unit/ucalc_formula.cxx @@ -23,6 +23,7 @@ #include "docfunc.hxx" #include "paramisc.hxx" #include "tokenstringcontext.hxx" +#include "dbdata.hxx" #include "formula/vectortoken.hxx" @@ -65,6 +66,31 @@ void Test::testFormulaCreateStringFromTokens() CPPUNIT_ASSERT_MESSAGE("Failed to insert a new name.", bInserted); } + // Insert DB ranges. + struct { + const char* pName; + SCTAB nTab; + SCCOL nCol1; + SCROW nRow1; + SCCOL nCol2; + SCROW nRow2; + } aDBs[] = { + { "Table1", 0, 0, 0, 10, 10 }, + { "Table2", 1, 0, 0, 10, 10 }, + { "Table3", 2, 0, 0, 10, 10 } + }; + + ScDBCollection* pDBs = m_pDoc->GetDBCollection(); + CPPUNIT_ASSERT_MESSAGE("Failed to fetch DB collection object.", pDBs); + + for (size_t i = 0, n = SAL_N_ELEMENTS(aDBs); i < n; ++i) + { + ScDBData* pData = new ScDBData( + OUString::createFromAscii( + aDBs[i].pName), aDBs[i].nTab, aDBs[i].nCol1, aDBs[i].nRow1, aDBs[i].nCol2,aDBs[i].nRow2); + pDBs->getNamedDBs().insert(pData); + } + const char* aTests[] = { "1+2", "SUM(A1:A10;B1:B10;C5;D6)", @@ -72,7 +98,8 @@ void Test::testFormulaCreateStringFromTokens() "AVERAGE('2013'.B10:C20)", "'Kevin''s Data'.B10", "'Past Data'.B1+'2013'.B2*(1+'Kevin''s Data'.C10)", - "x+y*z" + "x+y*z", // named ranges + "MAX(Table1)+MIN(Table2)*SUM(Table3)" // database ranges }; boost::scoped_ptr<ScTokenArray> pArray; diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx index c2b8056..3a780e3 100644 --- a/sc/source/core/tool/token.cxx +++ b/sc/source/core/tool/token.cxx @@ -40,6 +40,7 @@ #include "refupdatecontext.hxx" #include "tokenstringcontext.hxx" #include "types.hxx" +#include "globstr.hrc" #include "svl/sharedstring.hxx" using ::std::vector; @@ -3233,9 +3234,15 @@ void appendTokenByType( sc::TokenStringContext& rCxt, OUStringBuffer& rBuf, cons rBuf.append(it->second); } break; - // TODO : Handle other name types. + case ocDBArea: + { + sc::TokenStringContext::IndexNameMapType::const_iterator it = rCxt.maNamedDBs.find(nIndex); + if (it != rCxt.maNamedDBs.end()) + rBuf.append(it->second); + } + break; default: - ; + rBuf.append(ScGlobal::GetRscString(STR_NO_NAME_REF)); } } break; diff --git a/sc/source/core/tool/tokenstringcontext.cxx b/sc/source/core/tool/tokenstringcontext.cxx index 075bd96..6eaf0ee 100644 --- a/sc/source/core/tool/tokenstringcontext.cxx +++ b/sc/source/core/tool/tokenstringcontext.cxx @@ -10,6 +10,7 @@ #include "tokenstringcontext.hxx" #include "compiler.hxx" #include "document.hxx" +#include "dbdata.hxx" using namespace com::sun::star; @@ -26,6 +27,7 @@ TokenStringContext::TokenStringContext( const ScDocument* pDoc, formula::Formula if (pDoc) { + // Fetch all sheet names. maTabNames = pDoc->GetAllTableNames(); { std::vector<OUString>::iterator it = maTabNames.begin(), itEnd = maTabNames.end(); @@ -33,6 +35,7 @@ TokenStringContext::TokenStringContext( const ScDocument* pDoc, formula::Formula ScCompiler::CheckTabQuotes(*it, formula::FormulaGrammar::extractRefConvention(eGram)); } + // Fetch all named range names. const ScRangeName* pNames = pDoc->GetRangeName(); if (pNames) { @@ -43,6 +46,19 @@ TokenStringContext::TokenStringContext( const ScDocument* pDoc, formula::Formula maGlobalRangeNames.insert(IndexNameMapType::value_type(pData->GetIndex(), pData->GetName())); } } + + // 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 ScDBData& rData = *it; + maNamedDBs.insert(IndexNameMapType::value_type(rData.GetIndex(), rData.GetName())); + } + } } } _______________________________________________ Libreoffice-commits mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
