diff options
author | Kohei Yoshida <kohei.yoshida@gmail.com> | 2013-04-26 23:16:43 -0400 |
---|---|---|
committer | Kohei Yoshida <kohei.yoshida@gmail.com> | 2013-04-30 13:10:41 -0400 |
commit | 2f72495cd8097f782f0c8543c13605403f3e90c2 (patch) | |
tree | fa10d5fa64226e4f32882cb289acd5b86b9be9bd /sc | |
parent | 1eaf73af59cc5bc25c40ef8d18b25f853d273229 (diff) |
Move the invariant group handler into its own method.
Change-Id: I3ed8da3c9673b990d5ae17d235bcf4fc1a4541f1
Diffstat (limited to 'sc')
-rw-r--r-- | sc/inc/formulacell.hxx | 3 | ||||
-rw-r--r-- | sc/source/core/data/formulacell.cxx | 156 |
2 files changed, 82 insertions, 77 deletions
diff --git a/sc/inc/formulacell.hxx b/sc/inc/formulacell.hxx index 397fd9c72fe4..e4f1cfa5fd0e 100644 --- a/sc/inc/formulacell.hxx +++ b/sc/inc/formulacell.hxx @@ -302,7 +302,8 @@ public: CompareState CompareByTokenArray( ScFormulaCell *pOther ) const; - bool InterpretFormulaGroup(); + bool InterpretFormulaGroup(); + bool InterpretInvariantFormulaGroup(); // nOnlyNames may be one or more of SC_LISTENING_NAMES_* void StartListeningTo( ScDocument* pDoc ); diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx index 43d80cf906df..3bfd458320fd 100644 --- a/sc/source/core/data/formulacell.cxx +++ b/sc/source/core/data/formulacell.cxx @@ -2965,82 +2965,7 @@ bool ScFormulaCell::InterpretFormulaGroup() } if (xGroup->mbInvariant) - { - if (pCode->GetVectorState() == FormulaVectorCheckReference) - { - // An invariant group should only have absolute references, and no - // external references are allowed. - - ScTokenArray aCode; - pCode->Reset(); - for (const formula::FormulaToken* p = pCode->First(); p; p = pCode->Next()) - { - const ScToken* pToken = static_cast<const ScToken*>(p); - switch (pToken->GetType()) - { - case svSingleRef: - { - const ScSingleRefData& rRef = pToken->GetSingleRef(); - ScAddress aRefPos(rRef.nCol, rRef.nRow, rRef.nTab); - formula::FormulaTokenRef pNewToken = pDocument->ResolveStaticReference(aRefPos); - if (!pNewToken) - return false; - - aCode.AddToken(*pNewToken); - } - break; - case svDoubleRef: - { - const ScComplexRefData& rRef = pToken->GetDoubleRef(); - ScRange aRefRange( - rRef.Ref1.nCol, rRef.Ref1.nRow, rRef.Ref1.nTab, - rRef.Ref2.nCol, rRef.Ref2.nRow, rRef.Ref2.nTab); - - formula::FormulaTokenRef pNewToken = pDocument->ResolveStaticReference(aRefRange); - if (!pNewToken) - return false; - - aCode.AddToken(*pNewToken); - } - break; - default: - aCode.AddToken(*pToken); - } - } - - ScCompiler aComp(pDocument, aPos, aCode); - aComp.SetGrammar(pDocument->GetGrammar()); - aComp.CompileTokenArray(); // Create RPN token array. - ScInterpreter aInterpreter(this, pDocument, aPos, aCode); - aInterpreter.Interpret(); - aResult.SetToken(aInterpreter.GetResultToken().get()); - } - else - { - // Formula contains no references. - ScInterpreter aInterpreter(this, pDocument, aPos, *pCode); - aInterpreter.Interpret(); - aResult.SetToken(aInterpreter.GetResultToken().get()); - } - - for ( sal_Int32 i = 0; i < xGroup->mnLength; i++ ) - { - ScAddress aTmpPos = aPos; - aTmpPos.SetRow(xGroup->mnStart + i); - ScFormulaCell* pCell = pDocument->GetFormulaCell(aTmpPos); - assert( pCell != NULL ); - - // FIXME: this set of horrors is unclear to me ... certainly - // the above GetCell is profoundly nasty & slow ... - - // Ensure the cell truly has a result: - pCell->aResult = aResult; - pCell->ResetDirty(); - - // FIXME: there is a view / refresh missing here it appears. - } - return true; - } + return InterpretInvariantFormulaGroup(); // scan the formula ... // have a document method: "Get2DRangeAsDoublesArray" that does the @@ -3072,6 +2997,85 @@ bool ScFormulaCell::InterpretFormulaGroup() return false; } +bool ScFormulaCell::InterpretInvariantFormulaGroup() +{ + if (pCode->GetVectorState() == FormulaVectorCheckReference) + { + // An invariant group should only have absolute references, and no + // external references are allowed. + + ScTokenArray aCode; + pCode->Reset(); + for (const formula::FormulaToken* p = pCode->First(); p; p = pCode->Next()) + { + const ScToken* pToken = static_cast<const ScToken*>(p); + switch (pToken->GetType()) + { + case svSingleRef: + { + const ScSingleRefData& rRef = pToken->GetSingleRef(); + ScAddress aRefPos(rRef.nCol, rRef.nRow, rRef.nTab); + formula::FormulaTokenRef pNewToken = pDocument->ResolveStaticReference(aRefPos); + if (!pNewToken) + return false; + + aCode.AddToken(*pNewToken); + } + break; + case svDoubleRef: + { + const ScComplexRefData& rRef = pToken->GetDoubleRef(); + ScRange aRefRange( + rRef.Ref1.nCol, rRef.Ref1.nRow, rRef.Ref1.nTab, + rRef.Ref2.nCol, rRef.Ref2.nRow, rRef.Ref2.nTab); + + formula::FormulaTokenRef pNewToken = pDocument->ResolveStaticReference(aRefRange); + if (!pNewToken) + return false; + + aCode.AddToken(*pNewToken); + } + break; + default: + aCode.AddToken(*pToken); + } + } + + ScCompiler aComp(pDocument, aPos, aCode); + aComp.SetGrammar(pDocument->GetGrammar()); + aComp.CompileTokenArray(); // Create RPN token array. + ScInterpreter aInterpreter(this, pDocument, aPos, aCode); + aInterpreter.Interpret(); + aResult.SetToken(aInterpreter.GetResultToken().get()); + } + else + { + // Formula contains no references. + ScInterpreter aInterpreter(this, pDocument, aPos, *pCode); + aInterpreter.Interpret(); + aResult.SetToken(aInterpreter.GetResultToken().get()); + } + + for ( sal_Int32 i = 0; i < xGroup->mnLength; i++ ) + { + ScAddress aTmpPos = aPos; + aTmpPos.SetRow(xGroup->mnStart + i); + ScFormulaCell* pCell = pDocument->GetFormulaCell(aTmpPos); + assert( pCell != NULL ); + + // FIXME: this set of horrors is unclear to me ... certainly + // the above GetCell is profoundly nasty & slow ... + + // Ensure the cell truly has a result: + pCell->aResult = aResult; + pCell->ResetDirty(); + + // FIXME: there is a view / refresh missing here it appears. + } + + return true; +} + void ScFormulaCell::StartListeningTo( ScDocument* pDoc ) { if (pDoc->IsClipOrUndo() || pDoc->GetNoListening() || IsInChangeTrack()) |