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

Kohei Yoshida kohei.yoshida at gmail.com
Wed Jun 26 18:49:08 PDT 2013


 sc/inc/column.hxx               |    7 +++++
 sc/qa/unit/ucalc.cxx            |   31 ++++++++++++++++++++++
 sc/source/core/data/column.cxx  |   10 +------
 sc/source/core/data/column3.cxx |   56 +++++++++++++++++++++++++++++++++++++---
 4 files changed, 93 insertions(+), 11 deletions(-)

New commits:
commit a6f996db16bc6a84d28dde7aef15a23536f8f0b2
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Wed Jun 26 21:50:38 2013 -0400

    More on shared formula cell handling.
    
    Change-Id: Ifb0feff8c7016e3cadfa219ea6421852112ca189

diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 5354a07..c0dea00 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -469,6 +469,13 @@ public:
     void UnshareFormulaCell( const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell ) const;
 
     /**
+     * Split existing shared formula range at specified position. The cell at
+     * specified position becomes the top cell of the lower shared formula
+     * range after this call.
+     */
+    void SplitFormulaCellGroup( const sc::CellStoreType::position_type& aPos ) const;
+
+    /**
      * Regroup formula cells for the entire column.
      */
     void RegroupFormulaCells();
diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index 5286965..36c3628 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -6369,6 +6369,37 @@ void Test::testSharedFormulas()
     CPPUNIT_ASSERT_EQUAL(12, pFC->GetSharedTopRow());
     CPPUNIT_ASSERT_EQUAL(4, pFC->GetSharedLength());
 
+    // Extend B13:B16 to B13:B20.
+    aPos.SetRow(16); // B17
+    m_pDoc->SetString(aPos, "=A17*2");
+    aPos.IncRow();
+    m_pDoc->SetString(aPos, "=A18*2");
+    aPos.IncRow();
+    m_pDoc->SetString(aPos, "=A19*2");
+    aPos.IncRow();
+    m_pDoc->SetString(aPos, "=A20*2");
+    pFC = m_pDoc->GetFormulaCell(aPos);
+    CPPUNIT_ASSERT_MESSAGE("This cell is expected to be a shared formula cell.", pFC && pFC->IsShared());
+    CPPUNIT_ASSERT_EQUAL(12, pFC->GetSharedTopRow());
+    CPPUNIT_ASSERT_EQUAL(8, pFC->GetSharedLength());
+
+#if 0
+    // Insert empty rows at B16 to split B13:B20 into B13:B15 and B21:B25.
+    m_pDoc->InsertRow(1, 0, 1, 0, 15, 5);
+
+    aPos.SetRow(12); // B13
+    pFC = m_pDoc->GetFormulaCell(aPos);
+    CPPUNIT_ASSERT_MESSAGE("This cell is expected to be a shared formula cell.", pFC && pFC->IsShared());
+    CPPUNIT_ASSERT_EQUAL(12, pFC->GetSharedTopRow());
+    CPPUNIT_ASSERT_EQUAL(3, pFC->GetSharedLength());
+
+    aPos.SetRow(23); // B24
+    pFC = m_pDoc->GetFormulaCell(aPos);
+    CPPUNIT_ASSERT_MESSAGE("This cell is expected to be a shared formula cell.", pFC && pFC->IsShared());
+    CPPUNIT_ASSERT_EQUAL(20, pFC->GetSharedTopRow());
+    CPPUNIT_ASSERT_EQUAL(5, pFC->GetSharedLength());
+#endif
+
     m_pDoc->DeleteTab(0);
 }
 
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index 3918cd2..de330f5 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -1233,10 +1233,7 @@ void ScColumn::InsertRow( SCROW nStartRow, SCSIZE nSize )
     maCellTextAttrs.insert_empty(nStartRow, nSize);
     maCellTextAttrs.resize(MAXROWCOUNT);
 
-    // Check if this insertion will split an existing formula block.
     sc::CellStoreType::position_type aPos = maCells.position(nStartRow);
-    bool bSplitFormulaBlock = aPos.second != 0;
-
     sc::CellStoreType::iterator it = maCells.insert_empty(aPos.first, nStartRow, nSize);
     maCells.resize(MAXROWCOUNT);
 
