[Libreoffice-commits] core.git: Branch 'private/kohei/sort-ref-update' - 4 commits - sc/inc sc/source

Kohei Yoshida kohei.yoshida at collabora.com
Sat Jul 12 14:56:56 PDT 2014


 sc/inc/sortparam.hxx               |   20 ++-
 sc/inc/table.hxx                   |    3 
 sc/inc/undosort.hxx                |    3 
 sc/source/core/data/sortparam.cxx  |   51 +++++++
 sc/source/core/data/table3.cxx     |  242 +++++++++++++++++++++++++++----------
 sc/source/ui/docshell/dbdocfun.cxx |   93 --------------
 sc/source/ui/undo/undosort.cxx     |   23 +++
 7 files changed, 273 insertions(+), 162 deletions(-)

New commits:
commit 61655e2d53f7f6d620992eda5dd4b5d72c0d6a7c
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Sat Jul 12 17:56:23 2014 -0400

    Cleanup.
    
    Change-Id: I0da0f83778961b7f933f3b77a1337497072eea50

diff --git a/sc/source/ui/docshell/dbdocfun.cxx b/sc/source/ui/docshell/dbdocfun.cxx
index daaff7f..5398042 100644
--- a/sc/source/ui/docshell/dbdocfun.cxx
+++ b/sc/source/ui/docshell/dbdocfun.cxx
@@ -52,48 +52,6 @@
 #include <set>
 #include <memory>
 
-#include <stdio.h>
-#include <string>
-#include <sys/time.h>
-
-namespace {
-
-class stack_printer
-{
-public:
-    explicit stack_printer(const char* msg) :
-        msMsg(msg)
-    {
-        fprintf(stdout, "%s: --begin\n", msMsg.c_str());
-        mfStartTime = getTime();
-    }
-
-    ~stack_printer()
-    {
-        double fEndTime = getTime();
-        fprintf(stdout, "%s: --end (duration: %g sec)\n", msMsg.c_str(), (fEndTime - mfStartTime));
-    }
-
-    void printTime(int line) const
-    {
-        double fEndTime = getTime();
-        fprintf(stdout, "%s: --(%d) (duration: %g sec)\n", msMsg.c_str(), line, (fEndTime - mfStartTime));
-    }
-
-private:
-    double getTime() const
-    {
-        timeval tv;
-        gettimeofday(&tv, NULL);
-        return tv.tv_sec + tv.tv_usec / 1000000.0;
-    }
-
-    ::std::string msMsg;
-    double mfStartTime;
-};
-
-}
-
 using namespace ::com::sun::star;
 
 bool ScDBDocFunc::AddDBRange( const OUString& rName, const ScRange& rRange, bool /* bApi */ )
@@ -468,17 +426,12 @@ bool ScDBDocFunc::RepeatDB( const OUString& rDBName, bool bRecord, bool bApi, bo
 bool ScDBDocFunc::Sort( SCTAB nTab, const ScSortParam& rSortParam,
                             bool bRecord, bool bPaint, bool bApi )
 {
-    stack_printer __stack_printer__("ScDBDocFunc::Sort");
     ScDocShellModificator aModificator( rDocShell );
 
     ScDocument& rDoc = rDocShell.GetDocument();
     if (bRecord && !rDoc.IsUndoEnabled())
         bRecord = false;
 
-#if 0
-    ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer();
-#endif
-
     ScDBData* pDBData = rDoc.GetDBAtArea( nTab, rSortParam.nCol1, rSortParam.nRow1,
                                                     rSortParam.nCol2, rSortParam.nRow2 );
     if (!pDBData)
@@ -552,46 +505,6 @@ bool ScDBDocFunc::Sort( SCTAB nTab, const ScSortParam& rSortParam,
     if ( aQueryParam.GetEntry(0).bDoQuery )
         bRepeatQuery = true;
 
-#if 0
-    ScUndoSort* pUndoAction = 0;
-    if ( bRecord )
-    {
-        //  Referenzen ausserhalb des Bereichs werden nicht veraendert !
-
-        ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
-        //  Zeilenhoehen immer (wegen automatischer Anpassung)
-        //! auf ScBlockUndo umstellen
-        pUndoDoc->InitUndo( &rDoc, nTab, nTab, false, true );
-
-        /*  #i59745# Do not copy note captions to undo document. All existing
-            caption objects will be repositioned while sorting which is tracked
-            in drawing undo. When undo is executed, the old positions will be
-            restored, and the cells with the old notes (which still refer to the
-            existing captions) will be copied back into the source document. */
-        rDoc.CopyToDocument( aLocalParam.nCol1, aLocalParam.nRow1, nTab,
-                                aLocalParam.nCol2, aLocalParam.nRow2, nTab,
-                                IDF_ALL|IDF_NOCAPTIONS, false, pUndoDoc );
-
-        //  Zeilenhoehen immer (wegen automatischer Anpassung)
-        //! auf ScBlockUndo umstellen
-//        if (bRepeatQuery)
-            rDoc.CopyToDocument( 0, aLocalParam.nRow1, nTab, MAXCOL, aLocalParam.nRow2, nTab,
-                                    IDF_NONE, false, pUndoDoc );
-
-        ScDBCollection* pUndoDB = NULL;
-        ScDBCollection* pDocDB = rDoc.GetDBCollection();
-        if (!pDocDB->empty())
-            pUndoDB = new ScDBCollection( *pDocDB );
-
-        pUndoAction = new ScUndoSort(&rDocShell, nTab, rSortParam, pUndoDoc, pUndoDB);
-        rDocShell.GetUndoManager()->AddUndoAction( pUndoAction );
-
-        // #i59745# collect all drawing undo actions affecting cell note captions
-        if( pDrawLayer )
-            pDrawLayer->BeginCalcUndo(false);
-    }
-#endif
-
     sc::ReorderParam aUndoParam;
 
     // don't call ScDocument::Sort with an empty SortParam (may be empty here if bCopy is set)
@@ -634,12 +547,6 @@ bool ScDBDocFunc::Sort( SCTAB nTab, const ScSortParam& rSortParam,
     if (!bUniformRowHeight)
         rDocShell.AdjustRowHeight(nStartRow, aLocalParam.nRow2, nTab);
 
-#if 0
-    // #i59745# set collected drawing undo actions at sorting undo action
-    if( pUndoAction && pDrawLayer )
-        pUndoAction->SetDrawUndoAction( pDrawLayer->GetCalcUndo() );
-#endif
-
     aModificator.SetDocumentModified();
 
     return true;
commit 7aba1d6b4156dfcddff30cf548b2cf5407ca5ac2
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Sat Jul 12 17:52:12 2014 -0400

    Implement the redo.
    
    Change-Id: I2476f7415a5b91eef49a5da1ed3244d25679b60b

diff --git a/sc/inc/undosort.hxx b/sc/inc/undosort.hxx
index fb8fbeb..388fcfa 100644
--- a/sc/inc/undosort.hxx
+++ b/sc/inc/undosort.hxx
@@ -25,6 +25,9 @@ public:
     virtual OUString GetComment() const;
     virtual void Undo();
     virtual void Redo();
+
+private:
+    void Execute( bool bUndo );
 };
 
 }
diff --git a/sc/source/ui/undo/undosort.cxx b/sc/source/ui/undo/undosort.cxx
index d6ee8a4..d138491 100644
--- a/sc/source/ui/undo/undosort.cxx
+++ b/sc/source/ui/undo/undosort.cxx
@@ -25,22 +25,29 @@ OUString UndoSort::GetComment() const
 void UndoSort::Undo()
 {
     BeginUndo();
+    Execute(true);
+    EndUndo();
+}
 
+void UndoSort::Redo()
+{
+    BeginRedo();
+    Execute(false);
+    EndRedo();
+}
+
+void UndoSort::Execute( bool bUndo )
+{
     ScDocument& rDoc = pDocShell->GetDocument();
     sc::ReorderParam aParam = maParam;
-    aParam.reverse();
+    if (bUndo)
+        aParam.reverse();
     rDoc.Reorder(aParam, NULL);
 
     ScUndoUtil::MarkSimpleBlock(pDocShell, maParam.maSortRange);
 
     pDocShell->PostPaint(maParam.maSortRange, PAINT_GRID);
     pDocShell->PostDataChanged();
-
-    EndUndo();
-}
-
-void UndoSort::Redo()
-{
 }
 
 }
commit f247c55c3958ba8c8fd57c2fd4286bcc3f8e1111
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Sat Jul 12 17:30:55 2014 -0400

    More tweaking.
    
    Change-Id: Icc7d7ad5f6f418766b8688eef6b180ecfa9b57b3

diff --git a/sc/inc/sortparam.hxx b/sc/inc/sortparam.hxx
index 094ca90..7bf0664 100644
--- a/sc/inc/sortparam.hxx
+++ b/sc/inc/sortparam.hxx
@@ -88,17 +88,20 @@ struct SC_DLLPUBLIC ReorderParam
      * excludes that row / column.
      */
     ScRange maSortRange;
-    std::vector<SCCOLROW> maOldIndices;
+
+    /**
+     * List of original column / row positions after reordering.
+     */
+    std::vector<SCCOLROW> maPosIndices;
     bool mbByRow;
     bool mbPattern;
     bool mbHiddenFiltered;
 
     /**
-     * The input array of indices represent the positions after the
-     * reordering.  Calling this method reorders the array which can then be
-     * used to undo the original reordering.
+     * Reorder the position indices such that it can be used to undo the
+     * original reordering.
      */
-    static void reverse( std::vector<SCCOLROW>& rIndices, SCCOLROW nStart );
+    void reverse();
 };
 
 }
