diff options
author | Kohei Yoshida <kohei.yoshida@collabora.com> | 2014-11-25 00:02:21 -0500 |
---|---|---|
committer | Kohei Yoshida <kohei.yoshida@collabora.com> | 2014-11-25 10:00:49 -0500 |
commit | 7d52a5dff557117c0f8710eb27e61b328323ac90 (patch) | |
tree | ada43bcb8a7ed736d55c840760bc58135b98f85e /sc/source/core/data | |
parent | 847ac84d64cbbebe50d4ac5c21f5bda9e83d7fa4 (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.cxx | 24 | ||||
-rw-r--r-- | sc/source/core/data/cellvalue.cxx | 4 | ||||
-rw-r--r-- | sc/source/core/data/clipcontext.cxx | 14 | ||||
-rw-r--r-- | sc/source/core/data/column.cxx | 36 | ||||
-rw-r--r-- | sc/source/core/data/column3.cxx | 43 | ||||
-rw-r--r-- | sc/source/core/data/column4.cxx | 2 | ||||
-rw-r--r-- | sc/source/core/data/document.cxx | 28 | ||||
-rw-r--r-- | sc/source/core/data/document10.cxx | 34 | ||||
-rw-r--r-- | sc/source/core/data/formulacell.cxx | 59 | ||||
-rw-r--r-- | sc/source/core/data/table2.cxx | 14 |
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 ) |