From dc34bb9b05cf7b5261122a73fa9c6f5356802c19 Mon Sep 17 00:00:00 2001 From: Eike Rathke Date: Sat, 27 Jun 2015 00:13:20 +0200 Subject: tdf#90573 do not shift/move entire col/row references and ranges This gets significant now that we have regular A:A/1:1 references. Change-Id: I6cee35173cb1c13b03f6bf4dfc0dce9949536e23 --- sc/source/core/tool/address.cxx | 4 +++ sc/source/core/tool/refupdat.cxx | 10 +++--- sc/source/core/tool/token.cxx | 78 ++++++++++++++++++++++++++++++++++------ 3 files changed, 78 insertions(+), 14 deletions(-) diff --git a/sc/source/core/tool/address.cxx b/sc/source/core/tool/address.cxx index 8ac9d1abc324..60d6d2e080db 100644 --- a/sc/source/core/tool/address.cxx +++ b/sc/source/core/tool/address.cxx @@ -2116,6 +2116,10 @@ bool ScAddress::Move( SCsCOL dx, SCsROW dy, SCsTAB dz, ScDocument* pDoc ) bool ScRange::Move( SCsCOL dx, SCsROW dy, SCsTAB dz, ScDocument* pDoc ) { + if (dy && aStart.Row() == 0 && aEnd.Row() == MAXROW) + dy = 0; // Entire column not to be moved. + if (dx && aStart.Col() == 0 && aEnd.Col() == MAXCOL) + dx = 0; // Entire row not to be moved. bool b = aStart.Move( dx, dy, dz, pDoc ); b &= aEnd.Move( dx, dy, dz, pDoc ); return b; diff --git a/sc/source/core/tool/refupdat.cxx b/sc/source/core/tool/refupdat.cxx index a1f39be5800d..6aa2c3f8c55b 100644 --- a/sc/source/core/tool/refupdat.cxx +++ b/sc/source/core/tool/refupdat.cxx @@ -208,7 +208,8 @@ ScRefUpdateRes ScRefUpdate::Update( ScDocument* pDoc, UpdateRefMode eUpdateRefMo { bool bExpand = pDoc->IsExpandRefs(); if ( nDx && (theRow1 >= nRow1) && (theRow2 <= nRow2) && - (theTab1 >= nTab1) && (theTab2 <= nTab2) ) + (theTab1 >= nTab1) && (theTab2 <= nTab2) && + !(theCol1 == 0 && theCol2 == MAXCOL) ) { bool bExp = (bExpand && IsExpand( theCol1, theCol2, nCol1, nDx )); bCut1 = lcl_MoveStart( theCol1, nCol1, nDx, MAXCOL ); @@ -227,7 +228,8 @@ ScRefUpdateRes ScRefUpdate::Update( ScDocument* pDoc, UpdateRefMode eUpdateRefMo } } if ( nDy && (theCol1 >= nCol1) && (theCol2 <= nCol2) && - (theTab1 >= nTab1) && (theTab2 <= nTab2) ) + (theTab1 >= nTab1) && (theTab2 <= nTab2) && + !(theRow1 == 0 && theRow2 == MAXROW) ) { bool bExp = (bExpand && IsExpand( theRow1, theRow2, nRow1, nDy )); bCut1 = lcl_MoveStart( theRow1, nRow1, nDy, MAXROW ); @@ -272,14 +274,14 @@ ScRefUpdateRes ScRefUpdate::Update( ScDocument* pDoc, UpdateRefMode eUpdateRefMo if ((theCol1 >= nCol1-nDx) && (theRow1 >= nRow1-nDy) && (theTab1 >= nTab1-nDz) && (theCol2 <= nCol2-nDx) && (theRow2 <= nRow2-nDy) && (theTab2 <= nTab2-nDz)) { - if ( nDx ) + if ( nDx && !(theCol1 == 0 && theCol2 == MAXCOL) ) { bCut1 = lcl_MoveItCut( theCol1, nDx, MAXCOL ); bCut2 = lcl_MoveItCut( theCol2, nDx, MAXCOL ); if ( bCut1 || bCut2 ) eRet = UR_UPDATED; } - if ( nDy ) + if ( nDy && !(theRow1 == 0 && theRow2 == MAXROW) ) { bCut1 = lcl_MoveItCut( theRow1, nDy, MAXROW ); bCut2 = lcl_MoveItCut( theRow2, nDy, MAXROW ); diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx index c2a9f5bb171f..4ada5014a17b 100644 --- a/sc/source/core/tool/token.cxx +++ b/sc/source/core/tool/token.cxx @@ -2569,13 +2569,18 @@ void setRefDeleted( ScComplexRefData& rRef, const sc::RefUpdateContext& rCxt ) } } -bool shrinkRange( const sc::RefUpdateContext& rCxt, ScRange& rRefRange, const ScRange& rDeletedRange ) +bool shrinkRange( const sc::RefUpdateContext& rCxt, ScRange& rRefRange, const ScRange& rDeletedRange, + const ScComplexRefData& rRef ) { if (!rDeletedRange.Intersects(rRefRange)) return false; if (rCxt.mnColDelta < 0) { + if (rRef.IsEntireRow()) + // Entire rows are not affected, columns are anchored. + return false; + // 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. @@ -2614,6 +2619,10 @@ bool shrinkRange( const sc::RefUpdateContext& rCxt, ScRange& rRefRange, const Sc } else if (rCxt.mnRowDelta < 0) { + if (rRef.IsEntireCol()) + // Entire columns are not affected, rows are anchored. + return false; + // Shifting up. if (rRefRange.aStart.Col() < rDeletedRange.aStart.Col() || rDeletedRange.aEnd.Col() < rRefRange.aEnd.Col()) @@ -2655,13 +2664,18 @@ bool shrinkRange( const sc::RefUpdateContext& rCxt, ScRange& rRefRange, const Sc return false; } -bool expandRange( const sc::RefUpdateContext& rCxt, ScRange& rRefRange, const ScRange& rSelectedRange ) +bool expandRange( const sc::RefUpdateContext& rCxt, ScRange& rRefRange, const ScRange& rSelectedRange, + const ScComplexRefData& rRef ) { if (!rSelectedRange.Intersects(rRefRange)) return false; if (rCxt.mnColDelta > 0) { + if (rRef.IsEntireRow()) + // Entire rows are not affected, columns are anchored. + return false; + // Insert and shifting right. if (rRefRange.aStart.Row() < rSelectedRange.aStart.Row() || rSelectedRange.aEnd.Row() < rRefRange.aEnd.Row()) // Selected range is only partially overlapping in vertical direction. Bail out. @@ -2687,6 +2701,10 @@ bool expandRange( const sc::RefUpdateContext& rCxt, ScRange& rRefRange, const Sc } else if (rCxt.mnRowDelta > 0) { + if (rRef.IsEntireCol()) + // Entire columns are not affected, rows are anchored. + return false; + // Insert and shifting down. if (rRefRange.aStart.Col() < rSelectedRange.aStart.Col() || rSelectedRange.aEnd.Col() < rRefRange.aEnd.Col()) // Selected range is only partially overlapping in horizontal direction. Bail out. @@ -2717,7 +2735,8 @@ bool expandRange( const sc::RefUpdateContext& rCxt, ScRange& rRefRange, const Sc * Check if the referenced range is expandable when the selected range is * not overlapping the referenced range. */ -bool expandRangeByEdge( const sc::RefUpdateContext& rCxt, ScRange& rRefRange, const ScRange& rSelectedRange ) +bool expandRangeByEdge( const sc::RefUpdateContext& rCxt, ScRange& rRefRange, const ScRange& rSelectedRange, + const ScComplexRefData& rRef ) { if (!rCxt.mrDoc.IsExpandRefs()) // Edge-expansion is turned off. @@ -2729,6 +2748,10 @@ bool expandRangeByEdge( const sc::RefUpdateContext& rCxt, ScRange& rRefRange, co if (rCxt.mnColDelta > 0) { + if (rRef.IsEntireRow()) + // Entire rows are not affected, columns are anchored. + return false; + // Insert and shift right. if (rRefRange.aEnd.Col() - rRefRange.aStart.Col() < 1) @@ -2750,6 +2773,10 @@ bool expandRangeByEdge( const sc::RefUpdateContext& rCxt, ScRange& rRefRange, co } else if (rCxt.mnRowDelta > 0) { + if (rRef.IsEntireCol()) + // Entire columns are not affected, rows are anchored. + return false; + if (rRefRange.aEnd.Row() - rRefRange.aStart.Row() < 1) // Reference must be at least two rows tall. return false; @@ -2866,7 +2893,7 @@ sc::RefUpdateResult ScTokenArray::AdjustReferenceOnShift( const sc::RefUpdateCon } else if (aSelectedRange.Intersects(aAbs)) { - if (shrinkRange(rCxt, aAbs, aSelectedRange)) + if (shrinkRange(rCxt, aAbs, aSelectedRange, rRef)) { // The reference range has been shrunk. rRef.SetRange(aAbs, aNewPos); @@ -2879,7 +2906,7 @@ sc::RefUpdateResult ScTokenArray::AdjustReferenceOnShift( const sc::RefUpdateCon if (rCxt.isInserted()) { - if (expandRange(rCxt, aAbs, aSelectedRange)) + if (expandRange(rCxt, aAbs, aSelectedRange, rRef)) { // The reference range has been expanded. rRef.SetRange(aAbs, aNewPos); @@ -2888,7 +2915,7 @@ sc::RefUpdateResult ScTokenArray::AdjustReferenceOnShift( const sc::RefUpdateCon break; } - if (expandRangeByEdge(rCxt, aAbs, aSelectedRange)) + if (expandRangeByEdge(rCxt, aAbs, aSelectedRange, rRef)) { // The reference range has been expanded on the edge. rRef.SetRange(aAbs, aNewPos); @@ -3307,11 +3334,37 @@ bool adjustDoubleRefInName( } } - if (adjustSingleRefInName(rRef.Ref1, rCxt, rPos)) - bRefChanged = true; + if ((rCxt.mnRowDelta && rRef.IsEntireCol()) || (rCxt.mnColDelta && rRef.IsEntireRow())) + { + // References to entire col/row are not to be adjusted in the other axis. + sc::RefUpdateContext aCxt( rCxt.mrDoc); + // We only need a few parameters of RefUpdateContext. + aCxt.maRange = rCxt.maRange; + aCxt.mnColDelta = rCxt.mnColDelta; + aCxt.mnRowDelta = rCxt.mnRowDelta; + aCxt.mnTabDelta = rCxt.mnTabDelta; + if (aCxt.mnRowDelta && rRef.IsEntireCol()) + aCxt.mnRowDelta = 0; + if (aCxt.mnColDelta && rRef.IsEntireRow()) + aCxt.mnColDelta = 0; + if (!aCxt.mnColDelta && !aCxt.mnRowDelta && !aCxt.mnTabDelta) + // early bailout + return bRefChanged; + + if (adjustSingleRefInName(rRef.Ref1, aCxt, rPos)) + bRefChanged = true; + + if (adjustSingleRefInName(rRef.Ref2, aCxt, rPos)) + bRefChanged = true; + } + else + { + if (adjustSingleRefInName(rRef.Ref1, rCxt, rPos)) + bRefChanged = true; - if (adjustSingleRefInName(rRef.Ref2, rCxt, rPos)) - bRefChanged = true; + if (adjustSingleRefInName(rRef.Ref2, rCxt, rPos)) + bRefChanged = true; + } return bRefChanged; } @@ -3359,6 +3412,11 @@ sc::RefUpdateResult ScTokenArray::AdjustReferenceInName( else if (rCxt.mnRowDelta < 0) { // row(s) deleted. + + if (rRef.IsEntireCol()) + // Rows of entire columns are not affected. + break; + if (rRef.Ref1.IsRowRel() || rRef.Ref2.IsRowRel()) // Don't modify relative references in names. break; -- cgit v1.2.3