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