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

Kohei Yoshida kohei.yoshida at gmail.com
Wed Jul 3 19:46:28 PDT 2013


 sc/qa/unit/ucalc.cxx            |   42 ++++++++++++++++++++++++++++++++++++++++
 sc/source/core/data/column.cxx  |    1 
 sc/source/core/data/column3.cxx |   32 ++++++++++++++++++++++--------
 3 files changed, 66 insertions(+), 9 deletions(-)

New commits:
commit da05371a0ead3feff4b9fc237a80f5b2307cf6cd
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Wed Jul 3 22:48:31 2013 -0400

    Adjust formula grouping on range deletion.
    
    Change-Id: Id3c2cd0a3cffa299c8424f9c9e4989ce8bd60719

diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index d29aa89..baf957f 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -6467,7 +6467,49 @@ void Test::testSharedFormulas()
     CPPUNIT_ASSERT_MESSAGE("B18 should be a formula cell.", pFC);
     CPPUNIT_ASSERT_MESSAGE("B18 should be non-shared.", !pFC->IsShared());
 
+    // Set up a new group for shared formulas in B2:B10.
+    clearRange(m_pDoc, ScRange(0,0,0,2,100,0));
+
+    aPos.SetRow(1);
+    m_pDoc->SetString(aPos, "=A2*10");
+    aPos.IncRow();
+    m_pDoc->SetString(aPos, "=A3*10");
+    aPos.IncRow();
+    m_pDoc->SetString(aPos, "=A4*10");
+    aPos.IncRow();
+    m_pDoc->SetString(aPos, "=A5*10");
+    aPos.IncRow();
+    m_pDoc->SetString(aPos, "=A6*10");
+    aPos.IncRow();
+    m_pDoc->SetString(aPos, "=A7*10");
+    aPos.IncRow();
+    m_pDoc->SetString(aPos, "=A8*10");
+    aPos.IncRow();
+    m_pDoc->SetString(aPos, "=A9*10");
+    aPos.IncRow();
+    m_pDoc->SetString(aPos, "=A10*10");
+
+    pFC = m_pDoc->GetFormulaCell(aPos);
+    CPPUNIT_ASSERT_MESSAGE("B10 should be a formula cell.", pFC);
+    CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(1), pFC->GetSharedTopRow());
+    CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(9), pFC->GetSharedLength());
+
+    // Delete A4:B8. This should splite the grouping to B2:B3 and B9:B10.
+    clearRange(m_pDoc, ScRange(0,3,0,1,7,0));
+    aPos.SetRow(1);
+    pFC = m_pDoc->GetFormulaCell(aPos);
+    CPPUNIT_ASSERT_MESSAGE("B2 should be a formula cell.", pFC);
+    CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(1), pFC->GetSharedTopRow());
+    CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(2), pFC->GetSharedLength());
+
+    aPos.SetRow(8);
+    pFC = m_pDoc->GetFormulaCell(aPos);
+    CPPUNIT_ASSERT_MESSAGE("B9 should be a formula cell.", pFC);
+    CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(8), pFC->GetSharedTopRow());
+    CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(2), pFC->GetSharedLength());
+
     m_pDoc->DeleteTab(0);
+
 }
 
 namespace {
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index 68f7aa3..bdfde88 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -2808,7 +2808,6 @@ void ScColumn::UpdateCompile( bool bForceIfNameInUse )
 {
     UpdateCompileHandler aFunc(bForceIfNameInUse);
     sc::ProcessFormula(maCells, aFunc);
-    RegroupFormulaCells();
 }
 
 
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index 38dbd15..203bb96 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -739,17 +739,33 @@ class EmptyCells
     ScColumn& mrColumn;
     sc::ColumnBlockPosition& mrPos;
     sc::CellStoreType::iterator miPos;
-    sc::CellStoreType& mrCells;
-    sc::CellTextAttrStoreType& mrAttrs;
+
+    void splitFormulaGrouping(sc::CellStoreType& rCells, const sc::CellStoreType::position_type& rPos)
+    {
+        if (rPos.first->type == sc::element_type_formula)
+        {
+            ScFormulaCell& rCell = *sc::formula_block::at(*rPos.first->data, rPos.second);
+            mrColumn.UnshareFormulaCell(rPos, rCell);
+        }
+    }
+
 public:
-    EmptyCells(sc::ColumnBlockPosition& rPos, ScColumn& rColumn, sc::CellStoreType& rCells, sc::CellTextAttrStoreType& rAttrs) :
-        mrColumn(rColumn), mrPos(rPos), mrCells(rCells), mrAttrs(rAttrs) {}
+    EmptyCells(sc::ColumnBlockPosition& rPos, ScColumn& rColumn) :
+        mrColumn(rColumn), mrPos(rPos) {}
 
     void operator() (const sc::SingleColumnSpanSet::Span& rSpan)
     {
-        mrPos.miCellPos = mrCells.set_empty(mrPos.miCellPos, rSpan.mnRow1, rSpan.mnRow2);
-        mrPos.miCellTextAttrPos = mrAttrs.set_empty(mrPos.miCellTextAttrPos, rSpan.mnRow1, rSpan.mnRow2);
-        mrColumn.RegroupFormulaCells(rSpan.mnRow1, rSpan.mnRow2);
+        sc::CellStoreType& rCells = mrColumn.GetCellStore();
+
+        // First, split formula grouping at the top and bottom boundaries
+        // before emptying the cells.
+        sc::CellStoreType::position_type aPos = rCells.position(mrPos.miCellPos, rSpan.mnRow1);
+        splitFormulaGrouping(rCells, aPos);
+        aPos = rCells.position(aPos.first, rSpan.mnRow2);
+        splitFormulaGrouping(rCells, aPos);
+
+        mrPos.miCellPos = rCells.set_empty(mrPos.miCellPos, rSpan.mnRow1, rSpan.mnRow2);
+        mrPos.miCellTextAttrPos = mrColumn.GetCellAttrStore().set_empty(mrPos.miCellTextAttrPos, rSpan.mnRow1, rSpan.mnRow2);
     }
 };
 
@@ -783,7 +799,7 @@ void ScColumn::DeleteArea(SCROW nStartRow, SCROW nEndRow, sal_uInt16 nDelFlag)
         aBlockPos.miCellTextAttrPos = maCellTextAttrs.begin();
 
         // Delete the cells for real.
-        std::for_each(aSpans.begin(), aSpans.end(), EmptyCells(aBlockPos, *this, maCells, maCellTextAttrs));
+        std::for_each(aSpans.begin(), aSpans.end(), EmptyCells(aBlockPos, *this));
         CellStorageModified();
     }
 


More information about the Libreoffice-commits mailing list