diff options
author | Eike Rathke <erack@redhat.com> | 2014-12-02 14:53:53 +0100 |
---|---|---|
committer | Eike Rathke <erack@redhat.com> | 2014-12-02 15:37:06 +0100 |
commit | 61f8e9734d5e27fd39978bada0e91c1526bc6003 (patch) | |
tree | 9a0631e0badca2a981323085fd42d0cec0825fd5 | |
parent | 7e12f98fc05c6828ca0823cbaf45670073778c8a (diff) |
fdo#86762 re-establish listeners on moved broadcasters
... also in SortReorderByColumn() similar to SortReorderByRow()
Change-Id: I7665dcc90d70fcf3b08bef0adb9ab6aaff1cdcdf
(cherry picked from commit e119f3883513aeaa49f332362620e955dc8b453f)
-rw-r--r-- | sc/source/core/data/table3.cxx | 100 |
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. |