summaryrefslogtreecommitdiff
path: root/sc/source
diff options
context:
space:
mode:
Diffstat (limited to 'sc/source')
-rw-r--r--sc/source/core/data/bcaslot.cxx36
-rw-r--r--sc/source/core/data/documen7.cxx2
-rw-r--r--sc/source/core/data/table3.cxx67
-rw-r--r--sc/source/core/inc/bcaslot.hxx6
-rw-r--r--sc/source/core/tool/token.cxx2
5 files changed, 103 insertions, 10 deletions
diff --git a/sc/source/core/data/bcaslot.cxx b/sc/source/core/data/bcaslot.cxx
index 2dfc9a7d6ac6..1eff597ca194 100644
--- a/sc/source/core/data/bcaslot.cxx
+++ b/sc/source/core/data/bcaslot.cxx
@@ -446,7 +446,8 @@ void ScBroadcastAreaSlot::EraseArea( ScBroadcastAreas::iterator& rIter )
}
}
-void ScBroadcastAreaSlot::GetAllListeners( const ScRange& rRange, std::vector<sc::AreaListener>& rListeners )
+void ScBroadcastAreaSlot::GetAllListeners(
+ const ScRange& rRange, std::vector<sc::AreaListener>& rListeners, sc::AreaOverlapType eType )
{
for (ScBroadcastAreas::const_iterator aIter( aBroadcastAreaTbl.begin()),
aIterEnd( aBroadcastAreaTbl.end()); aIter != aIterEnd; ++aIter )
@@ -456,8 +457,32 @@ void ScBroadcastAreaSlot::GetAllListeners( const ScRange& rRange, std::vector<sc
ScBroadcastArea* pArea = (*aIter).mpArea;
const ScRange& rAreaRange = pArea->GetRange();
- if (!rRange.In(rAreaRange))
- 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();
@@ -1000,7 +1025,8 @@ void ScBroadcastAreaSlotMachine::FinallyEraseAreas( ScBroadcastAreaSlot* pSlot )
maAreasToBeErased.swap( aCopy);
}
-std::vector<sc::AreaListener> ScBroadcastAreaSlotMachine::GetAllListeners( const ScRange& rRange )
+std::vector<sc::AreaListener> ScBroadcastAreaSlotMachine::GetAllListeners(
+ const ScRange& rRange, sc::AreaOverlapType eType )
{
std::vector<sc::AreaListener> aRet;
@@ -1017,7 +1043,7 @@ std::vector<sc::AreaListener> ScBroadcastAreaSlotMachine::GetAllListeners( const
while ( nOff <= nEnd )
{
ScBroadcastAreaSlot* p = *pp;
- p->GetAllListeners(rRange, aRet);
+ p->GetAllListeners(rRange, aRet, eType);
ComputeNextSlot( nOff, nBreak, pp, nStart, ppSlots, nRowBreak);
}
}
diff --git a/sc/source/core/data/documen7.cxx b/sc/source/core/data/documen7.cxx
index a960c5a7011b..581da65fc3e6 100644
--- a/sc/source/core/data/documen7.cxx
+++ b/sc/source/core/data/documen7.cxx
@@ -156,7 +156,7 @@ void ScDocument::BroadcastRefMoved( const sc::RefMovedHint& rHint )
const ScAddress& rDelta = rHint.getDelta();
// Get all area listeners that listens on the old range, and end their listening.
- std::vector<sc::AreaListener> aAreaListeners = pBASM->GetAllListeners(rSrcRange);
+ std::vector<sc::AreaListener> aAreaListeners = pBASM->GetAllListeners(rSrcRange, sc::AreaInside);
{
std::vector<sc::AreaListener>::iterator it = aAreaListeners.begin(), itEnd = aAreaListeners.end();
for (; it != itEnd; ++it)
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)
{
diff --git a/sc/source/core/inc/bcaslot.hxx b/sc/source/core/inc/bcaslot.hxx
index b8587d6f4506..b4b57e92c859 100644
--- a/sc/source/core/inc/bcaslot.hxx
+++ b/sc/source/core/inc/bcaslot.hxx
@@ -221,7 +221,8 @@ public:
*/
void EraseArea( ScBroadcastAreas::iterator& rIter );
- void GetAllListeners( const ScRange& rRange, std::vector<sc::AreaListener>& rListeners );
+ void GetAllListeners(
+ const ScRange& rRange, std::vector<sc::AreaListener>& rListeners, sc::AreaOverlapType eType );
};
@@ -317,7 +318,8 @@ public:
// only for ScBroadcastAreaSlot
void FinallyEraseAreas( ScBroadcastAreaSlot* pSlot );
- std::vector<sc::AreaListener> GetAllListeners( const ScRange& rRange );
+ std::vector<sc::AreaListener> GetAllListeners(
+ const ScRange& rRange, sc::AreaOverlapType eType );
};
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index d39255076ab4..24f03432ad6e 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -3469,6 +3469,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();
@@ -3477,6 +3478,7 @@ void ScTokenArray::AdjustReferenceOnMovedOrigin( const ScAddress& rOldPos, const
}
break;
case svDoubleRef:
+ case svExternalDoubleRef:
{
ScToken* pToken = static_cast<ScToken*>(*p);
ScComplexRefData& rRef = pToken->GetDoubleRef();