summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEike Rathke <erack@redhat.com>2015-06-27 00:13:20 +0200
committerEike Rathke <erack@redhat.com>2015-06-27 01:59:54 +0200
commitdc34bb9b05cf7b5261122a73fa9c6f5356802c19 (patch)
tree0be52195c62eb95389b4c855bd89d34247887b2d
parent6d86e27c8467780133e0c3f7c195dd7758c9f490 (diff)
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
-rw-r--r--sc/source/core/tool/address.cxx4
-rw-r--r--sc/source/core/tool/refupdat.cxx10
-rw-r--r--sc/source/core/tool/token.cxx78
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;