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
bool hasDelta() const;
};
struct RefUpdateResult
{
bool mbValueChanged;
bool mbRangeSizeModified;
RefUpdateResult();
};
}
#endif
......
......@@ -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
......
......@@ -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;
......
......@@ -19,6 +19,8 @@ bool RefUpdateContext::hasDelta() const
return (mnColDelta > 0 || mnRowDelta > 0 || mnTabDelta > 0);
}
RefUpdateResult::RefUpdateResult() : mbValueChanged(false), mbRangeSizeModified(false) {}
}
......
......@@ -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
{
......
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