tdf#120948: row deltas should be stored as SCROW...

instead of SCCOL, else it may cause overflows.
Also included a unit test for protecting the fix.

Reviewed-on: https://gerrit.libreoffice.org/85118
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
(cherry picked from commit 3b8e554b69de349a20d10ec90b27ab71a013b464)
Reviewed-on: https://gerrit.libreoffice.org/85180
Signed-off-by: Xisco Fauli <xiscofauli@libreoffice.org>

Change-Id: I8f735b23b7f95ecf34ccae86f00c76b82b0d668f
Reviewed-on: https://gerrit.libreoffice.org/85205
Tested-by: Jenkins
Reviewed-by: Eike Rathke <erack@redhat.com>
diff --git a/sc/qa/unit/ucalc.hxx b/sc/qa/unit/ucalc.hxx
index ba85b9b..157a322 100644
--- a/sc/qa/unit/ucalc.hxx
+++ b/sc/qa/unit/ucalc.hxx
@@ -562,6 +562,7 @@ public:
    void testProtectedSheetEditByColumn();
    void testFuncRowsHidden();
    void testInsertColCellStoreEventSwap();
    void testFormulaAfterDeleteRows();

    CPPUNIT_TEST_SUITE(Test);
    CPPUNIT_TEST(testCollator);
@@ -862,6 +863,7 @@ public:
    CPPUNIT_TEST(testProtectedSheetEditByColumn);
    CPPUNIT_TEST(testFuncRowsHidden);
    CPPUNIT_TEST(testInsertColCellStoreEventSwap);
    CPPUNIT_TEST(testFormulaAfterDeleteRows);
    CPPUNIT_TEST_SUITE_END();

private:
diff --git a/sc/qa/unit/ucalc_formula.cxx b/sc/qa/unit/ucalc_formula.cxx
index 8754239..06cdf1e 100644
--- a/sc/qa/unit/ucalc_formula.cxx
+++ b/sc/qa/unit/ucalc_formula.cxx
@@ -8993,4 +8993,24 @@ void Test::testInsertColCellStoreEventSwap()
    m_pDoc->DeleteTab(0);
}

void Test::testFormulaAfterDeleteRows()
{
    sc::AutoCalcSwitch aACSwitch(*m_pDoc, true); // turn auto calc on.
    m_pDoc->InsertTab(0, "Test");

    // Fill A1:A70000 with 1.0
    std::vector<double> aVals(70000, 1.0);
    m_pDoc->SetValues(ScAddress(0, 0, 0), aVals);
    // Set A70001 with formula "=SUM(A1:A70000)"
    m_pDoc->SetString(0, 70000, 0, "=SUM(A1:A70000)");

    // Delete rows 2:69998
    m_pDoc->DeleteRow(ScRange(0, 1, 0, MAXCOL, 69997, 0));

    const ScAddress aPos(0, 3, 0);  // A4
    ASSERT_FORMULA_EQUAL(*m_pDoc, aPos, "SUM(A1:A3)", "Wrong formula in A4.");

    ASSERT_DOUBLES_EQUAL_MESSAGE("Wrong value at A4", 3.0, m_pDoc->GetValue(aPos));
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index 0b8b528..906f170 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -2833,8 +2833,8 @@ ShrinkResult shrinkRange( const sc::RefUpdateContext& rCxt, ScRange& rRefRange, 
            else
            {
                // The reference range is truncated on the top.
                SCCOL nOffset = rDeletedRange.aStart.Row() - rRefRange.aStart.Row();
                SCCOL nDelta = rRefRange.aStart.Row() - rDeletedRange.aEnd.Row() - 1;
                SCROW nOffset = rDeletedRange.aStart.Row() - rRefRange.aStart.Row();
                SCROW nDelta = rRefRange.aStart.Row() - rDeletedRange.aEnd.Row() - 1;
                rRefRange.IncEndRowSticky(nDelta+nOffset);
                rRefRange.aStart.IncRow(nOffset);
            }
@@ -2847,7 +2847,7 @@ ShrinkResult shrinkRange( const sc::RefUpdateContext& rCxt, ScRange& rRefRange, 

            // Reference is deleted in the middle. Move the last row
            // position upward.
            SCCOL nDelta = rDeletedRange.aStart.Row() - rDeletedRange.aEnd.Row() - 1;
            SCROW nDelta = rDeletedRange.aStart.Row() - rDeletedRange.aEnd.Row() - 1;
            rRefRange.IncEndRowSticky(nDelta);
        }
        else
@@ -2857,7 +2857,7 @@ ShrinkResult shrinkRange( const sc::RefUpdateContext& rCxt, ScRange& rRefRange, 
                return STICKY;

            // The reference range is truncated on the bottom.
            SCCOL nDelta = rDeletedRange.aStart.Row() - rRefRange.aEnd.Row() - 1;
            SCROW nDelta = rDeletedRange.aStart.Row() - rRefRange.aEnd.Row() - 1;
            rRefRange.IncEndRowSticky(nDelta);
        }
        return SHRUNK;