[Libreoffice-commits] core.git: sc/inc sc/qa sc/source
Kohei Yoshida
kohei.yoshida at collabora.com
Fri Dec 5 19:46:48 PST 2014
sc/inc/column.hxx | 1
sc/inc/columnspanset.hxx | 2
sc/inc/grouparealistener.hxx | 2
sc/inc/listenerquery.hxx | 19 +++
sc/inc/listenerqueryids.hxx | 3
sc/inc/rangelst.hxx | 2
sc/inc/types.hxx | 8 +
sc/qa/unit/ucalc.hxx | 22 +---
sc/qa/unit/ucalc_formula.cxx | 2
sc/qa/unit/ucalc_sharedformula.cxx | 2
sc/source/core/data/bcaslot.cxx | 26 ++++-
sc/source/core/data/column4.cxx | 21 ++++
sc/source/core/data/columnspanset.cxx | 6 +
sc/source/core/data/table3.cxx | 153 +++++++++++++++++++++++++++++-
sc/source/core/inc/bcaslot.hxx | 6 -
sc/source/core/tool/grouparealistener.cxx | 26 +++++
sc/source/core/tool/listenerquery.cxx | 25 ++++
sc/source/core/tool/rangelst.cxx | 6 +
18 files changed, 307 insertions(+), 25 deletions(-)
New commits:
commit 68fd7b7adc3021d30460a2c80d6876df239fd490
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Fri Dec 5 22:01:29 2014 -0500
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
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 7d7e39b..8709935 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 63e8c90..797b425 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 2c6ea50..feb10df 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 c0620bb..65fbc0e 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 48f240b..ce8a0e2 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 4a10eed..062e618 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 039010a..77934f0 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 cb2f839..d5fd983 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 56f5f8c..c66194c 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 8116123..2ef7d88 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 31b665c..12aeee7 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 ab804dd..2291d38 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 6132906..25f6b5b 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 a715194..9981356 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 7eea136..a566440 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 4a13398..2249732 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 bf9d38f..faa3bbb 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 7cf7bcd..788ef96 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())
More information about the Libreoffice-commits
mailing list