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

Kohei Yoshida kohei.yoshida at gmail.com
Wed Jul 10 17:35:26 PDT 2013


 sc/inc/column.hxx                     |    9 --
 sc/inc/sharedformula.hxx              |   34 +++++++
 sc/source/core/data/column.cxx        |   24 ++---
 sc/source/core/data/column3.cxx       |  145 +---------------------------------
 sc/source/core/tool/sharedformula.cxx |  126 +++++++++++++++++++++++++++++
 5 files changed, 179 insertions(+), 159 deletions(-)

New commits:
commit 893714a9b88c1019537659098717406a1cb40b71
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Wed Jul 10 19:46:46 2013 -0400

    Move more methods to SharedFormulaUtil.
    
    Change-Id: Ibd58f5d15292805d50823223d1ebe94e7b51b808

diff --git a/sc/inc/sharedformula.hxx b/sc/inc/sharedformula.hxx
index 6767d4a..fa75e80 100644
--- a/sc/inc/sharedformula.hxx
+++ b/sc/inc/sharedformula.hxx
@@ -66,6 +66,16 @@ public:
     static void splitFormulaCellGroup(const CellStoreType::position_type& aPos);
 
     /**
+     * See if two specified adjacent formula cells can be merged, and if they
+     * can, merge them into the same group.
+     *
+     * @param rPos position object of the first cell
+     * @param rCell1 first cell
+     * @param rCell2 second cell located immediately below the first cell.
+     */
+    static void joinFormulaCells(
+        const CellStoreType::position_type& rPos, ScFormulaCell& rCell1, ScFormulaCell& rCell2);
+    /**
      * Merge with an existing formula group (if any) located immediately above
      * if the cell at specified position is a formula cell, and its formula
      * tokens are identical to that of the above formula group.
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index de8adde..2136e04 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -306,69 +306,6 @@ sc::CellStoreType::iterator ScColumn::GetPositionToInsert( SCROW nRow )
     return GetPositionToInsert(maCells.begin(), nRow);
 }
 
-namespace {
-
-void joinFormulaCells(const sc::CellStoreType::position_type& rPos, ScFormulaCell& rCell1, ScFormulaCell& rCell2)
-{
-    ScFormulaCell::CompareState eState = rCell1.CompareByTokenArray(rCell2);
-    if (eState == ScFormulaCell::NotEqual)
-        return;
-
-    SCROW nRow = rPos.first->position + rPos.second;
-
-    // Formula tokens equal those of the previous formula cell.
-    ScFormulaCellGroupRef xGroup1 = rCell1.GetCellGroup();
-    ScFormulaCellGroupRef xGroup2 = rCell2.GetCellGroup();
-    if (xGroup1)
-    {
-        if (xGroup2)
-        {
-            // Both cell 1 and cell 2 are shared. Merge them together.
-            if (xGroup1.get() == xGroup2.get())
-                // They belong to the same group.
-                return;
-
-            // Set the group object from cell 1 to all cells in group 2.
-            xGroup1->mnLength += xGroup2->mnLength;
-            size_t nOffset = rPos.second + 1; // position of cell 2
-            for (size_t i = 0, n = xGroup2->mnLength; i < n; ++i)
-            {
-                ScFormulaCell& rCell = *sc::formula_block::at(*rPos.first->data, nOffset+i);
-                rCell.SetCellGroup(xGroup1);
-            }
-        }
-        else
-        {
-            // cell 1 is shared but cell 2 is not.
-            rCell2.SetCellGroup(xGroup1);
-            ++xGroup1->mnLength;
-        }
-    }
-    else
-    {
-        if (xGroup2)
-        {
-            // cell 1 is not shared, but cell 2 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
 {
@@ -378,14 +315,14 @@ void ScColumn::JoinNewFormulaCell(
         ScFormulaCell& rPrev = *sc::formula_block::at(*aPos.first->data, aPos.second-1);
         sc::CellStoreType::position_type aPosPrev = aPos;
         --aPosPrev.second;
-        joinFormulaCells(aPosPrev, rPrev, rCell);
+        sc::SharedFormulaUtil::joinFormulaCells(aPosPrev, 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(aPos, rCell, rNext);
+        sc::SharedFormulaUtil::joinFormulaCells(aPos, rCell, rNext);
     }
 }
 
diff --git a/sc/source/core/tool/sharedformula.cxx b/sc/source/core/tool/sharedformula.cxx
index c1bc564..5cdfc785 100644
--- a/sc/source/core/tool/sharedformula.cxx
+++ b/sc/source/core/tool/sharedformula.cxx
@@ -62,9 +62,7 @@ void SharedFormulaUtil::splitFormulaCellGroup(const CellStoreType::position_type
     }
 }
 
-namespace {
-
-void joinFormulaCells(const sc::CellStoreType::position_type& rPos, ScFormulaCell& rCell1, ScFormulaCell& rCell2)
+void SharedFormulaUtil::joinFormulaCells(const CellStoreType::position_type& rPos, ScFormulaCell& rCell1, ScFormulaCell& rCell2)
 {
     ScFormulaCell::CompareState eState = rCell1.CompareByTokenArray(rCell2);
     if (eState == ScFormulaCell::NotEqual)
@@ -123,8 +121,6 @@ void joinFormulaCells(const sc::CellStoreType::position_type& rPos, ScFormulaCel
     }
 }
 
-}
-
 void SharedFormulaUtil::joinFormulaCellAbove(const CellStoreType::position_type& aPos)
 {
     if (aPos.first->type != sc::element_type_formula)
commit 82796dde612daca0a06779ecda1a579de3276350
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Wed Jul 10 19:34:34 2013 -0400

    Move these methods out of ScColumn since they don't operate on column.
    
    Change-Id: I1a03b9b18dd236138306fd545e961a5443e22bc8

diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 01e9ef7..2c59b77 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -503,15 +503,6 @@ 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;
-
-    void JoinFormulaCellAbove( const sc::CellStoreType::position_type& aPos ) const;
-
-    /**
      * Regroup formula cells for the entire column.
      */
     void RegroupFormulaCells();
