summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEike Rathke <erack@redhat.com>2016-05-18 23:32:00 +0200
committerEike Rathke <erack@redhat.com>2016-05-19 00:30:18 +0200
commita2e591e26549294cdb07eb685d4069343404d898 (patch)
treef4e5c4c3de706b62b90136136b94d5457a135098
parent4f1ce46b8d65360436e09750242101b566e6186c (diff)
Resolves: tdf#86502 split formula groups referring bounds shifted into
So references can be updated or invalidated individually when deleting cells with shifting cells up or left. Change-Id: I03a57e94cf0fa9bb0716ffec21960e85ad5c7094
-rw-r--r--sc/source/core/tool/token.cxx38
1 files changed, 31 insertions, 7 deletions
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index 642e3afe586f..a9894c0ed1f5 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -4365,18 +4365,18 @@ namespace {
void checkBounds(
const ScAddress& rPos, SCROW nGroupLen, const ScRange& rCheckRange,
- const ScSingleRefData& rRef, std::vector<SCROW>& rBounds )
+ const ScSingleRefData& rRef, std::vector<SCROW>& rBounds, const ScRange* pDeletedRange )
{
if (!rRef.IsRowRel())
return;
ScRange aAbs(rRef.toAbs(rPos));
aAbs.aEnd.IncRow(nGroupLen-1);
- if (!rCheckRange.Intersects(aAbs))
+ if (!rCheckRange.Intersects(aAbs) && (!pDeletedRange || !pDeletedRange->Intersects(aAbs)))
return;
// Get the boundary row positions.
- if (aAbs.aEnd.Row() < rCheckRange.aStart.Row())
+ if (aAbs.aEnd.Row() < rCheckRange.aStart.Row() && (!pDeletedRange || aAbs.aEnd.Row() < pDeletedRange->aStart.Row()))
// No intersections.
return;
@@ -4393,6 +4393,12 @@ void checkBounds(
SCROW nOffset = rCheckRange.aStart.Row() - aAbs.aStart.Row();
rBounds.push_back(rPos.Row()+nOffset);
}
+ // Same for deleted range.
+ if (pDeletedRange && aAbs.aStart.Row() <= pDeletedRange->aStart.Row())
+ {
+ SCROW nOffset = pDeletedRange->aStart.Row() - aAbs.aStart.Row();
+ rBounds.push_back(rPos.Row()+nOffset);
+ }
if (aAbs.aEnd.Row() >= rCheckRange.aEnd.Row())
{
@@ -4409,6 +4415,12 @@ void checkBounds(
SCROW nOffset = rCheckRange.aEnd.Row() + 1 - aAbs.aStart.Row();
rBounds.push_back(rPos.Row()+nOffset);
}
+ // Same for deleted range.
+ if (pDeletedRange && aAbs.aEnd.Row() >= pDeletedRange->aEnd.Row())
+ {
+ SCROW nOffset = pDeletedRange->aEnd.Row() + 1 - aAbs.aStart.Row();
+ rBounds.push_back(rPos.Row()+nOffset);
+ }
}
void checkBounds(
@@ -4418,6 +4430,9 @@ void checkBounds(
if (!rRef.IsRowRel())
return;
+ ScRange aDeletedRange( ScAddress::UNINITIALIZED );
+ const ScRange* pDeletedRange = nullptr;
+
ScRange aCheckRange = rCxt.maRange;
if (rCxt.meMode == URM_MOVE)
{
@@ -4428,8 +4443,17 @@ void checkBounds(
assert(!"can't move");
}
}
+ else if (rCxt.meMode == URM_INSDEL &&
+ ((rCxt.mnColDelta < 0 && rCxt.maRange.aStart.Col() > 0) ||
+ (rCxt.mnRowDelta < 0 && rCxt.maRange.aStart.Row() > 0)))
+ {
+ // Check bounds also against deleted range where cells are shifted
+ // into and references need to be invalidated.
+ aDeletedRange = getSelectedRange( rCxt);
+ pDeletedRange = &aDeletedRange;
+ }
- checkBounds(rPos, nGroupLen, aCheckRange, rRef, rBounds);
+ checkBounds(rPos, nGroupLen, aCheckRange, rRef, rBounds, pDeletedRange);
}
}
@@ -4488,14 +4512,14 @@ void ScTokenArray::CheckRelativeReferenceBounds(
case svSingleRef:
{
const ScSingleRefData& rRef = *p->GetSingleRef();
- checkBounds(rPos, nGroupLen, rRange, rRef, rBounds);
+ checkBounds(rPos, nGroupLen, rRange, rRef, rBounds, nullptr);
}
break;
case svDoubleRef:
{
const ScComplexRefData& rRef = *p->GetDoubleRef();
- checkBounds(rPos, nGroupLen, rRange, rRef.Ref1, rBounds);
- checkBounds(rPos, nGroupLen, rRange, rRef.Ref2, rBounds);
+ checkBounds(rPos, nGroupLen, rRange, rRef.Ref1, rBounds, nullptr);
+ checkBounds(rPos, nGroupLen, rRange, rRef.Ref2, rBounds, nullptr);
}
break;
default: