[Libreoffice-commits] core.git: Branch 'feature/formula-core-rework' - 2 commits - sc/qa sc/source

Kohei Yoshida kohei.yoshida at gmail.com
Sat Jul 20 10:29:35 PDT 2013


 sc/qa/unit/ucalc.hxx                |    2 
 sc/qa/unit/ucalc_formula.cxx        |   95 ++++++++++++++++++++++++++++++++++++
 sc/source/core/data/formulacell.cxx |   19 ++-----
 sc/source/core/tool/interpr1.cxx    |   14 ++---
 4 files changed, 111 insertions(+), 19 deletions(-)

New commits:
commit 7b5c33c33886b2a4f5487d2716b5ae536946d5db
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Sat Jul 20 13:32:07 2013 -0400

    More on removing CalcAbsIfRel(). Almost there...
    
    Change-Id: Ife87377a8f157750c61fc81baa81a3cb4734419b

diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index 4defffd..773c474 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -3318,24 +3318,24 @@ public:
                 case svDoubleRef:
                 {
                     ScComplexRefData aRef = pToken->GetDoubleRef();
-                    aRef.CalcAbsIfRel(mrCell.aPos);
+                    ScRange aAbs = aRef.toAbs(mrCell.aPos);
 
                     // Row reference is relative.
                     bool bAbsFirst = !aRef.Ref1.IsRowRel();
                     bool bAbsLast = !aRef.Ref2.IsRowRel();
-                    ScAddress aRefPos(aRef.Ref1.nCol, aRef.Ref1.nRow, aRef.Ref1.nTab);
-                    size_t nCols = aRef.Ref2.nCol - aRef.Ref1.nCol + 1;
+                    ScAddress aRefPos = aAbs.aStart;
+                    size_t nCols = aAbs.aEnd.Col() - aAbs.aStart.Col() + 1;
                     std::vector<const double*> aArrays;
                     aArrays.reserve(nCols);
                     SCROW nArrayLength = mrCell.GetCellGroup()->mnLength;
-                    SCROW nRefRowSize = aRef.Ref2.nRow - aRef.Ref1.nRow + 1;
+                    SCROW nRefRowSize = aAbs.aEnd.Row() - aAbs.aStart.Row() + 1;
                     if (!bAbsLast)
                     {
                         // range end position is relative. Extend the array length.
                         nArrayLength += nRefRowSize - 1;
                     }
 
-                    for (SCCOL i = aRef.Ref1.nCol; i <= aRef.Ref2.nCol; ++i)
+                    for (SCCOL i = aAbs.aStart.Col(); i <= aAbs.aEnd.Col(); ++i)
                     {
                         aRefPos.SetCol(i);
                         const double* pArray = mrDoc.FetchDoubleArray(mrCxt, aRefPos, nArrayLength);
@@ -3456,8 +3456,7 @@ bool ScFormulaCell::InterpretInvariantFormulaGroup()
                 case svSingleRef:
                 {
                     ScSingleRefData aRef = pToken->GetSingleRef();
-                    aRef.CalcAbsIfRel(aPos); // column may be relative.
-                    ScAddress aRefPos(aRef.nCol, aRef.nRow, aRef.nTab);
+                    ScAddress aRefPos = aRef.toAbs(aPos);
                     formula::FormulaTokenRef pNewToken = pDocument->ResolveStaticReference(aRefPos);
                     if (!pNewToken)
                         return false;
@@ -3468,11 +3467,7 @@ bool ScFormulaCell::InterpretInvariantFormulaGroup()
                 case svDoubleRef:
                 {
                     ScComplexRefData aRef = pToken->GetDoubleRef();
-                    aRef.CalcAbsIfRel(aPos); // column may be relative.
-                    ScRange aRefRange(
-                        aRef.Ref1.nCol, aRef.Ref1.nRow, aRef.Ref1.nTab,
-                        aRef.Ref2.nCol, aRef.Ref2.nRow, aRef.Ref2.nTab);
-
+                    ScRange aRefRange = aRef.toAbs(aPos);
                     formula::FormulaTokenRef pNewToken = pDocument->ResolveStaticReference(aRefRange);
                     if (!pNewToken)
                         return false;
diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index 209c5ac..8fabd38 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -7615,13 +7615,13 @@ void ScInterpreter::ScOffset()
             String aTabName;
             ScComplexRefData aRef;
             PopExternalDoubleRef(nFileId, aTabName, aRef);
-            aRef.CalcAbsIfRel(aPos);
-            nCol1 = aRef.Ref1.nCol;
-            nRow1 = aRef.Ref1.nRow;
-            nTab1 = aRef.Ref1.nTab;
-            nCol2 = aRef.Ref2.nCol;
-            nRow2 = aRef.Ref2.nRow;
-            nTab2 = aRef.Ref2.nTab;
+            ScRange aAbs = aRef.toAbs(aPos);
+            nCol1 = aAbs.aStart.Col();
+            nRow1 = aAbs.aStart.Row();
+            nTab1 = aAbs.aStart.Tab();
+            nCol2 = aAbs.aEnd.Col();
+            nRow2 = aAbs.aEnd.Row();
+            nTab2 = aAbs.aEnd.Tab();
             if (nColNew < 0)
                 nColNew = nCol2 - nCol1 + 1;
             if (nRowNew < 0)
commit b4009f7397a89ef51fc7763b017fd995953e2465
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Sat Jul 20 12:55:50 2013 -0400

    Add test for updating reference on sheet change.
    
    Change-Id: I5ef6d9ed0fb45ea674d14cca98d3be2f4bfe4345

diff --git a/sc/qa/unit/ucalc.hxx b/sc/qa/unit/ucalc.hxx
index 09e3891..478c5bc 100644
--- a/sc/qa/unit/ucalc.hxx
+++ b/sc/qa/unit/ucalc.hxx
@@ -88,6 +88,7 @@ public:
     void testFormulaCompiler();
     void testFormulaRefUpdate();
     void testFormulaRefUpdateRange();
+    void testFormulaRefUpdateSheets();
     void testFuncSUM();
     void testFuncPRODUCT();
     void testFuncN();
@@ -276,6 +277,7 @@ public:
     CPPUNIT_TEST(testFormulaCompiler);
     CPPUNIT_TEST(testFormulaRefUpdate);
     CPPUNIT_TEST(testFormulaRefUpdateRange);
+    CPPUNIT_TEST(testFormulaRefUpdateSheets);
     CPPUNIT_TEST(testFuncSUM);
     CPPUNIT_TEST(testFuncPRODUCT);
     CPPUNIT_TEST(testFuncN);
diff --git a/sc/qa/unit/ucalc_formula.cxx b/sc/qa/unit/ucalc_formula.cxx
index 1968190..4181ec9 100644
--- a/sc/qa/unit/ucalc_formula.cxx
+++ b/sc/qa/unit/ucalc_formula.cxx
@@ -722,6 +722,101 @@ void Test::testFormulaRefUpdateRange()
     m_pDoc->DeleteTab(0);
 }
 
+void Test::testFormulaRefUpdateSheets()
+{
+    m_pDoc->InsertTab(0, "Sheet1");
+    m_pDoc->InsertTab(1, "Sheet2");
+
+    OUString aName;
+    m_pDoc->GetName(0, aName);
+    CPPUNIT_ASSERT_EQUAL(OUString("Sheet1"), aName);
+    m_pDoc->GetName(1, aName);
+    CPPUNIT_ASSERT_EQUAL(OUString("Sheet2"), aName);
+
+    sc::AutoCalcSwitch aACSwitch(*m_pDoc, true); // turn auto calc on.
+
+    // Set values to B2:C3 on sheet Sheet1.
+    m_pDoc->SetValue(ScAddress(1,1,0), 1);
+    m_pDoc->SetValue(ScAddress(1,2,0), 2);
+    m_pDoc->SetValue(ScAddress(2,1,0), 3);
+    m_pDoc->SetValue(ScAddress(2,2,0), 4);
+
+    // Set formulas to B2 and B3 on sheet Sheet2.
+    m_pDoc->SetString(ScAddress(1,1,1), "=SUM(Sheet1.B2:C3)");
+    m_pDoc->SetString(ScAddress(1,2,1), "=SUM(Sheet1.$B$2:$C$3)");
+
+    if (!checkFormula(*m_pDoc, ScAddress(1,1,1), "SUM(Sheet1.B2:C3)"))
+        CPPUNIT_FAIL("Wrong formula in Sheet2.B2.");
+
+    if (!checkFormula(*m_pDoc, ScAddress(1,2,1), "SUM(Sheet1.$B$2:$C$3)"))
+        CPPUNIT_FAIL("Wrong formula in Sheet2.B3.");
+
+    // Swap the sheets.
+    m_pDoc->MoveTab(0, 1);
+    m_pDoc->GetName(0, aName);
+    CPPUNIT_ASSERT_EQUAL(OUString("Sheet2"), aName);
+    m_pDoc->GetName(1, aName);
+    CPPUNIT_ASSERT_EQUAL(OUString("Sheet1"), aName);
+
+    if (!checkFormula(*m_pDoc, ScAddress(1,1,0), "SUM(Sheet1.B2:C3)"))
+        CPPUNIT_FAIL("Wrong formula in Sheet2.B2.");
+
+    if (!checkFormula(*m_pDoc, ScAddress(1,2,0), "SUM(Sheet1.$B$2:$C$3)"))
+        CPPUNIT_FAIL("Wrong formula in Sheet2.B3.");
+
+    // Swap back.
+    m_pDoc->MoveTab(0, 1);
+    m_pDoc->GetName(0, aName);
+    CPPUNIT_ASSERT_EQUAL(OUString("Sheet1"), aName);
+    m_pDoc->GetName(1, aName);
+    CPPUNIT_ASSERT_EQUAL(OUString("Sheet2"), aName);
+
+    if (!checkFormula(*m_pDoc, ScAddress(1,1,1), "SUM(Sheet1.B2:C3)"))
+        CPPUNIT_FAIL("Wrong formula in Sheet2.B2.");
+
+    if (!checkFormula(*m_pDoc, ScAddress(1,2,1), "SUM(Sheet1.$B$2:$C$3)"))
+        CPPUNIT_FAIL("Wrong formula in Sheet2.B3.");
+
+    // Insert a new sheet between the two.
+    m_pDoc->InsertTab(1, "Temp");
+
+    m_pDoc->GetName(1, aName);
+    CPPUNIT_ASSERT_EQUAL(OUString("Temp"), aName);
+    m_pDoc->GetName(2, aName);
+    CPPUNIT_ASSERT_EQUAL(OUString("Sheet2"), aName);
+
+    if (!checkFormula(*m_pDoc, ScAddress(1,1,2), "SUM(Sheet1.B2:C3)"))
+        CPPUNIT_FAIL("Wrong formula in Sheet2.B2.");
+
+    if (!checkFormula(*m_pDoc, ScAddress(1,2,2), "SUM(Sheet1.$B$2:$C$3)"))
+        CPPUNIT_FAIL("Wrong formula in Sheet2.B3.");
+
+    // Delete the temporary sheet.
+    m_pDoc->DeleteTab(1);
+
+    m_pDoc->GetName(1, aName);
+    CPPUNIT_ASSERT_EQUAL(OUString("Sheet2"), aName);
+
+    if (!checkFormula(*m_pDoc, ScAddress(1,1,1), "SUM(Sheet1.B2:C3)"))
+        CPPUNIT_FAIL("Wrong formula in Sheet2.B2.");
+
+    if (!checkFormula(*m_pDoc, ScAddress(1,2,1), "SUM(Sheet1.$B$2:$C$3)"))
+        CPPUNIT_FAIL("Wrong formula in Sheet2.B3.");
+
+    // Delete Sheet1.
+    m_pDoc->DeleteTab(0);
+    m_pDoc->GetName(0, aName);
+    CPPUNIT_ASSERT_EQUAL(OUString("Sheet2"), aName);
+
+    if (!checkFormula(*m_pDoc, ScAddress(1,1,0), "SUM(#REF!.B2:C3)"))
+        CPPUNIT_FAIL("Wrong formula in Sheet2.B2.");
+
+    if (!checkFormula(*m_pDoc, ScAddress(1,2,0), "SUM(#REF!.$B$2:$C$3)"))
+        CPPUNIT_FAIL("Wrong formula in Sheet2.B3.");
+
+    m_pDoc->DeleteTab(0);
+}
+
 void Test::testFuncSUM()
 {
     OUString aTabName("foo");


More information about the Libreoffice-commits mailing list