[Libreoffice-commits] core.git: Branch 'feature/perfwork5' - 2 commits - sc/inc sc/source

Kohei Yoshida kohei.yoshida at collabora.com
Tue Nov 18 17:12:07 PST 2014


 sc/inc/column.hxx                |   16 ++--
 sc/inc/table.hxx                 |   11 +-
 sc/source/core/data/column.cxx   |    5 -
 sc/source/core/data/column3.cxx  |   31 ++------
 sc/source/core/data/column4.cxx  |  146 ++++++++++++++++++++++++++++++++++++---
 sc/source/core/data/documen2.cxx |   19 ++---
 sc/source/core/data/documen7.cxx |    3 
 sc/source/core/data/document.cxx |   24 +-----
 sc/source/core/data/table2.cxx   |   12 ---
 sc/source/core/data/table4.cxx   |   41 +++++++++-
 10 files changed, 222 insertions(+), 86 deletions(-)

New commits:
commit 600d900e6c52bde98ed38370b104e5268689c5dd
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Tue Nov 18 20:08:53 2014 -0500

    Use group area listeners when filling down formula cells via fill series.
    
    Change-Id: Ib0d4f542986dc09968cad8b76da9d6e034eddd37

diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 972ed89..07ef1e5 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -255,9 +255,6 @@ public:
     void CopyFromClip(
         sc::CopyFromClipContext& rCxt, SCROW nRow1, SCROW nRow2, long nDy, ScColumn& rColumn );
 
-    void StartListeningFromClip(
-        sc::StartListeningContext& rStartCxt, sc::EndListeningContext& rEndCxt, SCROW nRow1, SCROW nRow2 );
-
     void        RemoveEditAttribs( SCROW nStartRow, SCROW nEndRow );
 
                 //  Selection (?) of this document
@@ -355,7 +352,7 @@ public:
 
     void SetAllFormulasDirty( const sc::SetFormulaDirtyContext& rCxt );
     void SetDirtyFromClip( SCROW nRow1, SCROW nRow2, sc::ColumnSpanSet& rBroadcastSpans );
-    void SetDirty( SCROW nRow1, SCROW nRow2 );
+    void SetDirty( SCROW nRow1, SCROW nRow2, bool bBroadcast = true );
     void        SetDirtyVar();
     void        SetDirtyAfterLoad();
     void        SetTableOpDirty( const ScRange& );
@@ -487,6 +484,14 @@ public:
     bool    TestTabRefAbs(SCTAB nTable) const;
     bool    GetNextSpellingCell(SCROW& nRow, bool bInSel, const ScMarkData& rData) const;
 
+    void StartListeningFormulaCells(
+        sc::StartListeningContext& rStartCxt, sc::EndListeningContext& rEndCxt, SCROW nRow1, SCROW nRow2,
+        SCROW* pStartRow = NULL, SCROW* pEndRow = NULL );
+
+    void EndListeningFormulaCells(
+        sc::EndListeningContext& rCxt, SCROW nRow1, SCROW nRow2,
+        SCROW* pStartRow = NULL, SCROW* pEndRow = NULL );
+
     void        StartListening( SvtListener& rLst, SCROW nRow );
     void        EndListening( SvtListener& rLst, SCROW nRow );
     void StartListening( sc::StartListeningContext& rCxt, SCROW nRow, SvtListener& rListener );
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index 3354a49..1100d92 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -3054,14 +3054,15 @@ void ScColumn::SetDirtyFromClip( SCROW nRow1, SCROW nRow2, sc::ColumnSpanSet& rB
     aHdl.fillBroadcastSpans(rBroadcastSpans);
 }
 
-void ScColumn::SetDirty( SCROW nRow1, SCROW nRow2 )
+void ScColumn::SetDirty( SCROW nRow1, SCROW nRow2, bool bBroadcast )
 {
     // broadcasts everything within the range, with FormulaTracking
     sc::AutoCalcSwitch aSwitch(*pDocument, false);
 
     SetDirtyOnRangeHandler aHdl(*this);
     sc::ProcessFormula(maCells.begin(), maCells, nRow1, nRow2, aHdl, aHdl);
-    aHdl.broadcast();
+    if (bBroadcast)
+        aHdl.broadcast();
 }
 
 void ScColumn::SetTableOpDirty( const ScRange& rRange )
diff --git a/sc/source/core/data/column4.cxx b/sc/source/core/data/column4.cxx
index b0d1d50..0a437e7 100644
--- a/sc/source/core/data/column4.cxx
+++ b/sc/source/core/data/column4.cxx
@@ -1140,14 +1140,25 @@ bool ScColumn::HasFormulaCell( SCROW nRow1, SCROW nRow2 ) const
 
 namespace {
 
-class StartListeningFromClipHandler
+void endListening( sc::EndListeningContext& rCxt, ScFormulaCell** pp, ScFormulaCell** ppEnd )
+{
+    for (; pp != ppEnd; ++pp)
+    {
+        ScFormulaCell& rFC = **pp;
+        rFC.EndListeningTo(rCxt);
+    }
+}
+
+class StartListeningFormulaCellsHandler
 {
     sc::StartListeningContext& mrStartCxt;
     sc::EndListeningContext& mrEndCxt;
+    SCROW mnStartRow;
+    SCROW mnEndRow;
 
 public:
-    StartListeningFromClipHandler( sc::StartListeningContext& rStartCxt, sc::EndListeningContext& rEndCxt ) :
-        mrStartCxt(rStartCxt), mrEndCxt(rEndCxt) {}
+    StartListeningFormulaCellsHandler( sc::StartListeningContext& rStartCxt, sc::EndListeningContext& rEndCxt ) :
+        mrStartCxt(rStartCxt), mrEndCxt(rEndCxt), mnStartRow(-1), mnEndRow(-1) {}
 
     void operator() ( const sc::CellStoreType::value_type& node, size_t nOffset, size_t nDataSize )
     {
@@ -1155,6 +1166,8 @@ public:
             // We are only interested in formulas.
             return;
 
+        mnStartRow = node.position + nOffset;
+
         ScFormulaCell** ppBeg = &sc::formula_block::at(*node.data, nOffset);
         ScFormulaCell** ppEnd = ppBeg + nDataSize;
 
@@ -1173,7 +1186,8 @@ public:
                 assert(static_cast<size_t>(nBackTrackSize) <= nOffset);
                 for (SCROW i = 0; i < nBackTrackSize; ++i)
                     --pp;
-                endListening(pp, ppBeg);
+                endListening(mrEndCxt, pp, ppBeg);
+                mnStartRow -= nBackTrackSize;
             }
         }
 
@@ -1183,6 +1197,7 @@ public:
 
             if (!pFC->IsSharedTop())
             {
+                assert(!pFC->IsShared());
                 pFC->StartListeningTo(mrStartCxt);
                 continue;
             }
@@ -1191,12 +1206,13 @@ public:
             // extends beyond the range, in which case have the excess
             // formula cells stop listening.
             size_t nEndGroupPos = (pp - ppBeg) + pFC->GetSharedLength();
+            mnEndRow = node.position + nOffset + nEndGroupPos - 1; // absolute row position of the last one in the group.
             if (nEndGroupPos > nDataSize)
             {
                 size_t nExcessSize = nEndGroupPos - nDataSize;
                 ScFormulaCell** ppGrpEnd = pp + pFC->GetSharedLength();
                 ScFormulaCell** ppGrp = ppGrpEnd - nExcessSize;
-                endListening(ppGrp, ppGrpEnd);
+                endListening(mrEndCxt, ppGrp, ppGrpEnd);
 
                 // Register formula cells as a group.
                 sc::SharedFormulaUtil::startListeningAsGroup(mrStartCxt, pp);
@@ -1211,24 +1227,132 @@ public:
         }
     }
 
+    SCROW getStartRow() const
+    {
+        return mnStartRow;
+    }
+
+    SCROW getEndRow() const
+    {
+        return mnEndRow;
+    }
+
 private:
-    void endListening( ScFormulaCell** pp, ScFormulaCell** ppEnd )
+};
+
+class EndListeningFormulaCellsHandler
+{
+    sc::EndListeningContext& mrEndCxt;
+    SCROW mnStartRow;
+    SCROW mnEndRow;
+
+public:
+    EndListeningFormulaCellsHandler( sc::EndListeningContext& rEndCxt ) :
+        mrEndCxt(rEndCxt), mnStartRow(-1), mnEndRow(-1) {}
+
+    void operator() ( const sc::CellStoreType::value_type& node, size_t nOffset, size_t nDataSize )
     {
+        if (node.type != sc::element_type_formula)
+            // We are only interested in formulas.
+            return;
+
+        mnStartRow = node.position + nOffset;
+
+        ScFormulaCell** ppBeg = &sc::formula_block::at(*node.data, nOffset);
+        ScFormulaCell** ppEnd = ppBeg + nDataSize;
+
+        ScFormulaCell** pp = ppBeg;
+
+        // If the first formula cell belongs to a group and it's not the top
+        // cell, move up to the top cell of the group.
+
+        ScFormulaCell* pFC = *pp;
+        if (pFC->IsShared() && !pFC->IsSharedTop())
+        {
+            SCROW nBackTrackSize = pFC->aPos.Row() - pFC->GetSharedTopRow();
+            if (nBackTrackSize > 0)
+            {
+                assert(static_cast<size_t>(nBackTrackSize) <= nOffset);
+                for (SCROW i = 0; i < nBackTrackSize; ++i)
+                    --pp;
+                mnStartRow -= nBackTrackSize;
+            }
+        }
+
         for (; pp != ppEnd; ++pp)
         {
-            ScFormulaCell& rFC = **pp;
-            rFC.EndListeningTo(mrEndCxt);
+            pFC = *pp;
+
+            if (!pFC->IsSharedTop())
+            {
+                assert(!pFC->IsShared());
+                pFC->EndListeningTo(mrEndCxt);
+                continue;
+            }
+
+            size_t nEndGroupPos = (pp - ppBeg) + pFC->GetSharedLength();
+            mnEndRow = node.position + nOffset + nEndGroupPos - 1; // absolute row position of the last one in the group.
+
+            ScFormulaCell** ppGrpEnd = pp + pFC->GetSharedLength();
+            endListening(mrEndCxt, pp, ppGrpEnd);
+
+            if (nEndGroupPos > nDataSize)
+            {
+                // The group goes beyond the specified end row.  Move to the
+                // one before the end postion to finish the loop.
+                pp = ppEnd - 1;
+            }
+            else
+            {
+                // Move to the last one in the group.
+                pp += pFC->GetSharedLength() - 1;
+            }
         }
     }
+
+    SCROW getStartRow() const
+    {
+        return mnStartRow;
+    }
+
+    SCROW getEndRow() const
+    {
+        return mnEndRow;
+    }
 };
 
 }
 