diff --git a/sc/source/core/data/sortparam.cxx b/sc/source/core/data/sortparam.cxx
index 1d5fa5f..ad7653f 100644
--- a/sc/source/core/data/sortparam.cxx
+++ b/sc/source/core/data/sortparam.cxx
@@ -257,24 +257,31 @@ struct ReorderIndex
 
 }
 
-void ReorderParam::reverse( std::vector<SCCOLROW>& rIndices, SCCOLROW nStart )
+void ReorderParam::reverse()
 {
+    SCCOLROW nStart;
+    if (mbByRow)
+        nStart = maSortRange.aStart.Row();
+    else
+        nStart = maSortRange.aStart.Col();
+
+    size_t n = maPosIndices.size();
     std::vector<ReorderIndex> aBucket;
-    aBucket.reserve(rIndices.size());
-    for (size_t i = 0, n = rIndices.size(); i < n; ++i)
+    aBucket.reserve(n);
+    for (size_t i = 0; i < n; ++i)
     {
         SCCOLROW nPos1 = i + nStart;
-        SCCOLROW nPos2 = rIndices[i];
+        SCCOLROW nPos2 = maPosIndices[i];
         aBucket.push_back(ReorderIndex(nPos1, nPos2));
     }
 
     std::sort(aBucket.begin(), aBucket.end(), ReorderIndex::LessByPos2());
     std::vector<SCCOLROW> aNew;
-    aNew.reserve(rIndices.size());
-    for (size_t i = 0, n = aBucket.size(); i < n; ++i)
+    aNew.reserve(n);
+    for (size_t i = 0; i < n; ++i)
         aNew.push_back(aBucket[i].mnPos1);
 
-    rIndices.swap(aNew);
+    maPosIndices.swap(aNew);
 }
 
 }
diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
index 5d67510..e15f1b9 100644
--- a/sc/source/core/data/table3.cxx
+++ b/sc/source/core/data/table3.cxx
@@ -1228,7 +1228,7 @@ void ScTable::Sort(
             if (pUndo)
             {
                 pUndo->maSortRange = ScRange(rSortParam.nCol1, nRow1, nTab, rSortParam.nCol2, nLastRow, nTab);
-                pUndo->maOldIndices = pArray->GetOldIndices();
+                pUndo->maPosIndices = pArray->GetOldIndices();
             }
 
             // #i59745# update position of caption objects of cell notes --> reported at (SortReorder) ScColumn::SwapCellNotes level
@@ -1256,7 +1256,7 @@ void ScTable::Sort(
             if (pUndo)
             {
                 pUndo->maSortRange = ScRange(nCol1, aSortParam.nRow1, nTab, nLastCol, aSortParam.nRow2, nTab);
-                pUndo->maOldIndices = pArray->GetOldIndices();
+                pUndo->maPosIndices = pArray->GetOldIndices();
             }
 
             // #i59745# update position of caption objects of cell notes --> reported at (SortReorder) ScColumn::SwapCellNotes level
@@ -1267,7 +1267,7 @@ void ScTable::Sort(
 
 void ScTable::Reorder( const sc::ReorderParam& rParam, ScProgress* pProgress )
 {
-    if (rParam.maOldIndices.empty())
+    if (rParam.maPosIndices.empty())
         return;
 
     if (rParam.mbByRow)
@@ -1276,8 +1276,7 @@ void ScTable::Reorder( const sc::ReorderParam& rParam, ScProgress* pProgress )
         boost::scoped_ptr<ScSortInfoArray> pArray(CreateSortInfoArray(rParam));
 
         // Re-play sorting from the known sort indices.
-        sc::ReorderParam::reverse(aParam.maOldIndices, aParam.maSortRange.aStart.Row());
-        pArray->ReorderDataRows(aParam.maOldIndices);
+        pArray->ReorderDataRows(aParam.maPosIndices);
 
         SortReorderByRow(
             pArray.get(), aParam.maSortRange.aStart.Col(), aParam.maSortRange.aEnd.Col(), pProgress);
diff --git a/sc/source/ui/undo/undosort.cxx b/sc/source/ui/undo/undosort.cxx
index 6220014..d6ee8a4 100644
--- a/sc/source/ui/undo/undosort.cxx
+++ b/sc/source/ui/undo/undosort.cxx
@@ -27,7 +27,9 @@ void UndoSort::Undo()
     BeginUndo();
 
     ScDocument& rDoc = pDocShell->GetDocument();
-    rDoc.Reorder(maParam, NULL);
+    sc::ReorderParam aParam = maParam;
+    aParam.reverse();
+    rDoc.Reorder(aParam, NULL);
 
     ScUndoUtil::MarkSimpleBlock(pDocShell, maParam.maSortRange);
 
commit 862fb6ad0ec890a40a5fa061d9d5d87a25b03625
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Sat Jul 12 16:48:21 2014 -0400

    First cut on undo of sort by row.
    
    Change-Id: I2637c9e353796005a94a8ea77283264556edf3d8

diff --git a/sc/inc/sortparam.hxx b/sc/inc/sortparam.hxx
index 83a1c34..094ca90 100644
--- a/sc/inc/sortparam.hxx
+++ b/sc/inc/sortparam.hxx
@@ -82,10 +82,23 @@ namespace sc {
 
 struct SC_DLLPUBLIC ReorderParam
 {
+    /**
+     * This sort range already takes into account the presence or absence of
+     * header row / column i.e. if a header row / column is present, it
+     * excludes that row / column.
+     */
     ScRange maSortRange;
     std::vector<SCCOLROW> maOldIndices;
     bool mbByRow;
-    bool mbIncludePattern;
+    bool mbPattern;
+    bool mbHiddenFiltered;
+
+    /**
+     * The input array of indices represent the positions after the
+     * reordering.  Calling this method reorders the array which can then be
+     * used to undo the original reordering.
+     */
+    static void reverse( std::vector<SCCOLROW>& rIndices, SCCOLROW nStart );
 };
 
 }
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index d84340f..452e171 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -1021,10 +1021,11 @@ private:
         ScRefCellValue& rCell2, SCCOL nCell2Col, SCROW nCell2Row ) const;
     short       Compare(SCCOLROW nIndex1, SCCOLROW nIndex2) const;
     short       Compare( ScSortInfoArray*, SCCOLROW nIndex1, SCCOLROW nIndex2) const;
+    ScSortInfoArray* CreateSortInfoArray( const sc::ReorderParam& rParam );
     ScSortInfoArray* CreateSortInfoArray( const ScSortParam& rSortParam, SCCOLROW nInd1, SCCOLROW nInd2, bool bKeepQuery );
     void        QuickSort( ScSortInfoArray*, SCsCOLROW nLo, SCsCOLROW nHi);
     void SortReorderByColumn( ScSortInfoArray* pArray, ScProgress* pProgress );
-    void SortReorderByRow( ScSortInfoArray* pArray, ScProgress* pProgress );
+    void SortReorderByRow( ScSortInfoArray* pArray, SCCOL nCol1, SCCOL nCol2, ScProgress* pProgress );
 
     bool        CreateExcelQuery(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, ScQueryParam& rQueryParam);
     bool        CreateStarQuery(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, ScQueryParam& rQueryParam);
diff --git a/sc/source/core/data/sortparam.cxx b/sc/source/core/data/sortparam.cxx
index 56448cf..1d5fa5f 100644
--- a/sc/source/core/data/sortparam.cxx
+++ b/sc/source/core/data/sortparam.cxx
@@ -235,4 +235,48 @@ void ScSortParam::MoveToDest()
     }
 }
 
+namespace sc {
+
+namespace {
+
+struct ReorderIndex
+{
+    struct LessByPos2 : std::binary_function<ReorderIndex, ReorderIndex, bool>
+    {
+        bool operator() ( const ReorderIndex& r1, const ReorderIndex& r2 ) const
+        {
+            return r1.mnPos2 < r2.mnPos2;
+        }
+    };
+
+    SCCOLROW mnPos1;
+    SCCOLROW mnPos2;
+
+    ReorderIndex( SCCOLROW nPos1, SCCOLROW nPos2 ) : mnPos1(nPos1), mnPos2(nPos2) {}
+};
+
+}
+
+void ReorderParam::reverse( std::vector<SCCOLROW>& rIndices, SCCOLROW nStart )
+{
+    std::vector<ReorderIndex> aBucket;
+    aBucket.reserve(rIndices.size());
+    for (size_t i = 0, n = rIndices.size(); i < n; ++i)
+    {
+        SCCOLROW nPos1 = i + nStart;
+        SCCOLROW nPos2 = rIndices[i];
+        aBucket.push_back(ReorderIndex(nPos1, nPos2));
+    }
+
+    std::sort(aBucket.begin(), aBucket.end(), ReorderIndex::LessByPos2());
+    std::vector<SCCOLROW> aNew;
+    aNew.reserve(rIndices.size());
+    for (size_t i = 0, n = aBucket.size(); i < n; ++i)
+        aNew.push_back(aBucket[i].mnPos1);
+
+    rIndices.swap(aNew);
+}
+
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
index db2df14..5d67510 100644
--- a/sc/source/core/data/table3.cxx
+++ b/sc/source/core/data/table3.cxx
@@ -262,18 +262,22 @@ private:
 
 public:
     ScSortInfoArray( sal_uInt16 nSorts, SCCOLROW nInd1, SCCOLROW nInd2 ) :
-        pppInfo( new ScSortInfo**[nSorts]),
+        pppInfo(NULL),
         nCount( nInd2 - nInd1 + 1 ), nStart( nInd1 ),
         mnLastIndex(nInd2),
         nUsedSorts(nSorts),
         mbKeepQuery(false)
     {
-        for ( sal_uInt16 nSort = 0; nSort < nUsedSorts; nSort++ )
+        if (nUsedSorts)
         {
-            ScSortInfo** ppInfo = new ScSortInfo* [nCount];
-            for ( SCSIZE j = 0; j < nCount; j++ )
-                ppInfo[j] = new ScSortInfo;
-            pppInfo[nSort] = ppInfo;
+            pppInfo = new ScSortInfo**[nUsedSorts];
+            for ( sal_uInt16 nSort = 0; nSort < nUsedSorts; nSort++ )
+            {
+                ScSortInfo** ppInfo = new ScSortInfo* [nCount];
+                for ( SCSIZE j = 0; j < nCount; j++ )
+                    ppInfo[j] = new ScSortInfo;
+                pppInfo[nSort] = ppInfo;
+            }
         }
 
         for (size_t i = 0; i < nCount; ++i)
@@ -282,14 +286,17 @@ public:
 
     ~ScSortInfoArray()
     {
-        for ( sal_uInt16 nSort = 0; nSort < nUsedSorts; nSort++ )
+        if (pppInfo)
         {
-            ScSortInfo** ppInfo = pppInfo[nSort];
-            for ( SCSIZE j = 0; j < nCount; j++ )
-                delete ppInfo[j];
-            delete [] ppInfo;
+            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;
         }
-        delete[] pppInfo;
 
         if (mpRows)
             std::for_each(mpRows->begin(), mpRows->end(), boost::checked_deleter<Row>());
@@ -299,11 +306,30 @@ public:
 
     bool IsKeepQuery() const { return mbKeepQuery; }
 
+    /**
+     * Call this only during normal sorting, not from reordering.
+     */
+    ScSortInfo** GetFirstArray() const
+    {
+        OSL_ASSERT(pppInfo);
+        return pppInfo[0];
+    }
+
+    /**
+     * Call this only during normal sorting, not from reordering.
+     */
     ScSortInfo* Get( sal_uInt16 nSort, SCCOLROW nInd )
-                    { return (pppInfo[nSort])[ nInd - nStart ]; }
+    {
+        OSL_ASSERT(pppInfo);
+        return (pppInfo[nSort])[ nInd - nStart ];
+    }
 
+    /**
+     * Call this only during normal sorting, not from reordering.
+     */
     void Swap( SCCOLROW nInd1, SCCOLROW nInd2 )
     {
+        OSL_ASSERT(pppInfo);
         SCSIZE n1 = static_cast<SCSIZE>(nInd1 - nStart);
         SCSIZE n2 = static_cast<SCSIZE>(nInd2 - nStart);
         for ( sal_uInt16 nSort = 0; nSort < nUsedSorts; nSort++ )
@@ -324,8 +350,37 @@ public:
         }
     }
 
+    /**
+     * @param rIndices indices are actual row positions on the sheet, not an
+     *                 offset from the top row.
+     */
+    void ReorderDataRows( const std::vector<SCCOLROW>& rIndices )
+    {
+        if (!mpRows)
+            return;
+
+        RowsType& rRows = *mpRows;
+
+        std::vector<SCCOLROW> aOldIndices2;
+        aOldIndices2.reserve(rIndices.size());
+
+        RowsType aRows2;
+        aRows2.reserve(rRows.size());
+
+        std::vector<SCCOLROW>::const_iterator it = rIndices.begin(), itEnd = rIndices.end();
+        for (; it != itEnd; ++it)
+        {
+            size_t nPos = *it - nStart; // switch to an offset to top row.
+            aRows2.push_back(rRows[nPos]);
+            aOldIndices2.push_back(maOldIndices[nPos]);
+        }
+
+        rRows.swap(aRows2);
+        maOldIndices.swap(aOldIndices2);
+    }
+
     sal_uInt16      GetUsedSorts() const { return nUsedSorts; }
-    ScSortInfo**    GetFirstArray() const { return pppInfo[0]; }
+
     SCCOLROW    GetStart() const { return nStart; }
     SCCOLROW GetLast() const { return mnLastIndex; }
     SCSIZE      GetCount() const { return nCount; }
@@ -348,6 +403,78 @@ public:
     }
 };
 
+namespace {
+
+void initDataRows(
+    ScSortInfoArray& rArray, ScTable& rTab, ScColumn* pCols,
+    SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
+    bool bPattern, bool bHiddenFiltered )
+{
+    // Fill row-wise data table.
+    ScSortInfoArray::RowsType& rRows = rArray.InitDataRows(nRow2-nRow1+1, nCol2-nCol1+1);
+
+    for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
+    {
+        ScColumn& rCol = pCols[nCol];
+
+        // Skip reordering of cell formats if the whole span is on the same pattern entry.
+        bool bUniformPattern = rCol.GetPatternCount(nRow1, nRow2) < 2u;
+
+        sc::ColumnBlockConstPosition aBlockPos;
+        rCol.InitBlockPosition(aBlockPos);
+        for (SCROW nRow = nRow1; nRow <= nRow2; ++nRow)
+        {
+            ScSortInfoArray::Row& rRow = *rRows[nRow-nRow1];
+            ScSortInfoArray::Cell& rCell = rRow.maCells[nCol-nCol1];
+
+            rCell.maCell = rCol.GetCellValue(aBlockPos, nRow);
+            rCell.mpAttr = rCol.GetCellTextAttr(aBlockPos, nRow);
+            rCell.mpBroadcaster = rCol.GetBroadcaster(aBlockPos, nRow);
+            rCell.mpNote = rCol.GetCellNote(aBlockPos, nRow);
+
+            if (!bUniformPattern && bPattern)
+                rCell.mpPattern = rCol.GetPattern(nRow);
+        }
+    }
+
+    if (bHiddenFiltered)
+    {
+        for (SCROW nRow = nRow1; nRow <= nRow2; ++nRow)
+        {
+            ScSortInfoArray::Row& rRow = *rRows[nRow-nRow1];
+            rRow.mbHidden = rTab.RowHidden(nRow);
+            rRow.mbFiltered = rTab.RowFiltered(nRow);
+        }
+    }
+}
+
+}
+
+ScSortInfoArray* ScTable::CreateSortInfoArray( const sc::ReorderParam& rParam )
+{
+    ScSortInfoArray* pArray = NULL;
+
+    if (rParam.mbByRow)
+    {
+        // Create a sort info array with just the data table.
+        SCROW nRow1 = rParam.maSortRange.aStart.Row();
+        SCROW nRow2 = rParam.maSortRange.aEnd.Row();
+        SCCOL nCol1 = rParam.maSortRange.aStart.Col();
+        SCCOL nCol2 = rParam.maSortRange.aEnd.Col();
+
+        pArray = new ScSortInfoArray(0, nRow1, nRow2);
+
+        initDataRows(
+            *pArray, *this, aCol, nCol1, nRow1, nCol2, nRow2,
+            rParam.mbPattern, rParam.mbHiddenFiltered);
+    }
+    else
+    {
+    }
+
+    return pArray;
+}
+
 ScSortInfoArray* ScTable::CreateSortInfoArray(
     const ScSortParam& rSortParam, SCCOLROW nInd1, SCCOLROW nInd2, bool bKeepQuery )
 {
@@ -373,43 +500,9 @@ ScSortInfoArray* ScTable::CreateSortInfoArray(
             }
         }
 
-        // Fill row-wise data table.
-        ScSortInfoArray::RowsType& rRows = pArray->InitDataRows(
-            nInd2 - nInd1 + 1, rSortParam.nCol2 - rSortParam.nCol1 + 1);
-
-        for (SCCOL nCol = rSortParam.nCol1; nCol <= rSortParam.nCol2; ++nCol)
-        {
-            ScColumn& rCol = aCol[nCol];
-
-            // Skip reordering of cell formats if the whole span is on the same pattern entry.
-            bool bUniformPattern = rCol.GetPatternCount(nInd1, nInd2) < 2u;
-
-            sc::ColumnBlockConstPosition aBlockPos;
-            rCol.InitBlockPosition(aBlockPos);
-            for (SCROW nRow = nInd1; nRow <= nInd2; ++nRow)
-            {
-                ScSortInfoArray::Row& rRow = *rRows[nRow-nInd1];
-                ScSortInfoArray::Cell& rCell = rRow.maCells[nCol-rSortParam.nCol1];
-
-                rCell.maCell = rCol.GetCellValue(aBlockPos, nRow);
-                rCell.mpAttr = rCol.GetCellTextAttr(aBlockPos, nRow);
-                rCell.mpBroadcaster = rCol.GetBroadcaster(aBlockPos, nRow);
-                rCell.mpNote = rCol.GetCellNote(aBlockPos, nRow);
-
-                if (!bUniformPattern && rSortParam.bIncludePattern)
-                    rCell.mpPattern = rCol.GetPattern(nRow);
-            }
-        }
-
-        if (bKeepQuery)
-        {
-            for (SCROW nRow = nInd1; nRow <= nInd2; ++nRow)
-            {
-                ScSortInfoArray::Row& rRow = *rRows[nRow-nInd1];
-                rRow.mbHidden = RowHidden(nRow);
-                rRow.mbFiltered = RowFiltered(nRow);
-            }
-        }
+        initDataRows(
+            *pArray, *this, aCol, rSortParam.nCol1, nInd1, rSortParam.nCol2, nInd2,
+            rSortParam.bIncludePattern, bKeepQuery);
     }
     else
     {
@@ -638,8 +731,12 @@ void ScTable::SortReorderByColumn( ScSortInfoArray* pArray, ScProgress* pProgres
     }
 }
 
