Blame SOURCES/0097-fdo-80501-Ensure-that-we-notify-each-listener-only-o.patch

f085be
From 5f9e7ee1cc330f3b08596db0d13ad01e4dea7880 Mon Sep 17 00:00:00 2001
f085be
From: Kohei Yoshida <kohei.yoshida@collabora.com>
f085be
Date: Wed, 30 Jul 2014 11:02:31 -0400
f085be
Subject: [PATCH 097/137] fdo#80501: Ensure that we notify each listener only
f085be
 once.
f085be
f085be
Change-Id: If2ce4643ff58c7c2ba326d749698dd5196a108dc
f085be
(cherry picked from commit b2ee0235e88dc4da715b5766295ed88f27974fbd)
f085be
Reviewed-on: https://gerrit.libreoffice.org/10647
f085be
Reviewed-by: Eike Rathke <erack@redhat.com>
f085be
Tested-by: Eike Rathke <erack@redhat.com>
f085be
---
f085be
 sc/inc/column.hxx                |  1 -
f085be
 sc/inc/table.hxx                 |  5 +----
f085be
 sc/source/core/data/column.cxx   | 27 ---------------------------
f085be
 sc/source/core/data/column4.cxx  |  3 +++
f085be
 sc/source/core/data/documen7.cxx | 40 ++++++++++++++++++++++++++++++++++++++--
f085be
 sc/source/core/data/table2.cxx   |  7 -------
f085be
 sc/source/core/data/table7.cxx   | 10 ++++++++++
f085be
 7 files changed, 52 insertions(+), 41 deletions(-)
f085be
f085be
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
f085be
index 8962422..66cd524 100644
f085be
--- a/sc/inc/column.hxx
f085be
+++ b/sc/inc/column.hxx
f085be
@@ -478,7 +478,6 @@ public:
f085be
     void        StartNeededListeners(); // only for cells where NeedsListening()==true
f085be
     void        SetDirtyIfPostponed();
f085be
     void BroadcastRecalcOnRefMove();
f085be
-    void BroadcastRefMoved( const sc::RefMovedHint& rHint );
f085be
     void TransferListeners( ScColumn& rDestCol, SCROW nRow1, SCROW nRow2, SCROW nRowDelta );
f085be
     void CollectListeners( std::vector<SvtListener*>& rListeners, SCROW nRow1, SCROW nRow2 );
f085be
 
f085be
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
f085be
index 9d36a1e..191a360 100644
f085be
--- a/sc/inc/table.hxx
f085be
+++ b/sc/inc/table.hxx
f085be
@@ -927,10 +927,7 @@ public:
f085be
      */
f085be
     void BroadcastRecalcOnRefMove();
f085be
 
f085be
-    /**
f085be
-     * Broadcast all listeners of specified range that the range have moved.
f085be
-     */
f085be
-    void BroadcastRefMoved( const sc::RefMovedHint& rHint );
f085be
+    void CollectListeners( std::vector<SvtListener*>& rListeners, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 );
f085be
 
