diff options
-rw-r--r-- | sc/inc/externalrefmgr.hxx | 7 | ||||
-rw-r--r-- | sc/inc/tokenstringcontext.hxx | 4 | ||||
-rw-r--r-- | sc/qa/unit/ucalc_formula.cxx | 10 | ||||
-rw-r--r-- | sc/source/core/tool/token.cxx | 35 | ||||
-rw-r--r-- | sc/source/core/tool/tokenstringcontext.cxx | 17 | ||||
-rw-r--r-- | sc/source/ui/docshell/externalrefmgr.cxx | 14 |
6 files changed, 86 insertions, 1 deletions
diff --git a/sc/inc/externalrefmgr.hxx b/sc/inc/externalrefmgr.hxx index c072cfd5eb2a..d5b4d7f20f2c 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 7af90eb15458..85b61f77b13d 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 7ae255472d4f..6db441caf4d5 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 fcd2aea1ecdb..f74c5eeaffdc 100644 --- a/sc/source/core/tool/token.cxx +++ b/sc/source/core/tool/token.cxx @@ -3221,7 +3221,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 e3aea0ecdd1b..a68ae759299a 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 c06490ee14a4..4646103a3190 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(); |