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

Kohei Yoshida kohei.yoshida at collabora.com
Mon Nov 17 20:37:03 PST 2014


 sc/inc/column.hxx                |    2 -
 sc/inc/table.hxx                 |    2 -
 sc/qa/unit/ucalc.cxx             |   39 ++++++++++++++++++++++++++++++++++++++
 sc/source/core/data/column3.cxx  |   35 +++++++++++++++++++++++++---------
 sc/source/core/data/document.cxx |   40 +++++++++++++++++++--------------------
 sc/source/core/data/table2.cxx   |    4 +--
 6 files changed, 89 insertions(+), 33 deletions(-)

New commits:
commit 93e0a6464e755719f95f55006e9661ddb9d9c84a
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Mon Nov 17 23:34:42 2014 -0500

    Extend the test to cover insertion / deletion of rows.
    
    Change-Id: I9c5f46af446f8384265d91ce5dfe269e7a090d09

diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index 960b180..248a0e9 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -4011,6 +4011,45 @@ void Test::testCopyPasteRepeatOneFormula()
     CPPUNIT_ASSERT_EQUAL(ScRange(0,0,0,1,9,0), pListener->maArea);
     CPPUNIT_ASSERT_MESSAGE("This listener should be a group listener.", pListener->mbGroupListening);
 
+    // Insert a new row at row 1.
+    ScRange aRowOne(0,0,0,MAXCOL,0,0);
+    aMark.SetMarkArea(aRowOne);
+    ScDocFunc& rFunc = getDocShell().GetDocFunc();
+    rFunc.InsertCells(aRowOne, &aMark, INS_INSROWS, true, true, false);
+
+    CPPUNIT_ASSERT_MESSAGE("C1 should be empty.", m_pDoc->GetCellType(ScAddress(2,0,0)) == CELLTYPE_NONE);
+
+    // Make there we only have one group area listener listening on A2:B11.
+    aListeners = pBASM->GetAllListeners(aWholeSheet, sc::AreaInside);
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aListeners.size());
+    pListener = &aListeners[0];
+    CPPUNIT_ASSERT_EQUAL(ScRange(0,1,0,1,10,0), pListener->maArea);
+    CPPUNIT_ASSERT_MESSAGE("This listener should be a group listener.", pListener->mbGroupListening);
+
+    // Check the formula results.
+    for (SCROW i = 0; i < 10; ++i)
+    {
+        double fExpected = (i+1.0)*11.0;
+        CPPUNIT_ASSERT_EQUAL(fExpected, m_pDoc->GetValue(ScAddress(2,i+1,0)));
+    }
+
+    // Delete row at row 1 to shift the cells up.
+    rFunc.DeleteCells(aRowOne, &aMark, DEL_DELROWS, true, true);
+
+    // Check the formula results again.
+    for (SCROW i = 0; i < 10; ++i)
+    {
+        double fExpected = (i+1.0)*11.0;
+        CPPUNIT_ASSERT_EQUAL(fExpected, m_pDoc->GetValue(ScAddress(2,i,0)));
+    }
+
+    // Check the group area listener again to make sure it's listening on A1:B10 once again.
+    aListeners = pBASM->GetAllListeners(aWholeSheet, sc::AreaInside);
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), aListeners.size());
+    pListener = &aListeners[0];
+    CPPUNIT_ASSERT_EQUAL(ScRange(0,0,0,1,9,0), pListener->maArea);
+    CPPUNIT_ASSERT_MESSAGE("This listener should be a group listener.", pListener->mbGroupListening);
+
     m_pDoc->DeleteTab(0);
 }
 
commit 738b6fb605ef3176d525f0634a0165b823e86c76
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Mon Nov 17 23:25:28 2014 -0500

    Register group area listeners as needed when inserting/deleting cells.
    
    Change-Id: I583ace5d134d526d660d4ff0bbf4a16aa10cbe5a

diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 5a0f70c..7800763 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -492,7 +492,7 @@ public:
     void StartListening( sc::StartListeningContext& rCxt, SCROW nRow, SvtListener& rListener );
     void EndListening( sc::EndListeningContext& rCxt, SCROW nRow, SvtListener& rListener );
     void        StartAllListeners();
-    void        StartNeededListeners(); // only for cells where NeedsListening()==true
+    void StartNeededListeners( sc::StartListeningContext& rCxt ); // only for cells where NeedsListening()==true
     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 7d802e3..074b5d08 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -916,7 +916,7 @@ public:
      * Have formula cells with NeedsListening() == true start listening to the
      * document.
      */