diff --git a/sc/inc/sharedformula.hxx b/sc/inc/sharedformula.hxx
index fcab6d7..6767d4a 100644
--- a/sc/inc/sharedformula.hxx
+++ b/sc/inc/sharedformula.hxx
@@ -11,6 +11,7 @@
 #define SC_SHAREDFORMULA_HXX
 
 #include "formulacell.hxx"
+#include "mtvelements.hxx"
 
 namespace sc {
 
@@ -18,6 +19,10 @@ class SharedFormulaUtil
 {
 public:
 
+    /**
+     * Group formula cells stored in the passed container. The formula cells
+     * in the container are assumed to be all <b>non-shared</b>.
+     */
     template<typename _Iter>
     static void groupFormulaCells(const _Iter& itBeg, const _Iter& itEnd)
     {
@@ -49,6 +54,25 @@ public:
             pCur->SetCellGroup(xGroup);
         }
     }
+
+    /**
+     * 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.  This method does nothing if the cell at
+     * specified position is not a formula cell.
+     *
+     * @param aPos position of cell to examine.
+     */
+    static void splitFormulaCellGroup(const CellStoreType::position_type& aPos);
+
+    /**
+     * Merge with an existing formula group (if any) located immediately above
+     * if the cell at specified position is a formula cell, and its formula
+     * tokens are identical to that of the above formula group.
+     *
+     * @param aPos position of cell to examine.
+     */
+    static void joinFormulaCellAbove(const CellStoreType::position_type& aPos);
 };
 
 }
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index b777905..730fed4 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -1383,12 +1383,12 @@ public:
                 sc::CellStoreType::position_type aPos =
                     rDestCells.position(maDestPos.miCellPos, nTopRow);
                 maDestPos.miCellPos = aPos.first;
-                mrDestCol.JoinFormulaCellAbove(aPos);
+                sc::SharedFormulaUtil::joinFormulaCellAbove(aPos);
                 size_t nLastRow = nTopRow + nDataSize;
                 if (nLastRow < static_cast<size_t>(MAXROW))
                 {
                     aPos = rDestCells.position(maDestPos.miCellPos, nLastRow+1);
-                    mrDestCol.JoinFormulaCellAbove(aPos);
+                    sc::SharedFormulaUtil::joinFormulaCellAbove(aPos);
                 }
 
                 setDefaultAttrsToDest(nTopRow, nDataSize);
@@ -2170,15 +2170,15 @@ void ScColumn::MoveTo(SCROW nStartRow, SCROW nEndRow, ScColumn& rCol)
 
     // Split the formula grouping at the top and bottom boundaries.
     sc::CellStoreType::position_type aPos = maCells.position(nStartRow);
-    SplitFormulaCellGroup(aPos);
+    sc::SharedFormulaUtil::splitFormulaCellGroup(aPos);
     aPos = maCells.position(aPos.first, nEndRow+1);
