summaryrefslogtreecommitdiff
path: root/sc/source/core/data
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@collabora.com>2014-11-25 00:02:21 -0500
committerKohei Yoshida <kohei.yoshida@collabora.com>2014-11-25 10:00:49 -0500
commit7d52a5dff557117c0f8710eb27e61b328323ac90 (patch)
treeada43bcb8a7ed736d55c840760bc58135b98f85e /sc/source/core/data
parent847ac84d64cbbebe50d4ac5c21f5bda9e83d7fa4 (diff)
Adjust ref undo to ensure group area listeners are used.
When undoing row deletion (and possibly other similar undo's). And write test for it. Change-Id: I04b4fd9932f4236f124dcd25967355c6055dec33 (cherry picked from commit 0dae7466fff1e742543ef7512b7dd22472c75624)
Diffstat (limited to 'sc/source/core/data')
-rw-r--r--sc/source/core/data/bcaslot.cxx24
-rw-r--r--sc/source/core/data/cellvalue.cxx4
-rw-r--r--sc/source/core/data/clipcontext.cxx14
-rw-r--r--sc/source/core/data/column.cxx36
-rw-r--r--sc/source/core/data/column3.cxx43
-rw-r--r--sc/source/core/data/column4.cxx2
-rw-r--r--sc/source/core/data/document.cxx28
-rw-r--r--sc/source/core/data/document10.cxx34
-rw-r--r--sc/source/core/data/formulacell.cxx59
-rw-r--r--sc/source/core/data/table2.cxx14
10 files changed, 214 insertions, 44 deletions
diff --git a/sc/source/core/data/bcaslot.cxx b/sc/source/core/data/bcaslot.cxx
index 0678a7febc70..4290fbd402ea 100644
--- a/sc/source/core/data/bcaslot.cxx
+++ b/sc/source/core/data/bcaslot.cxx
@@ -64,6 +64,30 @@
// STATIC DATA -----------------------------------------------------------
+namespace sc {
+
+bool AreaListener::SortByArea::operator ()( const AreaListener& rLeft, const AreaListener& rRight ) const
+{
+ if (rLeft.maArea.aStart.Tab() != rRight.maArea.aStart.Tab())
+ return rLeft.maArea.aStart.Tab() < rRight.maArea.aStart.Tab();
+
+ if (rLeft.maArea.aStart.Col() != rRight.maArea.aStart.Col())
+ return rLeft.maArea.aStart.Col() < rRight.maArea.aStart.Col();
+
+ if (rLeft.maArea.aStart.Row() != rRight.maArea.aStart.Row())
+ return rLeft.maArea.aStart.Row() < rRight.maArea.aStart.Row();
+
+ if (rLeft.maArea.aEnd.Tab() != rRight.maArea.aEnd.Tab())
+ return rLeft.maArea.aEnd.Tab() < rRight.maArea.aEnd.Tab();
+
+ if (rLeft.maArea.aEnd.Col() != rRight.maArea.aEnd.Col())
+ return rLeft.maArea.aEnd.Col() < rRight.maArea.aEnd.Col();
+
+ return rLeft.maArea.aEnd.Row() < rRight.maArea.aEnd.Row();
+}
+
+}
+
struct ScSlotData
{
SCROW nStartRow; // first row of this segment
diff --git a/sc/source/core/data/cellvalue.cxx b/sc/source/core/data/cellvalue.cxx
index b9eb32b2bc34..8a69d12dafbe 100644
--- a/sc/source/core/data/cellvalue.cxx
+++ b/sc/source/core/data/cellvalue.cxx
@@ -440,7 +440,7 @@ void ScCellValue::release( ScDocument& rDoc, const ScAddress& rPos )
mfValue = 0.0;
}
-void ScCellValue::release( ScColumn& rColumn, SCROW nRow )
+void ScCellValue::release( ScColumn& rColumn, SCROW nRow, sc::StartListeningType eListenType )
{
switch (meType)
{
@@ -460,7 +460,7 @@ void ScCellValue::release( ScColumn& rColumn, SCROW nRow )
break;
case CELLTYPE_FORMULA:
// This formula cell instance is directly placed in the document without copying.
- rColumn.SetFormulaCell(nRow, mpFormula);
+ rColumn.SetFormulaCell(nRow, mpFormula, eListenType);
break;
default:
rColumn.Delete(nRow);
diff --git a/sc/source/core/data/clipcontext.cxx b/sc/source/core/data/clipcontext.cxx
index 5fd08da7ef0c..83003273b62b 100644
--- a/sc/source/core/data/clipcontext.cxx
+++ b/sc/source/core/data/clipcontext.cxx
@@ -327,9 +327,21 @@ bool CopyToClipContext::isCloneNotes() const
return mbCloneNotes;
}
-CopyToDocContext::CopyToDocContext(ScDocument& rDoc) : ClipContextBase(rDoc) {}
+CopyToDocContext::CopyToDocContext(ScDocument& rDoc) :
+ ClipContextBase(rDoc), mbStartListening(true) {}
+
CopyToDocContext::~CopyToDocContext() {}
+void CopyToDocContext::setStartListening( bool b )
+{
+ mbStartListening = b;
+}
+
+bool CopyToDocContext::isStartListening() const
+{
+ return mbStartListening;
+}
+
MixDocContext::MixDocContext(ScDocument& rDoc) : ClipContextBase(rDoc) {}
MixDocContext::~MixDocContext() {}
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index c0e2991912c3..d9532307409e 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -1232,6 +1232,8 @@ class CopyAsLinkHandler
sc::ColumnBlockPosition* mpDestPos;
InsertDeleteFlags mnCopyFlags;
+ sc::StartListeningType meListenType;
+
void setDefaultAttrToDest(size_t nRow)
{
maDestPos.miCellTextAttrPos = mrDestCol.GetCellAttrStore().set(
@@ -1263,7 +1265,7 @@ class CopyAsLinkHandler
for (size_t i = 0; i < nDataSize; ++i)
{
SCROW nRow = nTopRow + i;
- mrDestCol.SetFormulaCell(maDestPos, nRow, createRefCell(nRow));
+ mrDestCol.SetFormulaCell(maDestPos, nRow, createRefCell(nRow), meListenType);
}
setDefaultAttrsToDest(nTopRow, nDataSize);
@@ -1276,7 +1278,11 @@ class CopyAsLinkHandler
public:
CopyAsLinkHandler(const ScColumn& rSrcCol, ScColumn& rDestCol, sc::ColumnBlockPosition* pDestPos, InsertDeleteFlags nCopyFlags) :
- mrSrcCol(rSrcCol), mrDestCol(rDestCol), mpDestPos(pDestPos), mnCopyFlags(nCopyFlags)
+ mrSrcCol(rSrcCol),
+ mrDestCol(rDestCol),
+ mpDestPos(pDestPos),
+ mnCopyFlags(nCopyFlags),
+ meListenType(sc::SingleCellListening)
{
if (mpDestPos)
maDestPos = *mpDestPos;
@@ -1288,6 +1294,11 @@ public:
*mpDestPos = maDestPos;
}
+ void setStartListening( bool b )
+ {
+ meListenType = b ? sc::SingleCellListening : sc::NoListening;
+ }
+
void operator() (const sc::CellStoreType::value_type& aNode, size_t nOffset, size_t nDataSize)
{
size_t nRow = aNode.position + nOffset;
@@ -1353,6 +1364,8 @@ class CopyByCloneHandler
svl::SharedStringPool* mpSharedStringPool;
InsertDeleteFlags mnCopyFlags;
+ sc::StartListeningType meListenType;
+
void setDefaultAttrToDest(size_t nRow)
{
maDestPos.miCellTextAttrPos = mrDestCol.GetCellAttrStore().set(
@@ -1396,7 +1409,7 @@ class CopyByCloneHandler
// Clone as formula cell.
ScFormulaCell* pCell = new ScFormulaCell(rSrcCell, mrDestCol.GetDoc(), aDestPos);
pCell->SetDirtyVar();
- mrDestCol.SetFormulaCell(maDestPos, nRow, pCell);
+ mrDestCol.SetFormulaCell(maDestPos, nRow, pCell, meListenType);
setDefaultAttrToDest(nRow);
return;
}
@@ -1412,7 +1425,7 @@ class CopyByCloneHandler
// error codes are cloned with values
ScFormulaCell* pErrCell = new ScFormulaCell(&mrDestCol.GetDoc(), aDestPos);
pErrCell->SetErrCode(nErr);
- mrDestCol.SetFormulaCell(maDestPos, nRow, pErrCell);
+ mrDestCol.SetFormulaCell(maDestPos, nRow, pErrCell, meListenType);
setDefaultAttrToDest(nRow);
return;
}
@@ -1466,8 +1479,12 @@ class CopyByCloneHandler
public:
CopyByCloneHandler(const ScColumn& rSrcCol, ScColumn& rDestCol, sc::ColumnBlockPosition* pDestPos,
InsertDeleteFlags nCopyFlags, svl::SharedStringPool* pSharedStringPool) :
- mrSrcCol(rSrcCol), mrDestCol(rDestCol), mpDestPos(pDestPos), mpSharedStringPool(pSharedStringPool),
- mnCopyFlags(nCopyFlags)
+ mrSrcCol(rSrcCol),
+ mrDestCol(rDestCol),
+ mpDestPos(pDestPos),
+ mpSharedStringPool(pSharedStringPool),
+ mnCopyFlags(nCopyFlags),
+ meListenType(sc::SingleCellListening)
{
if (mpDestPos)
maDestPos = *mpDestPos;
@@ -1479,6 +1496,11 @@ public:
*mpDestPos = maDestPos;
}
+ void setStartListening( bool b )
+ {
+ meListenType = b ? sc::SingleCellListening : sc::NoListening;
+ }
+
void operator() (const sc::CellStoreType::value_type& aNode, size_t nOffset, size_t nDataSize)
{
size_t nRow = aNode.position + nOffset;
@@ -1642,6 +1664,7 @@ void ScColumn::CopyToColumn(
if (bAsLink)
{
CopyAsLinkHandler aFunc(*this, rColumn, rCxt.getBlockPosition(rColumn.nTab, rColumn.nCol), nFlags);
+ aFunc.setStartListening(rCxt.isStartListening());
sc::ParseBlock(maCells.begin(), maCells, aFunc, nRow1, nRow2);
}
else
@@ -1653,6 +1676,7 @@ void ScColumn::CopyToColumn(
&rColumn.pDocument->GetSharedStringPool() : NULL;
CopyByCloneHandler aFunc(*this, rColumn, rCxt.getBlockPosition(rColumn.nTab, rColumn.nCol), nFlags,
pSharedStringPool);
+ aFunc.setStartListening(rCxt.isStartListening());
sc::ParseBlock(maCells.begin(), maCells, aFunc, nRow1, nRow2);
}
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index ae58aecf50a5..803bd3520811 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -377,13 +377,15 @@ sc::CellStoreType::iterator ScColumn::GetPositionToInsert( const sc::CellStoreTy
}
void ScColumn::AttachNewFormulaCell(
- const sc::CellStoreType::iterator& itPos, SCROW nRow, ScFormulaCell& rCell, bool bJoin, bool bSingle )
+ const sc::CellStoreType::iterator& itPos, SCROW nRow, ScFormulaCell& rCell,
+ bool bJoin, sc::StartListeningType eListenType )
{
- AttachNewFormulaCell(maCells.position(itPos, nRow), rCell, bJoin, bSingle);
+ AttachNewFormulaCell(maCells.position(itPos, nRow), rCell, bJoin, eListenType);
}
void ScColumn::AttachNewFormulaCell(
- const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell, bool bJoin, bool bSingle )
+ const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell,
+ bool bJoin, sc::StartListeningType eListenType )
{
if (bJoin)
// See if this new formula cell can join an existing shared formula group.
@@ -394,9 +396,12 @@ void ScColumn::AttachNewFormulaCell(
// we call StartListeningFromClip and BroadcastFromClip.
// If we insert into the Clipboard/andoDoc, we do not use a Broadcast.
// After Import we call CalcAfterLoad and in there Listening.
- if (!pDocument->IsClipOrUndo() && !pDocument->IsInsertingFromOtherDoc())
+ if (pDocument->IsClipOrUndo() || pDocument->IsInsertingFromOtherDoc())
+ return;
+
+ switch (eListenType)
{
- if (bSingle)
+ case sc::ConvertToGroupListening:
{
boost::shared_ptr<sc::ColumnBlockPositionSet> pPosSet(new sc::ColumnBlockPositionSet(*pDocument));
sc::StartListeningContext aStartCxt(*pDocument, pPosSet);
@@ -404,12 +409,18 @@ void ScColumn::AttachNewFormulaCell(
SCROW nRow = aPos.first->position + aPos.second;
StartListeningFormulaCells(aStartCxt, aEndCxt, nRow, nRow);
}
- else
+ break;
+ case sc::SingleCellListening:
rCell.StartListeningTo(pDocument);
+ break;
+ case sc::NoListening:
+ default:
+ ;
- if (!pDocument->IsCalcingAfterLoad())
- rCell.SetDirty();
}
+
+ if (!pDocument->IsCalcingAfterLoad())
+ rCell.SetDirty();
}
void ScColumn::AttachNewFormulaCells( const sc::CellStoreType::position_type& aPos, size_t nLength )
@@ -1734,7 +1745,10 @@ bool ScColumn::SetString( SCROW nRow, SCTAB nTabP, const OUString& rString,
ScCellValue aNewCell;
bool bNumFmtSet = ParseString(aNewCell, nRow, nTabP, rString, eConv, pParam);
- aNewCell.release(*this, nRow);
+ if (pParam)
+ aNewCell.release(*this, nRow, pParam->meStartListening);
+ else
+ aNewCell.release(*this, nRow);
// Do not set Formats and Formulas here anymore!
// These are queried during output
@@ -1834,7 +1848,8 @@ void ScColumn::SetFormula( SCROW nRow, const OUString& rFormula, formula::Formul
AttachNewFormulaCell(it, nRow, *pCell);
}
-ScFormulaCell* ScColumn::SetFormulaCell( SCROW nRow, ScFormulaCell* pCell, bool bSingle )
+ScFormulaCell* ScColumn::SetFormulaCell(
+ SCROW nRow, ScFormulaCell* pCell, sc::StartListeningType eListenType )
{
sc::CellStoreType::iterator it = GetPositionToInsert(nRow);
sal_uInt32 nCellFormat = GetNumberFormat(nRow);
@@ -1845,11 +1860,13 @@ ScFormulaCell* ScColumn::SetFormulaCell( SCROW nRow, ScFormulaCell* pCell, bool
CellStorageModified();
- AttachNewFormulaCell(it, nRow, *pCell, true, bSingle);
+ AttachNewFormulaCell(it, nRow, *pCell, true, eListenType);
return pCell;
}
-ScFormulaCell* ScColumn::SetFormulaCell( sc::ColumnBlockPosition& rBlockPos, SCROW nRow, ScFormulaCell* pCell )
+ScFormulaCell* ScColumn::SetFormulaCell(
+ sc::ColumnBlockPosition& rBlockPos, SCROW nRow, ScFormulaCell* pCell,
+ sc::StartListeningType eListenType )
{
rBlockPos.miCellPos = GetPositionToInsert(rBlockPos.miCellPos, nRow);
sal_uInt32 nCellFormat = GetNumberFormat(nRow);
@@ -1861,7 +1878,7 @@ ScFormulaCell* ScColumn::SetFormulaCell( sc::ColumnBlockPosition& rBlockPos, SCR
CellStorageModified();
- AttachNewFormulaCell(rBlockPos.miCellPos, nRow, *pCell);
+ AttachNewFormulaCell(rBlockPos.miCellPos, nRow, *pCell, true, eListenType);
return pCell;
}
diff --git a/sc/source/core/data/column4.cxx b/sc/source/core/data/column4.cxx
index 42d166a0e7c0..ab804ddf4340 100644
--- a/sc/source/core/data/column4.cxx
+++ b/sc/source/core/data/column4.cxx
@@ -1240,8 +1240,6 @@ public:
{
return mnEndRow;
}
-
-private:
};
class EndListeningFormulaCellsHandler
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index a206c09b5e04..660b39469133 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -1960,8 +1960,8 @@ void ScDocument::UndoToDocument(SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
PutInOrder( nTab1, nTab2 );
if (ValidTab(nTab1) && ValidTab(nTab2))
{
- bool bOldAutoCalc = pDestDoc->GetAutoCalc();
- pDestDoc->SetAutoCalc( false ); // avoid multiple calculations
+ sc::AutoCalcSwitch aACSwitch(*pDestDoc, false); // avoid multiple calculations
+
if (nTab1 > 0)
CopyToDocument( 0,0,0, MAXCOL,MAXROW,nTab1-1, IDF_FORMULA, false, pDestDoc, pMarks );
@@ -1976,7 +1976,6 @@ void ScDocument::UndoToDocument(SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
if (nTab2 < MAXTAB)
CopyToDocument( 0,0,nTab2+1, MAXCOL,MAXROW,MAXTAB, IDF_FORMULA, false, pDestDoc, pMarks );
- pDestDoc->SetAutoCalc( bOldAutoCalc );
}
}
@@ -1989,21 +1988,26 @@ void ScDocument::CopyToDocument(const ScRange& rRange,
if( pDestDoc->aDocName.isEmpty() )
pDestDoc->aDocName = aDocName;
- bool bOldAutoCalc = pDestDoc->GetAutoCalc();
- pDestDoc->SetAutoCalc( false ); // avoid multiple calculations
+
+ sc::AutoCalcSwitch aACSwitch(*pDestDoc, false); // avoid multiple calculations
+
sc::CopyToDocContext aCxt(*pDestDoc);
+ aCxt.setStartListening(false);
+
SCTAB nMinSizeBothTabs = static_cast<SCTAB>(std::min(maTabs.size(), pDestDoc->maTabs.size()));
for (SCTAB i = aNewRange.aStart.Tab(); i <= aNewRange.aEnd.Tab() && i < nMinSizeBothTabs; i++)
{
- if (!TableExists(i) || !pDestDoc->TableExists(i))
+ ScTable* pTab = FetchTable(i);
+ ScTable* pDestTab = pDestDoc->FetchTable(i);
+ if (!pTab || !pDestTab)
continue;
- maTabs[i]->CopyToTable(aCxt, aNewRange.aStart.Col(), aNewRange.aStart.Row(),
- aNewRange.aEnd.Col(), aNewRange.aEnd.Row(),
- nFlags, bOnlyMarked, pDestDoc->maTabs[i],
- pMarks, false, bColRowFlags);
+ pTab->CopyToTable(
+ aCxt, aNewRange.aStart.Col(), aNewRange.aStart.Row(), aNewRange.aEnd.Col(), aNewRange.aEnd.Row(),
+ nFlags, bOnlyMarked, pDestTab, pMarks, false, bColRowFlags);
}
- pDestDoc->SetAutoCalc( bOldAutoCalc );
+
+ pDestDoc->StartAllListeners(aNewRange);
}
void ScDocument::UndoToDocument(const ScRange& rRange,
@@ -2452,7 +2456,7 @@ void ScDocument::StartListeningFromClip( SCCOL nCol1, SCROW nRow1,
ScMarkData::const_iterator itr = rMark.begin(), itrEnd = rMark.end();
for (; itr != itrEnd && *itr < nMax; ++itr)
if (maTabs[*itr])
- maTabs[*itr]->StartListeningFromClip(aStartCxt, aEndCxt, nCol1, nRow1, nCol2, nRow2);
+ maTabs[*itr]->StartListeningFormulaCells(aStartCxt, aEndCxt, nCol1, nRow1, nCol2, nRow2);
}
}
diff --git a/sc/source/core/data/document10.cxx b/sc/source/core/data/document10.cxx
index d1b41687fb3e..c01b2647a755 100644
--- a/sc/source/core/data/document10.cxx
+++ b/sc/source/core/data/document10.cxx
@@ -423,4 +423,38 @@ void ScDocument::StartNeededListeners()
std::for_each(maTabs.begin(), maTabs.end(), StartNeededListenersHandler(*this));
}
+void ScDocument::StartAllListeners( const ScRange& rRange )
+{
+ boost::shared_ptr<sc::ColumnBlockPositionSet> pPosSet(new sc::ColumnBlockPositionSet(*this));
+ sc::StartListeningContext aStartCxt(*this, pPosSet);
+ sc::EndListeningContext aEndCxt(*this, pPosSet);
+
+ for (SCTAB nTab = rRange.aStart.Tab(); nTab <= rRange.aEnd.Tab(); ++nTab)
+ {
+ ScTable* pTab = FetchTable(nTab);
+ if (!pTab)
+ continue;
+
+ pTab->StartListeningFormulaCells(
+ aStartCxt, aEndCxt,
+ rRange.aStart.Col(), rRange.aStart.Row(), rRange.aEnd.Col(), rRange.aEnd.Row());
+ }
+}
+
+void ScDocument::EndAllListeners( const ScRange& rRange )
+{
+ sc::EndListeningContext aEndCxt(*this);
+
+ for (SCTAB nTab = rRange.aStart.Tab(); nTab <= rRange.aEnd.Tab(); ++nTab)
+ {
+ ScTable* pTab = FetchTable(nTab);
+ if (!pTab)
+ continue;
+
+ pTab->EndListeningFormulaCells(
+ aEndCxt,
+ rRange.aStart.Col(), rRange.aStart.Row(), rRange.aEnd.Col(), rRange.aEnd.Row());
+ }
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index dfeda726016f..a34d3fb139f4 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -61,6 +61,7 @@
#include <grouparealistener.hxx>
#include <boost/scoped_ptr.hpp>
+#include <boost/ptr_container/ptr_map.hpp>
using namespace formula;
@@ -382,6 +383,40 @@ void adjustDBRange(formula::FormulaToken* pToken, ScDocument& rNewDoc, const ScD
pToken->SetIndex(pNewDBData->GetIndex());
}
+struct AreaListenerKey
+{
+ ScRange maRange;
+ bool mbStartFixed;
+ bool mbEndFixed;
+
+ AreaListenerKey( const ScRange& rRange, bool bStartFixed, bool bEndFixed ) :
+ maRange(rRange), mbStartFixed(bStartFixed), mbEndFixed(bEndFixed) {}
+
+ bool operator < ( const AreaListenerKey& r ) const
+ {
+ if (maRange.aStart.Tab() != r.maRange.aStart.Tab())
+ return maRange.aStart.Tab() < r.maRange.aStart.Tab();
+ if (maRange.aStart.Col() != r.maRange.aStart.Col())
+ return maRange.aStart.Col() < r.maRange.aStart.Col();
+ if (maRange.aStart.Row() != r.maRange.aStart.Row())
+ return maRange.aStart.Row() < r.maRange.aStart.Row();
+ if (maRange.aEnd.Tab() != r.maRange.aEnd.Tab())
+ return maRange.aEnd.Tab() < r.maRange.aEnd.Tab();
+ if (maRange.aEnd.Col() != r.maRange.aEnd.Col())
+ return maRange.aEnd.Col() < r.maRange.aEnd.Col();
+ if (maRange.aEnd.Row() != r.maRange.aEnd.Row())
+ return maRange.aEnd.Row() < r.maRange.aEnd.Row();
+ if (mbStartFixed != r.mbStartFixed)
+ return r.mbStartFixed;
+ if (mbEndFixed != r.mbEndFixed)
+ return r.mbEndFixed;
+
+ return false;
+ }
+};
+
+typedef boost::ptr_map<AreaListenerKey, sc::FormulaGroupAreaListener> AreaListenersType;
+
}
#if ENABLE_THREADED_OPENCL_KERNEL_COMPILATION
@@ -406,7 +441,13 @@ int ScFormulaCellGroup::snCount = 0;
rtl::Reference<sc::CLBuildKernelThread> ScFormulaCellGroup::sxCompilationThread;
#endif
+struct ScFormulaCellGroup::Impl
+{
+ AreaListenersType maAreaListeners;
+};
+
ScFormulaCellGroup::ScFormulaCellGroup() :
+ mpImpl(new Impl),
mnRefCount(0),
mpCode(NULL),
mpCompiledFormula(NULL),
@@ -450,6 +491,7 @@ ScFormulaCellGroup::~ScFormulaCellGroup()
#endif
delete mpCode;
delete mpCompiledFormula;
+ delete mpImpl;
}
void ScFormulaCellGroup::scheduleCompilation()
@@ -512,24 +554,29 @@ void ScFormulaCellGroup::compileOpenCLKernel()
sc::FormulaGroupAreaListener* ScFormulaCellGroup::getAreaListener(
ScFormulaCell** ppTopCell, const ScRange& rRange, bool bStartFixed, bool bEndFixed )
{
- // TODO : Find existing one with the same criteria.
- maAreaListeners.push_back(new sc::FormulaGroupAreaListener(rRange, ppTopCell, mnLength, bStartFixed, bEndFixed));
- return &maAreaListeners.back();
+ AreaListenerKey aKey(rRange, bStartFixed, bEndFixed);
+
+ std::pair<AreaListenersType::iterator, bool> r =
+ mpImpl->maAreaListeners.insert(
+ aKey, new sc::FormulaGroupAreaListener(
+ rRange, ppTopCell, mnLength, bStartFixed, bEndFixed));
+
+ return r.first->second;
}
void ScFormulaCellGroup::endAllGroupListening( ScDocument& rDoc )
{
- AreaListenersType::iterator it = maAreaListeners.begin(), itEnd = maAreaListeners.end();
+ AreaListenersType::iterator it = mpImpl->maAreaListeners.begin(), itEnd = mpImpl->maAreaListeners.end();
for (; it != itEnd; ++it)
{
- sc::FormulaGroupAreaListener* pListener = &(*it);
+ sc::FormulaGroupAreaListener* pListener = it->second;
ScRange aListenRange = pListener->getListeningRange();
// This "always listen" special range is never grouped.
bool bGroupListening = (aListenRange != BCA_LISTEN_ALWAYS);
rDoc.EndListeningArea(aListenRange, bGroupListening, pListener);
}
- maAreaListeners.clear();
+ mpImpl->maAreaListeners.clear();
}
ScFormulaCell::ScFormulaCell( ScDocument* pDoc, const ScAddress& rPos ) :
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index 97355424c8c3..608ec13014a4 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -1057,7 +1057,7 @@ void ScTable::SetDirtyFromClip(
aCol[i].SetDirtyFromClip(nRow1, nRow2, rBroadcastSpans);
}
-void ScTable::StartListeningFromClip(
+void ScTable::StartListeningFormulaCells(
sc::StartListeningContext& rStartCxt, sc::EndListeningContext& rEndCxt,
SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
{
@@ -1068,6 +1068,16 @@ void ScTable::StartListeningFromClip(
aCol[i].StartListeningFormulaCells(rStartCxt, rEndCxt, nRow1, nRow2);
}
+void ScTable::EndListeningFormulaCells(
+ sc::EndListeningContext& rEndCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
+{
+ if (nCol2 > MAXCOL) nCol2 = MAXCOL;
+ if (nRow2 > MAXROW) nRow2 = MAXROW;
+ if (ValidColRow(nCol1, nRow1) && ValidColRow(nCol2, nRow2))
+ for (SCCOL i = nCol1; i <= nCol2; ++i)
+ aCol[i].EndListeningFormulaCells(rEndCxt, nRow1, nRow2);
+}
+
void ScTable::CopyToTable(
sc::CopyToDocContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
InsertDeleteFlags nFlags, bool bMarked, ScTable* pDestTab, const ScMarkData* pMarkData,
@@ -1413,7 +1423,7 @@ ScFormulaCell* ScTable::SetFormulaCell( SCCOL nCol, SCROW nRow, ScFormulaCell* p
return NULL;
}
- return aCol[nCol].SetFormulaCell(nRow, pCell, true);
+ return aCol[nCol].SetFormulaCell(nRow, pCell, sc::ConvertToGroupListening);
}
bool ScTable::SetFormulaCells( SCCOL nCol, SCROW nRow, std::vector<ScFormulaCell*>& rCells )