[Libreoffice-commits] core.git: Branch 'private/kohei/calc-sort-fix' - 3 commits - sc/inc sc/source

Kohei Yoshida kohei.yoshida at collabora.com
Thu Apr 17 21:34:30 PDT 2014


 sc/inc/cellvalues.hxx              |   21 +++
 sc/inc/column.hxx                  |    5 
 sc/inc/table.hxx                   |    3 
 sc/source/core/data/cellvalues.cxx |  119 ++++++++++++++++++++--
 sc/source/core/data/column.cxx     |   36 ++++++
 sc/source/core/data/column4.cxx    |   31 ++++-
 sc/source/core/data/table2.cxx     |    8 +
 sc/source/core/data/table3.cxx     |  200 ++++++++++++++++++++++++++++---------
 sc/source/core/data/table7.cxx     |    8 +
 9 files changed, 371 insertions(+), 60 deletions(-)

New commits:
commit 5bbf5e86ced9d449da1e859e0ad98385eaeb969c
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Fri Apr 18 00:29:55 2014 -0400

    Avoid using SwapRow() when sorting.
    
    Instead, build a data table prior to sorting, swap rows in this data table
    as we sort, then transfer the results back to the document in one step.  This
    significantly speeds up the sort performance.
    
    Formula cells are yet to be handled. I'll work on that next.
    
    Change-Id: I59bde1a243dc8940411d1a33eef147671b060cd0

diff --git a/sc/inc/cellvalues.hxx b/sc/inc/cellvalues.hxx
index c22e3b3..8de0b04 100644
--- a/sc/inc/cellvalues.hxx
+++ b/sc/inc/cellvalues.hxx
@@ -13,10 +13,12 @@
 #include <address.hxx>
 
 class ScColumn;
+struct ScRefCellValue;
 
 namespace sc {
 
 struct CellValuesImpl;
+struct CellTextAttr;
 
 /**
  * Think of this as a mini-ScColumn like storage that only stores cell
@@ -33,10 +35,21 @@ public:
     CellValues();
     ~CellValues();
 
+    /**
+     * Transfer values from specified column.  The transferred segment in the
+     * source column becomes empty after this call.
+     *
+     * @param rCol source column to transfer values from.
+     * @param nRow top row position in the source column.
+     * @param nLen length of the segment to transfer.
+     */
     void transferFrom( ScColumn& rCol, SCROW nRow, size_t nLen );
+
+    void transferTo( ScColumn& rCol, SCROW nRow );
     void copyTo( ScColumn& rCol, SCROW nRow ) const;
 
     void assign( const std::vector<double>& rVals );
+    void append( ScRefCellValue& rVal, const CellTextAttr* pAttr );
 
     size_t size() const;
 
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 1fc84ca..10970df 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -566,6 +566,7 @@ public:
     void RegroupFormulaCells();
 
     void TransferCellValuesTo( SCROW nRow, size_t nLen, sc::CellValues& rDest );
+    void TransferCellValuesFrom( SCROW nRow, sc::CellValues& rSrc );
     void CopyCellValuesFrom( SCROW nRow, const sc::CellValues& rSrc );
 
 #if DEBUG_COLUMN_STORAGE
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 542979f..5ddcc5c 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -916,6 +916,7 @@ public:
         SCCOL nColDelta, SCROW nRowDelta );
 
     void TransferCellValuesTo( SCCOL nCol, SCROW nRow, size_t nLen, sc::CellValues& rDest );
+    void TransferCellValuesFrom( SCCOL nCol, SCROW nRow, sc::CellValues& rSrc );
     void CopyCellValuesFrom( SCCOL nCol, SCROW nRow, const sc::CellValues& rSrc );
 
 #if DEBUG_COLUMN_STORAGE
diff --git a/sc/source/core/data/cellvalues.cxx b/sc/source/core/data/cellvalues.cxx
index 423fa26..38ce4e8 100644
--- a/sc/source/core/data/cellvalues.cxx
+++ b/sc/source/core/data/cellvalues.cxx
@@ -9,6 +9,7 @@
 
 #include <cellvalues.hxx>
 #include <column.hxx>
+#include <cellvalue.hxx>
 
 #include <cassert>
 #include <boost/noncopyable.hpp>
@@ -37,6 +38,15 @@ void CellValues::transferFrom( ScColumn& rCol, SCROW nRow, size_t nLen )
     rCol.maCellTextAttrs.transfer(nRow, nRow+nLen-1, mpImpl->maCellTextAttrs, 0);
 }
 
+void CellValues::transferTo( ScColumn& rCol, SCROW nRow )
+{
+    assert(mpImpl->maCells.size() == mpImpl->maCellTextAttrs.size());
+
+    size_t nLen = mpImpl->maCells.size();
+    mpImpl->maCells.transfer(0, nLen-1, rCol.maCells, nRow);
+    mpImpl->maCellTextAttrs.transfer(0, nLen-1, rCol.maCellTextAttrs, nRow);
+}
+
 void CellValues::copyTo( ScColumn& rCol, SCROW nRow ) const
 {
     copyCellsTo(rCol, nRow);
@@ -54,6 +64,55 @@ void CellValues::assign( const std::vector<double>& rVals )
     mpImpl->maCellTextAttrs.set(0, aDefaults.begin(), aDefaults.end());
 }
 
+void CellValues::append( ScRefCellValue& rVal, const CellTextAttr* pAttr )
+{
+    assert(mpImpl->maCells.size() == mpImpl->maCellTextAttrs.size());
+
+    size_t n = mpImpl->maCells.size();
+
+    bool bAppendAttr = true;
+
+    switch (rVal.meType)
+    {
+        case CELLTYPE_STRING:
+        {
+            mpImpl->maCells.resize(n+1);
+            mpImpl->maCells.set(n, *rVal.mpString);
+        }
+        break;
+        case CELLTYPE_VALUE:
+        {
+            mpImpl->maCells.resize(n+1);
+            mpImpl->maCells.set(n, rVal.mfValue);
+        }
+        break;
+        case CELLTYPE_EDIT:
+        {
+            mpImpl->maCells.resize(n+1);
+            mpImpl->maCells.set(n, rVal.mpEditText->Clone());
+        }
+        break;
+        case CELLTYPE_FORMULA:
+        {
+            mpImpl->maCells.resize(n+1);
+
+            // TODO : Handle this.
+        }
+        default:
+            bAppendAttr = false;
+    }
+
+    if (bAppendAttr)
+    {
+        mpImpl->maCellTextAttrs.resize(n+1);
+
+        if (pAttr)
+            mpImpl->maCellTextAttrs.set(n, *pAttr);
+        else
+            mpImpl->maCellTextAttrs.set(n, CellTextAttr());
+    }
+}
+
 size_t CellValues::size() const
 {
     assert(mpImpl->maCells.size() == mpImpl->maCellTextAttrs.size());
diff --git a/sc/source/core/data/column4.cxx b/sc/source/core/data/column4.cxx
index 37a082e..2698f0b 100644
--- a/sc/source/core/data/column4.cxx
+++ b/sc/source/core/data/column4.cxx
@@ -289,6 +289,31 @@ void ScColumn::TransferCellValuesTo( SCROW nRow, size_t nLen, sc::CellValues& rD
     BroadcastCells(aRows, SC_HINT_DATACHANGED);
 }
 
+void ScColumn::TransferCellValuesFrom( SCROW nRow, sc::CellValues& rSrc )
+{
+    if (!ValidRow(nRow))
+        return;
+
+    SCROW nLastRow = nRow + rSrc.size() - 1;
+    if (nLastRow > MAXROW)
+        // Out of bound. Do nothing
+        return;
+
+    sc::CellStoreType::position_type aPos = maCells.position(nRow);
+    DetachFormulaCells(aPos, rSrc.size());
+
+    rSrc.transferTo(*this, nRow);
+
+    CellStorageModified();
+
+    std::vector<SCROW> aRows;
+    aRows.reserve(rSrc.size());
+    for (SCROW i = nRow; i <= nLastRow; ++i)
+        aRows.push_back(i);
+
+    BroadcastCells(aRows, SC_HINT_DATACHANGED);
+}
+
 void ScColumn::CopyCellValuesFrom( SCROW nRow, const sc::CellValues& rSrc )
 {
     if (!ValidRow(nRow))
diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
index 4b7bde2..bb6148f 100644
--- a/sc/source/core/data/table3.cxx
+++ b/sc/source/core/data/table3.cxx
@@ -56,6 +56,8 @@
 #include "tokenarray.hxx"
 #include "mtvcellfunc.hxx"
 #include "columnspanset.hxx"
+#include <stlalgorithm.hxx>
+#include <cellvalues.hxx>
 
 #include "svl/sharedstringpool.hxx"
 
@@ -63,6 +65,8 @@
 #include <boost/scoped_ptr.hpp>
 #include <boost/scoped_array.hpp>
 #include <boost/unordered_set.hpp>
+#include <boost/noncopyable.hpp>
+#include <boost/ptr_container/ptr_vector.hpp>
 
 using namespace ::com::sun::star;
 
@@ -215,9 +219,24 @@ IMPL_FIXEDMEMPOOL_NEWDEL( ScSortInfo )
 // END OF STATIC DATA -----------------------------------------------------
 
 
-class ScSortInfoArray
+class ScSortInfoArray : boost::noncopyable
 {
+public:
+
+    struct Cell
+    {
+        ScRefCellValue maCell;
+        const sc::CellTextAttr* mpAttr;
+
+        Cell() : mpAttr(NULL) {}
+    };
+
+    typedef std::vector<Cell> RowType;
+    typedef std::vector<RowType*> RowsType;
+
 private:
+    boost::scoped_ptr<RowsType> mpRows; /// row-wise data table for sort by row operation.
+
     ScSortInfo***   pppInfo;
     SCSIZE          nCount;
     SCCOLROW        nStart;
@@ -237,35 +256,64 @@ public:
                             pppInfo[nSort] = ppInfo;
                         }
                     }
-                ~ScSortInfoArray()
-                    {
-                        for ( sal_uInt16 nSort = 0; nSort < nUsedSorts; nSort++ )
-                        {
-                            ScSortInfo** ppInfo = pppInfo[nSort];
-                            for ( SCSIZE j = 0; j < nCount; j++ )
-                                delete ppInfo[j];
-                            delete [] ppInfo;
-                        }
-                        delete[] pppInfo;
-                    }
+
+    ~ScSortInfoArray()
+    {
+        for ( sal_uInt16 nSort = 0; nSort < nUsedSorts; nSort++ )
+        {
+            ScSortInfo** ppInfo = pppInfo[nSort];
+            for ( SCSIZE j = 0; j < nCount; j++ )
+                delete ppInfo[j];
+            delete [] ppInfo;
+        }
+        delete[] pppInfo;
+
+        if (mpRows)
+            std::for_each(mpRows->begin(), mpRows->end(), ScDeleteObjectByPtr<RowType>());
+    }
+
     ScSortInfo* Get( sal_uInt16 nSort, SCCOLROW nInd )
                     { return (pppInfo[nSort])[ nInd - nStart ]; }
-    void        Swap( SCCOLROW nInd1, SCCOLROW nInd2 )
-                    {
-                        SCSIZE n1 = static_cast<SCSIZE>(nInd1 - nStart);
-                        SCSIZE n2 = static_cast<SCSIZE>(nInd2 - nStart);
-                        for ( sal_uInt16 nSort = 0; nSort < nUsedSorts; nSort++ )
-                        {
-                            ScSortInfo** ppInfo = pppInfo[nSort];
-                            ScSortInfo* pTmp = ppInfo[n1];
-                            ppInfo[n1] = ppInfo[n2];
-                            ppInfo[n2] = pTmp;
-                        }
-                    }
+
+    void Swap( SCCOLROW nInd1, SCCOLROW nInd2 )
+    {
+        SCSIZE n1 = static_cast<SCSIZE>(nInd1 - nStart);
+        SCSIZE n2 = static_cast<SCSIZE>(nInd2 - nStart);
+        for ( sal_uInt16 nSort = 0; nSort < nUsedSorts; nSort++ )
+        {
+            ScSortInfo** ppInfo = pppInfo[nSort];
+            ScSortInfo* pTmp = ppInfo[n1];
+            ppInfo[n1] = ppInfo[n2];
+            ppInfo[n2] = pTmp;
+        }
+
+        if (mpRows)
+        {
+            // Swap rows in data table.
+            RowsType& rRows = *mpRows;
+            std::swap(rRows[nInd1], rRows[nInd2]);
+        }
+    }
+
     sal_uInt16      GetUsedSorts() const { return nUsedSorts; }
     ScSortInfo**    GetFirstArray() const { return pppInfo[0]; }
     SCCOLROW    GetStart() const { return nStart; }
     SCSIZE      GetCount() const { return nCount; }
+
+    RowsType& InitDataRows( size_t nRowSize, size_t nColSize )
+    {
+        mpRows.reset(new RowsType);
+        mpRows->reserve(nRowSize);
+        for (size_t i = 0; i < nRowSize; ++i)
+            mpRows->push_back(new RowType(nColSize, Cell()));
+
+        return *mpRows;
+    }
+
+    RowsType* GetDataRows()
+    {
+        return mpRows.get();
+    }
 };
 
 ScSortInfoArray* ScTable::CreateSortInfoArray( SCCOLROW nInd1, SCCOLROW nInd2 )