-    SplitFormulaCellGroup(aPos);
+    sc::SharedFormulaUtil::splitFormulaCellGroup(aPos);
 
     // Do the same with the destination column.
     aPos = rCol.maCells.position(nStartRow);
-    rCol.SplitFormulaCellGroup(aPos);
+    sc::SharedFormulaUtil::splitFormulaCellGroup(aPos);
     aPos = rCol.maCells.position(aPos.first, nEndRow+1);
-    rCol.SplitFormulaCellGroup(aPos);
+    sc::SharedFormulaUtil::splitFormulaCellGroup(aPos);
 
     // Move the broadcasters to the destination column.
     maBroadcasters.transfer(nStartRow, nEndRow, rCol.maBroadcasters, nStartRow);
@@ -2187,9 +2187,9 @@ void ScColumn::MoveTo(SCROW nStartRow, SCROW nEndRow, ScColumn& rCol)
 
     // Re-group transferred formula cells.
     aPos = rCol.maCells.position(nStartRow);
-    rCol.JoinFormulaCellAbove(aPos);
+    sc::SharedFormulaUtil::joinFormulaCellAbove(aPos);
     aPos = rCol.maCells.position(aPos.first, nEndRow+1);
-    rCol.JoinFormulaCellAbove(aPos);
+    sc::SharedFormulaUtil::joinFormulaCellAbove(aPos);
 
     CellStorageModified();
     rCol.CellStorageModified();
@@ -2315,11 +2315,11 @@ bool ScColumn::UpdateReferenceOnCopy(
 
     // The formula groups at the top and bottom boundaries are expected to
     // have been split prior to this call. Here, we only do the joining.
-    JoinFormulaCellAbove(aPos);
+    sc::SharedFormulaUtil::joinFormulaCellAbove(aPos);
     if (rRange.aEnd.Row() < MAXROW)
     {
         aPos = maCells.position(aPos.first, rRange.aEnd.Row()+1);
-        JoinFormulaCellAbove(aPos);
+        sc::SharedFormulaUtil::joinFormulaCellAbove(aPos);
     }
 
     return aHandler.isUpdated();
@@ -2341,12 +2341,12 @@ bool ScColumn::UpdateReference(
         if (ValidRow(nSplitPos))
         {
             sc::CellStoreType::position_type aPos = maCells.position(nSplitPos);
-            SplitFormulaCellGroup(aPos);
+            sc::SharedFormulaUtil::splitFormulaCellGroup(aPos);
             nSplitPos = rRange.aEnd.Row() + 1;
             if (ValidRow(nSplitPos))
             {
                 aPos = maCells.position(aPos.first, nSplitPos);
-                SplitFormulaCellGroup(aPos);
+                sc::SharedFormulaUtil::splitFormulaCellGroup(aPos);
             }
         }
     }
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index 4fb06c3..de8adde 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -281,7 +281,7 @@ void ScColumn::DeleteRow( SCROW nStartRow, SCSIZE nSize )
     ShiftFormulaPosHandler aShiftFormulaFunc;
     sc::ProcessFormula(aPos.first, maCells, nStartRow, MAXROW, aShiftFormulaFunc);
 
-    JoinFormulaCellAbove(aPos);
+    sc::SharedFormulaUtil::joinFormulaCellAbove(aPos);
 
     // Single cell broadcasts on deleted cells.
     BroadcastCells(aDeleteRowsFunc.getNonEmptyRows());
@@ -420,13 +420,13 @@ void ScColumn::DetachFormulaCells(
     const sc::CellStoreType::position_type& aPos, size_t nLength )
 {
     // Split formula grouping at the top and bottom boundaries.
-    SplitFormulaCellGroup(aPos);
+    sc::SharedFormulaUtil::splitFormulaCellGroup(aPos);
     size_t nRow = aPos.first->position + aPos.second;
     size_t nNextTopRow = nRow + nLength; // start row of next formula group.
     if (ValidRow(nNextTopRow))
     {
         sc::CellStoreType::position_type aPos2 = maCells.position(aPos.first, nNextTopRow);
-        SplitFormulaCellGroup(aPos2);
+        sc::SharedFormulaUtil::splitFormulaCellGroup(aPos2);
     }
 
     if (pDocument->IsClipOrUndo())
@@ -555,74 +555,6 @@ 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);
-    }
-}
-
-void ScColumn::JoinFormulaCellAbove( const sc::CellStoreType::position_type& aPos ) const
-{
-    if (aPos.first->type != sc::element_type_formula)
-        // This is not a formula cell.
-        return;
-
-    if (aPos.second == 0)
-        // This cell is already the top cell in a formula block; the previous
-        // cell is not a formula cell.
-        return;
-
-    ScFormulaCell& rPrev = *sc::formula_block::at(*aPos.first->data, aPos.second-1);
-    ScFormulaCell& rCell = *sc::formula_block::at(*aPos.first->data, aPos.second);
-    sc::CellStoreType::position_type aPosPrev = aPos;
-    --aPosPrev.second;
-    joinFormulaCells(aPosPrev, rPrev, rCell);
-}
-
 sc::CellStoreType::iterator ScColumn::GetPositionToInsert( const sc::CellStoreType::iterator& it, SCROW nRow )
 {
     // See if we are overwriting an existing formula cell.
@@ -1545,14 +1477,14 @@ public:
 
                     // Merge with the previous formula group (if any).
                     aPos = rDestCells.position(itDestPos, nDestRow);
-                    mrDestColumn.JoinFormulaCellAbove(aPos);
+                    sc::SharedFormulaUtil::joinFormulaCellAbove(aPos);
 
                     // Merge with the next formula group (if any).
                     size_t nNextRow = nDestRow + it->size;
                     if (ValidRow(nNextRow))
                     {
                         aPos = rDestCells.position(aPos.first, nNextRow);
-                        mrDestColumn.JoinFormulaCellAbove(aPos);
+                        sc::SharedFormulaUtil::joinFormulaCellAbove(aPos);
                     }
                 }
                 break;
diff --git a/sc/source/core/tool/sharedformula.cxx b/sc/source/core/tool/sharedformula.cxx
index 7b6ac84..c1bc564 100644
--- a/sc/source/core/tool/sharedformula.cxx
+++ b/sc/source/core/tool/sharedformula.cxx
@@ -8,10 +8,140 @@
  */
 
 #include "sharedformula.hxx"
+#include "calcmacros.hxx"
 
 namespace sc {
 
+void SharedFormulaUtil::splitFormulaCellGroup(const CellStoreType::position_type& aPos)
+{
+    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);
+    }
+}
+
+namespace {
+
+void joinFormulaCells(const sc::CellStoreType::position_type& rPos, ScFormulaCell& rCell1, ScFormulaCell& rCell2)
+{
+    ScFormulaCell::CompareState eState = rCell1.CompareByTokenArray(rCell2);
+    if (eState == ScFormulaCell::NotEqual)
+        return;
+
+    SCROW nRow = rPos.first->position + rPos.second;
+
+    // Formula tokens equal those of the previous formula cell.
+    ScFormulaCellGroupRef xGroup1 = rCell1.GetCellGroup();
+    ScFormulaCellGroupRef xGroup2 = rCell2.GetCellGroup();
+    if (xGroup1)
+    {
+        if (xGroup2)
+        {
+            // Both cell 1 and cell 2 are shared. Merge them together.
+            if (xGroup1.get() == xGroup2.get())
+                // They belong to the same group.
+                return;
+
+            // Set the group object from cell 1 to all cells in group 2.
+            xGroup1->mnLength += xGroup2->mnLength;
+            size_t nOffset = rPos.second + 1; // position of cell 2
+            for (size_t i = 0, n = xGroup2->mnLength; i < n; ++i)
+            {
+                ScFormulaCell& rCell = *sc::formula_block::at(*rPos.first->data, nOffset+i);
+                rCell.SetCellGroup(xGroup1);
+            }
+        }
+        else
+        {
+            // cell 1 is shared but cell 2 is not.
+            rCell2.SetCellGroup(xGroup1);
+            ++xGroup1->mnLength;
+        }
+    }
+    else
+    {
+        if (xGroup2)
+        {
+            // cell 1 is not shared, but cell 2 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 SharedFormulaUtil::joinFormulaCellAbove(const CellStoreType::position_type& aPos)
+{
+    if (aPos.first->type != sc::element_type_formula)
+        // This is not a formula cell.
+        return;
+
+    if (aPos.second == 0)
+        // This cell is already the top cell in a formula block; the previous
+        // cell is not a formula cell.
+        return;
+
+    ScFormulaCell& rPrev = *sc::formula_block::at(*aPos.first->data, aPos.second-1);
+    ScFormulaCell& rCell = *sc::formula_block::at(*aPos.first->data, aPos.second);
+    sc::CellStoreType::position_type aPosPrev = aPos;
+    --aPosPrev.second;
+    joinFormulaCells(aPosPrev, rPrev, rCell);
+}
 
 }
 


More information about the Libreoffice-commits mailing list