diff options
author | Eike Rathke <erack@redhat.com> | 2016-05-19 23:49:08 +0200 |
---|---|---|
committer | Markus Mohrhard <markus.mohrhard@googlemail.com> | 2016-05-20 21:56:19 +0000 |
commit | 01a3831f9dc1b9f64775f3382180d27a3b51f131 (patch) | |
tree | d6902e3dc39bcbe16525a5e750cbac5d06586c68 | |
parent | 81af926d186b22f3cddf34ffcd3a9447d5574cd9 (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.cxx | 53 |
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; |