-    void StartNeededListeners();
+    void StartNeededListeners( sc::StartListeningContext& rCxt );
 
     /**
      * Mark formula cells dirty that have the mbPostponedDirty flag set or
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index b2a115f..353a974 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -1506,16 +1506,34 @@ public:
     }
 };
 
-class StartNeededListenerHandler
+class StartNeededListenersHandler
 {
-    ScDocument* mpDoc;
+    sc::StartListeningContext* mpCxt;
 public:
-    StartNeededListenerHandler(ScDocument* pDoc) : mpDoc(pDoc) {}
+    StartNeededListenersHandler( sc::StartListeningContext& rCxt ) : mpCxt(&rCxt) {}
 
-    void operator() (size_t, ScFormulaCell* p)
+    void operator() ( sc::CellStoreType::value_type& aBlk )
     {
-        if (p->NeedsListening())
-            p->StartListeningTo(mpDoc);
+        if (aBlk.type != sc::element_type_formula)
+            return;
+
+        ScFormulaCell** pp = &sc::formula_block::at(*aBlk.data, 0);
+        ScFormulaCell** ppEnd = pp + aBlk.size;
+
+        for (; pp != ppEnd; ++pp)
+        {
+            ScFormulaCell& rFC = **pp;
+            if (!rFC.NeedsListening())
+                continue;
+
+            if (rFC.IsSharedTop())
+            {
+                sc::SharedFormulaUtil::startListeningAsGroup(*mpCxt, pp);
+                pp += rFC.GetSharedLength() - 1; // Move to the last cell in the group.
+            }
+            else
+                rFC.StartListeningTo(*mpCxt);
+        }
     }
 };
 
@@ -1527,10 +1545,9 @@ void ScColumn::StartAllListeners()
     sc::ProcessFormula(maCells, aFunc);
 }
 
-void ScColumn::StartNeededListeners()
+void ScColumn::StartNeededListeners( sc::StartListeningContext& rCxt )
 {
-    StartNeededListenerHandler aFunc(pDocument);
-    sc::ProcessFormula(maCells, aFunc);
+    std::for_each(maCells.begin(), maCells.end(), StartNeededListenersHandler(rCxt));
 }
 
 namespace {
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index d6bb230..c5b4090 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -1164,12 +1164,16 @@ bool ScDocument::CanInsertRow( const ScRange& rRange ) const
 
 namespace {
 
-struct StartNeededListenersHandler : std::unary_function<ScTable*, void>
+class StartNeededListenersHandler : std::unary_function<ScTable*, void>
 {
+    boost::shared_ptr<sc::StartListeningContext> mpCxt;
+public:
+    StartNeededListenersHandler( ScDocument& rDoc ) : mpCxt(new sc::StartListeningContext(rDoc)) {}
+
     void operator() (ScTable* p)
     {
         if (p)
-            p->StartNeededListeners();
+            p->StartNeededListeners(*mpCxt);
     }
 };
 
@@ -1264,14 +1268,12 @@ bool ScDocument::InsertRow( SCCOL nStartCol, SCTAB nStartTab,
         }
         else
         {   // Listeners have been removed in UpdateReference
-            TableContainer::iterator it = maTabs.begin();
-            for (; it != maTabs.end(); ++it)
-                if (*it)
-                    (*it)->StartNeededListeners();
+            std::for_each(maTabs.begin(), maTabs.end(), StartNeededListenersHandler(*this));
+
             // At least all cells using range names pointing relative to the
             // moved range must be recalculated, and all cells marked postponed
             // dirty.
-            it = maTabs.begin();
+            TableContainer::iterator it = maTabs.begin();
             for (; it != maTabs.end(); ++it)
                 if (*it)
                     (*it)->SetDirtyIfPostponed();
@@ -1357,14 +1359,13 @@ void ScDocument::DeleteRow( SCCOL nStartCol, SCTAB nStartTab,
             maTabs[i]->DeleteRow(aCxt.maRegroupCols, nStartCol, nEndCol, nStartRow, nSize, pUndoOutline);
 
     if ( ValidRow(nStartRow+nSize) )
-    {   // Listeners have been removed in UpdateReference
-        TableContainer::iterator it = maTabs.begin();
-        for (; it != maTabs.end(); ++it)
-            if (*it)
-                (*it)->StartNeededListeners();
+    {
+        // Listeners have been removed in UpdateReference
+        std::for_each(maTabs.begin(), maTabs.end(), StartNeededListenersHandler(*this));
+
         // At least all cells using range names pointing relative to the moved
         // range must be recalculated, and all cells marked postponed dirty.
-        it = maTabs.begin();
+        TableContainer::iterator it = maTabs.begin();
         for (; it != maTabs.end(); ++it)
             if (*it)
                 (*it)->SetDirtyIfPostponed();
@@ -1466,7 +1467,7 @@ bool ScDocument::InsertCol( SCROW nStartRow, SCTAB nStartTab,
         else
         {
             // Listeners have been removed in UpdateReference
-            std::for_each(maTabs.begin(), maTabs.end(), StartNeededListenersHandler());
+            std::for_each(maTabs.begin(), maTabs.end(), StartNeededListenersHandler(*this));
             // At least all cells using range names pointing relative to the
             // moved range must be recalculated, and all cells marked postponed
             // dirty.
@@ -1553,14 +1554,13 @@ void ScDocument::DeleteCol(SCROW nStartRow, SCTAB nStartTab, SCROW nEndRow, SCTA
     }
 
     if ( ValidCol(sal::static_int_cast<SCCOL>(nStartCol+nSize)) )
-    {// Listeners have been removed in UpdateReference
-        TableContainer::iterator it = maTabs.begin();
-        for (; it != maTabs.end(); ++it)
-            if (*it)
-                (*it)->StartNeededListeners();
+    {
+        // Listeners have been removed in UpdateReference
+        std::for_each(maTabs.begin(), maTabs.end(), StartNeededListenersHandler(*this));
+
         // At least all cells using range names pointing relative to the moved
         // range must be recalculated, and all cells marked postponed dirty.
-        it = maTabs.begin();
+        TableContainer::iterator it = maTabs.begin();
         for (; it != maTabs.end(); ++it)
             if (*it)
                 (*it)->SetDirtyIfPostponed();
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index 6a4647c..d3b7ec0 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -1043,10 +1043,10 @@ void ScTable::DetachFormulaCells(
         aCol[nCol].DetachFormulaCells(rCxt, nRow1, nRow2);
 }
 
-void ScTable::StartNeededListeners()
+void ScTable::StartNeededListeners( sc::StartListeningContext& rCxt )
 {
     for (SCCOL i=0; i<=MAXCOL; i++)
-        aCol[i].StartNeededListeners();
+        aCol[i].StartNeededListeners(rCxt);
 }
 
 void ScTable::SetDirtyFromClip(


More information about the Libreoffice-commits mailing list