-void ScTable::SortReorderByRow( ScSortInfoArray* pArray, ScProgress* pProgress )
+void ScTable::SortReorderByRow(
+    ScSortInfoArray* pArray, SCCOL nCol1, SCCOL nCol2, ScProgress* pProgress )
 {
+    if (nCol2 < nCol1)
+        return;
+
     SCROW nRow1 = pArray->GetStart();
     SCROW nRow2 = pArray->GetLast();
     ScSortInfoArray::RowsType* pRows = pArray->GetDataRows();
@@ -648,7 +745,7 @@ void ScTable::SortReorderByRow( ScSortInfoArray* pArray, ScProgress* pProgress )
     // 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;
+    size_t nColCount = nCol2 - nCol1 + 1;
     boost::ptr_vector<SortedColumn> aSortedCols; // storage for copied cells.
     SortedRowFlags aRowFlags;
     aSortedCols.reserve(nColCount);
@@ -665,7 +762,7 @@ void ScTable::SortReorderByRow( ScSortInfoArray* pArray, ScProgress* pProgress )
         ScSortInfoArray::Row* pRow = (*pRows)[i];
         for (size_t j = 0; j < pRow->maCells.size(); ++j)
         {
-            ScAddress aCellPos(aSortParam.nCol1 + j, nRow1 + i, nTab);
+            ScAddress aCellPos(nCol1 + j, nRow1 + i, nTab);
 
             ScSortInfoArray::Cell& rCell = pRow->maCells[j];
 
@@ -743,7 +840,7 @@ void ScTable::SortReorderByRow( ScSortInfoArray* pArray, ScProgress* pProgress )
 
     for (size_t i = 0, n = aSortedCols.size(); i < n; ++i)
     {
-        SCCOL nThisCol = i + aSortParam.nCol1;
+        SCCOL nThisCol = i + nCol1;
 
         {
             sc::CellStoreType& rDest = aCol[nThisCol].maCells;
@@ -830,7 +927,7 @@ void ScTable::SortReorderByRow( ScSortInfoArray* pArray, ScProgress* pProgress )
 
     // Collect all listeners within sorted range ahead of time.
     std::vector<SvtListener*> aListeners;
-    for (SCCOL nCol = aSortParam.nCol1; nCol <= aSortParam.nCol2; ++nCol)
+    for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
         aCol[nCol].CollectListeners(aListeners, nRow1, nRow2);
 
     // Remove any duplicate listener entries.  We must ensure that we notify
@@ -841,7 +938,7 @@ void ScTable::SortReorderByRow( ScSortInfoArray* pArray, ScProgress* pProgress )
     // Collect positions of all shared formula cells outside the sorted range,
     // and make them unshared before notifying them.
     sc::RefQueryFormulaGroup aFormulaGroupPos;
-    aFormulaGroupPos.setSkipRange(ScRange(aSortParam.nCol1, nRow1, nTab, aSortParam.nCol2, nRow2, nTab));
+    aFormulaGroupPos.setSkipRange(ScRange(nCol1, nRow1, nTab, nCol2, nRow2, nTab));
 
     std::for_each(aListeners.begin(), aListeners.end(), FormulaGroupPosCollector(aFormulaGroupPos));
     const sc::RefQueryFormulaGroup::TabsType& rGroupTabs = aFormulaGroupPos.getAllPositions();
@@ -859,7 +956,7 @@ void ScTable::SortReorderByRow( ScSortInfoArray* pArray, ScProgress* pProgress )
     }
 
     // Notify the listeners.
-    RowReorderNotifier aFunc(aRowMap, nTab, aSortParam.nCol1, aSortParam.nCol2);
+    RowReorderNotifier aFunc(aRowMap, nTab, nCol1, nCol2);
     std::for_each(aListeners.begin(), aListeners.end(), aFunc);
 
     // Re-group formulas in affected columns.
@@ -872,7 +969,7 @@ void ScTable::SortReorderByRow( ScSortInfoArray* pArray, ScProgress* pProgress )
     }
 
     // Re-group columns in the sorted range too.
-    for (SCCOL i = aSortParam.nCol1; i <= aSortParam.nCol2; ++i)
+    for (SCCOL i = nCol1; i <= nCol2; ++i)
         aCol[i].RegroupFormulaCells();
 }
 
@@ -1103,7 +1200,8 @@ void ScTable::Sort(
     {
         // Copy over the basic sort parameters.
         pUndo->mbByRow = rSortParam.bByRow;
-        pUndo->mbIncludePattern = rSortParam.bIncludePattern;
+        pUndo->mbPattern = rSortParam.bIncludePattern;
+        pUndo->mbHiddenFiltered = bKeepQuery;
     }
 
     if (rSortParam.bByRow)
@@ -1125,7 +1223,7 @@ void ScTable::Sort(
                 DecoladeRow(pArray.get(), nRow1, nLastRow);
 
             QuickSort(pArray.get(), nRow1, nLastRow);
-            SortReorderByRow(pArray.get(), pProgress);
+            SortReorderByRow(pArray.get(), aSortParam.nCol1, aSortParam.nCol2, pProgress);
 
             if (pUndo)
             {
@@ -1171,6 +1269,23 @@ void ScTable::Reorder( const sc::ReorderParam& rParam, ScProgress* pProgress )
 {
     if (rParam.maOldIndices.empty())
         return;
+
+    if (rParam.mbByRow)
+    {
+        sc::ReorderParam aParam = rParam; // copy
+        boost::scoped_ptr<ScSortInfoArray> pArray(CreateSortInfoArray(rParam));
+
+        // Re-play sorting from the known sort indices.
+        sc::ReorderParam::reverse(aParam.maOldIndices, aParam.maSortRange.aStart.Row());
+        pArray->ReorderDataRows(aParam.maOldIndices);
+
+        SortReorderByRow(
+            pArray.get(), aParam.maSortRange.aStart.Col(), aParam.maSortRange.aEnd.Col(), pProgress);
+    }
+    else
+    {
+        // TODO : Implement this.
+    }
 }
 
 namespace {
diff --git a/sc/source/ui/undo/undosort.cxx b/sc/source/ui/undo/undosort.cxx
index 1258882..6220014 100644
--- a/sc/source/ui/undo/undosort.cxx
+++ b/sc/source/ui/undo/undosort.cxx
@@ -10,6 +10,7 @@
 #include <undosort.hxx>
 #include <globstr.hrc>
 #include <global.hxx>
+#include <undoutil.hxx>
 
 namespace sc {
 
@@ -23,8 +24,17 @@ OUString UndoSort::GetComment() const
 
 void UndoSort::Undo()
 {
+    BeginUndo();
+
     ScDocument& rDoc = pDocShell->GetDocument();
     rDoc.Reorder(maParam, NULL);
+
+    ScUndoUtil::MarkSimpleBlock(pDocShell, maParam.maSortRange);
+
+    pDocShell->PostPaint(maParam.maSortRange, PAINT_GRID);
+    pDocShell->PostDataChanged();
+
+    EndUndo();
 }
 
 void UndoSort::Redo()


More information about the Libreoffice-commits mailing list