summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sc/inc/types.hxx4
-rw-r--r--sc/source/core/data/bcaslot.cxx33
-rw-r--r--sc/source/core/data/table3.cxx67
-rw-r--r--sc/source/core/tool/token.cxx2
4 files changed, 95 insertions, 11 deletions
diff --git a/sc/inc/types.hxx b/sc/inc/types.hxx
index 8dc8f181f28d..d40b2a5e110e 100644
--- a/sc/inc/types.hxx
+++ b/sc/inc/types.hxx
@@ -103,7 +103,9 @@ typedef boost::unordered_map<SCCOLROW,SCCOLROW> ColRowReorderMapType;
enum AreaOverlapType
{
AreaInside,
- AreaPartialOverlap
+ AreaPartialOverlap,
+ OneRowInsideArea,
+ OneColumnInsideArea
};
}
diff --git a/sc/source/core/data/bcaslot.cxx b/sc/source/core/data/bcaslot.cxx
index ea70ffbd3615..2192706c0416 100644
--- a/sc/source/core/data/bcaslot.cxx
+++ b/sc/source/core/data/bcaslot.cxx
@@ -444,14 +444,31 @@ void ScBroadcastAreaSlot::GetAllListeners(
ScBroadcastArea* pArea = (*aIter).mpArea;
const ScRange& rAreaRange = pArea->GetRange();
- if (eType == sc::AreaInside && !rRange.In(rAreaRange))
- // The range needs to be fully inside specified range.
- continue;
-
- if (eType == sc::AreaPartialOverlap &&
- (!rRange.Intersects(rAreaRange) || rRange.In(rAreaRange)))
- // The range needs to be only partially overlapping.
- continue;
+ switch (eType)
+ {
+ case sc::AreaInside:
+ if (!rRange.In(rAreaRange))
+ // The range needs to be fully inside specified range.
+ continue;
+ break;
+ case sc::AreaPartialOverlap:
+ if (!rRange.Intersects(rAreaRange) || rRange.In(rAreaRange))
+ // The range needs to be only partially overlapping.
+ continue;
+ break;
+ case sc::OneRowInsideArea:
+ if (rAreaRange.aStart.Row() != rAreaRange.aEnd.Row() || !rRange.In(rAreaRange))
+ // The range needs to be one single row and fully inside
+ // specified range.
+ continue;
+ break;
+ case sc::OneColumnInsideArea:
+ if (rAreaRange.aStart.Col() != rAreaRange.aEnd.Col() || !rRange.In(rAreaRange))
+ // The range needs to be one single column and fully inside
+ // specified range.
+ continue;
+ break;
+ }
SvtBroadcaster::ListenersType& rLst = pArea->GetBroadcaster().GetAllListeners();
SvtBroadcaster::ListenersType::iterator itLst = rLst.begin(), itLstEnd = rLst.end();
diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
index 25e088fcc231..0409f14e3e07 100644
--- a/sc/source/core/data/table3.cxx
+++ b/sc/source/core/data/table3.cxx
@@ -60,6 +60,7 @@
#include <sharedformula.hxx>
#include <refhint.hxx>
#include <listenerquery.hxx>
+#include <bcaslot.hxx>
#include <svl/sharedstringpool.hxx>
@@ -717,6 +718,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);
@@ -728,6 +744,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)
@@ -803,8 +835,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);
@@ -944,6 +975,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);
@@ -976,6 +1023,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)
{
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index 34f9a16fdae1..0b7df591c1a7 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -3464,6 +3464,7 @@ void ScTokenArray::AdjustReferenceOnMovedOrigin( const ScAddress& rOldPos, const
switch ((*p)->GetType())
{
case svSingleRef:
+ case svExternalSingleRef:
{
ScToken* pToken = static_cast<ScToken*>(*p);
ScSingleRefData& rRef = pToken->GetSingleRef();
@@ -3472,6 +3473,7 @@ void ScTokenArray::AdjustReferenceOnMovedOrigin( const ScAddress& rOldPos, const
}
break;
case svDoubleRef:
+ case svExternalDoubleRef:
{
ScToken* pToken = static_cast<ScToken*>(*p);
ScComplexRefData& rRef = pToken->GetDoubleRef();