summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@collabora.com>2014-07-30 11:02:31 -0400
committerMarkus Mohrhard <markus.mohrhard@googlemail.com>2014-07-30 21:45:27 +0000
commitef32f401f27c394617df55114e912ffab3e6307a (patch)
treeb34ef428bd703e41477aa1799a17bf09e41e9e09
parent29803d51fe6db96d2a98475c059cd56f36e0da6b (diff)
fdo#80501: Ensure that we notify each listener only once.
Change-Id: If2ce4643ff58c7c2ba326d749698dd5196a108dc (cherry picked from commit b2ee0235e88dc4da715b5766295ed88f27974fbd) Reviewed-on: https://gerrit.libreoffice.org/10645 Reviewed-by: Markus Mohrhard <markus.mohrhard@googlemail.com> Tested-by: Markus Mohrhard <markus.mohrhard@googlemail.com>
-rw-r--r--sc/inc/column.hxx1
-rw-r--r--sc/inc/table.hxx5
-rw-r--r--sc/source/core/data/column.cxx27
-rw-r--r--sc/source/core/data/column4.cxx3
-rw-r--r--sc/source/core/data/documen7.cxx40
-rw-r--r--sc/source/core/data/table2.cxx7
-rw-r--r--sc/source/core/data/table7.cxx10
7 files changed, 52 insertions, 41 deletions
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 09b1588b24c2..d2b77997629c 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -484,7 +484,6 @@ public:
void StartNeededListeners(); // only for cells where NeedsListening()==true
void SetDirtyIfPostponed();
void BroadcastRecalcOnRefMove();
- void BroadcastRefMoved( const sc::RefMovedHint& rHint );
void TransferListeners( ScColumn& rDestCol, SCROW nRow1, SCROW nRow2, SCROW nRowDelta );
void CollectListeners( std::vector<SvtListener*>& rListeners, SCROW nRow1, SCROW nRow2 );
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index e6289ecec90f..537846ddf645 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -923,10 +923,7 @@ public:
*/
void BroadcastRecalcOnRefMove();
- /**
- * Broadcast all listeners of specified range that the range have moved.
- */
- void BroadcastRefMoved( const sc::RefMovedHint& rHint );
+ void CollectListeners( std::vector<SvtListener*>& rListeners, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 );
void TransferListeners(
ScTable& rDestTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index 3e4c4ae87633..1676e1b16735 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -3108,33 +3108,6 @@ void ScColumn::BroadcastRecalcOnRefMove()
namespace {
-class BroadcastRefMovedHandler
-{
- const sc::RefMovedHint& mrHint;
-public:
- BroadcastRefMovedHandler( const sc::RefMovedHint& rHint ) : mrHint(rHint) {}
-
- void operator() ( size_t, SvtBroadcaster* p )
- {
- p->Broadcast(mrHint);
- }
-};
-
-}
-
-void ScColumn::BroadcastRefMoved( const sc::RefMovedHint& rHint )
-{
- const ScRange& rRange = rHint.getRange();
- SCROW nRow1 = rRange.aStart.Row();
- SCROW nRow2 = rRange.aEnd.Row();
-
- // Notify all listeners within specified rows.
- BroadcastRefMovedHandler aFunc(rHint);
- sc::ProcessBroadcaster(maBroadcasters.begin(), maBroadcasters, nRow1, nRow2, aFunc);
-}
-
-namespace {
-
class TransferListenersHandler
{
public:
diff --git a/sc/source/core/data/column4.cxx b/sc/source/core/data/column4.cxx
index 131f8cc2a984..3f26db17752c 100644
--- a/sc/source/core/data/column4.cxx
+++ b/sc/source/core/data/column4.cxx
@@ -950,6 +950,9 @@ public:
void ScColumn::CollectListeners( std::vector<SvtListener*>& rListeners, SCROW nRow1, SCROW nRow2 )
{
+ if (nRow2 < nRow1 || !ValidRow(nRow1) || !ValidRow(nRow2))
+ return;
+
ListenerCollector aFunc(rListeners);
sc::ProcessBroadcaster(maBroadcasters.begin(), maBroadcasters, nRow1, nRow2, aFunc);
}
diff --git a/sc/source/core/data/documen7.cxx b/sc/source/core/data/documen7.cxx
index a4897d7f266d..ec34b4415861 100644
--- a/sc/source/core/data/documen7.cxx
+++ b/sc/source/core/data/documen7.cxx
@@ -128,6 +128,22 @@ void ScDocument::BroadcastCells( const ScRange& rRange, sal_uLong nHint )
BroadcastUno(SfxSimpleHint(SC_HINT_DATACHANGED));
}
+namespace {
+
+class RefMovedNotifier : std::unary_function<SvtListener*, void>
+{
+ const sc::RefMovedHint& mrHint;
+public:
+ RefMovedNotifier( const sc::RefMovedHint& rHint ) : mrHint(rHint) {}
+
+ void operator() ( SvtListener* p )
+ {
+ p->Notify(mrHint);
+ }
+};
+
+}
+
void ScDocument::BroadcastRefMoved( const sc::RefMovedHint& rHint )
{
if (!pBASM)
@@ -148,6 +164,28 @@ void ScDocument::BroadcastRefMoved( const sc::RefMovedHint& rHint )
}
}
+ // Collect all listeners listening into the range.
+ std::vector<SvtListener*> aListeners;
+ for (SCTAB nTab = rSrcRange.aStart.Tab(); nTab <= rSrcRange.aEnd.Tab(); ++nTab)
+ {
+ ScTable* pTab = FetchTable(nTab);
+ if (!pTab)
+ continue;
+
+ pTab->CollectListeners(
+ aListeners,
+ rSrcRange.aStart.Col(), rSrcRange.aStart.Row(),
+ rSrcRange.aEnd.Col(), rSrcRange.aEnd.Row());
+ }
+
+ // 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());
+
+ // Notify the listeners.
+ std::for_each(aListeners.begin(), aListeners.end(), RefMovedNotifier(rHint));
+
for (SCTAB nTab = rSrcRange.aStart.Tab(); nTab <= rSrcRange.aEnd.Tab(); ++nTab)
{
ScTable* pTab = FetchTable(nTab);
@@ -159,8 +197,6 @@ void ScDocument::BroadcastRefMoved( const sc::RefMovedHint& rHint )
if (!pDestTab)
continue;
- // Adjust the references.
- pTab->BroadcastRefMoved(rHint);
// Move the listeners from the old location to the new.
pTab->TransferListeners(
*pDestTab, rSrcRange.aStart.Col(), rSrcRange.aStart.Row(),
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index bba309560171..9abd954f23fb 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -1740,13 +1740,6 @@ void ScTable::BroadcastRecalcOnRefMove()
aCol[i].BroadcastRecalcOnRefMove();
}
-void ScTable::BroadcastRefMoved( const sc::RefMovedHint& rHint )
-{
- const ScRange& rRange = rHint.getRange();
- for (SCCOL nCol = rRange.aStart.Col(); nCol <= rRange.aEnd.Col(); ++nCol)
- aCol[nCol].BroadcastRefMoved(rHint);
-}
-
void ScTable::TransferListeners(
ScTable& rDestTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
SCCOL nColDelta, SCROW nRowDelta )
diff --git a/sc/source/core/data/table7.cxx b/sc/source/core/data/table7.cxx
index 6763565b62e7..407a8ba0d155 100644
--- a/sc/source/core/data/table7.cxx
+++ b/sc/source/core/data/table7.cxx
@@ -149,4 +149,14 @@ void ScTable::RegroupFormulaCells( SCCOL nCol )
aCol[nCol].RegroupFormulaCells();
}
+void ScTable::CollectListeners(
+ std::vector<SvtListener*>& rListeners, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
+{
+ if (nCol2 < nCol1 || !ValidCol(nCol1) || !ValidCol(nCol2))
+ return;
+
+ for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
+ aCol[nCol].CollectListeners(rListeners, nRow1, nRow2);
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */