summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEike Rathke <erack@redhat.com>2016-05-19 23:49:08 +0200
committerMarkus Mohrhard <markus.mohrhard@googlemail.com>2016-05-20 21:56:19 +0000
commit01a3831f9dc1b9f64775f3382180d27a3b51f131 (patch)
treed6902e3dc39bcbe16525a5e750cbac5d06586c68
parent81af926d186b22f3cddf34ffcd3a9447d5574cd9 (diff)
Resolves: tdf#83746 wrapAddress() didn't do what it was supposed to do
i.e. subtracted nMaxRow from MAXROW that is set for entire column references, resulting in row 983040=1048576-65536, instead of doing a modulo operation. Also, entire column/row references are now untouched so they still reference the entire column/row. Note that in Excel BIFF8 an absolute addressing of row 1 and 65536 means entire column, so B$1:B$65536 saved and reloaded results in B:B, which may be unexpected. Change-Id: Iae65d47ba937b9ade95e4ea1be98012b80e1c9db (cherry picked from commit 6821ad076c276b997c44520fd700817566a718c5) Reviewed-on: https://gerrit.libreoffice.org/25182 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Markus Mohrhard <markus.mohrhard@googlemail.com>
-rw-r--r--sc/source/core/tool/token.cxx53
1 files changed, 47 insertions, 6 deletions
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index 8d9400c8282e..76018e4f5136 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -4805,9 +4805,40 @@ namespace {
void wrapAddress( ScAddress& rPos, SCCOL nMaxCol, SCROW nMaxRow )
{
if (rPos.Col() > nMaxCol)
- rPos.SetCol(rPos.Col() - nMaxCol - 1);
+ rPos.SetCol((rPos.Col() % (nMaxCol+1)));
if (rPos.Row() > nMaxRow)
- rPos.SetRow(rPos.Row() - nMaxRow - 1);
+ rPos.SetRow((rPos.Row() % (nMaxRow+1)));
+}
+
+template<typename T> void wrapRange( T& n1, T& n2, T nMax )
+{
+ if (n2 > nMax)
+ {
+ if (n1 == 0)
+ n2 = nMax; // Truncate to full range instead of wrapping to a weird range.
+ else
+ n2 = n2 % (nMax+1);
+ }
+ if (n1 > nMax)
+ n1 = n1 % (nMax+1);
+}
+
+void wrapColRange( ScRange& rRange, SCCOL nMaxCol )
+{
+ SCCOL nCol1 = rRange.aStart.Col();
+ SCCOL nCol2 = rRange.aEnd.Col();
+ wrapRange( nCol1, nCol2, nMaxCol);
+ rRange.aStart.SetCol( nCol1);
+ rRange.aEnd.SetCol( nCol2);
+}
+
+void wrapRowRange( ScRange& rRange, SCROW nMaxRow )
+{
+ SCROW nRow1 = rRange.aStart.Row();
+ SCROW nRow2 = rRange.aEnd.Row();
+ wrapRange( nRow1, nRow2, nMaxRow);
+ rRange.aStart.SetRow( nRow1);
+ rRange.aEnd.SetRow( nRow2);
}
}
@@ -4834,8 +4865,17 @@ void ScTokenArray::WrapReference( const ScAddress& rPos, SCCOL nMaxCol, SCROW nM
formula::FormulaToken* pToken = *p;
ScComplexRefData& rRef = *pToken->GetDoubleRef();
ScRange aAbs = rRef.toAbs(rPos);
- wrapAddress(aAbs.aStart, nMaxCol, nMaxRow);
- wrapAddress(aAbs.aEnd, nMaxCol, nMaxRow);
+ // Entire columns/rows are sticky.
+ if (!rRef.IsEntireCol() && !rRef.IsEntireRow())
+ {
+ wrapColRange( aAbs, nMaxCol);
+ wrapRowRange( aAbs, nMaxRow);
+ }
+ else if (rRef.IsEntireCol() && !rRef.IsEntireRow())
+ wrapColRange( aAbs, nMaxCol);
+ else if (!rRef.IsEntireCol() && rRef.IsEntireRow())
+ wrapRowRange( aAbs, nMaxRow);
+ // else nothing if both, column and row, are entire.
aAbs.PutInOrder();
rRef.SetRange(aAbs, rPos);
}
@@ -4868,8 +4908,9 @@ bool ScTokenArray::NeedsWrapReference( const ScAddress& rPos, SCCOL nMaxCol, SCR
formula::FormulaToken* pToken = *p;
ScComplexRefData& rRef = *pToken->GetDoubleRef();
ScRange aAbs = rRef.toAbs(rPos);
- if (aAbs.aStart.Col() > nMaxCol || aAbs.aStart.Row() > nMaxRow ||
- aAbs.aEnd.Col() > nMaxCol || aAbs.aEnd.Row() > nMaxRow)
+ // Entire columns/rows are sticky.
+ if ( (!rRef.IsEntireCol() && (aAbs.aStart.Row() > nMaxRow || aAbs.aEnd.Row() > nMaxRow)) ||
+ (!rRef.IsEntireRow() && (aAbs.aStart.Col() > nMaxCol || aAbs.aEnd.Col() > nMaxCol)))
return true;
}
break;