diff options
author | Kohei Yoshida <kohei.yoshida@gmail.com> | 2013-07-18 15:57:10 -0400 |
---|---|---|
committer | Kohei Yoshida <kohei.yoshida@gmail.com> | 2013-07-24 23:29:29 -0400 |
commit | 87c187be0a2c56fefab53594e00f979492c004fd (patch) | |
tree | a4154731d1e53439e06a2f81704fab9016a60621 /sc | |
parent | 8a459277b4e27e7b18fae842a62f2774cb62fc2a (diff) |
Correctly update references on cell insertion/deletion.
Change-Id: Ie7499f1f589cd384c4e2421dc81d3c1f02e4a53e
Diffstat (limited to 'sc')
-rw-r--r-- | sc/inc/refupdatecontext.hxx | 8 | ||||
-rw-r--r-- | sc/inc/tokenarray.hxx | 16 | ||||
-rw-r--r-- | sc/source/core/data/formulacell.cxx | 10 | ||||
-rw-r--r-- | sc/source/core/data/refupdatecontext.cxx | 2 | ||||
-rw-r--r-- | sc/source/core/tool/token.cxx | 46 |
5 files changed, 75 insertions, 7 deletions
diff --git a/sc/inc/refupdatecontext.hxx b/sc/inc/refupdatecontext.hxx index 80fdd7417c37..7192ec70a7fd 100644 --- a/sc/inc/refupdatecontext.hxx +++ b/sc/inc/refupdatecontext.hxx @@ -43,6 +43,14 @@ struct RefUpdateContext bool hasDelta() const; }; +struct RefUpdateResult +{ + bool mbValueChanged; + bool mbRangeSizeModified; + + RefUpdateResult(); +}; + } #endif diff --git a/sc/inc/tokenarray.hxx b/sc/inc/tokenarray.hxx index 9f0c46357e4b..fe6204c1f2ff 100644 --- a/sc/inc/tokenarray.hxx +++ b/sc/inc/tokenarray.hxx @@ -27,6 +27,13 @@ #include "calcmacros.hxx" #include <formula/tokenarray.hxx> +namespace sc { + +struct RefUpdateContext; +struct RefUpdateResult; + +} + struct ScRawToken; struct ScSingleRefData; struct ScComplexRefData; @@ -113,6 +120,15 @@ public: */ void AdjustAbsoluteRefs( const ScDocument* pOldDoc, const ScAddress& rOldPos, const ScAddress& rNewPos, bool bRangeName = false, bool bCheckCopyArea = false ); + /** + * Adjust all references in response to shifting of cells during cell + * insertion and deletion. + * + * @param rCxt context that stores details of shifted region. + * @param rOldPos old cell position prior to shifting. + */ + sc::RefUpdateResult AdjustReferenceOnShift( const sc::RefUpdateContext& rCxt, const ScAddress& rOldPos ); + #if DEBUG_FORMULA_COMPILER void Dump() const; #endif diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx index f74231a52a88..e17d4c62e159 100644 --- a/sc/source/core/data/formulacell.cxx +++ b/sc/source/core/data/formulacell.cxx @@ -1852,7 +1852,6 @@ bool ScFormulaCell::GetMatrixOrigin( ScAddress& rPos ) const } break; } - fprintf(stdout, "ScFormulaCell::GetMatrixOrigin: failed\n"); return false; } @@ -2274,12 +2273,9 @@ bool ScFormulaCell::UpdateReferenceOnShift( if (bHasRefs) { // Update cell or range references. - ScCompiler aComp(pDocument, aPos, *pCode); - aComp.SetGrammar(pDocument->GetGrammar()); - aComp.UpdateReference( - URM_INSDEL, aOldPos, rCxt.maRange, rCxt.mnColDelta, rCxt.mnRowDelta, rCxt.mnTabDelta, - bValChanged, bRefSizeChanged); - bRangeModified = aComp.HasModifiedRange(); + sc::RefUpdateResult aRes = pCode->AdjustReferenceOnShift(rCxt, aOldPos); + bRangeModified = aRes.mbRangeSizeModified; + bValChanged = aRes.mbValueChanged; } bCellStateChanged |= bValChanged; diff --git a/sc/source/core/data/refupdatecontext.cxx b/sc/source/core/data/refupdatecontext.cxx index a5c861643db5..72dadf0a2452 100644 --- a/sc/source/core/data/refupdatecontext.cxx +++ b/sc/source/core/data/refupdatecontext.cxx @@ -19,6 +19,8 @@ bool RefUpdateContext::hasDelta() const return (mnColDelta > 0 || mnRowDelta > 0 || mnTabDelta > 0); } +RefUpdateResult::RefUpdateResult() : mbValueChanged(false), mbRangeSizeModified(false) {} + } diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx index 3447432c3313..56d4ddc77cbb 100644 --- a/sc/source/core/tool/token.cxx +++ b/sc/source/core/tool/token.cxx @@ -37,6 +37,7 @@ #include "rangeseq.hxx" #include "externalrefmgr.hxx" #include "document.hxx" +#include "refupdatecontext.hxx" using ::std::vector; @@ -2216,6 +2217,51 @@ void ScTokenArray::AdjustAbsoluteRefs( const ScDocument* pOldDoc, const ScAddres } } +sc::RefUpdateResult ScTokenArray::AdjustReferenceOnShift( const sc::RefUpdateContext& rCxt, const ScAddress& rOldPos ) +{ + sc::RefUpdateResult aRes; + ScAddress aNewPos = rOldPos; + bool bCellShifted = rCxt.maRange.In(rOldPos); + if (bCellShifted) + aNewPos.Move(rCxt.mnColDelta, rCxt.mnRowDelta, rCxt.mnTabDelta); + + FormulaToken** p = pCode; + FormulaToken** pEnd = p + static_cast<size_t>(nLen); + for (; p != pEnd; ++p) + { + ScToken* pToken = static_cast<ScToken*>(*p); + switch (pToken->GetType()) + { + case svSingleRef: + { + ScSingleRefData& rRef = pToken->GetSingleRef(); + ScAddress aAbs = rRef.toAbs(rOldPos); + + if (rCxt.maRange.In(aAbs)) + aAbs.Move(rCxt.mnColDelta, rCxt.mnRowDelta, rCxt.mnTabDelta); + + rRef.SetAddress(aAbs, aNewPos); + } + break; + case svDoubleRef: + { + ScComplexRefData& rRef = pToken->GetDoubleRef(); + ScRange aAbs = rRef.toAbs(rOldPos); + + if (rCxt.maRange.In(aAbs)) + aAbs.Move(rCxt.mnColDelta, rCxt.mnRowDelta, rCxt.mnTabDelta); + + rRef.SetRange(aAbs, aNewPos); + } + break; + default: + ; + } + } + + return aRes; +} + #if DEBUG_FORMULA_COMPILER void ScTokenArray::Dump() const { |