[Libreoffice-commits] core.git: sc/inc sc/source

Eike Rathke erack at redhat.com
Wed Sep 16 03:45:10 PDT 2015


 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 e4a8ae0bf54476e9a0c9e1f5348c05f3cd838899
Author: Eike Rathke <erack at 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

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 c7d71e3..7b1e410 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 0bcc206..c39c295 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);
     }
 }
 


More information about the Libreoffice-commits mailing list