[Libreoffice-commits] core.git: 2 commits - sc/inc sc/source

Kohei Yoshida kohei.yoshida at collabora.com
Fri Jan 31 12:41:46 PST 2014


 sc/inc/column.hxx               |    5 +
 sc/inc/table.hxx                |    8 +
 sc/source/core/data/column4.cxx |  112 ++++++++++++++++++---------
 sc/source/core/data/table4.cxx  |  161 +++++++++++++++++++++++++++++-----------
 4 files changed, 206 insertions(+), 80 deletions(-)

New commits:
commit 571070074671bd0102422dd8a0ac1c3be6358f80
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Fri Jan 31 15:44:00 2014 -0500

    Speed up simple fill of formula cells. Vertical direction only.
    
    Other cells could be optimized in a similar fashion, but they aren't
    that slow even with the current code.
    
    Change-Id: I0b71bf271fab68c9fba0b39463dfe3ef46dacfb0

diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 69ba1af..7fefa04 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -57,6 +57,7 @@ class EditTextIterator;
 struct NoteEntry;
 class DocumentStreamAccess;
 class CellValues;
+struct RowSpan;
 
 }
 
@@ -218,6 +219,8 @@ public:
     void        DeleteRow( SCROW nStartRow, SCSIZE nSize );
     void DeleteArea(
         SCROW nStartRow, SCROW nEndRow, sal_uInt16 nDelFlag, bool bBroadcast = true );
+    void DeleteRanges( const std::vector<sc::RowSpan>& rRanges, sal_uInt16 nDelFlag, bool bBroadcast );
+
     void CopyToClip(
         sc::CopyToClipContext& rCxt, SCROW nRow1, SCROW nRow2, ScColumn& rColumn ) const;
     void CopyStaticToDocument(SCROW nRow1, SCROW nRow2, ScColumn& rDestCol);
@@ -289,6 +292,8 @@ public:
     ScFormulaCell* SetFormulaCell( SCROW nRow, ScFormulaCell* pCell );
     ScFormulaCell* SetFormulaCell( sc::ColumnBlockPosition& rBlockPos, SCROW nRow, ScFormulaCell* pCell );
 
+    void CloneFormulaCell( const ScFormulaCell& rSrc, const std::vector<sc::RowSpan>& rRanges );
+
     svl::SharedString GetSharedString( SCROW nRow ) const;
 
     void SetRawString( SCROW nRow, const OUString& rStr, bool bBroadcast = true );
diff --git a/sc/source/core/data/column4.cxx b/sc/source/core/data/column4.cxx
index 661c38d..7a5998c 100644
--- a/sc/source/core/data/column4.cxx
+++ b/sc/source/core/data/column4.cxx
@@ -14,6 +14,8 @@
 #include <attarray.hxx>
 #include <document.hxx>
 #include <cellvalues.hxx>
+#include <columnspanset.hxx>
+#include <listenercontext.hxx>
 
 #include <svl/sharedstring.hxx>
 
