sc/inc/sharedformula.hxx | 3 ++- sc/source/core/data/column.cxx | 8 ++++---- sc/source/core/data/column3.cxx | 8 ++++---- sc/source/core/tool/sharedformula.cxx | 15 +++++++++++---- 4 files changed, 21 insertions(+), 13 deletions(-)
New commits: commit d4ecc08a365680aef2942681c5210b6d4aa1d749 Author: Eike Rathke <er...@redhat.com> Date: Wed Sep 16 12:38:06 2015 +0200 Resolves: tdf#94249 do not remove broadcasters while iterators are in use EndListeningContext holds BroadcasterStoreType iterators in its ColumnBlockPositionSet and collects broadcasters to purge them at the end. Removing broadcasters from ScColumn::maBroadcasters in between invalidates the iterators. Hence calling the "normal" EndListening() that removes a broadcaster when all listeners are gone while an EndListeningContext is in use is bad. Change-Id: Ibdd88469e91e6173ceff1f391c23ef7cb7c6f596 (cherry picked from commit e4a8ae0bf54476e9a0c9e1f5348c05f3cd838899) Reviewed-on: https://gerrit.libreoffice.org/18619 Reviewed-by: Jan Holesovsky <ke...@collabora.com> Reviewed-by: Tor Lillqvist <t...@collabora.com> Tested-by: Tor Lillqvist <t...@collabora.com> Reviewed-by: Tomaž Vajngerl <qui...@gmail.com> diff --git a/sc/inc/sharedformula.hxx b/sc/inc/sharedformula.hxx index e4b25bb..33a2d48 100644 --- a/sc/inc/sharedformula.hxx +++ b/sc/inc/sharedformula.hxx @@ -64,8 +64,9 @@ public: * specified position is not a formula cell. * * @param aPos position of cell to examine. + * @param pCxt context to be used, if any, may be nullptr. */ - static void splitFormulaCellGroup(const CellStoreType::position_type& aPos); + static void splitFormulaCellGroup(const CellStoreType::position_type& aPos, sc::EndListeningContext* pCxt); /** * Split existing shared formula ranges at specified row positions. diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx index 9accde9..910981a 100644 --- a/sc/source/core/data/column.cxx +++ b/sc/source/core/data/column.cxx @@ -1908,15 +1908,15 @@ void ScColumn::MoveTo(SCROW nStartRow, SCROW nEndRow, ScColumn& rCol) // Split the formula grouping at the top and bottom boundaries. sc::CellStoreType::position_type aPos = maCells.position(nStartRow); - sc::SharedFormulaUtil::splitFormulaCellGroup(aPos); + sc::SharedFormulaUtil::splitFormulaCellGroup(aPos, nullptr); aPos = maCells.position(aPos.first, nEndRow+1); - sc::SharedFormulaUtil::splitFormulaCellGroup(aPos); + sc::SharedFormulaUtil::splitFormulaCellGroup(aPos, nullptr); // Do the same with the destination column. aPos = rCol.maCells.position(nStartRow); - sc::SharedFormulaUtil::splitFormulaCellGroup(aPos); + sc::SharedFormulaUtil::splitFormulaCellGroup(aPos, nullptr); aPos = rCol.maCells.position(aPos.first, nEndRow+1); - sc::SharedFormulaUtil::splitFormulaCellGroup(aPos); + sc::SharedFormulaUtil::splitFormulaCellGroup(aPos, nullptr); // Move the broadcasters to the destination column. maBroadcasters.transfer(nStartRow, nEndRow, rCol.maBroadcasters, nStartRow); diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx index 757c3e3..c0376ea 100644 --- a/sc/source/core/data/column3.cxx +++ b/sc/source/core/data/column3.cxx @@ -327,13 +327,13 @@ void ScColumn::DetachFormulaCells( const sc::CellStoreType::position_type& aPos, size_t nLength ) { // Split formula grouping at the top and bottom boundaries. - sc::SharedFormulaUtil::splitFormulaCellGroup(aPos); + sc::SharedFormulaUtil::splitFormulaCellGroup(aPos, nullptr); size_t nRow = aPos.first->position + aPos.second; size_t nNextTopRow = nRow + nLength; // start row of next formula group. if (ValidRow(nNextTopRow)) { sc::CellStoreType::position_type aPos2 = maCells.position(aPos.first, nNextTopRow); - sc::SharedFormulaUtil::splitFormulaCellGroup(aPos2); + sc::SharedFormulaUtil::splitFormulaCellGroup(aPos2, nullptr); } if (pDocument->IsClipOrUndo()) @@ -368,11 +368,11 @@ void ScColumn::DetachFormulaCells( sc::EndListeningContext& rCxt, SCROW nRow1, S sc::CellStoreType::iterator it = aPos.first; // Split formula grouping at the top and bottom boundaries. - sc::SharedFormulaUtil::splitFormulaCellGroup(aPos); + sc::SharedFormulaUtil::splitFormulaCellGroup(aPos, &rCxt); if (ValidRow(nRow2+1)) { aPos = maCells.position(it, nRow2+1); - sc::SharedFormulaUtil::splitFormulaCellGroup(aPos); + sc::SharedFormulaUtil::splitFormulaCellGroup(aPos, &rCxt); } if (pDocument->IsClipOrUndo()) diff --git a/sc/source/core/tool/sharedformula.cxx b/sc/source/core/tool/sharedformula.cxx index a3fd1ae..8e84ac0 100644 --- a/sc/source/core/tool/sharedformula.cxx +++ b/sc/source/core/tool/sharedformula.cxx @@ -16,7 +16,7 @@ namespace sc { -void SharedFormulaUtil::splitFormulaCellGroup(const CellStoreType::position_type& aPos) +void SharedFormulaUtil::splitFormulaCellGroup(const CellStoreType::position_type& aPos, sc::EndListeningContext* pCxt) { SCROW nRow = aPos.first->position + aPos.second; @@ -61,7 +61,14 @@ void SharedFormulaUtil::splitFormulaCellGroup(const CellStoreType::position_type // other listeners, all listeners of this group's top cell are to be reset. if (nLength2) { - rPrevTop.EndListeningTo( rPrevTop.GetDocument(), NULL, ScAddress( ScAddress::UNINITIALIZED)); + // If a context exists it has to be used to not interfere with + // ScColumn::maBroadcasters iterators, which the EndListeningTo() + // without context would do when removing a broadcaster that had its + // last listener removed. + if (pCxt) + rPrevTop.EndListeningTo(*pCxt); + else + rPrevTop.EndListeningTo( rPrevTop.GetDocument(), NULL, ScAddress( ScAddress::UNINITIALIZED)); rPrevTop.SetNeedsListening(true); } #endif @@ -107,7 +114,7 @@ void SharedFormulaUtil::splitFormulaCellGroups(CellStoreType& rCells, std::vecto if (aPos.first == rCells.end()) return; - splitFormulaCellGroup(aPos); + splitFormulaCellGroup(aPos, nullptr); std::vector<SCROW>::iterator itEnd = rBounds.end(); for (++it; it != itEnd; ++it) { @@ -116,7 +123,7 @@ void SharedFormulaUtil::splitFormulaCellGroups(CellStoreType& rCells, std::vecto if (aPos.first == rCells.end()) return; - splitFormulaCellGroup(aPos); + splitFormulaCellGroup(aPos, nullptr); } }
_______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits