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

Kohei Yoshida kohei.yoshida at gmail.com
Wed Jun 26 16:15:33 PDT 2013


 sc/inc/column.hxx               |   16 +-
 sc/source/core/data/column.cxx  |   99 +++++++++-------
 sc/source/core/data/column3.cxx |  245 +++++++++++++++++++++-------------------
 3 files changed, 203 insertions(+), 157 deletions(-)

New commits:
commit 1a61dd41f2ad03ea49658ddc427a331368d9aad2
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Wed Jun 26 19:16:45 2013 -0400

    Handle formula cells in SwapCell().
    
    Change-Id: I9ddc69793e70bd399b93ce472a38060b1a946ff9

diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index 876dc3b..3918cd2 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -1129,26 +1129,43 @@ void updateRefInFormulaCell( ScFormulaCell& rCell, SCCOL nCol, SCTAB nTab, SCCOL
 
 void ScColumn::SwapCell( SCROW nRow, ScColumn& rCol)
 {
-    ScFormulaCell* pCell1 = maCells.get<ScFormulaCell*>(nRow);
-    ScFormulaCell* pCell2 = rCol.maCells.get<ScFormulaCell*>(nRow);
-    if (pCell1)
-        updateRefInFormulaCell(*pCell1, rCol.nCol, nTab, rCol.nCol - nCol);
+    sc::CellStoreType::position_type aPos1 = maCells.position(nRow);
+    sc::CellStoreType::position_type aPos2 = rCol.maCells.position(nRow);
 
-    if (pCell2)
-        updateRefInFormulaCell(*pCell2, nCol, nTab, nCol - rCol.nCol);
+    if (aPos1.first->type == sc::element_type_formula)
+    {
+        ScFormulaCell& rCell = *sc::formula_block::at(*aPos1.first->data, aPos1.second);
+        updateRefInFormulaCell(rCell, rCol.nCol, nTab, rCol.nCol - nCol);
+        UnshareFormulaCell(aPos1, rCell);
+    }
+
+    if (aPos2.first->type == sc::element_type_formula)
+    {
+        ScFormulaCell& rCell = *sc::formula_block::at(*aPos2.first->data, aPos2.second);
+        updateRefInFormulaCell(rCell, nCol, nTab, nCol - rCol.nCol);
+        UnshareFormulaCell(aPos2, rCell);
+    }
 
     maCells.swap(nRow, nRow, rCol.maCells, nRow);
     maCellTextAttrs.swap(nRow, nRow, rCol.maCellTextAttrs, nRow);
 
-    CellStorageModified();
-    rCol.CellStorageModified();
+    aPos1 = maCells.position(nRow);
+    aPos2 = rCol.maCells.position(nRow);
 
-    if (pCell1 || pCell2)
+    if (aPos1.first->type == sc::element_type_formula)
     {
-        // At least one of the two cells is a formula cell. Regroup them.
-        RegroupFormulaCells(nRow);
-        rCol.RegroupFormulaCells(nRow);
+        ScFormulaCell& rCell = *sc::formula_block::at(*aPos1.first->data, aPos1.second);
+        JoinNewFormulaCell(aPos1, rCell);
     }
+
+    if (aPos2.first->type == sc::element_type_formula)
+    {
+        ScFormulaCell& rCell = *sc::formula_block::at(*aPos2.first->data, aPos2.second);
+        rCol.JoinNewFormulaCell(aPos2, rCell);
+    }
+
+    CellStorageModified();
+    rCol.CellStorageModified();
 }
 
 
commit 566f2948d9c692d876470068b49dc56586e5da8e
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Wed Jun 26 18:59:57 2013 -0400

    Proper handling of formula cells in SwapRow().
    
    Change-Id: Id295160b69cc5cb40cd9e0403928dac8b0e58807

diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 2e1f0f1..5354a07 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -147,8 +147,7 @@ public:
     const sc::CellTextAttrStoreType& GetCellAttrStore() const { return maCellTextAttrs; }
 
     ScRefCellValue GetCellValue( SCROW nRow ) const;
-    ScRefCellValue GetCellValue( sc::CellStoreType::const_iterator& itPos, SCROW nRow ) const;
-    ScRefCellValue GetCellValue( sc::CellStoreType::const_iterator& itPos, size_t nOffset ) const;
+    ScRefCellValue GetCellValue( const sc::CellStoreType::const_iterator& itPos, size_t nOffset ) const;
 
     void        Delete( SCROW nRow );
     void        FreeAll();
@@ -461,6 +460,12 @@ public:
 
     void JoinNewFormulaCell( const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell ) const;
 
+    /**
+     * Detouch a formula cell that's about to be deleted, or removed from
+     * document storage (if that ever happens).
+     */
+    void DetouchFormulaCell( const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell ) const;
+
     void UnshareFormulaCell( const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell ) const;
 
     /**
@@ -490,6 +495,7 @@ private:
     sc::CellStoreType::iterator GetPositionToInsert( SCROW nRow );
     sc::CellStoreType::iterator GetPositionToInsert( const sc::CellStoreType::iterator& it, SCROW nRow );
     void ActivateNewFormulaCell( const sc::CellStoreType::iterator& itPos, SCROW nRow, ScFormulaCell& rCell );
+    void ActivateNewFormulaCell( const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell );
     void BroadcastNewCell( SCROW nRow );
     bool UpdateScriptType( sc::CellTextAttr& rAttr, SCROW nRow );
 
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index f3fb8cf..876dc3b 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -763,17 +763,7 @@ ScRefCellValue ScColumn::GetCellValue( SCROW nRow ) const
     return GetCellValue(aPos.first, aPos.second);
 }
 
-ScRefCellValue ScColumn::GetCellValue( sc::CellStoreType::const_iterator& itPos, SCROW nRow ) const
-{
-    std::pair<sc::CellStoreType::const_iterator,size_t> aPos = maCells.position(itPos, nRow);
-    itPos = aPos.first;
-    if (aPos.first == maCells.end())
-        return ScRefCellValue();
-
-    return GetCellValue(itPos, aPos.second);
-}
-
-ScRefCellValue ScColumn::GetCellValue( sc::CellStoreType::const_iterator& itPos, size_t nOffset ) const
+ScRefCellValue ScColumn::GetCellValue( const sc::CellStoreType::const_iterator& itPos, size_t nOffset ) const
 {
     ScRefCellValue aVal; // Defaults to empty cell.
     switch (itPos->type)
@@ -820,8 +810,6 @@ ScFormulaCell* cloneFormulaCell(ScDocument* pDoc, const ScAddress& rNewPos, ScFo
 
 void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
 {
-    typedef std::pair<sc::CellStoreType::iterator,size_t> CellPosType;
-
     if (nRow1 == nRow2)
         // Nothing to swap.
         return;
@@ -832,11 +820,11 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
 
     // Broadcasters (if exist) should NOT be swapped.
 
-    CellPosType aPos1 = maCells.position(nRow1);
+    sc::CellStoreType::position_type aPos1 = maCells.position(nRow1);
     if (aPos1.first == maCells.end())
         return;
 
-    CellPosType aPos2 = maCells.position(aPos1.first, nRow2);
+    sc::CellStoreType::position_type aPos2 = maCells.position(aPos1.first, nRow2);
     if (aPos2.first == maCells.end())
         return;
 
@@ -881,13 +869,15 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
                 // TODO: Find out a way to adjust references without cloning new instances.
                 boost::scoped_ptr<ScFormulaCell> pOld1(*itf1);
                 boost::scoped_ptr<ScFormulaCell> pOld2(*itf2);
+                DetouchFormulaCell(aPos1, **itf1);
+                DetouchFormulaCell(aPos2, **itf2);
                 ScFormulaCell* pNew1 = cloneFormulaCell(pDocument, ScAddress(nCol, nRow1, nTab), *pOld2);
                 ScFormulaCell* pNew2 = cloneFormulaCell(pDocument, ScAddress(nCol, nRow2, nTab), *pOld1);
                 *itf1 = pNew1;
                 *itf2 = pNew2;
 
-                RegroupFormulaCells(nRow1);
-                RegroupFormulaCells(nRow2);
+                ActivateNewFormulaCell(aPos1, *pNew1);
+                ActivateNewFormulaCell(aPos2, *pNew2);
             }
             break;
             default:
@@ -902,10 +892,10 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
 
     // The two cells are of different types.
 
-    sc::CellStoreType::const_iterator cit = it1;
-    ScRefCellValue aCell1 = GetCellValue(cit, nRow1);
-    cit = it2;
-    ScRefCellValue aCell2 = GetCellValue(cit, nRow2);
+    ScRefCellValue aCell1 = GetCellValue(aPos1.first, aPos1.second);
+    ScRefCellValue aCell2 = GetCellValue(aPos2.first, aPos2.second);
+
+    // Make sure to put cells in row 1 first then row 2!
 
     if (aCell1.meType == CELLTYPE_NONE)
     {
@@ -929,11 +919,12 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
             break;
             case CELLTYPE_FORMULA:
             {
+                // cell 1 is empty and cell 2 is a formula cell.
                 ScFormulaCell* pNew = cloneFormulaCell(pDocument, ScAddress(nCol, nRow1, nTab), *aCell2.mpFormula);
+                DetouchFormulaCell(aPos2, *aCell2.mpFormula);
                 it1 = maCells.set(it1, nRow1, pNew);
                 maCells.set_empty(it1, nRow2, nRow2); // original formula cell gets deleted.
-
-                RegroupFormulaCells(nRow2);
+                ActivateNewFormulaCell(it1, nRow1, *pNew);
             }
             break;
             default:
@@ -972,12 +963,12 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
             break;
             case CELLTYPE_FORMULA:
             {
+                // cell 1 is a formula cell and cell 2 is empty.
                 ScFormulaCell* pNew = cloneFormulaCell(pDocument, ScAddress(nCol, nRow2, nTab), *aCell1.mpFormula);
+                DetouchFormulaCell(aPos1, *aCell1.mpFormula);
                 it1 = maCells.set_empty(it1, nRow1, nRow1); // original formula cell is gone.
-                maCells.set(it1, nRow2, pNew);
-
-                RegroupFormulaCells(nRow1);
-                RegroupFormulaCells(nRow2);
+                it1 = maCells.set(it1, nRow2, pNew);
+                ActivateNewFormulaCell(it1, nRow2, *pNew);
             }
             break;
             default:
@@ -1009,8 +1000,10 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
                 break;
                 case CELLTYPE_FORMULA:
                 {
+                    DetouchFormulaCell(aPos2, *aCell2.mpFormula);
                     ScFormulaCell* pNew = cloneFormulaCell(pDocument, ScAddress(nCol, nRow1, nTab), *aCell2.mpFormula);
                     it1 = maCells.set(it1, nRow1, pNew);
+                    ActivateNewFormulaCell(it1, nRow1, *pNew);
                     // The old formula cell will get overwritten below.
                 }
                 break;
@@ -1040,8 +1033,10 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
                 case CELLTYPE_FORMULA:
                 {
                     // cell 1 - string, cell 2 - formula
+                    DetouchFormulaCell(aPos2, *aCell2.mpFormula);
                     ScFormulaCell* pNew = cloneFormulaCell(pDocument, ScAddress(nCol, nRow1, nTab), *aCell2.mpFormula);
                     it1 = maCells.set(it1, nRow1, pNew);
+                    ActivateNewFormulaCell(it1, nRow1, *pNew);
                     // Old formula cell will get overwritten below.
                 }
                 break;
@@ -1067,8 +1062,10 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
                 break;
                 case CELLTYPE_FORMULA:
                 {
+                    DetouchFormulaCell(aPos2, *aCell2.mpFormula);
                     ScFormulaCell* pNew = cloneFormulaCell(pDocument, ScAddress(nCol, nRow1, nTab), *aCell2.mpFormula);
                     it1 = maCells.set(it1, nRow1, pNew);
+                    ActivateNewFormulaCell(it1, nRow1, *pNew);
                     // Old formula cell will get overwritten below.
                 }
                 break;
@@ -1081,6 +1078,8 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
         break;
         case CELLTYPE_FORMULA:
         {
+            // cell 1 is a formula cell and cell 2 is not.
+            DetouchFormulaCell(aPos1, *aCell1.mpFormula);
             ScFormulaCell* pNew = cloneFormulaCell(pDocument, ScAddress(nCol, nRow2, nTab), *aCell1.mpFormula);
             switch (aCell2.meType)
             {
@@ -1101,7 +1100,8 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
                     ;
             }
 
-            maCells.set(it1, nRow2, pNew);
+            it1 = maCells.set(it1, nRow2, pNew);
+            ActivateNewFormulaCell(it1, nRow2, *pNew);
         }
         break;
         default:
@@ -1109,8 +1109,6 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
     }
 
     SwapCellTextAttrs(nRow1, nRow2);
-    RegroupFormulaCells(nRow1);
-    RegroupFormulaCells(nRow2);
     CellStorageModified();
     BroadcastCells(aRows);
 }
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index ee0ec33..ff152ff 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -398,6 +398,17 @@ void ScColumn::JoinNewFormulaCell(
     }
 }
 
+void ScColumn::DetouchFormulaCell(
+    const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell ) const
+{
+    if (!pDocument->IsClipOrUndo())
+        // Have the dying formula cell stop listening.
+        rCell.EndListeningTo(pDocument);
+
+    if (rCell.IsShared())
+        UnshareFormulaCell(aPos, rCell);
+}
+
 void ScColumn::UnshareFormulaCell(
     const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell ) const
 {
@@ -498,12 +509,7 @@ sc::CellStoreType::iterator ScColumn::GetPositionToInsert( const sc::CellStoreTy
     if (itRet->type == sc::element_type_formula)
     {
         ScFormulaCell& rCell = *sc::formula_block::at(*itRet->data, aPos.second);
-        if (!pDocument->IsClipOrUndo())
-            // Have the dying formula cell stop listening.
-            rCell.EndListeningTo(pDocument);
-
-        if (rCell.IsShared())
-            UnshareFormulaCell(aPos, rCell);
+        DetouchFormulaCell(aPos, rCell);
     }
 
     return itRet;
@@ -512,9 +518,13 @@ sc::CellStoreType::iterator ScColumn::GetPositionToInsert( const sc::CellStoreTy
 void ScColumn::ActivateNewFormulaCell(
     const sc::CellStoreType::iterator& itPos, SCROW nRow, ScFormulaCell& rCell )
 {
-    // See if this new formula cell can join an existing shared formula group.
-    sc::CellStoreType::position_type aPos = maCells.position(itPos, nRow);
+    ActivateNewFormulaCell(maCells.position(itPos, nRow), rCell);
+}
 
+void ScColumn::ActivateNewFormulaCell(
+    const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell )
+{
+    // See if this new formula cell can join an existing shared formula group.
     JoinNewFormulaCell(aPos, rCell);
 
     // When we insert from the Clipboard we still have wrong (old) References!
commit f4e30d145fd4cc3e7ad3f067d8cef4204200e88c
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Wed Jun 26 18:06:04 2013 -0400

    Make this a member method too.
    
    Change-Id: Ib1b16ce5a7a36560b04d4d57b585fdcf2a2b294d

diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index a80cd66..2e1f0f1 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -459,6 +459,8 @@ public:
 
     void InterpretDirtyCells( SCROW nRow1, SCROW nRow2 );
 
+    void JoinNewFormulaCell( const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell ) const;
+
     void UnshareFormulaCell( const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell ) const;
 
     /**
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index ddf59af..ee0ec33 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -327,6 +327,77 @@ sc::CellStoreType::iterator ScColumn::GetPositionToInsert( SCROW nRow )
     return GetPositionToInsert(maCells.begin(), nRow);
 }
 
+namespace {
+
+void joinFormulaCells(SCROW nRow, ScFormulaCell& rCell1, ScFormulaCell& rCell2)
+{
+    ScFormulaCell::CompareState eState = rCell1.CompareByTokenArray(rCell2);
+    if (eState == ScFormulaCell::NotEqual)
+        return;
+
+    // Formula tokens equal those of the previous formula cell.
+    ScFormulaCellGroupRef xGroup1 = rCell1.GetCellGroup();
+    ScFormulaCellGroupRef xGroup2 = rCell2.GetCellGroup();
+    if (xGroup1)
+    {
+        if (xGroup2)
+        {
+            // Both cell1 and cell2 are shared. Merge them together.
+            xGroup1->mnLength += xGroup2->mnLength;
+            rCell2.SetCellGroup(xGroup1);
+        }
+        else
+        {
+            // cell1 is shared but cell2 is not.
+            rCell2.SetCellGroup(xGroup1);
+            ++xGroup1->mnLength;
+        }
+    }
+    else
+    {
+        if (xGroup2)
+        {
+            // cell1 is not shared, but cell2 is already shared.
+            rCell1.SetCellGroup(xGroup2);
+            xGroup2->mnStart = nRow;
+            ++xGroup2->mnLength;
+        }
+        else
+        {
+            // neither cells are shared.
+            xGroup1.reset(new ScFormulaCellGroup);
+            xGroup1->mnStart = nRow;
+            xGroup1->mbInvariant = (eState == ScFormulaCell::EqualInvariant);
+            xGroup1->mnLength = 2;
+
+            rCell1.SetCellGroup(xGroup1);
+            rCell2.SetCellGroup(xGroup1);
+        }
+    }
+}
+
+}
+
+void ScColumn::JoinNewFormulaCell(
+    const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell ) const
+{
+    SCROW nRow = aPos.first->position + aPos.second;
+
+    // Check the previous row position for possible grouping.
+    if (aPos.first->type == sc::element_type_formula && aPos.second > 0)
+    {
+        ScFormulaCell& rPrev = *sc::formula_block::at(*aPos.first->data, aPos.second-1);
+        joinFormulaCells(nRow-1, rPrev, rCell);
+    }
+
+    // Check the next row position for possible grouping.
+    if (aPos.first->type == sc::element_type_formula && aPos.second+1 < aPos.first->size)
+    {
+        ScFormulaCell& rNext = *sc::formula_block::at(*aPos.first->data, aPos.second+1);
+        joinFormulaCells(nRow, rCell, rNext);
+    }
+}
+
 void ScColumn::UnshareFormulaCell(
     const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell ) const
 {
@@ -438,76 +509,13 @@ sc::CellStoreType::iterator ScColumn::GetPositionToInsert( const sc::CellStoreTy
     return itRet;
 }
 
-namespace {
-
-void joinFormulaCells(SCROW nRow, ScFormulaCell& rCell1, ScFormulaCell& rCell2)
-{
-    ScFormulaCell::CompareState eState = rCell1.CompareByTokenArray(rCell2);
-    if (eState == ScFormulaCell::NotEqual)
-        return;
-
-    // Formula tokens equal those of the previous formula cell.
-    ScFormulaCellGroupRef xGroup1 = rCell1.GetCellGroup();
-    ScFormulaCellGroupRef xGroup2 = rCell2.GetCellGroup();
-    if (xGroup1)
-    {
-        if (xGroup2)
-        {
-            // Both cell1 and cell2 are shared. Merge them together.
-            xGroup1->mnLength += xGroup2->mnLength;
-            rCell2.SetCellGroup(xGroup1);
-        }
-        else
-        {
-            // cell1 is shared but cell2 is not.
-            rCell2.SetCellGroup(xGroup1);
-            ++xGroup1->mnLength;
-        }
-    }
-    else
-    {
-        if (xGroup2)
-        {
-            // cell1 is not shared, but cell2 is already shared.
-            rCell1.SetCellGroup(xGroup2);
-            xGroup2->mnStart = nRow;
-            ++xGroup2->mnLength;
-        }
-        else
-        {
-            // neither cells are shared.
-            xGroup1.reset(new ScFormulaCellGroup);
-            xGroup1->mnStart = nRow;
-            xGroup1->mbInvariant = (eState == ScFormulaCell::EqualInvariant);
-            xGroup1->mnLength = 2;
-
-            rCell1.SetCellGroup(xGroup1);
-            rCell2.SetCellGroup(xGroup1);
-        }
-    }
-}
-
-}
-
 void ScColumn::ActivateNewFormulaCell(
     const sc::CellStoreType::iterator& itPos, SCROW nRow, ScFormulaCell& rCell )
 {
     // See if this new formula cell can join an existing shared formula group.
     sc::CellStoreType::position_type aPos = maCells.position(itPos, nRow);
 
-    // Check the previous row position for possible grouping.
-    if (aPos.first->type == sc::element_type_formula && aPos.second > 0)
-    {
-        ScFormulaCell& rPrev = *sc::formula_block::at(*aPos.first->data, aPos.second-1);
-        joinFormulaCells(nRow-1, rPrev, rCell);
-    }
-
-    // Check the next row position for possible grouping.
-    if (aPos.first->type == sc::element_type_formula && aPos.second+1 < aPos.first->size)
-    {
-        ScFormulaCell& rNext = *sc::formula_block::at(*aPos.first->data, aPos.second+1);
-        joinFormulaCells(nRow, rCell, rNext);
-    }
+    JoinNewFormulaCell(aPos, rCell);
 
     // When we insert from the Clipboard we still have wrong (old) References!
     // First they are rewired in CopyBlockFromClip via UpdateReference and the
commit 310f44a5e833fc29e34907c5e4d41ddc9ab4e995
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Wed Jun 26 17:57:34 2013 -0400

    Make this a member method of ScColumn.
    
    Change-Id: I5d0a573d277338ddef60fdd58bfb1f5ba7fc695e

diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 781e1a7..a80cd66 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -459,6 +459,8 @@ public:
 
     void InterpretDirtyCells( SCROW nRow1, SCROW nRow2 );
 
+    void UnshareFormulaCell( const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell ) const;
+
     /**
      * Regroup formula cells for the entire column.
      */
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index c6dae67..ddf59af 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -327,13 +327,13 @@ sc::CellStoreType::iterator ScColumn::GetPositionToInsert( SCROW nRow )
     return GetPositionToInsert(maCells.begin(), nRow);
 }
 
-namespace {
-
-/**
- * Re-group a shared formula cell that's being overwritten.
- */
-void adjustSharedFormulaCell(const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell)
+void ScColumn::UnshareFormulaCell(
+    const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell ) const
 {
+    if (!rCell.IsShared())
+        return;
+
+    ScFormulaCellGroupRef xNone;
     sc::CellStoreType::iterator it = aPos.first;
 
     // This formula cell is shared. Adjust the shared group.
@@ -352,7 +352,6 @@ void adjustSharedFormulaCell(const sc::CellStoreType::position_type& aPos, ScFor
                 abort();
             }
 #endif
-            ScFormulaCellGroupRef xNone;
             ScFormulaCell& rNext = *sc::formula_block::at(*it->data, aPos.second+1);
             rNext.SetCellGroup(xNone);
         }
@@ -378,7 +377,6 @@ void adjustSharedFormulaCell(const sc::CellStoreType::position_type& aPos, ScFor
                 abort();
             }
 #endif
-            ScFormulaCellGroupRef xNone;
             ScFormulaCell& rPrev = *sc::formula_block::at(*it->data, aPos.second-1);
             rPrev.SetCellGroup(xNone);
         }
@@ -417,8 +415,8 @@ void adjustSharedFormulaCell(const sc::CellStoreType::position_type& aPos, ScFor
             rCell2.SetCellGroup(xGroup2);
         }
     }
-}
 
+    rCell.SetCellGroup(xNone);
 }
 
 sc::CellStoreType::iterator ScColumn::GetPositionToInsert( const sc::CellStoreType::iterator& it, SCROW nRow )
@@ -434,7 +432,7 @@ sc::CellStoreType::iterator ScColumn::GetPositionToInsert( const sc::CellStoreTy
             rCell.EndListeningTo(pDocument);
 
         if (rCell.IsShared())
-            adjustSharedFormulaCell(aPos, rCell);
+            UnshareFormulaCell(aPos, rCell);
     }
 
     return itRet;
commit 12fc0ca3f5e52f03882f447d23afd9029c416a1a
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Wed Jun 26 17:43:18 2013 -0400

    We don't need this formula group vector.
    
    Change-Id: I96f3b19a5bb0d761b7abd943df6a2e48cfcbf9bd

diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 6b46cc8..781e1a7 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -110,8 +110,6 @@ class ScColumn
     SCCOL           nCol;
     SCTAB           nTab;
 
-    std::vector<ScFormulaCellGroupRef> maFnGroups;
-
     ScAttrArray*          pAttrArray;
     ScDocument*           pDocument;
     bool mbDirtyGroups;     /// formula groups are dirty.
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index 574dcd8..c6dae67 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -2713,11 +2713,9 @@ public:
 
 class GroupFormulaCells
 {
-    std::vector<ScFormulaCellGroupRef>& mrFnGroups;
     ScFormulaCellGroupRef mxNone;
 
 public:
-    GroupFormulaCells(std::vector<ScFormulaCellGroupRef>& rFnGroups) : mrFnGroups(rFnGroups) {}
 
     void operator() (sc::CellStoreType::value_type& node)
     {
@@ -2755,8 +2753,6 @@ public:
                 xGroup->mbInvariant = (eCompState == ScFormulaCell::EqualInvariant);
                 xGroup->mnLength = 2;
 
-                mrFnGroups.push_back(xGroup);
-
                 pCur->SetCellGroup(xGroup);
                 pPrev->SetCellGroup(xGroup);
             }
@@ -2783,10 +2779,9 @@ void ScColumn::RebuildFormulaGroups()
     ScFormulaCellGroupRef xNone;
     CellGroupSetter aFunc(xNone);
     sc::ProcessFormula(maCells, aFunc);
-    maFnGroups.clear();
 
     // re-build formula groups.
-    std::for_each(maCells.begin(), maCells.end(), GroupFormulaCells(maFnGroups));
+    std::for_each(maCells.begin(), maCells.end(), GroupFormulaCells());
 
     mbDirtyGroups = false;
 }
commit c7641bac30f95ac85bd5d462f6083378ee30db4b
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Wed Jun 26 17:37:23 2013 -0400

    Extract this code block into an own function.
    
    Change-Id: I6abe520ad6392e4f9163434b73f3b3ab88a71297

diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index 7fd16f0..574dcd8 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -327,103 +327,115 @@ sc::CellStoreType::iterator ScColumn::GetPositionToInsert( SCROW nRow )
     return GetPositionToInsert(maCells.begin(), nRow);
 }
 
-sc::CellStoreType::iterator ScColumn::GetPositionToInsert( const sc::CellStoreType::iterator& it, SCROW nRow )
+namespace {
+
+/**
+ * Re-group a shared formula cell that's being overwritten.
+ */
+void adjustSharedFormulaCell(const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell)
 {
-    // See if we are overwriting an existing formula cell.
-    sc::CellStoreType::position_type aRet = maCells.position(it, nRow);
-    sc::CellStoreType::iterator itRet = aRet.first;
-    if (itRet->type == sc::element_type_formula)
-    {
-        ScFormulaCell& rCell = *sc::formula_block::at(*itRet->data, aRet.second);
-        if (!pDocument->IsClipOrUndo())
-            // Have the dying formula cell stop listening.
-            rCell.EndListeningTo(pDocument);
+    sc::CellStoreType::iterator it = aPos.first;
 
-        if (rCell.IsShared())
+    // This formula cell is shared. Adjust the shared group.
+    if (rCell.aPos.Row() == rCell.GetSharedTopRow())
+    {
+        // Top of the shared range.
+        ScFormulaCellGroupRef xGroup = rCell.GetCellGroup();
+        if (xGroup->mnLength == 2)
         {
-            // This formula cell is shared. Adjust the shared group.
-            if (rCell.aPos.Row() == rCell.GetSharedTopRow())
-            {
-                // Top of the shared range.
-                ScFormulaCellGroupRef xGroup = rCell.GetCellGroup();
-                if (xGroup->mnLength == 2)
-                {
-                    // Group consists only only two cells. Mark the second one non-shared.
+            // Group consists only only two cells. Mark the second one non-shared.
 #if DEBUG_COLUMN_STORAGE
-                    if (aRet.second+1 >= aRet.first->size)
-                    {
-                        cerr << "ScColumn::GetPositionToInsert: There is no next formula cell but there should be!" << endl;
-                        cerr.flush();
-                        abort();
-                    }
-#endif
-                    ScFormulaCellGroupRef xNone;
-                    ScFormulaCell& rNext = *sc::formula_block::at(*itRet->data, aRet.second+1);
-                    rNext.SetCellGroup(xNone);
-                }
-                else
-                {
-                    // Move the top cell to the next formula cell down.
-                    --xGroup->mnLength;
-                    ++xGroup->mnStart;
-                }
-            }
-            else if (rCell.aPos.Row() == rCell.GetSharedTopRow() + rCell.GetSharedLength() - 1)
+            if (aPos.second+1 >= aPos.first->size)
             {
-                // Bottom of the shared range.
-                ScFormulaCellGroupRef xGroup = rCell.GetCellGroup();
-                if (xGroup->mnLength == 2)
-                {
-                    // Mark the top cell non-shared.
-#if DEBUG_COLUMN_STORAGE
-                    if (aRet.second == 0)
-                    {
-                        cerr << "ScColumn::GetPositionToInsert: There is no previous formula cell but there should be!" << endl;
-                        cerr.flush();
-                        abort();
-                    }
-#endif
-                    ScFormulaCellGroupRef xNone;
-                    ScFormulaCell& rPrev = *sc::formula_block::at(*itRet->data, aRet.second-1);
-                    rPrev.SetCellGroup(xNone);
-                }
-                else
-                {
-                    // Just shortern the shared range length by one.
-                    --xGroup->mnLength;
-                }
+                cerr << "ScColumn::GetPositionToInsert: There is no next formula cell but there should be!" << endl;
+                cerr.flush();
+                abort();
             }
-            else
+#endif
+            ScFormulaCellGroupRef xNone;
+            ScFormulaCell& rNext = *sc::formula_block::at(*it->data, aPos.second+1);
+            rNext.SetCellGroup(xNone);
+        }
+        else
+        {
+            // Move the top cell to the next formula cell down.
+            --xGroup->mnLength;
+            ++xGroup->mnStart;
+        }
+    }
+    else if (rCell.aPos.Row() == rCell.GetSharedTopRow() + rCell.GetSharedLength() - 1)
+    {
+        // Bottom of the shared range.
+        ScFormulaCellGroupRef xGroup = rCell.GetCellGroup();
+        if (xGroup->mnLength == 2)
+        {
+            // Mark the top cell non-shared.
+#if DEBUG_COLUMN_STORAGE
+            if (aPos.second == 0)
             {
-                // In the middle of the shared range. Split it into two groups.
-                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;
+                cerr << "ScColumn::GetPositionToInsert: There is no previous formula cell but there should be!" << endl;
+                cerr.flush();
+                abort();
+            }
+#endif
+            ScFormulaCellGroupRef xNone;
+            ScFormulaCell& rPrev = *sc::formula_block::at(*it->data, aPos.second-1);
+            rPrev.SetCellGroup(xNone);
+        }
+        else
+        {
+            // Just shortern the shared range length by one.
+            --xGroup->mnLength;
+        }
+    }
+    else
+    {
+        // In the middle of the shared range. Split it into two groups.
+        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 > itRet->position + itRet->size)
-                {
-                    cerr << "ScColumn::GetPositionToInsert: Shared formula region goes beyond the formula block. Not good." << endl;
-                    cerr.flush();
-                    abort();
-                }
+        if (xGroup2->mnStart + xGroup2->mnLength > it->position + it->size)
+        {
+            cerr << "ScColumn::GetPositionToInsert: Shared formula region goes beyond the formula block. Not good." << endl;
+            cerr.flush();
+            abort();
+        }
 #endif
-                sc::formula_block::iterator itCell = sc::formula_block::begin(*itRet->data);
-                std::advance(itCell, aRet.second+1);
-                sc::formula_block::iterator itCellEnd = itCell;
-                std::advance(itCellEnd, xGroup2->mnLength);
-                for (; itCell != itCellEnd; ++itCell)
-                {
-                    ScFormulaCell& rCell2 = **itCell;
-                    rCell2.SetCellGroup(xGroup2);
-                }
-            }
+        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);
         }
     }
+}
+
+}
+
+sc::CellStoreType::iterator ScColumn::GetPositionToInsert( const sc::CellStoreType::iterator& it, SCROW nRow )
+{
+    // See if we are overwriting an existing formula cell.
+    sc::CellStoreType::position_type aPos = maCells.position(it, nRow);
+    sc::CellStoreType::iterator itRet = aPos.first;
+    if (itRet->type == sc::element_type_formula)
+    {
+        ScFormulaCell& rCell = *sc::formula_block::at(*itRet->data, aPos.second);
+        if (!pDocument->IsClipOrUndo())
+            // Have the dying formula cell stop listening.
+            rCell.EndListeningTo(pDocument);
+
+        if (rCell.IsShared())
+            adjustSharedFormulaCell(aPos, rCell);
+    }
 
     return itRet;
 }


More information about the Libreoffice-commits mailing list