diff options
-rw-r--r-- | sc/inc/types.hxx | 8 | ||||
-rw-r--r-- | sc/source/core/data/bcaslot.cxx | 36 | ||||
-rw-r--r-- | sc/source/core/data/documen7.cxx | 2 | ||||
-rw-r--r-- | sc/source/core/data/table3.cxx | 67 | ||||
-rw-r--r-- | sc/source/core/inc/bcaslot.hxx | 6 | ||||
-rw-r--r-- | sc/source/core/tool/token.cxx | 2 |
6 files changed, 111 insertions, 10 deletions
diff --git a/sc/inc/types.hxx b/sc/inc/types.hxx index 732ff190ca64..5226463ad3c3 100644 --- a/sc/inc/types.hxx +++ b/sc/inc/types.hxx @@ -100,6 +100,14 @@ struct RangeMatrix typedef boost::unordered_map<SCCOLROW,SCCOLROW> ColRowReorderMapType; +enum AreaOverlapType +{ + AreaInside, + AreaPartialOverlap, + OneRowInsideArea, + OneColumnInsideArea +}; + } #endif 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(); |