[libreoffice/f20] Resolves: rhbz#1164898 and various other Calc sorting issues

Eike Rathke erack at fedoraproject.org
Wed Nov 26 18:04:35 UTC 2014


commit d80a8ee7734643ff6f4f880545fd2460d8f840d9
Author: Eike Rathke <erack at redhat.com>
Date:   Wed Nov 26 18:03:11 2014 +0100

    Resolves: rhbz#1164898 and various other Calc sorting issues
    
    see also fdo#85215, fdo#83765, fdo#79441

 ...dd-a-hidden-configuration-option-to-toggl.patch |  609 ++++++++++++++++++++
 ...nsure-that-formula-broadcasting-works-aft.patch |   71 +++
 ...on-t-adjust-references-wrt-cell-position-.patch |   67 +++
 ...o-not-update-references-in-SortReorderByC.patch |  126 ++++
 ...41-again-and-keep-references-to-other-she.patch |  148 +++++
 0008-fdo-86708-paint-after-Undo-of-Sort.patch      |   52 ++
 libreoffice.spec                                   |   12 +-
 7 files changed, 1083 insertions(+), 2 deletions(-)
---
diff --git a/0001-fdo-81633-Add-a-hidden-configuration-option-to-toggl.patch b/0001-fdo-81633-Add-a-hidden-configuration-option-to-toggl.patch
new file mode 100644
index 0000000..905ce6a
--- /dev/null
+++ b/0001-fdo-81633-Add-a-hidden-configuration-option-to-toggl.patch
@@ -0,0 +1,609 @@
+From 67f3ce3a9df2bc62db5602dd84975047c1137b92 Mon Sep 17 00:00:00 2001
+Message-Id: <67f3ce3a9df2bc62db5602dd84975047c1137b92.1417014697.git.erack at redhat.com>
+From: Kohei Yoshida <kohei.yoshida at collabora.com>
+Date: Thu, 9 Oct 2014 16:21:59 +0100
+Subject: [PATCH 1/8] fdo#81633: Add a hidden configuration option to toggle
+ ref update on sort.
+MIME-Version: 1.0
+Content-Type: multipart/mixed; boundary="------------erAck-patch-parts"
+
+This is a multi-part message in MIME format.
+--------------erAck-patch-parts
+Content-Type: text/plain; charset=UTF-8; format=fixed
+Content-Transfer-Encoding: 8bit
+
+
+This option is defaulted to off for 4.3 for back-compatibility.
+
+Reviewed-on: https://gerrit.libreoffice.org/11902
+Reviewed-by: Muthu Subramanian K <muthusuba at gmail.com>
+Reviewed-by: Eike Rathke <erack at redhat.com>
+Tested-by: Eike Rathke <erack at redhat.com>
+Signed-off-by: Andras Timar <andras.timar at collabora.com>
+
+Conflicts:
+	sc/inc/inputopt.hxx
+	sc/qa/unit/ucalc.cxx
+	sc/source/core/tool/inputopt.cxx
+
+Change-Id: I5ac686e96742df40f7d8ba5ffec23806db2988a6
+(cherry picked from commit c357fb2dbdc54d9ee8471ce4e9f9381e74a6deed)
+Signed-off-by: Andras Timar <andras.timar at collabora.com>
+---
+ .../registry/schema/org/openoffice/Office/Calc.xcs |  10 ++
+ sc/inc/document.hxx                                |   5 +-
+ sc/inc/inputopt.hxx                                |   3 +
+ sc/inc/sc.hrc                                      |   1 +
+ sc/inc/sortparam.hxx                               |   1 +
+ sc/inc/table.hxx                                   |   8 +-
+ sc/qa/unit/ucalc.cxx                               |  10 +-
+ sc/source/core/data/documen3.cxx                   |   5 +-
+ sc/source/core/data/table3.cxx                     | 115 ++++++++++++---------
+ sc/source/core/tool/inputopt.cxx                   |  34 +++---
+ sc/source/ui/app/scmod.cxx                         |   9 +-
+ sc/source/ui/docshell/dbdocfun.cxx                 |   5 +-
+ sc/source/ui/undo/undosort.cxx                     |   2 +
+ 13 files changed, 135 insertions(+), 73 deletions(-)
+
+
+--------------erAck-patch-parts
+Content-Type: text/x-patch; name="0001-fdo-81633-Add-a-hidden-configuration-option-to-toggl.patch"
+Content-Transfer-Encoding: 8bit
+Content-Disposition: attachment; filename="0001-fdo-81633-Add-a-hidden-configuration-option-to-toggl.patch"
+
+diff --git a/officecfg/registry/schema/org/openoffice/Office/Calc.xcs b/officecfg/registry/schema/org/openoffice/Office/Calc.xcs
+index 0cdb9d5..54e15fc 100644
+--- a/officecfg/registry/schema/org/openoffice/Office/Calc.xcs
++++ b/officecfg/registry/schema/org/openoffice/Office/Calc.xcs
+@@ -678,6 +678,16 @@
+         </info>
+         <value>false</value>
+       </prop>
++      <prop oor:name="UpdateReferenceOnSort" oor:type="xs:boolean" oor:nillable="false">
++        <!-- OldPath: Calc/Input -->
++        <!-- OldLocation: Soffice.cfg -->
++        <!-- UIHints: Tools - Options -Spreadsheets - Input - [Section] Input -->
++        <info>
++          <desc>Specifies whether references get updated when performing sort on a range of cells.</desc>
++          <label>Update references when sorting range of cells</label>
++        </info>
++        <value>false</value>
++      </prop>
+       <prop oor:name="HighlightSelection" oor:type="xs:boolean" oor:nillable="false">
+         <!-- OldPath: Calc/Input -->
+         <!-- OldLocation: Soffice.cfg -->
+diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
+index 9d365cc..44107b4 100644
+--- a/sc/inc/document.hxx
++++ b/sc/inc/document.hxx
+@@ -1664,7 +1664,10 @@ public:
+     SC_DLLPUBLIC SvNumberFormatter* GetFormatTable() const;
+     SC_DLLPUBLIC SvNumberFormatter* CreateFormatTable() const;
+ 
+-    void Sort( SCTAB nTab, const ScSortParam& rSortParam, bool bKeepQuery, ScProgress* pProgress, sc::ReorderParam* pUndo );
++    void Sort(
++        SCTAB nTab, const ScSortParam& rSortParam, bool bKeepQuery, bool bUpdateRefs,
++        ScProgress* pProgress, sc::ReorderParam* pUndo );
++
+     void Reorder( const sc::ReorderParam& rParam, ScProgress* pProgress );
+ 
+     SCSIZE          Query( SCTAB nTab, const ScQueryParam& rQueryParam, bool bKeepSub );
+diff --git a/sc/inc/inputopt.hxx b/sc/inc/inputopt.hxx
+index 3a46bf6..3c33154 100644
+--- a/sc/inc/inputopt.hxx
++++ b/sc/inc/inputopt.hxx
+@@ -32,6 +32,7 @@ private:
+     sal_Bool        bExtendFormat;
+     sal_Bool        bRangeFinder;
+     sal_Bool        bExpandRefs;
++    sal_Bool        mbSortRefUpdate;
+     sal_Bool        bMarkHeader;
+     sal_Bool        bUseTabCol;
+     sal_Bool        bTextWysiwyg;
+@@ -57,6 +58,8 @@ public:
+     sal_Bool        GetRangeFinder() const          { return bRangeFinder;   }
+     void        SetExpandRefs(sal_Bool bSet)        { bExpandRefs = bSet;    }
+     sal_Bool        GetExpandRefs() const           { return bExpandRefs;    }
++    void        SetSortRefUpdate(sal_Bool bSet)     { mbSortRefUpdate = bSet; }
++    sal_Bool        GetSortRefUpdate() const        { return mbSortRefUpdate; }
+     void        SetMarkHeader(sal_Bool bSet)        { bMarkHeader = bSet;    }
+     sal_Bool        GetMarkHeader() const           { return bMarkHeader;    }
+     void        SetUseTabCol(sal_Bool bSet)         { bUseTabCol = bSet;     }
+diff --git a/sc/inc/sc.hrc b/sc/inc/sc.hrc
+index 8e517ae..63ff3ba 100644
+--- a/sc/inc/sc.hrc
++++ b/sc/inc/sc.hrc
+@@ -86,6 +86,7 @@
+ 
+ // TabPage entry - Legacy selection
+ #define SID_SC_INPUT_LEGACY_CELL_SELECTION (SC_VIEW_START + 15)
++#define SID_SC_OPT_SORT_REF_UPDATE         (SC_VIEW_START + 16)
+ 
+ // Format options
+ #define SID_SCFORMULAOPTIONS    (SC_VIEW_START + 20)
+diff --git a/sc/inc/sortparam.hxx b/sc/inc/sortparam.hxx
+index 4c3ef1b..b83e941 100644
+--- a/sc/inc/sortparam.hxx
++++ b/sc/inc/sortparam.hxx
+@@ -98,6 +98,7 @@ struct SC_DLLPUBLIC ReorderParam
+     bool mbByRow;
+     bool mbPattern;
+     bool mbHiddenFiltered;
++    bool mbUpdateRefs;
+ 
+     /**
+      * Reorder the position indices such that it can be used to undo the
+diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
+index 191a360..480cc2c 100644
+--- a/sc/inc/table.hxx
++++ b/sc/inc/table.hxx
+@@ -830,7 +830,9 @@ public:
+     void        ExtendHidden( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2 );
+ 
+     void Sort(
+-        const ScSortParam& rSortParam, bool bKeepQuery, ScProgress* pProgress, sc::ReorderParam* pUndo );
++        const ScSortParam& rSortParam, bool bKeepQuery, bool bUpdateRefs,
++        ScProgress* pProgress, sc::ReorderParam* pUndo );
++
+     void Reorder( const sc::ReorderParam& rParam, ScProgress* pProgress );
+ 
+     bool ValidQuery(
+@@ -1007,7 +1009,9 @@ private:
+     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 );
++    ScSortInfoArray* CreateSortInfoArray(
++        const ScSortParam& rSortParam, SCCOLROW nInd1, SCCOLROW nInd2,
++        bool bKeepQuery, bool bUpdateRefs );
+     void        QuickSort( ScSortInfoArray*, SCsCOLROW nLo, SCsCOLROW nHi);
+     void SortReorderByColumn( ScSortInfoArray* pArray, SCROW nRow1, SCROW nRow2, bool bPattern, ScProgress* pProgress );
+     void SortReorderByRow( ScSortInfoArray* pArray, SCCOL nCol1, SCCOL nCol2, ScProgress* pProgress );
+diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
+index fbc2919..1cfff7a 100644
+--- a/sc/qa/unit/ucalc.cxx
++++ b/sc/qa/unit/ucalc.cxx
+@@ -4277,7 +4277,7 @@ void Test::testSortWithFormulaRefs()
+     aSortData.maKeyState[0].bDoSort = true;
+     aSortData.maKeyState[0].nField = 0;
+ 
+-    pDoc->Sort(0, aSortData, false, NULL, NULL);
++    pDoc->Sort(0, aSortData, false, true, NULL, NULL);
+ 
+     nEnd = SAL_N_ELEMENTS( aResults );
+     for ( SCROW i = nStart; i < nEnd; ++i )
+@@ -4313,7 +4313,7 @@ void Test::testSortWithStrings()
+     aParam.maKeyState[0].bAscending = true;
+     aParam.maKeyState[0].nField = 1;
+ 
+-    m_pDoc->Sort(0, aParam, false, NULL, NULL);
++    m_pDoc->Sort(0, aParam, false, true, 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)));
+@@ -4321,7 +4321,7 @@ void Test::testSortWithStrings()
+ 
+     aParam.maKeyState[0].bAscending = false;
+ 
+-    m_pDoc->Sort(0, aParam, false, NULL, NULL);
++    m_pDoc->Sort(0, aParam, false, true, 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)));
+@@ -4367,7 +4367,7 @@ void Test::testSort()
+     aSortData.maKeyState[0].nField = 1;
+     aSortData.maKeyState[0].bAscending = true;
+ 
+-    m_pDoc->Sort(0, aSortData, false, NULL, NULL);
++    m_pDoc->Sort(0, aSortData, false, true, NULL, NULL);
+ 
+     double nVal = m_pDoc->GetValue(1,0,0);
+     ASSERT_DOUBLES_EQUAL(nVal, 1.0);
+@@ -4400,7 +4400,7 @@ void Test::testSort()
+     aSortData.nRow2 = aDataRange.aEnd.Row();
+     aSortData.bHasHeader = true;
+     aSortData.maKeyState[0].nField = 0;
+-    m_pDoc->Sort(0, aSortData, false, NULL, NULL);
++    m_pDoc->Sort(0, aSortData, false, true, 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
+diff --git a/sc/source/core/data/documen3.cxx b/sc/source/core/data/documen3.cxx
+index 75514fd..10c30f6 100644
+--- a/sc/source/core/data/documen3.cxx
++++ b/sc/source/core/data/documen3.cxx
+@@ -1355,13 +1355,14 @@ bool ScDocument::UpdateOutlineRow( SCROW nStartRow, SCROW nEndRow, SCTAB nTab, b
+ }
+ 
+ void ScDocument::Sort(
+-    SCTAB nTab, const ScSortParam& rSortParam, bool bKeepQuery, ScProgress* pProgress, sc::ReorderParam* pUndo )
++    SCTAB nTab, const ScSortParam& rSortParam, bool bKeepQuery, bool bUpdateRefs,
++    ScProgress* pProgress, sc::ReorderParam* pUndo )
+ {
+     if ( ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab] )
+     {
+         bool bOldEnableIdle = IsIdleEnabled();
+         EnableIdle(false);
+-        maTabs[nTab]->Sort(rSortParam, bKeepQuery, pProgress, pUndo);
++        maTabs[nTab]->Sort(rSortParam, bKeepQuery, bUpdateRefs, pProgress, pUndo);
+         EnableIdle(bOldEnableIdle);
+     }
+ }
+diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
+index 946416d..589a9b1 100644
+--- a/sc/source/core/data/table3.cxx
++++ b/sc/source/core/data/table3.cxx
+@@ -261,6 +261,7 @@ private:
+ 
+     std::vector<SCCOLROW> maOrderIndices;
+     bool mbKeepQuery;
++    bool mbUpdateRefs;
+ 
+ public:
+     ScSortInfoArray( sal_uInt16 nSorts, SCCOLROW nInd1, SCCOLROW nInd2 ) :
+@@ -308,6 +309,10 @@ public:
+ 
+     bool IsKeepQuery() const { return mbKeepQuery; }
+ 
++    void SetUpdateRefs( bool b ) { mbUpdateRefs = b; }
++
++    bool IsUpdateRefs() const { return mbUpdateRefs; }
++
+     /**
+      * Call this only during normal sorting, not from reordering.
+      */
+@@ -471,6 +476,7 @@ ScSortInfoArray* ScTable::CreateSortInfoArray( const sc::ReorderParam& rParam )
+ 
+         pArray = new ScSortInfoArray(0, nRow1, nRow2);
+         pArray->SetKeepQuery(rParam.mbHiddenFiltered);
++        pArray->SetUpdateRefs(rParam.mbUpdateRefs);
+ 
+         initDataRows(
+             *pArray, *this, aCol, nCol1, nRow1, nCol2, nRow2,
+@@ -483,19 +489,22 @@ ScSortInfoArray* ScTable::CreateSortInfoArray( const sc::ReorderParam& rParam )
+ 
+         pArray = new ScSortInfoArray(0, nCol1, nCol2);
+         pArray->SetKeepQuery(rParam.mbHiddenFiltered);
++        pArray->SetUpdateRefs(rParam.mbUpdateRefs);
+     }
+ 
+     return pArray;
+ }
+ 
+ ScSortInfoArray* ScTable::CreateSortInfoArray(
+-    const ScSortParam& rSortParam, SCCOLROW nInd1, SCCOLROW nInd2, bool bKeepQuery )
++    const ScSortParam& rSortParam, SCCOLROW nInd1, SCCOLROW nInd2,
++    bool bKeepQuery, bool bUpdateRefs )
+ {
+     sal_uInt16 nUsedSorts = 1;
+     while ( nUsedSorts < rSortParam.GetSortKeyCount() && rSortParam.maKeyState[nUsedSorts].bDoSort )
+         nUsedSorts++;
+     ScSortInfoArray* pArray = new ScSortInfoArray( nUsedSorts, nInd1, nInd2 );
+     pArray->SetKeepQuery(bKeepQuery);
++    pArray->SetUpdateRefs(bUpdateRefs);
+ 
+     if ( rSortParam.bByRow )
+     {
+@@ -737,16 +746,19 @@ void ScTable::SortReorderByColumn(
+         }
+     }
+ 
+-    for (SCCOL nCol = nStart; nCol <= nLast; ++nCol)
+-        aCol[nCol].CollectListeners(aListeners, nRow1, nRow2);
++    if (pArray->IsUpdateRefs())
++    {
++        for (SCCOL nCol = nStart; nCol <= nLast; ++nCol)
++            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, nRow1, nRow2);
+-    std::for_each(aListeners.begin(), aListeners.end(), aFunc);
++        // 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, nRow1, nRow2);
++        std::for_each(aListeners.begin(), aListeners.end(), aFunc);
++    }
+ 
+     // Re-start area listeners on the reordered columns.
+     {
+@@ -1001,39 +1013,51 @@ void ScTable::SortReorderByRow(
+         }
+     }
+ 
+-    // Collect listeners of cell broadcasters.
+-    for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
+-        aCol[nCol].CollectListeners(aListeners, nRow1, nRow2);
++    if (pArray->IsUpdateRefs())
++    {
++        // Collect listeners of cell broadcasters.
++        for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
++            aCol[nCol].CollectListeners(aListeners, nRow1, nRow2);
+ 
+-    // Remove any duplicate listener entries.  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());
++        // Remove any duplicate listener entries.  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());
+ 
+-    // Collect positions of all shared formula cells outside the sorted range,
+-    // and make them unshared before notifying them.
+-    sc::RefQueryFormulaGroup aFormulaGroupPos;
+-    aFormulaGroupPos.setSkipRange(ScRange(nCol1, nRow1, nTab, nCol2, nRow2, nTab));
++        // Collect positions of all shared formula cells outside the sorted range,
++        // and make them unshared before notifying them.
++        sc::RefQueryFormulaGroup aFormulaGroupPos;
++        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();
+-    sc::RefQueryFormulaGroup::TabsType::const_iterator itGroupTab = rGroupTabs.begin(), itGroupTabEnd = rGroupTabs.end();
+-    for (; itGroupTab != itGroupTabEnd; ++itGroupTab)
+-    {
+-        const sc::RefQueryFormulaGroup::ColsType& rCols = itGroupTab->second;
+-        sc::RefQueryFormulaGroup::ColsType::const_iterator itCol = rCols.begin(), itColEnd = rCols.end();
+-        for (; itCol != itColEnd; ++itCol)
++        std::for_each(aListeners.begin(), aListeners.end(), FormulaGroupPosCollector(aFormulaGroupPos));
++        const sc::RefQueryFormulaGroup::TabsType& rGroupTabs = aFormulaGroupPos.getAllPositions();
++        sc::RefQueryFormulaGroup::TabsType::const_iterator itGroupTab = rGroupTabs.begin(), itGroupTabEnd = rGroupTabs.end();
++        for (; itGroupTab != itGroupTabEnd; ++itGroupTab)
++        {
++            const sc::RefQueryFormulaGroup::ColsType& rCols = itGroupTab->second;
++            sc::RefQueryFormulaGroup::ColsType::const_iterator itCol = rCols.begin(), itColEnd = rCols.end();
++            for (; itCol != itColEnd; ++itCol)
++            {
++                const sc::RefQueryFormulaGroup::ColType& rCol = itCol->second;
++                std::vector<SCROW> aBounds(rCol);
++                pDocument->UnshareFormulaCells(itGroupTab->first, itCol->first, aBounds);
++            }
++        }
++
++        // Notify the listeners.
++        RowReorderNotifier aFunc(aRowMap, nTab, nCol1, nCol2);
++        std::for_each(aListeners.begin(), aListeners.end(), aFunc);
++
++        // Re-group formulas in affected columns.
++        for (itGroupTab = rGroupTabs.begin(); itGroupTab != itGroupTabEnd; ++itGroupTab)
+         {
+-            const sc::RefQueryFormulaGroup::ColType& rCol = itCol->second;
+-            std::vector<SCROW> aBounds(rCol);
+-            pDocument->UnshareFormulaCells(itGroupTab->first, itCol->first, aBounds);
++            const sc::RefQueryFormulaGroup::ColsType& rCols = itGroupTab->second;
++            sc::RefQueryFormulaGroup::ColsType::const_iterator itCol = rCols.begin(), itColEnd = rCols.end();
++            for (; itCol != itColEnd; ++itCol)
++                pDocument->RegroupFormulaCells(itGroupTab->first, itCol->first);
+         }
+     }
+ 
+-    // Notify the listeners.
+-    RowReorderNotifier aFunc(aRowMap, nTab, nCol1, nCol2);
+-    std::for_each(aListeners.begin(), aListeners.end(), aFunc);
+-
+     // Re-start area listeners on the reordered rows.
+     {
+         std::vector<sc::AreaListener>::iterator it = aAreaListeners.begin(), itEnd = aAreaListeners.end();
+@@ -1050,15 +1074,6 @@ void ScTable::SortReorderByRow(
+         }
+     }
+ 
+-    // Re-group formulas in affected columns.
+-    for (itGroupTab = rGroupTabs.begin(); itGroupTab != itGroupTabEnd; ++itGroupTab)
+-    {
+-        const sc::RefQueryFormulaGroup::ColsType& rCols = itGroupTab->second;
+-        sc::RefQueryFormulaGroup::ColsType::const_iterator itCol = rCols.begin(), itColEnd = rCols.end();
+-        for (; itCol != itColEnd; ++itCol)
+-            pDocument->RegroupFormulaCells(itGroupTab->first, itCol->first);
+-    }
+-
+     // Re-group columns in the sorted range too.
+     for (SCCOL i = nCol1; i <= nCol2; ++i)
+         aCol[i].RegroupFormulaCells();
+@@ -1281,7 +1296,8 @@ void ScTable::DecoladeRow( ScSortInfoArray* pArray, SCROW nRow1, SCROW nRow2 )
+ }
+ 
+ void ScTable::Sort(
+-    const ScSortParam& rSortParam, bool bKeepQuery, ScProgress* pProgress, sc::ReorderParam* pUndo )
++    const ScSortParam& rSortParam, bool bKeepQuery, bool bUpdateRefs,
++    ScProgress* pProgress, sc::ReorderParam* pUndo )
+ {
+     aSortParam = rSortParam;
+     InitSortCollator( rSortParam );
+@@ -1293,6 +1309,7 @@ void ScTable::Sort(
+         pUndo->mbByRow = rSortParam.bByRow;
+         pUndo->mbPattern = rSortParam.bIncludePattern;
+         pUndo->mbHiddenFiltered = bKeepQuery;
++        pUndo->mbUpdateRefs = bUpdateRefs;
+     }
+ 
+     if (rSortParam.bByRow)
+@@ -1308,7 +1325,7 @@ void ScTable::Sort(
+             if(pProgress)
+                 pProgress->SetState( 0, nLastRow-nRow1 );
+ 
+-            boost::scoped_ptr<ScSortInfoArray> pArray(CreateSortInfoArray(aSortParam, nRow1, nLastRow, bKeepQuery));
++            boost::scoped_ptr<ScSortInfoArray> pArray(CreateSortInfoArray(aSortParam, nRow1, nLastRow, bKeepQuery, bUpdateRefs));
+ 
+             if ( nLastRow - nRow1 > 255 )
+                 DecoladeRow(pArray.get(), nRow1, nLastRow);
+@@ -1337,7 +1354,7 @@ void ScTable::Sort(
+             if(pProgress)
+                 pProgress->SetState( 0, nLastCol-nCol1 );
+ 
+-            boost::scoped_ptr<ScSortInfoArray> pArray(CreateSortInfoArray(aSortParam, nCol1, nLastCol, bKeepQuery));
++            boost::scoped_ptr<ScSortInfoArray> pArray(CreateSortInfoArray(aSortParam, nCol1, nLastCol, bKeepQuery, bUpdateRefs));
+ 
+             QuickSort(pArray.get(), nCol1, nLastCol);
+             SortReorderByColumn(pArray.get(), aSortParam.nRow1, aSortParam.nRow2, aSortParam.bIncludePattern, pProgress);
+@@ -2369,7 +2386,7 @@ void ScTable::TopTenQuery( ScQueryParam& rParam )
+                     bSortCollatorInitialized = true;
+                     InitSortCollator( aLocalSortParam );
+                 }
+-                boost::scoped_ptr<ScSortInfoArray> pArray(CreateSortInfoArray(aSortParam, nRow1, rParam.nRow2, bGlobalKeepQuery));
++                boost::scoped_ptr<ScSortInfoArray> pArray(CreateSortInfoArray(aSortParam, nRow1, rParam.nRow2, bGlobalKeepQuery, false));
+                 DecoladeRow( pArray.get(), nRow1, rParam.nRow2 );
+                 QuickSort( pArray.get(), nRow1, rParam.nRow2 );
+                 ScSortInfo** ppInfo = pArray->GetFirstArray();
+diff --git a/sc/source/core/tool/inputopt.cxx b/sc/source/core/tool/inputopt.cxx
+index e36cd85..756bf9d 100644
+--- a/sc/source/core/tool/inputopt.cxx
++++ b/sc/source/core/tool/inputopt.cxx
+@@ -55,6 +55,7 @@ void ScInputOptions::SetDefaults()
+     bExtendFormat   = false;
+     bRangeFinder    = sal_True;
+     bExpandRefs     = false;
++    mbSortRefUpdate = sal_True;
+     bMarkHeader     = sal_True;
+     bUseTabCol      = false;
+     bTextWysiwyg    = false;
+@@ -70,6 +71,7 @@ const ScInputOptions& ScInputOptions::operator=( const ScInputOptions& rCpy )
+     bExtendFormat   = rCpy.bExtendFormat;
+     bRangeFinder    = rCpy.bRangeFinder;
+     bExpandRefs     = rCpy.bExpandRefs;
++    mbSortRefUpdate = rCpy.mbSortRefUpdate;
+     bMarkHeader     = rCpy.bMarkHeader;
+     bUseTabCol      = rCpy.bUseTabCol;
+     bTextWysiwyg    = rCpy.bTextWysiwyg;
+@@ -83,18 +85,19 @@ const ScInputOptions& ScInputOptions::operator=( const ScInputOptions& rCpy )
+ 
+ #define CFGPATH_INPUT           "Office.Calc/Input"
+ 
+-#define SCINPUTOPT_MOVEDIR                0
+-#define SCINPUTOPT_MOVESEL                1
+-#define SCINPUTOPT_EDTEREDIT              2
+-#define SCINPUTOPT_EXTENDFMT              3
+-#define SCINPUTOPT_RANGEFIND              4
+-#define SCINPUTOPT_EXPANDREFS             5
+-#define SCINPUTOPT_MARKHEADER             6
+-#define SCINPUTOPT_USETABCOL              7
+-#define SCINPUTOPT_TEXTWYSIWYG            8
+-#define SCINPUTOPT_REPLCELLSWARN          9
+-#define SCINPUTOPT_LEGACY_CELL_SELECTION 10
+-#define SCINPUTOPT_COUNT                 11
++#define SCINPUTOPT_MOVEDIR                 0
++#define SCINPUTOPT_MOVESEL                 1
++#define SCINPUTOPT_EDTEREDIT               2
++#define SCINPUTOPT_EXTENDFMT               3
++#define SCINPUTOPT_RANGEFIND               4
++#define SCINPUTOPT_EXPANDREFS              5
++#define SCINPUTOPT_SORT_REF_UPDATE         6
++#define SCINPUTOPT_MARKHEADER              7
++#define SCINPUTOPT_USETABCOL               8
++#define SCINPUTOPT_TEXTWYSIWYG             9
++#define SCINPUTOPT_REPLCELLSWARN          10
++#define SCINPUTOPT_LEGACY_CELL_SELECTION  11
++#define SCINPUTOPT_COUNT                  12
+ 
+ Sequence<OUString> ScInputCfg::GetPropertyNames()
+ {
+@@ -106,6 +109,7 @@ Sequence<OUString> ScInputCfg::GetPropertyNames()
+         "ExpandFormatting",         // SCINPUTOPT_EXTENDFMT
+         "ShowReference",            // SCINPUTOPT_RANGEFIND
+         "ExpandReference",          // SCINPUTOPT_EXPANDREFS
++        "UpdateReferenceOnSort",    // SCINPUTOPT_SORT_REF_UPDATE
+         "HighlightSelection",       // SCINPUTOPT_MARKHEADER
+         "UseTabCol",                // SCINPUTOPT_USETABCOL
+         "UsePrinterMetrics",        // SCINPUTOPT_TEXTWYSIWYG
+@@ -157,6 +161,9 @@ ScInputCfg::ScInputCfg() :
+                     case SCINPUTOPT_EXPANDREFS:
+                         SetExpandRefs( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) );
+                         break;
++                    case SCINPUTOPT_SORT_REF_UPDATE:
++                        SetSortRefUpdate(ScUnoHelpFunctions::GetBoolFromAny(pValues[nProp]));
++                        break;
+                     case SCINPUTOPT_MARKHEADER:
+                         SetMarkHeader( ScUnoHelpFunctions::GetBoolFromAny( pValues[nProp] ) );
+                         break;
+@@ -206,6 +213,9 @@ void ScInputCfg::Commit()
+             case SCINPUTOPT_EXPANDREFS:
+                 ScUnoHelpFunctions::SetBoolInAny( pValues[nProp], GetExpandRefs() );
+                 break;
++            case SCINPUTOPT_SORT_REF_UPDATE:
++                ScUnoHelpFunctions::SetBoolInAny( pValues[nProp], GetSortRefUpdate() );
++                break;
+             case SCINPUTOPT_MARKHEADER:
+                 ScUnoHelpFunctions::SetBoolInAny( pValues[nProp], GetMarkHeader() );
+                 break;
+diff --git a/sc/source/ui/app/scmod.cxx b/sc/source/ui/app/scmod.cxx
+index 61b53c4..5e13cd1 100644
+--- a/sc/source/ui/app/scmod.cxx
++++ b/sc/source/ui/app/scmod.cxx
+@@ -1272,6 +1272,12 @@ void ScModule::ModifyOptions( const SfxItemSet& rOptSet )
+         pInputCfg->SetExpandRefs( ((const SfxBoolItem*)pItem)->GetValue() );
+         bSaveInputOptions = sal_True;
+     }
++    if (rOptSet.HasItem(SID_SC_OPT_SORT_REF_UPDATE, &pItem))
++    {
++        pInputCfg->SetSortRefUpdate(static_cast<const SfxBoolItem*>(pItem)->GetValue());
++        bSaveInputOptions = true;
++    }
++
+     if ( rOptSet.HasItem(SID_SC_INPUT_MARK_HEADER,&pItem) )
+     {
+         pInputCfg->SetMarkHeader( ((const SfxBoolItem*)pItem)->GetValue() );
+@@ -2034,7 +2040,7 @@ SfxItemSet*  ScModule::CreateItemSet( sal_uInt16 nId )
+                             SID_SC_INPUT_SELECTION,SID_SC_INPUT_MARK_HEADER,
+                             SID_SC_INPUT_TEXTWYSIWYG,SID_SC_INPUT_TEXTWYSIWYG,
+                             SID_SC_INPUT_REPLCELLSWARN,SID_SC_INPUT_REPLCELLSWARN,
+-                            SID_SC_INPUT_LEGACY_CELL_SELECTION,SID_SC_INPUT_LEGACY_CELL_SELECTION,
++                            SID_SC_INPUT_LEGACY_CELL_SELECTION,SID_SC_OPT_SORT_REF_UPDATE,
+                             // TP_USERLISTS:
+                             SCITEM_USERLIST,        SCITEM_USERLIST,
+                             // TP_PRINT:
+@@ -2097,6 +2103,7 @@ SfxItemSet*  ScModule::CreateItemSet( sal_uInt16 nId )
+                     rInpOpt.GetRangeFinder() ) );
+         pRet->Put( SfxBoolItem( SID_SC_INPUT_REF_EXPAND,
+                     rInpOpt.GetExpandRefs() ) );
++        pRet->Put( SfxBoolItem(SID_SC_OPT_SORT_REF_UPDATE, rInpOpt.GetSortRefUpdate()));
+         pRet->Put( SfxBoolItem( SID_SC_INPUT_MARK_HEADER,
+                     rInpOpt.GetMarkHeader() ) );
+         pRet->Put( SfxBoolItem( SID_SC_INPUT_TEXTWYSIWYG,
+diff --git a/sc/source/ui/docshell/dbdocfun.cxx b/sc/source/ui/docshell/dbdocfun.cxx
+index aa1e322..9163a84 100644
+--- a/sc/source/ui/docshell/dbdocfun.cxx
++++ b/sc/source/ui/docshell/dbdocfun.cxx
+@@ -48,6 +48,7 @@
+ #include "markdata.hxx"
+ #include "progress.hxx"
+ #include <undosort.hxx>
++#include <inputopt.hxx>
+ 
+ #include <set>
+ #include <memory>
+@@ -517,8 +518,10 @@ sal_Bool ScDBDocFunc::Sort( SCTAB nTab, const ScSortParam& rSortParam,
+     // don't call ScDocument::Sort with an empty SortParam (may be empty here if bCopy is set)
+     if (aLocalParam.GetSortKeyCount() && aLocalParam.maKeyState[0].bDoSort)
+     {
++        ScInputOptions aInputOption = SC_MOD()->GetInputOptions();
++        bool bUpdateRefs = aInputOption.GetSortRefUpdate();
+         ScProgress aProgress(&rDocShell, ScGlobal::GetRscString(STR_PROGRESS_SORTING), 0);
+-        pDoc->Sort(nTab, aLocalParam, bRepeatQuery, &aProgress, &aUndoParam);
++        pDoc->Sort(nTab, aLocalParam, bRepeatQuery, bUpdateRefs, &aProgress, &aUndoParam);
+     }
+ 
+     if (bRecord)
+diff --git a/sc/source/ui/undo/undosort.cxx b/sc/source/ui/undo/undosort.cxx
+index 4ff0960..36156fe 100644
+--- a/sc/source/ui/undo/undosort.cxx
++++ b/sc/source/ui/undo/undosort.cxx
+@@ -48,6 +48,8 @@ void UndoSort::Execute( bool bUndo )
+ 
+     pDocShell->PostPaint(maParam.maSortRange, PAINT_GRID);
+     pDocShell->PostDataChanged();
++    if (!aParam.mbUpdateRefs)
++        rDoc.BroadcastCells(aParam.maSortRange, SC_HINT_DATACHANGED);
+ }
+ 
+ }
+
+--------------erAck-patch-parts--
+
+
diff --git a/0002-fdo-85215-Ensure-that-formula-broadcasting-works-aft.patch b/0002-fdo-85215-Ensure-that-formula-broadcasting-works-aft.patch
new file mode 100644
index 0000000..194c8f9
--- /dev/null
+++ b/0002-fdo-85215-Ensure-that-formula-broadcasting-works-aft.patch
@@ -0,0 +1,71 @@
+From f4c179ea7f69e87e55a416c1588ee0aad7c146c0 Mon Sep 17 00:00:00 2001
+Message-Id: <f4c179ea7f69e87e55a416c1588ee0aad7c146c0.1417014698.git.erack at redhat.com>
+In-Reply-To: <67f3ce3a9df2bc62db5602dd84975047c1137b92.1417014697.git.erack at redhat.com>
+References: <67f3ce3a9df2bc62db5602dd84975047c1137b92.1417014697.git.erack at redhat.com>
+From: Kohei Yoshida <kohei.yoshida at collabora.com>
+Date: Mon, 27 Oct 2014 08:52:38 -0700
+Subject: [PATCH 2/8] fdo#85215: Ensure that formula broadcasting works after
+ sort.
+MIME-Version: 1.0
+Content-Type: multipart/mixed; boundary="------------erAck-patch-parts"
+
+This is a multi-part message in MIME format.
+--------------erAck-patch-parts
+Content-Type: text/plain; charset=UTF-8; format=fixed
+Content-Transfer-Encoding: 8bit
+
+
+When the reference update on sort is turned off.
+
+Change-Id: I547dd1525a638dd447fe331e22583af4a7947308
+(cherry picked from commit 1eb82c78a223d9a0b2bb5c3f5c129c1ee8bdf303)
+Reviewed-on: https://gerrit.libreoffice.org/12113
+Reviewed-by: Michael Meeks <michael.meeks at collabora.com>
+Tested-by: Michael Meeks <michael.meeks at collabora.com>
+---
+ sc/source/core/data/table3.cxx | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+
+--------------erAck-patch-parts
+Content-Type: text/x-patch; name="0002-fdo-85215-Ensure-that-formula-broadcasting-works-aft.patch"
+Content-Transfer-Encoding: 8bit
+Content-Disposition: attachment; filename="0002-fdo-85215-Ensure-that-formula-broadcasting-works-aft.patch"
+
+diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
+index 589a9b1..c36b4cd 100644
+--- a/sc/source/core/data/table3.cxx
++++ b/sc/source/core/data/table3.cxx
+@@ -802,6 +802,15 @@ void ScTable::SortReorderByRow(
+     ScSortInfoArray::RowsType* pRows = pArray->GetDataRows();
+     assert(pRows); // In sort-by-row mode we must have data rows already populated.
+ 
++    if (!pArray->IsUpdateRefs())
++    {
++        // When the update ref mode is disabled, we need to detach all formula
++        // cells in the sorted range before reordering, and re-start them
++        // afterward.
++        sc::EndListeningContext aCxt(*pDocument);
++        DetachFormulaCells(aCxt, nCol1, nRow1, nCol2, nRow2);
++    }
++
+     // Split formula groups at the sort range boundaries (if applicable).
+     std::vector<SCROW> aRowBounds;
+     aRowBounds.reserve(2);
+@@ -1077,6 +1086,12 @@ void ScTable::SortReorderByRow(
+     // Re-group columns in the sorted range too.
+     for (SCCOL i = nCol1; i <= nCol2; ++i)
+         aCol[i].RegroupFormulaCells();
++
++    if (!pArray->IsUpdateRefs())
++    {
++        sc::StartListeningContext aCxt(*pDocument);
++        AttachFormulaCells(aCxt, nCol1, nRow1, nCol2, nRow2);
++    }
+ }
+ 
+ short ScTable::CompareCell(
+
+--------------erAck-patch-parts--
+
+
diff --git a/0005-fdo-85215-Don-t-adjust-references-wrt-cell-position-.patch b/0005-fdo-85215-Don-t-adjust-references-wrt-cell-position-.patch
new file mode 100644
index 0000000..d8ea05c
--- /dev/null
+++ b/0005-fdo-85215-Don-t-adjust-references-wrt-cell-position-.patch
@@ -0,0 +1,67 @@
+From 1f0bca308e677a3e7a75837f93f14b679f698846 Mon Sep 17 00:00:00 2001
+Message-Id: <1f0bca308e677a3e7a75837f93f14b679f698846.1417014698.git.erack at redhat.com>
+In-Reply-To: <67f3ce3a9df2bc62db5602dd84975047c1137b92.1417014697.git.erack at redhat.com>
+References: <67f3ce3a9df2bc62db5602dd84975047c1137b92.1417014697.git.erack at redhat.com>
+From: Kohei Yoshida <kohei.yoshida at collabora.com>
+Date: Sun, 26 Oct 2014 14:43:14 -0700
+Subject: [PATCH 5/8] fdo#85215: Don't adjust references wrt cell position when
+ disabled.
+MIME-Version: 1.0
+Content-Type: multipart/mixed; boundary="------------erAck-patch-parts"
+
+This is a multi-part message in MIME format.
+--------------erAck-patch-parts
+Content-Type: text/plain; charset=UTF-8; format=fixed
+Content-Transfer-Encoding: 8bit
+
+
+Change-Id: Ie1a12cc189bcb66fad59ea9901ac0dc95bb68788
+(cherry picked from commit 10fc138307afb4b39baddb0d56eb8e986e5d29ea)
+Signed-off-by: Eike Rathke <erack at redhat.com>
+---
+ sc/source/core/data/table3.cxx | 7 +++++--
+ sc/source/ui/undo/undosort.cxx | 3 +--
+ 2 files changed, 6 insertions(+), 4 deletions(-)
+
+
+--------------erAck-patch-parts
+Content-Type: text/x-patch; name="0005-fdo-85215-Don-t-adjust-references-wrt-cell-position-.patch"
+Content-Transfer-Encoding: 8bit
+Content-Disposition: attachment; filename="0005-fdo-85215-Don-t-adjust-references-wrt-cell-position-.patch"
+
+diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
+index c36b4cd..d646678 100644
+--- a/sc/source/core/data/table3.cxx
++++ b/sc/source/core/data/table3.cxx
+@@ -864,8 +864,11 @@ void ScTable::SortReorderByRow(
+                     ScAddress aOldPos = rCell.maCell.mpFormula->aPos;
+ 
+                     ScFormulaCell* pNew = rCell.maCell.mpFormula->Clone( aCellPos, SC_CLONECELL_DEFAULT);
+-                    pNew->CopyAllBroadcasters(*rCell.maCell.mpFormula);
+-                    pNew->GetCode()->AdjustReferenceOnMovedOrigin(aOldPos, aCellPos);
++                    if (pArray->IsUpdateRefs())
++                    {
++                        pNew->CopyAllBroadcasters(*rCell.maCell.mpFormula);
++                        pNew->GetCode()->AdjustReferenceOnMovedOrigin(aOldPos, aCellPos);
++                    }
+ 
+                     sc::CellStoreType::iterator itBlk = rCellStore.push_back(pNew);
+                 }
+diff --git a/sc/source/ui/undo/undosort.cxx b/sc/source/ui/undo/undosort.cxx
+index 36156fe..4a00707 100644
+--- a/sc/source/ui/undo/undosort.cxx
++++ b/sc/source/ui/undo/undosort.cxx
+@@ -46,8 +46,7 @@ void UndoSort::Execute( bool bUndo )
+ 
+     ScUndoUtil::MarkSimpleBlock(pDocShell, maParam.maSortRange);
+ 
+-    pDocShell->PostPaint(maParam.maSortRange, PAINT_GRID);
+-    pDocShell->PostDataChanged();
++    rDoc.SetDirty(maParam.maSortRange);
+     if (!aParam.mbUpdateRefs)
+         rDoc.BroadcastCells(aParam.maSortRange, SC_HINT_DATACHANGED);
+ }
+
+--------------erAck-patch-parts--
+
+
diff --git a/0006-fdo-83765-do-not-update-references-in-SortReorderByC.patch b/0006-fdo-83765-do-not-update-references-in-SortReorderByC.patch
new file mode 100644
index 0000000..dfab7d7
--- /dev/null
+++ b/0006-fdo-83765-do-not-update-references-in-SortReorderByC.patch
@@ -0,0 +1,126 @@
+From e44d09160038c7cf661e23885a0997d54ca01752 Mon Sep 17 00:00:00 2001
+Message-Id: <e44d09160038c7cf661e23885a0997d54ca01752.1417014698.git.erack at redhat.com>
+In-Reply-To: <67f3ce3a9df2bc62db5602dd84975047c1137b92.1417014697.git.erack at redhat.com>
+References: <67f3ce3a9df2bc62db5602dd84975047c1137b92.1417014697.git.erack at redhat.com>
+From: Eike Rathke <erack at redhat.com>
+Date: Mon, 17 Nov 2014 22:44:56 +0100
+Subject: [PATCH 6/8] fdo#83765 do not update references in
+ SortReorderByColumn() if disabled
+MIME-Version: 1.0
+Content-Type: multipart/mixed; boundary="------------erAck-patch-parts"
+
+This is a multi-part message in MIME format.
+--------------erAck-patch-parts
+Content-Type: text/plain; charset=UTF-8; format=fixed
+Content-Transfer-Encoding: 8bit
+
+
+Similar to SortReorderByRow()
+
+(cherry picked from commit 115a4b7ca36f65d93070d2e81048320d202e87a3)
+
+Conflicts:
+	sc/inc/column.hxx
+
+Change-Id: I2d2fe243c91a663b14e5bd75ee30225d1b8073da
+Reviewed-on: https://gerrit.libreoffice.org/13117
+Reviewed-by: Kohei Yoshida <libreoffice at kohei.us>
+Tested-by: Kohei Yoshida <libreoffice at kohei.us>
+---
+ sc/inc/column.hxx               | 12 +++++++-----
+ sc/source/core/data/column4.cxx | 10 ++++++----
+ sc/source/core/data/table3.cxx  |  3 ++-
+ 3 files changed, 15 insertions(+), 10 deletions(-)
+
+
+--------------erAck-patch-parts
+Content-Type: text/x-patch; name="0006-fdo-83765-do-not-update-references-in-SortReorderByC.patch"
+Content-Transfer-Encoding: 8bit
+Content-Disposition: attachment; filename="0006-fdo-83765-do-not-update-references-in-SortReorderByC.patch"
+
+diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
+index 66cd524..4bda39d 100644
+--- a/sc/inc/column.hxx
++++ b/sc/inc/column.hxx
+@@ -575,18 +575,20 @@ public:
+ 
+     /**
+      * Reset column position of formula cells within specified row range.
+-     * Reference positions are also adjusted to reflect the new position so
+-     * that the formula cells still reference the same cells or ranges after
+-     * the the position change.  The position of a formula cell before the
+-     * call is interpreted as the old position of that cell.
++     * If bUpdateRefs==true then reference positions are also adjusted to
++     * reflect the new position so that the formula cells still reference the
++     * same cells or ranges after the the position change.
++     * The position of a formula cell before the call is interpreted as the old
++     * position of that cell.
+      *
+      * Caller needs to ensure that no formula groups cross the top and bottom
+      * row boundaries.
+      *
+      * @param nRow1 top row boundary
+      * @param nRow2 bottom row boundary
++     * @param bUpdateRefs whether to adjust references
+      */
+-    void ResetFormulaCellPositions( SCROW nRow1, SCROW nRow2 );
++    void ResetFormulaCellPositions( SCROW nRow1, SCROW nRow2, bool bUpdateRefs );
+ 
+     void SplitFormulaGroupByRelativeRef( const ScRange& rBoundRange );
+ 
+diff --git a/sc/source/core/data/column4.cxx b/sc/source/core/data/column4.cxx
+index 8b46e74..568b5b64 100644
+--- a/sc/source/core/data/column4.cxx
++++ b/sc/source/core/data/column4.cxx
+@@ -439,8 +439,9 @@ namespace {
+ class FormulaColPosSetter
+ {
+     SCCOL mnCol;
++    bool  mbUpdateRefs;
+ public:
+-    FormulaColPosSetter( SCCOL nCol ) : mnCol(nCol) {}
++    FormulaColPosSetter( SCCOL nCol, bool bUpdateRefs ) : mnCol(nCol), mbUpdateRefs(bUpdateRefs) {}
+ 
+     void operator() ( size_t nRow, ScFormulaCell* pCell )
+     {
+@@ -451,7 +452,8 @@ public:
+             ScAddress aOldPos = pCell->aPos;
+             pCell->aPos.SetCol(mnCol);
+             pCell->aPos.SetRow(nRow);
+-            pCell->GetCode()->AdjustReferenceOnMovedOrigin(aOldPos, pCell->aPos);
++            if (mbUpdateRefs)
++                pCell->GetCode()->AdjustReferenceOnMovedOrigin(aOldPos, pCell->aPos);
+         }
+         else
+         {
+@@ -463,9 +465,9 @@ public:
+ 
+ }
+ 
+-void ScColumn::ResetFormulaCellPositions( SCROW nRow1, SCROW nRow2 )
++void ScColumn::ResetFormulaCellPositions( SCROW nRow1, SCROW nRow2, bool bUpdateRefs )
+ {
+-    FormulaColPosSetter aFunc(nCol);
++    FormulaColPosSetter aFunc(nCol, bUpdateRefs);
+     sc::ProcessFormula(maCells.begin(), maCells, nRow1, nRow2, aFunc);
+ }
+ 
+diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
+index d646678..99d6239 100644
+--- a/sc/source/core/data/table3.cxx
++++ b/sc/source/core/data/table3.cxx
+@@ -716,8 +716,9 @@ void ScTable::SortReorderByColumn(
+     }
+ 
+     // Reset formula cell positions which became out-of-sync after column reordering.
++    bool bUpdateRefs = pArray->IsUpdateRefs();
+     for (SCCOL nCol = nStart; nCol <= nLast; ++nCol)
+-        aCol[nCol].ResetFormulaCellPositions(nRow1, nRow2);
++        aCol[nCol].ResetFormulaCellPositions(nRow1, nRow2, bUpdateRefs);
+ 
+     // Set up column reorder map (for later broadcasting of reference updates).
+     sc::ColRowReorderMapType aColMap;
+
+--------------erAck-patch-parts--
+
+
diff --git a/0007-fix-fdo-79441-again-and-keep-references-to-other-she.patch b/0007-fix-fdo-79441-again-and-keep-references-to-other-she.patch
new file mode 100644
index 0000000..7ed811e
--- /dev/null
+++ b/0007-fix-fdo-79441-again-and-keep-references-to-other-she.patch
@@ -0,0 +1,148 @@
+From 094b19c2759c8ecc88b38d37047e9ac2de9b68ee Mon Sep 17 00:00:00 2001
+Message-Id: <094b19c2759c8ecc88b38d37047e9ac2de9b68ee.1417014698.git.erack at redhat.com>
+In-Reply-To: <67f3ce3a9df2bc62db5602dd84975047c1137b92.1417014697.git.erack at redhat.com>
+References: <67f3ce3a9df2bc62db5602dd84975047c1137b92.1417014697.git.erack at redhat.com>
+From: Eike Rathke <erack at redhat.com>
+Date: Mon, 24 Nov 2014 23:29:32 +0100
+Subject: [PATCH 7/8] fix fdo#79441 again and keep references to other sheets
+ during sort
+MIME-Version: 1.0
+Content-Type: multipart/mixed; boundary="------------erAck-patch-parts"
+
+This is a multi-part message in MIME format.
+--------------erAck-patch-parts
+Content-Type: text/plain; charset=UTF-8; format=fixed
+Content-Transfer-Encoding: 8bit
+
+
+... also if other references are not updated. References to other sheets
+are never to be treated as relative during sort, they are always
+absolute, even if they have relative row/column part references.
+
+Broken again during the big sort mess. Even if there was a unit test,
+which didn't help as it got disabled / adapted to the change..
+
+(cherry picked from commit f0e7364603c9566bc158303c515c3274ccba62ca)
+
+Backported.
+
+Change-Id: Ic0e61c5e1cb0728e20725c29e450ab0eb55c3305
+Reviewed-on: https://gerrit.libreoffice.org/13118
+Reviewed-by: Kohei Yoshida <libreoffice at kohei.us>
+Tested-by: Kohei Yoshida <libreoffice at kohei.us>
+---
+ sc/inc/tokenarray.hxx           |  6 ++++++
+ sc/source/core/data/column4.cxx |  2 ++
+ sc/source/core/data/table3.cxx  |  4 ++++
+ sc/source/core/tool/token.cxx   | 43 +++++++++++++++++++++++++++++++++++++++++
+ 4 files changed, 55 insertions(+)
+
+
+--------------erAck-patch-parts
+Content-Type: text/x-patch; name="0007-fix-fdo-79441-again-and-keep-references-to-other-she.patch"
+Content-Transfer-Encoding: 8bit
+Content-Disposition: attachment; filename="0007-fix-fdo-79441-again-and-keep-references-to-other-she.patch"
+
+diff --git a/sc/inc/tokenarray.hxx b/sc/inc/tokenarray.hxx
+index fbb613c..75451e1 100644
+--- a/sc/inc/tokenarray.hxx
++++ b/sc/inc/tokenarray.hxx
+@@ -208,6 +208,12 @@ public:
+     void AdjustReferenceOnMovedOrigin( const ScAddress& rOldPos, const ScAddress& rNewPos );
+ 
+     /**
++     * Adjust all internal references on base position change if they point to
++     * a sheet other than the one of rOldPos.
++     */
++    void AdjustReferenceOnMovedOriginIfOtherSheet( const ScAddress& rOldPos, const ScAddress& rNewPos );
++
++    /**
+      * Clear sheet deleted flag from internal reference tokens if the sheet
+      * index falls within specified range.  Note that when a reference is on a
+      * sheet that's been deleted, its referenced sheet index retains the
+diff --git a/sc/source/core/data/column4.cxx b/sc/source/core/data/column4.cxx
+index 568b5b64..10bec05 100644
+--- a/sc/source/core/data/column4.cxx
++++ b/sc/source/core/data/column4.cxx
+@@ -454,6 +454,8 @@ public:
+             pCell->aPos.SetRow(nRow);
+             if (mbUpdateRefs)
+                 pCell->GetCode()->AdjustReferenceOnMovedOrigin(aOldPos, pCell->aPos);
++            else
++                pCell->GetCode()->AdjustReferenceOnMovedOriginIfOtherSheet(aOldPos, pCell->aPos);
+         }
+         else
+         {
+diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
+index 99d6239..e49a4dc 100644
+--- a/sc/source/core/data/table3.cxx
++++ b/sc/source/core/data/table3.cxx
+@@ -870,6 +870,10 @@ void ScTable::SortReorderByRow(
+                         pNew->CopyAllBroadcasters(*rCell.maCell.mpFormula);
+                         pNew->GetCode()->AdjustReferenceOnMovedOrigin(aOldPos, aCellPos);
+                     }
++                    else
++                    {
++                        pNew->GetCode()->AdjustReferenceOnMovedOriginIfOtherSheet(aOldPos, aCellPos);
++                    }
+ 
+                     sc::CellStoreType::iterator itBlk = rCellStore.push_back(pNew);
+                 }
+diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
+index 03ecc49..f561614 100644
+--- a/sc/source/core/tool/token.cxx
++++ b/sc/source/core/tool/token.cxx
+@@ -3548,6 +3548,49 @@ void ScTokenArray::AdjustReferenceOnMovedOrigin( const ScAddress& rOldPos, const
+     }
+ }
+ 
++void ScTokenArray::AdjustReferenceOnMovedOriginIfOtherSheet( const ScAddress& rOldPos, const ScAddress& rNewPos )
++{
++    FormulaToken** p = pCode;
++    FormulaToken** pEnd = p + static_cast<size_t>(nLen);
++    for (; p != pEnd; ++p)
++    {
++        bool bAdjust = false;
++        switch ((*p)->GetType())
++        {
++            case svExternalSingleRef:
++                bAdjust = true;     // always
++                // fallthru
++            case svSingleRef:
++            {
++                ScToken* pToken = static_cast<ScToken*>(*p);
++                ScSingleRefData& rRef = pToken->GetSingleRef();
++                ScAddress aAbs = rRef.toAbs(rOldPos);
++                if (!bAdjust)
++                    bAdjust = (aAbs.Tab() != rOldPos.Tab());
++                if (bAdjust)
++                    rRef.SetAddress(aAbs, rNewPos);
++            }
++            break;
++            case svExternalDoubleRef:
++                bAdjust = true;     // always
++                // fallthru
++            case svDoubleRef:
++            {
++                ScToken* pToken = static_cast<ScToken*>(*p);
++                ScComplexRefData& rRef = pToken->GetDoubleRef();
++                ScRange aAbs = rRef.toAbs(rOldPos);
++                if (!bAdjust)
++                    bAdjust = (rOldPos.Tab() < aAbs.aStart.Tab() || aAbs.aEnd.Tab() < rOldPos.Tab());
++                if (bAdjust)
++                    rRef.SetRange(aAbs, rNewPos);
++            }
++            break;
++            default:
++                ;
++        }
++    }
++}
++
+ namespace {
+ 
+ void clearTabDeletedFlag( ScSingleRefData& rRef, const ScAddress& rPos, SCTAB nStartTab, SCTAB nEndTab )
+
+--------------erAck-patch-parts--
+
+
diff --git a/0008-fdo-86708-paint-after-Undo-of-Sort.patch b/0008-fdo-86708-paint-after-Undo-of-Sort.patch
new file mode 100644
index 0000000..858b697
--- /dev/null
+++ b/0008-fdo-86708-paint-after-Undo-of-Sort.patch
@@ -0,0 +1,52 @@
+From 57d68a12a7f8c8ac1e60eda33a9f96ce3bca75c2 Mon Sep 17 00:00:00 2001
+Message-Id: <57d68a12a7f8c8ac1e60eda33a9f96ce3bca75c2.1417014698.git.erack at redhat.com>
+In-Reply-To: <67f3ce3a9df2bc62db5602dd84975047c1137b92.1417014697.git.erack at redhat.com>
+References: <67f3ce3a9df2bc62db5602dd84975047c1137b92.1417014697.git.erack at redhat.com>
+From: Eike Rathke <erack at redhat.com>
+Date: Tue, 25 Nov 2014 19:02:08 +0100
+Subject: [PATCH 8/8] fdo#86708 paint after Undo of Sort
+MIME-Version: 1.0
+Content-Type: multipart/mixed; boundary="------------erAck-patch-parts"
+
+This is a multi-part message in MIME format.
+--------------erAck-patch-parts
+Content-Type: text/plain; charset=UTF-8; format=fixed
+Content-Transfer-Encoding: 8bit
+
+
+Regression of 10fc138307afb4b39baddb0d56eb8e986e5d29ea that exchanged
+the PostPaint with SetDirty, but the paint is also needed.
+
+Change-Id: Ic3e81fa106f405568effaed71ab33b575b4c5c5c
+(cherry picked from commit 5cec4ea827570a5bb0a368025f3733b841107d07)
+Reviewed-on: https://gerrit.libreoffice.org/13123
+Reviewed-by: Andras Timar <andras.timar at collabora.com>
+Tested-by: Andras Timar <andras.timar at collabora.com>
+---
+ sc/source/ui/undo/undosort.cxx | 3 +++
+ 1 file changed, 3 insertions(+)
+
+
+--------------erAck-patch-parts
+Content-Type: text/x-patch; name="0008-fdo-86708-paint-after-Undo-of-Sort.patch"
+Content-Transfer-Encoding: 8bit
+Content-Disposition: attachment; filename="0008-fdo-86708-paint-after-Undo-of-Sort.patch"
+
+diff --git a/sc/source/ui/undo/undosort.cxx b/sc/source/ui/undo/undosort.cxx
+index 4a00707..f86bdc2 100644
+--- a/sc/source/ui/undo/undosort.cxx
++++ b/sc/source/ui/undo/undosort.cxx
+@@ -49,6 +49,9 @@ void UndoSort::Execute( bool bUndo )
+     rDoc.SetDirty(maParam.maSortRange);
+     if (!aParam.mbUpdateRefs)
+         rDoc.BroadcastCells(aParam.maSortRange, SC_HINT_DATACHANGED);
++
++    pDocShell->PostPaint(maParam.maSortRange, PAINT_GRID);
++    pDocShell->PostDataChanged();
+ }
+ 
+ }
+
+--------------erAck-patch-parts--
+
+
diff --git a/libreoffice.spec b/libreoffice.spec
index f219f09..96b4c9e 100644
--- a/libreoffice.spec
+++ b/libreoffice.spec
@@ -326,6 +326,12 @@ Patch70: 0001-impress-tables-are-not-interactively-growing.patch
 Patch71: 0001-Resolves-fdo-86449-backport-rtf-fixes.patch
 Patch72: 0002-Resolves-fdo-86451-guard-all-the-tops-post-pop.patch
 Patch73: 0001-rhbz-1167250-Avoid-X11Clipboard-already-being-destro.patch
+Patch74: 0001-fdo-81633-Add-a-hidden-configuration-option-to-toggl.patch
+Patch75: 0002-fdo-85215-Ensure-that-formula-broadcasting-works-aft.patch
+Patch76: 0005-fdo-85215-Don-t-adjust-references-wrt-cell-position-.patch
+Patch77: 0006-fdo-83765-do-not-update-references-in-SortReorderByC.patch
+Patch78: 0007-fix-fdo-79441-again-and-keep-references-to-other-she.patch
+Patch79: 0008-fdo-86708-paint-after-Undo-of-Sort.patch
 
 %define instdir %{_libdir}
 %define baseinstdir %{instdir}/libreoffice
@@ -2267,8 +2273,10 @@ update-desktop-database %{_datadir}/applications &> /dev/null || :
 %endif
 
 %changelog
-* Mon Nov 24 2014 Stephan Bergmann <sbergman at redhat.com>  - 1:4.2.7.2.-10-UNBUILT
-- Resolves: fdo#1167250 Crash in clipboard code
+* Wed Nov 26 2014 Eike Rathke <erack at redhat.com> - 1:4.2.7.2-10
+- Resolves: rhbz#1167250 Crash in clipboard code
+- Resolves: rhbz#1164898 and various other Calc sorting issues
+-           see also fdo#85215, fdo#83765, fdo#79441
 
 * Wed Nov 19 2014 Caolán McNamara <caolanm at redhat.com> - 1:4.2.7.2-9
 - Resolves: rhbz#1165740 arbitrarily backport some rtf crash fixes


More information about the scm-commits mailing list