[Libreoffice-commits] core.git: Branch 'feature/calc-group-interpreter' - sc/source

Kohei Yoshida kohei.yoshida at gmail.com
Mon Jul 8 21:46:01 PDT 2013


 sc/source/core/data/column.cxx  |   37 +++++++++++++++++++++++++++++++++++++
 sc/source/core/data/column3.cxx |   16 ++++++++++++----
 2 files changed, 49 insertions(+), 4 deletions(-)

New commits:
commit cf41d1d7c49b30ef2b69d5da31f9f57713c0a062
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Tue Jul 9 00:39:26 2013 -0400

    Group formula cells when copying to clip, prevent crash during pasting.
    
    Change-Id: I6a33301d74d9845e8c0fa77894fbd89bea40fd1b

diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index 8665873..5ff426e 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -1257,6 +1257,40 @@ class CopyToClipHandler
             maDestPos.miCellTextAttrPos, nRow, aAttrs.begin(), aAttrs.end());
     }
 
+    void groupFormulaCells(std::vector<ScFormulaCell*>& rCells)
+    {
+        if (rCells.empty())
+            return;
+
+        std::vector<ScFormulaCell*>::iterator it = rCells.begin(), itEnd = rCells.end();
+        ScFormulaCell* pPrev = *it;
+        ScFormulaCell* pCur = NULL;
+        for (++it; it != itEnd; ++it, pPrev = pCur)
+        {
+            pCur = *it;
+            ScFormulaCell::CompareState eState = pPrev->CompareByTokenArray(*pPrev);
+            if (eState == ScFormulaCell::NotEqual)
+                continue;
+
+            ScFormulaCellGroupRef xGroup = pPrev->GetCellGroup();
+            if (xGroup)
+            {
+                // Extend the group.
+                ++xGroup->mnLength;
+                pCur->SetCellGroup(xGroup);
+                continue;
+            }
+
+            // Create a new group.
+            xGroup.reset(new ScFormulaCellGroup);
+            xGroup->mnStart = pPrev->aPos.Row();
+            xGroup->mnLength = 2;
+            xGroup->mbInvariant = (eState == ScFormulaCell::EqualInvariant);
+            pPrev->SetCellGroup(xGroup);
+            pCur->SetCellGroup(xGroup);
+        }
+    }
+
 public:
     CopyToClipHandler(const ScColumn& rSrcCol, ScColumn& rDestCol, sc::ColumnBlockPosition* pDestPos) :
         mrSrcCol(rSrcCol), mrDestCol(rDestCol), mpDestPos(pDestPos)
@@ -1336,6 +1370,9 @@ public:
                     aCloned.push_back(new ScFormulaCell(rOld, mrDestCol.GetDoc(), aDestPos));
                 }
 
+                // Group the cloned formula cells.
+                groupFormulaCells(aCloned);
+
                 maDestPos.miCellPos = mrDestCol.GetCellStore().set(
                     maDestPos.miCellPos, nTopRow, aCloned.begin(), aCloned.end());
 
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index 3c35b80..d22825c 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -899,6 +899,7 @@ class CopyCellsFromClipHandler
     SCCOL mnCol;
     long mnRowOffset;
     sc::ColumnBlockPosition maDestBlockPos;
+    sc::ColumnBlockPosition* mpDestBlockPos; // to save it for next iteration.
 
     bool isDateCell(SCROW nSrcRow) const
     {
@@ -930,15 +931,22 @@ public:
         mrDestCol(rDestCol),
         mnTab(nDestTab),
         mnCol(nDestCol),
-        mnRowOffset(nRowOffset)
+        mnRowOffset(nRowOffset),
+        mpDestBlockPos(mrCxt.getBlockPosition(nDestTab, nDestCol))
     {
-        sc::ColumnBlockPosition* p = mrCxt.getBlockPosition(nDestTab, nDestCol);
-        if (p)
-            maDestBlockPos = *p;
+        if (mpDestBlockPos)
+            maDestBlockPos = *mpDestBlockPos;
         else
             mrDestCol.InitBlockPosition(maDestBlockPos);
     }
 
+    ~CopyCellsFromClipHandler()
+    {
+        if (mpDestBlockPos)
+            // Don't forget to save this to the context!
+            *mpDestBlockPos = maDestBlockPos;
+    }
+
     void operator() (const sc::CellStoreType::value_type& node, size_t nOffset, size_t nDataSize)
     {
         if (node.type == sc::element_type_empty)


More information about the Libreoffice-commits mailing list