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

Kohei Yoshida kohei.yoshida at gmail.com
Wed Jul 3 17:33:50 PDT 2013


 sc/qa/unit/ucalc.cxx            |   66 +++++++++++++++++++++++++++++------
 sc/source/core/data/column3.cxx |   75 ++++++++++++++++++++++++----------------
 2 files changed, 102 insertions(+), 39 deletions(-)

New commits:
commit 0505e1abb5e5a91165594ecd9551e1c606076d2c
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Wed Jul 3 19:32:31 2013 -0400

    More test on shared formula group adjustment on value insertions.
    
    Change-Id: Icaa48ef790cd71abdfc1d026ac912a88f727c0d5

diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index 6221b62..d29aa89 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -54,6 +54,7 @@
 #include "tokenarray.hxx"
 #include "scopetools.hxx"
 #include "dociter.hxx"
+#include "editutil.hxx"
 
 #include "formula/IFunctionDescription.hxx"
 
@@ -6434,6 +6435,38 @@ void Test::testSharedFormulas()
     CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(14), pFC->GetSharedTopRow());
     CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(4), pFC->GetSharedLength());
 
+    // Set numeric value to B15, to make B16:B18 shared.
+    aPos.SetRow(14);
+    m_pDoc->SetValue(aPos, 1.2);
+    aPos.SetRow(15);
+    pFC = m_pDoc->GetFormulaCell(aPos);
+    // B16:B18 should be shared.
+    CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(15), pFC->GetSharedTopRow());
+    CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(3), pFC->GetSharedLength());
+
+    // Set string value to B16 to make B17:B18 shared.
+    aPos.SetRow(15);
+    ScCellValue aCell("Test");
+    CPPUNIT_ASSERT_MESSAGE("This should be a string value.", aCell.meType == CELLTYPE_STRING);
+    aCell.commit(*m_pDoc, aPos);
+    CPPUNIT_ASSERT_EQUAL(*aCell.mpString, m_pDoc->GetString(aPos));
+    aPos.SetRow(16);
+    pFC = m_pDoc->GetFormulaCell(aPos);
+    // B17:B18 should be shared.
+    CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(16), pFC->GetSharedTopRow());
+    CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(2), pFC->GetSharedLength());
+
+    // Set edit text to B17. Now B18 should be non-shared.
+    ScFieldEditEngine& rEditEngine = m_pDoc->GetEditEngine();
+    rEditEngine.SetText("Edit Text");
+    aPos.SetRow(16);
+    m_pDoc->SetEditText(aPos, rEditEngine.CreateTextObject());
+    CPPUNIT_ASSERT_EQUAL(CELLTYPE_EDIT, m_pDoc->GetCellType(aPos));
+    aPos.SetRow(17);
+    pFC = m_pDoc->GetFormulaCell(aPos);
+    CPPUNIT_ASSERT_MESSAGE("B18 should be a formula cell.", pFC);
+    CPPUNIT_ASSERT_MESSAGE("B18 should be non-shared.", !pFC->IsShared());
+
     m_pDoc->DeleteTab(0);
 }
 
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index aa9fb88..38dbd15 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -1764,7 +1764,6 @@ void ScColumn::SetEditText( SCROW nRow, EditTextObject* pEditText )
     sc::CellStoreType::iterator it = GetPositionToInsert(nRow);
     maCells.set(it, nRow, pEditText);
     maCellTextAttrs.set(nRow, sc::CellTextAttr());
-    RegroupFormulaCells(nRow);
     CellStorageModified();
 
     BroadcastNewCell(nRow);
@@ -1776,7 +1775,6 @@ void ScColumn::SetEditText( sc::ColumnBlockPosition& rBlockPos, SCROW nRow, Edit
     rBlockPos.miCellPos = maCells.set(rBlockPos.miCellPos, nRow, pEditText);
     rBlockPos.miCellTextAttrPos = maCellTextAttrs.set(
         rBlockPos.miCellTextAttrPos, nRow, sc::CellTextAttr());
-    RegroupFormulaCells(nRow);
     CellStorageModified();
 
     BroadcastNewCell(nRow);
@@ -2286,7 +2284,6 @@ void ScColumn::SetError( SCROW nRow, const sal_uInt16 nError)
     sc::CellStoreType::iterator it = GetPositionToInsert(nRow);
     it = maCells.set(it, nRow, pCell);
     maCellTextAttrs.set(nRow, sc::CellTextAttr());
-    RegroupFormulaCells(nRow);
     CellStorageModified();
 
     ActivateNewFormulaCell(it, nRow, *pCell);
@@ -2300,7 +2297,6 @@ void ScColumn::SetRawString( SCROW nRow, const OUString& rStr, bool bBroadcast )
     sc::CellStoreType::iterator it = GetPositionToInsert(nRow);
     maCells.set(it, nRow, rStr);
     maCellTextAttrs.set(nRow, sc::CellTextAttr());
-    RegroupFormulaCells(nRow);
     CellStorageModified();
 
     if (bBroadcast)
@@ -2317,7 +2313,6 @@ void ScColumn::SetRawString(
     rBlockPos.miCellPos = maCells.set(rBlockPos.miCellPos, nRow, rStr);
     rBlockPos.miCellTextAttrPos = maCellTextAttrs.set(
         rBlockPos.miCellTextAttrPos, nRow, sc::CellTextAttr());
-    RegroupFormulaCells(nRow);
     CellStorageModified();
 
     if (bBroadcast)
@@ -2332,7 +2327,6 @@ void ScColumn::SetValue( SCROW nRow, double fVal )
     sc::CellStoreType::iterator it = GetPositionToInsert(nRow);
     maCells.set(it, nRow, fVal);
     maCellTextAttrs.set(nRow, sc::CellTextAttr());
-    RegroupFormulaCells(nRow);
     CellStorageModified();
 
     BroadcastNewCell(nRow);
@@ -2348,7 +2342,6 @@ void ScColumn::SetValue(
     rBlockPos.miCellPos = maCells.set(rBlockPos.miCellPos, nRow, fVal);
     rBlockPos.miCellTextAttrPos = maCellTextAttrs.set(
         rBlockPos.miCellTextAttrPos, nRow, sc::CellTextAttr());
-    RegroupFormulaCells(nRow);
     CellStorageModified();
 
     if (bBroadcast)
commit 52c004ba30b4d084e1cff934d17d6a3ad52a63fa
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Wed Jul 3 18:51:59 2013 -0400

    Adjust formula cell grouping on cell deletion without shifting.
    
    Change-Id: I4dad09faf10406163b5944933422d50b832f45bc

diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index c7eda91..6221b62 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -6401,25 +6401,38 @@ void Test::testSharedFormulas()
     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());
+    // B13:B20 shuld be shared.
     CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(12), pFC->GetSharedTopRow());
     CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(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);
-
+    // Empty B19. This should split it into B13:B18, and B20 non-shared.
+    aPos.SetRow(18);
+    m_pDoc->SetEmptyCell(aPos);
+    CPPUNIT_ASSERT_MESSAGE("This cell should have been emptied.", m_pDoc->GetCellType(aPos) == CELLTYPE_NONE);
     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());
+    // B13:B18 should be shared.
     CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(12), pFC->GetSharedTopRow());
-    CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(3), pFC->GetSharedLength());
+    CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(6), pFC->GetSharedLength());
+    // B20 shold be non-shared.
+    aPos.SetRow(19); // B20
+    pFC = m_pDoc->GetFormulaCell(aPos);
+    CPPUNIT_ASSERT_MESSAGE("B20 should be a formula cell.", pFC);
+    CPPUNIT_ASSERT_MESSAGE("This cell should be non-shared.", !pFC->IsShared());
 
-    aPos.SetRow(23); // B24
+    // Empty B14, to make B13 non-shared and B15:B18 shared.
+    aPos.SetRow(13); // B14
+    m_pDoc->SetEmptyCell(aPos);
+    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(static_cast<SCROW>(20), pFC->GetSharedTopRow());
-    CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(5), pFC->GetSharedLength());
-#endif
+    // B13 should be non-shared.
+    CPPUNIT_ASSERT_MESSAGE("B13 should be a formula cell.", pFC);
+    CPPUNIT_ASSERT_MESSAGE("This cell should be non-shared.", !pFC->IsShared());
+    // B15:B18 should be shared.
+    aPos.SetRow(14); // B15
+    pFC = m_pDoc->GetFormulaCell(aPos);
+    CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(14), pFC->GetSharedTopRow());
+    CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(4), pFC->GetSharedLength());
 
     m_pDoc->DeleteTab(0);
 }
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index ee200f5..aa9fb88 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -131,16 +131,16 @@ void ScColumn::InterpretDirtyCells( SCROW nRow1, SCROW nRow2 )
 
 void ScColumn::Delete( SCROW nRow )
 {
-    std::pair<sc::CellStoreType::iterator,size_t> aPos = maCells.position(nRow);
+    sc::CellStoreType::position_type aPos = maCells.position(nRow);
     sc::CellStoreType::iterator it = aPos.first;
     if (it == maCells.end())
         return;
 
-    bool bFormulaCell = it->type == sc::element_type_formula;
-    if (bFormulaCell)
+    if (it->type == sc::element_type_formula)
     {
         ScFormulaCell* p = sc::formula_block::at(*it->data, aPos.second);
         p->EndListeningTo(pDocument);
+        UnshareFormulaCell(aPos, *p);
     }
     maCells.set_empty(nRow, nRow);
     maCellTextAttrs.set_empty(nRow, nRow);
@@ -148,9 +148,6 @@ void ScColumn::Delete( SCROW nRow )
     pDocument->Broadcast(
         ScHint(SC_HINT_DATACHANGED, ScAddress(nCol, nRow, nTab)));
 
-    if (bFormulaCell)
-        RegroupFormulaCells(nRow);
-
     CellStorageModified();
 }
 
