summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
authorEike Rathke <erack@redhat.com>2016-05-18 23:32:00 +0200
committerCaolán McNamara <caolanm@redhat.com>2016-05-19 14:47:51 +0000
commit2dd04ab835656ebeabc341489650b9b97fa5dd8d (patch)
tree9348b1ae4c68a7d7a15e145c7aa05f9f0bdec24c /sc
parent455dbe1a568b342f07fc0f07ba849ac813010304 (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 (cherry picked from commit a2e591e26549294cdb07eb685d4069343404d898) Reviewed-on: https://gerrit.libreoffice.org/25118 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Caolán McNamara <caolanm@redhat.com> Tested-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'sc')
-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 1a8305153524..8d9400c8282e 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -4218,18 +4218,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;
@@ -4246,6 +4246,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())
{
@@ -4262,6 +4268,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(
@@ -4271,6 +4283,9 @@ void checkBounds(
if (!rRef.IsRowRel())
return;
+ ScRange aDeletedRange( ScAddress::UNINITIALIZED );
+ const ScRange* pDeletedRange = nullptr;
+
ScRange aCheckRange = rCxt.maRange;
if (rCxt.meMode == URM_MOVE)
{
@@ -4281,8 +4296,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);
}
}
@@ -4341,14 +4365,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: