Kaydet (Commit) 46b849a6 authored tarafından Kohei Yoshida's avatar Kohei Yoshida

Re-implement adjusting of references on move.

Change-Id: I52a8b78ed072eb6bcd86b4f80936a869046cbc4d
üst 13941df2
......@@ -129,6 +129,9 @@ public:
*/
sc::RefUpdateResult AdjustReferenceOnShift( const sc::RefUpdateContext& rCxt, const ScAddress& rOldPos );
sc::RefUpdateResult AdjustReferenceOnMove(
const sc::RefUpdateContext& rCxt, const ScAddress& rOldPos, const ScAddress& rNewPos );
/**
* Adjust all references on sheet deletion.
*
......
......@@ -2365,7 +2365,6 @@ bool ScFormulaCell::UpdateReferenceOnMove(
aOldPos.Set(aPos.Col() - rCxt.mnColDelta, aPos.Row() - rCxt.mnRowDelta, aPos.Tab() - rCxt.mnTabDelta);
}
// Check presence of any references or column row names.
pCode->Reset();
bool bHasRefs = (pCode->GetNextReferenceRPN() != NULL);
......@@ -2389,22 +2388,19 @@ bool ScFormulaCell::UpdateReferenceOnMove(
pOldCode.reset(pCode->Clone());
bool bValChanged = false;
bool bRangeModified = false; // any range, not only shared formula
bool bRefModified = false;
bool bRefSizeChanged = false;
if (bHasRefs)
{
// Update cell or range references.
ScCompiler aComp(pDocument, aPos, *pCode);
aComp.SetGrammar(pDocument->GetGrammar());
aComp.UpdateReference(
URM_MOVE, aOldPos, rCxt.maRange,
rCxt.mnColDelta, rCxt.mnRowDelta, rCxt.mnTabDelta,
bValChanged, bRefSizeChanged);
bRangeModified = aComp.HasModifiedRange();
sc::RefUpdateResult aRes = pCode->AdjustReferenceOnMove(rCxt, aOldPos, aPos);
bRefModified = aRes.mbReferenceModified;
bValChanged = aRes.mbValueChanged;
}
bCellStateChanged |= bValChanged;
if (bValChanged || bRefModified)
bCellStateChanged = true;
if (bOnRefMove)
// Cell may reference itself, e.g. ocColumn, ocRow without parameter
......@@ -2429,7 +2425,7 @@ bool ScFormulaCell::UpdateReferenceOnMove(
bHasRelName = HasRelNameReference();
// Reference changed and new listening needed?
// Except in Insert/Delete without specialties.
bNewListening = (bRangeModified || bColRowNameCompile
bNewListening = (bRefModified || bColRowNameCompile
|| bValChanged || bHasRelName)
// #i36299# Don't duplicate action during cut&paste / drag&drop
// on a cell in the range moved, start/end listeners is done
......@@ -2442,7 +2438,7 @@ bool ScFormulaCell::UpdateReferenceOnMove(
bool bNeedDirty = false;
// NeedDirty for changes except for Copy and Move/Insert without RelNames
if ( bRangeModified || bColRowNameCompile ||
if ( bRefModified || bColRowNameCompile ||
(bValChanged && bHasRelName && (bHasRelName || bInDeleteUndo || bRefSizeChanged)) || bOnRefMove)
bNeedDirty = true;
......@@ -2451,7 +2447,7 @@ bool ScFormulaCell::UpdateReferenceOnMove(
bValChanged = false;
if ( ( bCompile = (bCompile || bValChanged || bRangeModified || bColRowNameCompile) ) != 0 )
if ( ( bCompile = (bCompile || bValChanged || bRefModified || bColRowNameCompile) ) != 0 )
{
CompileTokenArray( bNewListening ); // no Listening
bNeedDirty = true;
......
......@@ -2472,6 +2472,58 @@ sc::RefUpdateResult ScTokenArray::AdjustReferenceOnShift( const sc::RefUpdateCon
return aRes;
}
sc::RefUpdateResult ScTokenArray::AdjustReferenceOnMove(
const sc::RefUpdateContext& rCxt, const ScAddress& rOldPos, const ScAddress& rNewPos )
{
// When moving, the range is the destination range. We need to use the old
// range prior to the move for hit analysis.
ScRange aOldRange = rCxt.maRange;
aOldRange.Move(-rCxt.mnColDelta, -rCxt.mnRowDelta, -rCxt.mnTabDelta);
sc::RefUpdateResult aRes;
FormulaToken** p = pCode;
FormulaToken** pEnd = p + static_cast<size_t>(nLen);
for (; p != pEnd; ++p)
{
switch ((*p)->GetType())
{
case svSingleRef:
{
ScToken* pToken = static_cast<ScToken*>(*p);
ScSingleRefData& rRef = pToken->GetSingleRef();
ScAddress aAbs = rRef.toAbs(rOldPos);
if (aOldRange.In(aAbs))
{
aAbs.Move(rCxt.mnColDelta, rCxt.mnRowDelta, rCxt.mnTabDelta);
aRes.mbReferenceModified = true;
}
rRef.SetAddress(aAbs, rNewPos);
}
break;
case svDoubleRef:
{
ScToken* pToken = static_cast<ScToken*>(*p);
ScComplexRefData& rRef = pToken->GetDoubleRef();
ScRange aAbs = rRef.toAbs(rOldPos);
if (aOldRange.In(aAbs))
{
aAbs.Move(rCxt.mnColDelta, rCxt.mnRowDelta, rCxt.mnTabDelta);
aRes.mbReferenceModified = true;
}
rRef.SetRange(aAbs, rNewPos);
}
break;
default:
;
}
}
return aRes;
}
namespace {
bool adjustSingleRef( ScSingleRefData& rRef, SCTAB nDelPos, SCTAB nSheets, const ScAddress& rOldPos, const ScAddress& rNewPos )
......
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