summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sc/inc/externalrefmgr.hxx7
-rw-r--r--sc/inc/tokenstringcontext.hxx4
-rw-r--r--sc/qa/unit/ucalc_formula.cxx10
-rw-r--r--sc/source/core/tool/token.cxx35
-rw-r--r--sc/source/core/tool/tokenstringcontext.cxx17
-rw-r--r--sc/source/ui/docshell/externalrefmgr.cxx14
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();