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

Kohei Yoshida kohei.yoshida at collabora.com
Mon Nov 18 12:25:27 PST 2013


 sc/inc/compiler.hxx                        |   15 +-
 sc/inc/externalrefmgr.hxx                  |    7 +
 sc/inc/tokenstringcontext.hxx              |    4 
 sc/qa/unit/ucalc_formula.cxx               |   10 +
 sc/source/core/tool/compiler.cxx           |  172 ++++++++++++-----------------
 sc/source/core/tool/token.cxx              |   35 +++++
 sc/source/core/tool/tokenstringcontext.cxx |   17 ++
 sc/source/ui/docshell/externalrefmgr.cxx   |   14 ++
 8 files changed, 168 insertions(+), 106 deletions(-)

New commits:
commit 4ab50bff9d446a049f7704e2ce77b1907447bf3a
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Mon Nov 18 15:26:05 2013 -0500

    Handle external reference bits too. This is the last missing piece.
    
    Change-Id: Ib1dd18bb5a8d70c53722ac91e2340d05bbc7798a

diff --git a/sc/inc/externalrefmgr.hxx b/sc/inc/externalrefmgr.hxx
index c072cfd..d5b4d7f 100644
--- a/sc/inc/externalrefmgr.hxx
+++ b/sc/inc/externalrefmgr.hxx
@@ -586,6 +586,13 @@ public:
      * @return const OUString* external document URI.
      */
     const OUString* getExternalFileName(sal_uInt16 nFileId, bool bForceOriginal = false);
+
+    /**
+     * Get all cached external file names as an array. Array indices of the
+     * returned name array correspond with external file ID's.
+     */
+    std::vector<OUString> getAllCachedExternalFileNames() const;
+
     bool hasExternalFile(sal_uInt16 nFileId) const;
     bool hasExternalFile(const OUString& rFile) const;
     const SrcFileData* getExternalFileData(sal_uInt16 nFileId) const;
diff --git a/sc/inc/tokenstringcontext.hxx b/sc/inc/tokenstringcontext.hxx
index 7af90eb..85b61f7 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<size_t, std::vector<OUString> > IndexNamesMapType;
     typedef boost::unordered_map<SCTAB, IndexNameMapType> TabIndexMapType;
 
     formula::FormulaGrammar::Grammar meGram;
@@ -39,6 +40,9 @@ struct SC_DLLPUBLIC TokenStringContext
     TabIndexMapType maSheetRangeNames;
     IndexNameMapType maNamedDBs;
 
+    std::vector<OUString> maExternalFileNames;
+    IndexNamesMapType maExternalCachedTabNames;
+
     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 7ae2554..6db441c 100644
--- a/sc/qa/unit/ucalc_formula.cxx
+++ b/sc/qa/unit/ucalc_formula.cxx
@@ -115,11 +115,21 @@ void Test::testFormulaCreateStringFromTokens()
         "SUM(sheetx;x;y;z)", // sheet local and global named ranges mixed
         "MAX(Table1)+MIN(Table2)*SUM(Table3)", // database ranges
         "{1;TRUE;3|FALSE;5;\"Text\"|;;}", // inline matrix
+        "SUM('file:///path/to/fake.file'#$Sheet.A1:B10)",
     };
 
     boost::scoped_ptr<ScTokenArray> pArray;
 
     sc::TokenStringContext aCxt(m_pDoc, formula::FormulaGrammar::GRAM_ENGLISH);
