summaryrefslogtreecommitdiff
path: root/sc/source/core/tool/sharedformula.cxx
diff options
context:
space:
mode:
authorEike Rathke <erack@redhat.com>2015-09-16 12:38:06 +0200
committerEike Rathke <erack@redhat.com>2015-09-16 12:44:26 +0200
commite4a8ae0bf54476e9a0c9e1f5348c05f3cd838899 (patch)
tree0a45a4f914577483e53f9de2c99da7e6493ba4a7 /sc/source/core/tool/sharedformula.cxx
parentbfceb557efcd607ef018ae35fc73f8d61a9b9a4e (diff)
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
Diffstat (limited to 'sc/source/core/tool/sharedformula.cxx')
-rw-r--r--sc/source/core/tool/sharedformula.cxx15
1 files changed, 11 insertions, 4 deletions
diff --git a/sc/source/core/tool/sharedformula.cxx b/sc/source/core/tool/sharedformula.cxx
index a3fd1aeea926..8e84ac0f0135 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);
}
}