[Libreoffice-commits] core.git: Branch 'libreoffice-5-1' - sc/inc sc/source

Eike Rathke erack at redhat.com
Thu May 26 08:45:10 UTC 2016


 sc/inc/externalrefmgr.hxx                |   27 +++-
 sc/source/filter/xml/xmltabi.cxx         |    3 
 sc/source/ui/docshell/docsh.cxx          |   15 ++
 sc/source/ui/docshell/externalrefmgr.cxx |  179 ++++++++++++++++++++++++++-----
 4 files changed, 192 insertions(+), 32 deletions(-)

New commits:
commit 06197fca43d12848e49ad0d3e4240b814032a27b
Author: Eike Rathke <erack at redhat.com>
Date:   Wed May 25 23:25:17 2016 +0200

    tdf#86282 handle both, base name and Sheet1, as external reference sheet name
    
    This is a combination of 4 commits.
    
    Resolves: tdf#86282 do not use file name as sheet name for linked documents
    
    ... and external references.
    
    (cherry picked from commit 43030487c45f49bccdfad987c60d9483b938ebac)
    
    tdf#86282 handle both, base name and Sheet1, as external reference sheet name
    
    While 43030487c45f49bccdfad987c60d9483b938ebac fixed things for older
    'name.csv'#Sheet1.A1 references, loading documents that meanwhile stored
    'name.csv'#name.A1 lead to #REF! when the external links were updated.
    
    Now recognize both, the base file name and Sheet1 name and set up one as
    the alias of the other, so both variants can be handled.
    
    (cherry picked from commit ec693d9b9df631605028271f62daa7dfbe8e273d)
    
    tdf#86282 switch to base name sheet name again for external references CSV
    
    ... now that we can handle both, a base name and Sheet1 name.
    
    For the following reasons:
    
    * Since 4.3 we write and expect the base name as sheet name for CSV.
      While 43030487c45f49bccdfad987c60d9483b938ebac switched that back to
      Sheet1 or its equivalent to be able to load older documents, a mixed
      environment of earlier and later versions gets confused by this.
    
    * The name Sheet1 can be localized and even customized by the user and
      thus fails to update/refresh in a different localized or customized
      environment. This also was already the case for all versions prior to
      4.3 but apparently wasn't recognized or brought in connection with
      some possible failures when updating externally referenced CSV files.
    
    * Deriving the sheet name to be stored from the base name prevents all
      problems related to localized or customized environments, and keeps
      interoperability with all versions from 4.3 on.
    
    (cherry picked from commit d9e7a54809c88c4ac166630c11038188c8f50a6f)
    
    remove now moot comment, tdf#86282 follow-up
    
    (cherry picked from commit 386b284241a16d96eaf792e2385c41f57ce3d870)
    
    Change-Id: I6e23eeff39086091f13914a3f964aec1016a7de4
    e9314e11be19c3316a06e10583777e2d5f5ec1b8
    8d71b3ad6370747115ea419a21094b649326642c
    7e720de93a5f47ca6a81addbb75c113dc2fe53f0
    Reviewed-on: https://gerrit.libreoffice.org/25471
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/sc/inc/externalrefmgr.hxx b/sc/inc/externalrefmgr.hxx
index cb8a1b2..77c497f 100644
--- a/sc/inc/externalrefmgr.hxx
+++ b/sc/inc/externalrefmgr.hxx
@@ -249,7 +249,7 @@ public:
                           const TokenArrayRef& pArray);
 
     bool isDocInitialized(sal_uInt16 nFileId);
-    void initializeDoc(sal_uInt16 nFileId, const ::std::vector<OUString>& rTabNames);
+    void initializeDoc(sal_uInt16 nFileId, const ::std::vector<OUString>& rTabNames, const OUString& rBaseName);
     OUString getTableName(sal_uInt16 nFileId, size_t nCacheId) const;
     void getAllTableNames(sal_uInt16 nFileId, ::std::vector<OUString>& rTabNames) const;
     SCsTAB getTabSpan( sal_uInt16 nFileId, const OUString& rStartTabName, const OUString& rEndTabName ) const;
