summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@gmail.com>2013-01-10 12:02:07 -0500
committerKohei Yoshida <kohei.yoshida@gmail.com>2013-01-10 12:18:47 -0500
commit3d78fe6b23eb3d6552bf5ed65f3a8ead081533d1 (patch)
tree53b7066d51cf6c18383de1474f02e31b58a3889c
parent9a11737360528249437bccbb374201453f5cddfe (diff)
fdo#58531: Register cells with external references at compile time.
In the old code, we would do this during interpretation. But we need to move that to the compilation to make this work properly without full recalculation during ods import. For 4.0, we'll just add calls to insertRefCells in ScCompiler. On master we should remove these calls from the old places to avoid duplicate calls. Duplicate calls for the same external file ID - cell address pair will not hurt; it just adds more overhead. Change-Id: I25cf2e08195da17c6c8f7d19c74d744df6e1638e
-rw-r--r--sc/inc/compiler.hxx1
-rw-r--r--sc/inc/externalrefmgr.hxx4
-rw-r--r--sc/source/core/tool/compiler.cxx31
3 files changed, 34 insertions, 2 deletions
diff --git a/sc/inc/compiler.hxx b/sc/inc/compiler.hxx
index d40d26166deb..10af9016ee4f 100644
--- a/sc/inc/compiler.hxx
+++ b/sc/inc/compiler.hxx
@@ -331,6 +331,7 @@ private:
ExtendedErrorDetection meExtendedErrorDetection;
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;
bool NextNewToken(bool bInArray = false);
diff --git a/sc/inc/externalrefmgr.hxx b/sc/inc/externalrefmgr.hxx
index 3fd3ab5588eb..87693a3c8def 100644
--- a/sc/inc/externalrefmgr.hxx
+++ b/sc/inc/externalrefmgr.hxx
@@ -679,14 +679,14 @@ public:
*/
bool containsUnsavedReferences() { return !maUnsavedDocShells.empty(); }
+ void insertRefCell(sal_uInt16 nFileId, const ScAddress& rCell);
+
private:
ScExternalRefManager();
ScExternalRefManager(const ScExternalRefManager&);
void refreshAllRefCells(sal_uInt16 nFileId);
- void insertRefCell(sal_uInt16 nFileId, const ScAddress& rCell);
-
void fillCellFormat(sal_uLong nFmtIndex, ScExternalRefCache::CellFormat* pFmt) const;
ScExternalRefCache::TokenRef getSingleRefTokenFromSrcDoc(
diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx
index 6de041772e4e..7b7ab88f95bd 100644
--- a/sc/source/core/tool/compiler.cxx
+++ b/sc/source/core/tool/compiler.cxx
@@ -2717,6 +2717,7 @@ bool ScCompiler::IsDoubleReference( const String& rName )
const OUString* pRealTab = pRefMgr->getRealTableName(aExtInfo.mnFileId, aExtInfo.maTabName);
aToken.SetExternalDoubleRef(
aExtInfo.mnFileId, pRealTab ? *pRealTab : aExtInfo.maTabName, aRef);
+ maExternalFiles.push_back(aExtInfo.mnFileId);
}
else
{
@@ -2765,6 +2766,7 @@ bool ScCompiler::IsSingleReference( const String& rName )
const OUString* pRealTab = pRefMgr->getRealTableName(aExtInfo.mnFileId, aExtInfo.maTabName);
aToken.SetExternalSingleRef(
aExtInfo.mnFileId, pRealTab ? *pRealTab : aExtInfo.maTabName, aRef);
+ maExternalFiles.push_back(aExtInfo.mnFileId);
}
else
aToken.SetSingleReference(aRef);
@@ -2973,6 +2975,7 @@ bool ScCompiler::IsExternalNamedRange( const String& rSymbol )
const OUString* pRealName = pRefMgr->getRealRangeName(nFileId, aName);
aToken.SetExternalName(nFileId, pRealName ? *pRealName : OUString(aTmp));
pRawToken = aToken.Clone();
+ maExternalFiles.push_back(nFileId);
return true;
}
@@ -3736,6 +3739,24 @@ void ScCompiler::CreateStringFromXMLTokenArray( rtl::OUString& rFormula, rtl::OU
rFormulaNmsp = aFormulaNmsp;
}
+namespace {
+
+class ExternalFileInserter : std::unary_function<sal_uInt16, void>
+{
+ ScAddress maPos;
+ ScExternalRefManager& mrRefMgr;
+public:
+ ExternalFileInserter(const ScAddress& rPos, ScExternalRefManager& rRefMgr) :
+ maPos(rPos), mrRefMgr(rRefMgr) {}
+
+ void operator() (sal_uInt16 nFileId) const
+ {
+ mrRefMgr.insertRefCell(nFileId, maPos);
+ }
+};
+
+}
+
ScTokenArray* ScCompiler::CompileString( const String& rFormula )
{
OSL_ENSURE( meGrammar != FormulaGrammar::GRAM_EXTERNAL, "ScCompiler::CompileString - unexpected grammar GRAM_EXTERNAL" );
@@ -3942,6 +3963,16 @@ ScTokenArray* ScCompiler::CompileString( const String& rFormula )
// remember pArr, in case a subsequent CompileTokenArray() is executed.
ScTokenArray* pNew = new ScTokenArray( aArr );
pArr = pNew;
+
+ if (!maExternalFiles.empty())
+ {
+ // Remove duplicates, and register all external files found in this cell.
+ std::sort(maExternalFiles.begin(), maExternalFiles.end());
+ std::vector<sal_uInt16>::iterator itEnd = std::unique(maExternalFiles.begin(), maExternalFiles.end());
+ std::for_each(maExternalFiles.begin(), itEnd, ExternalFileInserter(aPos, *pDoc->GetExternalRefManager()));
+ maExternalFiles.erase(itEnd, maExternalFiles.end());
+ }
+
return pNew;
}