-void ScColumn::StartListeningFromClip(
-    sc::StartListeningContext& rStartCxt, sc::EndListeningContext& rEndCxt, SCROW nRow1, SCROW nRow2 )
+void ScColumn::StartListeningFormulaCells(
+    sc::StartListeningContext& rStartCxt, sc::EndListeningContext& rEndCxt,
+    SCROW nRow1, SCROW nRow2, SCROW* pStartRow, SCROW* pEndRow )
 {
-    StartListeningFromClipHandler aFunc(rStartCxt, rEndCxt);
+    StartListeningFormulaCellsHandler aFunc(rStartCxt, rEndCxt);
     sc::ProcessBlock(maCells.begin(), maCells, aFunc, nRow1, nRow2);
+
+    if (pStartRow)
+        // start row position may be smaller than nRow1 in case the formula
+        // group starts before nRow1 position.
+        *pStartRow = aFunc.getStartRow();
+
+    if (pEndRow)
+        // row position of the last cell that started listening, which may be
+        // greater than nRow2 in case the formula group extends beyond nRow2.
+        *pEndRow = aFunc.getEndRow();
+}
+
+void ScColumn::EndListeningFormulaCells(
+    sc::EndListeningContext& rCxt, SCROW nRow1, SCROW nRow2,
+    SCROW* pStartRow, SCROW* pEndRow )
+{
+    EndListeningFormulaCellsHandler aFunc(rCxt);
+    sc::ProcessBlock(maCells.begin(), maCells, aFunc, nRow1, nRow2);
+
+    if (pStartRow)
+        *pStartRow = aFunc.getStartRow();
+
+    if (pEndRow)
+        *pEndRow = aFunc.getEndRow();
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index 7e7507c..a00c5c3 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -1061,7 +1061,7 @@ void ScTable::StartListeningFromClip(
     if (nRow2 > MAXROW) nRow2 = MAXROW;
     if (ValidColRow(nCol1, nRow1) && ValidColRow(nCol2, nRow2))
         for (SCCOL i = nCol1; i <= nCol2; i++)
-            aCol[i].StartListeningFromClip(rStartCxt, rEndCxt, nRow1, nRow2);
+            aCol[i].StartListeningFormulaCells(rStartCxt, rEndCxt, nRow1, nRow2);
 }
 
 void ScTable::CopyToTable(
diff --git a/sc/source/core/data/table4.cxx b/sc/source/core/data/table4.cxx
index 3561a04..13a7baf 100644
--- a/sc/source/core/data/table4.cxx
+++ b/sc/source/core/data/table4.cxx
@@ -1130,6 +1130,10 @@ void ScTable::FillFormulaVertical(
     SCCOLROW& rInner, SCCOL nCol, SCROW nRow1, SCROW nRow2,
     ScProgress* pProgress, sal_uLong& rProgress )
 {
+    // rInner is the row position when filling vertically.  Also, when filling
+    // across hidden regions, it may create multiple dis-jointed spans of
+    // formula cells.
+
     bool bHidden = false;
     SCCOLROW nHiddenLast = -1;
 
@@ -1163,9 +1167,24 @@ void ScTable::FillFormulaVertical(
         aSpans.push_back(sc::RowSpan(nRowStart, nRowEnd));
     }
 
+    if (aSpans.empty())
+        return;
+
     aCol[nCol].DeleteRanges(aSpans, IDF_CONTENTS, false);
-    sc::StartListeningContext aCxt(*pDocument);
-    aCol[nCol].CloneFormulaCell(rSrcCell, aSpans, &aCxt);
+    aCol[nCol].CloneFormulaCell(rSrcCell, aSpans, NULL);
+
+    boost::shared_ptr<sc::ColumnBlockPositionSet> pSet(new sc::ColumnBlockPositionSet(*pDocument));
+    sc::StartListeningContext aStartCxt(*pDocument, pSet);
+    sc::EndListeningContext aEndCxt(*pDocument, pSet);
+
+    SCROW nStartRow = aSpans.front().mnRow1;
+    SCROW nEndRow = aSpans.back().mnRow2;
+    aCol[nCol].EndListeningFormulaCells(aEndCxt, nStartRow, nEndRow, &nStartRow, &nEndRow);
+    aCol[nCol].StartListeningFormulaCells(aStartCxt, aEndCxt, nStartRow, nEndRow);
+
+    std::vector<sc::RowSpan>::const_iterator it = aSpans.begin(), itEnd = aSpans.end();
+    for (; it != itEnd; ++it)
+        aCol[nCol].SetDirty(it->mnRow1, it->mnRow2, false);
 
     rProgress += nRow2 - nRow1 + 1;
     if (pProgress)
@@ -1424,6 +1443,13 @@ void ScTable::FillSeries( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
                     double nStepValue, double nMaxValue, sal_uInt16 nArgMinDigits,
                     bool bAttribs, ScProgress* pProgress )
 {
+    // The term 'inner' here refers to the loop in the filling direction i.e.
+    // when filling vertically, the inner position is the row position whereas
+    // when filling horizontally the column position becomes the inner
+    // position. The term 'outer' refers to the column position when filling
+    // vertically, or the row positon when filling horizontally. The fill is
+    // performed once in each 'outer' position e.g. when filling vertically,
+    // we perform the fill once in each column.
 
     //  Detect direction
 
@@ -1450,13 +1476,15 @@ void ScTable::FillSeries( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
         nOEnd = nCol2;
         if (bPositive)
         {
-            nISource = nRow1;
-            nIStart = nRow1 + 1;
+            // downward fill
+            nISource = nRow1; // top row of the source range.
+            nIStart = nRow1 + 1; // first row where we start filling.
             nIEnd = nRow1 + nFillCount;
             aFillRange = ScRange(nCol1, nRow1 + 1, nTab, nCol2, nRow1 + nFillCount, nTab);
         }
         else
         {
+            // upward fill
             nISource = nRow2;
             nIStart = nRow2 - 1;
             nIEnd = nRow2 - nFillCount;
@@ -1472,6 +1500,7 @@ void ScTable::FillSeries( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
         nOEnd = nRow2;
         if (bPositive)
         {
+            // to the right
             nISource = nCol1;
             nIStart = nCol1 + 1;
             nIEnd = nCol1 + nFillCount;
@@ -1479,6 +1508,7 @@ void ScTable::FillSeries( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
         }
         else
         {
+            // to the left
             nISource = nCol2;
             nIStart = nCol2 - 1;
             nIEnd = nCol2 - nFillCount;
@@ -1504,7 +1534,8 @@ void ScTable::FillSeries( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
     if (pProgress)
         nProgress = pProgress->GetState();
 
-    //  execute
+    // Perform the fill once per each 'outer' position i.e. one per column
+    // when filling vertically.
 
     sal_uLong nActFormCnt = 0;
     for (rOuter = nOStart; rOuter <= nOEnd; rOuter++)
commit fa355e25b70b5e6892cd4840d9fad0a39d7a63c1
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Tue Nov 18 12:35:39 2014 -0500

    Combine StartAllListeners() and StartNeededListeners()...
    
    And call the new method StartListeners().  This also adjusts what was
    previously StartAllListener() to be group-listener aware.
    
    Change-Id: I74de45c00f5b8ef232eea9fe3b93aa44d1d8855b

diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 440a95b..972ed89 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -491,8 +491,7 @@ public:
     void        EndListening( SvtListener& rLst, SCROW nRow );
     void StartListening( sc::StartListeningContext& rCxt, SCROW nRow, SvtListener& rListener );
     void EndListening( sc::EndListeningContext& rCxt, SCROW nRow, SvtListener& rListener );
-    void        StartAllListeners();
-    void StartNeededListeners( sc::StartListeningContext& rCxt ); // only for cells where NeedsListening()==true
+    void StartListeners( sc::StartListeningContext& rCxt, bool bAll );
     void        SetDirtyIfPostponed();
     void BroadcastRecalcOnRefMove();
     void TransferListeners( ScColumn& rDestCol, SCROW nRow1, SCROW nRow2, SCROW nRowDelta );
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 074b5d08..02a88ef 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -913,10 +913,14 @@ public:
     void SetFormulaResults( SCCOL nCol, SCROW nRow, const formula::FormulaTokenRef* pResults, size_t nLen );
 
     /**
-     * Have formula cells with NeedsListening() == true start listening to the
-     * document.
+     * Either start all formula cells as listeners unconditionally, or start
+     * those that are marked "needs listening".
+     *
+     * @param rCxt context object.
+     * @param bAll when true, start all formula cells as listeners. When
+     *             false, only start those that are marked "needs listening".
      */
-    void StartNeededListeners( sc::StartListeningContext& rCxt );
+    void StartListeners( sc::StartListeningContext& rCxt, bool bAll );
 
     /**
      * Mark formula cells dirty that have the mbPostponedDirty flag set or
@@ -1070,7 +1074,6 @@ private:
     void        EndListening( const ScAddress& rAddress, SvtListener* pListener );
     void StartListening( sc::StartListeningContext& rCxt, SCCOL nCol, SCROW nRow, SvtListener& rListener );
     void EndListening( sc::EndListeningContext& rCxt, SCCOL nCol, SCROW nRow, SvtListener& rListener );
-    void        StartAllListeners();
 
     void AttachFormulaCells( sc::StartListeningContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 );
     void DetachFormulaCells( sc::EndListeningContext& rCxt, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 );
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index ec0dd45..be6dfc4 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -1500,23 +1500,14 @@ ScAttrIterator* ScColumn::CreateAttrIterator( SCROW nStartRow, SCROW nEndRow ) c
 
 namespace {
 
-class StartAllListenersHandler
-{
-    ScDocument* mpDoc;
-public:
-    StartAllListenersHandler(ScDocument* pDoc) : mpDoc(pDoc) {}
-
-    void operator() (size_t, ScFormulaCell* p)
-    {
-        p->StartListeningTo(mpDoc);
-    }
-};
-
-class StartNeededListenersHandler
+class StartListenersHandler
 {
     sc::StartListeningContext* mpCxt;
+    bool mbAllListeners;
+
 public:
-    StartNeededListenersHandler( sc::StartListeningContext& rCxt ) : mpCxt(&rCxt) {}
+    StartListenersHandler( sc::StartListeningContext& rCxt, bool bAllListeners ) :
+        mpCxt(&rCxt), mbAllListeners(bAllListeners) {}
 
     void operator() ( sc::CellStoreType::value_type& aBlk )
     {
@@ -1529,7 +1520,7 @@ public:
         for (; pp != ppEnd; ++pp)
         {
             ScFormulaCell& rFC = **pp;
-            if (!rFC.NeedsListening())
+            if (!mbAllListeners && !rFC.NeedsListening())
                 continue;
 
             if (rFC.IsSharedTop())
@@ -1545,15 +1536,9 @@ public:
 
 }
 
-void ScColumn::StartAllListeners()
-{
-    StartAllListenersHandler aFunc(pDocument);
-    sc::ProcessFormula(maCells, aFunc);
-}
-
-void ScColumn::StartNeededListeners( sc::StartListeningContext& rCxt )
+void ScColumn::StartListeners( sc::StartListeningContext& rCxt, bool bAll )
 {
-    std::for_each(maCells.begin(), maCells.end(), StartNeededListenersHandler(rCxt));
+    std::for_each(maCells.begin(), maCells.end(), StartListenersHandler(rCxt, bAll));
 }
 
 namespace {
diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx
index 6837a54..df9c106 100644
--- a/sc/source/core/data/documen2.cxx
+++ b/sc/source/core/data/documen2.cxx
@@ -99,6 +99,7 @@
 #include "interpre.hxx"
 #include <tokenstringcontext.hxx>
 #include "docsh.hxx"
+#include <listenercontext.hxx>
 
 using namespace com::sun::star;
 
@@ -765,10 +766,8 @@ bool ScDocument::MoveTab( SCTAB nOldPos, SCTAB nNewPos, ScProgress* pProgress )
                 if (*it)
                     (*it)->UpdateCompile();
             SetNoListening( false );
-            it = maTabs.begin();
-            for (; it != maTabs.end(); ++it)
-                if (*it)
-                    (*it)->StartAllListeners();
+            StartAllListeners();
+
             // sheet names of references may not be valid until sheet is moved
             pChartListenerCollection->UpdateScheduledSeriesRanges();
 
@@ -806,6 +805,7 @@ bool ScDocument::CopyTab( SCTAB nOldPos, SCTAB nNewPos, const ScMarkData* pOnlyM
 
     sc::AutoCalcSwitch aACSwitch(*this, false);
     sc::RefUpdateInsertTabContext aCxt(nNewPos, 1);
+    sc::StartListeningContext aSLCxt(*this);
 
     if (bValid)
     {
@@ -854,7 +854,7 @@ bool ScDocument::CopyTab( SCTAB nOldPos, SCTAB nNewPos, const ScMarkData* pOnlyM
                 SetNoListening( false );
                 for (TableContainer::iterator it = maTabs.begin(); it != maTabs.end(); ++it)
                     if (*it && it != maTabs.begin()+nOldPos && it != maTabs.begin()+nNewPos)
-                        (*it)->StartAllListeners();
+                        (*it)->StartListeners(aSLCxt, true);
 
                 if (pValidationList)
                     pValidationList->UpdateInsertTab(aCxt);
@@ -889,8 +889,8 @@ bool ScDocument::CopyTab( SCTAB nOldPos, SCTAB nNewPos, const ScMarkData* pOnlyM
         maTabs[nOldPos]->UpdateCompile();
         maTabs[nNewPos]->UpdateCompile( true ); //  maybe already compiled in Clone, but used names need recompilation
         SetNoListening( false );
-        maTabs[nOldPos]->StartAllListeners();
-        maTabs[nNewPos]->StartAllListeners();
+        maTabs[nOldPos]->StartListeners(aSLCxt, true);
+        maTabs[nNewPos]->StartListeners(aSLCxt, true);
 
         sc::SetFormulaDirtyContext aFormulaDirtyCxt;
         SetAllFormulasDirty(aFormulaDirtyCxt);
@@ -1000,7 +1000,10 @@ sal_uLong ScDocument::TransferTab( ScDocument* pSrcDoc, SCTAB nSrcPos,
 
         SetNoListening( false );
         if ( !bResultsOnly )
-            maTabs[nDestPos]->StartAllListeners();
+        {
+            sc::StartListeningContext aSLCxt(*this);
+            maTabs[nDestPos]->StartListeners(aSLCxt, true);
+        }
         SetDirty( ScRange( 0, 0, nDestPos, MAXCOL, MAXROW, nDestPos));
 
         if ( bResultsOnly )
diff --git a/sc/source/core/data/documen7.cxx b/sc/source/core/data/documen7.cxx
index b7bdf30..6429fa5 100644
--- a/sc/source/core/data/documen7.cxx
+++ b/sc/source/core/data/documen7.cxx
@@ -620,9 +620,10 @@ void ScDocument::TrackFormulas( sal_uLong nHintId )
 
 void ScDocument::StartAllListeners()
 {
+    sc::StartListeningContext aCxt(*this);
     for ( SCTAB i = 0; i < static_cast<SCTAB>(maTabs.size()); ++i )
         if ( maTabs[i] )
-            maTabs[i]->StartAllListeners();
+            maTabs[i]->StartListeners(aCxt, true);
 }
 
 void ScDocument::UpdateBroadcastAreas( UpdateRefMode eUpdateRefMode,
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index c5b4090..fe4cba1 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -530,10 +530,8 @@ bool ScDocument::InsertTab(
                 for (; it != maTabs.end(); ++it)
                     if ( *it )
                         (*it)->UpdateCompile();
-                it = maTabs.begin();
-                for (; it != maTabs.end(); ++it)
-                    if ( *it )
-                        (*it)->StartAllListeners();
+
+                StartAllListeners();
 
                 if (pValidationList)
                     pValidationList->UpdateInsertTab(aCxt);
@@ -622,10 +620,8 @@ bool ScDocument::InsertTabs( SCTAB nPos, const std::vector<OUString>& rNames,
                     if ( *it )
                         (*it)->UpdateCompile();
                 }
-                it = maTabs.begin();
-                for (; it != maTabs.end(); ++it)
-                    if ( *it )
-                        (*it)->StartAllListeners();
+
+                StartAllListeners();
 
                 if (pValidationList)
                     pValidationList->UpdateInsertTab(aCxt);
@@ -717,10 +713,7 @@ bool ScDocument::DeleteTab( SCTAB nTab )
                 // only be triggered after the loading is done.
                 if ( !bInsertingFromOtherDoc )
                 {
-                    it = maTabs.begin();
-                    for (; it != maTabs.end(); ++it)
-                        if ( *it )
-                            (*it)->StartAllListeners();
+                    StartAllListeners();
 
                     sc::SetFormulaDirtyContext aFormulaDirtyCxt;
                     SetAllFormulasDirty(aFormulaDirtyCxt);
@@ -807,10 +800,7 @@ bool ScDocument::DeleteTabs( SCTAB nTab, SCTAB nSheets )
                 // only be triggered after the loading is done.
                 if ( !bInsertingFromOtherDoc )
                 {
-                    it = maTabs.begin();
-                    for (; it != maTabs.end(); ++it)
-                        if ( *it )
-                            (*it)->StartAllListeners();
+                    StartAllListeners();
 
                     sc::SetFormulaDirtyContext aFormulaDirtyCxt;
                     SetAllFormulasDirty(aFormulaDirtyCxt);
@@ -1173,7 +1163,7 @@ public:
     void operator() (ScTable* p)
     {
         if (p)
-            p->StartNeededListeners(*mpCxt);
+            p->StartListeners(*mpCxt, false);
     }
 };
 
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index d3b7ec0..7e7507c 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -1023,10 +1023,10 @@ const ScColumn* ScTable::FetchColumn( SCCOL nCol ) const
     return &aCol[nCol];
 }
 
-void ScTable::StartAllListeners()
+void ScTable::StartListeners( sc::StartListeningContext& rCxt, bool bAll )
 {
     for (SCCOL i=0; i<=MAXCOL; i++)
-        aCol[i].StartAllListeners();
+        aCol[i].StartListeners(rCxt, bAll);
 }
 
 void ScTable::AttachFormulaCells(
@@ -1043,12 +1043,6 @@ void ScTable::DetachFormulaCells(
         aCol[nCol].DetachFormulaCells(rCxt, nRow1, nRow2);
 }
 
-void ScTable::StartNeededListeners( sc::StartListeningContext& rCxt )
-{
-    for (SCCOL i=0; i<=MAXCOL; i++)
-        aCol[i].StartNeededListeners(rCxt);
-}
-
 void ScTable::SetDirtyFromClip(
     SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, sc::ColumnSpanSet& rBroadcastSpans )
 {


More information about the Libreoffice-commits mailing list