summaryrefslogtreecommitdiff
path: root/sc/source/core/data
diff options
context:
space:
mode:
authorEike Rathke <erack@redhat.com>2014-12-02 14:53:53 +0100
committerEike Rathke <erack@redhat.com>2014-12-02 15:37:06 +0100
commit61f8e9734d5e27fd39978bada0e91c1526bc6003 (patch)
tree9a0631e0badca2a981323085fd42d0cec0825fd5 /sc/source/core/data
parent7e12f98fc05c6828ca0823cbaf45670073778c8a (diff)
fdo#86762 re-establish listeners on moved broadcasters
... also in SortReorderByColumn() similar to SortReorderByRow() Change-Id: I7665dcc90d70fcf3b08bef0adb9ab6aaff1cdcdf (cherry picked from commit e119f3883513aeaa49f332362620e955dc8b453f)
Diffstat (limited to 'sc/source/core/data')
-rw-r--r--sc/source/core/data/table3.cxx100
1 files changed, 64 insertions, 36 deletions
diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
index 2c7b30947037..7e1d24af7d3d 100644
--- a/sc/source/core/data/table3.cxx
+++ b/sc/source/core/data/table3.cxx
@@ -714,6 +714,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)
@@ -742,38 +764,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.
@@ -781,23 +803,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.