+
+    // Artificially add external refererence data after the context object is
+    // initialized.
+    aCxt.maExternalFileNames.push_back("file:///path/to/fake.file");
+    std::vector<OUString> aExtTabNames;
+    aExtTabNames.push_back("Sheet");
+    aCxt.maExternalCachedTabNames.insert(
+        sc::TokenStringContext::IndexNamesMapType::value_type(0, aExtTabNames));
+
     ScAddress aPos(0,0,0);
 
     for (size_t i = 0, n = SAL_N_ELEMENTS(aTests); i < n; ++i)
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index ff7294e..c5e4fd1 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -3181,7 +3181,40 @@ void appendTokenByType( sc::TokenStringContext& rCxt, OUStringBuffer& rBuf, cons
 {
     if (rToken.IsExternalRef())
     {
-        // TODO : Implement this.
+        size_t nFileId = rToken.GetIndex();
+        OUString aTabName = rToken.GetString().getString();
+        if (nFileId >= rCxt.maExternalFileNames.size())
+            // out of bound
+            return;
+
+        OUString aFileName = rCxt.maExternalFileNames[nFileId];
+
+        switch (rToken.GetType())
+        {
+            case svExternalName:
+                rBuf.append(rCxt.mpRefConv->makeExternalNameStr(aFileName, aTabName));
+            break;
+            case svExternalSingleRef:
+                rCxt.mpRefConv->makeExternalRefStr(
+                       rBuf, rPos, aFileName, aTabName, static_cast<const ScToken&>(rToken).GetSingleRef());
+            break;
+            case svExternalDoubleRef:
+            {
+                sc::TokenStringContext::IndexNamesMapType::const_iterator it =
+                    rCxt.maExternalCachedTabNames.find(nFileId);
+
+                if (it == rCxt.maExternalCachedTabNames.end())
+                    return;
+
+                rCxt.mpRefConv->makeExternalRefStr(
+                    rBuf, rPos, aFileName, it->second, aTabName, static_cast<const ScToken&>(rToken).GetDoubleRef());
+            }
+            break;
+            default:
+                // warning, not error, otherwise we may end up with a never
+                // ending message box loop if this was the cursor cell to be redrawn.
+                OSL_FAIL("appendTokenByType: unknown type of ocExternalRef");
+        }
         return;
     }
 
diff --git a/sc/source/core/tool/tokenstringcontext.cxx b/sc/source/core/tool/tokenstringcontext.cxx
index e3aea0e..a68ae75 100644
--- a/sc/source/core/tool/tokenstringcontext.cxx
+++ b/sc/source/core/tool/tokenstringcontext.cxx
@@ -11,6 +11,7 @@
 #include "compiler.hxx"
 #include "document.hxx"
 #include "dbdata.hxx"
+#include "externalrefmgr.hxx"
 
 using namespace com::sun::star;
 
@@ -86,6 +87,22 @@ TokenStringContext::TokenStringContext( const ScDocument* pDoc, formula::Formula
             maNamedDBs.insert(IndexNameMapType::value_type(rData.GetIndex(), rData.GetName()));
         }
     }
+
+    // Fetch all relevant bits for external references.
+    if (pDoc->HasExternalRefManager())
+    {
+        const ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
+        maExternalFileNames = pRefMgr->getAllCachedExternalFileNames();
+        for (size_t i = 0, n = maExternalFileNames.size(); i < n; ++i)
+        {
+            sal_uInt16 nFileId = static_cast<sal_uInt16>(i);
+            std::vector<OUString> aTabNames;
+            pRefMgr->getAllCachedTableNames(nFileId, aTabNames);
+            if (!aTabNames.empty())
+                maExternalCachedTabNames.insert(
+                    IndexNamesMapType::value_type(nFileId, aTabNames));
+        }
+    }
 }
 
 }
diff --git a/sc/source/ui/docshell/externalrefmgr.cxx b/sc/source/ui/docshell/externalrefmgr.cxx
index c06490e..4646103 100644
--- a/sc/source/ui/docshell/externalrefmgr.cxx
+++ b/sc/source/ui/docshell/externalrefmgr.cxx
@@ -2480,6 +2480,20 @@ const OUString* ScExternalRefManager::getExternalFileName(sal_uInt16 nFileId, bo
     return &maSrcFiles[nFileId].maFileName;
 }
 
+std::vector<OUString> ScExternalRefManager::getAllCachedExternalFileNames() const
+{
+    std::vector<OUString> aNames;
+    aNames.reserve(maSrcFiles.size());
+    std::vector<SrcFileData>::const_iterator it = maSrcFiles.begin(), itEnd = maSrcFiles.end();
+    for (; it != itEnd; ++it)
+    {
+        const SrcFileData& rData = *it;
+        aNames.push_back(rData.maFileName);
+    }
+
+    return aNames;
+}
+
 bool ScExternalRefManager::hasExternalFile(sal_uInt16 nFileId) const
 {
     return nFileId < maSrcFiles.size();
commit 8615f7431e8db69d7000744a4b7cdcd3fa942861
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Mon Nov 18 14:39:13 2013 -0500

    Avoid passing the external ref manager pointer to make it re-entrant.
    
    Change-Id: I67a0df1dcd0635ea82bfc397041a9c43dedbe75d

diff --git a/sc/inc/compiler.hxx b/sc/inc/compiler.hxx
index b6251f7..a8757e7 100644
--- a/sc/inc/compiler.hxx
+++ b/sc/inc/compiler.hxx
@@ -252,13 +252,14 @@ public:
 
         virtual OUString makeExternalNameStr( const OUString& rFile, const OUString& rName ) const = 0;
 
-        virtual void makeExternalRefStr( OUStringBuffer& rBuffer, const ScAddress& rPos,
-                                         sal_uInt16 nFileId, const OUString& rTabName, const ScSingleRefData& rRef,
-                                         ScExternalRefManager* pRefMgr ) const = 0;
-
-        virtual void makeExternalRefStr( OUStringBuffer& rBuffer, const ScAddress& rPos,
-                                         sal_uInt16 nFileId, const OUString& rTabName, const ScComplexRefData& rRef,
-                                         ScExternalRefManager* pRefMgr ) const = 0;
+        virtual void makeExternalRefStr(
+            OUStringBuffer& rBuffer, const ScAddress& rPos, const OUString& rFileName,
+            const OUString& rTabName, const ScSingleRefData& rRef ) const = 0;
+
+        virtual void makeExternalRefStr(
+            OUStringBuffer& rBuffer, const ScAddress& rPos,
+            const OUString& rFileName, const std::vector<OUString>& rTabNames,
+            const OUString& rTabName, const ScComplexRefData& rRef ) const = 0;
 
         enum SpecialSymbolType
         {
diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx
index d3e696e..1668973 100644
--- a/sc/source/core/tool/compiler.cxx
+++ b/sc/source/core/tool/compiler.cxx
@@ -821,22 +821,17 @@ struct ConventionOOO_A1 : public Convention_A1
     }
 
     bool makeExternalSingleRefStr(
-        OUStringBuffer& rBuffer, sal_uInt16 nFileId,
-        const OUString& rTabName, const ScSingleRefData& rRef, const ScAddress& rPos,
-        ScExternalRefManager* pRefMgr, bool bDisplayTabName, bool bEncodeUrl ) const
+        OUStringBuffer& rBuffer, const OUString& rFileName, const OUString& rTabName,
+        const ScSingleRefData& rRef, const ScAddress& rPos, bool bDisplayTabName, bool bEncodeUrl ) const
     {
         ScAddress aAbsRef = rRef.toAbs(rPos);
         if (bDisplayTabName)
         {
             OUString aFile;
-            const OUString* p = pRefMgr->getExternalFileName(nFileId);
-            if (p)
-            {
-                if (bEncodeUrl)
-                    aFile = *p;
-                else
-                    aFile = INetURLObject::decode(*p, INET_HEX_ESCAPE, INetURLObject::DECODE_UNAMBIGUOUS);
-            }
+            if (bEncodeUrl)
+                aFile = rFileName;
+            else
+                aFile = INetURLObject::decode(rFileName, INET_HEX_ESCAPE, INetURLObject::DECODE_UNAMBIGUOUS);
 
             rBuffer.append("'" + aFile.replaceAll("'", "''") + "'#");
 
@@ -857,29 +852,30 @@ struct ConventionOOO_A1 : public Convention_A1
         return true;
     }
 
-    void makeExternalRefStrImpl( OUStringBuffer& rBuffer, const ScAddress& rPos,
-                                     sal_uInt16 nFileId, const OUString& rTabName, const ScSingleRefData& rRef,
-                                     ScExternalRefManager* pRefMgr, bool bODF ) const
+    void makeExternalRefStrImpl(
+        OUStringBuffer& rBuffer, const ScAddress& rPos, const OUString& rFileName,
+        const OUString& rTabName, const ScSingleRefData& rRef, bool bODF ) const
     {
         if (bODF)
             rBuffer.append( '[');
 
         bool bEncodeUrl = bODF;
-        makeExternalSingleRefStr(rBuffer, nFileId, rTabName, rRef, rPos, pRefMgr, true, bEncodeUrl);
+        makeExternalSingleRefStr(rBuffer, rFileName, rTabName, rRef, rPos, true, bEncodeUrl);
         if (bODF)
             rBuffer.append( ']');
     }
 
-    virtual void makeExternalRefStr( OUStringBuffer& rBuffer, const ScAddress& rPos,
-                                     sal_uInt16 nFileId, const OUString& rTabName, const ScSingleRefData& rRef,
-                                     ScExternalRefManager* pRefMgr ) const
+    virtual void makeExternalRefStr(
+        OUStringBuffer& rBuffer, const ScAddress& rPos, const OUString& rFileName,
+        const OUString& rTabName, const ScSingleRefData& rRef ) const
     {
-        makeExternalRefStrImpl(rBuffer, rPos, nFileId, rTabName, rRef, pRefMgr, false);
+        makeExternalRefStrImpl(rBuffer, rPos, rFileName, rTabName, rRef, false);
     }
 
-    void makeExternalRefStrImpl( OUStringBuffer& rBuffer, const ScAddress& rPos,
-                                     sal_uInt16 nFileId, const OUString& rTabName, const ScComplexRefData& rRef,
-                                     ScExternalRefManager* pRefMgr, bool bODF ) const
+    void makeExternalRefStrImpl(
+        OUStringBuffer& rBuffer, const ScAddress& rPos, const OUString& rFileName,
+        const std::vector<OUString>& rTabNames, const OUString& rTabName,
+        const ScComplexRefData& rRef, bool bODF ) const
     {
         ScRange aAbsRange = rRef.toAbs(rPos);
 
@@ -890,7 +886,7 @@ struct ConventionOOO_A1 : public Convention_A1
 
         do
         {
-            if (!makeExternalSingleRefStr(rBuffer, nFileId, rTabName, rRef.Ref1, rPos, pRefMgr, true, bEncodeUrl))
+            if (!makeExternalSingleRefStr(rBuffer, rFileName, rTabName, rRef.Ref1, rPos, true, bEncodeUrl))
                 break;
 
             rBuffer.append(':');
@@ -900,14 +896,7 @@ struct ConventionOOO_A1 : public Convention_A1
             if (bDisplayTabName)
             {
                 // Get the name of the last table.
-                vector<OUString> aTabNames;
-                pRefMgr->getAllCachedTableNames(nFileId, aTabNames);
-                if (aTabNames.empty())
-                {
-                    OSL_TRACE( "ConventionOOO_A1::makeExternalRefStrImpl: no sheet names for document ID %d", nFileId);
-                }
-
-                if (!lcl_getLastTabName(aLastTabName, rTabName, aTabNames, aAbsRange))
+                if (!lcl_getLastTabName(aLastTabName, rTabName, rTabNames, aAbsRange))
                 {
                     OSL_FAIL( "ConventionOOO_A1::makeExternalRefStrImpl: sheet name not found");
                     // aLastTabName contains #REF!, proceed.
@@ -915,18 +904,20 @@ struct ConventionOOO_A1 : public Convention_A1
             }
             else if (bODF)
                 rBuffer.append( '.');      // need at least the sheet separator in ODF
-            makeExternalSingleRefStr( rBuffer, nFileId, aLastTabName,
-                    rRef.Ref2, rPos, pRefMgr, bDisplayTabName, bEncodeUrl);
+            makeExternalSingleRefStr(
+                rBuffer, rFileName, aLastTabName, rRef.Ref2, rPos, bDisplayTabName, bEncodeUrl);
         } while (0);
+
         if (bODF)
             rBuffer.append( ']');
     }
 
-    virtual void makeExternalRefStr( OUStringBuffer& rBuffer, const ScAddress& rPos,
-                                     sal_uInt16 nFileId, const OUString& rTabName, const ScComplexRefData& rRef,
-                                     ScExternalRefManager* pRefMgr ) const
+    virtual void makeExternalRefStr(
+        OUStringBuffer& rBuffer, const ScAddress& rPos, const OUString& rFileName,
+        const std::vector<OUString>& rTabNames, const OUString& rTabName,
+        const ScComplexRefData& rRef ) const
     {
-        makeExternalRefStrImpl(rBuffer, rPos, nFileId, rTabName, rRef, pRefMgr, false);
+        makeExternalRefStrImpl(rBuffer, rPos, rFileName, rTabNames, rTabName, rRef, false);
     }
 };
 
@@ -975,18 +966,19 @@ struct ConventionOOO_A1_ODF : public ConventionOOO_A1
         return lcl_makeExternalNameStr( rFile, rName, '#', true);
     }
 
-    virtual void makeExternalRefStr( OUStringBuffer& rBuffer, const ScAddress& rPos,
-                                     sal_uInt16 nFileId, const OUString& rTabName, const ScSingleRefData& rRef,
-                                     ScExternalRefManager* pRefMgr ) const
+    virtual void makeExternalRefStr(
+        OUStringBuffer& rBuffer, const ScAddress& rPos, const OUString& rFileName,
+        const OUString& rTabName, const ScSingleRefData& rRef ) const
     {
-        makeExternalRefStrImpl(rBuffer, rPos, nFileId, rTabName, rRef, pRefMgr, true);
+        makeExternalRefStrImpl(rBuffer, rPos, rFileName, rTabName, rRef, true);
     }
 
-    virtual void makeExternalRefStr( OUStringBuffer& rBuffer, const ScAddress& rPos,
-                                     sal_uInt16 nFileId, const OUString& rTabName, const ScComplexRefData& rRef,
-                                     ScExternalRefManager* pRefMgr ) const
+    virtual void makeExternalRefStr(
+        OUStringBuffer& rBuffer, const ScAddress& rPos, const OUString& rFileName,
+        const std::vector<OUString>& rTabNames,
+        const OUString& rTabName, const ScComplexRefData& rRef ) const
     {
-        makeExternalRefStrImpl(rBuffer, rPos, nFileId, rTabName, rRef, pRefMgr, true);
+        makeExternalRefStrImpl(rBuffer, rPos, rFileName, rTabNames, rTabName, rRef, true);
     }
 };
 
@@ -1277,9 +1269,9 @@ struct ConventionXL_A1 : public Convention_A1, public ConventionXL
         return ConventionXL::makeExternalNameStr(rFile, rName);
     }
 
-    virtual void makeExternalRefStr( OUStringBuffer& rBuffer, const ScAddress& rPos,
-                                     sal_uInt16 nFileId, const OUString& rTabName, const ScSingleRefData& rRef,
-                                     ScExternalRefManager* pRefMgr ) const
+    virtual void makeExternalRefStr(
+        OUStringBuffer& rBuffer, const ScAddress& rPos, const OUString& rFileName,
+        const OUString& rTabName, const ScSingleRefData& rRef ) const
     {
         // ['file:///path/to/file/filename.xls']'Sheet Name'!$A$1
         // This is a little different from the format Excel uses, as Excel
@@ -1287,34 +1279,22 @@ struct ConventionXL_A1 : public Convention_A1, public ConventionXL
         // whole file path with [] because the file name can contain any
         // characters.
 
-        const OUString* pFullName = pRefMgr->getExternalFileName(nFileId);
-        if (!pFullName)
-            return;
-
-        ConventionXL::makeExternalDocStr(rBuffer, *pFullName, false);
+        ConventionXL::makeExternalDocStr(rBuffer, rFileName, false);
         ScRangeStringConverter::AppendTableName(rBuffer, rTabName);
         rBuffer.append('!');
 
         makeSingleCellStr(rBuffer, rRef, rRef.toAbs(rPos));
     }
 
-    virtual void makeExternalRefStr( OUStringBuffer& rBuffer, const ScAddress& rPos,
-                                     sal_uInt16 nFileId, const OUString& rTabName, const ScComplexRefData& rRef,
-                                     ScExternalRefManager* pRefMgr ) const
+    virtual void makeExternalRefStr(
+        OUStringBuffer& rBuffer, const ScAddress& rPos, const OUString& rFileName,
+        const std::vector<OUString>& rTabNames, const OUString& rTabName,
+        const ScComplexRefData& rRef ) const
     {
-        const OUString* pFullName = pRefMgr->getExternalFileName(nFileId);
-        if (!pFullName)
-            return;
-
-        vector<OUString> aTabNames;
-        pRefMgr->getAllCachedTableNames(nFileId, aTabNames);
-        if (aTabNames.empty())
-            return;
-
         ScRange aAbsRef = rRef.toAbs(rPos);
 
-        ConventionXL::makeExternalDocStr(rBuffer, *pFullName, false);
-        ConventionXL::makeExternalTabNameRange(rBuffer, rTabName, aTabNames, aAbsRef);
+        ConventionXL::makeExternalDocStr(rBuffer, rFileName, false);
+        ConventionXL::makeExternalTabNameRange(rBuffer, rTabName, rTabNames, aAbsRef);
         rBuffer.append('!');
 
         makeSingleCellStr(rBuffer, rRef.Ref1, aAbsRef.aStart);
@@ -1470,9 +1450,9 @@ struct ConventionXL_R1C1 : public ScCompiler::Convention, public ConventionXL
         return ConventionXL::makeExternalNameStr(rFile, rName);
     }
 
-    virtual void makeExternalRefStr( OUStringBuffer& rBuffer, const ScAddress& rPos,
-                                     sal_uInt16 nFileId, const OUString& rTabName, const ScSingleRefData& rRef,
-                                     ScExternalRefManager* pRefMgr ) const
+    virtual void makeExternalRefStr(
+        OUStringBuffer& rBuffer, const ScAddress& rPos, const OUString& rFileName,
+        const OUString& rTabName, const ScSingleRefData& rRef ) const
     {
         // ['file:///path/to/file/filename.xls']'Sheet Name'!$A$1
         // This is a little different from the format Excel uses, as Excel
@@ -1480,13 +1460,8 @@ struct ConventionXL_R1C1 : public ScCompiler::Convention, public ConventionXL
         // whole file path with [] because the file name can contain any
         // characters.
 
-        const OUString* pFullName = pRefMgr->getExternalFileName(nFileId);
-        if (!pFullName)
-            return;
-
         ScAddress aAbsRef = rRef.toAbs(rPos);
-
-        ConventionXL::makeExternalDocStr(rBuffer, *pFullName, false);
+        ConventionXL::makeExternalDocStr(rBuffer, rFileName, false);
         ScRangeStringConverter::AppendTableName(rBuffer, rTabName);
         rBuffer.append('!');
 
@@ -1494,23 +1469,15 @@ struct ConventionXL_R1C1 : public ScCompiler::Convention, public ConventionXL
         r1c1_add_col(rBuffer, rRef, aAbsRef);
     }
 
-    virtual void makeExternalRefStr( OUStringBuffer& rBuffer, const ScAddress& rPos,
-                                     sal_uInt16 nFileId, const OUString& rTabName, const ScComplexRefData& rRef,
-                                     ScExternalRefManager* pRefMgr ) const
+    virtual void makeExternalRefStr(
+        OUStringBuffer& rBuffer, const ScAddress& rPos, const OUString& rFileName,
+        const std::vector<OUString>& rTabNames, const OUString& rTabName,
+        const ScComplexRefData& rRef ) const
     {
-        const OUString* pFullName = pRefMgr->getExternalFileName(nFileId);
-        if (!pFullName)
-            return;
-
-        vector<OUString> aTabNames;
-        pRefMgr->getAllCachedTableNames(nFileId, aTabNames);
-        if (aTabNames.empty())
-            return;
-
         ScRange aAbsRef = rRef.toAbs(rPos);
 
-        ConventionXL::makeExternalDocStr(rBuffer, *pFullName, false);
-        ConventionXL::makeExternalTabNameRange(rBuffer, rTabName, aTabNames, aAbsRef);
+        ConventionXL::makeExternalDocStr(rBuffer, rFileName, false);
+        ConventionXL::makeExternalTabNameRange(rBuffer, rTabName, rTabNames, aAbsRef);
         rBuffer.append('!');
 
         if (!ValidCol(aAbsRef.aEnd.Col()) || !ValidRow(aAbsRef.aEnd.Row()))
@@ -4083,23 +4050,32 @@ void ScCompiler::CreateStringFromExternal(OUStringBuffer& rBuffer, FormulaToken*
 {
     FormulaToken* t = pTokenP;
     ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
+    const OUString* pFileName = pRefMgr->getExternalFileName(t->GetIndex());
+    if (!pFileName)
+        return;
+
     switch (t->GetType())
     {
         case svExternalName:
-        {
-            const OUString *pStr = pRefMgr->getExternalFileName(t->GetIndex());
-            OUString aFileName = pStr ? *pStr : ScGlobal::GetRscString(STR_NO_NAME_REF);
-            rBuffer.append(pConv->makeExternalNameStr( aFileName, t->GetString().getString()));
-        }
+            rBuffer.append(pConv->makeExternalNameStr(*pFileName, t->GetString().getString()));
         break;
         case svExternalSingleRef:
             pConv->makeExternalRefStr(
-                   rBuffer, GetPos(), t->GetIndex(), t->GetString().getString(), static_cast<ScToken*>(t)->GetSingleRef(), pRefMgr);
+                   rBuffer, GetPos(), *pFileName, t->GetString().getString(),
+                   static_cast<ScToken*>(t)->GetSingleRef());
         break;
         case svExternalDoubleRef:
+        {
+            vector<OUString> aTabNames;
+            pRefMgr->getAllCachedTableNames(t->GetIndex(), aTabNames);
+            if (aTabNames.empty())
+                return;
+
             pConv->makeExternalRefStr(
-                        rBuffer, GetPos(), t->GetIndex(), t->GetString().getString(), static_cast<ScToken*>(t)->GetDoubleRef(), pRefMgr);
-           break;
+                rBuffer, GetPos(), *pFileName, aTabNames, t->GetString().getString(),
+                static_cast<ScToken*>(t)->GetDoubleRef());
+        }
+        break;
         default:
             // warning, not error, otherwise we may end up with a never
             // ending message box loop if this was the cursor cell to be redrawn.


More information about the Libreoffice-commits mailing list