[Libreoffice-commits] core.git: Branch 'private/kohei/sort-ref-update' - 74 commits - android/Bootstrap chart2/source comphelper/source connectivity/source desktop/source external/collada2gltf external/libgltf include/LibreOfficeKit include/sal include/sfx2 include/svl include/vcl libreofficekit/CppunitTest_libreofficekit_tiledrendering.mk libreofficekit/Executable_gtktiledviewer.mk libreofficekit/Module_libreofficekit.mk libreofficekit/qa libreofficekit/source sal/osl sc/inc sc/Library_sc.mk sc/qa sc/source sd/source sfx2/source sot/source svl/source svtools/source sw/inc sw/qa sw/source vcl/source writerfilter/CustomTarget_source.mk writerfilter/source

Kohei Yoshida kohei.yoshida at collabora.com
Sun Jul 13 13:28:35 PDT 2014


Rebased ref, commits from common ancestor:
commit dcba99a508f53864c5c4e03a73dea80ba73e32bb
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Sun Jul 13 16:12:39 2014 -0400

    Implement reorder by column.  Now undo of column sorting is working too.
    
    Change-Id: I2b98610f6b774400ecfaffe2905201c27fcab33f

diff --git a/sc/inc/sortparam.hxx b/sc/inc/sortparam.hxx
index 7bf0664..ab26d10 100644
--- a/sc/inc/sortparam.hxx
+++ b/sc/inc/sortparam.hxx
@@ -92,7 +92,7 @@ struct SC_DLLPUBLIC ReorderParam
     /**
      * List of original column / row positions after reordering.
      */
-    std::vector<SCCOLROW> maPosIndices;
+    std::vector<SCCOLROW> maOrderIndices;
     bool mbByRow;
     bool mbPattern;
     bool mbHiddenFiltered;
diff --git a/sc/source/core/data/sortparam.cxx b/sc/source/core/data/sortparam.cxx
index ad7653f..1e265b3 100644
--- a/sc/source/core/data/sortparam.cxx
+++ b/sc/source/core/data/sortparam.cxx
@@ -265,13 +265,13 @@ void ReorderParam::reverse()
     else
         nStart = maSortRange.aStart.Col();
 
-    size_t n = maPosIndices.size();
+    size_t n = maOrderIndices.size();
     std::vector<ReorderIndex> aBucket;
     aBucket.reserve(n);
     for (size_t i = 0; i < n; ++i)
     {
         SCCOLROW nPos1 = i + nStart;
-        SCCOLROW nPos2 = maPosIndices[i];
+        SCCOLROW nPos2 = maOrderIndices[i];
         aBucket.push_back(ReorderIndex(nPos1, nPos2));
     }
 
@@ -281,7 +281,7 @@ void ReorderParam::reverse()
     for (size_t i = 0; i < n; ++i)
         aNew.push_back(aBucket[i].mnPos1);
 
-    maPosIndices.swap(aNew);
+    maOrderIndices.swap(aNew);
 }
 
 }
diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
index 844db24..64f0ef5 100644
--- a/sc/source/core/data/table3.cxx
+++ b/sc/source/core/data/table3.cxx
@@ -350,6 +350,11 @@ public:
         }
     }
 
+    void SetOrderIndices( const std::vector<SCCOLROW>& rIndices )
+    {
+        maOrderIndices = rIndices;
+    }
+
     /**
      * @param rIndices indices are actual row positions on the sheet, not an
      *                 offset from the top row.
@@ -471,6 +476,11 @@ ScSortInfoArray* ScTable::CreateSortInfoArray( const sc::ReorderParam& rParam )
     }
     else
     {
+        SCCOLROW nCol1 = rParam.maSortRange.aStart.Col();
+        SCCOLROW nCol2 = rParam.maSortRange.aEnd.Col();
+
+        pArray = new ScSortInfoArray(0, nCol1, nCol2);
+        pArray->SetKeepQuery(rParam.mbHiddenFiltered);
     }
 
     return pArray;
@@ -1228,7 +1238,7 @@ void ScTable::Sort(
             if (pUndo)
             {
                 pUndo->maSortRange = ScRange(rSortParam.nCol1, nRow1, nTab, rSortParam.nCol2, nLastRow, nTab);
-                pUndo->maPosIndices = pArray->GetOrderIndices();
+                pUndo->maOrderIndices = pArray->GetOrderIndices();
             }
         }
     }
@@ -1254,7 +1264,7 @@ void ScTable::Sort(
             if (pUndo)
             {
                 pUndo->maSortRange = ScRange(nCol1, aSortParam.nRow1, nTab, nLastCol, aSortParam.nRow2, nTab);
-                pUndo->maPosIndices = pArray->GetOrderIndices();
+                pUndo->maOrderIndices = pArray->GetOrderIndices();
             }
         }
     }
@@ -1263,7 +1273,7 @@ void ScTable::Sort(
 
 void ScTable::Reorder( const sc::ReorderParam& rParam, ScProgress* pProgress )
 {
-    if (rParam.maPosIndices.empty())
+    if (rParam.maOrderIndices.empty())
         return;
 
     boost::scoped_ptr<ScSortInfoArray> pArray(CreateSortInfoArray(rParam));
@@ -1273,14 +1283,18 @@ void ScTable::Reorder( const sc::ReorderParam& rParam, ScProgress* pProgress )
     if (rParam.mbByRow)
     {
         // Re-play sorting from the known sort indices.
-        pArray->ReorderByRow(rParam.maPosIndices);
+        pArray->ReorderByRow(rParam.maOrderIndices);
 
         SortReorderByRow(
             pArray.get(), rParam.maSortRange.aStart.Col(), rParam.maSortRange.aEnd.Col(), pProgress);
     }
     else
     {
-
+        // Ordering by column is much simpler.  Just set the order indices and we are done.
+        pArray->SetOrderIndices(rParam.maOrderIndices);
+        SortReorderByColumn(
+            pArray.get(), rParam.maSortRange.aStart.Row(), rParam.maSortRange.aEnd.Row(),
+            rParam.mbPattern, pProgress);
     }
 }
 
commit a359237e1668f835d0d420ec675aafdad54275de
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Sun Jul 13 16:01:58 2014 -0400

    Some renaming.  The name "old indices" is not very representative.
    
    Change-Id: Idbb462e3b366d6fcc3fbbade6ee1310b9941423d

diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
index 4e9dd6d..844db24 100644
--- a/sc/source/core/data/table3.cxx
+++ b/sc/source/core/data/table3.cxx
@@ -257,7 +257,7 @@ private:
     SCCOLROW        mnLastIndex; /// index of last non-empty cell position.
     sal_uInt16      nUsedSorts;
 
-    std::vector<SCCOLROW> maOldIndices;
+    std::vector<SCCOLROW> maOrderIndices;
     bool mbKeepQuery;
 
 public:
@@ -281,7 +281,7 @@ public:
         }
 
         for (size_t i = 0; i < nCount; ++i)
-            maOldIndices.push_back(i+nStart);
+            maOrderIndices.push_back(i+nStart);
     }
 
     ~ScSortInfoArray()
@@ -340,7 +340,7 @@ public:
             ppInfo[n2] = pTmp;
         }
 
-        std::swap(maOldIndices[n1], maOldIndices[n2]);
+        std::swap(maOrderIndices[n1], maOrderIndices[n2]);
 
         if (mpRows)
         {
@@ -354,15 +354,15 @@ 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 )
+    void ReorderByRow( const std::vector<SCCOLROW>& rIndices )
     {
         if (!mpRows)
             return;
 
         RowsType& rRows = *mpRows;
 
-        std::vector<SCCOLROW> aOldIndices2;
-        aOldIndices2.reserve(rIndices.size());
+        std::vector<SCCOLROW> aOrderIndices2;
+        aOrderIndices2.reserve(rIndices.size());
 
         RowsType aRows2;
         aRows2.reserve(rRows.size());
@@ -372,11 +372,11 @@ public:
         {
             size_t nPos = *it - nStart; // switch to an offset to top row.
             aRows2.push_back(rRows[nPos]);
-            aOldIndices2.push_back(maOldIndices[nPos]);
+            aOrderIndices2.push_back(maOrderIndices[nPos]);
         }
 
         rRows.swap(aRows2);
-        maOldIndices.swap(aOldIndices2);
+        maOrderIndices.swap(aOrderIndices2);
     }
 
     sal_uInt16      GetUsedSorts() const { return nUsedSorts; }
@@ -385,7 +385,7 @@ public:
     SCCOLROW GetLast() const { return mnLastIndex; }
     SCSIZE      GetCount() const { return nCount; }
 
-    const std::vector<SCCOLROW>& GetOldIndices() const { return maOldIndices; }
+    const std::vector<SCCOLROW>& GetOrderIndices() const { return maOrderIndices; }
 
     RowsType& InitDataRows( size_t nRowSize, size_t nColSize )
     {
@@ -661,7 +661,7 @@ void ScTable::SortReorderByColumn(
     SCCOLROW nStart = pArray->GetStart();
     SCCOLROW nLast = pArray->GetLast();
 
-    std::vector<SCCOLROW> aIndices = pArray->GetOldIndices();
+    std::vector<SCCOLROW> aIndices = pArray->GetOrderIndices();
     size_t nCount = aIndices.size();
 
     // Cut formula grouping at row and reference boundaries before the reordering.
@@ -698,7 +698,7 @@ void ScTable::SortReorderByColumn(
 
     // Set up column reorder map (for later broadcasting of reference updates).
     sc::ColRowReorderMapType aColMap;
-    const std::vector<SCCOLROW>& rOldIndices = pArray->GetOldIndices();
+    const std::vector<SCCOLROW>& rOldIndices = pArray->GetOrderIndices();
     for (size_t i = 0, n = rOldIndices.size(); i < n; ++i)
     {
         SCCOL nNew = i + nStart;
@@ -917,7 +917,7 @@ void ScTable::SortReorderByRow(
 
     // Set up row reorder map (for later broadcasting of reference updates).
     sc::ColRowReorderMapType aRowMap;
-    const std::vector<SCCOLROW>& rOldIndices = pArray->GetOldIndices();
+    const std::vector<SCCOLROW>& rOldIndices = pArray->GetOrderIndices();
     for (size_t i = 0, n = rOldIndices.size(); i < n; ++i)
     {
         SCROW nNew = i + nRow1;
@@ -1228,7 +1228,7 @@ void ScTable::Sort(
             if (pUndo)
             {
                 pUndo->maSortRange = ScRange(rSortParam.nCol1, nRow1, nTab, rSortParam.nCol2, nLastRow, nTab);
-                pUndo->maPosIndices = pArray->GetOldIndices();
+                pUndo->maPosIndices = pArray->GetOrderIndices();
             }
         }
     }
@@ -1254,7 +1254,7 @@ void ScTable::Sort(
             if (pUndo)
             {
                 pUndo->maSortRange = ScRange(nCol1, aSortParam.nRow1, nTab, nLastCol, aSortParam.nRow2, nTab);
-                pUndo->maPosIndices = pArray->GetOldIndices();
+                pUndo->maPosIndices = pArray->GetOrderIndices();
             }
         }
     }
@@ -1266,19 +1266,21 @@ void ScTable::Reorder( const sc::ReorderParam& rParam, ScProgress* pProgress )
     if (rParam.maPosIndices.empty())
         return;
 
+    boost::scoped_ptr<ScSortInfoArray> pArray(CreateSortInfoArray(rParam));
+    if (!pArray)
+        return;
+
     if (rParam.mbByRow)
     {
-        boost::scoped_ptr<ScSortInfoArray> pArray(CreateSortInfoArray(rParam));
-
         // Re-play sorting from the known sort indices.
-        pArray->ReorderDataRows(rParam.maPosIndices);
+        pArray->ReorderByRow(rParam.maPosIndices);
 
         SortReorderByRow(
             pArray.get(), rParam.maSortRange.aStart.Col(), rParam.maSortRange.aEnd.Col(), pProgress);
     }
     else
     {
-        // TODO : Implement this.
+
     }
 }
 
commit 8d5df8403c3df8523fad2f79c8e01940be6d72bb
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Sun Jul 13 15:52:02 2014 -0400

    No need to copy it here anymore.
    
    Change-Id: Ie636149e0ed71bbc5c6675c4e1481d62c66ab68e

diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
index 008e883..4e9dd6d 100644
--- a/sc/source/core/data/table3.cxx
+++ b/sc/source/core/data/table3.cxx
@@ -1268,14 +1268,13 @@ void ScTable::Reorder( const sc::ReorderParam& rParam, ScProgress* pProgress )
 
     if (rParam.mbByRow)
     {
-        sc::ReorderParam aParam = rParam; // copy
         boost::scoped_ptr<ScSortInfoArray> pArray(CreateSortInfoArray(rParam));
 
         // Re-play sorting from the known sort indices.
-        pArray->ReorderDataRows(aParam.maPosIndices);
+        pArray->ReorderDataRows(rParam.maPosIndices);
 
         SortReorderByRow(
-            pArray.get(), aParam.maSortRange.aStart.Col(), aParam.maSortRange.aEnd.Col(), pProgress);
+            pArray.get(), rParam.maSortRange.aStart.Col(), rParam.maSortRange.aEnd.Col(), pProgress);
     }
     else
     {
commit a20da109c16468aee4119c5c46765af9bff0b4af
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Sun Jul 13 14:51:56 2014 -0400

    Reorder columns without using ScSortInfo array.
    
    Change-Id: Iee17dc79db1336fdd7921e7ac7e1ee3da066f1de

diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
index 218c4df..008e883 100644
--- a/sc/source/core/data/table3.cxx
+++ b/sc/source/core/data/table3.cxx
@@ -658,40 +658,38 @@ public:
 void ScTable::SortReorderByColumn(
     ScSortInfoArray* pArray, SCROW nRow1, SCROW nRow2, bool bPattern, ScProgress* pProgress )
 {
-    size_t nCount = pArray->GetCount();
     SCCOLROW nStart = pArray->GetStart();
     SCCOLROW nLast = pArray->GetLast();
-    ScSortInfo** ppInfo = pArray->GetFirstArray();
 
-    std::vector<ScSortInfo*> aTable(nCount);
-
-    SCSIZE nPos;
-    for ( nPos = 0; nPos < nCount; nPos++ )
-        aTable[ppInfo[nPos]->nOrg - nStart] = ppInfo[nPos];
+    std::vector<SCCOLROW> aIndices = pArray->GetOldIndices();
+    size_t nCount = aIndices.size();
 
     // Cut formula grouping at row and reference boundaries before the reordering.
     ScRange aSortRange(nStart, nRow1, nTab, nLast, nRow2, nTab);
     for (SCCOL nCol = nStart; nCol <= nLast; ++nCol)
         aCol[nCol].SplitFormulaGroupByRelativeRef(aSortRange);
 
+    // table to keep track of column index to position in the index table.
+    std::vector<SCCOLROW> aPosTable(nCount);
+    for (size_t i = 0; i < nCount; ++i)
+        aPosTable[aIndices[i]-nStart] = i;
+
     SCCOLROW nDest = nStart;
-    for ( nPos = 0; nPos < nCount; nPos++, nDest++ )
+    for (size_t i = 0; i < nCount; ++i, ++nDest)
     {
-        SCCOLROW nOrg = ppInfo[nPos]->nOrg;
-        if ( nDest != nOrg )
+        SCCOLROW nSrc = aIndices[i];
+        if (nDest != nSrc)
         {
-            aCol[nDest].Swap(aCol[nOrg], nRow1, nRow2, bPattern);
+            aCol[nDest].Swap(aCol[nSrc], nRow1, nRow2, bPattern);
 
-            // 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" );
+            // Update the position of the index that was originally equal to nDest.
+            size_t nPos = aPosTable[nDest-nStart];
+            aIndices[nPos] = nSrc;
+            aPosTable[nSrc-nStart] = nPos;
         }
-        if(pProgress)
-            pProgress->SetStateOnPercent( nPos );
+
+        if (pProgress)
+            pProgress->SetStateOnPercent(i);
     }
 
     // Reset formula cell positions which became out-of-sync after column reordering.
commit 7a02a69c914b2271feae8f4d8562159651b90907
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Sun Jul 13 10:39:17 2014 -0400

    Don't forget to pass this flag.
    
    Change-Id: Ibc95b67266eb6a96cebdd026ac51a419e978f197

diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
index 061dd56..218c4df 100644
--- a/sc/source/core/data/table3.cxx
+++ b/sc/source/core/data/table3.cxx
@@ -463,6 +463,7 @@ ScSortInfoArray* ScTable::CreateSortInfoArray( const sc::ReorderParam& rParam )
         SCCOL nCol2 = rParam.maSortRange.aEnd.Col();
 
         pArray = new ScSortInfoArray(0, nRow1, nRow2);
+        pArray->SetKeepQuery(rParam.mbHiddenFiltered);
 
         initDataRows(
             *pArray, *this, aCol, nCol1, nRow1, nCol2, nRow2,
commit 8b5d80a8af184f7001de7561c85228d75c52fd6f
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Sat Jul 12 18:08:44 2014 -0400

    SortReorderByColumn() to not access aSortParam member.
    
    Change-Id: I9b66f42e49873b732caba727432a472a07fb43f4

diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 452e171..44c4951 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -1024,7 +1024,7 @@ private:
     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 SortReorderByColumn( ScSortInfoArray* pArray, SCROW nRow1, SCROW nRow2, bool bPattern, ScProgress* pProgress );
     void SortReorderByRow( ScSortInfoArray* pArray, SCCOL nCol1, SCCOL nCol2, ScProgress* pProgress );
 
     bool        CreateExcelQuery(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, ScQueryParam& rQueryParam);
diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
index e15f1b9..061dd56 100644
--- a/sc/source/core/data/table3.cxx
+++ b/sc/source/core/data/table3.cxx
@@ -654,7 +654,8 @@ public:
 
 }
 
-void ScTable::SortReorderByColumn( ScSortInfoArray* pArray, ScProgress* pProgress )
+void ScTable::SortReorderByColumn(
+    ScSortInfoArray* pArray, SCROW nRow1, SCROW nRow2, bool bPattern, ScProgress* pProgress )
 {
     size_t nCount = pArray->GetCount();
     SCCOLROW nStart = pArray->GetStart();
@@ -668,7 +669,7 @@ void ScTable::SortReorderByColumn( ScSortInfoArray* pArray, ScProgress* pProgres
         aTable[ppInfo[nPos]->nOrg - nStart] = ppInfo[nPos];
 
     // Cut formula grouping at row and reference boundaries before the reordering.
-    ScRange aSortRange(nStart, aSortParam.nRow1, nTab, nLast, aSortParam.nRow2, nTab);
+    ScRange aSortRange(nStart, nRow1, nTab, nLast, nRow2, nTab);
     for (SCCOL nCol = nStart; nCol <= nLast; ++nCol)
         aCol[nCol].SplitFormulaGroupByRelativeRef(aSortRange);
 
@@ -678,7 +679,7 @@ void ScTable::SortReorderByColumn( ScSortInfoArray* pArray, ScProgress* pProgres
         SCCOLROW nOrg = ppInfo[nPos]->nOrg;
         if ( nDest != nOrg )
         {
-            aCol[nDest].Swap(aCol[nOrg], aSortParam.nRow1, aSortParam.nRow2, aSortParam.bIncludePattern);
+            aCol[nDest].Swap(aCol[nOrg], nRow1, nRow2, bPattern);
 
             // neue Position des weggeswapten eintragen
             ScSortInfo* p = ppInfo[nPos];
@@ -694,7 +695,7 @@ void ScTable::SortReorderByColumn( ScSortInfoArray* pArray, ScProgress* pProgres
 
     // Reset formula cell positions which became out-of-sync after column reordering.
     for (SCCOL nCol = nStart; nCol <= nLast; ++nCol)
-        aCol[nCol].ResetFormulaCellPositions(aSortParam.nRow1, aSortParam.nRow2);
+        aCol[nCol].ResetFormulaCellPositions(nRow1, nRow2);
 
     // Set up column reorder map (for later broadcasting of reference updates).
     sc::ColRowReorderMapType aColMap;
@@ -709,14 +710,14 @@ void ScTable::SortReorderByColumn( ScSortInfoArray* pArray, ScProgress* pProgres
     // Collect all listeners within sorted range ahead of time.
     std::vector<SvtListener*> aListeners;
     for (SCCOL nCol = nStart; nCol <= nLast; ++nCol)
-        aCol[nCol].CollectListeners(aListeners, aSortParam.nRow1, aSortParam.nRow2);
+        aCol[nCol].CollectListeners(aListeners, nRow1, nRow2);
 
     // Remove any duplicate listener entries and notify all listeners
     // afterward.  We must ensure that we notify each unique listener only
     // once.
     std::sort(aListeners.begin(), aListeners.end());
     aListeners.erase(std::unique(aListeners.begin(), aListeners.end()), aListeners.end());
-    ColReorderNotifier aFunc(aColMap, nTab, aSortParam.nRow1, aSortParam.nRow2);
+    ColReorderNotifier aFunc(aColMap, nTab, nRow1, nRow2);
     std::for_each(aListeners.begin(), aListeners.end(), aFunc);
 
     // Re-join formulas at row boundaries now that all the references have
@@ -724,9 +725,9 @@ void ScTable::SortReorderByColumn( ScSortInfoArray* pArray, ScProgress* pProgres
     for (SCCOL nCol = nStart; nCol <= nLast; ++nCol)
     {
         sc::CellStoreType& rCells = aCol[nCol].maCells;
-        sc::CellStoreType::position_type aPos = rCells.position(aSortParam.nRow1);
+        sc::CellStoreType::position_type aPos = rCells.position(nRow1);
         sc::SharedFormulaUtil::joinFormulaCellAbove(aPos);
-        aPos = rCells.position(aPos.first, aSortParam.nRow2+1);
+        aPos = rCells.position(aPos.first, nRow2+1);
         sc::SharedFormulaUtil::joinFormulaCellAbove(aPos);
     }
 }
@@ -1230,8 +1231,6 @@ void ScTable::Sort(
                 pUndo->maSortRange = ScRange(rSortParam.nCol1, nRow1, nTab, rSortParam.nCol2, nLastRow, nTab);
                 pUndo->maPosIndices = pArray->GetOldIndices();
             }
-
-            // #i59745# update position of caption objects of cell notes --> reported at (SortReorder) ScColumn::SwapCellNotes level
         }
     }
     else
@@ -1251,15 +1250,13 @@ void ScTable::Sort(
             boost::scoped_ptr<ScSortInfoArray> pArray(CreateSortInfoArray(aSortParam, nCol1, nLastCol, bKeepQuery));
 
             QuickSort(pArray.get(), nCol1, nLastCol);
-            SortReorderByColumn(pArray.get(), pProgress);
+            SortReorderByColumn(pArray.get(), aSortParam.nRow1, aSortParam.nRow2, aSortParam.bIncludePattern, pProgress);
 
             if (pUndo)
             {
                 pUndo->maSortRange = ScRange(nCol1, aSortParam.nRow1, nTab, nLastCol, aSortParam.nRow2, nTab);
                 pUndo->maPosIndices = pArray->GetOldIndices();
             }
-
-            // #i59745# update position of caption objects of cell notes --> reported at (SortReorder) ScColumn::SwapCellNotes level
         }
     }
     DestroySortCollator();
commit 05bb4a028f72af608942a76f1a94dc854d5f1854
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 9891c8a..187621d 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)
@@ -554,46 +507,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)
@@ -636,12 +549,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 d820dcbedc1ef1e83968a354fea05e5261e92a3c
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 85bb737841bf327161918248a86fbcb0b7f022a8
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 bfd13304cac74e3437dd487723c681aa14799cc5
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()
commit 17434957f471599f9954de6a8e813a03b48ce13e
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Fri Jul 11 23:12:05 2014 -0400

    Build fix after rebase.
    
    Change-Id: Ia4077db9f5c5563c52968805ab0c7e0781af9d42

diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
index 85a6cad..db2df14 100644
--- a/sc/source/core/data/table3.cxx
+++ b/sc/source/core/data/table3.cxx
@@ -689,7 +689,8 @@ void ScTable::SortReorderByRow( ScSortInfoArray* pArray, ScProgress* pProgress )
                     assert(rCell.mpAttr);
                     ScAddress aOldPos = rCell.maCell.mpFormula->aPos;
 
-                    ScFormulaCell* pNew = rCell.maCell.mpFormula->Clone(aCellPos);
+                    ScFormulaCell* pNew = rCell.maCell.mpFormula->Clone(
+                        aCellPos, SC_CLONECELL_DEFAULT | SC_CLONECELL_ADJUST3DREL);
                     pNew->CopyAllBroadcasters(*rCell.maCell.mpFormula);
                     pNew->GetCode()->AdjustReferenceOnMovedOrigin(aOldPos, aCellPos);
 
@@ -1168,7 +1169,8 @@ void ScTable::Sort(
 
 void ScTable::Reorder( const sc::ReorderParam& rParam, ScProgress* pProgress )
 {
-
+    if (rParam.maOldIndices.empty())
+        return;
 }
 
 namespace {
commit d32995b4360e0f7fa76659abd8895199f3b0eede
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Mon Jun 30 12:02:11 2014 -0400

    Pass ScSortParam to this rather than using the data member.
    
    I need a variant of this method that doesn't use ScSortParam...
    
    Change-Id: I1bba02f2db5fba5c5ee985b3adfe566d99079835

diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 9f0cff2..d84340f 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -1021,7 +1021,7 @@ 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( SCCOLROW nInd1, SCCOLROW nInd2, bool bKeepQuery );
+    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 );
diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
index e83f86f..85a6cad 100644
--- a/sc/source/core/data/table3.cxx
+++ b/sc/source/core/data/table3.cxx
@@ -348,19 +348,20 @@ public:
     }
 };
 
-ScSortInfoArray* ScTable::CreateSortInfoArray( SCCOLROW nInd1, SCCOLROW nInd2, bool bKeepQuery )
+ScSortInfoArray* ScTable::CreateSortInfoArray(
+    const ScSortParam& rSortParam, SCCOLROW nInd1, SCCOLROW nInd2, bool bKeepQuery )
 {
     sal_uInt16 nUsedSorts = 1;
-    while ( nUsedSorts < aSortParam.GetSortKeyCount() && aSortParam.maKeyState[nUsedSorts].bDoSort )
+    while ( nUsedSorts < rSortParam.GetSortKeyCount() && rSortParam.maKeyState[nUsedSorts].bDoSort )
         nUsedSorts++;
     ScSortInfoArray* pArray = new ScSortInfoArray( nUsedSorts, nInd1, nInd2 );
     pArray->SetKeepQuery(bKeepQuery);
 
-    if ( aSortParam.bByRow )
+    if ( rSortParam.bByRow )
     {
         for ( sal_uInt16 nSort = 0; nSort < nUsedSorts; nSort++ )
         {
-            SCCOL nCol = static_cast<SCCOL>(aSortParam.maKeyState[nSort].nField);
+            SCCOL nCol = static_cast<SCCOL>(rSortParam.maKeyState[nSort].nField);
             ScColumn* pCol = &aCol[nCol];
             sc::ColumnBlockConstPosition aBlockPos;
             pCol->InitBlockPosition(aBlockPos);
@@ -374,9 +375,9 @@ ScSortInfoArray* ScTable::CreateSortInfoArray( SCCOLROW nInd1, SCCOLROW nInd2, b
 
         // Fill row-wise data table.
         ScSortInfoArray::RowsType& rRows = pArray->InitDataRows(
-            nInd2 - nInd1 + 1, aSortParam.nCol2 - aSortParam.nCol1 + 1);
+            nInd2 - nInd1 + 1, rSortParam.nCol2 - rSortParam.nCol1 + 1);
 
-        for (SCCOL nCol = aSortParam.nCol1; nCol <= aSortParam.nCol2; ++nCol)
+        for (SCCOL nCol = rSortParam.nCol1; nCol <= rSortParam.nCol2; ++nCol)
         {
             ScColumn& rCol = aCol[nCol];
 
@@ -388,14 +389,14 @@ ScSortInfoArray* ScTable::CreateSortInfoArray( SCCOLROW nInd1, SCCOLROW nInd2, b
             for (SCROW nRow = nInd1; nRow <= nInd2; ++nRow)
             {
                 ScSortInfoArray::Row& rRow = *rRows[nRow-nInd1];
-                ScSortInfoArray::Cell& rCell = rRow.maCells[nCol-aSortParam.nCol1];
+                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 && aSortParam.bIncludePattern)
+                if (!bUniformPattern && rSortParam.bIncludePattern)
                     rCell.mpPattern = rCol.GetPattern(nRow);
             }
         }
@@ -414,7 +415,7 @@ ScSortInfoArray* ScTable::CreateSortInfoArray( SCCOLROW nInd1, SCCOLROW nInd2, b
     {
         for ( sal_uInt16 nSort = 0; nSort < nUsedSorts; nSort++ )
         {
-            SCROW nRow = aSortParam.maKeyState[nSort].nField;
+            SCROW nRow = rSortParam.maKeyState[nSort].nField;
             for ( SCCOL nCol = static_cast<SCCOL>(nInd1);
                     nCol <= static_cast<SCCOL>(nInd2); nCol++ )
             {
@@ -1117,7 +1118,7 @@ void ScTable::Sort(
             if(pProgress)
                 pProgress->SetState( 0, nLastRow-nRow1 );
 
-            boost::scoped_ptr<ScSortInfoArray> pArray(CreateSortInfoArray(nRow1, nLastRow, bKeepQuery));
+            boost::scoped_ptr<ScSortInfoArray> pArray(CreateSortInfoArray(aSortParam, nRow1, nLastRow, bKeepQuery));
 
             if ( nLastRow - nRow1 > 255 )
                 DecoladeRow(pArray.get(), nRow1, nLastRow);
@@ -1148,7 +1149,7 @@ void ScTable::Sort(
             if(pProgress)
                 pProgress->SetState( 0, nLastCol-nCol1 );
 
-            boost::scoped_ptr<ScSortInfoArray> pArray(CreateSortInfoArray(nCol1, nLastCol, bKeepQuery));
+            boost::scoped_ptr<ScSortInfoArray> pArray(CreateSortInfoArray(aSortParam, nCol1, nLastCol, bKeepQuery));
 
             QuickSort(pArray.get(), nCol1, nLastCol);
             SortReorderByColumn(pArray.get(), pProgress);
@@ -2159,7 +2160,7 @@ void ScTable::TopTenQuery( ScQueryParam& rParam )
                     bSortCollatorInitialized = true;
                     InitSortCollator( aLocalSortParam );
                 }
-                boost::scoped_ptr<ScSortInfoArray> pArray(CreateSortInfoArray(nRow1, rParam.nRow2, bGlobalKeepQuery));
+                boost::scoped_ptr<ScSortInfoArray> pArray(CreateSortInfoArray(aSortParam, nRow1, rParam.nRow2, bGlobalKeepQuery));
                 DecoladeRow( pArray.get(), nRow1, rParam.nRow2 );
                 QuickSort( pArray.get(), nRow1, rParam.nRow2 );
                 ScSortInfo** ppInfo = pArray->GetFirstArray();
commit 63f5adb350da392230736955a743c518b74972ae
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Mon Jun 30 10:43:49 2014 -0400

    Let's not include sortparam.hxx in document.hxx.
    
    Change-Id: Ie2179c64909845163398b1f0592e1c88151afe8e

diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index aa52132..44e88c0 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -29,7 +29,6 @@
 #include "rangenam.hxx"
 #include "brdcst.hxx"
 #include "tabopparams.hxx"
-#include "sortparam.hxx"
 #include "types.hxx"
 #include <formula/grammar.hxx>
 #include <formula/types.hxx>
@@ -80,6 +79,7 @@ class RowHeightContext;
 struct SetFormulaDirtyContext;
 class RefMovedHint;
 struct SortUndoParam;
+struct ReorderParam;
 
 }
 
@@ -182,6 +182,8 @@ class EditTextObject;
 struct ScRefCellValue;
 class ScDocumentImport;
 class ScPostIt;
+struct ScSubTotalParam;
+struct ScQueryParam;
 
 namespace com { namespace sun { namespace star {
     namespace lang {
@@ -2036,8 +2038,8 @@ public:
 
     void            InvalidateStyleSheetUsage()
                         { bStyleSheetUsageInvalid = true; }
-    void GetSortParam( ScSortParam& rParam, SCTAB nTab );
-    void SetSortParam( ScSortParam& rParam, SCTAB nTab );
+    void SC_DLLPUBLIC GetSortParam( ScSortParam& rParam, SCTAB nTab );
+    void SC_DLLPUBLIC SetSortParam( ScSortParam& rParam, SCTAB nTab );
 
     inline void     SetVbaEventProcessor( const com::sun::star::uno::Reference< com::sun::star::script::vba::XVBAEventProcessor >& rxVbaEvents )
                         { mxVbaEvents = rxVbaEvents; }
@@ -2164,15 +2166,6 @@ private:
 
     void SharePooledResources( ScDocument* pSrcDoc );
 };
-inline void ScDocument::GetSortParam( ScSortParam& rParam, SCTAB nTab )
-{
-    rParam = mSheetSortParams[ nTab ];
-}
-
-inline void ScDocument::SetSortParam( ScSortParam& rParam, SCTAB nTab )
-{
-    mSheetSortParams[ nTab ] = rParam;
-}
 
 #endif
 
diff --git a/sc/qa/unit/filters-test.cxx b/sc/qa/unit/filters-test.cxx
index bb60b7b..da9ec56 100644
--- a/sc/qa/unit/filters-test.cxx
+++ b/sc/qa/unit/filters-test.cxx
@@ -35,6 +35,7 @@
 #include <dbdocfun.hxx>
 #include <globalnames.hxx>
 #include <dbdata.hxx>
+#include <sortparam.hxx>
 
 #include <svx/svdpage.hxx>
 
diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index 573ce5a..8e88ee4 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -63,6 +63,7 @@
 #include <docpool.hxx>
 #include <globalnames.hxx>
 #include <inputopt.hxx>
+#include <sortparam.hxx>
 
 #include <editable.hxx>
 
diff --git a/sc/source/core/data/documen3.cxx b/sc/source/core/data/documen3.cxx
index 2d44b71..34badd8 100644
--- a/sc/source/core/data/documen3.cxx
+++ b/sc/source/core/data/documen3.cxx
@@ -2012,4 +2012,14 @@ bool ScDocument::ReservePatternCount( SCTAB nTab, SCCOL nCol, SCSIZE nReserve )
         return false;
 }
 
+void ScDocument::GetSortParam( ScSortParam& rParam, SCTAB nTab )
+{
+    rParam = mSheetSortParams[ nTab ];
+}
+
+void ScDocument::SetSortParam( ScSortParam& rParam, SCTAB nTab )
+{
+    mSheetSortParams[ nTab ] = rParam;
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/xml/XMLExportDatabaseRanges.cxx b/sc/source/filter/xml/XMLExportDatabaseRanges.cxx
index a507427..758a1f9 100644
--- a/sc/source/filter/xml/XMLExportDatabaseRanges.cxx
+++ b/sc/source/filter/xml/XMLExportDatabaseRanges.cxx
@@ -35,6 +35,7 @@
 #include "subtotalparam.hxx"
 #include "queryparam.hxx"
 #include "queryentry.hxx"
+#include <sortparam.hxx>
 
 #include <svx/dataaccessdescriptor.hxx>
 
diff --git a/sc/source/filter/xml/xmldrani.cxx b/sc/source/filter/xml/xmldrani.cxx
index 9088e00..38db1b30 100644
--- a/sc/source/filter/xml/xmldrani.cxx
+++ b/sc/source/filter/xml/xmldrani.cxx
@@ -34,6 +34,7 @@
 #include "rangeutl.hxx"
 #include "queryentry.hxx"
 #include "dputil.hxx"
+#include <sortparam.hxx>
 
 #include <xmloff/xmltkmap.hxx>
 #include <xmloff/nmspmap.hxx>
diff --git a/sc/source/ui/undo/undobase.cxx b/sc/source/ui/undo/undobase.cxx
index 8740c6b..dc7efd4 100644
--- a/sc/source/ui/undo/undobase.cxx
+++ b/sc/source/ui/undo/undobase.cxx
@@ -33,6 +33,7 @@
 #include "globstr.hrc"
 #include <rowheightcontext.hxx>
 #include <column.hxx>
+#include <sortparam.hxx>
 
 TYPEINIT1(ScSimpleUndo,     SfxUndoAction);
 TYPEINIT1(ScBlockUndo,      ScSimpleUndo);
diff --git a/sc/source/ui/unoobj/cellsuno.cxx b/sc/source/ui/unoobj/cellsuno.cxx
index 3a94df0..7ad0202 100644
--- a/sc/source/ui/unoobj/cellsuno.cxx
+++ b/sc/source/ui/unoobj/cellsuno.cxx
@@ -125,6 +125,7 @@
 #include "tokenarray.hxx"
 #include "stylehelper.hxx"
 #include "dputil.hxx"
+#include <sortparam.hxx>
 
 #include <list>
 #include <boost/scoped_array.hpp>
diff --git a/sc/source/ui/unoobj/datauno.cxx b/sc/source/ui/unoobj/datauno.cxx
index b848791..0dc0bcf 100644
--- a/sc/source/ui/unoobj/datauno.cxx
+++ b/sc/source/ui/unoobj/datauno.cxx
@@ -51,6 +51,7 @@
 #include "dpshttab.hxx"
 #include "queryentry.hxx"
 #include "dputil.hxx"
+#include <sortparam.hxx>
 
 #include <comphelper/extract.hxx>
 #include <comphelper/servicehelper.hxx>
commit 57745a18705fd157d59d0d082bf69893c7651f38
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Fri Jun 27 21:00:38 2014 -0400

    More tweaking...
    
    Change-Id: I9276fd92a90dc2689bd59b2ed7eef3d7267ff5b8

diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 0f69c4a..aa52132 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -1677,7 +1677,9 @@ public:
     SC_DLLPUBLIC SvNumberFormatter* GetFormatTable() const;
     SC_DLLPUBLIC SvNumberFormatter* CreateFormatTable() const;
 
-    void Sort( SCTAB nTab, const ScSortParam& rSortParam, bool bKeepQuery, ScProgress* pProgress, sc::SortUndoParam* pUndo );
+    void Sort( SCTAB nTab, const ScSortParam& rSortParam, bool bKeepQuery, ScProgress* pProgress, sc::ReorderParam* pUndo );
+    void Reorder( const sc::ReorderParam& rParam, ScProgress* pProgress );
+
     SCSIZE          Query( SCTAB nTab, const ScQueryParam& rQueryParam, bool bKeepSub );
     SC_DLLPUBLIC bool           CreateQueryParam( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
                                         SCTAB nTab, ScQueryParam& rQueryParam );
diff --git a/sc/inc/sortparam.hxx b/sc/inc/sortparam.hxx
index df3a449..83a1c34 100644
--- a/sc/inc/sortparam.hxx
+++ b/sc/inc/sortparam.hxx
@@ -80,11 +80,10 @@ struct SC_DLLPUBLIC ScSortParam
 
 namespace sc {
 
-struct SC_DLLPUBLIC SortUndoParam
+struct SC_DLLPUBLIC ReorderParam
 {
     ScRange maSortRange;
     std::vector<SCCOLROW> maOldIndices;
-    bool mbHasHeader;
     bool mbByRow;
     bool mbIncludePattern;
 };
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 649d8e6..9f0cff2 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -73,7 +73,7 @@ class RowHeightContext;
 class CompileFormulaContext;
 struct SetFormulaDirtyContext;
 class RefMovedHint;
-struct SortUndoParam;
+struct ReorderParam;
 
 }
 
@@ -826,7 +826,9 @@ public:
     void        ExtendHidden( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2 );
 
     void Sort(
-        const ScSortParam& rSortParam, bool bKeepQuery, ScProgress* pProgress, sc::SortUndoParam* pUndo );
+        const ScSortParam& rSortParam, bool bKeepQuery, ScProgress* pProgress, sc::ReorderParam* pUndo );
+    void Reorder( const sc::ReorderParam& rParam, ScProgress* pProgress );
+
     bool ValidQuery(
         SCROW nRow, const ScQueryParam& rQueryParam, ScRefCellValue* pCell = NULL,
         bool* pbTestEqualCondition = NULL);
@@ -1021,8 +1023,8 @@ private:
     short       Compare( ScSortInfoArray*, SCCOLROW nIndex1, SCCOLROW nIndex2) const;
     ScSortInfoArray* CreateSortInfoArray( SCCOLROW nInd1, SCCOLROW nInd2, bool bKeepQuery );
     void        QuickSort( ScSortInfoArray*, SCsCOLROW nLo, SCsCOLROW nHi);
-    void SortReorderByColumn( ScSortInfoArray* pArray, ScProgress* pProgress, sc::SortUndoParam* pUndo );
-    void SortReorderByRow( ScSortInfoArray* pArray, ScProgress* pProgress, sc::SortUndoParam* pUndo );
+    void SortReorderByColumn( ScSortInfoArray* pArray, ScProgress* pProgress );
+    void SortReorderByRow( ScSortInfoArray* pArray, 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/inc/undosort.hxx b/sc/inc/undosort.hxx
index d7a4512..fb8fbeb 100644
--- a/sc/inc/undosort.hxx
+++ b/sc/inc/undosort.hxx
@@ -17,10 +17,10 @@ namespace sc {
 
 class UndoSort : public ScSimpleUndo
 {
-    SortUndoParam maParam;
+    ReorderParam maParam;
 
 public:
-    UndoSort( ScDocShell* pDocSh, const SortUndoParam& rParam );
+    UndoSort( ScDocShell* pDocSh, const ReorderParam& rParam );
 
     virtual OUString GetComment() const;
     virtual void Undo();
diff --git a/sc/source/core/data/documen3.cxx b/sc/source/core/data/documen3.cxx
index 6122696..2d44b71 100644
--- a/sc/source/core/data/documen3.cxx
+++ b/sc/source/core/data/documen3.cxx
@@ -1336,7 +1336,7 @@ bool ScDocument::UpdateOutlineRow( SCROW nStartRow, SCROW nEndRow, SCTAB nTab, b
 }
 
 void ScDocument::Sort(
-    SCTAB nTab, const ScSortParam& rSortParam, bool bKeepQuery, ScProgress* pProgress, sc::SortUndoParam* pUndo )
+    SCTAB nTab, const ScSortParam& rSortParam, bool bKeepQuery, ScProgress* pProgress, sc::ReorderParam* pUndo )
 {
     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
     {
@@ -1347,6 +1347,18 @@ void ScDocument::Sort(
     }
 }
 
+void ScDocument::Reorder( const sc::ReorderParam& rParam, ScProgress* pProgress )
+{
+    ScTable* pTab = FetchTable(rParam.maSortRange.aStart.Tab());
+    if (!pTab)
+        return;
+
+    bool bOldEnableIdle = IsIdleEnabled();
+    EnableIdle(false);
+    pTab->Reorder(rParam, pProgress);
+    EnableIdle(bOldEnableIdle);
+}
+
 SCSIZE ScDocument::Query(SCTAB nTab, const ScQueryParam& rQueryParam, bool bKeepSub)
 {
     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
index 1283ee1..e83f86f 100644
--- a/sc/source/core/data/table3.cxx
+++ b/sc/source/core/data/table3.cxx
@@ -560,8 +560,7 @@ public:
 
 }
 
-void ScTable::SortReorderByColumn(
-    ScSortInfoArray* pArray, ScProgress* pProgress, sc::SortUndoParam* pUndo )
+void ScTable::SortReorderByColumn( ScSortInfoArray* pArray, ScProgress* pProgress )
 {
     size_t nCount = pArray->GetCount();
     SCCOLROW nStart = pArray->GetStart();
@@ -638,8 +637,7 @@ void ScTable::SortReorderByColumn(
     }
 }
 
-void ScTable::SortReorderByRow(
-    ScSortInfoArray* pArray, ScProgress* pProgress, sc::SortUndoParam* pUndo )
+void ScTable::SortReorderByRow( ScSortInfoArray* pArray, ScProgress* pProgress )
 {
     SCROW nRow1 = pArray->GetStart();
     SCROW nRow2 = pArray->GetLast();
@@ -1093,11 +1091,19 @@ void ScTable::DecoladeRow( ScSortInfoArray* pArray, SCROW nRow1, SCROW nRow2 )
 }
 
 void ScTable::Sort(
-    const ScSortParam& rSortParam, bool bKeepQuery, ScProgress* pProgress, sc::SortUndoParam* pUndo )
+    const ScSortParam& rSortParam, bool bKeepQuery, ScProgress* pProgress, sc::ReorderParam* pUndo )
 {
     aSortParam = rSortParam;
     InitSortCollator( rSortParam );
     bGlobalKeepQuery = bKeepQuery;
+
+    if (pUndo)
+    {
+        // Copy over the basic sort parameters.
+        pUndo->mbByRow = rSortParam.bByRow;
+        pUndo->mbIncludePattern = rSortParam.bIncludePattern;
+    }
+
     if (rSortParam.bByRow)
     {
         SCROW nLastRow = 0;
@@ -1117,7 +1123,13 @@ void ScTable::Sort(
                 DecoladeRow(pArray.get(), nRow1, nLastRow);
 
             QuickSort(pArray.get(), nRow1, nLastRow);
-            SortReorderByRow(pArray.get(), pProgress, pUndo);
+            SortReorderByRow(pArray.get(), pProgress);
+
+            if (pUndo)
+            {
+                pUndo->maSortRange = ScRange(rSortParam.nCol1, nRow1, nTab, rSortParam.nCol2, nLastRow, nTab);
+                pUndo->maOldIndices = pArray->GetOldIndices();
+            }
 
             // #i59745# update position of caption objects of cell notes --> reported at (SortReorder) ScColumn::SwapCellNotes level
         }
@@ -1139,7 +1151,13 @@ void ScTable::Sort(
             boost::scoped_ptr<ScSortInfoArray> pArray(CreateSortInfoArray(nCol1, nLastCol, bKeepQuery));
 
             QuickSort(pArray.get(), nCol1, nLastCol);
-            SortReorderByColumn(pArray.get(), pProgress, pUndo);
+            SortReorderByColumn(pArray.get(), pProgress);
+
+            if (pUndo)
+            {
+                pUndo->maSortRange = ScRange(nCol1, aSortParam.nRow1, nTab, nLastCol, aSortParam.nRow2, nTab);
+                pUndo->maOldIndices = pArray->GetOldIndices();
+            }
 
             // #i59745# update position of caption objects of cell notes --> reported at (SortReorder) ScColumn::SwapCellNotes level
         }
@@ -1147,6 +1165,11 @@ void ScTable::Sort(
     DestroySortCollator();
 }
 
+void ScTable::Reorder( const sc::ReorderParam& rParam, ScProgress* pProgress )
+{
+
+}
+
 namespace {
 
 class SubTotalRowFinder
diff --git a/sc/source/ui/docshell/dbdocfun.cxx b/sc/source/ui/docshell/dbdocfun.cxx
index 3b8aaba..9891c8a 100644
--- a/sc/source/ui/docshell/dbdocfun.cxx
+++ b/sc/source/ui/docshell/dbdocfun.cxx
@@ -594,7 +594,7 @@ bool ScDBDocFunc::Sort( SCTAB nTab, const ScSortParam& rSortParam,
     }
 #endif
 
-    sc::SortUndoParam aUndoParam;
+    sc::ReorderParam aUndoParam;
 
     // don't call ScDocument::Sort with an empty SortParam (may be empty here if bCopy is set)
     if (aLocalParam.GetSortKeyCount() && aLocalParam.maKeyState[0].bDoSort)
diff --git a/sc/source/ui/undo/undosort.cxx b/sc/source/ui/undo/undosort.cxx
index 09671bc..1258882 100644
--- a/sc/source/ui/undo/undosort.cxx
+++ b/sc/source/ui/undo/undosort.cxx
@@ -13,7 +13,7 @@
 
 namespace sc {
 
-UndoSort::UndoSort( ScDocShell* pDocSh, const SortUndoParam& rParam ) :
+UndoSort::UndoSort( ScDocShell* pDocSh, const ReorderParam& rParam ) :
     ScSimpleUndo(pDocSh), maParam(rParam) {}
 
 OUString UndoSort::GetComment() const
@@ -23,6 +23,8 @@ OUString UndoSort::GetComment() const
 
 void UndoSort::Undo()
 {
+    ScDocument& rDoc = pDocShell->GetDocument();
+    rDoc.Reorder(maParam, NULL);
 }
 
 void UndoSort::Redo()
commit 8618506cf6feaafdce37ccd92f8d554dcfed0df1
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Fri Jun 27 16:24:36 2014 -0400

    Set up a new undo sort mechanism.  It's empty for now.
    
    Change-Id: I14a235f050d64d64d1102a688a304249afacf802

diff --git a/sc/Library_sc.mk b/sc/Library_sc.mk
index 8e42c63..639946a 100644
--- a/sc/Library_sc.mk
+++ b/sc/Library_sc.mk
@@ -518,6 +518,7 @@ $(eval $(call gb_Library_add_exception_objects,sc,\
     sc/source/ui/undo/undodraw \
     sc/source/ui/undo/undoolk \
     sc/source/ui/undo/undorangename \
+    sc/source/ui/undo/undosort \
     sc/source/ui/undo/undostyl \
     sc/source/ui/undo/undotab \
     sc/source/ui/undo/undoutil \
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 7ab6a20..0f69c4a 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -79,6 +79,7 @@ class CellValues;
 class RowHeightContext;
 struct SetFormulaDirtyContext;
 class RefMovedHint;
+struct SortUndoParam;
 
 }
 
@@ -1676,7 +1677,7 @@ public:
     SC_DLLPUBLIC SvNumberFormatter* GetFormatTable() const;
     SC_DLLPUBLIC SvNumberFormatter* CreateFormatTable() const;
 
-    void            Sort( SCTAB nTab, const ScSortParam& rSortParam, bool bKeepQuery, ScProgress* pProgress );
+    void Sort( SCTAB nTab, const ScSortParam& rSortParam, bool bKeepQuery, ScProgress* pProgress, sc::SortUndoParam* pUndo );
     SCSIZE          Query( SCTAB nTab, const ScQueryParam& rQueryParam, bool bKeepSub );
     SC_DLLPUBLIC bool           CreateQueryParam( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
                                         SCTAB nTab, ScQueryParam& rQueryParam );
diff --git a/sc/inc/sortparam.hxx b/sc/inc/sortparam.hxx
index 55b09a6..df3a449 100644
--- a/sc/inc/sortparam.hxx
+++ b/sc/inc/sortparam.hxx
@@ -78,6 +78,19 @@ struct SC_DLLPUBLIC ScSortParam
     inline sal_uInt16 GetSortKeyCount() const { return maKeyState.size(); }
 };
 
+namespace sc {
+
+struct SC_DLLPUBLIC SortUndoParam
+{
+    ScRange maSortRange;
+    std::vector<SCCOLROW> maOldIndices;
+    bool mbHasHeader;
+    bool mbByRow;
+    bool mbIncludePattern;
+};
+
+}
+
 #endif // INCLUDED_SC_INC_SORTPARAM_HXX
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 580b738..649d8e6 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -73,6 +73,7 @@ class RowHeightContext;
 class CompileFormulaContext;
 struct SetFormulaDirtyContext;
 class RefMovedHint;
+struct SortUndoParam;
 
 }
 
@@ -824,7 +825,8 @@ public:
     void        StripHidden( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2 );
     void        ExtendHidden( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2 );
 
-    void        Sort(const ScSortParam& rSortParam, bool bKeepQuery, ScProgress* pProgress);
+    void Sort(
+        const ScSortParam& rSortParam, bool bKeepQuery, ScProgress* pProgress, sc::SortUndoParam* pUndo );
     bool ValidQuery(
         SCROW nRow, const ScQueryParam& rQueryParam, ScRefCellValue* pCell = NULL,
         bool* pbTestEqualCondition = NULL);
@@ -1019,8 +1021,8 @@ private:
     short       Compare( ScSortInfoArray*, SCCOLROW nIndex1, SCCOLROW nIndex2) const;
     ScSortInfoArray* CreateSortInfoArray( 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 SortReorderByColumn( ScSortInfoArray* pArray, ScProgress* pProgress, sc::SortUndoParam* pUndo );
+    void SortReorderByRow( ScSortInfoArray* pArray, ScProgress* pProgress, sc::SortUndoParam* pUndo );
 
     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/inc/undosort.hxx b/sc/inc/undosort.hxx
new file mode 100644
index 0000000..d7a4512
--- /dev/null
+++ b/sc/inc/undosort.hxx
@@ -0,0 +1,34 @@
+/* -*- 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 INCLUDED_SC_UNDOSORT_HXX
+#define INCLUDED_SC_UNDOSORT_HXX
+
+#include <undobase.hxx>
+#include <sortparam.hxx>
+
+namespace sc {
+
+class UndoSort : public ScSimpleUndo
+{
+    SortUndoParam maParam;
+
+public:
+    UndoSort( ScDocShell* pDocSh, const SortUndoParam& rParam );
+
+    virtual OUString GetComment() const;
+    virtual void Undo();
+    virtual void Redo();
+};
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index 7708427..573ce5a 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -4810,7 +4810,7 @@ void Test::testSortWithFormulaRefs()
     aSortData.maKeyState[0].bDoSort = true;
     aSortData.maKeyState[0].nField = 0;
 
-    m_pDoc->Sort(0, aSortData, false, NULL);
+    m_pDoc->Sort(0, aSortData, false, NULL, NULL);
 
     for (size_t i = 0; i < SAL_N_ELEMENTS(aResults); ++i)
     {
@@ -4845,7 +4845,7 @@ void Test::testSortWithStrings()
     aParam.maKeyState[0].bAscending = true;
     aParam.maKeyState[0].nField = 1;
 
-    m_pDoc->Sort(0, aParam, false, NULL);
+    m_pDoc->Sort(0, aParam, false, NULL, NULL);
 
     CPPUNIT_ASSERT_EQUAL(OUString("Header"), m_pDoc->GetString(ScAddress(1,1,0)));
     CPPUNIT_ASSERT_EQUAL(OUString("Val1"), m_pDoc->GetString(ScAddress(1,2,0)));
@@ -4853,7 +4853,7 @@ void Test::testSortWithStrings()
 
     aParam.maKeyState[0].bAscending = false;
 
-    m_pDoc->Sort(0, aParam, false, NULL);
+    m_pDoc->Sort(0, aParam, false, NULL, NULL);
 
     CPPUNIT_ASSERT_EQUAL(OUString("Header"), m_pDoc->GetString(ScAddress(1,1,0)));
     CPPUNIT_ASSERT_EQUAL(OUString("Val2"), m_pDoc->GetString(ScAddress(1,2,0)));
@@ -4896,7 +4896,7 @@ void Test::testSort()
     aSortData.maKeyState[0].nField = 1;
     aSortData.maKeyState[0].bAscending = true;
 
-    m_pDoc->Sort(0, aSortData, false, NULL);
+    m_pDoc->Sort(0, aSortData, false, NULL, NULL);
 
     double nVal = m_pDoc->GetValue(1,0,0);
     ASSERT_DOUBLES_EQUAL(nVal, 1.0);
@@ -4929,7 +4929,7 @@ void Test::testSort()
     aSortData.nRow2 = aDataRange.aEnd.Row();
     aSortData.bHasHeader = true;
     aSortData.maKeyState[0].nField = 0;
-    m_pDoc->Sort(0, aSortData, false, NULL);
+    m_pDoc->Sort(0, aSortData, false, NULL, NULL);
 
     // Title should stay at the top, numbers should be sorted numerically,
     // numbers always come before strings, and empty cells always occur at the
@@ -5127,7 +5127,7 @@ void Test::testSortInFormulaGroup()
     aSortData.maKeyState[0].nField = 0;
     aSortData.maKeyState[0].bAscending = true;
 
-    m_pDoc->Sort(0, aSortData, false, NULL);
+    m_pDoc->Sort(0, aSortData, false, NULL, NULL);
 
     static struct {
         SCCOL nCol;
diff --git a/sc/source/core/data/documen3.cxx b/sc/source/core/data/documen3.cxx
index e8719fc..6122696 100644
--- a/sc/source/core/data/documen3.cxx
+++ b/sc/source/core/data/documen3.cxx
@@ -1335,13 +1335,14 @@ bool ScDocument::UpdateOutlineRow( SCROW nStartRow, SCROW nEndRow, SCTAB nTab, b
     return false;
 }
 
-void ScDocument::Sort(SCTAB nTab, const ScSortParam& rSortParam, bool bKeepQuery, ScProgress* pProgress)
+void ScDocument::Sort(
+    SCTAB nTab, const ScSortParam& rSortParam, bool bKeepQuery, ScProgress* pProgress, sc::SortUndoParam* pUndo )
 {
     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
     {
         bool bOldEnableIdle = IsIdleEnabled();
         EnableIdle(false);
-        maTabs[nTab]->Sort(rSortParam, bKeepQuery, pProgress);
+        maTabs[nTab]->Sort(rSortParam, bKeepQuery, pProgress, pUndo);
         EnableIdle(bOldEnableIdle);
     }
 }
diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
index 1ffc739..1283ee1 100644
--- a/sc/source/core/data/table3.cxx
+++ b/sc/source/core/data/table3.cxx
@@ -560,7 +560,8 @@ public:
 
 }
 
-void ScTable::SortReorderByColumn( ScSortInfoArray* pArray, ScProgress* pProgress )
+void ScTable::SortReorderByColumn(
+    ScSortInfoArray* pArray, ScProgress* pProgress, sc::SortUndoParam* pUndo )
 {
     size_t nCount = pArray->GetCount();
     SCCOLROW nStart = pArray->GetStart();
@@ -637,7 +638,8 @@ void ScTable::SortReorderByColumn( ScSortInfoArray* pArray, ScProgress* pProgres
     }
 }
 
-void ScTable::SortReorderByRow( ScSortInfoArray* pArray, ScProgress* pProgress )
+void ScTable::SortReorderByRow(
+    ScSortInfoArray* pArray, ScProgress* pProgress, sc::SortUndoParam* pUndo )
 {
     SCROW nRow1 = pArray->GetStart();
     SCROW nRow2 = pArray->GetLast();
@@ -1090,7 +1092,8 @@ void ScTable::DecoladeRow( ScSortInfoArray* pArray, SCROW nRow1, SCROW nRow2 )
     }
 }
 
-void ScTable::Sort(const ScSortParam& rSortParam, bool bKeepQuery, ScProgress* pProgress)
+void ScTable::Sort(
+    const ScSortParam& rSortParam, bool bKeepQuery, ScProgress* pProgress, sc::SortUndoParam* pUndo )
 {
     aSortParam = rSortParam;
     InitSortCollator( rSortParam );
@@ -1114,7 +1117,7 @@ void ScTable::Sort(const ScSortParam& rSortParam, bool bKeepQuery, ScProgress* p
                 DecoladeRow(pArray.get(), nRow1, nLastRow);
 
             QuickSort(pArray.get(), nRow1, nLastRow);
-            SortReorderByRow(pArray.get(), pProgress);
+            SortReorderByRow(pArray.get(), pProgress, pUndo);
 
             // #i59745# update position of caption objects of cell notes --> reported at (SortReorder) ScColumn::SwapCellNotes level
         }
@@ -1136,7 +1139,7 @@ void ScTable::Sort(const ScSortParam& rSortParam, bool bKeepQuery, ScProgress* p
             boost::scoped_ptr<ScSortInfoArray> pArray(CreateSortInfoArray(nCol1, nLastCol, bKeepQuery));
 
             QuickSort(pArray.get(), nCol1, nLastCol);
-            SortReorderByColumn(pArray.get(), pProgress);
+            SortReorderByColumn(pArray.get(), pProgress, pUndo);
 
             // #i59745# update position of caption objects of cell notes --> reported at (SortReorder) ScColumn::SwapCellNotes level
         }
diff --git a/sc/source/ui/docshell/dbdocfun.cxx b/sc/source/ui/docshell/dbdocfun.cxx
index de41cfc..3b8aaba 100644
--- a/sc/source/ui/docshell/dbdocfun.cxx
+++ b/sc/source/ui/docshell/dbdocfun.cxx
@@ -47,6 +47,7 @@
 #include "queryentry.hxx"
 #include "markdata.hxx"
 #include "progress.hxx"
+#include <undosort.hxx>
 
 #include <set>
 #include <memory>
@@ -474,7 +475,9 @@ bool ScDBDocFunc::Sort( SCTAB nTab, const ScSortParam& rSortParam,
     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 );
@@ -551,6 +554,7 @@ bool ScDBDocFunc::Sort( SCTAB nTab, const ScSortParam& rSortParam,
     if ( aQueryParam.GetEntry(0).bDoQuery )
         bRepeatQuery = true;
 
+#if 0
     ScUndoSort* pUndoAction = 0;
     if ( bRecord )
     {
@@ -588,12 +592,22 @@ bool ScDBDocFunc::Sort( SCTAB nTab, const ScSortParam& rSortParam,
         if( pDrawLayer )
             pDrawLayer->BeginCalcUndo(false);
     }
+#endif
+
+    sc::SortUndoParam aUndoParam;
 
     // don't call ScDocument::Sort with an empty SortParam (may be empty here if bCopy is set)
     if (aLocalParam.GetSortKeyCount() && aLocalParam.maKeyState[0].bDoSort)
     {
         ScProgress aProgress(&rDocShell, ScGlobal::GetRscString(STR_PROGRESS_SORTING), 0);
-        rDoc.Sort( nTab, aLocalParam, bRepeatQuery, &aProgress );
+        rDoc.Sort(nTab, aLocalParam, bRepeatQuery, &aProgress, &aUndoParam);
+    }
+
+    if (bRecord)
+    {
+        // Set up an undo object.
+        sc::UndoSort* pUndoAction = new sc::UndoSort(&rDocShell, aUndoParam);
+        rDocShell.GetUndoManager()->AddUndoAction(pUndoAction);
     }
 
     pDBData->SetSortParam(rSortParam);
@@ -622,9 +636,11 @@ 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();
 
diff --git a/sc/source/ui/undo/undosort.cxx b/sc/source/ui/undo/undosort.cxx
new file mode 100644
index 0000000..09671bc
--- /dev/null
+++ b/sc/source/ui/undo/undosort.cxx
@@ -0,0 +1,34 @@
+/* -*- 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 <undosort.hxx>
+#include <globstr.hrc>
+#include <global.hxx>
+
+namespace sc {
+
+UndoSort::UndoSort( ScDocShell* pDocSh, const SortUndoParam& rParam ) :
+    ScSimpleUndo(pDocSh), maParam(rParam) {}
+
+OUString UndoSort::GetComment() const
+{
+    return ScGlobal::GetRscString(STR_UNDO_SORT);
+}
+
+void UndoSort::Undo()
+{
+}
+
+void UndoSort::Redo()
+{
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit cf7c9cebb18ed312a0365042523c0dfceacb9643
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Fri Jun 27 14:30:33 2014 -0400

    Use one map type for both column and row mapping.
    
    Change-Id: I7581ece97113acc88ff12fabec66c46c706bad3e

diff --git a/sc/inc/refhint.hxx b/sc/inc/refhint.hxx
index 81449ad..1eff906 100644
--- a/sc/inc/refhint.hxx
+++ b/sc/inc/refhint.hxx
@@ -61,16 +61,16 @@ public:
 
 class RefColReorderHint : public RefHint
 {
-    const sc::ColReorderMapType& mrColMap;
+    const sc::ColRowReorderMapType& mrColMap;
     SCTAB mnTab;
     SCROW mnRow1;
     SCROW mnRow2;
 
 public:
-    RefColReorderHint( const sc::ColReorderMapType& rColMap, SCTAB nTab, SCROW nRow1, SCROW nRow2 );
+    RefColReorderHint( const sc::ColRowReorderMapType& rColMap, SCTAB nTab, SCROW nRow1, SCROW nRow2 );
     virtual ~RefColReorderHint();
 
-    const sc::ColReorderMapType& getColMap() const;
+    const sc::ColRowReorderMapType& getColMap() const;
 
     SCTAB getTab() const;
     SCROW getStartRow() const;
@@ -79,16 +79,16 @@ public:
 
 class RefRowReorderHint : public RefHint
 {
-    const sc::RowReorderMapType& mrRowMap;
+    const sc::ColRowReorderMapType& mrRowMap;
     SCTAB mnTab;
     SCCOL mnCol1;
     SCCOL mnCol2;
 
 public:
-    RefRowReorderHint( const sc::RowReorderMapType& rRowMap, SCTAB nTab, SCCOL nCol1, SCCOL nCol2 );
+    RefRowReorderHint( const sc::ColRowReorderMapType& rRowMap, SCTAB nTab, SCCOL nCol1, SCCOL nCol2 );
     virtual ~RefRowReorderHint();
 
-    const sc::RowReorderMapType& getRowMap() const;
+    const sc::ColRowReorderMapType& getRowMap() const;
 
     SCTAB getTab() const;
     SCCOL getStartColumn() const;
diff --git a/sc/inc/tokenarray.hxx b/sc/inc/tokenarray.hxx
index 375dd3a..8ae6145 100644
--- a/sc/inc/tokenarray.hxx
+++ b/sc/inc/tokenarray.hxx
@@ -168,9 +168,13 @@ public:
      * @param nRow2 bottom row of reordered range.
      * @param rColMap old-to-new column mapping.
      */
-    void MoveReferenceColReorder( const ScAddress& rPos, SCTAB nTab, SCROW nRow1, SCROW nRow2, const sc::ColReorderMapType& rColMap );
+    void MoveReferenceColReorder(
+        const ScAddress& rPos, SCTAB nTab, SCROW nRow1, SCROW nRow2,
+        const sc::ColRowReorderMapType& rColMap );
 
-    void MoveReferenceRowReorder( const ScAddress& rPos, SCTAB nTab, SCCOL nCol1, SCCOL nCol2, const sc::RowReorderMapType& rRowMap );
+    void MoveReferenceRowReorder(
+        const ScAddress& rPos, SCTAB nTab, SCCOL nCol1, SCCOL nCol2,
+        const sc::ColRowReorderMapType& rRowMap );
 
     /**
      * Adjust all references in named expression. In named expression, we only
diff --git a/sc/inc/types.hxx b/sc/inc/types.hxx
index 976baaf..37784dc 100644
--- a/sc/inc/types.hxx
+++ b/sc/inc/types.hxx
@@ -98,8 +98,7 @@ struct RangeMatrix
     bool isRangeValid() const;
 };
 
-typedef boost::unordered_map<SCCOL,SCCOL> ColReorderMapType;
-typedef boost::unordered_map<SCROW,SCROW> RowReorderMapType;
+typedef boost::unordered_map<SCCOLROW,SCCOLROW> ColRowReorderMapType;
 
 }
 
diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
index b107464..1ffc739 100644
--- a/sc/source/core/data/table3.cxx
+++ b/sc/source/core/data/table3.cxx
@@ -542,8 +542,8 @@ public:
     }
 };
 
-typedef ReorderNotifier<sc::RefColReorderHint, sc::ColReorderMapType, SCROW> ColReorderNotifier;
-typedef ReorderNotifier<sc::RefRowReorderHint, sc::RowReorderMapType, SCROW> RowReorderNotifier;
+typedef ReorderNotifier<sc::RefColReorderHint, sc::ColRowReorderMapType, SCCOL> ColReorderNotifier;
+typedef ReorderNotifier<sc::RefRowReorderHint, sc::ColRowReorderMapType, SCROW> RowReorderNotifier;
 
 class FormulaGroupPosCollector : std::unary_function<SvtListener*, void>
 {
@@ -603,13 +603,13 @@ void ScTable::SortReorderByColumn( ScSortInfoArray* pArray, ScProgress* pProgres
         aCol[nCol].ResetFormulaCellPositions(aSortParam.nRow1, aSortParam.nRow2);
 
     // Set up column reorder map (for later broadcasting of reference updates).
-    sc::ColReorderMapType aColMap;
+    sc::ColRowReorderMapType aColMap;
     const std::vector<SCCOLROW>& rOldIndices = pArray->GetOldIndices();
     for (size_t i = 0, n = rOldIndices.size(); i < n; ++i)
     {
         SCCOL nNew = i + nStart;
         SCCOL nOld = rOldIndices[i];
-        aColMap.insert(sc::ColReorderMapType::value_type(nOld, nNew));
+        aColMap.insert(sc::ColRowReorderMapType::value_type(nOld, nNew));
     }
 
     // Collect all listeners within sorted range ahead of time.
@@ -817,13 +817,13 @@ void ScTable::SortReorderByRow( ScSortInfoArray* pArray, ScProgress* pProgress )
     }
 
     // Set up row reorder map (for later broadcasting of reference updates).
-    sc::RowReorderMapType aRowMap;
+    sc::ColRowReorderMapType aRowMap;
     const std::vector<SCCOLROW>& rOldIndices = pArray->GetOldIndices();
     for (size_t i = 0, n = rOldIndices.size(); i < n; ++i)
     {
         SCROW nNew = i + nRow1;
         SCROW nOld = rOldIndices[i];
-        aRowMap.insert(sc::RowReorderMapType::value_type(nOld, nNew));
+        aRowMap.insert(sc::ColRowReorderMapType::value_type(nOld, nNew));
     }
 
     // Collect all listeners within sorted range ahead of time.
diff --git a/sc/source/core/tool/refhint.cxx b/sc/source/core/tool/refhint.cxx
index 8e5540a..533a41b 100644
--- a/sc/source/core/tool/refhint.cxx
+++ b/sc/source/core/tool/refhint.cxx
@@ -34,12 +34,12 @@ const ScAddress& RefMovedHint::getDelta() const
     return maMoveDelta;
 }
 
-RefColReorderHint::RefColReorderHint( const sc::ColReorderMapType& rColMap, SCTAB nTab, SCROW nRow1, SCROW nRow2 ) :
+RefColReorderHint::RefColReorderHint( const sc::ColRowReorderMapType& rColMap, SCTAB nTab, SCROW nRow1, SCROW nRow2 ) :
     RefHint(ColumnReordered), mrColMap(rColMap), mnTab(nTab), mnRow1(nRow1), mnRow2(nRow2) {}
 
 RefColReorderHint::~RefColReorderHint() {}
 
-const sc::ColReorderMapType& RefColReorderHint::getColMap() const
+const sc::ColRowReorderMapType& RefColReorderHint::getColMap() const
 {
     return mrColMap;
 }
@@ -59,12 +59,12 @@ SCROW RefColReorderHint::getEndRow() const
     return mnRow2;
 }
 
-RefRowReorderHint::RefRowReorderHint( const sc::RowReorderMapType& rRowMap, SCTAB nTab, SCCOL nCol1, SCCOL nCol2 ) :
+RefRowReorderHint::RefRowReorderHint( const sc::ColRowReorderMapType& rRowMap, SCTAB nTab, SCCOL nCol1, SCCOL nCol2 ) :
     RefHint(RowReordered), mrRowMap(rRowMap), mnTab(nTab), mnCol1(nCol1), mnCol2(nCol2) {}
 
 RefRowReorderHint::~RefRowReorderHint() {}
 
-const sc::RowReorderMapType& RefRowReorderHint::getRowMap() const
+const sc::ColRowReorderMapType& RefRowReorderHint::getRowMap() const
 {
     return mrRowMap;
 }
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index 564c38b..99a26a8 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -2900,7 +2900,7 @@ void ScTokenArray::MoveReference(
 }
 
 void ScTokenArray::MoveReferenceColReorder(
-    const ScAddress& rPos, SCTAB nTab, SCROW nRow1, SCROW nRow2, const sc::ColReorderMapType& rColMap )
+    const ScAddress& rPos, SCTAB nTab, SCROW nRow1, SCROW nRow2, const sc::ColRowReorderMapType& rColMap )
 {
     FormulaToken** p = pCode;
     FormulaToken** pEnd = p + static_cast<size_t>(nLen);
@@ -2917,7 +2917,7 @@ void ScTokenArray::MoveReferenceColReorder(
                 if (aAbs.Tab() == nTab && nRow1 <= aAbs.Row() && aAbs.Row() <= nRow2)
                 {
                     // Inside reordered row range.
-                    sc::ColReorderMapType::const_iterator it = rColMap.find(aAbs.Col());
+                    sc::ColRowReorderMapType::const_iterator it = rColMap.find(aAbs.Col());
                     if (it != rColMap.end())
                     {
                         // This column is reordered.
@@ -2945,7 +2945,7 @@ void ScTokenArray::MoveReferenceColReorder(
                 if (aAbs.aStart.Tab() == nTab && nRow1 <= aAbs.aStart.Row() && aAbs.aEnd.Row() <= nRow2)
                 {
                     // Inside reordered row range.
-                    sc::ColReorderMapType::const_iterator it = rColMap.find(aAbs.aStart.Col());
+                    sc::ColRowReorderMapType::const_iterator it = rColMap.find(aAbs.aStart.Col());
                     if (it != rColMap.end())
                     {
                         // This column is reordered.
@@ -2963,7 +2963,7 @@ void ScTokenArray::MoveReferenceColReorder(
     }
 }
 
-void ScTokenArray::MoveReferenceRowReorder( const ScAddress& rPos, SCTAB nTab, SCCOL nCol1, SCCOL nCol2, const sc::RowReorderMapType& rRowMap )
+void ScTokenArray::MoveReferenceRowReorder( const ScAddress& rPos, SCTAB nTab, SCCOL nCol1, SCCOL nCol2, const sc::ColRowReorderMapType& rRowMap )
 {
     FormulaToken** p = pCode;
     FormulaToken** pEnd = p + static_cast<size_t>(nLen);
@@ -2980,7 +2980,7 @@ void ScTokenArray::MoveReferenceRowReorder( const ScAddress& rPos, SCTAB nTab, S
                 if (aAbs.Tab() == nTab && nCol1 <= aAbs.Col() && aAbs.Col() <= nCol2)
                 {
                     // Inside reordered column range.
-                    sc::RowReorderMapType::const_iterator it = rRowMap.find(aAbs.Row());
+                    sc::ColRowReorderMapType::const_iterator it = rRowMap.find(aAbs.Row());
                     if (it != rRowMap.end())
                     {
                         // This column is reordered.
@@ -3008,7 +3008,7 @@ void ScTokenArray::MoveReferenceRowReorder( const ScAddress& rPos, SCTAB nTab, S
                 if (aAbs.aStart.Tab() == nTab && nCol1 <= aAbs.aStart.Col() && aAbs.aEnd.Col() <= nCol2)
                 {
                     // Inside reordered column range.
-                    sc::RowReorderMapType::const_iterator it = rRowMap.find(aAbs.aStart.Row());
+                    sc::ColRowReorderMapType::const_iterator it = rRowMap.find(aAbs.aStart.Row());
                     if (it != rRowMap.end())
                     {
                         // This row is reordered.
commit f2a5d8d8de38f4d578d749fe44727acd7f8bb248
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Fri Jun 27 14:03:18 2014 -0400

    Dis-ambiguate these two MoveReference(...) methods.
    
    Change-Id: I08503b1e8ec20c3a236d4ee823efae84a4be54a1

diff --git a/sc/inc/tokenarray.hxx b/sc/inc/tokenarray.hxx
index 082f152..375dd3a 100644
--- a/sc/inc/tokenarray.hxx
+++ b/sc/inc/tokenarray.hxx
@@ -168,9 +168,9 @@ public:
      * @param nRow2 bottom row of reordered range.
      * @param rColMap old-to-new column mapping.
      */
-    void MoveReference( const ScAddress& rPos, SCTAB nTab, SCROW nRow1, SCROW nRow2, const sc::ColReorderMapType& rColMap );
+    void MoveReferenceColReorder( const ScAddress& rPos, SCTAB nTab, SCROW nRow1, SCROW nRow2, const sc::ColReorderMapType& rColMap );
 
-    void MoveReference( const ScAddress& rPos, SCTAB nTab, SCCOL nCol1, SCCOL nCol2, const sc::RowReorderMapType& rRowMap );
+    void MoveReferenceRowReorder( const ScAddress& rPos, SCTAB nTab, SCCOL nCol1, SCCOL nCol2, const sc::RowReorderMapType& rRowMap );
 
     /**
      * Adjust all references in named expression. In named expression, we only
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index 87b3684..8d9dee1 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -1940,8 +1940,11 @@ void ScFormulaCell::Notify( const SfxHint& rHint )
                 const sc::RefColReorderHint& rRefColReorder =
                     static_cast<const sc::RefColReorderHint&>(rRefHint);
                 if (!IsShared() || IsSharedTop())
-                    pCode->MoveReference(
-                        aPos, rRefColReorder.getTab(), rRefColReorder.getStartRow(), rRefColReorder.getEndRow(), rRefColReorder.getColMap());
+                    pCode->MoveReferenceColReorder(
+                        aPos, rRefColReorder.getTab(),
+                        rRefColReorder.getStartRow(),
+                        rRefColReorder.getEndRow(),
+                        rRefColReorder.getColMap());
             }
             break;
             case sc::RefHint::RowReordered:
@@ -1949,7 +1952,7 @@ void ScFormulaCell::Notify( const SfxHint& rHint )
                 const sc::RefRowReorderHint& rRefRowReorder =
                     static_cast<const sc::RefRowReorderHint&>(rRefHint);
                 if (!IsShared() || IsSharedTop())
-                    pCode->MoveReference(
+                    pCode->MoveReferenceRowReorder(
                         aPos, rRefRowReorder.getTab(),
                         rRefRowReorder.getStartColumn(),
                         rRefRowReorder.getEndColumn(),
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index 5d21dd3..564c38b 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -2899,7 +2899,7 @@ void ScTokenArray::MoveReference(
     }
 }
 
-void ScTokenArray::MoveReference(
+void ScTokenArray::MoveReferenceColReorder(
     const ScAddress& rPos, SCTAB nTab, SCROW nRow1, SCROW nRow2, const sc::ColReorderMapType& rColMap )
 {
     FormulaToken** p = pCode;
@@ -2963,7 +2963,7 @@ void ScTokenArray::MoveReference(
     }
 }
 
-void ScTokenArray::MoveReference( const ScAddress& rPos, SCTAB nTab, SCCOL nCol1, SCCOL nCol2, const sc::RowReorderMapType& rRowMap )
+void ScTokenArray::MoveReferenceRowReorder( const ScAddress& rPos, SCTAB nTab, SCCOL nCol1, SCCOL nCol2, const sc::RowReorderMapType& rRowMap )
 {
     FormulaToken** p = pCode;
     FormulaToken** pEnd = p + static_cast<size_t>(nLen);
commit b4a0886e565ff7fc35bfe7eac6f388de06d33c9d
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Fri Jun 27 12:38:20 2014 -0400

    Make sort a two step process when "copy to range" is specified.
    
    First step is to copy the range from A to B, then sort on B.  This will
    be handled as two commands rather than one.
    
    Change-Id: Ibb1ad7384a3a25337b2b15c67ece90b3d61a6632

diff --git a/sc/source/ui/docshell/dbdocfun.cxx b/sc/source/ui/docshell/dbdocfun.cxx
index a99c0f1..de41cfc 100644
--- a/sc/source/ui/docshell/dbdocfun.cxx
+++ b/sc/source/ui/docshell/dbdocfun.cxx
@@ -473,7 +473,7 @@ bool ScDBDocFunc::Sort( SCTAB nTab, const ScSortParam& rSortParam,
     ScDocument& rDoc = rDocShell.GetDocument();
     if (bRecord && !rDoc.IsUndoEnabled())
         bRecord = false;
-    SCTAB nSrcTab = nTab;
+
     ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer();
 
     ScDBData* pDBData = rDoc.GetDBAtArea( nTab, rSortParam.nCol1, rSortParam.nRow1,
@@ -484,28 +484,25 @@ bool ScDBDocFunc::Sort( SCTAB nTab, const ScSortParam& rSortParam,
         return false;
     }
 
-    ScDBData* pDestData = NULL;
-    ScRange aOldDest;
     bool bCopy = !rSortParam.bInplace;
     if ( bCopy && rSortParam.nDestCol == rSortParam.nCol1 &&
                   rSortParam.nDestRow == rSortParam.nRow1 && rSortParam.nDestTab == nTab )
         bCopy = false;
+
     ScSortParam aLocalParam( rSortParam );
     if ( bCopy )
     {
-        aLocalParam.MoveToDest();
-        if ( !ValidColRow( aLocalParam.nCol2, aLocalParam.nRow2 ) )
-        {
-            if (!bApi)
-                rDocShell.ErrorMessage(STR_PASTE_FULL);
+        // Copy the data range to the destination then move the sort range to it.

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list