sc/source/core/tool/token.cxx | 53 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 47 insertions(+), 6 deletions(-)
New commits: commit 6821ad076c276b997c44520fd700817566a718c5 Author: Eike Rathke <er...@redhat.com> Date: Thu May 19 23:49:08 2016 +0200 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 diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx index a9894c0..e20104b 100644 --- a/sc/source/core/tool/token.cxx +++ b/sc/source/core/tool/token.cxx @@ -4969,9 +4969,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); } } @@ -4998,8 +5029,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); } @@ -5032,8 +5072,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; _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits