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

Eike Rathke erack at redhat.com
Tue Dec 2 05:57:21 PST 2014


 sc/inc/column.hxx                   |    2 
 sc/inc/document.hxx                 |    2 
 sc/inc/refhint.hxx                  |   18 ++
 sc/inc/table.hxx                    |    2 
 sc/source/core/data/column.cxx      |   19 ++
 sc/source/core/data/document.cxx    |    4 
 sc/source/core/data/formulacell.cxx |   10 +
 sc/source/core/data/table2.cxx      |    4 
 sc/source/core/data/table3.cxx      |  245 +++++++++++++++++++++++-------------
 sc/source/core/tool/refhint.cxx     |    6 
 sc/source/ui/docshell/dbdocfun.cxx  |    2 
 11 files changed, 221 insertions(+), 93 deletions(-)

New commits:
commit e119f3883513aeaa49f332362620e955dc8b453f
Author: Eike Rathke <erack at redhat.com>
Date:   Tue Dec 2 14:53:53 2014 +0100

    fdo#86762 re-establish listeners on moved broadcasters
    
    ...  also in SortReorderByColumn() similar to SortReorderByRow()
    
    Change-Id: I7665dcc90d70fcf3b08bef0adb9ab6aaff1cdcdf

diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
index 857850f..280cb32 100644
--- a/sc/source/core/data/table3.cxx
+++ b/sc/source/core/data/table3.cxx
@@ -715,6 +715,28 @@ void ScTable::SortReorderByColumn(
     for (SCCOL nCol = nStart; nCol <= nLast; ++nCol)
         aCol[nCol].SplitFormulaGroupByRelativeRef(aSortRange);
 
+    // Collect all listeners of cell broadcasters of sorted range.
+    std::vector<SvtListener*> aCellListeners;
+
+    if (!pArray->IsUpdateRefs())
+    {
+        // Collect listeners of cell broadcasters.
+        for (SCCOL nCol = nStart; nCol <= nLast; ++nCol)
+            aCol[nCol].CollectListeners(aCellListeners, nRow1, nRow2);
+
+        // Remove any duplicate listener entries.  We must ensure that we
+        // notify each unique listener only once.
+        std::sort(aCellListeners.begin(), aCellListeners.end());
+        aCellListeners.erase(std::unique(aCellListeners.begin(), aCellListeners.end()), aCellListeners.end());
+
+        // Notify the cells' listeners to stop listening.
+        /* TODO: for performance this could be enhanced to stop and later
+         * restart only listening to within the reordered range and keep
+         * listening to everything outside untouched. */
+        StopListeningNotifier aFunc;
+        std::for_each(aCellListeners.begin(), aCellListeners.end(), aFunc);
+    }
+
     // 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)
@@ -743,38 +765,38 @@ void ScTable::SortReorderByColumn(
     for (SCCOL nCol = nStart; nCol <= nLast; ++nCol)
         aCol[nCol].ResetFormulaCellPositions(nRow1, nRow2, bUpdateRefs);
 
-    // Set up column reorder map (for later broadcasting of reference updates).
-    sc::ColRowReorderMapType aColMap;
-    const std::vector<SCCOLROW>& rOldIndices = pArray->GetOrderIndices();
-    for (size_t i = 0, n = rOldIndices.size(); i < n; ++i)
-    {
-        SCCOL nNew = i + nStart;
-        SCCOL nOld = rOldIndices[i];
-        aColMap.insert(sc::ColRowReorderMapType::value_type(nOld, nNew));
-    }
-
-    // Collect all listeners within sorted range ahead of time.
-    std::vector<SvtListener*> aListeners;
-
-    // Get all area listeners that listen on one column within the range and
-    // end their listening.
-    ScRange aMoveRange( nStart, nRow1, nTab, nLast, nRow2, nTab);
-    std::vector<sc::AreaListener> aAreaListeners = pDocument->GetBASM()->GetAllListeners(
-            aMoveRange, sc::OneColumnInsideArea);
+    if (pArray->IsUpdateRefs())
     {
-        std::vector<sc::AreaListener>::iterator it = aAreaListeners.begin(), itEnd = aAreaListeners.end();
-        for (; it != itEnd; ++it)
+        // Set up column reorder map (for later broadcasting of reference updates).
+        sc::ColRowReorderMapType aColMap;
+        const std::vector<SCCOLROW>& rOldIndices = pArray->GetOrderIndices();
+        for (size_t i = 0, n = rOldIndices.size(); i < n; ++i)
         {
-            pDocument->EndListeningArea(it->maArea, it->mbGroupListening, it->mpListener);
-            aListeners.push_back( it->mpListener);
+            SCCOL nNew = i + nStart;
+            SCCOL nOld = rOldIndices[i];
+            aColMap.insert(sc::ColRowReorderMapType::value_type(nOld, nNew));
         }
-    }
 
-    if (pArray->IsUpdateRefs())
-    {
+        // Collect all listeners within sorted range ahead of time.
+        std::vector<SvtListener*> aListeners;
+
         for (SCCOL nCol = nStart; nCol <= nLast; ++nCol)
             aCol[nCol].CollectListeners(aListeners, nRow1, nRow2);
 
+        // Get all area listeners that listen on one column within the range
+        // and end their listening.
+        ScRange aMoveRange( nStart, nRow1, nTab, nLast, nRow2, nTab);
+        std::vector<sc::AreaListener> aAreaListeners = pDocument->GetBASM()->GetAllListeners(
+                aMoveRange, sc::OneColumnInsideArea);
+        {
+            std::vector<sc::AreaListener>::iterator it = aAreaListeners.begin(), itEnd = aAreaListeners.end();
+            for (; it != itEnd; ++it)
+            {
+                pDocument->EndListeningArea(it->maArea, it->mbGroupListening, it->mpListener);
+                aListeners.push_back( it->mpListener);
+            }
+        }
+
         // Remove any duplicate listener entries and notify all listeners
         // afterward.  We must ensure that we notify each unique listener only
         // once.
@@ -782,23 +804,29 @@ void ScTable::SortReorderByColumn(
         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.
-    {
-        std::vector<sc::AreaListener>::iterator it = aAreaListeners.begin(), itEnd = aAreaListeners.end();
-        for (; it != itEnd; ++it)
+        // Re-start area listeners on the reordered columns.
         {
-            ScRange aNewRange = it->maArea;
-            sc::ColRowReorderMapType::const_iterator itCol = aColMap.find( aNewRange.aStart.Col());
-            if (itCol != aColMap.end())
+            std::vector<sc::AreaListener>::iterator it = aAreaListeners.begin(), itEnd = aAreaListeners.end();
+            for (; it != itEnd; ++it)
             {
-                aNewRange.aStart.SetCol( itCol->second);
-                aNewRange.aEnd.SetCol( itCol->second);
+                ScRange aNewRange = it->maArea;
+                sc::ColRowReorderMapType::const_iterator itCol = aColMap.find( aNewRange.aStart.Col());
+                if (itCol != aColMap.end())
+                {
+                    aNewRange.aStart.SetCol( itCol->second);
+                    aNewRange.aEnd.SetCol( itCol->second);
+                }
+                pDocument->StartListeningArea(aNewRange, it->mbGroupListening, it->mpListener);
             }
-            pDocument->StartListeningArea(aNewRange, it->mbGroupListening, it->mpListener);
         }
     }
+    else    // !(pArray->IsUpdateRefs())
+    {
+        // Notify the cells' listeners to (re-)start listening.
+        StartListeningNotifier aFunc;
+        std::for_each(aCellListeners.begin(), aCellListeners.end(), aFunc);
+    }
 
     // Re-join formulas at row boundaries now that all the references have
     // been adjusted for column reordering.
commit 08793e08c7e9cefe594c49130f782725e386c463
Author: Eike Rathke <erack at redhat.com>
Date:   Tue Dec 2 14:22:23 2014 +0100

    fdo#86762 broadcast also empty cells after sort
    
    Change-Id: Ie275a754c530d6039ed14304900dd71416f36e46

diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 7f883a6..bfe3fb8 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -361,7 +361,7 @@ public:
 
     void SetAllFormulasDirty( const sc::SetFormulaDirtyContext& rCxt );
     void SetDirtyFromClip( SCROW nRow1, SCROW nRow2, sc::ColumnSpanSet& rBroadcastSpans );
-    void SetDirty( SCROW nRow1, SCROW nRow2, bool bBroadcast = true );
+    void SetDirty( SCROW nRow1, SCROW nRow2, bool bBroadcast = true, bool bIncludeEmptyCells = false );
     void        SetDirtyVar();
     void        SetDirtyAfterLoad();
     void        SetTableOpDirty( const ScRange& );
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 31fde4d..afa215d 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -1012,7 +1012,7 @@ public:
     void            ResetChanged( const ScRange& rRange );
 
     void SetAllFormulasDirty( const sc::SetFormulaDirtyContext& rCxt );
-    void            SetDirty( const ScRange& );
+    void            SetDirty( const ScRange&, bool bIncludeEmptyCells = false );
     void            SetTableOpDirty( const ScRange& );  // for Interpreter TableOp
     void            InterpretDirtyCells( const ScRangeList& rRanges );
     SC_DLLPUBLIC void CalcAll();
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index df3372e..78ca0d8 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -532,7 +532,7 @@ public:
     void        ResetChanged( const ScRange& rRange );
 
     void SetAllFormulasDirty( const sc::SetFormulaDirtyContext& rCxt );
-    void        SetDirty( const ScRange& );
+    void        SetDirty( const ScRange&, bool bIncludeEmptyCells = false );
     void        SetDirtyAfterLoad();
     void        SetDirtyVar();
     void        SetTableOpDirty( const ScRange& );
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index d953230..5185c3a 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -3055,7 +3055,7 @@ void ScColumn::SetDirtyFromClip( SCROW nRow1, SCROW nRow2, sc::ColumnSpanSet& rB
     aHdl.fillBroadcastSpans(rBroadcastSpans);
 }
 
-void ScColumn::SetDirty( SCROW nRow1, SCROW nRow2, bool bBroadcast )
+void ScColumn::SetDirty( SCROW nRow1, SCROW nRow2, bool bBroadcast, bool bIncludeEmptyCells )
 {
     // broadcasts everything within the range, with FormulaTracking
     sc::AutoCalcSwitch aSwitch(*pDocument, false);
@@ -3063,7 +3063,22 @@ void ScColumn::SetDirty( SCROW nRow1, SCROW nRow2, bool bBroadcast )
     SetDirtyOnRangeHandler aHdl(*this);
     sc::ProcessFormula(maCells.begin(), maCells, nRow1, nRow2, aHdl, aHdl);
     if (bBroadcast)
-        aHdl.broadcast();
+    {
+        if (bIncludeEmptyCells)
+        {
+            // Broadcast the changes.
+            ScHint aHint( SC_HINT_DATACHANGED, ScAddress( nCol, 0, nTab));
+            for (SCROW nRow = nRow1; nRow <= nRow2; ++nRow)
+            {
+                aHint.GetAddress().SetRow(nRow);
+                pDocument->Broadcast(aHint);
+            }
+        }
+        else
+        {
+            aHdl.broadcast();
+        }
+    }
 }
 
 void ScColumn::SetTableOpDirty( const ScRange& rRange )
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 660b394..820870b 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -3618,7 +3618,7 @@ void ScDocument::SetAllFormulasDirty( const sc::SetFormulaDirtyContext& rCxt )
     SetAutoCalc( bOldAutoCalc );
 }
 
-void ScDocument::SetDirty( const ScRange& rRange )
+void ScDocument::SetDirty( const ScRange& rRange, bool bIncludeEmptyCells )
 {
     bool bOldAutoCalc = GetAutoCalc();
     bAutoCalc = false;      // keine Mehrfachberechnung
@@ -3626,7 +3626,7 @@ void ScDocument::SetDirty( const ScRange& rRange )
         ScBulkBroadcast aBulkBroadcast( GetBASM());
         SCTAB nTab2 = rRange.aEnd.Tab();
         for (SCTAB i=rRange.aStart.Tab(); i<=nTab2 && i < static_cast<SCTAB>(maTabs.size()); i++)
-            if (maTabs[i]) maTabs[i]->SetDirty( rRange );
+            if (maTabs[i]) maTabs[i]->SetDirty( rRange, bIncludeEmptyCells );
     }
     SetAutoCalc( bOldAutoCalc );
 }
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index 608ec13..fad5443 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -1684,13 +1684,13 @@ void ScTable::SetAllFormulasDirty( const sc::SetFormulaDirtyContext& rCxt )
         aCol[i].SetAllFormulasDirty(rCxt);
 }
 
-void ScTable::SetDirty( const ScRange& rRange )
+void ScTable::SetDirty( const ScRange& rRange, bool bIncludeEmptyCells )
 {
     bool bOldAutoCalc = pDocument->GetAutoCalc();
     pDocument->SetAutoCalc( false );    // Mehrfachberechnungen vermeiden
     SCCOL nCol2 = rRange.aEnd.Col();
     for (SCCOL i=rRange.aStart.Col(); i<=nCol2; i++)
-        aCol[i].SetDirty(rRange.aStart.Row(), rRange.aEnd.Row());
+        aCol[i].SetDirty(rRange.aStart.Row(), rRange.aEnd.Row(), true, bIncludeEmptyCells);
     pDocument->SetAutoCalc( bOldAutoCalc );
 }
 
diff --git a/sc/source/ui/docshell/dbdocfun.cxx b/sc/source/ui/docshell/dbdocfun.cxx
index bed565a..72a11a3 100644
--- a/sc/source/ui/docshell/dbdocfun.cxx
+++ b/sc/source/ui/docshell/dbdocfun.cxx
@@ -571,7 +571,7 @@ bool ScDBDocFunc::Sort( SCTAB nTab, const ScSortParam& rSortParam,
     ScRange aDirtyRange(
         aLocalParam.nCol1, nStartRow, nTab,
         aLocalParam.nCol2, aLocalParam.nRow2, nTab);
-    rDoc.SetDirty( aDirtyRange );
+    rDoc.SetDirty( aDirtyRange, true );
 
     if (bPaint)
     {
commit 6c2111f17089eb667bf526561d7667d17825e822
Author: Eike Rathke <erack at redhat.com>
Date:   Mon Dec 1 23:56:44 2014 +0100

    fdo#86762 re-establish listeners to move cell broadcasters
    
    ... for UpdateReferenceOnSort=false
    
    Change-Id: Id90288660e317d6e47ee01ee3b5ff9058cfa18df

diff --git a/sc/inc/refhint.hxx b/sc/inc/refhint.hxx
index 7081522..8d00ae1 100644
--- a/sc/inc/refhint.hxx
+++ b/sc/inc/refhint.hxx
@@ -24,7 +24,9 @@ public:
     enum Type {
         Moved,
         ColumnReordered,
-        RowReordered
+        RowReordered,
+        StartListening,
+        StopListening
     };
 
 private:
@@ -101,6 +103,20 @@ public:
     SCCOL getEndColumn() const;
 };
 
+class RefStartListeningHint : public RefHint
+{
+public:
+    RefStartListeningHint();
+    virtual ~RefStartListeningHint();
+};
+
+class RefStopListeningHint : public RefHint
+{
+public:
+    RefStopListeningHint();
+    virtual ~RefStopListeningHint();
+};
+
 }
 
 #endif
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index c9c0616..eb98809 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -2044,6 +2044,16 @@ void ScFormulaCell::Notify( const SfxHint& rHint )
                         rRefRowReorder.getRowMap());
             }
             break;
+            case sc::RefHint::StartListening:
+            {
+                StartListeningTo( pDocument);
+            }
+            break;
+            case sc::RefHint::StopListening:
+            {
+                EndListeningTo( pDocument);
+            }
+            break;
             default:
                 ;
         }
diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
index f808db5..857850f 100644
--- a/sc/source/core/data/table3.cxx
+++ b/sc/source/core/data/table3.cxx
@@ -662,6 +662,30 @@ public:
 typedef ReorderNotifier<sc::RefColReorderHint, sc::ColRowReorderMapType, SCCOL> ColReorderNotifier;
 typedef ReorderNotifier<sc::RefRowReorderHint, sc::ColRowReorderMapType, SCROW> RowReorderNotifier;
 
+class StartListeningNotifier : std::unary_function<SvtListener*, void>
+{
+    sc::RefStartListeningHint maHint;
+public:
+    StartListeningNotifier() {}
+
+    void operator() ( SvtListener* p )
+    {
+        p->Notify(maHint);
+    }
+};
+
+class StopListeningNotifier : std::unary_function<SvtListener*, void>
+{
+    sc::RefStopListeningHint maHint;
+public:
+    StopListeningNotifier() {}
+
+    void operator() ( SvtListener* p )
+    {
+        p->Notify(maHint);
+    }
+};
+
 class FormulaGroupPosCollector : std::unary_function<SvtListener*, void>
 {
     sc::RefQueryFormulaGroup& mrQuery;
@@ -802,6 +826,9 @@ void ScTable::SortReorderByRow(
     ScSortInfoArray::RowsType* pRows = pArray->GetDataRows();
     assert(pRows); // In sort-by-row mode we must have data rows already populated.
 
+    // Collect all listeners of cell broadcasters of sorted range.
+    std::vector<SvtListener*> aCellListeners;
+
     if (!pArray->IsUpdateRefs())
     {
         // When the update ref mode is disabled, we need to detach all formula
@@ -809,6 +836,22 @@ void ScTable::SortReorderByRow(
         // afterward.
         sc::EndListeningContext aCxt(*pDocument);
         DetachFormulaCells(aCxt, nCol1, nRow1, nCol2, nRow2);
+
+        // Collect listeners of cell broadcasters.
+        for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
+            aCol[nCol].CollectListeners(aCellListeners, nRow1, nRow2);
+
+        // Remove any duplicate listener entries.  We must ensure that we notify
+        // each unique listener only once.
+        std::sort(aCellListeners.begin(), aCellListeners.end());
+        aCellListeners.erase(std::unique(aCellListeners.begin(), aCellListeners.end()), aCellListeners.end());
+
+        // Notify the cells' listeners to stop listening.
+        /* TODO: for performance this could be enhanced to stop and later
+         * restart only listening to within the reordered range and keep
+         * listening to everything outside untouched. */
+        StopListeningNotifier aFunc;
+        std::for_each(aCellListeners.begin(), aCellListeners.end(), aFunc);
     }
 
     // Split formula groups at the sort range boundaries (if applicable).
@@ -888,15 +931,18 @@ void ScTable::SortReorderByRow(
             else
                 rAttrStore.push_back_empty();
 
-            // At this point each broadcaster instance is managed by 2
-            // containers. We will release those in the original storage
-            // below before transferring them to the document.
-            sc::BroadcasterStoreType& rBCStore = aSortedCols.at(j).maBroadcasters;
-            if (rCell.mpBroadcaster)
-                // A const pointer would be implicitly converted to a bool type.
-                rBCStore.push_back(const_cast<SvtBroadcaster*>(rCell.mpBroadcaster));
-            else
-                rBCStore.push_back_empty();
+            if (pArray->IsUpdateRefs())
+            {
+                // At this point each broadcaster instance is managed by 2
+                // containers. We will release those in the original storage
+                // below before transferring them to the document.
+                sc::BroadcasterStoreType& rBCStore = aSortedCols.at(j).maBroadcasters;
+                if (rCell.mpBroadcaster)
+                    // A const pointer would be implicitly converted to a bool type.
+                    rBCStore.push_back(const_cast<SvtBroadcaster*>(rCell.mpBroadcaster));
+                else
+                    rBCStore.push_back_empty();
+            }
 
             // The same with cell note instances ...
             sc::CellNoteStoreType& rNoteStore = aSortedCols.at(j).maCellNotes;
@@ -937,6 +983,7 @@ void ScTable::SortReorderByRow(
             rSrc.transfer(nRow1, nRow2, rDest, nRow1);
         }
 
+        if (pArray->IsUpdateRefs())
         {
             sc::BroadcasterStoreType& rSrc = aSortedCols[i].maBroadcasters;
             sc::BroadcasterStoreType& rDest = aCol[nThisCol].maBroadcasters;
@@ -1004,39 +1051,39 @@ void ScTable::SortReorderByRow(
             SetRowFiltered(it->mnRow1, it->mnRow2, true);
     }
 
-    // Set up row reorder map (for later broadcasting of reference updates).
-    sc::ColRowReorderMapType aRowMap;
-    const std::vector<SCCOLROW>& rOldIndices = pArray->GetOrderIndices();
-    for (size_t i = 0, n = rOldIndices.size(); i < n; ++i)
-    {
-        SCROW nNew = i + nRow1;
-        SCROW nOld = rOldIndices[i];
-        aRowMap.insert(sc::ColRowReorderMapType::value_type(nOld, nNew));
-    }
-
-    // Collect all listeners within sorted range ahead of time.
-    std::vector<SvtListener*> aListeners;
-
-    // Get all area listeners that listen on one row within the range and end
-    // their listening.
-    ScRange aMoveRange( nCol1, nRow1, nTab, nCol2, nRow2, nTab);
-    std::vector<sc::AreaListener> aAreaListeners = pDocument->GetBASM()->GetAllListeners(
-            aMoveRange, sc::OneRowInsideArea);
+    if (pArray->IsUpdateRefs())
     {
-        std::vector<sc::AreaListener>::iterator it = aAreaListeners.begin(), itEnd = aAreaListeners.end();
-        for (; it != itEnd; ++it)
+        // Set up row reorder map (for later broadcasting of reference updates).
+        sc::ColRowReorderMapType aRowMap;
+        const std::vector<SCCOLROW>& rOldIndices = pArray->GetOrderIndices();
+        for (size_t i = 0, n = rOldIndices.size(); i < n; ++i)
         {
-            pDocument->EndListeningArea(it->maArea, it->mbGroupListening, it->mpListener);
-            aListeners.push_back( it->mpListener);
+            SCROW nNew = i + nRow1;
+            SCROW nOld = rOldIndices[i];
+            aRowMap.insert(sc::ColRowReorderMapType::value_type(nOld, nNew));
         }
-    }
 
-    if (pArray->IsUpdateRefs())
-    {
+        // Collect all listeners within sorted range ahead of time.
+        std::vector<SvtListener*> aListeners;
+
         // Collect listeners of cell broadcasters.
         for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
             aCol[nCol].CollectListeners(aListeners, nRow1, nRow2);
 
+        // Get all area listeners that listen on one row within the range and end
+        // their listening.
+        ScRange aMoveRange( nCol1, nRow1, nTab, nCol2, nRow2, nTab);
+        std::vector<sc::AreaListener> aAreaListeners = pDocument->GetBASM()->GetAllListeners(
+                aMoveRange, sc::OneRowInsideArea);
+        {
+            std::vector<sc::AreaListener>::iterator it = aAreaListeners.begin(), itEnd = aAreaListeners.end();
+            for (; it != itEnd; ++it)
+            {
+                pDocument->EndListeningArea(it->maArea, it->mbGroupListening, it->mpListener);
+                aListeners.push_back( it->mpListener);
+            }
+        }
+
         // Remove any duplicate listener entries.  We must ensure that we notify
         // each unique listener only once.
         std::sort(aListeners.begin(), aListeners.end());
@@ -1062,7 +1109,7 @@ void ScTable::SortReorderByRow(
             }
         }
 
-        // Notify the listeners.
+        // Notify the listeners to update their references.
         RowReorderNotifier aFunc(aRowMap, nTab, nCol1, nCol2);
         std::for_each(aListeners.begin(), aListeners.end(), aFunc);
 
@@ -1074,23 +1121,29 @@ void ScTable::SortReorderByRow(
             for (; itCol != itColEnd; ++itCol)
                 pDocument->RegroupFormulaCells(itGroupTab->first, itCol->first);
         }
-    }
 
-    // Re-start area listeners on the reordered rows.
-    {
-        std::vector<sc::AreaListener>::iterator it = aAreaListeners.begin(), itEnd = aAreaListeners.end();
-        for (; it != itEnd; ++it)
+        // Re-start area listeners on the reordered rows.
         {
-            ScRange aNewRange = it->maArea;
-            sc::ColRowReorderMapType::const_iterator itRow = aRowMap.find( aNewRange.aStart.Row());
-            if (itRow != aRowMap.end())
+            std::vector<sc::AreaListener>::iterator it = aAreaListeners.begin(), itEnd = aAreaListeners.end();
+            for (; it != itEnd; ++it)
             {
-                aNewRange.aStart.SetRow( itRow->second);
-                aNewRange.aEnd.SetRow( itRow->second);
+                ScRange aNewRange = it->maArea;
+                sc::ColRowReorderMapType::const_iterator itRow = aRowMap.find( aNewRange.aStart.Row());
+                if (itRow != aRowMap.end())
+                {
+                    aNewRange.aStart.SetRow( itRow->second);
+                    aNewRange.aEnd.SetRow( itRow->second);
+                }
+                pDocument->StartListeningArea(aNewRange, it->mbGroupListening, it->mpListener);
             }
-            pDocument->StartListeningArea(aNewRange, it->mbGroupListening, it->mpListener);
         }
     }
+    else    // !(pArray->IsUpdateRefs())
+    {
+        // Notify the cells' listeners to (re-)start listening.
+        StartListeningNotifier aFunc;
+        std::for_each(aCellListeners.begin(), aCellListeners.end(), aFunc);
+    }
 
     // Re-group columns in the sorted range too.
     for (SCCOL i = nCol1; i <= nCol2; ++i)
diff --git a/sc/source/core/tool/refhint.cxx b/sc/source/core/tool/refhint.cxx
index f76489c..c159e96 100644
--- a/sc/source/core/tool/refhint.cxx
+++ b/sc/source/core/tool/refhint.cxx
@@ -89,6 +89,12 @@ SCCOL RefRowReorderHint::getEndColumn() const
     return mnCol2;
 }
 
+RefStartListeningHint::RefStartListeningHint() : RefHint(StartListening) {}
+RefStartListeningHint::~RefStartListeningHint() {}
+
+RefStopListeningHint::RefStopListeningHint() : RefHint(StopListening) {}
+RefStopListeningHint::~RefStopListeningHint() {}
+
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */


More information about the Libreoffice-commits mailing list