@@ -277,6 +277,8 @@ public:
      */
     void getAllCachedDataSpans( sal_uInt16 nFileId, sc::ColumnSpanSet& rSet ) const;
 
+    bool getSrcDocTable( const ScDocument& rSrcDoc, const OUString& rTabName, SCTAB& rTab, sal_uInt16 nFileId ) const;
+
 private:
     struct ReferencedStatus
     {
@@ -302,7 +304,8 @@ private:
 public:
 
     ScExternalRefCache::TableTypeRef getCacheTable(sal_uInt16 nFileId, size_t nTabIndex) const;
-    ScExternalRefCache::TableTypeRef getCacheTable(sal_uInt16 nFileId, const OUString& rTabName, bool bCreateNew, size_t* pnIndex);
+    ScExternalRefCache::TableTypeRef getCacheTable(sal_uInt16 nFileId, const OUString& rTabName, bool bCreateNew,
+            size_t* pnIndex, const OUString* pExtUrl);
 
     /**
      * Clear all caches including the cache tables.
@@ -346,9 +349,18 @@ private:
         /** Upper- to real-case mapping for range names. */
         NamePairMap                 maRealRangeNameMap;
 
+        /** Either the base name that was stored as sheet name for CSV files if
+            sheet name is Sheet1, or Sheet1 name if sheet name is base name.
+         */
+        OUString                    maSingleTableNameAlias;
+
         bool mbInitFromSource;
 
         DocItem() : mbInitFromSource(false) {}
+
+        TableNameIndexMap::const_iterator findTableNameIndex( const OUString& rTabName ) const;
+        bool getTableDataIndex( const OUString& rTabName, size_t& rIndex ) const;
+        bool getSingleTableNameAlternative( OUString& rTabName ) const;
     };
     typedef std::unordered_map<sal_uInt16, DocItem>  DocDataType;
     DocItem* getDocItem(sal_uInt16 nFileId) const;
@@ -460,7 +472,8 @@ public:
      * table orders are critical.</I>
      *
      * Excel filter calls this method to populate the cache table from the
-     * XCT/CRN records.
+     * XCT/CRN records. ODF import calls it for cached tables for external
+     * references.
      *
      * @param nFileId file ID
      * @param rTabName table name
@@ -469,10 +482,14 @@ public:
      *                   specified table's cache doesn't exist.
      * @param pnIndex if non-NULL pointer is passed, it stores the internal
      *                index of a cache table instance.
+     * @param pExtUrl if non-NULL and bCreateNew==true, the base name will be
+     *                propagated as an alias for the first table (and removed
+     *                later if further tables are created).
      *
      * @return shared_ptr to the cache table instance
      */
