summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEike Rathke <erack@redhat.com>2017-06-27 15:00:55 +0200
committerEike Rathke <erack@redhat.com>2017-06-27 15:04:22 +0200
commita962f1465a8db9b6c4dfdfd8fef9141f07d7fd06 (patch)
tree747e4bd5f74039af7303664187b921b5234c43eb
parentb06657fca57b02ffb267a168bc9323780aeafbef (diff)
Resolves: tdf#108788 update references for deletions at end of sheet
ie. when the last column or row is included in the deletion. This seems to have never worked. Change-Id: Ic1bd1944298fe248367597177ca01e109585fcd2
-rw-r--r--sc/source/core/data/documen3.cxx6
-rw-r--r--sc/source/core/data/document.cxx31
-rw-r--r--sc/source/core/tool/token.cxx43
3 files changed, 59 insertions, 21 deletions
diff --git a/sc/source/core/data/documen3.cxx b/sc/source/core/data/documen3.cxx
index 677eef69ba6b..a2d06821e8ca 100644
--- a/sc/source/core/data/documen3.cxx
+++ b/sc/source/core/data/documen3.cxx
@@ -983,7 +983,11 @@ void ScDocument::AddUnoRefChange( sal_Int64 nId, const ScRangeList& rOldRanges )
void ScDocument::UpdateReference(
sc::RefUpdateContext& rCxt, ScDocument* pUndoDoc, bool bIncludeDraw, bool bUpdateNoteCaptionPos )
{
- if (!ValidRange(rCxt.maRange))
+ if (!ValidRange(rCxt.maRange) && !(rCxt.meMode == URM_INSDEL &&
+ ((rCxt.mnColDelta < 0 && // convention from ScDocument::DeleteCol()
+ rCxt.maRange.aStart.Col() == MAXCOLCOUNT && rCxt.maRange.aEnd.Col() == MAXCOLCOUNT) ||
+ (rCxt.mnRowDelta < 0 && // convention from ScDocument::DeleteRow()
+ rCxt.maRange.aStart.Row() == MAXROWCOUNT && rCxt.maRange.aEnd.Row() == MAXROWCOUNT))))
return;
std::unique_ptr<sc::ExpandRefsSwitch> pExpandRefsSwitch;
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index b0a953801d72..2627a0c33f0b 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -1416,12 +1416,21 @@ void ScDocument::DeleteRow( SCCOL nStartCol, SCTAB nStartTab,
while ( lcl_GetNextTabRange( nTabRangeStart, nTabRangeEnd, pTabMark, static_cast<SCTAB>(maTabs.size()) ) );
sc::RefUpdateContext aCxt(*this);
- if ( ValidRow(nStartRow+nSize) )
+ const bool bLastRowIncluded = (nStartRow + nSize == MAXROWCOUNT && ValidRow(nStartRow));
+ if ( ValidRow(nStartRow+nSize) || bLastRowIncluded )
{
lcl_GetFirstTabRange( nTabRangeStart, nTabRangeEnd, pTabMark, static_cast<SCTAB>(maTabs.size()) );
aCxt.meMode = URM_INSDEL;
- aCxt.maRange = ScRange(nStartCol, nStartRow+nSize, nTabRangeStart, nEndCol, MAXROW, nTabRangeEnd);
aCxt.mnRowDelta = -(static_cast<SCROW>(nSize));
+ if (bLastRowIncluded)
+ {
+ // Last row is included, shift a virtually non-existent row in.
+ aCxt.maRange = ScRange( nStartCol, MAXROWCOUNT, nTabRangeStart, nEndCol, MAXROWCOUNT, nTabRangeEnd);
+ }
+ else
+ {
+ aCxt.maRange = ScRange( nStartCol, nStartRow+nSize, nTabRangeStart, nEndCol, MAXROW, nTabRangeEnd);
+ }
do
{
UpdateReference(aCxt, pRefUndoDoc, true, false);
@@ -1447,7 +1456,7 @@ void ScDocument::DeleteRow( SCCOL nStartCol, SCTAB nStartTab,
// Mark all joined groups for group listening.
SetNeedsListeningGroups(aGroupPos);
- if ( ValidRow(nStartRow+nSize) )
+ if ( ValidRow(nStartRow+nSize) || bLastRowIncluded )
{
// Listeners have been removed in UpdateReference
StartNeededListeners();
@@ -1616,12 +1625,22 @@ void ScDocument::DeleteCol(SCROW nStartRow, SCTAB nStartTab, SCROW nEndRow, SCTA
while ( lcl_GetNextTabRange( nTabRangeStart, nTabRangeEnd, pTabMark, static_cast<SCTAB>(maTabs.size()) ) );
sc::RefUpdateContext aCxt(*this);
- if ( ValidCol(sal::static_int_cast<SCCOL>(nStartCol+nSize)) )
+ const bool bLastColIncluded = (nStartCol + nSize == MAXCOLCOUNT && ValidCol(nStartCol));
+ if ( ValidCol(sal::static_int_cast<SCCOL>(nStartCol+nSize)) || bLastColIncluded )
{
lcl_GetFirstTabRange( nTabRangeStart, nTabRangeEnd, pTabMark, static_cast<SCTAB>(maTabs.size()) );
aCxt.meMode = URM_INSDEL;
- aCxt.maRange = ScRange(sal::static_int_cast<SCCOL>(nStartCol+nSize), nStartRow, nTabRangeStart, MAXCOL, nEndRow, nTabRangeEnd);
aCxt.mnColDelta = -(static_cast<SCCOL>(nSize));
+ if (bLastColIncluded)
+ {
+ // Last column is included, shift a virtually non-existent column in.
+ aCxt.maRange = ScRange( MAXCOLCOUNT, nStartRow, nTabRangeStart, MAXCOLCOUNT, nEndRow, nTabRangeEnd);
+ }
+ else
+ {
+ aCxt.maRange = ScRange( sal::static_int_cast<SCCOL>(nStartCol+nSize), nStartRow, nTabRangeStart,
+ MAXCOL, nEndRow, nTabRangeEnd);
+ }
do
{
UpdateReference(aCxt, pRefUndoDoc, true, false);
@@ -1638,7 +1657,7 @@ void ScDocument::DeleteCol(SCROW nStartRow, SCTAB nStartTab, SCROW nEndRow, SCTA
maTabs[i]->DeleteCol(aCxt.maRegroupCols, nStartCol, nStartRow, nEndRow, nSize, pUndoOutline);
}
- if ( ValidCol(sal::static_int_cast<SCCOL>(nStartCol+nSize)) )
+ if ( ValidCol(sal::static_int_cast<SCCOL>(nStartCol+nSize)) || bLastColIncluded )
{
// Listeners have been removed in UpdateReference
StartNeededListeners();
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index 2e054973dca2..0538a1097888 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -2650,22 +2650,29 @@ void restoreDeletedRef( ScComplexRefData& rRef, const sc::RefUpdateContext& rCxt
restoreDeletedRef(rRef.Ref2, rCxt);
}
-bool shrinkRange( const sc::RefUpdateContext& rCxt, ScRange& rRefRange, const ScRange& rDeletedRange,
+enum ShrinkResult
+{
+ UNMODIFIED,
+ SHRUNK,
+ STICKY
+};
+
+ShrinkResult shrinkRange( const sc::RefUpdateContext& rCxt, ScRange& rRefRange, const ScRange& rDeletedRange,
const ScComplexRefData& rRef )
{
if (!rDeletedRange.Intersects(rRefRange))
- return false;
+ return UNMODIFIED;
if (rCxt.mnColDelta < 0)
{
if (rRef.IsEntireRow())
// Entire rows are not affected, columns are anchored.
- return false;
+ return STICKY;
// Shifting left.
if (rRefRange.aStart.Row() < rDeletedRange.aStart.Row() || rDeletedRange.aEnd.Row() < rRefRange.aEnd.Row())
// Deleted range is only partially overlapping in vertical direction. Bail out.
- return false;
+ return UNMODIFIED;
if (rDeletedRange.aStart.Col() <= rRefRange.aStart.Col())
{
@@ -2687,7 +2694,7 @@ bool shrinkRange( const sc::RefUpdateContext& rCxt, ScRange& rRefRange, const Sc
{
if (rRefRange.IsEndColSticky())
// Sticky end not affected.
- return false;
+ return STICKY;
// Reference is deleted in the middle. Move the last column
// position to the left.
@@ -2698,25 +2705,25 @@ bool shrinkRange( const sc::RefUpdateContext& rCxt, ScRange& rRefRange, const Sc
{
if (rRefRange.IsEndColSticky())
// Sticky end not affected.
- return false;
+ return STICKY;
// The reference range is truncated on the right.
SCCOL nDelta = rDeletedRange.aStart.Col() - rRefRange.aEnd.Col() - 1;
rRefRange.IncEndColSticky(nDelta);
}
- return true;
+ return SHRUNK;
}
else if (rCxt.mnRowDelta < 0)
{
if (rRef.IsEntireCol())
// Entire columns are not affected, rows are anchored.
- return false;
+ return STICKY;
// Shifting up.
if (rRefRange.aStart.Col() < rDeletedRange.aStart.Col() || rDeletedRange.aEnd.Col() < rRefRange.aEnd.Col())
// Deleted range is only partially overlapping in horizontal direction. Bail out.
- return false;
+ return UNMODIFIED;
if (rDeletedRange.aStart.Row() <= rRefRange.aStart.Row())
{
@@ -2738,7 +2745,7 @@ bool shrinkRange( const sc::RefUpdateContext& rCxt, ScRange& rRefRange, const Sc
{
if (rRefRange.IsEndRowSticky())
// Sticky end not affected.
- return false;
+ return STICKY;
// Reference is deleted in the middle. Move the last row
// position upward.
@@ -2749,16 +2756,16 @@ bool shrinkRange( const sc::RefUpdateContext& rCxt, ScRange& rRefRange, const Sc
{
if (rRefRange.IsEndRowSticky())
// Sticky end not affected.
- return false;
+ return STICKY;
// The reference range is truncated on the bottom.
SCCOL nDelta = rDeletedRange.aStart.Row() - rRefRange.aEnd.Row() - 1;
rRefRange.IncEndRowSticky(nDelta);
}
- return true;
+ return SHRUNK;
}
- return false;
+ return UNMODIFIED;
}
bool expandRange( const sc::RefUpdateContext& rCxt, ScRange& rRefRange, const ScRange& rSelectedRange,
@@ -3014,7 +3021,8 @@ sc::RefUpdateResult ScTokenArray::AdjustReferenceOnShift( const sc::RefUpdateCon
}
else if (aSelectedRange.Intersects(aAbs))
{
- if (shrinkRange(rCxt, aAbs, aSelectedRange, rRef))
+ const ShrinkResult eSR = shrinkRange(rCxt, aAbs, aSelectedRange, rRef);
+ if (eSR == SHRUNK)
{
// The reference range has been shrunk.
rRef.SetRange(aAbs, aNewPos);
@@ -3022,6 +3030,13 @@ sc::RefUpdateResult ScTokenArray::AdjustReferenceOnShift( const sc::RefUpdateCon
aRes.mbReferenceModified = true;
break;
}
+ else if (eSR == STICKY)
+ {
+ // The reference range stays the same but a
+ // new (empty) cell range is shifted in and
+ // may change the calculation result.
+ aRes.mbValueChanged = true;
+ }
}
}