@@ -474,27 +471,54 @@ void ScColumn::UnshareFormulaCell(
         ScFormulaCellGroupRef xGroup = rCell.GetCellGroup();
         SCROW nEndRow = xGroup->mnStart + xGroup->mnLength - 1;
         xGroup->mnLength = rCell.aPos.Row() - xGroup->mnStart; // Shorten the top group.
-
-        ScFormulaCellGroupRef xGroup2(new ScFormulaCellGroup);
-        xGroup2->mnStart = rCell.aPos.Row() + 1;
-        xGroup2->mnLength = nEndRow - rCell.aPos.Row();
-        xGroup2->mbInvariant = xGroup->mbInvariant;
-#if DEBUG_COLUMN_STORAGE
-        if (xGroup2->mnStart + xGroup2->mnLength > it->position + it->size)
+        if (xGroup->mnLength == 1)
         {
-            cerr << "ScColumn::UnshareFormulaCell: Shared formula region goes beyond the formula block. Not good." << endl;
-            cerr.flush();
-            abort();
+            // Make the top cell non-shared.
+#if DEBUG_COLUMN_STORAGE
+            if (aPos.second == 0)
+            {
+                cerr << "ScColumn::UnshareFormulaCell: There is no previous formula cell but there should be!" << endl;
+                cerr.flush();
+                abort();
+            }
+#endif
+            ScFormulaCell& rPrev = *sc::formula_block::at(*it->data, aPos.second-1);
+            rPrev.SetCellGroup(xNone);
         }
+
+        SCROW nLength2 = nEndRow - rCell.aPos.Row();
+        if (nLength2 >= 2)
+        {
+            ScFormulaCellGroupRef xGroup2;
+            xGroup2.reset(new ScFormulaCellGroup);
+            xGroup2->mnStart = rCell.aPos.Row() + 1;
+            xGroup2->mnLength = nLength2;
+            xGroup2->mbInvariant = xGroup->mbInvariant;
+#if DEBUG_COLUMN_STORAGE
+            if (xGroup2->mnStart + xGroup2->mnLength > it->position + it->size)
+            {
+                cerr << "ScColumn::UnshareFormulaCell: Shared formula region goes beyond the formula block. Not good." << endl;
+                cerr.flush();
+                abort();
+            }
 #endif
-        sc::formula_block::iterator itCell = sc::formula_block::begin(*it->data);
-        std::advance(itCell, aPos.second+1);
-        sc::formula_block::iterator itCellEnd = itCell;
-        std::advance(itCellEnd, xGroup2->mnLength);
-        for (; itCell != itCellEnd; ++itCell)
+            sc::formula_block::iterator itCell = sc::formula_block::begin(*it->data);
+            std::advance(itCell, aPos.second+1);
+            sc::formula_block::iterator itCellEnd = itCell;
+            std::advance(itCellEnd, xGroup2->mnLength);
+            for (; itCell != itCellEnd; ++itCell)
+            {
+                ScFormulaCell& rCell2 = **itCell;
+                rCell2.SetCellGroup(xGroup2);
+            }
+        }
+        else
         {
+            // Make the next cell non-shared.
+            sc::formula_block::iterator itCell = sc::formula_block::begin(*it->data);
+            std::advance(itCell, aPos.second+1);
             ScFormulaCell& rCell2 = **itCell;
-            rCell2.SetCellGroup(xGroup2);
+            rCell2.SetCellGroup(xNone);
         }
     }
 


More information about the Libreoffice-commits mailing list