@@ -49,6 +51,8 @@ void ScColumn::CopyOneCellFromClip( sc::CopyFromClipContext& rCxt, SCROW nRow1,
 
     if ((nFlags & IDF_CONTENTS) != 0)
     {
+        std::vector<sc::CellTextAttr> aTextAttrs(nDestSize);
+
         switch (rSrcCell.meType)
         {
             case CELLTYPE_VALUE:
@@ -56,13 +60,18 @@ void ScColumn::CopyOneCellFromClip( sc::CopyFromClipContext& rCxt, SCROW nRow1,
                 std::vector<double> aVals(nDestSize, rSrcCell.mfValue);
                 pBlockPos->miCellPos =
                     maCells.set(pBlockPos->miCellPos, nRow1, aVals.begin(), aVals.end());
+                pBlockPos->miCellTextAttrPos =
+                    maCellTextAttrs.set(pBlockPos->miCellTextAttrPos, nRow1, aTextAttrs.begin(), aTextAttrs.end());
                 CellStorageModified();
             }
             break;
             case CELLTYPE_STRING:
             {
                 std::vector<svl::SharedString> aStrs(nDestSize, *rSrcCell.mpString);
-                maCells.set(pBlockPos->miCellPos, nRow1, aStrs.begin(), aStrs.end());
+                pBlockPos->miCellPos =
+                    maCells.set(pBlockPos->miCellPos, nRow1, aStrs.begin(), aStrs.end());
+                pBlockPos->miCellTextAttrPos =
+                    maCellTextAttrs.set(pBlockPos->miCellTextAttrPos, nRow1, aTextAttrs.begin(), aTextAttrs.end());
                 CellStorageModified();
             }
             break;
@@ -75,46 +84,17 @@ void ScColumn::CopyOneCellFromClip( sc::CopyFromClipContext& rCxt, SCROW nRow1,
 
                 pBlockPos->miCellPos =
                     maCells.set(pBlockPos->miCellPos, nRow1, aStrs.begin(), aStrs.end());
+                pBlockPos->miCellTextAttrPos =
+                    maCellTextAttrs.set(pBlockPos->miCellTextAttrPos, nRow1, aTextAttrs.begin(), aTextAttrs.end());
                 CellStorageModified();
             }
             break;
             case CELLTYPE_FORMULA:
             {
-                std::vector<ScFormulaCell*> aFormulas;
-                ScAddress aPos(nCol, nRow1, nTab);
-                aFormulas.reserve(nDestSize);
-                ScFormulaCellGroupRef xGroup(new ScFormulaCellGroup);
-                xGroup->setCode(*rSrcCell.mpFormula->GetCode());
-                xGroup->compileCode(*pDocument, aPos, pDocument->GetGrammar());
-                for (size_t i = 0; i < nDestSize; ++i)
-                {
-                    ScFormulaCell* pCell = new ScFormulaCell(pDocument, aPos, xGroup);
-                    if (i == 0)
-                    {
-                        xGroup->mpTopCell = pCell;
-                        xGroup->mnLength = nDestSize;
-                    }
-                    aFormulas.push_back(pCell);
-                    aPos.IncRow();
-                }
-
-                pBlockPos->miCellPos =
-                    maCells.set(pBlockPos->miCellPos, nRow1, aFormulas.begin(), aFormulas.end());
-
-                // Join the top and bottom of the pasted formula cells as needed.
-                sc::CellStoreType::position_type aPosObj =
-                    maCells.position(pBlockPos->miCellPos, nRow1);
-
-                assert(aPosObj.first->type == sc::element_type_formula);
-                ScFormulaCell* pCell = sc::formula_block::at(*aPosObj.first->data, aPosObj.second);
-                JoinNewFormulaCell(aPosObj, *pCell);
-
-                aPosObj = maCells.position(aPosObj.first, nRow2);
-                assert(aPosObj.first->type == sc::element_type_formula);
-                pCell = sc::formula_block::at(*aPosObj.first->data, aPosObj.second);
-                JoinNewFormulaCell(aPosObj, *pCell);
-
-                CellStorageModified();
+                std::vector<sc::RowSpan> aRanges;
+                aRanges.reserve(1);
+                aRanges.push_back(sc::RowSpan(nRow1, nRow2));
+                CloneFormulaCell(*rSrcCell.mpFormula, aRanges);
             }
             break;
             default:
@@ -228,4 +208,64 @@ void ScColumn::CopyCellValuesFrom( SCROW nRow, const sc::CellValues& rSrc )
     BroadcastCells(aRows, SC_HINT_DATACHANGED);
 }
 
+void ScColumn::DeleteRanges( const std::vector<sc::RowSpan>& rRanges, sal_uInt16 nDelFlag, bool bBroadcast )
+{
+    std::vector<sc::RowSpan>::const_iterator itSpan = rRanges.begin(), itSpanEnd = rRanges.end();
+    for (; itSpan != itSpanEnd; ++itSpan)
+        DeleteArea(itSpan->mnRow1, itSpan->mnRow2, nDelFlag, bBroadcast);
+}
+
+void ScColumn::CloneFormulaCell( const ScFormulaCell& rSrc, const std::vector<sc::RowSpan>& rRanges )
+{
+    sc::CellStoreType::iterator itPos = maCells.begin();
+    sc::CellTextAttrStoreType::iterator itAttrPos = maCellTextAttrs.begin();
+    sc::StartListeningContext aCxt(*pDocument);
+
+    std::vector<ScFormulaCell*> aFormulas;
+    std::vector<sc::RowSpan>::const_iterator itSpan = rRanges.begin(), itSpanEnd = rRanges.end();
+    for (; itSpan != itSpanEnd; ++itSpan)
+    {
+        SCROW nRow1 = itSpan->mnRow1, nRow2 = itSpan->mnRow2;
+        size_t nLen = nRow2 - nRow1 + 1;
+        aFormulas.clear();
+        aFormulas.reserve(nLen);
+
+        ScAddress aPos(nCol, nRow1, nTab);
+        ScFormulaCellGroupRef xGroup(new ScFormulaCellGroup);
+        xGroup->setCode(*rSrc.GetCode());
+        xGroup->compileCode(*pDocument, aPos, pDocument->GetGrammar());
+        for (size_t i = 0; i < nLen; ++i, aPos.IncRow())
+        {
+            ScFormulaCell* pCell = new ScFormulaCell(pDocument, aPos, xGroup);
+            if (i == 0)
+            {
+                xGroup->mpTopCell = pCell;
+                xGroup->mnLength = nLen;
+            }
+            pCell->StartListeningTo(aCxt);
+            pCell->SetDirty();
+            aFormulas.push_back(pCell);
+        }
+
+        itPos = maCells.set(itPos, nRow1, aFormulas.begin(), aFormulas.end());
+
+        // Join the top and bottom of the pasted formula cells as needed.
+        sc::CellStoreType::position_type aPosObj = maCells.position(itPos, nRow1);
+
+        assert(aPosObj.first->type == sc::element_type_formula);
+        ScFormulaCell* pCell = sc::formula_block::at(*aPosObj.first->data, aPosObj.second);
+        JoinNewFormulaCell(aPosObj, *pCell);
+
+        aPosObj = maCells.position(aPosObj.first, nRow2);
+        assert(aPosObj.first->type == sc::element_type_formula);
+        pCell = sc::formula_block::at(*aPosObj.first->data, aPosObj.second);
+        JoinNewFormulaCell(aPosObj, *pCell);
+
+        std::vector<sc::CellTextAttr> aTextAttrs(nLen);
+        itAttrPos = maCellTextAttrs.set(itAttrPos, nRow1, aTextAttrs.begin(), aTextAttrs.end());
+    }
+
+    CellStorageModified();
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/data/table4.cxx b/sc/source/core/data/table4.cxx
index 6a21cef..3f586f5 100644
--- a/sc/source/core/data/table4.cxx
+++ b/sc/source/core/data/table4.cxx
@@ -60,6 +60,7 @@
 #include "segmenttree.hxx"
 #include "conditio.hxx"
 #include "editutil.hxx"
+#include <columnspanset.hxx>
 
 #include <math.h>
 #include <boost/scoped_ptr.hpp>
@@ -1287,42 +1288,110 @@ void ScTable::FillSimple(
     SCCOLROW& rCol, SCCOLROW& rRow, bool bVertical, ScProgress* pProgress, sal_uLong& rProgress )
 {
     bool bHidden = false;
-    SCCOLROW nHiddenValid = -1;
+    SCCOLROW nHiddenLast = -1;
 
-    switch (rSrcCell.meType)
+    if (bVertical)
     {
-        case CELLTYPE_FORMULA:
+        switch (rSrcCell.meType)
         {
-            for (rInner = nIMin; rInner <= nIMax; ++rInner)
+            case CELLTYPE_FORMULA:
             {
-                if (rInner > nHiddenValid)
-                    bHidden = HiddenRowColumn(this, rInner, bVertical, nHiddenValid);
+                SCCOLROW nRowStart = -1, nRowEnd = -1;
+                std::vector<sc::RowSpan> aSpans;
+                for (rInner = nIMin; rInner <= nIMax; ++rInner)
+                {
+                    if (rInner > nHiddenLast)
+                        bHidden = HiddenRowColumn(this, rInner, bVertical, nHiddenLast);
+
+                    if (bHidden)
+                    {
+                        if (nRowStart >= 0)
+                        {
+                            nRowEnd = rInner - 1;
+                            aSpans.push_back(sc::RowSpan(nRowStart, nRowEnd));
+                            nRowStart = -1;
+                        }
+                        rInner = nHiddenLast;
+                        continue;
+                    }
 
-                if (bHidden)
-                    continue;
+                    if (nRowStart < 0)
+                        nRowStart = rInner;
+                }
 
-                FillFormula(rSrcCell.mpFormula, rCol, rRow, (rInner == nIMax));
+                if (nRowStart >= 0)
+                {
+                    nRowEnd = rInner - 1;
+                    aSpans.push_back(sc::RowSpan(nRowStart, nRowEnd));
+                }
+
+                aCol[rCol].DeleteRanges(aSpans, IDF_CONTENTS, false);
+                aCol[rCol].CloneFormulaCell(*rSrcCell.mpFormula, aSpans);
+
+                rProgress += nIMax - nIMin + 1;
                 if (pProgress)
-                    pProgress->SetStateOnPercent(++rProgress);
+                    pProgress->SetStateOnPercent(rProgress);
+            }
+            break;
+            default:
+            {
+                for (rInner = nIMin; rInner <= nIMax; ++rInner)
+                {
+                    if (rInner > nHiddenLast)
+                        bHidden = HiddenRowColumn(this, rInner, bVertical, nHiddenLast);
+
+                    if (bHidden)
+                    {
+                        rInner = nHiddenLast;
+                        continue;
+                    }
+
+                    ScAddress aDestPos(rCol, rRow, nTab);
+                    rSrcCell.commit(aCol[rCol], aDestPos.Row());
+                }
+                rProgress += nIMax - nIMin + 1;
+                if (pProgress)
+                    pProgress->SetStateOnPercent(rProgress);
             }
         }
-        break;
-        default:
+    }
+    else
+    {
+        switch (rSrcCell.meType)
         {
-            for (rInner = nIMin; rInner <= nIMax; ++rInner)
+            case CELLTYPE_FORMULA:
+            {
+                for (rInner = nIMin; rInner <= nIMax; ++rInner)
+                {
+                    if (rInner > nHiddenLast)
+                        bHidden = HiddenRowColumn(this, rInner, bVertical, nHiddenLast);
+
+                    if (bHidden)
+                        continue;
+
+                    FillFormula(rSrcCell.mpFormula, rCol, rRow, (rInner == nIMax));
+                    if (pProgress)
+                        pProgress->SetStateOnPercent(++rProgress);
+                }
+            }
+            break;
+            default:
             {
-                if (rInner > nHiddenValid)
-                    bHidden = HiddenRowColumn(this, rInner, bVertical, nHiddenValid);
+                for (rInner = nIMin; rInner <= nIMax; ++rInner)
+                {
+                    if (rInner > nHiddenLast)
+                        bHidden = HiddenRowColumn(this, rInner, bVertical, nHiddenLast);
 
-                if (bHidden)
-                    continue;
+                    if (bHidden)
+                        continue;
 
-                ScAddress aDestPos(rCol, rRow, nTab);
-                rSrcCell.commit(aCol[rCol], aDestPos.Row());
+                    ScAddress aDestPos(rCol, rRow, nTab);
+                    rSrcCell.commit(aCol[rCol], aDestPos.Row());
+                }
+                rProgress += nIMax - nIMin + 1;
+                if (pProgress)
+                    pProgress->SetStateOnPercent(rProgress);
             }
-            rProgress += nIMax - nIMin + 1;
-            if (pProgress)
-                pProgress->SetStateOnPercent(rProgress);
         }
     }
 }
commit 777e3930a1e85b9bc97c1852b09802fc389c5e2d
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Fri Jan 31 12:34:26 2014 -0500

    Move the code for "fill simple" to its own method.
    
    Change-Id: I317f20eb4e8b6e41f12b7da872d158b859579861

diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 260a736..658b4c1 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -915,6 +915,10 @@ public:
     static void UpdateSearchItemAddressForReplace( const SvxSearchItem& rSearchItem, SCCOL& rCol, SCROW& rRow );
 
 private:
+    void FillSimple(
+        ScCellValue& rSrcCell, SCCOLROW& rInner, SCCOLROW nIMin, SCCOLROW nIMax,
+        SCCOLROW& rCol, SCCOLROW& rRow, bool bVertical, ScProgress* pProgress, sal_uLong& rProgress );
+
     void        FillSeries( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
                                 sal_uLong nFillCount, FillDir eFillDir, FillCmd eFillCmd,
                                 FillDateCmd eFillDateCmd,
@@ -990,8 +994,8 @@ private:
     bool        IsEmptyLine(SCROW nRow, SCCOL nStartCol, SCCOL nEndCol) const;
 
     void        IncDate(double& rVal, sal_uInt16& nDayOfMonth, double nStep, FillDateCmd eCmd);
-    void        FillFormula(sal_uLong& nFormulaCounter, bool bFirst, ScFormulaCell* pSrcCell,
-                            SCCOL nDestCol, SCROW nDestRow, bool bLast );
+    void FillFormula(
+        ScFormulaCell* pSrcCell, SCCOL nDestCol, SCROW nDestRow, bool bLast );
     void        UpdateInsertTabAbs(SCTAB nNewPos);
     bool        GetNextSpellingCell(SCCOL& rCol, SCROW& rRow, bool bInSel,
                                     const ScMarkData& rMark) const;
diff --git a/sc/source/core/data/table4.cxx b/sc/source/core/data/table4.cxx
index ca89428..6a21cef 100644
--- a/sc/source/core/data/table4.cxx
+++ b/sc/source/core/data/table4.cxx
@@ -427,8 +427,8 @@ void ScTable::FillAnalyse( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
     }
 }
 
-void ScTable::FillFormula(sal_uLong& /* nFormulaCounter */, bool /* bFirst */, ScFormulaCell* pSrcCell,
-                          SCCOL nDestCol, SCROW nDestRow, bool bLast )
+void ScTable::FillFormula(
+    ScFormulaCell* pSrcCell, SCCOL nDestCol, SCROW nDestRow, bool bLast )
 {
 
     pDocument->SetNoListening( true );  // still the wrong reference
@@ -753,7 +753,6 @@ void ScTable::FillAuto( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
                 nDelta = -1.0;
             double nVal = 0.0;
             sal_uLong nFormulaCounter = nActFormCnt;
-            bool bFirst = true;
             bool bGetCell = true;
             sal_uInt16 nCellDigits = 0;
             short nHeadNoneTail = 0;
@@ -843,7 +842,8 @@ void ScTable::FillAuto( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
 
                             break;
                         case CELLTYPE_FORMULA :
-                            FillFormula( nFormulaCounter, bFirst, aSrcCell.mpFormula,
+                            FillFormula(
+                                aSrcCell.mpFormula,
                                     static_cast<SCCOL>(nCol),
                                     static_cast<SCROW>(nRow), (rInner == nIEnd) );
                             if (nFormulaCounter - nActFormCnt > nMaxFormCnt)
@@ -870,7 +870,6 @@ void ScTable::FillAuto( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
                                 nDelta -= 1.0;
                         }
                         nFormulaCounter = nActFormCnt;
-                        bFirst = false;
                     }
                     else if (bPositive)
                     {
@@ -1283,6 +1282,51 @@ bool HiddenRowColumn(ScTable* pTable, SCCOLROW nRowColumn, bool bVertical, SCCOL
 
 }
 
+void ScTable::FillSimple(
+    ScCellValue& rSrcCell, SCCOLROW& rInner, SCCOLROW nIMin, SCCOLROW nIMax,
+    SCCOLROW& rCol, SCCOLROW& rRow, bool bVertical, ScProgress* pProgress, sal_uLong& rProgress )
+{
+    bool bHidden = false;
+    SCCOLROW nHiddenValid = -1;
+
+    switch (rSrcCell.meType)
+    {
+        case CELLTYPE_FORMULA:
+        {
+            for (rInner = nIMin; rInner <= nIMax; ++rInner)
+            {
+                if (rInner > nHiddenValid)
+                    bHidden = HiddenRowColumn(this, rInner, bVertical, nHiddenValid);
+
+                if (bHidden)
+                    continue;
+
+                FillFormula(rSrcCell.mpFormula, rCol, rRow, (rInner == nIMax));
+                if (pProgress)
+                    pProgress->SetStateOnPercent(++rProgress);
+            }
+        }
+        break;
+        default:
+        {
+            for (rInner = nIMin; rInner <= nIMax; ++rInner)
+            {
+                if (rInner > nHiddenValid)
+                    bHidden = HiddenRowColumn(this, rInner, bVertical, nHiddenValid);
+
+                if (bHidden)
+                    continue;
+
+                ScAddress aDestPos(rCol, rRow, nTab);
+                rSrcCell.commit(aCol[rCol], aDestPos.Row());
+            }
+            rProgress += nIMax - nIMin + 1;
+            if (pProgress)
+                pProgress->SetStateOnPercent(rProgress);
+        }
+    }
+}
+
 void ScTable::FillSeries( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
                     sal_uLong nFillCount, FillDir eFillDir, FillCmd eFillCmd, FillDateCmd eFillDateCmd,
                     double nStepValue, double nMaxValue, sal_uInt16 nArgMinDigits,
@@ -1449,43 +1493,7 @@ void ScTable::FillSeries( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
 
             if (eFillCmd == FILL_SIMPLE)                // copy
             {
-                bool bHidden = false;
-                SCCOLROW nHiddenValid = -1;
-
-                if (eCellType == CELLTYPE_FORMULA)
-                {
-                    bool bFirst = true;
-                    for (rInner = nIMin; rInner <= nIMax; rInner++)
-                    {
-                        if (rInner > nHiddenValid)
-                            bHidden = HiddenRowColumn(this, rInner, bVertical, nHiddenValid);
-
-                        if (bHidden)
-                            continue;
-                        sal_uLong nInd = nActFormCnt;
-                        FillFormula(nInd, bFirst, aSrcCell.mpFormula,
-                            static_cast<SCCOL>(nCol), nRow, (rInner == nIEnd) );
-                        bFirst = false;
-                        if(pProgress)
-                            pProgress->SetStateOnPercent( ++nProgress );
-                    }
-                }
-                else
-                {
-                    for (rInner = nIMin; rInner <= nIMax; rInner++)
-                    {
-                        if (rInner > nHiddenValid)
-                            bHidden = HiddenRowColumn(this, rInner, bVertical, nHiddenValid);
-
-                        if (bHidden)
-                            continue;
-                        ScAddress aDestPos( static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), nTab );
-                        aSrcCell.commit(aCol[nCol], aDestPos.Row());
-                    }
-                    nProgress += nIMax - nIMin + 1;
-                    if(pProgress)
-                        pProgress->SetStateOnPercent( nProgress );
-                }
+                FillSimple(aSrcCell, rInner, nIMin, nIMax, nCol, nRow, bVertical, pProgress, nProgress);
             }
             else if (eCellType == CELLTYPE_VALUE || eCellType == CELLTYPE_FORMULA)
             {


More information about the Libreoffice-commits mailing list