summaryrefslogtreecommitdiff
path: root/sc/source/core/data/table3.cxx
diff options
context:
space:
mode:
authorEike Rathke <erack@redhat.com>2014-08-14 23:36:47 +0200
committerAndras Timar <andras.timar@collabora.com>2014-08-23 07:43:15 -0700
commit84584cc237b2eb93f7684d8fcd063bb37e87b5fb (patch)
tree3f7e759cdda73628b5987656116ed9cf9328700a /sc/source/core/data/table3.cxx
parent8ecff2710f0ea19c9048900e7d5399471e262c47 (diff)
correct references after sort, fdo#79441 cp-4.2-8
5c6ee09126631342939ae8766fe36083d8c011e3 introduced a different algorithm for reference handling during sort. Unfortunately that clashed with the SC_CLONECELL_ADJUST3DREL introduced a little earlier resulting in relative 3D references effectively being "adjusted" twice. Furthermore, in-sort-range range references to one row (or column) were not adapted to the move at all if the formula within the range listened only to ranges and not a single cell. Added collecting and adjusting area listeners for this. Last but not least, external (relative) references need to be treated the same as internal 3D references, making them point to the same location after the sort. (cherry picked from commit 69adec3ec051ff94f600ab899506ca9d645a8b56) Conflicts: sc/inc/types.hxx sc/source/core/data/bcaslot.cxx Plus necessary parts of 27182231acd3a0c9898a8dba78b76dc8a827b4c0 related to bcaslot changes. Change-Id: I492768b525f95f1c43d1c6e7a63a36cce093fa5a Reviewed-on: https://gerrit.libreoffice.org/10930 Reviewed-by: Kohei Yoshida <libreoffice@kohei.us> Tested-by: Kohei Yoshida <libreoffice@kohei.us>
Diffstat (limited to 'sc/source/core/data/table3.cxx')
-rw-r--r--sc/source/core/data/table3.cxx67
1 files changed, 65 insertions, 2 deletions
diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
index 3b63f7e4b4dd..a719f85eff45 100644
--- a/sc/source/core/data/table3.cxx
+++ b/sc/source/core/data/table3.cxx
@@ -62,6 +62,7 @@
#include <sharedformula.hxx>
#include <refhint.hxx>
#include <listenerquery.hxx>
+#include <bcaslot.hxx>
#include "svl/sharedstringpool.hxx"
@@ -721,6 +722,21 @@ void ScTable::SortReorderByColumn(
// 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);
+ {
+ std::vector<sc::AreaListener>::iterator it = aAreaListeners.begin(), itEnd = aAreaListeners.end();
+ for (; it != itEnd; ++it)
+ {
+ pDocument->EndListeningArea(it->maArea, it->mpListener);
+ aListeners.push_back( it->mpListener);
+ }
+ }
+
for (SCCOL nCol = nStart; nCol <= nLast; ++nCol)
aCol[nCol].CollectListeners(aListeners, nRow1, nRow2);
@@ -732,6 +748,22 @@ void ScTable::SortReorderByColumn(
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)
+ {
+ 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->mpListener);
+ }
+ }
+
// Re-join formulas at row boundaries now that all the references have
// been adjusted for column reordering.
for (SCCOL nCol = nStart; nCol <= nLast; ++nCol)
@@ -807,8 +839,7 @@ void ScTable::SortReorderByRow(
assert(rCell.mpAttr);
ScAddress aOldPos = rCell.maCell.mpFormula->aPos;
- ScFormulaCell* pNew = rCell.maCell.mpFormula->Clone(
- aCellPos, SC_CLONECELL_DEFAULT | SC_CLONECELL_ADJUST3DREL);
+ ScFormulaCell* pNew = rCell.maCell.mpFormula->Clone( aCellPos, SC_CLONECELL_DEFAULT);
pNew->CopyAllBroadcasters(*rCell.maCell.mpFormula);
pNew->GetCode()->AdjustReferenceOnMovedOrigin(aOldPos, aCellPos);
@@ -948,6 +979,22 @@ void ScTable::SortReorderByRow(
// 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);
+ {
+ std::vector<sc::AreaListener>::iterator it = aAreaListeners.begin(), itEnd = aAreaListeners.end();
+ for (; it != itEnd; ++it)
+ {
+ pDocument->EndListeningArea(it->maArea, it->mpListener);
+ aListeners.push_back( it->mpListener);
+ }
+ }
+
+ // Collect listeners of cell broadcasters.
for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
aCol[nCol].CollectListeners(aListeners, nRow1, nRow2);
@@ -980,6 +1027,22 @@ void ScTable::SortReorderByRow(
RowReorderNotifier aFunc(aRowMap, nTab, nCol1, nCol2);
std::for_each(aListeners.begin(), aListeners.end(), aFunc);
+ // Re-start area listeners on the reordered rows.
+ {
+ std::vector<sc::AreaListener>::iterator it = aAreaListeners.begin(), itEnd = aAreaListeners.end();
+ for (; it != itEnd; ++it)
+ {
+ 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->mpListener);
+ }
+ }
+
// Re-group formulas in affected columns.
for (itGroupTab = rGroupTabs.begin(); itGroupTab != itGroupTabEnd; ++itGroupTab)
{