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

Kohei Yoshida kohei.yoshida at gmail.com
Fri Jul 19 08:30:40 PDT 2013


 sc/qa/unit/ucalc_formula.cxx  |   92 ++++++++++++++++++++++++++++++++++++++++++
 sc/source/core/tool/token.cxx |   41 ++++++++++++++++++
 2 files changed, 133 insertions(+)

New commits:
commit d13e67d7a3591626b165462e42ce77ddbf6dfed2
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Fri Jul 19 11:32:58 2013 -0400

    Add test for shrinking of range references on row/column deletion.
    
    Change-Id: I096aa1aa548f0166c02de5b923d0ab8a710cfd98

diff --git a/sc/qa/unit/ucalc_formula.cxx b/sc/qa/unit/ucalc_formula.cxx
index a902cae..6310297 100644
--- a/sc/qa/unit/ucalc_formula.cxx
+++ b/sc/qa/unit/ucalc_formula.cxx
@@ -467,6 +467,9 @@ void Test::testFormulaRefUpdateRange()
     if (!checkFormula(*m_pDoc, ScAddress(0,7,0), "SUM($B$2:$C$5)"))
         CPPUNIT_FAIL("Wrong formula in A8.");
 
+    CPPUNIT_ASSERT_EQUAL(36.0, m_pDoc->GetValue(ScAddress(0,6,0)));
+    CPPUNIT_ASSERT_EQUAL(36.0, m_pDoc->GetValue(ScAddress(0,7,0)));
+
     // Delete row 3. This should shrink the range references by one row.
     m_pDoc->DeleteRow(ScRange(0,2,0,MAXCOL,2,0));
 
@@ -476,6 +479,95 @@ void Test::testFormulaRefUpdateRange()
     if (!checkFormula(*m_pDoc, ScAddress(0,6,0), "SUM($B$2:$C$4)"))
         CPPUNIT_FAIL("Wrong formula in A7.");
 
+    CPPUNIT_ASSERT_EQUAL(28.0, m_pDoc->GetValue(ScAddress(0,5,0)));
+    CPPUNIT_ASSERT_EQUAL(28.0, m_pDoc->GetValue(ScAddress(0,6,0)));
+
+    // Delete row 4 - bottom of range
+    m_pDoc->DeleteRow(ScRange(0,3,0,MAXCOL,3,0));
+
+    if (!checkFormula(*m_pDoc, ScAddress(0,4,0), "SUM(B2:C3)"))
+        CPPUNIT_FAIL("Wrong formula in A5.");
+
+    if (!checkFormula(*m_pDoc, ScAddress(0,5,0), "SUM($B$2:$C$3)"))
+        CPPUNIT_FAIL("Wrong formula in A6.");
+
+    CPPUNIT_ASSERT_EQUAL(16.0, m_pDoc->GetValue(ScAddress(0,4,0)));
+    CPPUNIT_ASSERT_EQUAL(16.0, m_pDoc->GetValue(ScAddress(0,5,0)));
+
+    // Delete row 2 - top of range
+    m_pDoc->DeleteRow(ScRange(0,1,0,MAXCOL,1,0));
+
+    if (!checkFormula(*m_pDoc, ScAddress(0,3,0), "SUM(B2:C2)"))
+        CPPUNIT_FAIL("Wrong formula in A4.");
+
+    if (!checkFormula(*m_pDoc, ScAddress(0,4,0), "SUM($B$2:$C$2)"))
+        CPPUNIT_FAIL("Wrong formula in A5.");
+
+    CPPUNIT_ASSERT_EQUAL(10.0, m_pDoc->GetValue(ScAddress(0,3,0)));
+    CPPUNIT_ASSERT_EQUAL(10.0, m_pDoc->GetValue(ScAddress(0,4,0)));
+
+    // Clear the range and start over.
+    clearRange(m_pDoc, ScRange(0,0,0,20,20,0));
+
+    // Fill C2:F3 with values.
+    m_pDoc->SetValue(ScAddress(2,1,0), 1);
+    m_pDoc->SetValue(ScAddress(3,1,0), 2);
+    m_pDoc->SetValue(ScAddress(4,1,0), 3);
+    m_pDoc->SetValue(ScAddress(5,1,0), 4);
+    m_pDoc->SetValue(ScAddress(2,2,0), 5);
+    m_pDoc->SetValue(ScAddress(3,2,0), 6);
+    m_pDoc->SetValue(ScAddress(4,2,0), 7);
+    m_pDoc->SetValue(ScAddress(5,2,0), 8);
+
+    // Set formulas to A2 and A3.
+    m_pDoc->SetString(ScAddress(0,1,0), "=SUM(C2:F3)");
+    m_pDoc->SetString(ScAddress(0,2,0), "=SUM($C$2:$F$3)");
+
+    if (!checkFormula(*m_pDoc, ScAddress(0,1,0), "SUM(C2:F3)"))
+        CPPUNIT_FAIL("Wrong formula in A2.");
+
+    if (!checkFormula(*m_pDoc, ScAddress(0,2,0), "SUM($C$2:$F$3)"))
+        CPPUNIT_FAIL("Wrong formula in A3.");
+
+    CPPUNIT_ASSERT_EQUAL(36.0, m_pDoc->GetValue(ScAddress(0,1,0)));
+    CPPUNIT_ASSERT_EQUAL(36.0, m_pDoc->GetValue(ScAddress(0,2,0)));
+
+    // Delete column D.
+    m_pDoc->DeleteCol(ScRange(3,0,0,3,MAXROW,0));
+
+    if (!checkFormula(*m_pDoc, ScAddress(0,1,0), "SUM(C2:E3)"))
+        CPPUNIT_FAIL("Wrong formula in A2.");
+
+    if (!checkFormula(*m_pDoc, ScAddress(0,2,0), "SUM($C$2:$E$3)"))
+        CPPUNIT_FAIL("Wrong formula in A3.");
+
+    CPPUNIT_ASSERT_EQUAL(28.0, m_pDoc->GetValue(ScAddress(0,1,0)));
+    CPPUNIT_ASSERT_EQUAL(28.0, m_pDoc->GetValue(ScAddress(0,2,0)));
+
+    // Delete column E - the right edge of reference range.
+    m_pDoc->DeleteCol(ScRange(4,0,0,4,MAXROW,0));
+
+    if (!checkFormula(*m_pDoc, ScAddress(0,1,0), "SUM(C2:D3)"))
+        CPPUNIT_FAIL("Wrong formula in A2.");
+
+    if (!checkFormula(*m_pDoc, ScAddress(0,2,0), "SUM($C$2:$D$3)"))
+        CPPUNIT_FAIL("Wrong formula in A3.");
+
+    CPPUNIT_ASSERT_EQUAL(16.0, m_pDoc->GetValue(ScAddress(0,1,0)));
+    CPPUNIT_ASSERT_EQUAL(16.0, m_pDoc->GetValue(ScAddress(0,2,0)));
+
+    // Delete column C - the left edge of reference range.
+    m_pDoc->DeleteCol(ScRange(2,0,0,2,MAXROW,0));
+
+    if (!checkFormula(*m_pDoc, ScAddress(0,1,0), "SUM(C2:C3)"))
+        CPPUNIT_FAIL("Wrong formula in A2.");
+
+    if (!checkFormula(*m_pDoc, ScAddress(0,2,0), "SUM($C$2:$C$3)"))
+        CPPUNIT_FAIL("Wrong formula in A3.");
+
+    CPPUNIT_ASSERT_EQUAL(10.0, m_pDoc->GetValue(ScAddress(0,1,0)));
+    CPPUNIT_ASSERT_EQUAL(10.0, m_pDoc->GetValue(ScAddress(0,2,0)));
+
     m_pDoc->DeleteTab(0);
 }
 