@@ -1254,8 +1251,8 @@ void ScColumn::InsertRow( SCROW nStartRow, SCSIZE nSize )
         std::advance(itf, aPos.second);
         for (; itf != itfEnd; ++itf)
         {
-            ScFormulaCell* pCell = *itf;
-            pCell->aPos.IncRow(nSize);
+            ScFormulaCell& rCell = **itf;
+            rCell.aPos.IncRow(nSize);
         }
     }
 
@@ -1273,9 +1270,6 @@ void ScColumn::InsertRow( SCROW nStartRow, SCSIZE nSize )
         }
     }
 
-    if (bSplitFormulaBlock)
-        RegroupFormulaCells(nStartRow, nStartRow+nSize-1);
-
     CellStorageModified();
 
     // We *probably* don't need to broadcast here since the parent call seems
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index ff152ff..16d4ada 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -429,7 +429,7 @@ void ScColumn::UnshareFormulaCell(
 #if DEBUG_COLUMN_STORAGE
             if (aPos.second+1 >= aPos.first->size)
             {
-                cerr << "ScColumn::GetPositionToInsert: There is no next formula cell but there should be!" << endl;
+                cerr << "ScColumn::UnshareFormulaCell: There is no next formula cell but there should be!" << endl;
                 cerr.flush();
                 abort();
             }
@@ -454,7 +454,7 @@ void ScColumn::UnshareFormulaCell(
 #if DEBUG_COLUMN_STORAGE
             if (aPos.second == 0)
             {
-                cerr << "ScColumn::GetPositionToInsert: There is no previous formula cell but there should be!" << endl;
+                cerr << "ScColumn::UnshareFormulaCell: There is no previous formula cell but there should be!" << endl;
                 cerr.flush();
                 abort();
             }
@@ -482,7 +482,7 @@ void ScColumn::UnshareFormulaCell(
 #if DEBUG_COLUMN_STORAGE
         if (xGroup2->mnStart + xGroup2->mnLength > it->position + it->size)
         {
-            cerr << "ScColumn::GetPositionToInsert: Shared formula region goes beyond the formula block. Not good." << endl;
+            cerr << "ScColumn::UnshareFormulaCell: Shared formula region goes beyond the formula block. Not good." << endl;
             cerr.flush();
             abort();
         }
@@ -501,6 +501,56 @@ void ScColumn::UnshareFormulaCell(
     rCell.SetCellGroup(xNone);
 }
 
+void ScColumn::SplitFormulaCellGroup( const sc::CellStoreType::position_type& aPos ) const
+{
+    SCROW nRow = aPos.first->position + aPos.second;
+
+    if (aPos.first->type != sc::element_type_formula)
+        // Not a formula cell block.
+        return;
+
+    if (aPos.second == 0)
+        // Split position coincides with the block border. Nothing to do.
+        return;
+
+    sc::formula_block::iterator it = sc::formula_block::begin(*aPos.first->data);
+    std::advance(it, aPos.second);
+    ScFormulaCell& rTop = **it;
+    if (!rTop.IsShared())
+        // Not a shared formula.
+        return;
+
+    if (nRow == rTop.GetSharedTopRow())
+        // Already the top cell of a shared group.
+        return;
+
+    ScFormulaCellGroupRef xGroup = rTop.GetCellGroup();
+
+    ScFormulaCellGroupRef xGroup2(new ScFormulaCellGroup);
+    xGroup2->mbInvariant = xGroup->mbInvariant;
+    xGroup2->mnStart = nRow;
+    xGroup2->mnLength = xGroup->mnStart + xGroup->mnLength - nRow;
+
+    xGroup->mnLength = nRow - xGroup->mnStart;
+
+    // Apply the lower group object to the lower cells.
+#if DEBUG_COLUMN_STORAGE
+        if (xGroup2->mnStart + xGroup2->mnLength > aPos.first->position + aPos.first->size)
+        {
+            cerr << "ScColumn::SplitFormulaCellGroup: Shared formula region goes beyond the formula block. Not good." << endl;
+            cerr.flush();
+            abort();
+        }
+#endif
+    sc::formula_block::iterator itEnd = it;
+    std::advance(itEnd, xGroup2->mnLength);
+    for (; it != itEnd; ++it)
+    {
+        ScFormulaCell& rCell = **it;
+        rCell.SetCellGroup(xGroup2);
+    }
+}
+
 sc::CellStoreType::iterator ScColumn::GetPositionToInsert( const sc::CellStoreType::iterator& it, SCROW nRow )
 {
     // See if we are overwriting an existing formula cell.


More information about the Libreoffice-commits mailing list