f085be
     void TransferListeners(
f085be
         ScTable& rDestTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
f085be
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
f085be
index 2d0a018..10da725 100644
f085be
--- a/sc/source/core/data/column.cxx
f085be
+++ b/sc/source/core/data/column.cxx
f085be
@@ -3119,33 +3119,6 @@ void ScColumn::BroadcastRecalcOnRefMove()
f085be
 
f085be
 namespace {
f085be
 
f085be
-class BroadcastRefMovedHandler
f085be
-{
f085be
-    const sc::RefMovedHint& mrHint;
f085be
-public:
f085be
-    BroadcastRefMovedHandler( const sc::RefMovedHint& rHint ) : mrHint(rHint) {}
f085be
-
f085be
-    void operator() ( size_t, SvtBroadcaster* p )
f085be
-    {
f085be
-        p->Broadcast(mrHint);
f085be
-    }
f085be
-};
f085be
-
f085be
-}
f085be
-
f085be
-void ScColumn::BroadcastRefMoved( const sc::RefMovedHint& rHint )
f085be
-{
f085be
-    const ScRange& rRange = rHint.getRange();
f085be
-    SCROW nRow1 = rRange.aStart.Row();
f085be
-    SCROW nRow2 = rRange.aEnd.Row();
f085be
-
f085be
-    // Notify all listeners within specified rows.
f085be
-    BroadcastRefMovedHandler aFunc(rHint);
f085be
-    sc::ProcessBroadcaster(maBroadcasters.begin(), maBroadcasters, nRow1, nRow2, aFunc);
f085be
-}
f085be
-
f085be
-namespace {
f085be
-
f085be
 class TransferListenersHandler
f085be
 {
f085be
 public:
f085be
diff --git a/sc/source/core/data/column4.cxx b/sc/source/core/data/column4.cxx
f085be
index bf3b817..d1aacdd 100644
f085be
--- a/sc/source/core/data/column4.cxx
f085be
+++ b/sc/source/core/data/column4.cxx
f085be
@@ -533,6 +533,9 @@ public:
f085be
 
f085be
 void ScColumn::CollectListeners( std::vector<SvtListener*>& rListeners, SCROW nRow1, SCROW nRow2 )
f085be
 {
f085be
+    if (nRow2 < nRow1 || !ValidRow(nRow1) || !ValidRow(nRow2))
f085be
+        return;
f085be
+
f085be
     ListenerCollector aFunc(rListeners);
f085be
     sc::ProcessBroadcaster(maBroadcasters.begin(), maBroadcasters, nRow1, nRow2, aFunc);
f085be
 }
f085be
diff --git a/sc/source/core/data/documen7.cxx b/sc/source/core/data/documen7.cxx
f085be
index 02a75fb..a960c5a 100644
f085be
--- a/sc/source/core/data/documen7.cxx
f085be
+++ b/sc/source/core/data/documen7.cxx
f085be
@@ -130,6 +130,22 @@ void ScDocument::BroadcastCells( const ScRange& rRange, sal_uLong nHint )
f085be
     BroadcastUno(SfxSimpleHint(SC_HINT_DATACHANGED));
f085be
 }
f085be
 
f085be
+namespace {
f085be
+
f085be
+class RefMovedNotifier : std::unary_function<SvtListener*, void>
f085be
+{
f085be
+    const sc::RefMovedHint& mrHint;
f085be
+public:
f085be
+    RefMovedNotifier( const sc::RefMovedHint& rHint ) : mrHint(rHint) {}
f085be
+
f085be
+    void operator() ( SvtListener* p )
f085be
+    {
f085be
+        p->Notify(mrHint);
f085be
+    }
f085be
+};
f085be
+
f085be
+}
f085be
+
f085be
 void ScDocument::BroadcastRefMoved( const sc::RefMovedHint& rHint )
f085be
 {
f085be
     if (!pBASM)
f085be
@@ -150,6 +166,28 @@ void ScDocument::BroadcastRefMoved( const sc::RefMovedHint& rHint )
f085be
         }
f085be
     }
f085be
 
f085be
+    // Collect all listeners listening into the range.
f085be
+    std::vector<SvtListener*> aListeners;
f085be
+    for (SCTAB nTab = rSrcRange.aStart.Tab(); nTab <= rSrcRange.aEnd.Tab(); ++nTab)
f085be
+    {
f085be
+        ScTable* pTab = FetchTable(nTab);
f085be
+        if (!pTab)
f085be
+            continue;
f085be
+
f085be
+        pTab->CollectListeners(
f085be
+            aListeners,
f085be
+            rSrcRange.aStart.Col(), rSrcRange.aStart.Row(),
f085be
+            rSrcRange.aEnd.Col(), rSrcRange.aEnd.Row());
f085be
+    }
f085be
+
f085be
+    // Remove any duplicate listener entries.  We must ensure that we notify
f085be
+    // each unique listener only once.
f085be
+    std::sort(aListeners.begin(), aListeners.end());
f085be
+    aListeners.erase(std::unique(aListeners.begin(), aListeners.end()), aListeners.end());
f085be
+
f085be
+    // Notify the listeners.
f085be
+    std::for_each(aListeners.begin(), aListeners.end(), RefMovedNotifier(rHint));
f085be
+
f085be
     for (SCTAB nTab = rSrcRange.aStart.Tab(); nTab <= rSrcRange.aEnd.Tab(); ++nTab)
f085be
     {
f085be
         ScTable* pTab = FetchTable(nTab);
f085be
@@ -161,8 +199,6 @@ void ScDocument::BroadcastRefMoved( const sc::RefMovedHint& rHint )
f085be
         if (!pDestTab)
f085be
             continue;
f085be
 
f085be
-        // Adjust the references.
f085be
-        pTab->BroadcastRefMoved(rHint);
f085be
         // Move the listeners from the old location to the new.
f085be
         pTab->TransferListeners(
f085be
             *pDestTab, rSrcRange.aStart.Col(), rSrcRange.aStart.Row(),
f085be
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
f085be
index 3f0d190..1a37801 100644
f085be
--- a/sc/source/core/data/table2.cxx
f085be
+++ b/sc/source/core/data/table2.cxx
f085be
@@ -1739,13 +1739,6 @@ void ScTable::BroadcastRecalcOnRefMove()
f085be
         aCol[i].BroadcastRecalcOnRefMove();
f085be
 }
f085be
 
f085be
-void ScTable::BroadcastRefMoved( const sc::RefMovedHint& rHint )
f085be
-{
f085be
-    const ScRange& rRange = rHint.getRange();
f085be
-    for (SCCOL nCol = rRange.aStart.Col(); nCol <= rRange.aEnd.Col(); ++nCol)
f085be
-        aCol[nCol].BroadcastRefMoved(rHint);
f085be
-}
f085be
-
f085be
 void ScTable::TransferListeners(
f085be
     ScTable& rDestTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
f085be
     SCCOL nColDelta, SCROW nRowDelta )
f085be
diff --git a/sc/source/core/data/table7.cxx b/sc/source/core/data/table7.cxx
f085be
index 1ede729..ff976a2 100644
f085be
--- a/sc/source/core/data/table7.cxx
f085be
+++ b/sc/source/core/data/table7.cxx
f085be
@@ -110,4 +110,14 @@ void ScTable::RegroupFormulaCells( SCCOL nCol )
f085be
     aCol[nCol].RegroupFormulaCells();
f085be
 }
f085be
 
f085be
+void ScTable::CollectListeners(
f085be
+    std::vector<SvtListener*>& rListeners, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
f085be
+{
f085be
+    if (nCol2 < nCol1 || !ValidCol(nCol1) || !ValidCol(nCol2))
f085be
+        return;
f085be
+
f085be
+    for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
f085be
+        aCol[nCol].CollectListeners(rListeners, nRow1, nRow2);
f085be
+}
f085be
+
f085be
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
f085be
-- 
f085be
1.9.3
f085be