commit 1ac273fdd9805ba3536d5f67fed7269a1581d1f9
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Fri Jul 19 11:31:12 2013 -0400

    Handle shrinking of range references on row/column deletion.
    
    Change-Id: Id53de2b24e02f6d8a078dceadf2d8399a0348b72

diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index 2d1a236..981e898 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -2248,6 +2248,37 @@ void setRefDeleted( ScComplexRefData& rRef, const sc::RefUpdateContext& rCxt )
     }
 }
 
+bool shrinkRange( const sc::RefUpdateContext& rCxt, ScRange& rRefRange, const ScRange& rDeletedRange )
+{
+    if (rCxt.mnColDelta < 0)
+    {
+        // Shifting left.
+        if (rRefRange.aStart.Row() < rDeletedRange.aStart.Row() || rDeletedRange.aEnd.Row() < rRefRange.aEnd.Row())
+            // Deleted range is only partially overlapping in vertical direction. Bail out.
+            return false;
+
+        // Move the last column position to the left.
+        SCCOL nDelta = rDeletedRange.aStart.Col() - rDeletedRange.aEnd.Col() - 1;
+        rRefRange.aEnd.IncCol(nDelta);
+        return true;
+    }
+    else if (rCxt.mnRowDelta < 0)
+    {
+        // Shifting up.
+
+        if (rRefRange.aStart.Col() < rDeletedRange.aStart.Col() || rDeletedRange.aEnd.Col() < rRefRange.aEnd.Col())
+            // Deleted range is only partially overlapping in horizontal direction. Bail out.
+            return false;
+
+        // Move the last row position up.
+        SCROW nDelta = rDeletedRange.aStart.Row() - rDeletedRange.aEnd.Row() - 1;
+        rRefRange.aEnd.IncRow(nDelta);
+        return true;
+    }
+
+    return false;
+}
+
 }
 
 sc::RefUpdateResult ScTokenArray::AdjustReferenceOnShift( const sc::RefUpdateContext& rCxt, const ScAddress& rOldPos )
@@ -2298,6 +2329,16 @@ sc::RefUpdateResult ScTokenArray::AdjustReferenceOnShift( const sc::RefUpdateCon
                     aRes.mbValueChanged = true;
                     break;
                 }
+                else if (aDeletedRange.Intersects(aAbs))
+                {
+                    if (shrinkRange(rCxt, aAbs, aDeletedRange))
+                    {
+                        // The reference range has been shrunk.
+                        rRef.SetRange(aAbs, aNewPos);
+                        aRes.mbValueChanged = true;
+                        break;
+                    }
+                }
 
                 if (rCxt.maRange.In(aAbs))
                     aAbs.Move(rCxt.mnColDelta, rCxt.mnRowDelta, rCxt.mnTabDelta);


More information about the Libreoffice-commits mailing list