@@ -290,6 +338,25 @@ ScSortInfoArray* ScTable::CreateSortInfoArray( SCCOLROW nInd1, SCCOLROW nInd2 )
                 pInfo->nOrg = nRow;
             }
         }
+
+        // Filll row-wise data table.
+        ScSortInfoArray::RowsType& rRows = pArray->InitDataRows(
+            aSortParam.nRow2 - aSortParam.nRow1 + 1, aSortParam.nCol2 - aSortParam.nCol1 + 1);
+
+        for (SCCOL nCol = aSortParam.nCol1; nCol <= aSortParam.nCol2; ++nCol)
+        {
+            ScColumn& rCol = aCol[nCol];
+            sc::ColumnBlockConstPosition aBlockPos;
+            rCol.InitBlockPosition(aBlockPos);
+            for (SCROW nRow = aSortParam.nRow1; nRow <= aSortParam.nRow2; ++nRow)
+            {
+                ScSortInfoArray::RowType& rRow = *rRows[nRow-aSortParam.nRow1];
+                ScSortInfoArray::Cell& rCell = rRow[nCol-aSortParam.nCol1];
+
+                rCell.maCell = rCol.GetCellValue(aBlockPos, nRow);
+                rCell.mpAttr = rCol.GetCellTextAttr(aBlockPos, nRow);
+            }
+        }
     }
     else
     {
@@ -348,35 +415,69 @@ void ScTable::DestroySortCollator()
 
 void ScTable::SortReorder( ScSortInfoArray* pArray, ScProgress* pProgress )
 {
-    bool bByRow = aSortParam.bByRow;
-    SCSIZE nCount = pArray->GetCount();
+    size_t nCount = pArray->GetCount();
     SCCOLROW nStart = pArray->GetStart();
     ScSortInfo** ppInfo = pArray->GetFirstArray();
-    ::std::vector<ScSortInfo*> aTable(nCount);
-    SCSIZE nPos;
-    for ( nPos = 0; nPos < nCount; nPos++ )
-        aTable[ppInfo[nPos]->nOrg - nStart] = ppInfo[nPos];
 
-    SCCOLROW nDest = nStart;
-    for ( nPos = 0; nPos < nCount; nPos++, nDest++ )
+    if (aSortParam.bByRow)
     {
-        SCCOLROW nOrg = ppInfo[nPos]->nOrg;
-        if ( nDest != nOrg )
+        ScSortInfoArray::RowsType* pRows = pArray->GetDataRows();
+        assert(pRows); // In sort-by-row mode we must have data rows already populated.
+
+        // Cells in the data rows only reference values in the document. Make
+        // a copy before updating the document.
+
+        size_t nColCount = aSortParam.nCol2 - aSortParam.nCol1 + 1;
+        boost::ptr_vector<sc::CellValues> aSortedCols;
+        aSortedCols.reserve(nColCount);
+        for (size_t i = 0; i < nColCount; ++i)
+            aSortedCols.push_back(new sc::CellValues);
+
+        for (size_t i = 0; i < pRows->size(); ++i)
         {
-            if ( bByRow )
-                SwapRow( nDest, nOrg );
-            else
+            ScSortInfoArray::RowType* pRow = (*pRows)[i];
+            for (size_t nCol = 0; nCol < pRow->size(); ++nCol)
+            {
+                ScSortInfoArray::Cell& rCell = (*pRow)[nCol];
+                sc::CellValues& rStore = aSortedCols.at(nCol);
+                rStore.append(rCell.maCell, rCell.mpAttr);
+            }
+
+            if (pProgress)
+                pProgress->SetStateOnPercent(i);
+        }
+
+        for (size_t i = 0, n = aSortedCols.size(); i < n; ++i)
+        {
+            sc::CellValues& rSortedCol = aSortedCols[i];
+            TransferCellValuesFrom(i+aSortParam.nCol1, aSortParam.nRow1, rSortedCol);
+        }
+    }
+    else
+    {
+        std::vector<ScSortInfo*> aTable(nCount);
+        SCSIZE nPos;
+        for ( nPos = 0; nPos < nCount; nPos++ )
+            aTable[ppInfo[nPos]->nOrg - nStart] = ppInfo[nPos];
+
+        SCCOLROW nDest = nStart;
+        for ( nPos = 0; nPos < nCount; nPos++, nDest++ )
+        {
+            SCCOLROW nOrg = ppInfo[nPos]->nOrg;
+            if ( nDest != nOrg )
+            {
                 SwapCol( static_cast<SCCOL>(nDest), static_cast<SCCOL>(nOrg) );
-            // neue Position des weggeswapten eintragen
-            ScSortInfo* p = ppInfo[nPos];
-            p->nOrg = nDest;
-            ::std::swap(p, aTable[nDest-nStart]);
-            p->nOrg = nOrg;
-            ::std::swap(p, aTable[nOrg-nStart]);
-            OSL_ENSURE( p == ppInfo[nPos], "SortReorder: nOrg MisMatch" );
+                // neue Position des weggeswapten eintragen
+                ScSortInfo* p = ppInfo[nPos];
+                p->nOrg = nDest;
+                ::std::swap(p, aTable[nDest-nStart]);
+                p->nOrg = nOrg;
+                ::std::swap(p, aTable[nOrg-nStart]);
+                OSL_ENSURE( p == ppInfo[nPos], "SortReorder: nOrg MisMatch" );
+            }
+            if(pProgress)
+                pProgress->SetStateOnPercent( nPos );
         }
-        if(pProgress)
-            pProgress->SetStateOnPercent( nPos );
     }
 }
 
diff --git a/sc/source/core/data/table7.cxx b/sc/source/core/data/table7.cxx
index 48aa0a4..928c109 100644
--- a/sc/source/core/data/table7.cxx
+++ b/sc/source/core/data/table7.cxx
@@ -72,6 +72,14 @@ void ScTable::TransferCellValuesTo( SCCOL nCol, SCROW nRow, size_t nLen, sc::Cel
     aCol[nCol].TransferCellValuesTo(nRow, nLen, rDest);
 }
 
+void ScTable::TransferCellValuesFrom( SCCOL nCol, SCROW nRow, sc::CellValues& rSrc )
+{
+    if (!ValidCol(nCol))
+        return;
+
+    aCol[nCol].TransferCellValuesFrom(nRow, rSrc);
+}
+
 void ScTable::CopyCellValuesFrom( SCCOL nCol, SCROW nRow, const sc::CellValues& rSrc )
 {
     if (!ValidCol(nCol))
commit 510d620b0f068b4d4e006c6a7fc203edd55ab03b
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Thu Apr 17 21:14:04 2014 -0400

    Have CellValues handle text attribute values as well.
    
    To ensure that the cell and cell text attribute storage stay in sync at all
    times.
    
    Change-Id: I5ea3fb7601f42f22af30f4f2d96d9d5e481e0853

diff --git a/sc/inc/cellvalues.hxx b/sc/inc/cellvalues.hxx
index 8b249b4..c22e3b3 100644
--- a/sc/inc/cellvalues.hxx
+++ b/sc/inc/cellvalues.hxx
@@ -18,6 +18,10 @@ namespace sc {
 
 struct CellValuesImpl;
 
+/**
+ * Think of this as a mini-ScColumn like storage that only stores cell
+ * values in a column.
+ */
 class CellValues
 {
     CellValuesImpl* mpImpl;
@@ -35,6 +39,10 @@ public:
     void assign( const std::vector<double>& rVals );
 
     size_t size() const;
+
+private:
+    void copyCellsTo( ScColumn& rCol, SCROW nRow ) const;
+    void copyCellTextAttrsTo( ScColumn& rCol, SCROW nRow ) const;
 };
 
 }
diff --git a/sc/source/core/data/cellvalues.cxx b/sc/source/core/data/cellvalues.cxx
index 5f7802e..423fa26 100644
--- a/sc/source/core/data/cellvalues.cxx
+++ b/sc/source/core/data/cellvalues.cxx
@@ -18,6 +18,7 @@ namespace sc {
 struct CellValuesImpl : boost::noncopyable
 {
     CellStoreType maCells;
+    CellTextAttrStoreType maCellTextAttrs;
 };
 
 CellValues::CellValues() :
@@ -31,11 +32,36 @@ CellValues::~CellValues()
 void CellValues::transferFrom( ScColumn& rCol, SCROW nRow, size_t nLen )
 {
     mpImpl->maCells.resize(nLen);
+    mpImpl->maCellTextAttrs.resize(nLen);
     rCol.maCells.transfer(nRow, nRow+nLen-1, mpImpl->maCells, 0);
+    rCol.maCellTextAttrs.transfer(nRow, nRow+nLen-1, mpImpl->maCellTextAttrs, 0);
 }
 
 void CellValues::copyTo( ScColumn& rCol, SCROW nRow ) const
 {
+    copyCellsTo(rCol, nRow);
+    copyCellTextAttrsTo(rCol, nRow);
+}
+
+void CellValues::assign( const std::vector<double>& rVals )
+{
+    mpImpl->maCells.resize(rVals.size());
+    mpImpl->maCells.set(0, rVals.begin(), rVals.end());
+
+    // Set default text attributes.
+    std::vector<CellTextAttr> aDefaults(rVals.size(), CellTextAttr());
+    mpImpl->maCellTextAttrs.resize(rVals.size());
+    mpImpl->maCellTextAttrs.set(0, aDefaults.begin(), aDefaults.end());
+}
+
+size_t CellValues::size() const
+{
+    assert(mpImpl->maCells.size() == mpImpl->maCellTextAttrs.size());
+    return mpImpl->maCells.size();
+}
+
+void CellValues::copyCellsTo( ScColumn& rCol, SCROW nRow ) const
+{
     CellStoreType& rDest = rCol.maCells;
     const CellStoreType& rSrc = mpImpl->maCells;
 
@@ -100,15 +126,35 @@ void CellValues::copyTo( ScColumn& rCol, SCROW nRow ) const
     }
 }
 
-void CellValues::assign( const std::vector<double>& rVals )
+void CellValues::copyCellTextAttrsTo( ScColumn& rCol, SCROW nRow ) const
 {
-    mpImpl->maCells.resize(rVals.size());
-    mpImpl->maCells.set(0, rVals.begin(), rVals.end());
-}
+    CellTextAttrStoreType& rDest = rCol.maCellTextAttrs;
+    const CellTextAttrStoreType& rSrc = mpImpl->maCellTextAttrs;
 
-size_t CellValues::size() const
-{
-    return mpImpl->maCells.size();
+    // Caller must ensure the destination is long enough.
+    assert(rSrc.size() + static_cast<size_t>(nRow) < rDest.size());
+
+    SCROW nCurRow = nRow;
+    CellTextAttrStoreType::iterator itPos = rDest.begin();
+
+    CellTextAttrStoreType::const_iterator itBlk = rSrc.begin(), itBlkEnd = rSrc.end();
+    for (; itBlk != itBlkEnd; ++itBlk)
+    {
+        switch (itBlk->type)
+        {
+            case element_type_celltextattr:
+            {
+                celltextattr_block::const_iterator it = celltextattr_block::begin(*itBlk->data);
+                celltextattr_block::const_iterator itEnd = celltextattr_block::end(*itBlk->data);
+                itPos = rDest.set(itPos, nCurRow, it, itEnd);
+            }
+            break;
+            default:
+                itPos = rDest.set_empty(itPos, nCurRow, nCurRow+itBlk->size-1);
+        }
+
+        nCurRow += itBlk->size;
+    }
 }
 
 }
diff --git a/sc/source/core/data/column4.cxx b/sc/source/core/data/column4.cxx
index ec938d8..37a082e 100644
--- a/sc/source/core/data/column4.cxx
+++ b/sc/source/core/data/column4.cxx
@@ -279,9 +279,6 @@ void ScColumn::TransferCellValuesTo( SCROW nRow, size_t nLen, sc::CellValues& rD
 
     rDest.transferFrom(*this, nRow, nLen);
 
-    std::vector<sc::CellTextAttr> aDefaults(nLen);
-    maCellTextAttrs.set(nRow, aDefaults.begin(), aDefaults.end());
-
     CellStorageModified();
 
     std::vector<SCROW> aRows;
@@ -307,9 +304,6 @@ void ScColumn::CopyCellValuesFrom( SCROW nRow, const sc::CellValues& rSrc )
 
     rSrc.copyTo(*this, nRow);
 
-    std::vector<sc::CellTextAttr> aDefaults(rSrc.size());
-    maCellTextAttrs.set(nRow, aDefaults.begin(), aDefaults.end());
-
     CellStorageModified();
 
     std::vector<SCROW> aRows;
commit c08d8c10927d533d81b1c6c9d0b6b631af462172
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Thu Apr 17 13:24:51 2014 -0400

    Store cell text attribute pointers during initialization.
    
    This will be used later when re-ordering rows.
    
    Change-Id: I47504b49be11174b0002b1af1cbce9b8b7f2531c

diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 9318a77..1fc84ca 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -178,8 +178,12 @@ public:
     const sc::CellNoteStoreType& GetCellNoteStore() const { return maCellNotes; }
 
     ScRefCellValue GetCellValue( SCROW nRow ) const;
+    ScRefCellValue GetCellValue( sc::ColumnBlockConstPosition& rBlockPos, SCROW nRow ) const;
     ScRefCellValue GetCellValue( const sc::CellStoreType::const_iterator& itPos, size_t nOffset ) const;
 
+    const sc::CellTextAttr* GetCellTextAttr( SCROW nRow ) const;
+    const sc::CellTextAttr* GetCellTextAttr( sc::ColumnBlockConstPosition& rBlockPos, SCROW nRow ) const;
+
     void        Delete( SCROW nRow );
     void        FreeAll();
     void        SwapRow( SCROW nRow1, SCROW nRow2 );
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 7da8177..542979f 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -384,6 +384,8 @@ public:
     CellType    GetCellType( SCCOL nCol, SCROW nRow ) const;
     ScRefCellValue GetCellValue( SCCOL nCol, SCROW nRow ) const;
 
+    const sc::CellTextAttr* GetCellTextAttr( SCCOL nCol, SCROW nRow ) const;
+
     void        GetFirstDataPos(SCCOL& rCol, SCROW& rRow) const;
     void        GetLastDataPos(SCCOL& rCol, SCROW& rRow) const;
 
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index 2d2c44e..192aa5b 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -771,6 +771,16 @@ ScRefCellValue ScColumn::GetCellValue( SCROW nRow ) const
     return GetCellValue(aPos.first, aPos.second);
 }
 
+ScRefCellValue ScColumn::GetCellValue( sc::ColumnBlockConstPosition& rBlockPos, SCROW nRow ) const
+{
+    std::pair<sc::CellStoreType::const_iterator,size_t> aPos = maCells.position(rBlockPos.miCellPos, nRow);
+    if (aPos.first == maCells.end())
+        return ScRefCellValue();
+
+    rBlockPos.miCellPos = aPos.first; // Store this for next call.
+    return GetCellValue(aPos.first, aPos.second);
+}
+
 ScRefCellValue ScColumn::GetCellValue( const sc::CellStoreType::const_iterator& itPos, size_t nOffset ) const
 {
     ScRefCellValue aVal; // Defaults to empty cell.
@@ -803,6 +813,32 @@ ScRefCellValue ScColumn::GetCellValue( const sc::CellStoreType::const_iterator&
     return aVal;
 }
 
+const sc::CellTextAttr* ScColumn::GetCellTextAttr( SCROW nRow ) const
+{
+    sc::CellTextAttrStoreType::const_position_type aPos = maCellTextAttrs.position(nRow);
+    if (aPos.first == maCellTextAttrs.end())
+        return NULL;
+
+    if (aPos.first->type != sc::element_type_celltextattr)
+        return NULL;
+
+    return &sc::celltextattr_block::at(*aPos.first->data, aPos.second);
+}
+
+const sc::CellTextAttr* ScColumn::GetCellTextAttr( sc::ColumnBlockConstPosition& rBlockPos, SCROW nRow ) const
+{
+    sc::CellTextAttrStoreType::const_position_type aPos = maCellTextAttrs.position(rBlockPos.miCellTextAttrPos, nRow);
+    if (aPos.first == maCellTextAttrs.end())
+        return NULL;
+
+    rBlockPos.miCellTextAttrPos = aPos.first;
+
+    if (aPos.first->type != sc::element_type_celltextattr)
+        return NULL;
+
+    return &sc::celltextattr_block::at(*aPos.first->data, aPos.second);
+}
+
 namespace {
 
 ScFormulaCell* cloneFormulaCell(ScDocument* pDoc, const ScAddress& rNewPos, ScFormulaCell& rOldCell)
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index d72a436..af2492e 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -1596,6 +1596,14 @@ ScRefCellValue ScTable::GetCellValue( SCCOL nCol, SCROW nRow ) const
     return aCol[nCol].GetCellValue(nRow);
 }
 
+const sc::CellTextAttr* ScTable::GetCellTextAttr( SCCOL nCol, SCROW nRow ) const
+{
+    if (!ValidColRow(nCol, nRow))
+        return NULL;
+
+    return aCol[nCol].GetCellTextAttr(nRow);
+}
+
 void ScTable::GetFirstDataPos(SCCOL& rCol, SCROW& rRow) const
 {
     rCol = 0;
diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
index a9dcd03..4b7bde2 100644
--- a/sc/source/core/data/table3.cxx
+++ b/sc/source/core/data/table3.cxx
@@ -206,6 +206,7 @@ short Compare( const OUString &sInput1, const OUString &sInput2,
 struct ScSortInfo
 {
     ScRefCellValue maCell;
+    const sc::CellTextAttr* mpTextAttr;
     SCCOLROW        nOrg;
     DECL_FIXEDMEMPOOL_NEWDEL( ScSortInfo );
 };
@@ -279,10 +280,13 @@ ScSortInfoArray* ScTable::CreateSortInfoArray( SCCOLROW nInd1, SCCOLROW nInd2 )
         {
             SCCOL nCol = static_cast<SCCOL>(aSortParam.maKeyState[nSort].nField);
             ScColumn* pCol = &aCol[nCol];
+            sc::ColumnBlockConstPosition aBlockPos;
+            pCol->InitBlockPosition(aBlockPos);
             for ( SCROW nRow = nInd1; nRow <= nInd2; nRow++ )
             {
                 ScSortInfo* pInfo = pArray->Get( nSort, nRow );
-                pInfo->maCell = pCol->GetCellValue(nRow);
+                pInfo->maCell = pCol->GetCellValue(aBlockPos, nRow);
+                pInfo->mpTextAttr = pCol->GetCellTextAttr(aBlockPos, nRow);
                 pInfo->nOrg = nRow;
             }
         }
@@ -297,6 +301,7 @@ ScSortInfoArray* ScTable::CreateSortInfoArray( SCCOLROW nInd1, SCCOLROW nInd2 )
             {
                 ScSortInfo* pInfo = pArray->Get( nSort, nCol );
                 pInfo->maCell = GetCellValue(nCol, nRow);
+                pInfo->mpTextAttr = GetCellTextAttr(nCol, nRow);
                 pInfo->nOrg = nCol;
             }
         }


More information about the Libreoffice-commits mailing list