diff options
Diffstat (limited to 'sc')
-rw-r--r-- | sc/inc/column.hxx | 17 | ||||
-rw-r--r-- | sc/inc/compiler.hxx | 10 | ||||
-rw-r--r-- | sc/inc/formulacell.hxx | 21 | ||||
-rw-r--r-- | sc/inc/rangenam.hxx | 15 | ||||
-rw-r--r-- | sc/inc/table.hxx | 17 | ||||
-rw-r--r-- | sc/inc/tokenstringcontext.hxx | 19 | ||||
-rw-r--r-- | sc/source/core/data/column.cxx | 48 | ||||
-rw-r--r-- | sc/source/core/data/column2.cxx | 46 | ||||
-rw-r--r-- | sc/source/core/data/documen2.cxx | 4 | ||||
-rw-r--r-- | sc/source/core/data/documen4.cxx | 13 | ||||
-rw-r--r-- | sc/source/core/data/document.cxx | 16 | ||||
-rw-r--r-- | sc/source/core/data/formulacell.cxx | 172 | ||||
-rw-r--r-- | sc/source/core/data/table2.cxx | 20 | ||||
-rw-r--r-- | sc/source/core/data/table4.cxx | 20 | ||||
-rw-r--r-- | sc/source/core/tool/compiler.cxx | 36 | ||||
-rw-r--r-- | sc/source/core/tool/rangenam.cxx | 11 | ||||
-rw-r--r-- | sc/source/core/tool/tokenstringcontext.cxx | 43 |
17 files changed, 410 insertions, 118 deletions
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx index 414f40d90e5c..9eef0853c05e 100644 --- a/sc/inc/column.hxx +++ b/sc/inc/column.hxx @@ -56,6 +56,7 @@ struct RefUpdateMoveTabContext; class EditTextIterator; struct NoteEntry; class DocumentStreamAccess; +class CompileFormulaContext; } @@ -321,11 +322,11 @@ public: void SetDirtyAfterLoad(); void SetTableOpDirty( const ScRange& ); void CalcAll(); - void CalcAfterLoad(); - void CompileAll(); - void CompileXML( ScProgress& rProgress ); + void CalcAfterLoad( sc::CompileFormulaContext& rCxt ); + void CompileAll( sc::CompileFormulaContext& rCxt ); + void CompileXML( sc::CompileFormulaContext& rCxt, ScProgress& rProgress ); - bool CompileErrorCells(sal_uInt16 nErrCode); + bool CompileErrorCells( sc::CompileFormulaContext& rCxt, sal_uInt16 nErrCode ); void ResetChanged( SCROW nStartRow, SCROW nEndRow ); @@ -449,10 +450,10 @@ public: void SetDirtyIfPostponed(); void BroadcastRecalcOnRefMove(); - void CompileDBFormula(); - void CompileDBFormula( bool bCreateFormulaString ); - void CompileNameFormula( bool bCreateFormulaString ); - void CompileColRowNameFormula(); + void CompileDBFormula( sc::CompileFormulaContext& rCxt ); + void CompileDBFormula( sc::CompileFormulaContext& rCxt, bool bCreateFormulaString ); + void CompileNameFormula( sc::CompileFormulaContext& rCxt, bool bCreateFormulaString ); + void CompileColRowNameFormula( sc::CompileFormulaContext& rCxt ); sal_Int32 GetMaxStringLen( SCROW nRowStart, SCROW nRowEnd, rtl_TextEncoding eCharSet ) const; xub_StrLen GetMaxNumberStringLen( sal_uInt16& nPrecision, diff --git a/sc/inc/compiler.hxx b/sc/inc/compiler.hxx index a8757e7f8cda..78f896e4badb 100644 --- a/sc/inc/compiler.hxx +++ b/sc/inc/compiler.hxx @@ -78,6 +78,12 @@ class ScRangeData; class ScExternalRefManager; class ScTokenArray; +namespace sc { + +class CompileFormulaContext; + +} + // constants and data types internal to compiler /* @@ -362,8 +368,12 @@ private: static void InitCharClassEnglish(); public: + ScCompiler( sc::CompileFormulaContext& rCxt, const ScAddress& rPos ); + ScCompiler( ScDocument* pDocument, const ScAddress&); + ScCompiler( sc::CompileFormulaContext& rCxt, const ScAddress& rPos, ScTokenArray& rArr ); + ScCompiler( ScDocument* pDocument, const ScAddress&,ScTokenArray& rArr); virtual ~ScCompiler(); diff --git a/sc/inc/formulacell.hxx b/sc/inc/formulacell.hxx index 68c620cd67c8..e901c6e2b10e 100644 --- a/sc/inc/formulacell.hxx +++ b/sc/inc/formulacell.hxx @@ -44,6 +44,7 @@ struct RefUpdateContext; struct RefUpdateInsertTabContext; struct RefUpdateDeleteTabContext; struct RefUpdateMoveTabContext; +class CompileFormulaContext; } @@ -205,6 +206,8 @@ public: void GetFormula( OUStringBuffer& rBuffer, const formula::FormulaGrammar::Grammar = formula::FormulaGrammar::GRAM_DEFAULT ) const; + OUString GetFormula( sc::CompileFormulaContext& rCxt ) const; + void SetDirty( bool bDirtyFlag=true ); void SetDirtyVar(); // If setting entire document dirty after load, no broadcasts but still append to FormulaTree. @@ -221,9 +224,13 @@ public: void Compile(const OUString& rFormula, bool bNoListening = false, const formula::FormulaGrammar::Grammar = formula::FormulaGrammar::GRAM_DEFAULT ); - void CompileTokenArray( bool bNoListening = false ); - void CompileXML( ScProgress& rProgress ); // compile temporary string tokens - void CalcAfterLoad(); + void Compile( + sc::CompileFormulaContext& rCxt, const OUString& rFormula, bool bNoListening = false ); + + void CompileTokenArray( bool bNoListening = false ); + void CompileTokenArray( sc::CompileFormulaContext& rCxt, bool bNoListening = false ); + void CompileXML( sc::CompileFormulaContext& rCxt, ScProgress& rProgress ); // compile temporary string tokens + void CalcAfterLoad( sc::CompileFormulaContext& rCxt ); bool MarkUsedExternalReferences(); void Interpret(); bool IsIterCell() const; @@ -285,10 +292,10 @@ public: bool IsRunning() const; void SetRunning( bool bVal ); - void CompileDBFormula(); - void CompileDBFormula( bool bCreateFormulaString ); - void CompileNameFormula( bool bCreateFormulaString ); - void CompileColRowNameFormula(); + void CompileDBFormula( sc::CompileFormulaContext& rCxt ); + void CompileDBFormula( sc::CompileFormulaContext& rCxt, bool bCreateFormulaString ); + void CompileNameFormula( sc::CompileFormulaContext& rCxt, bool bCreateFormulaString ); + void CompileColRowNameFormula( sc::CompileFormulaContext& rCxt ); ScFormulaCell* GetPrevious() const; ScFormulaCell* GetNext() const; void SetPrevious( ScFormulaCell* pF ); diff --git a/sc/inc/rangenam.hxx b/sc/inc/rangenam.hxx index 6113709b118b..5d4aebea1b4f 100644 --- a/sc/inc/rangenam.hxx +++ b/sc/inc/rangenam.hxx @@ -35,10 +35,13 @@ class ScDocument; class ScTokenArray; namespace sc { - struct RefUpdateContext; - struct RefUpdateInsertTabContext; - struct RefUpdateDeleteTabContext; - struct RefUpdateMoveTabContext; + +struct RefUpdateContext; +struct RefUpdateInsertTabContext; +struct RefUpdateDeleteTabContext; +struct RefUpdateMoveTabContext; +class CompileFormulaContext; + } typedef sal_uInt16 RangeType; @@ -151,7 +154,7 @@ public: SCROW GetMaxRow() const; SCCOL GetMaxCol() const; - void CompileUnresolvedXML(); + void CompileUnresolvedXML( sc::CompileFormulaContext& rCxt ); #if DEBUG_FORMULA_COMPILER void Dump() const; @@ -201,7 +204,7 @@ public: /** Compile those names that couldn't be resolved during loading and inserting because they may have referred a name that was inserted later. */ - void CompileUnresolvedXML(); + void CompileUnresolvedXML( sc::CompileFormulaContext& rCxt ); SC_DLLPUBLIC const_iterator begin() const; SC_DLLPUBLIC const_iterator end() const; diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx index f067658e1b0a..3049698492c9 100644 --- a/sc/inc/table.hxx +++ b/sc/inc/table.hxx @@ -68,6 +68,7 @@ struct RefUpdateDeleteTabContext; struct RefUpdateMoveTabContext; struct NoteEntry; class DocumentStreamAccess; +class CompileFormulaContext; } @@ -509,11 +510,11 @@ public: void SetDirtyVar(); void SetTableOpDirty( const ScRange& ); void CalcAll(); - void CalcAfterLoad(); - void CompileAll(); - void CompileXML( ScProgress& rProgress ); + void CalcAfterLoad( sc::CompileFormulaContext& rCxt ); + void CompileAll( sc::CompileFormulaContext& rCxt ); + void CompileXML( sc::CompileFormulaContext& rCxt, ScProgress& rProgress ); - bool CompileErrorCells(sal_uInt16 nErrCode); + bool CompileErrorCells( sc::CompileFormulaContext& rCxt, sal_uInt16 nErrCode ); void UpdateReference( sc::RefUpdateContext& rCxt, ScDocument* pUndoDoc = NULL, @@ -986,10 +987,10 @@ private: const ScMarkData& rMark) const; bool GetNextMarkedCell( SCCOL& rCol, SCROW& rRow, const ScMarkData& rMark ) const; bool TestTabRefAbs(SCTAB nTable) const; - void CompileDBFormula(); - void CompileDBFormula( bool bCreateFormulaString ); - void CompileNameFormula( bool bCreateFormulaString ); - void CompileColRowNameFormula(); + void CompileDBFormula( sc::CompileFormulaContext& rCxt ); + void CompileDBFormula( sc::CompileFormulaContext& rCxt, bool bCreateFormulaString ); + void CompileNameFormula( sc::CompileFormulaContext& rCxt, bool bCreateFormulaString ); + void CompileColRowNameFormula( sc::CompileFormulaContext& rCxt ); void RebuildFormulaGroups(); void StartListening( const ScAddress& rAddress, SvtListener* pListener ); diff --git a/sc/inc/tokenstringcontext.hxx b/sc/inc/tokenstringcontext.hxx index 85b61f77b13d..3740f60146bf 100644 --- a/sc/inc/tokenstringcontext.hxx +++ b/sc/inc/tokenstringcontext.hxx @@ -46,6 +46,25 @@ struct SC_DLLPUBLIC TokenStringContext TokenStringContext( const ScDocument* pDoc, formula::FormulaGrammar::Grammar eGram ); }; +class CompileFormulaContext +{ + ScDocument* mpDoc; + formula::FormulaGrammar::Grammar meGram; + std::vector<OUString> maTabNames; + + void updateTabNames(); + +public: + CompileFormulaContext( ScDocument* pDoc ); + + formula::FormulaGrammar::Grammar getGrammar() const; + void setGrammar( formula::FormulaGrammar::Grammar eGram ); + + const std::vector<OUString>& getTabNames() const; + + ScDocument* getDoc(); +}; + } #endif diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx index 7771f0e065f8..0b1032873786 100644 --- a/sc/source/core/data/column.cxx +++ b/sc/source/core/data/column.cxx @@ -2836,24 +2836,30 @@ struct CalcAllHandler } }; -struct CompileAllHandler +class CompileAllHandler { + sc::CompileFormulaContext& mrCxt; +public: + CompileAllHandler( sc::CompileFormulaContext& rCxt ) : mrCxt(rCxt) {} + void operator() (size_t /*nRow*/, ScFormulaCell* pCell) { // for unconditional compilation // bCompile=true and pCode->nError=0 pCell->GetCode()->SetCodeError(0); pCell->SetCompile(true); - pCell->CompileTokenArray(); + pCell->CompileTokenArray(mrCxt); } }; class CompileXMLHandler { + sc::CompileFormulaContext& mrCxt; ScProgress& mrProgress; const ScColumn& mrCol; public: - CompileXMLHandler(ScProgress& rProgress, const ScColumn& rCol) : + CompileXMLHandler( sc::CompileFormulaContext& rCxt, ScProgress& rProgress, const ScColumn& rCol) : + mrCxt(rCxt), mrProgress(rProgress), mrCol(rCol) {} @@ -2865,23 +2871,24 @@ public: else pCell->SetDirtyVar(); - pCell->CompileXML(mrProgress); + pCell->CompileXML(mrCxt, mrProgress); } }; class CompileErrorCellsHandler { + sc::CompileFormulaContext& mrCxt; ScColumn& mrColumn; sc::CellStoreType::iterator miPos; sal_uInt16 mnErrCode; FormulaGrammar::Grammar meGram; bool mbCompiled; public: - CompileErrorCellsHandler(ScColumn& rColumn, sal_uInt16 nErrCode, FormulaGrammar::Grammar eGram) : + CompileErrorCellsHandler( sc::CompileFormulaContext& rCxt, ScColumn& rColumn, sal_uInt16 nErrCode ) : + mrCxt(rCxt), mrColumn(rColumn), miPos(mrColumn.GetCellStore().begin()), mnErrCode(nErrCode), - meGram(eGram), mbCompiled(false) { } @@ -2901,9 +2908,8 @@ public: miPos = aPos.first; sc::SharedFormulaUtil::unshareFormulaCell(aPos, *pCell); pCell->GetCode()->SetCodeError(0); - OUStringBuffer aBuf; - pCell->GetFormula(aBuf, meGram); - pCell->Compile(aBuf.makeStringAndClear(), false, meGram); + OUString aFormula = pCell->GetFormula(mrCxt); + pCell->Compile(mrCxt, aFormula, false); mrColumn.JoinNewFormulaCell(aPos, *pCell); mbCompiled = true; @@ -2912,11 +2918,15 @@ public: bool isCompiled() const { return mbCompiled; } }; -struct CalcAfterLoadHandler +class CalcAfterLoadHandler { + sc::CompileFormulaContext& mrCxt; +public: + CalcAfterLoadHandler( sc::CompileFormulaContext& rCxt ) : mrCxt(rCxt) {} + void operator() (size_t /*nRow*/, ScFormulaCell* pCell) { - pCell->CalcAfterLoad(); + pCell->CalcAfterLoad(mrCxt); } }; @@ -3165,29 +3175,29 @@ void ScColumn::CalcAll() sc::ProcessFormula(maCells, aFunc); } -void ScColumn::CompileAll() +void ScColumn::CompileAll( sc::CompileFormulaContext& rCxt ) { - CompileAllHandler aFunc; + CompileAllHandler aFunc(rCxt); sc::ProcessFormula(maCells, aFunc); } -void ScColumn::CompileXML( ScProgress& rProgress ) +void ScColumn::CompileXML( sc::CompileFormulaContext& rCxt, ScProgress& rProgress ) { - CompileXMLHandler aFunc(rProgress, *this); + CompileXMLHandler aFunc(rCxt, rProgress, *this); sc::ProcessFormula(maCells, aFunc); RegroupFormulaCells(); } -bool ScColumn::CompileErrorCells(sal_uInt16 nErrCode) +bool ScColumn::CompileErrorCells( sc::CompileFormulaContext& rCxt, sal_uInt16 nErrCode ) { - CompileErrorCellsHandler aHdl(*this, nErrCode, pDocument->GetGrammar()); + CompileErrorCellsHandler aHdl(rCxt, *this, nErrCode); sc::ProcessFormula(maCells, aHdl); return aHdl.isCompiled(); } -void ScColumn::CalcAfterLoad() +void ScColumn::CalcAfterLoad( sc::CompileFormulaContext& rCxt ) { - CalcAfterLoadHandler aFunc; + CalcAfterLoadHandler aFunc(rCxt); sc::ProcessFormula(maCells, aFunc); } diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx index 6aef111d9b6a..04f127fba81e 100644 --- a/sc/source/core/data/column2.cxx +++ b/sc/source/core/data/column2.cxx @@ -3181,75 +3181,87 @@ void ScColumn::EndListening( sc::EndListeningContext& rCxt, SCROW nRow, SvtListe namespace { -struct CompileDBFormulaHandler +class CompileDBFormulaHandler { + sc::CompileFormulaContext& mrCxt; + +public: + CompileDBFormulaHandler( sc::CompileFormulaContext& rCxt ) : + mrCxt(rCxt) {} + void operator() (size_t, ScFormulaCell* p) { - p->CompileDBFormula(); + p->CompileDBFormula(mrCxt); } }; class CompileDBFormula2Handler { + sc::CompileFormulaContext& mrCxt; bool mbCreateFormulaString; public: - CompileDBFormula2Handler(bool bCreateFormulaString) : - mbCreateFormulaString(bCreateFormulaString) {} + CompileDBFormula2Handler( sc::CompileFormulaContext& rCxt, bool bCreateFormulaString ) : + mrCxt(rCxt), mbCreateFormulaString(bCreateFormulaString) {} void operator() (size_t, ScFormulaCell* p) { - p->CompileDBFormula(mbCreateFormulaString); + p->CompileDBFormula(mrCxt, mbCreateFormulaString); } }; class CompileNameFormulaHandler { + sc::CompileFormulaContext& mrCxt; bool mbCreateFormulaString; public: - CompileNameFormulaHandler(bool bCreateFormulaString) : - mbCreateFormulaString(bCreateFormulaString) {} + CompileNameFormulaHandler( sc::CompileFormulaContext& rCxt, bool bCreateFormulaString) : + mrCxt(rCxt), mbCreateFormulaString(bCreateFormulaString) {} void operator() (size_t, ScFormulaCell* p) { - p->CompileNameFormula(mbCreateFormulaString); + p->CompileNameFormula(mrCxt, mbCreateFormulaString); } }; struct CompileColRowNameFormulaHandler { + sc::CompileFormulaContext& mrCxt; +public: + CompileColRowNameFormulaHandler( sc::CompileFormulaContext& rCxt ) : mrCxt(rCxt) {} + void operator() (size_t, ScFormulaCell* p) { - p->CompileColRowNameFormula(); + p->CompileColRowNameFormula(mrCxt); } }; } -void ScColumn::CompileDBFormula() +void ScColumn::CompileDBFormula( sc::CompileFormulaContext& rCxt ) { - CompileDBFormulaHandler aFunc; + CompileDBFormulaHandler aFunc(rCxt); sc::ProcessFormula(maCells, aFunc); RegroupFormulaCells(); } -void ScColumn::CompileDBFormula( bool bCreateFormulaString ) +void ScColumn::CompileDBFormula( sc::CompileFormulaContext& rCxt, bool bCreateFormulaString ) { - CompileDBFormula2Handler aFunc(bCreateFormulaString); + CompileDBFormula2Handler aFunc(rCxt, bCreateFormulaString); sc::ProcessFormula(maCells, aFunc); RegroupFormulaCells(); } -void ScColumn::CompileNameFormula( bool bCreateFormulaString ) +void ScColumn::CompileNameFormula( sc::CompileFormulaContext& rCxt, bool bCreateFormulaString ) { - CompileNameFormulaHandler aFunc(bCreateFormulaString); + CompileNameFormulaHandler aFunc(rCxt, bCreateFormulaString); sc::ProcessFormula(maCells, aFunc); } -void ScColumn::CompileColRowNameFormula() +void ScColumn::CompileColRowNameFormula( sc::CompileFormulaContext& rCxt ) { - CompileColRowNameFormulaHandler aFunc; + CompileColRowNameFormulaHandler aFunc(rCxt); sc::ProcessFormula(maCells, aFunc); RegroupFormulaCells(); } diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx index ae9cbd9dbcc6..d027bb49f9d2 100644 --- a/sc/source/core/data/documen2.cxx +++ b/sc/source/core/data/documen2.cxx @@ -93,6 +93,7 @@ #include "scopetools.hxx" #include "formulagroup.hxx" #include "documentlinkmgr.hxx" +#include <tokenstringcontext.hxx> using namespace com::sun::star; @@ -1018,7 +1019,8 @@ sal_uLong ScDocument::TransferTab( ScDocument* pSrcDoc, SCTAB nSrcPos, // Readjust self-contained absolute references to this sheet maTabs[nDestPos]->TestTabRefAbs(nSrcPos); - maTabs[nDestPos]->CompileAll(); + sc::CompileFormulaContext aFormulaCxt(this); + maTabs[nDestPos]->CompileAll(aFormulaCxt); } SetNoListening( false ); diff --git a/sc/source/core/data/documen4.cxx b/sc/source/core/data/documen4.cxx index ed496961c38b..fb4538581c73 100644 --- a/sc/source/core/data/documen4.cxx +++ b/sc/source/core/data/documen4.cxx @@ -44,6 +44,7 @@ #include "formulacell.hxx" #include "tokenarray.hxx" #include "scmatrix.hxx" +#include <tokenstringcontext.hxx> using namespace formula; @@ -538,41 +539,45 @@ bool ScDocument::ReplaceStyle(const SvxSearchItem& rSearchItem, void ScDocument::CompileDBFormula() { + sc::CompileFormulaContext aCxt(this); TableContainer::iterator it = maTabs.begin(); for (;it != maTabs.end(); ++it) { if (*it) - (*it)->CompileDBFormula(); + (*it)->CompileDBFormula(aCxt); } } void ScDocument::CompileDBFormula( bool bCreateFormulaString ) { + sc::CompileFormulaContext aCxt(this); TableContainer::iterator it = maTabs.begin(); for (;it != maTabs.end(); ++it) { if (*it) - (*it)->CompileDBFormula( bCreateFormulaString ); + (*it)->CompileDBFormula(aCxt, bCreateFormulaString); } } void ScDocument::CompileNameFormula( bool bCreateFormulaString ) { + sc::CompileFormulaContext aCxt(this); TableContainer::iterator it = maTabs.begin(); for (;it != maTabs.end(); ++it) { if (*it) - (*it)->CompileNameFormula( bCreateFormulaString ); + (*it)->CompileNameFormula(aCxt, bCreateFormulaString); } } void ScDocument::CompileColRowNameFormula() { + sc::CompileFormulaContext aCxt(this); TableContainer::iterator it = maTabs.begin(); for (;it != maTabs.end(); ++it) { if (*it) - (*it)->CompileColRowNameFormula(); + (*it)->CompileColRowNameFormula(aCxt); } } diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx index 6bbe8358b4bc..99192e485181 100644 --- a/sc/source/core/data/document.cxx +++ b/sc/source/core/data/document.cxx @@ -95,6 +95,7 @@ #include "scopetools.hxx" #include "refupdatecontext.hxx" #include "formulagroup.hxx" +#include <tokenstringcontext.hxx> #include "formula/vectortoken.hxx" @@ -3644,10 +3645,11 @@ void ScDocument::CalcAll() void ScDocument::CompileAll() { + sc::CompileFormulaContext aCxt(this); TableContainer::iterator it = maTabs.begin(); for (; it != maTabs.end(); ++it) if (*it) - (*it)->CompileAll(); + (*it)->CompileAll(aCxt); SetDirty(); } @@ -3659,17 +3661,19 @@ void ScDocument::CompileXML() ScProgress aProgress( GetDocumentShell(), ScGlobal::GetRscString( STR_PROGRESS_CALCULATING ), GetXMLImportedFormulaCount() ); + sc::CompileFormulaContext aCxt(this); + // set AutoNameCache to speed up automatic name lookup OSL_ENSURE( !pAutoNameCache, "AutoNameCache already set" ); pAutoNameCache = new ScAutoNameCache( this ); if (pRangeName) - pRangeName->CompileUnresolvedXML(); + pRangeName->CompileUnresolvedXML(aCxt); TableContainer::iterator it = maTabs.begin(); for (; it != maTabs.end(); ++it) if (*it) - (*it)->CompileXML( aProgress ); + (*it)->CompileXML(aCxt, aProgress); DELETEZ( pAutoNameCache ); // valid only during CompileXML, where cell contents don't change @@ -3682,6 +3686,7 @@ void ScDocument::CompileXML() bool ScDocument::CompileErrorCells(sal_uInt16 nErrCode) { bool bCompiled = false; + sc::CompileFormulaContext aCxt(this); TableContainer::iterator it = maTabs.begin(), itEnd = maTabs.end(); for (; it != itEnd; ++it) { @@ -3689,7 +3694,7 @@ bool ScDocument::CompileErrorCells(sal_uInt16 nErrCode) if (!pTab) continue; - if (pTab->CompileErrorCells(nErrCode)) + if (pTab->CompileErrorCells(aCxt, nErrCode)) bCompiled = true; } @@ -3702,11 +3707,12 @@ void ScDocument::CalcAfterLoad() return; // dann wird erst beim Einfuegen in das richtige Doc berechnet bCalcingAfterLoad = true; + sc::CompileFormulaContext aCxt(this); { TableContainer::iterator it = maTabs.begin(); for (; it != maTabs.end(); ++it) if (*it) - (*it)->CalcAfterLoad(); + (*it)->CalcAfterLoad(aCxt); for (it = maTabs.begin(); it != maTabs.end(); ++it) if (*it) (*it)->SetDirtyAfterLoad(); diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx index cad21446ad05..7d1dff1d58ec 100644 --- a/sc/source/core/data/formulacell.cxx +++ b/sc/source/core/data/formulacell.cxx @@ -50,6 +50,7 @@ #include "types.hxx" #include "scopetools.hxx" #include "refupdatecontext.hxx" +#include <tokenstringcontext.hxx> #include <boost/scoped_ptr.hpp> @@ -882,6 +883,62 @@ void ScFormulaCell::GetFormula( OUString& rFormula, const FormulaGrammar::Gramma rFormula = rBuffer.makeStringAndClear(); } +OUString ScFormulaCell::GetFormula( sc::CompileFormulaContext& rCxt ) const +{ + OUStringBuffer aBuf; + if (pCode->GetCodeError() && !pCode->GetLen()) + { + aBuf = OUStringBuffer( ScGlobal::GetErrorString( pCode->GetCodeError())); + return aBuf.makeStringAndClear(); + } + else if( cMatrixFlag == MM_REFERENCE ) + { + // Reference to another cell that contains a matrix formula. + pCode->Reset(); + ScToken* p = static_cast<ScToken*>(pCode->GetNextReferenceRPN()); + if( p ) + { + /* FIXME: original GetFormula() code obtained + * pCell only if (!this->IsInChangeTrack()), + * GetEnglishFormula() omitted that test. + * Can we live without in all cases? */ + ScFormulaCell* pCell = NULL; + ScSingleRefData& rRef = p->GetSingleRef(); + ScAddress aAbs = rRef.toAbs(aPos); + if (ValidAddress(aAbs)) + pCell = pDocument->GetFormulaCell(aAbs); + + if (pCell) + { + return pCell->GetFormula(rCxt); + } + else + { + ScCompiler aComp(rCxt, aPos, *pCode); + aComp.CreateStringFromTokenArray(aBuf); + } + } + else + { + OSL_FAIL("ScFormulaCell::GetFormula: not a matrix"); + } + } + else + { + ScCompiler aComp(rCxt, aPos, *pCode); + aComp.CreateStringFromTokenArray(aBuf); + } + + aBuf.insert( 0, '='); + if( cMatrixFlag ) + { + aBuf.insert( 0, '{'); + aBuf.append( '}'); + } + + return aBuf.makeStringAndClear(); +} + void ScFormulaCell::GetResultDimensions( SCSIZE& rCols, SCSIZE& rRows ) { MaybeInterpret(); @@ -940,6 +997,40 @@ void ScFormulaCell::Compile( const OUString& rFormula, bool bNoListening, pDocument->PutInFormulaTree( this ); } +void ScFormulaCell::Compile( + sc::CompileFormulaContext& rCxt, const OUString& rFormula, bool bNoListening ) +{ + if ( pDocument->IsClipOrUndo() ) + return; + bool bWasInFormulaTree = pDocument->IsInFormulaTree( this ); + if ( bWasInFormulaTree ) + pDocument->RemoveFromFormulaTree( this ); + // pCode may not deleted for queries, but must be empty + if ( pCode ) + pCode->Clear(); + ScTokenArray* pCodeOld = pCode; + ScCompiler aComp(rCxt, aPos); + pCode = aComp.CompileString( rFormula ); + if ( pCodeOld ) + delete pCodeOld; + if( !pCode->GetCodeError() ) + { + if ( !pCode->GetLen() && !aResult.GetHybridFormula().isEmpty() && rFormula == aResult.GetHybridFormula() ) + { // not recursive CompileTokenArray/Compile/CompileTokenArray + if ( rFormula[0] == '=' ) + pCode->AddBad( rFormula.copy(1) ); + else + pCode->AddBad( rFormula ); + } + bCompile = true; + CompileTokenArray(rCxt, bNoListening); + } + else + bChanged = true; + + if ( bWasInFormulaTree ) + pDocument->PutInFormulaTree( this ); +} void ScFormulaCell::CompileTokenArray( bool bNoListening ) { @@ -981,8 +1072,47 @@ void ScFormulaCell::CompileTokenArray( bool bNoListening ) } } +void ScFormulaCell::CompileTokenArray( sc::CompileFormulaContext& rCxt, bool bNoListening ) +{ + // Not already compiled? + if( !pCode->GetLen() && !aResult.GetHybridFormula().isEmpty() ) + { + rCxt.setGrammar(eTempGrammar); + Compile(rCxt, aResult.GetHybridFormula(), bNoListening); + } + else if( bCompile && !pDocument->IsClipOrUndo() && !pCode->GetCodeError() ) + { + // RPN length may get changed + bool bWasInFormulaTree = pDocument->IsInFormulaTree( this ); + if ( bWasInFormulaTree ) + pDocument->RemoveFromFormulaTree( this ); + + // Loading from within filter? No listening yet! + if( pDocument->IsInsertingFromOtherDoc() ) + bNoListening = true; -void ScFormulaCell::CompileXML( ScProgress& rProgress ) + if( !bNoListening && pCode->GetCodeLen() ) + EndListeningTo( pDocument ); + ScCompiler aComp(rCxt, aPos, *pCode); + bSubTotal = aComp.CompileTokenArray(); + if( !pCode->GetCodeError() ) + { + nFormatType = aComp.GetNumFormatType(); + bChanged = true; + aResult.SetToken( NULL); + bCompile = false; + if ( !bNoListening ) + StartListeningTo( pDocument ); + } + if ( bWasInFormulaTree ) + pDocument->PutInFormulaTree( this ); + + if (bSubTotal) + pDocument->AddSubTotalCell(this); + } +} + +void ScFormulaCell::CompileXML( sc::CompileFormulaContext& rCxt, ScProgress& rProgress ) { if ( cMatrixFlag == MM_REFERENCE ) { // is already token code via ScDocFunc::EnterMatrix, ScDocument::InsertMatrixFormula @@ -996,8 +1126,8 @@ void ScFormulaCell::CompileXML( ScProgress& rProgress ) bool bWasInFormulaTree = pDocument->IsInFormulaTree( this); if (bWasInFormulaTree) pDocument->RemoveFromFormulaTree( this); - ScCompiler aComp( pDocument, aPos, *pCode); - aComp.SetGrammar(eTempGrammar); + rCxt.setGrammar(eTempGrammar); + ScCompiler aComp(rCxt, aPos, *pCode); OUString aFormula, aFormulaNmsp; aComp.CreateStringFromXMLTokenArray( aFormula, aFormulaNmsp ); pDocument->DecXMLImportedFormulaCount( aFormula.getLength() ); @@ -1051,13 +1181,14 @@ void ScFormulaCell::CompileXML( ScProgress& rProgress ) } -void ScFormulaCell::CalcAfterLoad() +void ScFormulaCell::CalcAfterLoad( sc::CompileFormulaContext& rCxt ) { bool bNewCompiled = false; // If a Calc 1.0-doc is read, we have a result, but no token array if( !pCode->GetLen() && !aResult.GetHybridFormula().isEmpty() ) { - Compile( aResult.GetHybridFormula(), true, eTempGrammar); + rCxt.setGrammar(eTempGrammar); + Compile(rCxt, aResult.GetHybridFormula(), true); aResult.SetToken( NULL); bDirty = true; bNewCompiled = true; @@ -1065,8 +1196,7 @@ void ScFormulaCell::CalcAfterLoad() // The RPN array is not created when a Calc 3.0-Doc has been read as the Range Names exist until now. if( pCode->GetLen() && !pCode->GetCodeLen() && !pCode->GetCodeError() ) { - ScCompiler aComp(pDocument, aPos, *pCode); - aComp.SetGrammar(pDocument->GetGrammar()); + ScCompiler aComp(rCxt, aPos, *pCode); bSubTotal = aComp.CompileTokenArray(); nFormatType = aComp.GetNumFormatType(); bDirty = true; @@ -3213,7 +3343,7 @@ void ScFormulaCell::SetRunning( bool bVal ) bRunning = bVal; } -void ScFormulaCell::CompileDBFormula() +void ScFormulaCell::CompileDBFormula( sc::CompileFormulaContext& rCxt ) { for( FormulaToken* p = pCode->First(); p; p = pCode->Next() ) { @@ -3221,14 +3351,14 @@ void ScFormulaCell::CompileDBFormula() || (p->GetOpCode() == ocName && p->GetIndex() >= SC_START_INDEX_DB_COLL) ) { bCompile = true; - CompileTokenArray(); + CompileTokenArray(rCxt); SetDirty(); break; } } } -void ScFormulaCell::CompileDBFormula( bool bCreateFormulaString ) +void ScFormulaCell::CompileDBFormula( sc::CompileFormulaContext& rCxt, bool bCreateFormulaString ) { // Two phases must be called after each other // 1. Formula String with old generated names @@ -3256,8 +3386,7 @@ void ScFormulaCell::CompileDBFormula( bool bCreateFormulaString ) } if ( bRecompile ) { - OUString aFormula; - GetFormula( aFormula, formula::FormulaGrammar::GRAM_NATIVE); + OUString aFormula = GetFormula(rCxt); if ( GetMatrixFlag() != MM_NONE && !aFormula.isEmpty() ) { if ( aFormula[ aFormula.getLength()-1 ] == '}' ) @@ -3268,18 +3397,19 @@ void ScFormulaCell::CompileDBFormula( bool bCreateFormulaString ) EndListeningTo( pDocument ); pDocument->RemoveFromFormulaTree( this ); pCode->Clear(); - SetHybridFormula( aFormula, formula::FormulaGrammar::GRAM_NATIVE); + SetHybridFormula(aFormula, rCxt.getGrammar()); } } else if ( !pCode->GetLen() && !aResult.GetHybridFormula().isEmpty() ) { - Compile( aResult.GetHybridFormula(), false, eTempGrammar ); + rCxt.setGrammar(eTempGrammar); + Compile(rCxt, aResult.GetHybridFormula(), false); aResult.SetToken( NULL); SetDirty(); } } -void ScFormulaCell::CompileNameFormula( bool bCreateFormulaString ) +void ScFormulaCell::CompileNameFormula( sc::CompileFormulaContext& rCxt, bool bCreateFormulaString ) { // Two phases must be called after each other // 1. Formula String with old generated names @@ -3303,8 +3433,7 @@ void ScFormulaCell::CompileNameFormula( bool bCreateFormulaString ) } if ( bRecompile ) { - OUString aFormula; - GetFormula( aFormula, formula::FormulaGrammar::GRAM_NATIVE); + OUString aFormula = GetFormula(rCxt); if ( GetMatrixFlag() != MM_NONE && !aFormula.isEmpty() ) { if ( aFormula[ aFormula.getLength()-1 ] == '}' ) @@ -3315,18 +3444,19 @@ void ScFormulaCell::CompileNameFormula( bool bCreateFormulaString ) EndListeningTo( pDocument ); pDocument->RemoveFromFormulaTree( this ); pCode->Clear(); - SetHybridFormula( aFormula, formula::FormulaGrammar::GRAM_NATIVE); + SetHybridFormula(aFormula, rCxt.getGrammar()); } } else if ( !pCode->GetLen() && !aResult.GetHybridFormula().isEmpty() ) { - Compile( aResult.GetHybridFormula(), false, eTempGrammar ); + rCxt.setGrammar(eTempGrammar); + Compile(rCxt, aResult.GetHybridFormula(), false); aResult.SetToken( NULL); SetDirty(); } } -void ScFormulaCell::CompileColRowNameFormula() +void ScFormulaCell::CompileColRowNameFormula( sc::CompileFormulaContext& rCxt ) { pCode->Reset(); for ( FormulaToken* p = pCode->First(); p; p = pCode->Next() ) @@ -3334,7 +3464,7 @@ void ScFormulaCell::CompileColRowNameFormula() if ( p->GetOpCode() == ocColRowName ) { bCompile = true; - CompileTokenArray(); + CompileTokenArray(rCxt); SetDirty(); break; } diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx index e81a5e218811..ce0909d0aeb2 100644 --- a/sc/source/core/data/table2.cxx +++ b/sc/source/core/data/table2.cxx @@ -1704,44 +1704,46 @@ void ScTable::CalcAll() } -void ScTable::CompileAll() +void ScTable::CompileAll( sc::CompileFormulaContext& rCxt ) { - for (SCCOL i=0; i <= MAXCOL; i++) aCol[i].CompileAll(); + for (SCCOL i = 0; i <= MAXCOL; ++i) + aCol[i].CompileAll(rCxt); if(mpCondFormatList) mpCondFormatList->CompileAll(); } -void ScTable::CompileXML( ScProgress& rProgress ) +void ScTable::CompileXML( sc::CompileFormulaContext& rCxt, ScProgress& rProgress ) { if (mpRangeName) - mpRangeName->CompileUnresolvedXML(); + mpRangeName->CompileUnresolvedXML(rCxt); for (SCCOL i=0; i <= MAXCOL; i++) { - aCol[i].CompileXML( rProgress ); + aCol[i].CompileXML(rCxt, rProgress); } if(mpCondFormatList) mpCondFormatList->CompileXML(); } -bool ScTable::CompileErrorCells(sal_uInt16 nErrCode) +bool ScTable::CompileErrorCells( sc::CompileFormulaContext& rCxt, sal_uInt16 nErrCode ) { bool bCompiled = false; for (SCCOL i = 0; i <= MAXCOL; ++i) { - if (aCol[i].CompileErrorCells(nErrCode)) + if (aCol[i].CompileErrorCells(rCxt, nErrCode)) bCompiled = true; } return bCompiled; } -void ScTable::CalcAfterLoad() +void ScTable::CalcAfterLoad( sc::CompileFormulaContext& rCxt ) { - for (SCCOL i=0; i <= MAXCOL; i++) aCol[i].CalcAfterLoad(); + for (SCCOL i = 0; i <= MAXCOL; ++i) + aCol[i].CalcAfterLoad(rCxt); } bool ScTable::IsEmptyData( SCCOL nCol ) const diff --git a/sc/source/core/data/table4.cxx b/sc/source/core/data/table4.cxx index b7112bbc661b..9a50176a890d 100644 --- a/sc/source/core/data/table4.cxx +++ b/sc/source/core/data/table4.cxx @@ -2056,24 +2056,28 @@ bool ScTable::TestTabRefAbs(SCTAB nTable) const return false; } -void ScTable::CompileDBFormula() +void ScTable::CompileDBFormula( sc::CompileFormulaContext& rCxt ) { - for (SCCOL i=0; i<=MAXCOL; i++) aCol[i].CompileDBFormula(); + for (SCCOL i = 0; i <= MAXCOL; ++i) + aCol[i].CompileDBFormula(rCxt); } -void ScTable::CompileDBFormula( bool bCreateFormulaString ) +void ScTable::CompileDBFormula( sc::CompileFormulaContext& rCxt, bool bCreateFormulaString ) { - for (SCCOL i=0; i<=MAXCOL; i++) aCol[i].CompileDBFormula( bCreateFormulaString ); + for (SCCOL i = 0; i <= MAXCOL; ++i) + aCol[i].CompileDBFormula(rCxt, bCreateFormulaString); } -void ScTable::CompileNameFormula( bool bCreateFormulaString ) +void ScTable::CompileNameFormula( sc::CompileFormulaContext& rCxt, bool bCreateFormulaString ) { - for (SCCOL i=0; i<=MAXCOL; i++) aCol[i].CompileNameFormula( bCreateFormulaString ); + for (SCCOL i = 0; i <= MAXCOL; ++i) + aCol[i].CompileNameFormula(rCxt, bCreateFormulaString); } -void ScTable::CompileColRowNameFormula() +void ScTable::CompileColRowNameFormula( sc::CompileFormulaContext& rCxt ) { - for (SCCOL i=0; i<=MAXCOL; i++) aCol[i].CompileColRowNameFormula(); + for (SCCOL i = 0; i <= MAXCOL; ++i) + aCol[i].CompileColRowNameFormula(rCxt); } diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx index dcb676e4a001..4a1bbd723570 100644 --- a/sc/source/core/tool/compiler.cxx +++ b/sc/source/core/tool/compiler.cxx @@ -68,6 +68,7 @@ #include "formulaparserpool.hxx" #include "tokenarray.hxx" #include "scmatrix.hxx" +#include <tokenstringcontext.hxx> using namespace formula; using namespace ::com::sun::star; @@ -1529,6 +1530,24 @@ struct ConventionXL_R1C1 : public ScCompiler::Convention, public ConventionXL static const ConventionXL_R1C1 ConvXL_R1C1; const ScCompiler::Convention * const ScCompiler::pConvXL_R1C1 = &ConvXL_R1C1; +ScCompiler::ScCompiler( sc::CompileFormulaContext& rCxt, const ScAddress& rPos, ScTokenArray& rArr ) : + FormulaCompiler(rArr), + pDoc(rCxt.getDoc()), + aPos(rPos), + mpFormatter(pDoc->GetFormatTable()), + pCharClass(ScGlobal::pCharClass), + mnPredetectedReference(0), + mnRangeOpPosInSymbol(-1), + pConv(GetRefConvention(FormulaGrammar::CONV_OOO)), + meExtendedErrorDetection(EXTENDED_ERROR_DETECTION_NONE), + mbCloseBrackets(true), + mbRewind(false), + maTabNames(rCxt.getTabNames()) +{ + nMaxTab = pDoc ? pDoc->GetTableCount() - 1 : 0; + SetGrammar(rCxt.getGrammar()); +} + ScCompiler::ScCompiler( ScDocument* pDocument, const ScAddress& rPos,ScTokenArray& rArr) : FormulaCompiler(rArr), pDoc( pDocument ), @@ -1555,6 +1574,23 @@ ScCompiler::ScCompiler( ScDocument* pDocument, const ScAddress& rPos,ScTokenArra } } +ScCompiler::ScCompiler( sc::CompileFormulaContext& rCxt, const ScAddress& rPos ) : + pDoc(rCxt.getDoc()), + aPos(rPos), + mpFormatter(pDoc ? pDoc->GetFormatTable() : NULL), + pCharClass(ScGlobal::pCharClass), + mnPredetectedReference(0), + mnRangeOpPosInSymbol(-1), + pConv(GetRefConvention(FormulaGrammar::CONV_OOO)), + meExtendedErrorDetection(EXTENDED_ERROR_DETECTION_NONE), + mbCloseBrackets(true), + mbRewind(false), + maTabNames(rCxt.getTabNames()) +{ + nMaxTab = pDoc ? pDoc->GetTableCount() - 1 : 0; + SetGrammar(rCxt.getGrammar()); +} + ScCompiler::ScCompiler( ScDocument* pDocument, const ScAddress& rPos) : pDoc( pDocument ), diff --git a/sc/source/core/tool/rangenam.cxx b/sc/source/core/tool/rangenam.cxx index 6130c614a138..5d88ee8c6959 100644 --- a/sc/source/core/tool/rangenam.cxx +++ b/sc/source/core/tool/rangenam.cxx @@ -34,6 +34,7 @@ #include "refupdat.hxx" #include "document.hxx" #include "refupdatecontext.hxx" +#include <tokenstringcontext.hxx> #include "formula/errorcodes.hxx" @@ -181,14 +182,14 @@ void ScRangeData::CompileRangeData( const OUString& rSymbol, bool bSetError ) } } -void ScRangeData::CompileUnresolvedXML() +void ScRangeData::CompileUnresolvedXML( sc::CompileFormulaContext& rCxt ) { if (pCode->GetCodeError() == errNoName) { // Reconstruct the symbol/formula and then recompile. OUString aSymbol; - ScCompiler aComp( pDoc, aPos, *pCode); - aComp.SetGrammar( eTempGrammar); + rCxt.setGrammar(eTempGrammar); + ScCompiler aComp(rCxt, aPos, *pCode); aComp.CreateStringFromTokenArray( aSymbol); // Don't let the compiler set an error for unknown names on final // compile, errors are handled by the interpreter thereafter. @@ -764,11 +765,11 @@ void ScRangeName::UpdateGrow(const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY) itr->second->UpdateGrow(rArea, nGrowX, nGrowY); } -void ScRangeName::CompileUnresolvedXML() +void ScRangeName::CompileUnresolvedXML( sc::CompileFormulaContext& rCxt ) { DataType::iterator itr = maData.begin(), itrEnd = maData.end(); for (; itr != itrEnd; ++itr) - itr->second->CompileUnresolvedXML(); + itr->second->CompileUnresolvedXML(rCxt); } ScRangeName::const_iterator ScRangeName::begin() const diff --git a/sc/source/core/tool/tokenstringcontext.cxx b/sc/source/core/tool/tokenstringcontext.cxx index a68ae759299a..203d36aaf3e8 100644 --- a/sc/source/core/tool/tokenstringcontext.cxx +++ b/sc/source/core/tool/tokenstringcontext.cxx @@ -105,6 +105,49 @@ TokenStringContext::TokenStringContext( const ScDocument* pDoc, formula::Formula } } +CompileFormulaContext::CompileFormulaContext( ScDocument* pDoc ) : + mpDoc(pDoc), meGram(pDoc->GetGrammar()) +{ + if (!pDoc) + return; + + updateTabNames(); +} + +void CompileFormulaContext::updateTabNames() +{ + // Fetch all sheet names. + maTabNames = mpDoc->GetAllTableNames(); + { + std::vector<OUString>::iterator it = maTabNames.begin(), itEnd = maTabNames.end(); + for (; it != itEnd; ++it) + ScCompiler::CheckTabQuotes(*it, formula::FormulaGrammar::extractRefConvention(meGram)); + } +} + +formula::FormulaGrammar::Grammar CompileFormulaContext::getGrammar() const +{ + return meGram; +} + +void CompileFormulaContext::setGrammar( formula::FormulaGrammar::Grammar eGram ) +{ + bool bUpdate = (meGram != eGram); + meGram = eGram; + if (bUpdate) + updateTabNames(); +} + +const std::vector<OUString>& CompileFormulaContext::getTabNames() const +{ + return maTabNames; +} + +ScDocument* CompileFormulaContext::getDoc() +{ + return mpDoc; +} + } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |