[Libreoffice-commits] core.git: sc/source

Eike Rathke erack at redhat.com
Thu May 19 22:02:24 UTC 2016


 sc/source/core/tool/token.cxx |   53 +++++++++++++++++++++++++++++++++++++-----
 1 file changed, 47 insertions(+), 6 deletions(-)

New commits:
commit 6821ad076c276b997c44520fd700817566a718c5
Author: Eike Rathke <erack at 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;


More information about the Libreoffice-commits mailing list