diff options
author | Eike Rathke <erack@redhat.com> | 2017-06-27 15:00:55 +0200 |
---|---|---|
committer | Eike Rathke <erack@redhat.com> | 2017-06-27 15:04:22 +0200 |
commit | a962f1465a8db9b6c4dfdfd8fef9141f07d7fd06 (patch) | |
tree | 747e4bd5f74039af7303664187b921b5234c43eb | |
parent | b06657fca57b02ffb267a168bc9323780aeafbef (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.cxx | 6 | ||||
-rw-r--r-- | sc/source/core/data/document.cxx | 31 | ||||
-rw-r--r-- | sc/source/core/tool/token.cxx | 43 |
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; + } } } |