-    ScExternalRefCache::TableTypeRef getCacheTable(sal_uInt16 nFileId, const OUString& rTabName, bool bCreateNew, size_t* pnIndex = nullptr);
+    ScExternalRefCache::TableTypeRef getCacheTable(sal_uInt16 nFileId, const OUString& rTabName, bool bCreateNew,
+            size_t* pnIndex = nullptr, const OUString* pExtUrl = nullptr);
 
     /** Returns a vector containing all (real) table names and cache tables of
         the specified file.
@@ -715,6 +732,8 @@ private:
 
     void fillCellFormat(sal_uLong nFmtIndex, ScExternalRefCache::CellFormat* pFmt) const;
 
+    bool getSrcDocTable( const ScDocument& rSrcDoc, const OUString& rTabName, SCTAB& rTab, sal_uInt16 nFileId ) const;
+
     ScExternalRefCache::TokenRef getSingleRefTokenFromSrcDoc(
         sal_uInt16 nFileId, ScDocument* pSrcDoc, const ScAddress& rPos,
         ScExternalRefCache::CellFormat* pFmt);
diff --git a/sc/source/filter/xml/xmltabi.cxx b/sc/source/filter/xml/xmltabi.cxx
index e0a18c8..cd3d74d 100644
--- a/sc/source/filter/xml/xmltabi.cxx
+++ b/sc/source/filter/xml/xmltabi.cxx
@@ -203,7 +203,8 @@ ScXMLTableContext::ScXMLTableContext( ScXMLImport& rImport,
         {
             ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
             pExternalRefInfo->mnFileId = pRefMgr->getExternalFileId(aExtUrl);
-            pExternalRefInfo->mpCacheTable = pRefMgr->getCacheTable(pExternalRefInfo->mnFileId, aExtTabName, true);
+            pExternalRefInfo->mpCacheTable = pRefMgr->getCacheTable(pExternalRefInfo->mnFileId, aExtTabName, true,
+                    nullptr, &aExtUrl);
             pExternalRefInfo->mpCacheTable->setWholeTableCached();
         }
     }
diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx
index 562254d..452a03a 100644
--- a/sc/source/ui/docshell/docsh.cxx
+++ b/sc/source/ui/docshell/docsh.cxx
@@ -1201,8 +1201,19 @@ bool ScDocShell::ConvertFrom( SfxMedium& rMedium )
                     aDocument.StartAllListeners();
                     sc::SetFormulaDirtyContext aCxt;
                     aDocument.SetAllFormulasDirty(aCxt);
-                    INetURLObject aURLObjForDefaultNameSheetName(rMedium.GetName());
-                    aDocument.RenameTab(0,aURLObjForDefaultNameSheetName.GetBase());
+
+                    // The same resulting name has to be handled in
+                    // ScExternalRefCache::initializeDoc() and related, hence
+                    // pass 'true' for RenameTab()'s bExternalDocument for a
+                    // composed name so ValidTabName() will not be checked,
+                    // which could veto the rename in case it contained
+                    // characters that Excel does not handle. If we wanted to
+                    // change that then it needed to be handled in all
+                    // corresponding places of the external references
+                    // manager/cache. Likely then we'd also need a method to
+                    // compose a name excluding such characters.
+                    aDocument.RenameTab( 0, INetURLObject( rMedium.GetName()).GetBase(), true, true);
+
                     bOverflowRow = aImpEx.IsOverflowRow();
                     bOverflowCol = aImpEx.IsOverflowCol();
                     bOverflowCell = aImpEx.IsOverflowCell();
diff --git a/sc/source/ui/docshell/externalrefmgr.cxx b/sc/source/ui/docshell/externalrefmgr.cxx
index 65065ab..4b3c521 100644
--- a/sc/source/ui/docshell/externalrefmgr.cxx
+++ b/sc/source/ui/docshell/externalrefmgr.cxx
@@ -32,6 +32,7 @@
 #include "sc.hrc"
 #include "globstr.hrc"
 #include "cellvalue.hxx"
+#include "defaultsoptions.hxx"
 
 #include <osl/file.hxx>
 #include <sfx2/app.hxx>
@@ -496,8 +497,7 @@ const OUString* ScExternalRefCache::getRealTableName(sal_uInt16 nFileId, const O
     }
 
     const DocItem& rDoc = itrDoc->second;
-    TableNameIndexMap::const_iterator itrTabId = rDoc.maTableNameIndex.find(
-        ScGlobal::pCharClass->uppercase(rTabName));
+    TableNameIndexMap::const_iterator itrTabId = rDoc.findTableNameIndex( rTabName);
     if (itrTabId == rDoc.maTableNameIndex.end())
     {
         // the specified table is not in cache.
@@ -541,8 +541,7 @@ ScExternalRefCache::TokenRef ScExternalRefCache::getCellData(
     }
 
     const DocItem& rDoc = itrDoc->second;
-    TableNameIndexMap::const_iterator itrTabId = rDoc.maTableNameIndex.find(
-        ScGlobal::pCharClass->uppercase(rTabName));
+    TableNameIndexMap::const_iterator itrTabId = rDoc.findTableNameIndex( rTabName);
     if (itrTabId == rDoc.maTableNameIndex.end())
     {
         // the specified table is not in cache.
@@ -571,8 +570,7 @@ ScExternalRefCache::TokenArrayRef ScExternalRefCache::getCellRangeData(
 
     DocItem& rDoc = itrDoc->second;
 
-    TableNameIndexMap::iterator itrTabId = rDoc.maTableNameIndex.find(
-        ScGlobal::pCharClass->uppercase(rTabName));
+    TableNameIndexMap::const_iterator itrTabId = rDoc.findTableNameIndex( rTabName);
     if (itrTabId == rDoc.maTableNameIndex.end())
         // the specified table is not in cache.
         return TokenArrayRef();
@@ -802,8 +800,7 @@ void ScExternalRefCache::setCellData(sal_uInt16 nFileId, const OUString& rTabNam
     DocItem& rDoc = *pDocItem;
 
     // See if the table by this name already exists.
-    TableNameIndexMap::iterator itrTabName = rDoc.maTableNameIndex.find(
-        ScGlobal::pCharClass->uppercase(rTabName));
+    TableNameIndexMap::const_iterator itrTabName = rDoc.findTableNameIndex( rTabName);
     if (itrTabName == rDoc.maTableNameIndex.end())
         // Table not found.  Maybe the table name or the file id is wrong ???
         return;
@@ -833,8 +830,7 @@ void ScExternalRefCache::setCellRangeData(sal_uInt16 nFileId, const ScRange& rRa
 
     // Now, find the table position of the first table to cache.
     const OUString& rFirstTabName = rData.front().maTableName;
-    TableNameIndexMap::iterator itrTabName = rDoc.maTableNameIndex.find(
-        ScGlobal::pCharClass->uppercase(rFirstTabName));
+    TableNameIndexMap::const_iterator itrTabName = rDoc.findTableNameIndex( rFirstTabName);
     if (itrTabName == rDoc.maTableNameIndex.end())
     {
         // table index not found.
@@ -920,7 +916,7 @@ bool ScExternalRefCache::isDocInitialized(sal_uInt16 nFileId)
     return pDoc->mbInitFromSource;
 }
 
-static bool lcl_getTableDataIndex(const ScExternalRefCache::TableNameIndexMap& rMap, const OUString& rName, size_t& rIndex)
+static bool lcl_getStrictTableDataIndex(const ScExternalRefCache::TableNameIndexMap& rMap, const OUString& rName, size_t& rIndex)
 {
     ScExternalRefCache::TableNameIndexMap::const_iterator itr = rMap.find(rName);
     if (itr == rMap.end())
@@ -930,7 +926,29 @@ static bool lcl_getTableDataIndex(const ScExternalRefCache::TableNameIndexMap& r
     return true;
 }
 
-void ScExternalRefCache::initializeDoc(sal_uInt16 nFileId, const vector<OUString>& rTabNames)
+bool ScExternalRefCache::DocItem::getTableDataIndex( const OUString& rTabName, size_t& rIndex ) const
+{
+    ScExternalRefCache::TableNameIndexMap::const_iterator itr = findTableNameIndex(rTabName);
+    if (itr == maTableNameIndex.end())
+        return false;
+
+    rIndex = itr->second;
+    return true;
+}
+
+namespace {
+OUString getFirstSheetName()
+{
+    // Get Custom prefix.
+    const ScDefaultsOptions& rOpt = SC_MOD()->GetDefaultsOptions();
+    // Form sheet name identical to the first generated sheet name when
+    // creating an internal document, e.g. 'Sheet1'.
+    return rOpt.GetInitTabPrefix() + "1";
+}
+}
+
+void ScExternalRefCache::initializeDoc(sal_uInt16 nFileId, const vector<OUString>& rTabNames,
+        const OUString& rBaseName)
 {
     DocItem* pDoc = getDocItem(nFileId);
     if (!pDoc)
@@ -957,7 +975,7 @@ void ScExternalRefCache::initializeDoc(sal_uInt16 nFileId, const vector<OUString
     for (size_t i = 0; i < n; ++i)
     {
         size_t nIndex;
-        if (lcl_getTableDataIndex(pDoc->maTableNameIndex, pDoc->maTableNames[i].maUpperName, nIndex))
+        if (lcl_getStrictTableDataIndex(pDoc->maTableNameIndex, pDoc->maTableNames[i].maUpperName, nIndex))
         {
             aNewTables[i] = pDoc->maTables[nIndex];
         }
@@ -970,9 +988,82 @@ void ScExternalRefCache::initializeDoc(sal_uInt16 nFileId, const vector<OUString
         aNewNameIndex.insert(TableNameIndexMap::value_type(pDoc->maTableNames[i].maUpperName, i));
     pDoc->maTableNameIndex.swap(aNewNameIndex);
 
+    // Setup name for Sheet1 vs base name to be able to load documents
+    // that store the base name as table name, or vice versa.
+    pDoc->maSingleTableNameAlias.clear();
+    if (!rBaseName.isEmpty() && pDoc->maTableNames.size() == 1)
+    {
+        OUString aSheetName = getFirstSheetName();
+        // If the one and only table name matches exactly, carry on the base
+        // file name for further alias use. If instead the table name matches
+        // the base name, carry on the sheet name as alias.
+        if (ScGlobal::GetpTransliteration()->isEqual( pDoc->maTableNames[0].maRealName, aSheetName))
+            pDoc->maSingleTableNameAlias = rBaseName;
+        else if (ScGlobal::GetpTransliteration()->isEqual( pDoc->maTableNames[0].maRealName, rBaseName))
+            pDoc->maSingleTableNameAlias = aSheetName;
+    }
+
     pDoc->mbInitFromSource = true;
 }
 
+ScExternalRefCache::TableNameIndexMap::const_iterator ScExternalRefCache::DocItem::findTableNameIndex(
+        const OUString& rTabName ) const
+{
+    const OUString aTabNameUpper = ScGlobal::pCharClass->uppercase( rTabName);
+    TableNameIndexMap::const_iterator itrTabName = maTableNameIndex.find( aTabNameUpper);
+    if (itrTabName != maTableNameIndex.end())
+        return itrTabName;
+
+    // Since some time for external references to CSV files the base name is
+    // used as sheet name instead of Sheet1, check if we can resolve that.
+    // Also helps users that got accustomed to one or the other way.
+    if (maSingleTableNameAlias.isEmpty() || maTableNameIndex.size() != 1)
+        return itrTabName;
+
+    // maSingleTableNameAlias has been set up only if the original file loaded
+    // had exactly one sheet and internal sheet name was Sheet1 or localized or
+    // customized equivalent, or base name.
+    if (aTabNameUpper == ScGlobal::pCharClass->uppercase( maSingleTableNameAlias))
+        return maTableNameIndex.begin();
+
+    return itrTabName;
+}
+
+bool ScExternalRefCache::DocItem::getSingleTableNameAlternative( OUString& rTabName ) const
+{
+    if (maSingleTableNameAlias.isEmpty() || maTableNames.size() != 1)
+        return false;
+    if (ScGlobal::GetpTransliteration()->isEqual( rTabName, maTableNames[0].maRealName))
+    {
+        rTabName = maSingleTableNameAlias;
+        return true;
+    }
+    if (ScGlobal::GetpTransliteration()->isEqual( rTabName, maSingleTableNameAlias))
+    {
+        rTabName = maTableNames[0].maRealName;
+        return true;
+    }
+    return false;
+}
+
+bool ScExternalRefCache::getSrcDocTable( const ScDocument& rSrcDoc, const OUString& rTabName, SCTAB& rTab,
+        sal_uInt16 nFileId ) const
+{
+    bool bFound = rSrcDoc.GetTable( rTabName, rTab);
+    if (!bFound)
+    {
+        // Check the one table alias alternative.
+        const DocItem* pDoc = getDocItem( nFileId );
+        if (pDoc)
+        {
+            OUString aTabName( rTabName);
+            if (pDoc->getSingleTableNameAlternative( aTabName))
+                bFound = rSrcDoc.GetTable( aTabName, rTab);
+        }
+    }
+    return bFound;
+}
+
 OUString ScExternalRefCache::getTableName(sal_uInt16 nFileId, size_t nCacheId) const
 {
     if( DocItem* pDoc = getDocItem( nFileId ) )
@@ -1070,8 +1161,7 @@ bool ScExternalRefCache::setCacheTableReferenced( sal_uInt16 nFileId, const OUSt
     if (pDoc)
     {
         size_t nIndex = 0;
-        OUString aTabNameUpper = ScGlobal::pCharClass->uppercase( rTabName);
-        if (lcl_getTableDataIndex( pDoc->maTableNameIndex, aTabNameUpper, nIndex))
+        if (pDoc->getTableDataIndex( rTabName, nIndex))
         {
             size_t nStop = ::std::min( nIndex + nSheets, pDoc->maTables.size());
             for (size_t i = nIndex; i < nStop; ++i)
@@ -1266,7 +1356,8 @@ ScExternalRefCache::TableTypeRef ScExternalRefCache::getCacheTable(sal_uInt16 nF
     return pDoc->maTables[nTabIndex];
 }
 
-ScExternalRefCache::TableTypeRef ScExternalRefCache::getCacheTable(sal_uInt16 nFileId, const OUString& rTabName, bool bCreateNew, size_t* pnIndex)
+ScExternalRefCache::TableTypeRef ScExternalRefCache::getCacheTable(sal_uInt16 nFileId, const OUString& rTabName,
+        bool bCreateNew, size_t* pnIndex, const OUString* pExtUrl)
 {
     // In API, the index is transported as cached sheet ID of type sal_Int32 in
     // sheet::SingleReference.Sheet or sheet::ComplexReference.Reference1.Sheet
@@ -1284,8 +1375,7 @@ ScExternalRefCache::TableTypeRef ScExternalRefCache::getCacheTable(sal_uInt16 nF
     DocItem& rDoc = *pDoc;
 
     size_t nIndex;
-    OUString aTabNameUpper = ScGlobal::pCharClass->uppercase(rTabName);
-    if (lcl_getTableDataIndex(rDoc.maTableNameIndex, aTabNameUpper, nIndex))
+    if (rDoc.getTableDataIndex(rTabName, nIndex))
     {
         // specified table found.
         if( pnIndex ) *pnIndex = nIndex;
@@ -1301,7 +1391,27 @@ ScExternalRefCache::TableTypeRef ScExternalRefCache::getCacheTable(sal_uInt16 nF
         return TableTypeRef();
     }
 
+    // If this is the first table to be created propagate the base name or
+    // Sheet1 as an alias. For subsequent tables remove it again.
+    if (rDoc.maTableNames.empty())
+    {
+        if (pExtUrl)
+        {
+            const OUString aBaseName( INetURLObject( *pExtUrl).GetBase());
+            const OUString aSheetName( getFirstSheetName());
+            if (ScGlobal::GetpTransliteration()->isEqual( rTabName, aSheetName))
+                pDoc->maSingleTableNameAlias = aBaseName;
+            else if (ScGlobal::GetpTransliteration()->isEqual( rTabName, aBaseName))
+                pDoc->maSingleTableNameAlias = aSheetName;
+        }
+    }
+    else
+    {
+        rDoc.maSingleTableNameAlias.clear();
+    }
+
     // Specified table doesn't exist yet.  Create one.
+    OUString aTabNameUpper = ScGlobal::pCharClass->uppercase(rTabName);
     nIndex = rDoc.maTables.size();
     if( pnIndex ) *pnIndex = nIndex;
     TableTypeRef pTab(new Table);
@@ -1740,9 +1850,9 @@ ScExternalRefCache::TableTypeRef ScExternalRefManager::getCacheTable(sal_uInt16
 }
 
 ScExternalRefCache::TableTypeRef ScExternalRefManager::getCacheTable(
-    sal_uInt16 nFileId, const OUString& rTabName, bool bCreateNew, size_t* pnIndex)
+    sal_uInt16 nFileId, const OUString& rTabName, bool bCreateNew, size_t* pnIndex, const OUString* pExtUrl)
 {
-    return maRefCache.getCacheTable(nFileId, rTabName, bCreateNew, pnIndex);
+    return maRefCache.getCacheTable(nFileId, rTabName, bCreateNew, pnIndex, pExtUrl);
 }
 
 ScExternalRefManager::LinkListener::LinkListener()
@@ -1888,7 +1998,7 @@ void putRangeDataIntoCache(
         // Make sure to set this range 'cached', to prevent unnecessarily
         // accessing the src document time and time again.
         ScExternalRefCache::TableTypeRef pCacheTab =
-            rRefCache.getCacheTable(nFileId, rTabName, true, nullptr);
+            rRefCache.getCacheTable(nFileId, rTabName, true, nullptr, nullptr);
         if (pCacheTab)
             pCacheTab->setCachedCellRange(
                 rCacheRange.aStart.Col(), rCacheRange.aStart.Row(), rCacheRange.aEnd.Col(), rCacheRange.aEnd.Row());
@@ -1926,12 +2036,31 @@ void initDocInCache(ScExternalRefCache& rRefCache, const ScDocument* pSrcDoc, sa
             pSrcDoc->GetName(i, aName);
             aTabNames.push_back(aName);
         }
-        rRefCache.initializeDoc(nFileId, aTabNames);
+
+        // Obtain the base name, don't bother if there are more than one sheets.
+        OUString aBaseName;
+        if (nTabCount == 1)
+        {
+            const SfxObjectShell* pShell = pSrcDoc->GetDocumentShell();
+            if (pShell && pShell->GetMedium())
+            {
+                OUString aName = pShell->GetMedium()->GetName();
+                aBaseName = INetURLObject( aName).GetBase();
+            }
+        }
+
+        rRefCache.initializeDoc(nFileId, aTabNames, aBaseName);
     }
 }
 
 }
 
+bool ScExternalRefManager::getSrcDocTable( const ScDocument& rSrcDoc, const OUString& rTabName, SCTAB& rTab,
+        sal_uInt16 nFileId ) const
+{
+    return maRefCache.getSrcDocTable( rSrcDoc, rTabName, rTab, nFileId);
+}
+
 ScExternalRefCache::TokenRef ScExternalRefManager::getSingleRefToken(
     sal_uInt16 nFileId, const OUString& rTabName, const ScAddress& rCell,
     const ScAddress* pCurPos, SCTAB* pTab, ScExternalRefCache::CellFormat* pFmt)
@@ -1952,7 +2081,7 @@ ScExternalRefCache::TokenRef ScExternalRefManager::getSingleRefToken(
     {
         // source document already loaded in memory.  Re-use this instance.
         SCTAB nTab;
-        if (!pSrcDoc->GetTable(rTabName, nTab))
+        if (!getSrcDocTable( *pSrcDoc, rTabName, nTab, nFileId))
         {
             // specified table name doesn't exist in the source document.
             ScExternalRefCache::TokenRef pToken(new FormulaErrorToken(errNoRef));
@@ -1991,7 +2120,7 @@ ScExternalRefCache::TokenRef ScExternalRefManager::getSingleRefToken(
     }
 
     SCTAB nTab;
-    if (!pSrcDoc->GetTable(rTabName, nTab))
+    if (!getSrcDocTable( *pSrcDoc, rTabName, nTab, nFileId))
     {
         // specified table name doesn't exist in the source document.
         pToken.reset(new FormulaErrorToken(errNoRef));
@@ -2010,7 +2139,7 @@ ScExternalRefCache::TokenRef ScExternalRefManager::getSingleRefToken(
         // this data, but add it to the cached range to prevent accessing the
         // source document time and time again.
         ScExternalRefCache::TableTypeRef pCacheTab =
-            maRefCache.getCacheTable(nFileId, rTabName, true, nullptr);
+            maRefCache.getCacheTable(nFileId, rTabName, true, nullptr, nullptr);
         if (pCacheTab)
             pCacheTab->setCachedCell(rCell.Col(), rCell.Row());
 


More information about the Libreoffice-commits mailing list