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

Kohei Yoshida kohei.yoshida at gmail.com
Wed Jul 10 13:34:31 PDT 2013


 sc/Library_sc.mk                      |    1 
 sc/inc/column.hxx                     |   15 ---
 sc/inc/sharedformula.hxx              |   58 +++++++++++
 sc/source/core/data/column.cxx        |   20 ++--
 sc/source/core/data/column2.cxx       |    4 
 sc/source/core/data/column3.cxx       |  170 ++++++++++++++++++----------------
 sc/source/core/tool/sharedformula.cxx |   18 +++
 7 files changed, 185 insertions(+), 101 deletions(-)

New commits:
commit 8594a04b7ff69e1f82b828e9a8daa669a99f2e26
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Wed Jul 10 16:32:39 2013 -0400

    Group formula cells in ScColumn::MixData().
    
    Change-Id: I38186e2bf82ed56fbe859b17dcc1d31f36471bd8

diff --git a/sc/Library_sc.mk b/sc/Library_sc.mk
index d5b486e3..1b84dd9 100644
--- a/sc/Library_sc.mk
+++ b/sc/Library_sc.mk
@@ -245,6 +245,7 @@ $(eval $(call gb_Library_add_exception_objects,sc,\
 	sc/source/core/tool/refupdat \
 	sc/source/core/tool/scmatrix \
 	sc/source/core/tool/scopetools \
+	sc/source/core/tool/sharedformula \
 	sc/source/core/tool/simplerangelist \
 	sc/source/core/tool/stringutil \
 	sc/source/core/tool/subtotal \
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 3e66ca9..1aff86f 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -480,17 +480,18 @@ public:
     bool HasBroadcaster() const;
 
     void BroadcastCells( const std::vector<SCROW>& rRows );
-    void EndFormulaListening( sc::ColumnBlockPosition& rBlockPos, SCROW nRow1, SCROW nRow2 );
 
     void InterpretDirtyCells( SCROW nRow1, SCROW nRow2 );
 
     void JoinNewFormulaCell( const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell ) const;
 
     /**
-     * Detouch a formula cell that's about to be deleted, or removed from
+     * Detach 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 DetachFormulaCell( const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell );
+
+    void DetachFormulaCells( const sc::CellStoreType::position_type& aPos, size_t nLength );
 
     void UnshareFormulaCell( const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell ) const;
 
@@ -508,14 +509,6 @@ public:
      */
     void RegroupFormulaCells();
 
-    /**
-     * Regroup existing formula cells when a range of new cells are inserted.
-     *
-     * @param nRow1 first row of inserted new cell span.
-     * @param nRow2 last row of inserted new cell span.
-     */
-    void RegroupFormulaCells( SCROW nRow1, SCROW nRow2 );
-
 #if DEBUG_COLUMN_STORAGE
     void DumpFormulaGroups() const;
 #endif
diff --git a/sc/inc/sharedformula.hxx b/sc/inc/sharedformula.hxx
new file mode 100644
index 0000000..fcab6d7
--- /dev/null
+++ b/sc/inc/sharedformula.hxx
@@ -0,0 +1,58 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef SC_SHAREDFORMULA_HXX
+#define SC_SHAREDFORMULA_HXX
+
+#include "formulacell.hxx"
+
+namespace sc {
+
+class SharedFormulaUtil
+{
+public:
+
+    template<typename _Iter>
+    static void groupFormulaCells(const _Iter& itBeg, const _Iter& itEnd)
+    {
+        _Iter it = itBeg;
+        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);
+        }
+    }
+};
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index 70bd46b..50bc855 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -39,6 +39,7 @@
 #include "mtvcellfunc.hxx"
 #include "columnspanset.hxx"
 #include "scopetools.hxx"
+#include "sharedformula.hxx"
 
 #include <svl/poolcach.hxx>
 #include <svl/zforlist.hxx>
@@ -868,8 +869,8 @@ 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);
+                DetachFormulaCell(aPos1, **itf1);
+                DetachFormulaCell(aPos2, **itf2);
                 ScFormulaCell* pNew1 = cloneFormulaCell(pDocument, ScAddress(nCol, nRow1, nTab), *pOld2);
                 ScFormulaCell* pNew2 = cloneFormulaCell(pDocument, ScAddress(nCol, nRow2, nTab), *pOld1);
                 *itf1 = pNew1;
@@ -920,7 +921,7 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
             {
                 // 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);
+                DetachFormulaCell(aPos2, *aCell2.mpFormula);
                 it1 = maCells.set(it1, nRow1, pNew);
                 maCells.set_empty(it1, nRow2, nRow2); // original formula cell gets deleted.
                 ActivateNewFormulaCell(it1, nRow1, *pNew);
@@ -964,7 +965,7 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
             {
                 // 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);
+                DetachFormulaCell(aPos1, *aCell1.mpFormula);
                 it1 = maCells.set_empty(it1, nRow1, nRow1); // original formula cell is gone.
                 it1 = maCells.set(it1, nRow2, pNew);
                 ActivateNewFormulaCell(it1, nRow2, *pNew);
@@ -999,7 +1000,7 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
                 break;
                 case CELLTYPE_FORMULA:
                 {
-                    DetouchFormulaCell(aPos2, *aCell2.mpFormula);
+                    DetachFormulaCell(aPos2, *aCell2.mpFormula);
                     ScFormulaCell* pNew = cloneFormulaCell(pDocument, ScAddress(nCol, nRow1, nTab), *aCell2.mpFormula);
                     it1 = maCells.set(it1, nRow1, pNew);
                     ActivateNewFormulaCell(it1, nRow1, *pNew);
@@ -1032,7 +1033,7 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
                 case CELLTYPE_FORMULA:
                 {
                     // cell 1 - string, cell 2 - formula
-                    DetouchFormulaCell(aPos2, *aCell2.mpFormula);
+                    DetachFormulaCell(aPos2, *aCell2.mpFormula);
                     ScFormulaCell* pNew = cloneFormulaCell(pDocument, ScAddress(nCol, nRow1, nTab), *aCell2.mpFormula);
                     it1 = maCells.set(it1, nRow1, pNew);
                     ActivateNewFormulaCell(it1, nRow1, *pNew);
@@ -1061,7 +1062,7 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
                 break;
                 case CELLTYPE_FORMULA:
                 {
-                    DetouchFormulaCell(aPos2, *aCell2.mpFormula);
+                    DetachFormulaCell(aPos2, *aCell2.mpFormula);
                     ScFormulaCell* pNew = cloneFormulaCell(pDocument, ScAddress(nCol, nRow1, nTab), *aCell2.mpFormula);
                     it1 = maCells.set(it1, nRow1, pNew);
                     ActivateNewFormulaCell(it1, nRow1, *pNew);
@@ -1078,7 +1079,7 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
         case CELLTYPE_FORMULA:
         {
             // cell 1 is a formula cell and cell 2 is not.
-            DetouchFormulaCell(aPos1, *aCell1.mpFormula);
+            DetachFormulaCell(aPos1, *aCell1.mpFormula);
             ScFormulaCell* pNew = cloneFormulaCell(pDocument, ScAddress(nCol, nRow2, nTab), *aCell1.mpFormula);
             switch (aCell2.meType)
             {
@@ -1371,7 +1372,8 @@ public:
                 }
 
                 // Group the cloned formula cells.
-                groupFormulaCells(aCloned);
+                if (!aCloned.empty())
+                    sc::SharedFormulaUtil::groupFormulaCells(aCloned.begin(), aCloned.end());
 
                 sc::CellStoreType& rDestCells = mrDestCol.GetCellStore();
                 maDestPos.miCellPos = rDestCells.set(
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index 3fe48fb..58abd53 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -1533,10 +1533,6 @@ void ScColumn::CellStorageModified()
 #endif
 }
 
-void ScColumn::RegroupFormulaCells( SCROW /*nRow1*/, SCROW /*nRow2*/ )
-{
-}
-
 #if DEBUG_COLUMN_STORAGE
 
 namespace {
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index d22825c..690bc8a 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -45,6 +45,7 @@
 #include "mtvcellfunc.hxx"
 #include "scopetools.hxx"
 #include "editutil.hxx"
+#include "sharedformula.hxx"
 
 #include <com/sun/star/i18n/LocaleDataItem.hpp>
 
@@ -91,29 +92,6 @@ void ScColumn::BroadcastCells( const std::vector<SCROW>& rRows )
     broadcastCells(*pDocument, nCol, nTab, rRows);
 }
 
-namespace {
-
-class EndListeningHandler
-{
-    ScDocument* mpDoc;
-public:
-    EndListeningHandler(ScDocument* pDoc) : mpDoc(pDoc) {}
-
-    void operator() (size_t, ScFormulaCell* p)
-    {
-        p->EndListeningTo(mpDoc);
-    }
-};
-
-}
-
-void ScColumn::EndFormulaListening( sc::ColumnBlockPosition& rBlockPos, SCROW nRow1, SCROW nRow2 )
-{
-    EndListeningHandler aFunc(pDocument);
-    rBlockPos.miCellPos =
-        sc::ProcessFormula(rBlockPos.miCellPos, maCells, nRow1, nRow2, aFunc);
-}
-
 struct DirtyCellInterpreter
 {
     void operator() (size_t, ScFormulaCell* p)
@@ -411,8 +389,8 @@ void ScColumn::JoinNewFormulaCell(
     }
 }
 
-void ScColumn::DetouchFormulaCell(
-    const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell ) const
+void ScColumn::DetachFormulaCell(
+    const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell )
 {
     if (!pDocument->IsClipOrUndo())
         // Have the dying formula cell stop listening.
@@ -422,6 +400,42 @@ void ScColumn::DetouchFormulaCell(
         UnshareFormulaCell(aPos, rCell);
 }
 
+namespace {
+
+class DetachFormulaCellsHandler
+{
+    ScDocument* mpDoc;
+public:
+    DetachFormulaCellsHandler(ScDocument* pDoc) : mpDoc(pDoc) {}
+
+    void operator() (size_t /*nRow*/, ScFormulaCell* pCell)
+    {
+        pCell->EndListeningTo(mpDoc);
+    }
+};
+
+}
+
+void ScColumn::DetachFormulaCells(
+    const sc::CellStoreType::position_type& aPos, size_t nLength )
+{
+    // Split formula grouping at the top and bottom boundaries.
+    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);
+    }
+
+    if (pDocument->IsClipOrUndo())
+        return;
+
+    DetachFormulaCellsHandler aFunc(pDocument);
+    sc::ProcessFormula(aPos.first, maCells, nRow, nNextTopRow-1, aFunc);
+}
+
 void ScColumn::UnshareFormulaCell(
     const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell ) const
 {
@@ -617,7 +631,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);
-        DetouchFormulaCell(aPos, rCell);
+        DetachFormulaCell(aPos, rCell);
     }
 
     return itRet;
@@ -1242,11 +1256,7 @@ void lcl_AddCode( ScTokenArray& rArr, const ScFormulaCell* pCell )
 class MixDataHandler
 {
     ScColumn& mrDestColumn;
-
-    sc::CellStoreType& mrDestCells;
-    sc::CellStoreType::iterator miDestPos;
-
-    sc::CellTextAttrStoreType& mrDestAttrs;
+    sc::ColumnBlockPosition& mrBlockPos;
 
     sc::CellStoreType maNewCells;
     sc::CellStoreType::iterator miNewCellsPos;
@@ -1258,37 +1268,30 @@ class MixDataHandler
 
 public:
     MixDataHandler(
-        sc::ColumnBlockPosition* pBlockPos,
+        sc::ColumnBlockPosition& rBlockPos,
         ScColumn& rDestColumn,
-        sc::CellStoreType& rDestCells,
-        sc::CellTextAttrStoreType& rDestAttrs,
         SCROW nRow1, SCROW nRow2,
         sal_uInt16 nFunction, bool bSkipEmpty) :
         mrDestColumn(rDestColumn),
-        mrDestCells(rDestCells),
-        mrDestAttrs(rDestAttrs),
+        mrBlockPos(rBlockPos),
         maNewCells(nRow2 - nRow1 + 1),
         miNewCellsPos(maNewCells.begin()),
         mnRowOffset(nRow1),
         mnFunction(nFunction),
         mbSkipEmpty(bSkipEmpty)
     {
-        if (pBlockPos)
-            miDestPos = pBlockPos->miCellPos;
-        else
-            miDestPos = mrDestCells.begin();
     }
 
     void operator() (size_t nRow, double f)
     {
-        std::pair<sc::CellStoreType::iterator, size_t> aPos = mrDestCells.position(miDestPos, nRow);
-        miDestPos = aPos.first;
-        switch (miDestPos->type)
+        sc::CellStoreType::position_type aPos = mrDestColumn.GetCellStore().position(mrBlockPos.miCellPos, nRow);
+        mrBlockPos.miCellPos = aPos.first;
+        switch (aPos.first->type)
         {
             case sc::element_type_numeric:
             {
                 // Both src and dest are of numeric type.
-                bool bOk = lcl_DoFunction(f, sc::numeric_block::at(*miDestPos->data, aPos.second), mnFunction);
+                bool bOk = lcl_DoFunction(f, sc::numeric_block::at(*aPos.first->data, aPos.second), mnFunction);
 
                 if (bOk)
                     miNewCellsPos = maNewCells.set(miNewCellsPos, nRow-mnRowOffset, f);
@@ -1323,7 +1326,7 @@ public:
                 aArr.AddOpCode(eOp); // Function
 
                 // Second row
-                ScFormulaCell* pDest = sc::formula_block::at(*miDestPos->data, aPos.second);
+                ScFormulaCell* pDest = sc::formula_block::at(*aPos.first->data, aPos.second);
                 lcl_AddCode(aArr, pDest);
 
                 miNewCellsPos = maNewCells.set(
@@ -1357,9 +1360,9 @@ public:
 
     void operator() (size_t nRow, const ScFormulaCell* p)
     {
-        std::pair<sc::CellStoreType::iterator, size_t> aPos = mrDestCells.position(miDestPos, nRow);
-        miDestPos = aPos.first;
-        switch (miDestPos->type)
+        sc::CellStoreType::position_type aPos = mrDestColumn.GetCellStore().position(mrBlockPos.miCellPos, nRow);
+        mrBlockPos.miCellPos = aPos.first;
+        switch (aPos.first->type)
         {
             case sc::element_type_numeric:
             {
@@ -1381,7 +1384,7 @@ public:
                 aArr.AddOpCode(eOp); // Function
 
                 // Second row
-                aArr.AddDouble(sc::numeric_block::at(*miDestPos->data, aPos.second));
+                aArr.AddDouble(sc::numeric_block::at(*aPos.first->data, aPos.second));
 
                 miNewCellsPos = maNewCells.set(
                     miNewCellsPos, nRow-mnRowOffset,
@@ -1409,7 +1412,7 @@ public:
                 aArr.AddOpCode(eOp); // Function
 
                 // Second row
-                ScFormulaCell* pDest = sc::formula_block::at(*miDestPos->data, aPos.second);
+                ScFormulaCell* pDest = sc::formula_block::at(*aPos.first->data, aPos.second);
                 lcl_AddCode(aArr, pDest);
 
                 miNewCellsPos = maNewCells.set(
@@ -1445,9 +1448,9 @@ public:
         for (size_t i = 0; i < nDataSize; ++i)
         {
             size_t nDestRow = nTopRow + i;
-            std::pair<sc::CellStoreType::iterator, size_t> aPos = mrDestCells.position(miDestPos, nDestRow);
-            miDestPos = aPos.first;
-            switch (miDestPos->type)
+            sc::CellStoreType::position_type aPos = mrDestColumn.GetCellStore().position(mrBlockPos.miCellPos, nDestRow);
+            mrBlockPos.miCellPos = aPos.first;
+            switch (aPos.first->type)
             {
                 case sc::element_type_numeric:
                 case sc::element_type_string:
@@ -1459,7 +1462,7 @@ public:
                     ScTokenArray aArr;
 
                     // First row
-                    ScFormulaCell* pSrc = sc::formula_block::at(*miDestPos->data, aPos.second);
+                    ScFormulaCell* pSrc = sc::formula_block::at(*aPos.first->data, aPos.second);
                     lcl_AddCode( aArr, pSrc);
 
                     // Operator
@@ -1490,21 +1493,17 @@ public:
     /**
      * Set the new cells to the destination (this) column.
      */
-    void commit(sc::ColumnBlockPosition* pDestBlockPos)
+    void commit()
     {
-        sc::ColumnBlockPosition aDestBlockPos;
-        if (pDestBlockPos)
-            aDestBlockPos = *pDestBlockPos;
-        else
-            mrDestColumn.InitBlockPosition(aDestBlockPos);
+        sc::CellStoreType& rDestCells = mrDestColumn.GetCellStore();
 
         // Stop all formula cells in the destination range first.
-        sc::ColumnBlockPosition aCopy = aDestBlockPos;
-        mrDestColumn.EndFormulaListening(aCopy, mnRowOffset, mnRowOffset + maNewCells.size() - 1);
+        sc::CellStoreType::position_type aPos = rDestCells.position(mrBlockPos.miCellPos, mnRowOffset);
+        mrDestColumn.DetachFormulaCells(aPos, maNewCells.size());
 
         // Move the new cells to the destination range.
-        sc::CellStoreType::iterator& itDestPos = aDestBlockPos.miCellPos;
-        sc::CellTextAttrStoreType::iterator& itDestAttrPos = aDestBlockPos.miCellTextAttrPos;
+        sc::CellStoreType::iterator& itDestPos = mrBlockPos.miCellPos;
+        sc::CellTextAttrStoreType::iterator& itDestAttrPos = mrBlockPos.miCellTextAttrPos;
 
         sc::CellStoreType::iterator it = maNewCells.begin(), itEnd = maNewCells.end();
         for (; it != itEnd; ++it)
@@ -1518,32 +1517,49 @@ public:
                 {
                     sc::numeric_block::iterator itData = sc::numeric_block::begin(*it->data);
                     sc::numeric_block::iterator itDataEnd = sc::numeric_block::end(*it->data);
-                    itDestPos = mrDestCells.set(itDestPos, nDestRow, itData, itDataEnd);
+                    itDestPos = mrDestColumn.GetCellStore().set(itDestPos, nDestRow, itData, itDataEnd);
                 }
                 break;
                 case sc::element_type_string:
                 {
                     sc::string_block::iterator itData = sc::string_block::begin(*it->data);
                     sc::string_block::iterator itDataEnd = sc::string_block::end(*it->data);
-                    itDestPos = mrDestCells.set(itDestPos, nDestRow, itData, itDataEnd);
+                    itDestPos = rDestCells.set(itDestPos, nDestRow, itData, itDataEnd);
                 }
                 break;
                 case sc::element_type_edittext:
                 {
                     sc::edittext_block::iterator itData = sc::edittext_block::begin(*it->data);
                     sc::edittext_block::iterator itDataEnd = sc::edittext_block::end(*it->data);
-                    itDestPos = mrDestCells.set(itDestPos, nDestRow, itData, itDataEnd);
+                    itDestPos = rDestCells.set(itDestPos, nDestRow, itData, itDataEnd);
                 }
                 case sc::element_type_formula:
                 {
                     sc::formula_block::iterator itData = sc::formula_block::begin(*it->data);
                     sc::formula_block::iterator itDataEnd = sc::formula_block::end(*it->data);
-                    itDestPos = mrDestCells.set(itDestPos, nDestRow, itData, itDataEnd);
+
+                    // Group new formula cells before inserting them.
+                    sc::SharedFormulaUtil::groupFormulaCells(itData, itDataEnd);
+
+                    // Insert the formula cells to the column.
+                    itDestPos = rDestCells.set(itDestPos, nDestRow, itData, itDataEnd);
+
+                    // Merge with the previous formula group (if any).
+                    aPos = rDestCells.position(itDestPos, nDestRow);
+                    mrDestColumn.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);
+                    }
                 }
                 break;
                 case sc::element_type_empty:
                 {
-                    itDestPos = mrDestCells.set_empty(itDestPos, nDestRow, nDestRow+it->size-1);
+                    itDestPos = rDestCells.set_empty(itDestPos, nDestRow, nDestRow+it->size-1);
                     bHasContent = false;
                 }
                 break;
@@ -1551,19 +1567,17 @@ public:
                     ;
             }
 
+            sc::CellTextAttrStoreType& rDestAttrs = mrDestColumn.GetCellAttrStore();
             if (bHasContent)
             {
                 std::vector<sc::CellTextAttr> aAttrs(it->size, sc::CellTextAttr());
-                itDestAttrPos = mrDestAttrs.set(itDestAttrPos, nDestRow, aAttrs.begin(), aAttrs.end());
+                itDestAttrPos = rDestAttrs.set(itDestAttrPos, nDestRow, aAttrs.begin(), aAttrs.end());
             }
             else
-                itDestAttrPos = mrDestAttrs.set_empty(itDestAttrPos, nDestRow, nDestRow+it->size-1);
+                itDestAttrPos = rDestAttrs.set_empty(itDestAttrPos, nDestRow, nDestRow+it->size-1);
         }
 
         maNewCells.release();
-
-        if (pDestBlockPos)
-            *pDestBlockPos = aDestBlockPos;
     }
 };
 
@@ -1576,11 +1590,13 @@ void ScColumn::MixData(
     // destination (this column) block position.
 
     sc::ColumnBlockPosition* p = rCxt.getBlockPosition(nTab, nCol);
-    MixDataHandler aFunc(p, *this, maCells, maCellTextAttrs, nRow1, nRow2, nFunction, bSkipEmpty);
+    if (!p)
+        return;
+
+    MixDataHandler aFunc(*p, *this, nRow1, nRow2, nFunction, bSkipEmpty);
     sc::ParseAll(rSrcCol.maCells.begin(), rSrcCol.maCells, nRow1, nRow2, aFunc, aFunc);
 
-    aFunc.commit(p);
-    RegroupFormulaCells(nRow1, nRow2);
+    aFunc.commit();
     CellStorageModified();
 }
 
diff --git a/sc/source/core/tool/sharedformula.cxx b/sc/source/core/tool/sharedformula.cxx
new file mode 100644
index 0000000..7b6ac84
--- /dev/null
+++ b/sc/source/core/tool/sharedformula.cxx
@@ -0,0 +1,18 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "sharedformula.hxx"
+
+namespace sc {
+
+
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */


More information about the Libreoffice-commits mailing list