diff options
author | Kohei Yoshida <kohei.yoshida@collabora.com> | 2014-12-05 22:01:29 -0500 |
---|---|---|
committer | Kohei Yoshida <kohei.yoshida@collabora.com> | 2014-12-05 22:45:40 -0500 |
commit | 68fd7b7adc3021d30460a2c80d6876df239fd490 (patch) | |
tree | 36ba2c8efa323a3cc1ae1bdb62f3d65df90cb2a3 /sc | |
parent | d0894ff58fbdd823273bc91939801971b7a03182 (diff) |
Fix incorrect adjustment of range references during sort.
... as a result of the introduction of range-based area listeners.
With this change, the insertRangeData() function for ucalc no longer needs
the additional bGroupListening flag. All tests pass with group listening
enabled at all times.
Change-Id: I9b9fb9443c727ff62badbd60ec9cd94094eb5a45
Diffstat (limited to 'sc')
-rw-r--r-- | sc/inc/column.hxx | 1 | ||||
-rw-r--r-- | sc/inc/columnspanset.hxx | 2 | ||||
-rw-r--r-- | sc/inc/grouparealistener.hxx | 2 | ||||
-rw-r--r-- | sc/inc/listenerquery.hxx | 19 | ||||
-rw-r--r-- | sc/inc/listenerqueryids.hxx | 3 | ||||
-rw-r--r-- | sc/inc/rangelst.hxx | 2 | ||||
-rw-r--r-- | sc/inc/types.hxx | 8 | ||||
-rw-r--r-- | sc/qa/unit/ucalc.hxx | 22 | ||||
-rw-r--r-- | sc/qa/unit/ucalc_formula.cxx | 2 | ||||
-rw-r--r-- | sc/qa/unit/ucalc_sharedformula.cxx | 2 | ||||
-rw-r--r-- | sc/source/core/data/bcaslot.cxx | 26 | ||||
-rw-r--r-- | sc/source/core/data/column4.cxx | 21 | ||||
-rw-r--r-- | sc/source/core/data/columnspanset.cxx | 6 | ||||
-rw-r--r-- | sc/source/core/data/table3.cxx | 153 | ||||
-rw-r--r-- | sc/source/core/inc/bcaslot.hxx | 6 | ||||
-rw-r--r-- | sc/source/core/tool/grouparealistener.cxx | 26 | ||||
-rw-r--r-- | sc/source/core/tool/listenerquery.cxx | 25 | ||||
-rw-r--r-- | sc/source/core/tool/rangelst.cxx | 6 |
18 files changed, 307 insertions, 25 deletions
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx index 7d7e39ba9974..87099351b97f 100644 --- a/sc/inc/column.hxx +++ b/sc/inc/column.hxx @@ -510,6 +510,7 @@ public: void BroadcastRecalcOnRefMove(); void TransferListeners( ScColumn& rDestCol, SCROW nRow1, SCROW nRow2, SCROW nRowDelta ); void CollectListeners( std::vector<SvtListener*>& rListeners, SCROW nRow1, SCROW nRow2 ); + void CollectFormulaCells( std::vector<ScFormulaCell*>& rCells, SCROW nRow1, SCROW nRow2 ); void CompileDBFormula( sc::CompileFormulaContext& rCxt ); void CompileColRowNameFormula( sc::CompileFormulaContext& rCxt ); diff --git a/sc/inc/columnspanset.hxx b/sc/inc/columnspanset.hxx index 63e8c9025e63..797b425579c5 100644 --- a/sc/inc/columnspanset.hxx +++ b/sc/inc/columnspanset.hxx @@ -103,6 +103,8 @@ public: void executeAction(Action& ac) const; void executeColumnAction(ScDocument& rDoc, ColumnAction& ac) const; + + void swap( ColumnSpanSet& r ); }; /** diff --git a/sc/inc/grouparealistener.hxx b/sc/inc/grouparealistener.hxx index 2c6ea50e2f8c..feb10df0fb63 100644 --- a/sc/inc/grouparealistener.hxx +++ b/sc/inc/grouparealistener.hxx @@ -39,6 +39,7 @@ public: ScRange getListeningRange() const; virtual void Notify( const SfxHint& rHint ) SAL_OVERRIDE; + virtual void Query( QueryBase& rQuery ) const SAL_OVERRIDE; /** * Given the row span of changed cells within a single column, collect all @@ -52,6 +53,7 @@ public: * this container. */ void collectFormulaCells( SCTAB nTab, SCCOL nCol, SCROW nRow1, SCROW nRow2, std::vector<ScFormulaCell*>& rCells ) const; + void collectFormulaCells( SCROW nRow1, SCROW nRow2, std::vector<ScFormulaCell*>& rCells ) const; ScAddress getTopCellPos() const; const ScRange& getRange() const; diff --git a/sc/inc/listenerquery.hxx b/sc/inc/listenerquery.hxx index c0620bb1a38f..65fbc0edfb0c 100644 --- a/sc/inc/listenerquery.hxx +++ b/sc/inc/listenerquery.hxx @@ -15,6 +15,8 @@ #include <boost/unordered_map.hpp> +class ScRangeList; + namespace sc { /** @@ -45,6 +47,23 @@ private: TabsType maTabs; }; +class QueryRange : public SvtListener::QueryBase +{ + struct Impl; + Impl* mpImpl; + + QueryRange( const QueryRange& ); // disabled + QueryRange& operator= ( const QueryRange& ); // disabled + +public: + QueryRange(); + virtual ~QueryRange(); + + void add( const ScRange& rRange ); + + void swapRanges( ScRangeList& rRanges ); +}; + } #endif diff --git a/sc/inc/listenerqueryids.hxx b/sc/inc/listenerqueryids.hxx index 48f240b13fd8..ce8a0e252900 100644 --- a/sc/inc/listenerqueryids.hxx +++ b/sc/inc/listenerqueryids.hxx @@ -10,7 +10,8 @@ #ifndef SC_LISTENERQUERYIDS_HXX #define SC_LISTENERQUERYIDS_HXX -#define SC_LISTENER_QUERY_FORMULA_GROUP_POS 0 +#define SC_LISTENER_QUERY_FORMULA_GROUP_POS 0 +#define SC_LISTENER_QUERY_FORMULA_GROUP_RANGE 1 #endif diff --git a/sc/inc/rangelst.hxx b/sc/inc/rangelst.hxx index 4a10eedbb616..062e618a5ce2 100644 --- a/sc/inc/rangelst.hxx +++ b/sc/inc/rangelst.hxx @@ -91,6 +91,8 @@ public: const ScRange* back() const; void push_back(ScRange* p); + void swap( ScRangeList& r ); + private: ::std::vector<ScRange*> maRanges; SCROW mnMaxRowUsed; diff --git a/sc/inc/types.hxx b/sc/inc/types.hxx index 039010a3fa24..77934f07482a 100644 --- a/sc/inc/types.hxx +++ b/sc/inc/types.hxx @@ -101,10 +101,18 @@ enum AreaOverlapType { AreaInside, AreaPartialOverlap, + AreaInsideOrOverlap, OneRowInsideArea, OneColumnInsideArea }; +enum ListenerGroupType +{ + ListenerSingle, + ListenerGroup, + ListenerBoth +}; + enum StartListeningType { ConvertToGroupListening, diff --git a/sc/qa/unit/ucalc.hxx b/sc/qa/unit/ucalc.hxx index cb2f8394fb79..d5fd98380263 100644 --- a/sc/qa/unit/ucalc.hxx +++ b/sc/qa/unit/ucalc.hxx @@ -59,13 +59,8 @@ public: template<size_t _Size> static ScRange insertRangeData( - ScDocument* pDoc, const ScAddress& rPos, const char* aData[][_Size], size_t nRowCount, - bool bGroupListening = false ) + ScDocument* pDoc, const ScAddress& rPos, const char* aData[][_Size], size_t nRowCount ) { - // TODO : Ideally bGroupListening should be always true for all tests. - // Eventually we want to drop this parameter once all tests pass with - // group listening turned on. - ScRange aRange(rPos); aRange.aEnd.SetCol(rPos.Col()+_Size-1); aRange.aEnd.SetRow(rPos.Row()+nRowCount-1); @@ -82,19 +77,14 @@ public: SCCOL nCol = i + rPos.Col(); SCROW nRow = j + rPos.Row(); OUString aStr(aData[j][i], strlen(aData[j][i]), RTL_TEXTENCODING_UTF8); - if (bGroupListening) - { - ScSetStringParam aParam; // Leave default. - aParam.meStartListening = sc::NoListening; - pDoc->SetString(nCol, nRow, rPos.Tab(), aStr, &aParam); - } - else - pDoc->SetString(nCol, nRow, rPos.Tab(), aStr, NULL); + + ScSetStringParam aParam; // Leave default. + aParam.meStartListening = sc::NoListening; + pDoc->SetString(nCol, nRow, rPos.Tab(), aStr, &aParam); } } - if (bGroupListening) - pDoc->StartAllListeners(aRange); + pDoc->StartAllListeners(aRange); printRange(pDoc, aRange, "Range data content"); return aRange; diff --git a/sc/qa/unit/ucalc_formula.cxx b/sc/qa/unit/ucalc_formula.cxx index 56f5f8c080a5..c66194c34a4b 100644 --- a/sc/qa/unit/ucalc_formula.cxx +++ b/sc/qa/unit/ucalc_formula.cxx @@ -4274,7 +4274,7 @@ void Test::testFormulaDepTracking3() { "5", "6", "=SUM(A3:B3)", 0 }, }; - insertRangeData(m_pDoc, ScAddress(0,0,0), pData, SAL_N_ELEMENTS(pData), true); + insertRangeData(m_pDoc, ScAddress(0,0,0), pData, SAL_N_ELEMENTS(pData)); // Check the initial formula results. CPPUNIT_ASSERT_EQUAL( 3.0, m_pDoc->GetValue(ScAddress(2,0,0))); diff --git a/sc/qa/unit/ucalc_sharedformula.cxx b/sc/qa/unit/ucalc_sharedformula.cxx index 811612379163..2ef7d88b06c8 100644 --- a/sc/qa/unit/ucalc_sharedformula.cxx +++ b/sc/qa/unit/ucalc_sharedformula.cxx @@ -596,7 +596,7 @@ void Test::testSharedFormulasRefUpdateRangeDeleteRow() { "7", "8", "=SUM(A5:B5)" } }; - insertRangeData(m_pDoc, ScAddress(0,0,0), aData, SAL_N_ELEMENTS(aData), true); + insertRangeData(m_pDoc, ScAddress(0,0,0), aData, SAL_N_ELEMENTS(aData)); // Check initial formula values. CPPUNIT_ASSERT_EQUAL( 3.0, m_pDoc->GetValue(ScAddress(2,0,0))); diff --git a/sc/source/core/data/bcaslot.cxx b/sc/source/core/data/bcaslot.cxx index 31b665c50255..12aeee70f652 100644 --- a/sc/source/core/data/bcaslot.cxx +++ b/sc/source/core/data/bcaslot.cxx @@ -587,7 +587,8 @@ void ScBroadcastAreaSlot::EraseArea( ScBroadcastAreas::iterator& rIter ) } void ScBroadcastAreaSlot::GetAllListeners( - const ScRange& rRange, std::vector<sc::AreaListener>& rListeners, sc::AreaOverlapType eType ) + const ScRange& rRange, std::vector<sc::AreaListener>& rListeners, + sc::AreaOverlapType eType, sc::ListenerGroupType eGroup ) { for (ScBroadcastAreas::const_iterator aIter( aBroadcastAreaTbl.begin()), aIterEnd( aBroadcastAreaTbl.end()); aIter != aIterEnd; ++aIter ) @@ -597,6 +598,20 @@ void ScBroadcastAreaSlot::GetAllListeners( ScBroadcastArea* pArea = (*aIter).mpArea; const ScRange& rAreaRange = pArea->GetRange(); + switch (eGroup) + { + case sc::ListenerSingle: + if (pArea->IsGroupListening()) + continue; + break; + case sc::ListenerGroup: + if (!pArea->IsGroupListening()) + continue; + break; + case sc::ListenerBoth: + default: + ; + } switch (eType) { @@ -610,6 +625,11 @@ void ScBroadcastAreaSlot::GetAllListeners( // The range needs to be only partially overlapping. continue; break; + case sc::AreaInsideOrOverlap: + if (!rRange.Intersects(rAreaRange)) + // The range needs to be partially overlapping or fully inside. + 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 @@ -1256,7 +1276,7 @@ void ScBroadcastAreaSlotMachine::FinallyEraseAreas( ScBroadcastAreaSlot* pSlot ) } std::vector<sc::AreaListener> ScBroadcastAreaSlotMachine::GetAllListeners( - const ScRange& rRange, sc::AreaOverlapType eType ) + const ScRange& rRange, sc::AreaOverlapType eType, sc::ListenerGroupType eGroup ) { std::vector<sc::AreaListener> aRet; @@ -1274,7 +1294,7 @@ std::vector<sc::AreaListener> ScBroadcastAreaSlotMachine::GetAllListeners( { ScBroadcastAreaSlot* p = *pp; if (p) - p->GetAllListeners(rRange, aRet, eType); + p->GetAllListeners(rRange, aRet, eType, eGroup); ComputeNextSlot( nOff, nBreak, pp, nStart, ppSlots, nRowBreak); } } diff --git a/sc/source/core/data/column4.cxx b/sc/source/core/data/column4.cxx index ab804ddf4340..2291d3810827 100644 --- a/sc/source/core/data/column4.cxx +++ b/sc/source/core/data/column4.cxx @@ -1107,6 +1107,18 @@ public: } }; +class FormulaCellCollector +{ + std::vector<ScFormulaCell*>& mrCells; +public: + FormulaCellCollector( std::vector<ScFormulaCell*>& rCells ) : mrCells(rCells) {} + + void operator() ( size_t /*nRow*/, ScFormulaCell* p ) + { + mrCells.push_back(p); + } +}; + } void ScColumn::CollectListeners( std::vector<SvtListener*>& rListeners, SCROW nRow1, SCROW nRow2 ) @@ -1118,6 +1130,15 @@ void ScColumn::CollectListeners( std::vector<SvtListener*>& rListeners, SCROW nR sc::ProcessBroadcaster(maBroadcasters.begin(), maBroadcasters, nRow1, nRow2, aFunc); } +void ScColumn::CollectFormulaCells( std::vector<ScFormulaCell*>& rCells, SCROW nRow1, SCROW nRow2 ) +{ + if (nRow2 < nRow1 || !ValidRow(nRow1) || !ValidRow(nRow2)) + return; + + FormulaCellCollector aFunc(rCells); + sc::ProcessFormula(maCells.begin(), maCells, nRow1, nRow2, aFunc); +} + namespace { struct FindAnyFormula diff --git a/sc/source/core/data/columnspanset.cxx b/sc/source/core/data/columnspanset.cxx index 6132906db33a..25f6b5baf45b 100644 --- a/sc/source/core/data/columnspanset.cxx +++ b/sc/source/core/data/columnspanset.cxx @@ -227,6 +227,12 @@ void ColumnSpanSet::executeColumnAction(ScDocument& rDoc, ColumnAction& ac) cons } } +void ColumnSpanSet::swap( ColumnSpanSet& r ) +{ + maDoc.swap(r.maDoc); + std::swap(mbInit, r.mbInit); +} + namespace { class Scanner diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx index a7151947678c..99813566074a 100644 --- a/sc/source/core/data/table3.cxx +++ b/sc/source/core/data/table3.cxx @@ -824,6 +824,70 @@ void fillSortedColumnArray( rRowFlags.swap(aRowFlags); } +void expandRowRange( ScRange& rRange, SCROW nTop, SCROW nBottom ) +{ + if (nTop < rRange.aStart.Row()) + rRange.aStart.SetRow(nTop); + + if (rRange.aEnd.Row() < nBottom) + rRange.aEnd.SetRow(nBottom); +} + +class FormulaCellCollectAction : public sc::ColumnSpanSet::ColumnAction +{ + std::vector<ScFormulaCell*>& mrCells; + ScColumn* mpCol; + +public: + FormulaCellCollectAction( std::vector<ScFormulaCell*>& rCells ) : + mrCells(rCells), mpCol(NULL) {} + + virtual void startColumn( ScColumn* pCol ) SAL_OVERRIDE + { + mpCol = pCol; + } + + virtual void execute( SCROW nRow1, SCROW nRow2, bool bVal ) SAL_OVERRIDE + { + assert(mpCol); + + if (!bVal) + return; + + mpCol->CollectFormulaCells(mrCells, nRow1, nRow2); + } +}; + +class ListenerStartAction : public sc::ColumnSpanSet::ColumnAction +{ + ScColumn* mpCol; + + boost::shared_ptr<sc::ColumnBlockPositionSet> mpPosSet; + sc::StartListeningContext maStartCxt; + sc::EndListeningContext maEndCxt; + +public: + ListenerStartAction( ScDocument& rDoc ) : + mpPosSet(new sc::ColumnBlockPositionSet(rDoc)), + maStartCxt(rDoc, mpPosSet), + maEndCxt(rDoc, mpPosSet) {} + + virtual void startColumn( ScColumn* pCol ) SAL_OVERRIDE + { + mpCol = pCol; + } + + virtual void execute( SCROW nRow1, SCROW nRow2, bool bVal ) SAL_OVERRIDE + { + assert(mpCol); + + if (!bVal) + return; + + mpCol->StartListeningFormulaCells(maStartCxt, maEndCxt, nRow1, nRow2); + } +}; + } void ScTable::SortReorderByColumn( @@ -1121,6 +1185,78 @@ void ScTable::SortReorderByRowRefUpdate( SCROW nRow1 = pArray->GetStart(); SCROW nRow2 = pArray->GetLast(); + ScRange aMoveRange( nCol1, nRow1, nTab, nCol2, nRow2, nTab); + sc::ColumnSpanSet aGrpListenerRanges(false); + + { + // Get the range of formula group listeners within sorted range (if any). + sc::QueryRange aQuery; + + ScBroadcastAreaSlotMachine* pBASM = pDocument->GetBASM(); + std::vector<sc::AreaListener> aGrpListeners = + pBASM->GetAllListeners( + aMoveRange, sc::AreaInsideOrOverlap, sc::ListenerGroup); + + { + std::vector<sc::AreaListener>::iterator it = aGrpListeners.begin(), itEnd = aGrpListeners.end(); + for (; it != itEnd; ++it) + { + assert(it->mbGroupListening); + SvtListener* pGrpLis = it->mpListener; + pGrpLis->Query(aQuery); + pDocument->EndListeningArea(it->maArea, it->mbGroupListening, pGrpLis); + } + } + + ScRangeList aTmp; + aQuery.swapRanges(aTmp); + + // If the range is within the sorted range, we need to expand its rows + // to the top and bottom of the sorted range, since the formula cells + // could be anywhere in the sorted range after reordering. + for (size_t i = 0, n = aTmp.size(); i < n; ++i) + { + ScRange aRange = *aTmp[i]; + if (!aMoveRange.Intersects(aRange)) + { + // Doesn't overlap with the sorted range at all. + aGrpListenerRanges.set(aRange, true); + continue; + } + + if (aMoveRange.aStart.Col() <= aRange.aStart.Col() && aRange.aEnd.Col() <= aMoveRange.aEnd.Col()) + { + // Its column range is within the column range of the sorted range. + expandRowRange(aRange, aMoveRange.aStart.Row(), aMoveRange.aEnd.Row()); + aGrpListenerRanges.set(aRange, true); + continue; + } + + // It intersects with the sorted range, but its column range is + // not within the column range of the sorted range. Split it into + // 2 ranges. + ScRange aR1 = aRange; + ScRange aR2 = aRange; + if (aRange.aStart.Col() < aMoveRange.aStart.Col()) + { + // Left half is outside the sorted range while the right half is inside. + aR1.aEnd.SetCol(aMoveRange.aStart.Col()-1); + aR2.aStart.SetCol(aMoveRange.aStart.Col()); + expandRowRange(aR2, aMoveRange.aStart.Row(), aMoveRange.aEnd.Row()); + } + else + { + // Left half is inside the sorted range while the right half is outside. + aR1.aEnd.SetCol(aMoveRange.aEnd.Col()-1); + aR2.aStart.SetCol(aMoveRange.aEnd.Col()); + expandRowRange(aR1, aMoveRange.aStart.Row(), aMoveRange.aEnd.Row()); + } + + aGrpListenerRanges.set(aR1, true); + aGrpListenerRanges.set(aR2, true); + } + } + // Split formula groups at the sort range boundaries (if applicable). std::vector<SCROW> aRowBounds; aRowBounds.reserve(2); @@ -1237,7 +1373,6 @@ void ScTable::SortReorderByRowRefUpdate( // 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); { @@ -1249,6 +1384,16 @@ void ScTable::SortReorderByRowRefUpdate( } } + { + // Get all formula cells from the former group area listener ranges. + + std::vector<ScFormulaCell*> aFCells; + FormulaCellCollectAction aAction(aFCells); + aGrpListenerRanges.executeColumnAction(*pDocument, aAction); + + std::copy(aFCells.begin(), aFCells.end(), std::back_inserter(aListeners)); + } + // Remove any duplicate listener entries. We must ensure that we notify // each unique listener only once. std::sort(aListeners.begin(), aListeners.end()); @@ -1306,6 +1451,12 @@ void ScTable::SortReorderByRowRefUpdate( // Re-group columns in the sorted range too. for (SCCOL i = nCol1; i <= nCol2; ++i) aCol[i].RegroupFormulaCells(); + + { + // Re-start area listeners on the old group listener ranges. + ListenerStartAction aAction(*pDocument); + aGrpListenerRanges.executeColumnAction(*pDocument, aAction); + } } short ScTable::CompareCell( diff --git a/sc/source/core/inc/bcaslot.hxx b/sc/source/core/inc/bcaslot.hxx index 7eea13654fad..a566440b8420 100644 --- a/sc/source/core/inc/bcaslot.hxx +++ b/sc/source/core/inc/bcaslot.hxx @@ -239,7 +239,8 @@ public: void EraseArea( ScBroadcastAreas::iterator& rIter ); void GetAllListeners( - const ScRange& rRange, std::vector<sc::AreaListener>& rListeners, sc::AreaOverlapType eType ); + const ScRange& rRange, std::vector<sc::AreaListener>& rListeners, + sc::AreaOverlapType eType, sc::ListenerGroupType eGroup ); #if DEBUG_AREA_BROADCASTER void Dump() const; @@ -348,7 +349,8 @@ public: void FinallyEraseAreas( ScBroadcastAreaSlot* pSlot ); std::vector<sc::AreaListener> GetAllListeners( - const ScRange& rRange, sc::AreaOverlapType eType ); + const ScRange& rRange, sc::AreaOverlapType eType, + sc::ListenerGroupType eGroup = sc::ListenerBoth ); #if DEBUG_AREA_BROADCASTER void Dump() const; diff --git a/sc/source/core/tool/grouparealistener.cxx b/sc/source/core/tool/grouparealistener.cxx index 4a13398c2e46..224973238907 100644 --- a/sc/source/core/tool/grouparealistener.cxx +++ b/sc/source/core/tool/grouparealistener.cxx @@ -13,6 +13,8 @@ #include <bulkdatahint.hxx> #include <columnspanset.hxx> #include <column.hxx> +#include <listenerquery.hxx> +#include <listenerqueryids.hxx> namespace sc { @@ -108,6 +110,24 @@ void FormulaGroupAreaListener::Notify( const SfxHint& rHint ) } } +void FormulaGroupAreaListener::Query( QueryBase& rQuery ) const +{ + switch (rQuery.getId()) + { + case SC_LISTENER_QUERY_FORMULA_GROUP_RANGE: + { + ScFormulaCell* pTop = *mppTopCell; + ScRange aRange(pTop->aPos); + aRange.aEnd.IncRow(mnGroupLen-1); + QueryRange& rQR = static_cast<QueryRange&>(rQuery); + rQR.add(aRange); + } + break; + default: + ; + } +} + void FormulaGroupAreaListener::notifyBulkChange( const BulkDataHint& rHint ) { const ColumnSpanSet* pSpans = rHint.getSpans(); @@ -138,6 +158,12 @@ void FormulaGroupAreaListener::collectFormulaCells( // Outside the column range. return; + collectFormulaCells(nRow1, nRow2, rCells); +} + +void FormulaGroupAreaListener::collectFormulaCells( + SCROW nRow1, SCROW nRow2, std::vector<ScFormulaCell*>& rCells ) const +{ ScFormulaCell** pp = mppTopCell; ScFormulaCell** ppEnd = pp + mnGroupLen; diff --git a/sc/source/core/tool/listenerquery.cxx b/sc/source/core/tool/listenerquery.cxx index bf9d38fe2070..faa3bbb4e3a0 100644 --- a/sc/source/core/tool/listenerquery.cxx +++ b/sc/source/core/tool/listenerquery.cxx @@ -10,6 +10,7 @@ #include <listenerquery.hxx> #include <listenerqueryids.hxx> #include <address.hxx> +#include <rangelst.hxx> namespace sc { @@ -67,6 +68,30 @@ const RefQueryFormulaGroup::TabsType& RefQueryFormulaGroup::getAllPositions() co return maTabs; } +struct QueryRange::Impl +{ + ScRangeList maRanges; +}; + +QueryRange::QueryRange() : + SvtListener::QueryBase(SC_LISTENER_QUERY_FORMULA_GROUP_RANGE), + mpImpl(new Impl) {} + +QueryRange::~QueryRange() +{ + delete mpImpl; +} + +void QueryRange::add( const ScRange& rRange ) +{ + mpImpl->maRanges.Join(rRange); +} + +void QueryRange::swapRanges( ScRangeList& rRanges ) +{ + mpImpl->maRanges.swap(rRanges); +} + } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/core/tool/rangelst.cxx b/sc/source/core/tool/rangelst.cxx index 7cf7bcd0ac07..788ef961ac0d 100644 --- a/sc/source/core/tool/rangelst.cxx +++ b/sc/source/core/tool/rangelst.cxx @@ -1170,6 +1170,12 @@ void ScRangeList::push_back(ScRange* p) mnMaxRowUsed = p->aEnd.Row(); } +void ScRangeList::swap( ScRangeList& r ) +{ + maRanges.swap(r.maRanges); + std::swap(mnMaxRowUsed, r.mnMaxRowUsed); +} + ScAddress ScRangeList::GetTopLeftCorner() const { if(empty()) |