[Libreoffice-commits] core.git: Branch 'private/kohei/xlsx-import-speedup' - 3 commits - sc/inc sc/qa sc/source

Kohei Yoshida kohei.yoshida at collabora.com
Fri Nov 15 15:28:44 PST 2013


 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 <kohei.yoshida at collabora.com>
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 <kohei.yoshida at collabora.com>
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 <kohei.yoshida at collabora.com>
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()));
+            }
+        }
     }
 }
 


More information about the Libreoffice-commits mailing list