Kaydet (Commit) 87c187be authored tarafından Kohei Yoshida's avatar Kohei Yoshida

Correctly update references on cell insertion/deletion.

Change-Id: Ie7499f1f589cd384c4e2421dc81d3c1f02e4a53e
üst 8a459277
...@@ -43,6 +43,14 @@ struct RefUpdateContext ...@@ -43,6 +43,14 @@ struct RefUpdateContext
bool hasDelta() const; bool hasDelta() const;
}; };
struct RefUpdateResult
{
bool mbValueChanged;
bool mbRangeSizeModified;
RefUpdateResult();
};
} }
#endif #endif
......
...@@ -27,6 +27,13 @@ ...@@ -27,6 +27,13 @@
#include "calcmacros.hxx" #include "calcmacros.hxx"
#include <formula/tokenarray.hxx> #include <formula/tokenarray.hxx>
namespace sc {
struct RefUpdateContext;
struct RefUpdateResult;
}
struct ScRawToken; struct ScRawToken;
struct ScSingleRefData; struct ScSingleRefData;
struct ScComplexRefData; struct ScComplexRefData;
...@@ -113,6 +120,15 @@ public: ...@@ -113,6 +120,15 @@ public:
*/ */
void AdjustAbsoluteRefs( const ScDocument* pOldDoc, const ScAddress& rOldPos, const ScAddress& rNewPos, bool bRangeName = false, bool bCheckCopyArea = false ); 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 #if DEBUG_FORMULA_COMPILER
void Dump() const; void Dump() const;
#endif #endif
......
...@@ -1852,7 +1852,6 @@ bool ScFormulaCell::GetMatrixOrigin( ScAddress& rPos ) const ...@@ -1852,7 +1852,6 @@ bool ScFormulaCell::GetMatrixOrigin( ScAddress& rPos ) const
} }
break; break;
} }
fprintf(stdout, "ScFormulaCell::GetMatrixOrigin: failed\n");
return false; return false;
} }
...@@ -2274,12 +2273,9 @@ bool ScFormulaCell::UpdateReferenceOnShift( ...@@ -2274,12 +2273,9 @@ bool ScFormulaCell::UpdateReferenceOnShift(
if (bHasRefs) if (bHasRefs)
{ {
// Update cell or range references. // Update cell or range references.
ScCompiler aComp(pDocument, aPos, *pCode); sc::RefUpdateResult aRes = pCode->AdjustReferenceOnShift(rCxt, aOldPos);
aComp.SetGrammar(pDocument->GetGrammar()); bRangeModified = aRes.mbRangeSizeModified;
aComp.UpdateReference( bValChanged = aRes.mbValueChanged;
URM_INSDEL, aOldPos, rCxt.maRange, rCxt.mnColDelta, rCxt.mnRowDelta, rCxt.mnTabDelta,
bValChanged, bRefSizeChanged);
bRangeModified = aComp.HasModifiedRange();
} }
bCellStateChanged |= bValChanged; bCellStateChanged |= bValChanged;
......
...@@ -19,6 +19,8 @@ bool RefUpdateContext::hasDelta() const ...@@ -19,6 +19,8 @@ bool RefUpdateContext::hasDelta() const
return (mnColDelta > 0 || mnRowDelta > 0 || mnTabDelta > 0); return (mnColDelta > 0 || mnRowDelta > 0 || mnTabDelta > 0);
} }
RefUpdateResult::RefUpdateResult() : mbValueChanged(false), mbRangeSizeModified(false) {}
} }
......
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#include "rangeseq.hxx" #include "rangeseq.hxx"
#include "externalrefmgr.hxx" #include "externalrefmgr.hxx"
#include "document.hxx" #include "document.hxx"
#include "refupdatecontext.hxx"
using ::std::vector; using ::std::vector;
...@@ -2216,6 +2217,51 @@ void ScTokenArray::AdjustAbsoluteRefs( const ScDocument* pOldDoc, const ScAddres ...@@ -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 #if DEBUG_FORMULA_COMPILER
void ScTokenArray::Dump() const void ScTokenArray::Dump() const
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment