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

Kohei Yoshida kohei.yoshida at gmail.com
Wed Jun 26 09:17:24 PDT 2013


 sc/Library_sc.mk                         |    1 
 sc/inc/cellclonehandler.hxx              |   68 ---
 sc/inc/column.hxx                        |   34 +
 sc/inc/document.hxx                      |   10 
 sc/inc/table.hxx                         |    4 
 sc/inc/validat.hxx                       |    1 
 sc/source/core/data/cellclonehandler.cxx |  116 ------
 sc/source/core/data/column.cxx           |  581 +++++++++++++++++++++----------
 sc/source/core/data/column2.cxx          |   50 ++
 sc/source/core/data/column3.cxx          |  151 ++------
 sc/source/core/data/dociter.cxx          |   14 
 sc/source/core/data/documen8.cxx         |    9 
 sc/source/core/data/document.cxx         |   18 
 sc/source/core/data/table1.cxx           |   14 
 sc/source/core/inc/interpre.hxx          |    1 
 sc/source/filter/xml/xmlexprt.cxx        |   13 
 sc/source/ui/app/transobj.cxx            |    4 
 sc/source/ui/view/tabview4.cxx           |   11 
 18 files changed, 574 insertions(+), 526 deletions(-)

New commits:
commit 6a163e4ab553500a725ba8dab6426d28682f3aea
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Wed Jun 26 11:45:28 2013 -0400

    Implement a way to set an array of formula results to formula cell group.
    
    Conflicts:
    	sc/source/core/tool/formulagroup.cxx
    
    Change-Id: Ifdea531e963339607a5066f81af32ffedfd408aa

diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 93d292d..974a934 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -447,6 +447,7 @@ public:
     bool ResolveStaticReference( ScMatrix& rMat, SCCOL nMatCol, SCROW nRow1, SCROW nRow2 );
     void FillMatrix( ScMatrix& rMat, size_t nMatCol, SCROW nRow1, SCROW nRow2 ) const;
     const double* FetchDoubleArray( sc::FormulaGroupContext& rCxt, SCROW nRow1, SCROW nRow2 ) const;
+    void SetFormulaResults( SCROW nRow, const double* pResults, size_t nLen );
 
     void SetNumberFormat( SCROW nRow, sal_uInt32 nNumberFormat );
 
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 2166898..f123008 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -1715,6 +1715,16 @@ public:
 
     void FillMatrix( ScMatrix& rMat, SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ) const;
 
+    /**
+     * Set an array of numerical formula results to a group of contiguous
+     * formula cells.
+     *
+     * @param rTopPos position of the top formula cell of a group.
+     * @param pResults array of numeric results.
+     * @param nLen length of numeric results.
+     */
+    void SetFormulaResults( const ScAddress& rTopPos, const double* pResults, size_t nLen );
+
 private:
     ScDocument(const ScDocument& r); // disabled with no definition
 
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index e945477..0d0aa8e 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -849,6 +849,8 @@ public:
 
     void InterpretDirtyCells( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 );
 
+    void SetFormulaResults( SCCOL nCol, SCROW nRow, const double* pResults, size_t nLen );
+
     /** Replace behaves differently to the Search; adjust the rCol and rRow accordingly.
 
         'Replace' replaces at the 'current' position, but in order to achieve
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index 726da1a..ee68502 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -2095,6 +2095,32 @@ const double* ScColumn::FetchDoubleArray( sc::FormulaGroupContext& /*rCxt*/, SCR
     return &sc::numeric_block::at(*aPos.first->data, aPos.second);
 }
 
+void ScColumn::SetFormulaResults( SCROW nRow, const double* pResults, size_t nLen )
+{
+    sc::CellStoreType::position_type aPos = maCells.position(nRow);
+    sc::CellStoreType::iterator it = aPos.first;
+    if (it->type != sc::element_type_formula)
+        // This is not a formula block.
+        return;
+
+    size_t nBlockLen = it->size - aPos.second;
+    if (nBlockLen < nLen)
+        // Result array is longer than the length of formula cells. Not good.
+        return;
+
+    sc::formula_block::iterator itCell = sc::formula_block::begin(*it->data);
+    std::advance(itCell, aPos.second);
+
+    const double* pResEnd = pResults + nLen;
+    for (; pResults != pResEnd; ++pResults, ++itCell)
+    {
+        ScFormulaCell& rCell = **itCell;
+        rCell.SetResultDouble(*pResults);
+        rCell.ResetDirty();
+        rCell.SetChanged(true);
+    }
+}
+
 void ScColumn::SetNumberFormat( SCROW nRow, sal_uInt32 nNumberFormat )
 {
     short eOldType = pDocument->GetFormatTable()->GetType(
diff --git a/sc/source/core/data/documen8.cxx b/sc/source/core/data/documen8.cxx
index feec6ff..f75058d 100644
--- a/sc/source/core/data/documen8.cxx
+++ b/sc/source/core/data/documen8.cxx
@@ -449,6 +449,15 @@ void ScDocument::FillMatrix(
     pTab->FillMatrix(rMat, nCol1, nRow1, nCol2, nRow2);
 }
 
+void ScDocument::SetFormulaResults( const ScAddress& rTopPos, const double* pResults, size_t nLen )
+{
+    ScTable* pTab = FetchTable(rTopPos.Tab());
+    if (!pTab)
+        return;
+
+    pTab->SetFormulaResults(rTopPos.Col(), rTopPos.Row(), pResults, nLen);
+}
+
 
 //------------------------------------------------------------------------
 
diff --git a/sc/source/core/data/table1.cxx b/sc/source/core/data/table1.cxx
index 2de23b1..be6f4ae 100644
--- a/sc/source/core/data/table1.cxx
+++ b/sc/source/core/data/table1.cxx
@@ -2215,6 +2215,14 @@ void ScTable::InterpretDirtyCells( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW
         aCol[nCol].InterpretDirtyCells(nRow1, nRow2);
 }
 
+void ScTable::SetFormulaResults( SCCOL nCol, SCROW nRow, const double* pResults, size_t nLen )
+{
+    if (!ValidCol(nCol))
+        return;
+
+    aCol[nCol].SetFormulaResults(nRow, pResults, nLen);
+}
+
 const SvtBroadcaster* ScTable::GetBroadcaster( SCCOL nCol, SCROW nRow ) const
 {
     if (!ValidColRow(nCol, nRow))
commit f9658bf7606f4bf6bbf291c2f362c06e264df105
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Wed Jun 26 02:53:40 2013 -0400

    Remove these unused files.
    
    Change-Id: Ifcff5ee2849f9f390f82197fa60a3cea12dd0b27

diff --git a/sc/Library_sc.mk b/sc/Library_sc.mk
index d2a3dea..070aa37 100644
--- a/sc/Library_sc.mk
+++ b/sc/Library_sc.mk
@@ -95,7 +95,6 @@ $(eval $(call gb_Library_add_exception_objects,sc,\
 	sc/source/core/data/autonamecache \
 	sc/source/core/data/bcaslot \
 	sc/source/core/data/bigrange \
-	sc/source/core/data/cellclonehandler \
 	sc/source/core/data/cellvalue \
 	sc/source/core/data/clipcontext \
 	sc/source/core/data/clipparam \
diff --git a/sc/inc/cellclonehandler.hxx b/sc/inc/cellclonehandler.hxx
deleted file mode 100644
index 4ae8123..0000000
--- a/sc/inc/cellclonehandler.hxx
+++ /dev/null
@@ -1,68 +0,0 @@
-/* -*- 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_CELLCLONEHANDLER_HXX
-#define SC_CELLCLONEHANDLER_HXX
-
-#include "rtl/ustring.hxx"
-#include "address.hxx"
-#include "mtvelements.hxx"
-
-class ScDocument;
-class EditTextObject;
-class ScFormulaCell;
-
-namespace sc {
-
-class CellBlockCloneHandler
-{
-    ScDocument& mrSrcDoc;
-    ScDocument& mrDestDoc;
-    CellStoreType& mrDestCellStore;
-    CellTextAttrStoreType& mrDestAttrStore;
-
-protected:
-    ScDocument& getSrcDoc();
-    ScDocument& getDestDoc();
-    const ScDocument& getDestDoc() const;
-    CellStoreType& getDestCellStore();
-    CellTextAttrStoreType& getDestAttrStore();
-
-    void setDefaultAttrToDest(ColumnBlockPosition& rPos, SCROW nRow);
-    void setDefaultAttrsToDest(ColumnBlockPosition& rPos, SCROW nRow, size_t nSize);
-
-public:
-    CellBlockCloneHandler(
-        ScDocument& rSrcDoc, ScDocument& rDestDoc,
-        CellStoreType& rDestCellStore, CellTextAttrStoreType& rDestAttrStore);
-
-    virtual ~CellBlockCloneHandler();
-
-    virtual void cloneDoubleBlock(
-        ColumnBlockPosition& rPos, const ScAddress& rSrcPos, const ScAddress& rDestPos,
-        const numeric_block::const_iterator& itBegin, const numeric_block::const_iterator& itEnd);
-
-    virtual void cloneStringBlock(
-        ColumnBlockPosition& rPos, const ScAddress& rSrcPos, const ScAddress& rDestPos,
-        const string_block::const_iterator& itBegin, const string_block::const_iterator& itEnd);
-
-    virtual void cloneEditTextBlock(
-        ColumnBlockPosition& rPos, const ScAddress& rSrcPos, const ScAddress& rDestPos,
-        const edittext_block::const_iterator& itBegin, const edittext_block::const_iterator& itEnd);
-
-    virtual void cloneFormulaBlock(
-        ColumnBlockPosition& rPos, const ScAddress& rSrcPos, const ScAddress& rDestPos,
-        const formula_block::const_iterator& itBegin, const formula_block::const_iterator& itEnd);
-};
-
-}
-
-#endif
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 8e4502a..93d292d 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -45,7 +45,6 @@ namespace sc {
     class CopyToDocContext;
     class MixDocContext;
     struct ColumnBlockPosition;
-    class CellBlockCloneHandler;
     class SingleColumnSpanSet;
 }
 
diff --git a/sc/source/core/data/cellclonehandler.cxx b/sc/source/core/data/cellclonehandler.cxx
deleted file mode 100644
index 8f5bd17..0000000
--- a/sc/source/core/data/cellclonehandler.cxx
+++ /dev/null
@@ -1,116 +0,0 @@
-/* -*- 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 "cellclonehandler.hxx"
-#include "editutil.hxx"
-#include "document.hxx"
-
-namespace sc {
-
-CellBlockCloneHandler::CellBlockCloneHandler(
-    ScDocument& rSrcDoc, ScDocument& rDestDoc,
-    CellStoreType& rDestCellStore, CellTextAttrStoreType& rDestAttrStore) :
-    mrSrcDoc(rSrcDoc), mrDestDoc(rDestDoc),
-    mrDestCellStore(rDestCellStore), mrDestAttrStore(rDestAttrStore) {}
-
-CellBlockCloneHandler::~CellBlockCloneHandler() {}
-
-ScDocument& CellBlockCloneHandler::getSrcDoc()
-{
-    return mrSrcDoc;
-}
-
-ScDocument& CellBlockCloneHandler::getDestDoc()
-{
-    return mrDestDoc;
-}
-
-const ScDocument& CellBlockCloneHandler::getDestDoc() const
-{
-    return mrDestDoc;
-}
-
-CellStoreType& CellBlockCloneHandler::getDestCellStore()
-{
-    return mrDestCellStore;
-}
-
-CellTextAttrStoreType& CellBlockCloneHandler::getDestAttrStore()
-{
-    return mrDestAttrStore;
-}
-
-void CellBlockCloneHandler::setDefaultAttrToDest(ColumnBlockPosition& rPos, SCROW nRow)
-{
-    rPos.miCellTextAttrPos = mrDestAttrStore.set(rPos.miCellTextAttrPos, nRow, CellTextAttr());
-}
-
-void CellBlockCloneHandler::setDefaultAttrsToDest(ColumnBlockPosition& rPos, SCROW nRow, size_t nSize)
-{
-    std::vector<sc::CellTextAttr> aAttrs(nSize); // default values
-    rPos.miCellTextAttrPos = mrDestAttrStore.set(
-        rPos.miCellTextAttrPos, nRow, aAttrs.begin(), aAttrs.end());
-}
-
-void CellBlockCloneHandler::cloneDoubleBlock(
-    ColumnBlockPosition& rPos, const ScAddress& /*rSrcPos*/, const ScAddress& rDestPos,
-    const numeric_block::const_iterator& itBegin, const numeric_block::const_iterator& itEnd)
-{
-    rPos.miCellPos = mrDestCellStore.set(rPos.miCellPos, rDestPos.Row(), itBegin, itEnd);
-    setDefaultAttrsToDest(rPos, rDestPos.Row(), std::distance(itBegin, itEnd));
-}
-
-void CellBlockCloneHandler::cloneStringBlock(
-    ColumnBlockPosition& rPos, const ScAddress& /*rSrcPos*/, const ScAddress& rDestPos,
-    const string_block::const_iterator& itBegin, const string_block::const_iterator& itEnd)
-{
-    rPos.miCellPos = mrDestCellStore.set(rPos.miCellPos, rDestPos.Row(), itBegin, itEnd);
-    setDefaultAttrsToDest(rPos, rDestPos.Row(), std::distance(itBegin, itEnd));
-}
-
-void CellBlockCloneHandler::cloneEditTextBlock(
-    ColumnBlockPosition& rPos, const ScAddress& /*rSrcPos*/, const ScAddress& rDestPos,
-    const edittext_block::const_iterator& itBegin, const edittext_block::const_iterator& itEnd)
-{
-    std::vector<EditTextObject*> aCloned;
-    aCloned.reserve(std::distance(itBegin, itEnd));
-    for (edittext_block::const_iterator it = itBegin; it != itEnd; ++it)
-        aCloned.push_back(ScEditUtil::Clone(**it, getDestDoc()));
-
-    rPos.miCellPos = getDestCellStore().set(
-        rPos.miCellPos, rDestPos.Row(), aCloned.begin(), aCloned.end());
-
-    setDefaultAttrsToDest(rPos, rDestPos.Row(), std::distance(itBegin, itEnd));
-}
-
-void CellBlockCloneHandler::cloneFormulaBlock(
-    ColumnBlockPosition& rPos, const ScAddress& /*rSrcPos*/, const ScAddress& rDestPos,
-    const formula_block::const_iterator& itBegin, const formula_block::const_iterator& itEnd)
-{
-    std::vector<ScFormulaCell*> aCloned;
-    aCloned.reserve(std::distance(itBegin, itEnd));
-    ScAddress aDestPos = rDestPos;
-    for (formula_block::const_iterator it = itBegin; it != itEnd; ++it, aDestPos.IncRow())
-    {
-        const ScFormulaCell& rOld = **it;
-        if (rOld.GetDirty() && getSrcDoc().GetAutoCalc())
-            const_cast<ScFormulaCell&>(rOld).Interpret();
-
-        aCloned.push_back(new ScFormulaCell(rOld, getDestDoc(), aDestPos));
-    }
-
-    rPos.miCellPos = getDestCellStore().set(
-        rPos.miCellPos, rDestPos.Row(), aCloned.begin(), aCloned.end());
-
-    setDefaultAttrsToDest(rPos, rDestPos.Row(), std::distance(itBegin, itEnd));
-}
-
-}
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index 3f54d59..f3fb8cf 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -36,7 +36,6 @@
 #include "clipcontext.hxx"
 #include "types.hxx"
 #include "editutil.hxx"
-#include "cellclonehandler.hxx"
 #include "mtvcellfunc.hxx"
 #include "columnspanset.hxx"
 #include "scopetools.hxx"
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index 5d1dc7e..aef6852 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -44,7 +44,6 @@
 #include "columnspanset.hxx"
 #include "mtvcellfunc.hxx"
 #include "scopetools.hxx"
-#include "cellclonehandler.hxx"
 #include "editutil.hxx"
 
 #include <com/sun/star/i18n/LocaleDataItem.hpp>
commit edb7cb545e344229b78a9ab2a8cba3aebd5ddd32
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Wed Jun 26 02:49:00 2013 -0400

    Adopt CopyAsLinkHandler as well.
    
    With this, we no longer use CopyCellsInRangeToColumn().
    
    Change-Id: I6506d72d084f724ccf7a6395a0daf88fe7bff40e

diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index c6b3945..8e4502a 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -485,10 +485,6 @@ public:
 
 private:
 
-    void CopyCellsInRangeToColumn(
-        sc::ColumnBlockConstPosition* rSrcColPos, sc::ColumnBlockPosition* pDestColPos,
-        sc::CellBlockCloneHandler& Hdl, SCROW nRow1, SCROW nRow2, ScColumn& rColumn ) const;
-
     sc::CellStoreType::iterator GetPositionToInsert( SCROW nRow );
     sc::CellStoreType::iterator GetPositionToInsert( const sc::CellStoreType::iterator& it, SCROW nRow );
     void ActivateNewFormulaCell( ScFormulaCell* pCell );
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index 2310212..3f54d59 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -1558,92 +1558,114 @@ bool canCopyValue(const ScDocument& rDoc, const ScAddress& rPos, sal_uInt16 nFla
     return ((nFlags & IDF_VALUE) != 0);
 }
 
-class CopyAsLinkHandler : public sc::CellBlockCloneHandler
+class CopyAsLinkHandler
 {
+    const ScColumn& mrSrcCol;
+    ScColumn& mrDestCol;
+    sc::ColumnBlockPosition maDestPos;
+    sc::ColumnBlockPosition* mpDestPos;
     sal_uInt16 mnCopyFlags;
     std::vector<ScFormulaCell*> maCellBuffer;
 
-    ScFormulaCell* createRefCell(const ScAddress& rSrcPos, const ScAddress& rDestPos)
+    void setDefaultAttrToDest(size_t nRow)
+    {
+        maDestPos.miCellTextAttrPos = mrDestCol.GetCellAttrStore().set(
+            maDestPos.miCellTextAttrPos, nRow, sc::CellTextAttr());
+    }
+
+    void setDefaultAttrsToDest(size_t nRow, size_t nSize)
+    {
+        std::vector<sc::CellTextAttr> aAttrs(nSize); // default values
+        maDestPos.miCellTextAttrPos = mrDestCol.GetCellAttrStore().set(
+            maDestPos.miCellTextAttrPos, nRow, aAttrs.begin(), aAttrs.end());
+    }
+
+    ScFormulaCell* createRefCell(size_t nRow)
     {
         ScSingleRefData aRef;
-        aRef.InitAddress(rSrcPos); // Absolute reference.
+        aRef.InitAddress(ScAddress(mrSrcCol.GetCol(), nRow, mrSrcCol.GetTab())); // Absolute reference.
         aRef.SetFlag3D(true);
 
         ScTokenArray aArr;
         aArr.AddSingleReference(aRef);
-        return new ScFormulaCell(&getDestDoc(), rDestPos, &aArr);
+        return new ScFormulaCell(&mrDestCol.GetDoc(), ScAddress(mrDestCol.GetCol(), nRow, mrDestCol.GetTab()), &aArr);
     }
 
-    template<typename _DataBlock>
-    void createRefBlock(
-        sc::ColumnBlockPosition& rPos, const ScAddress& rSrcPos, const ScAddress& rDestPos,
-        const typename _DataBlock::const_iterator& itBegin, const typename _DataBlock::const_iterator& itEnd)
+    void createRefBlock(const sc::CellStoreType::value_type& aNode, size_t nOffset, size_t nDataSize)
     {
-        size_t nSize = std::distance(itBegin, itEnd);
+        size_t nTopRow = aNode.position + nOffset;
+
         maCellBuffer.clear();
-        maCellBuffer.reserve(nSize);
-        ScAddress aSrcPos = rSrcPos;
-        ScAddress aDestPos = rDestPos;
-        for (typename _DataBlock::const_iterator it = itBegin; it != itEnd; ++it, aSrcPos.IncRow(), aDestPos.IncRow())
-            maCellBuffer.push_back(createRefCell(aSrcPos, aDestPos));
+        maCellBuffer.reserve(nDataSize);
+
+        for (size_t i = 0; i < nDataSize; ++i)
+            maCellBuffer.push_back(createRefCell(nTopRow + i));
 
-        rPos.miCellPos = getDestCellStore().set(rPos.miCellPos, rDestPos.Row(), maCellBuffer.begin(), maCellBuffer.end());
-        setDefaultAttrsToDest(rPos, rDestPos.Row(), nSize);
+        maDestPos.miCellPos = mrDestCol.GetCellStore().set(maDestPos.miCellPos, nTopRow, maCellBuffer.begin(), maCellBuffer.end());
+        setDefaultAttrsToDest(nTopRow, nDataSize);
     }
 
 public:
-    CopyAsLinkHandler(
-        ScDocument& rSrcDoc, ScDocument& rDestDoc, sc::CellStoreType& rDestCellStore, sc::CellTextAttrStoreType& rDestAttrStore, sal_uInt16 nCopyFlags) :
-        sc::CellBlockCloneHandler(rSrcDoc, rDestDoc, rDestCellStore, rDestAttrStore),
-        mnCopyFlags(nCopyFlags) {}
-
-    virtual void cloneDoubleBlock(
-        sc::ColumnBlockPosition& rPos, const ScAddress& rSrcPos, const ScAddress& rDestPos,
-        const sc::numeric_block::const_iterator& itBegin, const sc::numeric_block::const_iterator& itEnd)
+    CopyAsLinkHandler(const ScColumn& rSrcCol, ScColumn& rDestCol, sc::ColumnBlockPosition* pDestPos, sal_uInt16 nCopyFlags) :
+        mrSrcCol(rSrcCol), mrDestCol(rDestCol), mpDestPos(pDestPos), mnCopyFlags(nCopyFlags)
     {
-        if ((mnCopyFlags & (IDF_DATETIME|IDF_VALUE)) == 0)
-            return;
-
-        ScAddress aSrcPos = rSrcPos;
-        ScAddress aDestPos = rDestPos;
-        for (sc::numeric_block::const_iterator it = itBegin; it != itEnd; ++it, aSrcPos.IncRow(), aDestPos.IncRow())
-        {
-            if (!canCopyValue(getSrcDoc(), aSrcPos, mnCopyFlags))
-                continue;
-
-            rPos.miCellPos = getDestCellStore().set(rPos.miCellPos, aDestPos.Row(), createRefCell(aSrcPos, aDestPos));
-            setDefaultAttrToDest(rPos, aDestPos.Row());
-        }
+        if (mpDestPos)
+            maDestPos = *mpDestPos;
     }
 
-    virtual void cloneStringBlock(
-        sc::ColumnBlockPosition& rPos, const ScAddress& rSrcPos, const ScAddress& rDestPos,
-        const sc::string_block::const_iterator& itBegin, const sc::string_block::const_iterator& itEnd)
+    ~CopyAsLinkHandler()
     {
-        if (!(mnCopyFlags & IDF_STRING))
-            return;
-
-        createRefBlock<sc::string_block>(rPos, rSrcPos, rDestPos, itBegin, itEnd);
+        if (mpDestPos)
+            *mpDestPos = maDestPos;
     }
 
-    virtual void cloneEditTextBlock(
-        sc::ColumnBlockPosition& rPos, const ScAddress& rSrcPos, const ScAddress& rDestPos,
-        const sc::edittext_block::const_iterator& itBegin, const sc::edittext_block::const_iterator& itEnd)
+    void operator() (const sc::CellStoreType::value_type& aNode, size_t nOffset, size_t nDataSize)
     {
-        if (!(mnCopyFlags & IDF_STRING))
-            return;
+        size_t nRow = aNode.position - nOffset;
 
-        createRefBlock<sc::edittext_block>(rPos, rSrcPos, rDestPos, itBegin, itEnd);
-    }
+        switch (aNode.type)
+        {
+            case sc::element_type_numeric:
+            {
+                if ((mnCopyFlags & (IDF_DATETIME|IDF_VALUE)) == 0)
+                    return;
 
-    virtual void cloneFormulaBlock(
-        sc::ColumnBlockPosition& rPos, const ScAddress& rSrcPos, const ScAddress& rDestPos,
-        const sc::formula_block::const_iterator& itBegin, const sc::formula_block::const_iterator& itEnd)
-    {
-        if (!(mnCopyFlags & IDF_FORMULA))
-            return;
+                sc::numeric_block::const_iterator it = sc::numeric_block::begin(*aNode.data);
+                std::advance(it, nOffset);
+                sc::numeric_block::const_iterator itEnd = it;
+                std::advance(itEnd, nDataSize);
 
-        createRefBlock<sc::formula_block>(rPos, rSrcPos, rDestPos, itBegin, itEnd);
+                ScAddress aSrcPos(mrSrcCol.GetCol(), nRow, mrSrcCol.GetTab());
+                for (; it != itEnd; ++it, aSrcPos.IncRow(), ++nRow)
+                {
+                    if (!canCopyValue(mrSrcCol.GetDoc(), aSrcPos, mnCopyFlags))
+                        continue;
+
+                    maDestPos.miCellPos = mrDestCol.GetCellStore().set(maDestPos.miCellPos, nRow, createRefCell(nRow));
+                    setDefaultAttrToDest(nRow);
+                }
+            }
+            break;
+            case sc::element_type_string:
+            case sc::element_type_edittext:
+            {
+                if (!(mnCopyFlags & IDF_STRING))
+                    return;
+
+                createRefBlock(aNode, nOffset, nDataSize);
+            }
+            break;
+            case sc::element_type_formula:
+            {
+                if (!(mnCopyFlags & IDF_FORMULA))
+                    return;
+
+                createRefBlock(aNode, nOffset, nDataSize);
+            }
+            break;
+            default:
+                ;
+        }
     }
 };
 
@@ -1920,21 +1942,19 @@ void ScColumn::CopyToColumn(
 
     if ((nFlags & IDF_CONTENTS) != 0)
     {
-        boost::scoped_ptr<sc::CellBlockCloneHandler> pHdl(NULL);
-
         if (bAsLink)
         {
-            pHdl.reset(new CopyAsLinkHandler(*pDocument, *rColumn.pDocument, rColumn.maCells, rColumn.maCellTextAttrs, nFlags));
-            CopyCellsInRangeToColumn(NULL, rCxt.getBlockPosition(rColumn.nTab, rColumn.nCol), *pHdl, nRow1, nRow2, rColumn);
+            CopyAsLinkHandler aFunc(*this, rColumn, rCxt.getBlockPosition(rColumn.nTab, rColumn.nCol), nFlags);
+            sc::ParseBlock(maCells.begin(), maCells, aFunc, nRow1, nRow2);
         }
         else
         {
             CopyByCloneHandler aFunc(*this, rColumn, rCxt.getBlockPosition(rColumn.nTab, rColumn.nCol), nFlags);
             sc::ParseBlock(maCells.begin(), maCells, aFunc, nRow1, nRow2);
-            rColumn.RegroupFormulaCells(nRow1, nRow2);
-            rColumn.CellStorageModified();
         }
 
+        rColumn.RegroupFormulaCells(nRow1, nRow2);
+        rColumn.CellStorageModified();
     }
 }
 
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index da10a49..5d1dc7e 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -323,111 +323,6 @@ void ScColumn::DeleteRow( SCROW nStartRow, SCSIZE nSize )
     std::for_each(aSpans.begin(), aSpans.end(), RangeBroadcaster(*pDocument, nTab, nCol));
 }
 
-void ScColumn::CopyCellsInRangeToColumn(
-    sc::ColumnBlockConstPosition* pSrcColPos,
-    sc::ColumnBlockPosition* pDestColPos, sc::CellBlockCloneHandler& rHdl, SCROW nRow1, SCROW nRow2, ScColumn& rColumn ) const
-{
-    sc::ColumnBlockConstPosition aSrcColPos;
-    sc::ColumnBlockPosition aDestColPos;
-
-    if (pSrcColPos)
-        aSrcColPos = *pSrcColPos;
-    else
-        InitBlockPosition(aSrcColPos);
-
-    if (pDestColPos)
-        aDestColPos = *pDestColPos;
-    else
-        rColumn.InitBlockPosition(aDestColPos);
-
-    std::pair<sc::CellStoreType::const_iterator,size_t> aPos = maCells.position(aSrcColPos.miCellPos, nRow1);
-    sc::CellStoreType::const_iterator it = aPos.first;
-    aSrcColPos.miCellPos = aPos.first;
-    size_t nOffset = aPos.second;
-    size_t nDataSize = 0;
-    size_t nCurRow = nRow1;
-
-    for (; it != maCells.end() && nCurRow <= static_cast<size_t>(nRow2); ++it, nOffset = 0, nCurRow += nDataSize)
-    {
-        bool bLastBlock = false;
-        nDataSize = it->size - nOffset;
-        if (nCurRow + nDataSize - 1 > static_cast<size_t>(nRow2))
-        {
-            // Truncate the block to copy to clipboard.
-            nDataSize = nRow2 - nCurRow + 1;
-            bLastBlock = true;
-        }
-
-        switch (it->type)
-        {
-            case sc::element_type_numeric:
-            {
-                sc::numeric_block::const_iterator itData = sc::numeric_block::begin(*it->data);
-                std::advance(itData, nOffset);
-                sc::numeric_block::const_iterator itDataEnd = itData;
-                std::advance(itDataEnd, nDataSize);
-                ScAddress aSrcPos(nCol, nCurRow, nTab);
-                ScAddress aDestPos(rColumn.nCol, nCurRow, rColumn.nTab);
-                rHdl.cloneDoubleBlock(aDestColPos, aSrcPos, aDestPos, itData, itDataEnd);
-            }
-            break;
-            case sc::element_type_string:
-            {
-                sc::string_block::const_iterator itData = sc::string_block::begin(*it->data);
-                std::advance(itData, nOffset);
-                sc::string_block::const_iterator itDataEnd = itData;
-                std::advance(itDataEnd, nDataSize);
-                ScAddress aSrcPos(nCol, nCurRow, nTab);
-                ScAddress aDestPos(rColumn.nCol, nCurRow, rColumn.nTab);
-                rHdl.cloneStringBlock(aDestColPos, aSrcPos, aDestPos, itData, itDataEnd);
-            }
-            break;
-            case sc::element_type_edittext:
-            {
-                sc::edittext_block::const_iterator itData = sc::edittext_block::begin(*it->data);
-                std::advance(itData, nOffset);
-                sc::edittext_block::const_iterator itDataEnd = itData;
-                std::advance(itDataEnd, nDataSize);
-                ScAddress aSrcPos(nCol, nCurRow, nTab);
-                ScAddress aDestPos(rColumn.nCol, nCurRow, rColumn.nTab);
-                rHdl.cloneEditTextBlock(aDestColPos, aSrcPos, aDestPos, itData, itDataEnd);
-            }
-            break;
-            case sc::element_type_formula:
-            {
-                sc::formula_block::const_iterator itData = sc::formula_block::begin(*it->data);
-                std::advance(itData, nOffset);
-                sc::formula_block::const_iterator itDataEnd = itData;
-                std::advance(itDataEnd, nDataSize);
-                ScAddress aSrcPos(nCol, nCurRow, nTab);
-                ScAddress aDestPos(rColumn.nCol, nCurRow, rColumn.nTab);
-                rHdl.cloneFormulaBlock(aDestColPos, aSrcPos, aDestPos, itData, itDataEnd);
-            }
-            break;
-            default:
-                ;
-        }
-
-        if (bLastBlock)
-            break;
-    }
-
-    if (pSrcColPos)
-    {
-        // Save the positions for the next iteration.
-        *pSrcColPos = aSrcColPos;
-    }
-
-    if (pDestColPos)
-    {
-        // Save the positions for the next iteration.
-        *pDestColPos = aDestColPos;
-    }
-
-    rColumn.RegroupFormulaCells(nRow1, nRow2);
-    rColumn.CellStorageModified();
-}
-
 sc::CellStoreType::iterator ScColumn::GetPositionToInsert( SCROW nRow )
 {
     return GetPositionToInsert(maCells.begin(), nRow);
commit e072b6e929724c700946a110529ec523f46d7919
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Wed Jun 26 02:02:14 2013 -0400

    Adopt CopyByCloneHandler to ParseBlock().
    
    Change-Id: Iac82967a9cdd1b7c3e062b1931bb306cf160bba0

diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index c561035..2310212 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -1302,7 +1302,7 @@ public:
 
     void operator() (const sc::CellStoreType::value_type& aNode, size_t nOffset, size_t nDataSize)
     {
-        size_t nTopRow = aNode.position;
+        size_t nTopRow = aNode.position - nOffset;
 
         switch (aNode.type)
         {
@@ -1647,14 +1647,31 @@ public:
     }
 };
 
-class CopyByCloneHandler : public sc::CellBlockCloneHandler
+class CopyByCloneHandler
 {
+    const ScColumn& mrSrcCol;
+    ScColumn& mrDestCol;
+    sc::ColumnBlockPosition maDestPos;
+    sc::ColumnBlockPosition* mpDestPos;
     sal_uInt16 mnCopyFlags;
 
-    void cloneFormulaCell(
-        sc::ColumnBlockPosition& rPos, const ScAddress& rSrcPos, const ScAddress& rDestPos,
-        ScFormulaCell& rSrcCell)
+    void setDefaultAttrToDest(size_t nRow)
     {
+        maDestPos.miCellTextAttrPos = mrDestCol.GetCellAttrStore().set(
+            maDestPos.miCellTextAttrPos, nRow, sc::CellTextAttr());
+    }
+
+    void setDefaultAttrsToDest(size_t nRow, size_t nSize)
+    {
+        std::vector<sc::CellTextAttr> aAttrs(nSize); // default values
+        maDestPos.miCellTextAttrPos = mrDestCol.GetCellAttrStore().set(
+            maDestPos.miCellTextAttrPos, nRow, aAttrs.begin(), aAttrs.end());
+    }
+
+    void cloneFormulaCell(size_t nRow, ScFormulaCell& rSrcCell)
+    {
+        ScAddress aDestPos(mrDestCol.GetCol(), nRow, mrDestCol.GetTab());
+
         bool bCloneValue          = (mnCopyFlags & IDF_VALUE) != 0;
         bool bCloneDateTime       = (mnCopyFlags & IDF_DATETIME) != 0;
         bool bCloneString         = (mnCopyFlags & IDF_STRING) != 0;
@@ -1679,15 +1696,14 @@ class CopyByCloneHandler : public sc::CellBlockCloneHandler
         if (bForceFormula || bCloneFormula)
         {
             // Clone as formula cell.
-            ScFormulaCell* pCell = new ScFormulaCell(rSrcCell, getDestDoc(), rDestPos);
+            ScFormulaCell* pCell = new ScFormulaCell(rSrcCell, mrDestCol.GetDoc(), aDestPos);
             pCell->SetDirtyVar();
-            rPos.miCellPos = getDestCellStore().set(rPos.miCellPos, rDestPos.Row(), pCell);
-            setDefaultAttrToDest(rPos, rDestPos.Row());
-
+            maDestPos.miCellPos = mrDestCol.GetCellStore().set(maDestPos.miCellPos, nRow, pCell);
+            setDefaultAttrToDest(nRow);
             return;
         }
 
-        if (getDestDoc().IsUndo())
+        if (mrDestCol.GetDoc().IsUndo())
             return;
 
         if (bCloneValue)
@@ -1696,11 +1712,11 @@ class CopyByCloneHandler : public sc::CellBlockCloneHandler
             if (nErr)
             {
                 // error codes are cloned with values
-                ScFormulaCell* pErrCell = new ScFormulaCell(&getDestDoc(), rDestPos);
+                ScFormulaCell* pErrCell = new ScFormulaCell(&mrDestCol.GetDoc(), aDestPos);
                 pErrCell->SetErrCode(nErr);
-                rPos.miCellPos = getDestCellStore().set(
-                    rPos.miCellPos, rDestPos.Row(), new ScFormulaCell(rSrcCell, getDestDoc(), rDestPos));
-                setDefaultAttrToDest(rPos, rDestPos.Row());
+                maDestPos.miCellPos = mrDestCol.GetCellStore().set(
+                    maDestPos.miCellPos, nRow, new ScFormulaCell(rSrcCell, mrDestCol.GetDoc(), aDestPos));
+                setDefaultAttrToDest(nRow);
                 return;
             }
         }
@@ -1709,11 +1725,11 @@ class CopyByCloneHandler : public sc::CellBlockCloneHandler
         {
             if (rSrcCell.IsValue())
             {
-                if (canCopyValue(getSrcDoc(), rSrcPos, mnCopyFlags))
+                if (canCopyValue(mrSrcCol.GetDoc(), ScAddress(mrSrcCol.GetCol(), nRow, mrSrcCol.GetTab()), mnCopyFlags))
                 {
-                    rPos.miCellPos = getDestCellStore().set(
-                        rPos.miCellPos, rDestPos.Row(), rSrcCell.GetValue());
-                    setDefaultAttrToDest(rPos, rDestPos.Row());
+                    maDestPos.miCellPos = mrDestCol.GetCellStore().set(
+                        maDestPos.miCellPos, nRow, rSrcCell.GetValue());
+                    setDefaultAttrToDest(nRow);
                 }
 
                 return;
@@ -1730,91 +1746,127 @@ class CopyByCloneHandler : public sc::CellBlockCloneHandler
             if (rSrcCell.IsMultilineResult())
             {
                 // Clone as an edit text object.
-                EditEngine& rEngine = getDestDoc().GetEditEngine();
+                EditEngine& rEngine = mrDestCol.GetDoc().GetEditEngine();
                 rEngine.SetText(aStr);
-                rPos.miCellPos =
-                    getDestCellStore().set(rPos.miCellPos, rDestPos.Row(), rEngine.CreateTextObject());
+                maDestPos.miCellPos =
+                    mrDestCol.GetCellStore().set(maDestPos.miCellPos, nRow, rEngine.CreateTextObject());
             }
             else
             {
-                rPos.miCellPos =
-                    getDestCellStore().set(rPos.miCellPos, rDestPos.Row(), aStr);
+                maDestPos.miCellPos =
+                    mrDestCol.GetCellStore().set(maDestPos.miCellPos, nRow, aStr);
             }
 
-            setDefaultAttrToDest(rPos, rDestPos.Row());
+            setDefaultAttrToDest(nRow);
         }
     }
 
 public:
-    CopyByCloneHandler(ScDocument& rSrcDoc, ScDocument& rDestDoc,
-                       sc::CellStoreType& rDestCellStore, sc::CellTextAttrStoreType& rDestAttrStore, sal_uInt16 nCopyFlags) :
-        sc::CellBlockCloneHandler(rSrcDoc, rDestDoc, rDestCellStore, rDestAttrStore),
-        mnCopyFlags(nCopyFlags)
+    CopyByCloneHandler(const ScColumn& rSrcCol, ScColumn& rDestCol, sc::ColumnBlockPosition* pDestPos, sal_uInt16 nCopyFlags) :
+        mrSrcCol(rSrcCol), mrDestCol(rDestCol), mpDestPos(pDestPos), mnCopyFlags(nCopyFlags)
     {
+        if (mpDestPos)
+            maDestPos = *mpDestPos;
     }
 
-    virtual void cloneDoubleBlock(
-        sc::ColumnBlockPosition& rPos, const ScAddress& rSrcPos, const ScAddress& rDestPos,
-        const sc::numeric_block::const_iterator& itBegin, const sc::numeric_block::const_iterator& itEnd)
+    ~CopyByCloneHandler()
     {
-        if ((mnCopyFlags & (IDF_DATETIME|IDF_VALUE)) == 0)
-            return;
-
-        ScAddress aSrcPos = rSrcPos;
-        ScAddress aDestPos = rDestPos;
-        for (sc::numeric_block::const_iterator it = itBegin; it != itEnd; ++it, aSrcPos.IncRow(), aDestPos.IncRow())
-        {
-            if (!canCopyValue(getSrcDoc(), aSrcPos, mnCopyFlags))
-                continue;
-
-            rPos.miCellPos = getDestCellStore().set(rPos.miCellPos, aDestPos.Row(), *it);
-            setDefaultAttrToDest(rPos, aDestPos.Row());
-        }
+        if (mpDestPos)
+            *mpDestPos = maDestPos;
     }
 
-    virtual void cloneStringBlock(
-        sc::ColumnBlockPosition& rPos, const ScAddress& /*rSrcPos*/, const ScAddress& rDestPos,
-        const sc::string_block::const_iterator& itBegin, const sc::string_block::const_iterator& itEnd)
+    void operator() (const sc::CellStoreType::value_type& aNode, size_t nOffset, size_t nDataSize)
     {
-        if (!(mnCopyFlags & IDF_STRING))
-            return;
+        size_t nRow = aNode.position - nOffset;
 
-        ScAddress aDestPos = rDestPos;
-        for (sc::string_block::const_iterator it = itBegin; it != itEnd; ++it, aDestPos.IncRow())
+        switch (aNode.type)
         {
-            const OUString& rStr = *it;
-            if (rStr.isEmpty())
+            case sc::element_type_numeric:
             {
-                // String cell with empty value is used to special-case cell value removal.
-                rPos.miCellPos = getDestCellStore().set_empty(rPos.miCellPos, aDestPos.Row(), aDestPos.Row());
-                rPos.miCellTextAttrPos = getDestAttrStore().set_empty(rPos.miCellTextAttrPos, aDestPos.Row(), aDestPos.Row());
+                if ((mnCopyFlags & (IDF_DATETIME|IDF_VALUE)) == 0)
+                    return;
+
+                sc::numeric_block::const_iterator it = sc::numeric_block::begin(*aNode.data);
+                std::advance(it, nOffset);
+                sc::numeric_block::const_iterator itEnd = it;
+                std::advance(itEnd, nDataSize);
+
+                ScAddress aSrcPos(mrSrcCol.GetCol(), nRow, mrSrcCol.GetTab());
+                for (; it != itEnd; ++it, aSrcPos.IncRow(), ++nRow)
+                {
+                    if (!canCopyValue(mrSrcCol.GetDoc(), aSrcPos, mnCopyFlags))
+                        continue;
+
+                    maDestPos.miCellPos = mrDestCol.GetCellStore().set(maDestPos.miCellPos, nRow, *it);
+                    setDefaultAttrToDest(nRow);
+                }
             }
-            else
+            break;
+            case sc::element_type_string:
             {
-                rPos.miCellPos = getDestCellStore().set(rPos.miCellPos, aDestPos.Row(), rStr);
-                setDefaultAttrToDest(rPos, aDestPos.Row());
+                if (!(mnCopyFlags & IDF_STRING))
+                    return;
+
+                sc::string_block::const_iterator it = sc::string_block::begin(*aNode.data);
+                std::advance(it, nOffset);
+                sc::string_block::const_iterator itEnd = it;
+                std::advance(itEnd, nDataSize);
+
+                for (; it != itEnd; ++it, ++nRow)
+                {
+                    const OUString& rStr = *it;
+                    if (rStr.isEmpty())
+                    {
+                        // String cell with empty value is used to special-case cell value removal.
+                        maDestPos.miCellPos = mrDestCol.GetCellStore().set_empty(
+                            maDestPos.miCellPos, nRow, nRow);
+                        maDestPos.miCellTextAttrPos = mrDestCol.GetCellAttrStore().set_empty(
+                            maDestPos.miCellTextAttrPos, nRow, nRow);
+                    }
+                    else
+                    {
+                        maDestPos.miCellPos =
+                            mrDestCol.GetCellStore().set(maDestPos.miCellPos, nRow, rStr);
+                        setDefaultAttrToDest(nRow);
+                    }
+                }
             }
-        }
-    }
+            break;
+            case sc::element_type_edittext:
+            {
+                if (!(mnCopyFlags & IDF_STRING))
+                    return;
 
-    virtual void cloneEditTextBlock(
-        sc::ColumnBlockPosition& rPos, const ScAddress& rSrcPos, const ScAddress& rDestPos,
-        const sc::edittext_block::const_iterator& itBegin, const sc::edittext_block::const_iterator& itEnd)
-    {
-        if (!(mnCopyFlags & IDF_STRING))
-            return;
+                sc::edittext_block::const_iterator it = sc::edittext_block::begin(*aNode.data);
+                std::advance(it, nOffset);
+                sc::edittext_block::const_iterator itEnd = it;
+                std::advance(itEnd, nDataSize);
 
-        sc::CellBlockCloneHandler::cloneEditTextBlock(rPos, rSrcPos, rDestPos, itBegin, itEnd);
-    }
+                std::vector<EditTextObject*> aCloned;
+                aCloned.reserve(nDataSize);
+                for (; it != itEnd; ++it)
+                    aCloned.push_back(ScEditUtil::Clone(**it, mrDestCol.GetDoc()));
 
-    virtual void cloneFormulaBlock(
-        sc::ColumnBlockPosition& rPos, const ScAddress& rSrcPos, const ScAddress& rDestPos,
-        const sc::formula_block::const_iterator& itBegin, const sc::formula_block::const_iterator& itEnd)
-    {
-        ScAddress aSrcPos = rSrcPos;
-        ScAddress aDestPos = rDestPos;
-        for (sc::formula_block::const_iterator it = itBegin; it != itEnd; ++it, aSrcPos.IncRow(), aDestPos.IncRow())
-            cloneFormulaCell(rPos, aSrcPos, aDestPos, const_cast<ScFormulaCell&>(**it));
+                maDestPos.miCellPos = mrDestCol.GetCellStore().set(
+                    maDestPos.miCellPos, nRow, aCloned.begin(), aCloned.end());
+
+                setDefaultAttrsToDest(nRow, nDataSize);
+            }
+            break;
+            case sc::element_type_formula:
+            {
+                sc::formula_block::const_iterator it = sc::formula_block::begin(*aNode.data);
+                std::advance(it, nOffset);
+                sc::formula_block::const_iterator itEnd = it;
+                std::advance(itEnd, nDataSize);
+
+                for (; it != itEnd; ++it, ++nRow)
+                    cloneFormulaCell(nRow, const_cast<ScFormulaCell&>(**it));
+            }
+            break;
+            default:
+                ;
+        }
     }
 };
 
@@ -1871,11 +1923,18 @@ void ScColumn::CopyToColumn(
         boost::scoped_ptr<sc::CellBlockCloneHandler> pHdl(NULL);
 
         if (bAsLink)
+        {
             pHdl.reset(new CopyAsLinkHandler(*pDocument, *rColumn.pDocument, rColumn.maCells, rColumn.maCellTextAttrs, nFlags));
+            CopyCellsInRangeToColumn(NULL, rCxt.getBlockPosition(rColumn.nTab, rColumn.nCol), *pHdl, nRow1, nRow2, rColumn);
+        }
         else
-            pHdl.reset(new CopyByCloneHandler(*pDocument, *rColumn.pDocument, rColumn.maCells, rColumn.maCellTextAttrs, nFlags));
+        {
+            CopyByCloneHandler aFunc(*this, rColumn, rCxt.getBlockPosition(rColumn.nTab, rColumn.nCol), nFlags);
+            sc::ParseBlock(maCells.begin(), maCells, aFunc, nRow1, nRow2);
+            rColumn.RegroupFormulaCells(nRow1, nRow2);
+            rColumn.CellStorageModified();
+        }
 
-        CopyCellsInRangeToColumn(NULL, rCxt.getBlockPosition(rColumn.nTab, rColumn.nCol), *pHdl, nRow1, nRow2, rColumn);
     }
 }
 
commit 5eb0d467740f0e0b52eb1ee9147e55d5ce590aaf
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Tue Jun 25 23:30:56 2013 -0400

    CopyUpdated() to use ParseBlock() instead of CopyCellsInRangeToColumn().
    
    Change-Id: I7f1456462ac3bb9d551d3d1bb303a68d74fa16f1

diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index 2ff8780..c561035 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -1897,13 +1897,7 @@ void ScColumn::UndoToColumn(
 void ScColumn::CopyUpdated( const ScColumn& rPosCol, ScColumn& rDestCol ) const
 {
     // Copy cells from this column to the destination column only for those
-    // rows that are present in the position column.
-
-    sc::CellBlockCloneHandler aHdl(*pDocument, *rDestCol.pDocument, rDestCol.maCells, rDestCol.maCellTextAttrs);
-    sc::ColumnBlockConstPosition aSrcPos;
-    sc::ColumnBlockPosition aDestPos;
-    InitBlockPosition(aSrcPos);
-    rDestCol.InitBlockPosition(aDestPos);
+    // rows that are present in the position column (rPosCol).
 
     // First, mark all the non-empty cell ranges from the position column.
     sc::SingleColumnSpanSet aRangeSet;
@@ -1913,9 +1907,17 @@ void ScColumn::CopyUpdated( const ScColumn& rPosCol, ScColumn& rDestCol ) const
     // marked row ranges.
     sc::SingleColumnSpanSet::SpansType aRanges;
     aRangeSet.getSpans(aRanges);
+
+    CopyToClipHandler aFunc(*this, rDestCol, NULL);
+    sc::CellStoreType::const_iterator itPos = maCells.begin();
     sc::SingleColumnSpanSet::SpansType::const_iterator it = aRanges.begin(), itEnd = aRanges.end();
     for (; it != itEnd; ++it)
-        CopyCellsInRangeToColumn(&aSrcPos, &aDestPos, aHdl, it->mnRow1, it->mnRow2, rDestCol);
+    {
+        itPos = sc::ParseBlock(itPos, maCells, aFunc, it->mnRow1, it->mnRow2);
+        rDestCol.RegroupFormulaCells(it->mnRow1, it->mnRow2);
+    }
+
+    rDestCol.CellStorageModified();
 }
 
 
commit 0e9b18631302ec17771b72e4903b150e00027ccf
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Tue Jun 25 23:14:43 2013 -0400

    Let's not forget to store the position afterward.
    
    Change-Id: Ia5067db46460e164643dd8cc6d21b68a05b3b33a

diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index 600eb58..2ff8780 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -1275,6 +1275,7 @@ class CopyToClipHandler
     const ScColumn& mrSrcCol;
     ScColumn& mrDestCol;
     sc::ColumnBlockPosition maDestPos;
+    sc::ColumnBlockPosition* mpDestPos;
 
     void setDefaultAttrsToDest(size_t nRow, size_t nSize)
     {
@@ -1285,14 +1286,20 @@ class CopyToClipHandler
 
 public:
     CopyToClipHandler(const ScColumn& rSrcCol, ScColumn& rDestCol, sc::ColumnBlockPosition* pDestPos) :
-        mrSrcCol(rSrcCol), mrDestCol(rDestCol)
+        mrSrcCol(rSrcCol), mrDestCol(rDestCol), mpDestPos(pDestPos)
     {
-        if (pDestPos)
-            maDestPos = *pDestPos;
+        if (mpDestPos)
+            maDestPos = *mpDestPos;
         else
             mrDestCol.InitBlockPosition(maDestPos);
     }
 
+    ~CopyToClipHandler()
+    {
+        if (mpDestPos)
+            *mpDestPos = maDestPos;
+    }
+
     void operator() (const sc::CellStoreType::value_type& aNode, size_t nOffset, size_t nDataSize)
     {
         size_t nTopRow = aNode.position;
commit b3b1f83832a72013f7cdb569d86125e7b6c30a19
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Tue Jun 25 23:07:25 2013 -0400

    Replace CopyCellsInRangeToColumn() with ParseBlock().
    
    Change-Id: I7b7f827fcdb9e31956d0b123ecee8751d791e54f

diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 69f3420..c6b3945 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -144,6 +144,10 @@ public:
     const ScDocument& GetDoc() const;
     SCTAB GetTab() const { return nTab; }
     SCCOL GetCol() const { return nCol; }
+    sc::CellStoreType& GetCellStore() { return maCells; }
+    const sc::CellStoreType& GetCellStore() const { return maCells; }
+    sc::CellTextAttrStoreType& GetCellAttrStore() { return maCellTextAttrs; }
+    const sc::CellTextAttrStoreType& GetCellAttrStore() const { return maCellTextAttrs; }
 
     ScRefCellValue GetCellValue( SCROW nRow ) const;
     ScRefCellValue GetCellValue( sc::CellStoreType::const_iterator& itPos, SCROW nRow ) const;
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index cfea95d..600eb58 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -1270,12 +1270,102 @@ void ScColumn::InsertRow( SCROW nStartRow, SCSIZE nSize )
 
 namespace {
 
-class CopyToClipHandler : public sc::CellBlockCloneHandler
+class CopyToClipHandler
 {
+    const ScColumn& mrSrcCol;
+    ScColumn& mrDestCol;
+    sc::ColumnBlockPosition maDestPos;
+
+    void setDefaultAttrsToDest(size_t nRow, size_t nSize)
+    {
+        std::vector<sc::CellTextAttr> aAttrs(nSize); // default values
+        maDestPos.miCellTextAttrPos = mrDestCol.GetCellAttrStore().set(
+            maDestPos.miCellTextAttrPos, nRow, aAttrs.begin(), aAttrs.end());
+    }
+
 public:
-    CopyToClipHandler(ScDocument& rSrcDoc, ScDocument& rDestDoc,
-                      sc::CellStoreType& rDestCellStore, sc::CellTextAttrStoreType& rDestAttrStore) :
-        sc::CellBlockCloneHandler(rSrcDoc, rDestDoc, rDestCellStore, rDestAttrStore) {}
+    CopyToClipHandler(const ScColumn& rSrcCol, ScColumn& rDestCol, sc::ColumnBlockPosition* pDestPos) :
+        mrSrcCol(rSrcCol), mrDestCol(rDestCol)
+    {
+        if (pDestPos)
+            maDestPos = *pDestPos;
+        else
+            mrDestCol.InitBlockPosition(maDestPos);
+    }
+
+    void operator() (const sc::CellStoreType::value_type& aNode, size_t nOffset, size_t nDataSize)
+    {
+        size_t nTopRow = aNode.position;
+
+        switch (aNode.type)
+        {
+            case sc::element_type_numeric:
+            {
+                sc::numeric_block::const_iterator it = sc::numeric_block::begin(*aNode.data);
+                std::advance(it, nOffset);
+                sc::numeric_block::const_iterator itEnd = it;
+                std::advance(itEnd, nDataSize);
+                maDestPos.miCellPos = mrDestCol.GetCellStore().set(maDestPos.miCellPos, nTopRow, it, itEnd);
+                setDefaultAttrsToDest(nTopRow, nDataSize);
+            }
+            break;
+            case sc::element_type_string:
+            {
+                sc::string_block::const_iterator it = sc::string_block::begin(*aNode.data);
+                std::advance(it, nOffset);
+                sc::string_block::const_iterator itEnd = it;
+                std::advance(itEnd, nDataSize);
+                maDestPos.miCellPos = mrDestCol.GetCellStore().set(maDestPos.miCellPos, nTopRow, it, itEnd);
+                setDefaultAttrsToDest(nTopRow, nDataSize);
+            }
+            break;
+            case sc::element_type_edittext:
+            {
+                sc::edittext_block::const_iterator it = sc::edittext_block::begin(*aNode.data);
+                std::advance(it, nOffset);
+                sc::edittext_block::const_iterator itEnd = it;
+                std::advance(itEnd, nDataSize);
+
+                std::vector<EditTextObject*> aCloned;
+                aCloned.reserve(nDataSize);
+                for (; it != itEnd; ++it)
+                    aCloned.push_back(ScEditUtil::Clone(**it, mrDestCol.GetDoc()));
+
+                maDestPos.miCellPos = mrDestCol.GetCellStore().set(
+                    maDestPos.miCellPos, nTopRow, aCloned.begin(), aCloned.end());
+
+                setDefaultAttrsToDest(nTopRow, nDataSize);
+            }
+            break;
+            case sc::element_type_formula:
+            {
+                sc::formula_block::const_iterator it = sc::formula_block::begin(*aNode.data);
+                std::advance(it, nOffset);
+                sc::formula_block::const_iterator itEnd = it;
+                std::advance(itEnd, nDataSize);
+
+                std::vector<ScFormulaCell*> aCloned;
+                aCloned.reserve(nDataSize);
+                ScAddress aDestPos(mrDestCol.GetCol(), nTopRow, mrDestCol.GetTab());
+                for (; it != itEnd; ++it, aDestPos.IncRow())
+                {
+                    const ScFormulaCell& rOld = **it;
+                    if (rOld.GetDirty() && mrSrcCol.GetDoc().GetAutoCalc())
+                        const_cast<ScFormulaCell&>(rOld).Interpret();
+
+                    aCloned.push_back(new ScFormulaCell(rOld, mrDestCol.GetDoc(), aDestPos));
+                }
+
+                maDestPos.miCellPos = mrDestCol.GetCellStore().set(
+                    maDestPos.miCellPos, nTopRow, aCloned.begin(), aCloned.end());
+
+                setDefaultAttrsToDest(nTopRow, nDataSize);
+            }
+            break;
+            default:
+                ;
+        }
+    }
 };
 
 }
@@ -1286,8 +1376,10 @@ void ScColumn::CopyToClip(
     pAttrArray->CopyArea( nRow1, nRow2, 0, *rColumn.pAttrArray,
                           rCxt.isKeepScenarioFlags() ? (SC_MF_ALL & ~SC_MF_SCENARIO) : SC_MF_ALL );
 
-    CopyToClipHandler aHdl(*pDocument, *rColumn.pDocument, rColumn.maCells, rColumn.maCellTextAttrs);
-    CopyCellsInRangeToColumn(NULL, rCxt.getBlockPosition(rColumn.nTab, rColumn.nCol), aHdl, nRow1, nRow2, rColumn);
+    CopyToClipHandler aFunc(*this, rColumn, rCxt.getBlockPosition(rColumn.nTab, rColumn.nCol));
+    sc::ParseBlock(maCells.begin(), maCells, aFunc, nRow1, nRow2);
+    rColumn.RegroupFormulaCells(nRow1, nRow2);
+    rColumn.CellStorageModified();
 }
 
 void ScColumn::CopyStaticToDocument(SCROW nRow1, SCROW nRow2, ScColumn& rDestCol)
commit 7d18e671d1699148783ce82a234c3d5f119e951d
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Tue Jun 25 21:01:37 2013 -0400

    Remove this inheritance.
    
    Change-Id: I37e0a6b8e95f56210df823af7aa8828189edfbef

diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index ac3ab98..cfea95d 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -2002,22 +2002,19 @@ void ScColumn::MoveTo(SCROW nStartRow, SCROW nEndRow, ScColumn& rCol)
 
 namespace {
 
-class UpdateRefHandler
+class UpdateRefOnCopy
 {
 protected:
     ScRange maRange;
     SCCOL mnDx;
     SCROW mnDy;
     SCTAB mnDz;
-    UpdateRefMode meMode;
     ScDocument* mpUndoDoc;
     bool mbUpdated;
 
 public:
-    UpdateRefHandler(const ScRange& rRange, SCCOL nDx, SCROW nDy, SCTAB nDz, UpdateRefMode eMode, ScDocument* pUndoDoc) :
-        maRange(rRange), mnDx(nDx), mnDy(nDy), mnDz(nDz), meMode(eMode), mpUndoDoc(pUndoDoc), mbUpdated(false) {}
-
-    virtual ~UpdateRefHandler() {}
+    UpdateRefOnCopy(const ScRange& rRange, SCCOL nDx, SCROW nDy, SCTAB nDz, ScDocument* pUndoDoc) :
+        maRange(rRange), mnDx(nDx), mnDy(nDy), mnDz(nDz), mpUndoDoc(pUndoDoc), mbUpdated(false) {}
 
     bool isUpdated() const { return mbUpdated; }
 
@@ -2031,23 +2028,11 @@ public:
         sc::formula_block::iterator itEnd = it;
         std::advance(itEnd, nDataSize);
 
-        size_t nRow = node.position + nOffset;
-        for (; it != itEnd; ++it, ++nRow)
-            updateReference(**it, static_cast<SCROW>(nRow));
-    }
-
-    virtual void updateReference(ScFormulaCell& rCell, SCROW nRow) = 0;
-};
-
-class UpdateRefOnCopy : public UpdateRefHandler
-{
-public:
-    UpdateRefOnCopy(const ScRange& rRange, SCCOL nDx, SCROW nDy, SCTAB nDz, ScDocument* pUndoDoc) :
-        UpdateRefHandler(rRange, nDx, nDy, nDz, URM_COPY, pUndoDoc) {}
-
-    virtual void updateReference(ScFormulaCell& rCell, SCROW /*nRow*/)
-    {
-        mbUpdated |= rCell.UpdateReference(meMode, maRange, mnDx, mnDy, mnDz, mpUndoDoc);
+        for (; it != itEnd; ++it)
+        {
+            ScFormulaCell& rCell = **it;
+            mbUpdated |= rCell.UpdateReference(URM_COPY, maRange, mnDx, mnDy, mnDz, mpUndoDoc);
+        }
     }
 };
 
commit 5e71c6f3ce53d71583ce95b34c36d40ea9900388
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Tue Jun 25 17:06:45 2013 -0400

    Identify spots where we may need to regroup formula cells.
    
    Change-Id: Ib448480bb3a3e39638dd42cafc272934a226cc1e

diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 3cbd7b8..69f3420 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -457,6 +457,28 @@ public:
 
     void InterpretDirtyCells( SCROW nRow1, SCROW nRow2 );
 
+    /**
+     * Regroup formula cells for the entire column.
+     */
+    void RegroupFormulaCells();
+
+    /**
+     * Regroup existing formula cells when a new cell is inserted.
+     *
+     * @param nRow row at which a new cell is inserted.
+     */
+    void RegroupFormulaCells( SCROW nRow );
+
+    /**
+     * 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 );
+
+    void FormulaCellsUndecided( SCROW nRow1, SCROW nRow2 );
+
 private:
 
     void CopyCellsInRangeToColumn(
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index bd1eeae..ac3ab98 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -886,6 +886,9 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
                 ScFormulaCell* pNew2 = cloneFormulaCell(pDocument, ScAddress(nCol, nRow2, nTab), *pOld1);
                 *itf1 = pNew1;
                 *itf2 = pNew2;
+
+                RegroupFormulaCells(nRow1);
+                RegroupFormulaCells(nRow2);
             }
             break;
             default:
@@ -930,6 +933,8 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
                 ScFormulaCell* pNew = cloneFormulaCell(pDocument, ScAddress(nCol, nRow1, nTab), *aCell2.mpFormula);
                 it1 = maCells.set(it1, nRow1, pNew);
                 maCells.set_empty(it1, nRow2, nRow2); // original formula cell gets deleted.
+
+                RegroupFormulaCells(nRow2);
             }
             break;
             default:
@@ -971,6 +976,9 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
                 ScFormulaCell* pNew = cloneFormulaCell(pDocument, ScAddress(nCol, nRow2, nTab), *aCell1.mpFormula);
                 it1 = maCells.set_empty(it1, nRow1, nRow1); // original formula cell is gone.
                 maCells.set(it1, nRow2, pNew);
+
+                RegroupFormulaCells(nRow1);
+                RegroupFormulaCells(nRow2);
             }
             break;
             default:
@@ -1012,6 +1020,7 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
             }
 
             maCells.set(it1, nRow2, aCell1.mfValue);
+
         }
         break;
         case CELLTYPE_STRING:
@@ -1101,6 +1110,8 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
     }
 
     SwapCellTextAttrs(nRow1, nRow2);
+    RegroupFormulaCells(nRow1);
+    RegroupFormulaCells(nRow2);
     CellStorageModified();
     BroadcastCells(aRows);
 }
@@ -1125,6 +1136,7 @@ void ScColumn::SwapCell( SCROW nRow, ScColumn& rCol)
     ScFormulaCell* pCell2 = rCol.maCells.get<ScFormulaCell*>(nRow);
     if (pCell1)
         updateRefInFormulaCell(*pCell1, rCol.nCol, nTab, rCol.nCol - nCol);
+
     if (pCell2)
         updateRefInFormulaCell(*pCell2, nCol, nTab, nCol - rCol.nCol);
 
@@ -1133,6 +1145,13 @@ void ScColumn::SwapCell( SCROW nRow, ScColumn& rCol)
 
     CellStorageModified();
     rCol.CellStorageModified();
+
+    if (pCell1 || pCell2)
+    {
+        // At least one of the two cells is a formula cell. Regroup them.
+        RegroupFormulaCells(nRow);
+        rCol.RegroupFormulaCells(nRow);
+    }
 }
 
 
@@ -1200,15 +1219,18 @@ void ScColumn::InsertRow( SCROW nStartRow, SCSIZE nSize )
     maCellTextAttrs.insert_empty(nStartRow, nSize);
     maCellTextAttrs.resize(MAXROWCOUNT);
 
-    maCells.insert_empty(nStartRow, nSize);
+    // Check if this insertion will split an existing formula block.
+    sc::CellStoreType::position_type aPos = maCells.position(nStartRow);
+    bool bSplitFormulaBlock = aPos.second != 0;
+
+    sc::CellStoreType::iterator it = maCells.insert_empty(aPos.first, nStartRow, nSize);
     maCells.resize(MAXROWCOUNT);
 
-    bool bOldAutoCalc = pDocument->GetAutoCalc();
-    pDocument->SetAutoCalc( false );    // avoid recalculations
+    sc::AutoCalcSwitch aSwitch(*pDocument, false);
 
     // Get the position of the first affected cell.
-    std::pair<sc::CellStoreType::iterator,size_t> aPos = maCells.position(nStartRow+nSize);
-    sc::CellStoreType::iterator it = aPos.first;
+    aPos = maCells.position(it, nStartRow+nSize);
+    it = aPos.first;
 
     // Update the positions of all affected formula cells.
     if (it->type == sc::element_type_formula)
@@ -1237,9 +1259,10 @@ void ScColumn::InsertRow( SCROW nStartRow, SCSIZE nSize )
         }
     }
 
-    CellStorageModified();
+    if (bSplitFormulaBlock)
+        RegroupFormulaCells(nStartRow, nStartRow+nSize-1);
 
-    pDocument->SetAutoCalc( bOldAutoCalc );
+    CellStorageModified();
 
     // We *probably* don't need to broadcast here since the parent call seems
     // to take care of it.
@@ -1370,6 +1393,7 @@ void ScColumn::CopyStaticToDocument(SCROW nRow1, SCROW nRow2, ScColumn& rDestCol
             break;
     }
 
+    rDestCol.RegroupFormulaCells(nRow1, nRow2);
     rDestCol.CellStorageModified();
 }
 
@@ -1419,6 +1443,7 @@ void ScColumn::CopyCellToDocument( SCROW nSrcRow, SCROW nDestRow, ScColumn& rDes
     else
         rDestCol.maCellTextAttrs.set_empty(nDestRow, nDestRow);
 
+    rDestCol.RegroupFormulaCells(nDestRow);
     rDestCol.CellStorageModified();
 }
 
@@ -1956,6 +1981,8 @@ void ScColumn::MoveTo(SCROW nStartRow, SCROW nEndRow, ScColumn& rCol)
     maCells.transfer(nStartRow, nEndRow, rCol.maCells, nStartRow);
     maCellTextAttrs.transfer(nStartRow, nEndRow, rCol.maCellTextAttrs, nStartRow);
 
+    RegroupFormulaCells(nStartRow, nEndRow);
+    rCol.RegroupFormulaCells(nStartRow, nEndRow);
     CellStorageModified();
     rCol.CellStorageModified();
 
@@ -2064,11 +2091,13 @@ bool ScColumn::UpdateReference( UpdateRefMode eUpdateRefMode, SCCOL nCol1, SCROW
     if (eUpdateRefMode == URM_COPY)
     {
         UpdateRefOnCopy aHandler(aRange, nDx, nDy, nDz, pUndoDoc);
+        FormulaCellsUndecided(nRow1, nRow2);
         sc::ProcessBlock(maCells.begin(), maCells, aHandler, nRow1, nRow2);
         return aHandler.isUpdated();
     }
 
     UpdateRefOnNonCopy aHandler(nCol, nTab, aRange, nDx, nDy, nDz, eUpdateRefMode, pUndoDoc);
+    FormulaCellsUndecided(0, MAXROW);
     sc::ProcessFormula(maCells, aHandler);
     return aHandler.isUpdated();
 }
@@ -2547,6 +2576,7 @@ void ScColumn::UpdateTranspose( const ScRange& rSource, const ScAddress& rDest,
 {
     UpdateTransHandler aFunc(rSource, rDest, pUndoDoc);
     sc::ProcessFormula(maCells, aFunc);
+    RegroupFormulaCells();
 }
 
 
@@ -2554,6 +2584,7 @@ void ScColumn::UpdateGrow( const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY )
 {
     UpdateGrowHandler aFunc(rArea, nGrowX, nGrowY);
     sc::ProcessFormula(maCells, aFunc);
+    RegroupFormulaCells();
 }
 
 
@@ -2573,7 +2604,10 @@ void ScColumn::UpdateInsertTabOnlyCells(SCTAB nInsPos, SCTAB nNewSheets)
     InsertTabUpdater aFunc(maCellTextAttrs, nTab, nInsPos, nNewSheets);
     sc::ProcessFormulaEditText(maCells, aFunc);
     if (aFunc.isModified())
+    {
+        RegroupFormulaCells();
         CellStorageModified();
+    }
 }
 
 void ScColumn::UpdateDeleteTab(SCTAB nDelPos, bool bIsMove, ScColumn* /*pRefUndo*/, SCTAB nSheets)
@@ -2587,7 +2621,10 @@ void ScColumn::UpdateDeleteTab(SCTAB nDelPos, bool bIsMove, ScColumn* /*pRefUndo
     DeleteTabUpdater aFunc(maCellTextAttrs, nDelPos, nSheets, nTab, bIsMove);
     sc::ProcessFormulaEditText(maCells, aFunc);
     if (aFunc.isModified())
+    {
+        RegroupFormulaCells();
         CellStorageModified();
+    }
 }
 
 void ScColumn::UpdateInsertTabAbs(SCTAB nNewPos)
@@ -2595,7 +2632,10 @@ void ScColumn::UpdateInsertTabAbs(SCTAB nNewPos)
     InsertAbsTabUpdater aFunc(maCellTextAttrs, nTab, nNewPos);
     sc::ProcessFormulaEditText(maCells, aFunc);
     if (aFunc.isModified())
+    {
+        RegroupFormulaCells();
         CellStorageModified();
+    }
 }
 
 void ScColumn::UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos, SCTAB nTabNo )
@@ -2606,7 +2646,10 @@ void ScColumn::UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos, SCTAB nTabNo )
     MoveTabUpdater aFunc(maCellTextAttrs, nTab, nOldPos, nNewPos);
     sc::ProcessFormulaEditText(maCells, aFunc);
     if (aFunc.isModified())
+    {
+        RegroupFormulaCells();
         CellStorageModified();
+    }
 }
 
 
@@ -2614,6 +2657,7 @@ void ScColumn::UpdateCompile( bool bForceIfNameInUse )
 {
     UpdateCompileHandler aFunc(bForceIfNameInUse);
     sc::ProcessFormula(maCells, aFunc);
+    RegroupFormulaCells();
 }
 
 
@@ -2711,12 +2755,17 @@ void ScColumn::CompileXML( ScProgress& rProgress )
 {
     CompileXMLHandler aFunc(rProgress);
     sc::ProcessFormula(maCells, aFunc);
+    RegroupFormulaCells();
 }
 
 bool ScColumn::CompileErrorCells(sal_uInt16 nErrCode)
 {
     CompileErrorCellsHandler aHdl(nErrCode, pDocument->GetGrammar());
     sc::ProcessFormula(maCells, aHdl);
+    if (aHdl.isCompiled())
+        // TODO: Probably more efficient to do this individually rather than the whole column.
+        RegroupFormulaCells();
+
     return aHdl.isCompiled();
 }
 
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index 8dae8d6..726da1a 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -1469,6 +1469,8 @@ SCROW ScColumn::FindNextVisibleRowWithContent(
 
 void ScColumn::CellStorageModified()
 {
+    // TODO: Update column's "last updated" timestamp here.
+
     mbDirtyGroups = true;
 
 #if DEBUG_COLUMN_STORAGE
@@ -1529,6 +1531,22 @@ void ScColumn::CellStorageModified()
 #endif
 }
 
+void ScColumn::RegroupFormulaCells()
+{
+}
+
+void ScColumn::RegroupFormulaCells( SCROW nRow )
+{
+}
+
+void ScColumn::RegroupFormulaCells( SCROW nRow1, SCROW nRow2 )
+{
+}
+
+void ScColumn::FormulaCellsUndecided( SCROW nRow1, SCROW nRow2 )
+{
+}
+
 void ScColumn::CopyCellTextAttrsToDocument(SCROW nRow1, SCROW nRow2, ScColumn& rDestCol) const
 {
     rDestCol.maCellTextAttrs.set_empty(nRow1, nRow2); // Empty the destination range first.
@@ -1991,7 +2009,7 @@ public:
                 sc::formula_block::const_iterator itEnd = it;
                 std::advance(itEnd, nDataSize);
 
-                size_t nPrevRow, nThisRow = node.position + nOffset;
+                size_t nPrevRow = 0, nThisRow = node.position + nOffset;
                 for (; it != itEnd; ++it, nPrevRow = nThisRow, ++nThisRow)
                 {
                     ScFormulaCell& rCell = const_cast<ScFormulaCell&>(**it);
@@ -2396,24 +2414,28 @@ void ScColumn::CompileDBFormula()
 {
     CompileDBFormulaHandler aFunc;
     sc::ProcessFormula(maCells, aFunc);
+    RegroupFormulaCells();
 }
 
 void ScColumn::CompileDBFormula( bool bCreateFormulaString )
 {
     CompileDBFormula2Handler aFunc(bCreateFormulaString);
     sc::ProcessFormula(maCells, aFunc);
+    RegroupFormulaCells();
 }
 
 void ScColumn::CompileNameFormula( bool bCreateFormulaString )
 {
     CompileNameFormulaHandler aFunc(bCreateFormulaString);
     sc::ProcessFormula(maCells, aFunc);
+    RegroupFormulaCells();
 }
 
 void ScColumn::CompileColRowNameFormula()
 {
     CompileColRowNameFormulaHandler aFunc;
     sc::ProcessFormula(maCells, aFunc);
+    RegroupFormulaCells();
 }
 
 namespace {
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index c4886af..da10a49 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -137,7 +137,8 @@ void ScColumn::Delete( SCROW nRow )
     if (it == maCells.end())
         return;
 
-    if (it->type == sc::element_type_formula)
+    bool bFormulaCell = it->type == sc::element_type_formula;
+    if (bFormulaCell)
     {
         ScFormulaCell* p = sc::formula_block::at(*it->data, aPos.second);
         p->EndListeningTo(pDocument);
@@ -148,6 +149,9 @@ void ScColumn::Delete( SCROW nRow )
     pDocument->Broadcast(
         ScHint(SC_HINT_DATACHANGED, ScAddress(nCol, nRow, nTab)));
 
+    if (bFormulaCell)
+        RegroupFormulaCells(nRow);
+
     CellStorageModified();
 }
 
@@ -244,7 +248,7 @@ void ScColumn::DeleteRow( SCROW nStartRow, SCSIZE nSize )
     maBroadcasters.resize(MAXROWCOUNT);
 
     // See if we have any cells that would get deleted or shifted by deletion.
-    std::pair<sc::CellStoreType::iterator,size_t> aPos = maCells.position(nStartRow);
+    sc::CellStoreType::position_type aPos = maCells.position(nStartRow);
     sc::CellStoreType::iterator itCell = aPos.first;
     if (itCell->type == sc::element_type_empty)
     {
@@ -307,6 +311,7 @@ void ScColumn::DeleteRow( SCROW nStartRow, SCSIZE nSize )
     maCellTextAttrs.erase(nStartRow, nEndRow);
     maCellTextAttrs.resize(MAXROWCOUNT);
 
+    RegroupFormulaCells(nStartRow);
     CellStorageModified();
 
     if (!bShiftCells)
@@ -419,6 +424,7 @@ void ScColumn::CopyCellsInRangeToColumn(
         *pDestColPos = aDestColPos;
     }
 
+    rColumn.RegroupFormulaCells(nRow1, nRow2);
     rColumn.CellStorageModified();
 }
 
@@ -430,7 +436,7 @@ sc::CellStoreType::iterator ScColumn::GetPositionToInsert( SCROW nRow )
 sc::CellStoreType::iterator ScColumn::GetPositionToInsert( const sc::CellStoreType::iterator& it, SCROW nRow )
 {
     // See if we are overwriting an existing formula cell.
-    std::pair<sc::CellStoreType::iterator,size_t> aRet = maCells.position(it, nRow);
+    sc::CellStoreType::position_type aRet = maCells.position(it, nRow);
     sc::CellStoreType::iterator itRet = aRet.first;
     if (itRet->type == sc::element_type_formula && !pDocument->IsClipOrUndo())
     {
@@ -580,18 +586,20 @@ public:
 
 class EmptyCells
 {
+    ScColumn& mrColumn;
     sc::ColumnBlockPosition& mrPos;
     sc::CellStoreType::iterator miPos;
     sc::CellStoreType& mrCells;
     sc::CellTextAttrStoreType& mrAttrs;
 public:
-    EmptyCells(sc::ColumnBlockPosition& rPos, sc::CellStoreType& rCells, sc::CellTextAttrStoreType& rAttrs) :
-        mrPos(rPos), mrCells(rCells), mrAttrs(rAttrs) {}
+    EmptyCells(sc::ColumnBlockPosition& rPos, ScColumn& rColumn, sc::CellStoreType& rCells, sc::CellTextAttrStoreType& rAttrs) :
+        mrColumn(rColumn), mrPos(rPos), mrCells(rCells), mrAttrs(rAttrs) {}
 
     void operator() (const sc::SingleColumnSpanSet::Span& rSpan)
     {
         mrPos.miCellPos = mrCells.set_empty(mrPos.miCellPos, rSpan.mnRow1, rSpan.mnRow2);
         mrPos.miCellTextAttrPos = mrAttrs.set_empty(mrPos.miCellTextAttrPos, rSpan.mnRow1, rSpan.mnRow2);
+        mrColumn.RegroupFormulaCells(rSpan.mnRow1, rSpan.mnRow2);
     }
 };
 
@@ -625,7 +633,7 @@ void ScColumn::DeleteArea(SCROW nStartRow, SCROW nEndRow, sal_uInt16 nDelFlag)
         aBlockPos.miCellTextAttrPos = maCellTextAttrs.begin();
 
         // Delete the cells for real.
-        std::for_each(aSpans.begin(), aSpans.end(), EmptyCells(aBlockPos, maCells, maCellTextAttrs));
+        std::for_each(aSpans.begin(), aSpans.end(), EmptyCells(aBlockPos, *this, maCells, maCellTextAttrs));
         CellStorageModified();
     }
 
@@ -1362,6 +1370,7 @@ void ScColumn::MixData(
     sc::ParseAll(rSrcCol.maCells.begin(), rSrcCol.maCells, nRow1, nRow2, aFunc, aFunc);
 
     aFunc.commit(p);
+    RegroupFormulaCells(nRow1, nRow2);
     CellStorageModified();
 }
 
@@ -1604,6 +1613,7 @@ 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);
@@ -1615,6 +1625,7 @@ 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);
@@ -1692,6 +1703,7 @@ void ScColumn::SetFormula( SCROW nRow, const ScTokenArray& rArray, formula::Form
     ScFormulaCell* pCell = new ScFormulaCell(pDocument, aPos, &rArray, eGram);
     maCells.set(it, nRow, pCell);
     maCellTextAttrs.set(nRow, sc::CellTextAttr());
+    RegroupFormulaCells(nRow);
     CellStorageModified();
 
     ActivateNewFormulaCell(pCell);
@@ -1705,6 +1717,7 @@ void ScColumn::SetFormula( SCROW nRow, const OUString& rFormula, formula::Formul
     ScFormulaCell* pCell = new ScFormulaCell(pDocument, aPos, rFormula, eGram);
     maCells.set(it, nRow, pCell);
     maCellTextAttrs.set(nRow, sc::CellTextAttr());
+    RegroupFormulaCells(nRow);
     CellStorageModified();
 
     ActivateNewFormulaCell(pCell);
@@ -1715,6 +1728,7 @@ void ScColumn::SetFormulaCell( SCROW nRow, ScFormulaCell* pCell )
     sc::CellStoreType::iterator it = GetPositionToInsert(nRow);
     maCells.set(it, nRow, pCell);
     maCellTextAttrs.set(nRow, sc::CellTextAttr());
+    RegroupFormulaCells(nRow);
     CellStorageModified();
 
     ActivateNewFormulaCell(pCell);
@@ -1726,6 +1740,7 @@ void ScColumn::SetFormulaCell( sc::ColumnBlockPosition& rBlockPos, SCROW nRow, S
     rBlockPos.miCellPos = maCells.set(rBlockPos.miCellPos, nRow, pCell);
     rBlockPos.miCellTextAttrPos = maCellTextAttrs.set(
         rBlockPos.miCellTextAttrPos, nRow, sc::CellTextAttr());
+    RegroupFormulaCells(nRow);
     CellStorageModified();
 
     ActivateNewFormulaCell(pCell);
@@ -2117,6 +2132,7 @@ void ScColumn::SetError( SCROW nRow, const sal_uInt16 nError)
     sc::CellStoreType::iterator it = GetPositionToInsert(nRow);
     maCells.set(it, nRow, pCell);
     maCellTextAttrs.set(nRow, sc::CellTextAttr());
+    RegroupFormulaCells(nRow);
     CellStorageModified();
 
     ActivateNewFormulaCell(pCell);
@@ -2130,6 +2146,7 @@ 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)
@@ -2146,6 +2163,7 @@ 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)
@@ -2160,6 +2178,7 @@ 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);
@@ -2175,6 +2194,7 @@ 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 3bad09c223fe697a4df46facc1ee390a67ea76e8
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Tue Jun 25 13:38:20 2013 -0400

    I forgot to pass the string param objects.
    
    Change-Id: I691de93daa1a6acaa99fba3af359f062406023d3

diff --git a/sc/source/ui/app/transobj.cxx b/sc/source/ui/app/transobj.cxx
index 6bf6d93..1e0d1e8 100644
--- a/sc/source/ui/app/transobj.cxx
+++ b/sc/source/ui/app/transobj.cxx
@@ -809,7 +809,7 @@ void ScTransferObj::StripRefs( ScDocument* pDoc,
 
                 ScSetStringParam aParam;
                 aParam.setTextInput();
-                pDestDoc->SetString(aPos, ScGlobal::GetErrorString(nErrCode));
+                pDestDoc->SetString(aPos, ScGlobal::GetErrorString(nErrCode), &aParam);
             }
             else if (pFCell->IsValue())
             {
@@ -828,7 +828,7 @@ void ScTransferObj::StripRefs( ScDocument* pDoc,
                 {
                     ScSetStringParam aParam;
                     aParam.setTextInput();
-                    pDestDoc->SetString(aPos, aStr);
+                    pDestDoc->SetString(aPos, aStr, &aParam);
                 }
             }
 
commit 68b24a8f0e8494ceb7c85d0cbf8447a381e5825d
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Tue Jun 25 12:39:27 2013 -0400

    Remove duplicate code blocks.
    
    Change-Id: Ie014ec8866d9e3055a6e67bd20503fc6fc26f503

diff --git a/sc/inc/validat.hxx b/sc/inc/validat.hxx
index 85737a3..904279a 100644
--- a/sc/inc/validat.hxx
+++ b/sc/inc/validat.hxx
@@ -29,7 +29,6 @@ namespace ValidListType = ::com::sun::star::sheet::TableValidationVisibility;
 class ScPatternAttr;
 class ScTokenArray;
 class ScTypedStrData;
-class ScCellIterator;
 
 enum ScValidationMode
 {
diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx
index 7826874..61f93fd 100644
--- a/sc/source/core/inc/interpre.hxx
+++ b/sc/source/core/inc/interpre.hxx
@@ -49,7 +49,6 @@ struct ScComplexRefData;
 
 class ScToken;
 class ScJumpMatrix;
-class ScCellIterator;
 struct ScRefCellValue;
 
 #define MAXSTACK      (4096 / sizeof(formula::FormulaToken*))
diff --git a/sc/source/filter/xml/xmlexprt.cxx b/sc/source/filter/xml/xmlexprt.cxx
index c78c4df..40965ae 100644
--- a/sc/source/filter/xml/xmlexprt.cxx
+++ b/sc/source/filter/xml/xmlexprt.cxx
@@ -2059,18 +2059,7 @@ void ScXMLExport::_ExportAutoStyles()
             SCTAB nTabCount = pDoc->GetTableCount();
             for (SCTAB nTab=0; nTab<nTabCount; ++nTab)
                 if (pDoc->IsStreamValid(nTab))
-                {
-                    ScCellIterator aIter( pDoc, ScRange(0, 0, nTab, MAXCOL, MAXROW, nTab) );
-                    for (bool bHas = aIter.first(); bHas; bHas = aIter.next())
-                    {
-                        if (aIter.getType() != CELLTYPE_FORMULA)
-                            continue;
-
-                        ScFormulaCell* pFC = aIter.getFormulaCell();
-                        if (pFC)
-                            pFC->IsValue(); // interpret if dirty
-                    }
-                }
+                    pDoc->InterpretDirtyCells(ScRange(0, 0, nTab, MAXCOL, MAXROW, nTab));
 
             // stored cell styles
             const std::vector<ScCellStyleEntry>& rCellEntries = pSheetData->GetCellStyles();
diff --git a/sc/source/ui/view/tabview4.cxx b/sc/source/ui/view/tabview4.cxx
index 227d3d5..8140d51 100644
--- a/sc/source/ui/view/tabview4.cxx
+++ b/sc/source/ui/view/tabview4.cxx
@@ -506,16 +506,7 @@ void ScTabView::InterpretVisible()
             if (nX2 > MAXCOL) nX2 = MAXCOL;
             if (nY2 > MAXROW) nY2 = MAXROW;
 
-            ScCellIterator aIter(pDoc, ScRange(nX1, nY1, nTab, nX2, nY2, nTab));
-            for (bool bHas = aIter.first(); bHas; bHas = aIter.next())
-            {
-                if (aIter.getType() != CELLTYPE_FORMULA)
-                    continue;
-
-                ScFormulaCell* p = aIter.getFormulaCell();
-                if (p->GetDirty())
-                    p->Interpret();
-            }
+            pDoc->InterpretDirtyCells(ScRange(nX1, nY1, nTab, nX2, nY2, nTab));
         }
     }
 
commit 624f4b05e17c9af010795601d2ede06b0ca76f46
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Tue Jun 25 12:29:46 2013 -0400

    Replace ScCellIterator with sc::ProcessFormula.
    
    Change-Id: I0adf57e5e80972175633dd0c69d465544aa7d7a9

diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 79c37fc..3cbd7b8 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -455,6 +455,8 @@ public:
     void BroadcastCells( const std::vector<SCROW>& rRows );
     void EndFormulaListening( sc::ColumnBlockPosition& rBlockPos, SCROW nRow1, SCROW nRow2 );
 
+    void InterpretDirtyCells( SCROW nRow1, SCROW nRow2 );
+
 private:
 
     void CopyCellsInRangeToColumn(
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index fe88f09..e945477 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -847,6 +847,8 @@ public:
 
     void FillMatrix( ScMatrix& rMat, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ) const;
 
+    void InterpretDirtyCells( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 );
+
     /** Replace behaves differently to the Search; adjust the rCol and rRow accordingly.
 
         'Replace' replaces at the 'current' position, but in order to achieve
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index d1d5e38..c4886af 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -115,6 +115,21 @@ void ScColumn::EndFormulaListening( sc::ColumnBlockPosition& rBlockPos, SCROW nR
         sc::ProcessFormula(rBlockPos.miCellPos, maCells, nRow1, nRow2, aFunc);
 }
 
+struct DirtyCellInterpreter
+{
+    void operator() (size_t, ScFormulaCell* p)
+    {
+        if (p->GetDirty())
+            p->Interpret();
+    }
+};
+
+void ScColumn::InterpretDirtyCells( SCROW nRow1, SCROW nRow2 )
+{
+    DirtyCellInterpreter aFunc;
+    sc::ProcessFormula(maCells.begin(), maCells, nRow1, nRow2, aFunc);
+}
+
 void ScColumn::Delete( SCROW nRow )
 {
     std::pair<sc::CellStoreType::iterator,size_t> aPos = maCells.position(nRow);
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 57d95a3..1e23d7a 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -3480,20 +3480,22 @@ void ScDocument::SetTableOpDirty( const ScRange& rRange )
     SetAutoCalc( bOldAutoCalc );
 }
 
-
 void ScDocument::InterpretDirtyCells( const ScRangeList& rRanges )
 {
+    if (!GetAutoCalc())
+        return;
+
     for (size_t nPos=0, nRangeCount = rRanges.size(); nPos < nRangeCount; nPos++)
     {
-        ScCellIterator aIter( this, *rRanges[ nPos ] );
-        for (bool bHas = aIter.first(); bHas; bHas = aIter.next())
+        const ScRange& rRange = *rRanges[nPos];
+        for (SCTAB nTab = rRange.aStart.Tab(); nTab <= rRange.aEnd.Tab(); ++nTab)
         {
-            if (aIter.getType() != CELLTYPE_FORMULA)
-                continue;
+            ScTable* pTab = FetchTable(nTab);
+            if (!pTab)
+                return;
 
-            ScFormulaCell* p = aIter.getFormulaCell();
-            if (p->GetDirty() && GetAutoCalc())
-                p->Interpret();
+            pTab->InterpretDirtyCells(
+                rRange.aStart.Col(), rRange.aStart.Row(), rRange.aEnd.Col(), rRange.aEnd.Row());
         }
     }
 }
diff --git a/sc/source/core/data/table1.cxx b/sc/source/core/data/table1.cxx
index d3d26a8..2de23b1 100644
--- a/sc/source/core/data/table1.cxx
+++ b/sc/source/core/data/table1.cxx
@@ -2209,6 +2209,12 @@ void ScTable::FillMatrix( ScMatrix& rMat, SCCOL nCol1, SCROW nRow1, SCCOL nCol2,
         aCol[nCol].FillMatrix(rMat, nMatCol, nRow1, nRow2);
 }
 
+void ScTable::InterpretDirtyCells( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
+{
+    for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
+        aCol[nCol].InterpretDirtyCells(nRow1, nRow2);
+}
+
 const SvtBroadcaster* ScTable::GetBroadcaster( SCCOL nCol, SCROW nRow ) const
 {
     if (!ValidColRow(nCol, nRow))
commit a65939310f67d364adbbcab7ccee8a269f746d67
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Tue Jun 25 11:54:10 2013 -0400

    Move a common if statement into the function.
    
    Change-Id: Ic13c9e7bdfea97c4f7782181dc70d6965ba0b6b9

diff --git a/sc/source/core/data/dociter.cxx b/sc/source/core/data/dociter.cxx
index fc0c75a..34eb605 100644
--- a/sc/source/core/data/dociter.cxx
+++ b/sc/source/core/data/dociter.cxx
@@ -1776,6 +1776,10 @@ namespace {
 
 bool advanceBlock(size_t nRow, sc::CellStoreType::const_iterator& rPos, const sc::CellStoreType::const_iterator& rEnd)
 {
+    if (nRow < rPos->position + rPos->size)
+        // Block already contains the specified row. Nothing to do.
+        return true;
+
     // This block is behind the current row position. Advance the block.
     for (++rPos; rPos != rEnd; ++rPos)
     {
@@ -1803,9 +1807,8 @@ void ScHorizontalCellIterator::Advance()
         if (nRow < r.maPos->position)
             continue;
 
-        if (r.maPos->position + r.maPos->size <= nRow)
-            if (!advanceBlock(nRow, r.maPos, r.maEnd))
-                continue;
+        if (!advanceBlock(nRow, r.maPos, r.maEnd))
+            continue;
 
         if (r.maPos->type == sc::element_type_empty)
             continue;
@@ -1841,9 +1844,8 @@ void ScHorizontalCellIterator::Advance()
                 continue;
             }
 
-            if (r.maPos->position + r.maPos->size <= nRow)
-                if (!advanceBlock(nRow, r.maPos, r.maEnd))
-                    continue;
+            if (!advanceBlock(nRow, r.maPos, r.maEnd))
+                continue;
 
             if (r.maPos->type == sc::element_type_empty)
             {


More information about the Libreoffice-commits mailing list