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

Kohei Yoshida kohei.yoshida at collabora.com
Wed Jul 30 08:06:13 PDT 2014


 sc/inc/column.hxx                  |    1 
 sc/inc/table.hxx                   |    5 ---
 sc/qa/unit/ucalc.hxx               |    2 +
 sc/qa/unit/ucalc_sharedformula.cxx |   56 +++++++++++++++++++++++++++++++++++++
 sc/source/core/data/column.cxx     |   27 -----------------
 sc/source/core/data/column4.cxx    |    3 +
 sc/source/core/data/documen7.cxx   |   40 +++++++++++++++++++++++++-
 sc/source/core/data/table2.cxx     |    7 ----
 sc/source/core/data/table7.cxx     |   10 ++++++
 9 files changed, 110 insertions(+), 41 deletions(-)

New commits:
commit b2ee0235e88dc4da715b5766295ed88f27974fbd
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Wed Jul 30 11:02:31 2014 -0400

    fdo#80501: Ensure that we notify each listener only once.
    
    Change-Id: If2ce4643ff58c7c2ba326d749698dd5196a108dc

diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 1a08163..fb1eb97 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -484,7 +484,6 @@ public:
     void        StartNeededListeners(); // only for cells where NeedsListening()==true
     void        SetDirtyIfPostponed();
     void BroadcastRecalcOnRefMove();
-    void BroadcastRefMoved( const sc::RefMovedHint& rHint );
     void TransferListeners( ScColumn& rDestCol, SCROW nRow1, SCROW nRow2, SCROW nRowDelta );
     void CollectListeners( std::vector<SvtListener*>& rListeners, SCROW nRow1, SCROW nRow2 );
 
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 4486d42..9806a47 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -923,10 +923,7 @@ public:
      */
     void BroadcastRecalcOnRefMove();
 
-    /**
-     * Broadcast all listeners of specified range that the range have moved.
-     */
-    void BroadcastRefMoved( const sc::RefMovedHint& rHint );
+    void CollectListeners( std::vector<SvtListener*>& rListeners, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 );
 
     void TransferListeners(
         ScTable& rDestTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index c32fb01..e2cfc74 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -3052,33 +3052,6 @@ void ScColumn::BroadcastRecalcOnRefMove()
 
 namespace {
 
-class BroadcastRefMovedHandler
-{
-    const sc::RefMovedHint& mrHint;
-public:
-    BroadcastRefMovedHandler( const sc::RefMovedHint& rHint ) : mrHint(rHint) {}
-
-    void operator() ( size_t, SvtBroadcaster* p )
-    {
-        p->Broadcast(mrHint);
-    }
-};
-
-}
-
-void ScColumn::BroadcastRefMoved( const sc::RefMovedHint& rHint )
-{
-    const ScRange& rRange = rHint.getRange();
-    SCROW nRow1 = rRange.aStart.Row();
-    SCROW nRow2 = rRange.aEnd.Row();
-
-    // Notify all listeners within specified rows.
-    BroadcastRefMovedHandler aFunc(rHint);
-    sc::ProcessBroadcaster(maBroadcasters.begin(), maBroadcasters, nRow1, nRow2, aFunc);
-}
-
-namespace {
-
 class TransferListenersHandler
 {
 public:
diff --git a/sc/source/core/data/column4.cxx b/sc/source/core/data/column4.cxx
index 131f8cc..3f26db1 100644
--- a/sc/source/core/data/column4.cxx
+++ b/sc/source/core/data/column4.cxx
@@ -950,6 +950,9 @@ public:
 
 void ScColumn::CollectListeners( std::vector<SvtListener*>& rListeners, SCROW nRow1, SCROW nRow2 )
 {
+    if (nRow2 < nRow1 || !ValidRow(nRow1) || !ValidRow(nRow2))
+        return;
+
     ListenerCollector aFunc(rListeners);
     sc::ProcessBroadcaster(maBroadcasters.begin(), maBroadcasters, nRow1, nRow2, aFunc);
 }
diff --git a/sc/source/core/data/documen7.cxx b/sc/source/core/data/documen7.cxx
index d973fc7..5a4df60f1 100644
--- a/sc/source/core/data/documen7.cxx
+++ b/sc/source/core/data/documen7.cxx
@@ -126,6 +126,22 @@ void ScDocument::BroadcastCells( const ScRange& rRange, sal_uLong nHint )
     BroadcastUno(SfxSimpleHint(SC_HINT_DATACHANGED));
 }
 
+namespace {
+
+class RefMovedNotifier : std::unary_function<SvtListener*, void>
+{
+    const sc::RefMovedHint& mrHint;
+public:
+    RefMovedNotifier( const sc::RefMovedHint& rHint ) : mrHint(rHint) {}
+
+    void operator() ( SvtListener* p )
+    {
+        p->Notify(mrHint);
+    }
+};
+
+}
+
 void ScDocument::BroadcastRefMoved( const sc::RefMovedHint& rHint )
 {
     if (!pBASM)
@@ -146,6 +162,28 @@ void ScDocument::BroadcastRefMoved( const sc::RefMovedHint& rHint )
         }
     }
 
+    // Collect all listeners listening into the range.
+    std::vector<SvtListener*> aListeners;
+    for (SCTAB nTab = rSrcRange.aStart.Tab(); nTab <= rSrcRange.aEnd.Tab(); ++nTab)
+    {
+        ScTable* pTab = FetchTable(nTab);
+        if (!pTab)
+            continue;
+
+        pTab->CollectListeners(
+            aListeners,
+            rSrcRange.aStart.Col(), rSrcRange.aStart.Row(),
+            rSrcRange.aEnd.Col(), rSrcRange.aEnd.Row());
+    }
+
+    // Remove any duplicate listener entries.  We must ensure that we notify
+    // each unique listener only once.
+    std::sort(aListeners.begin(), aListeners.end());
+    aListeners.erase(std::unique(aListeners.begin(), aListeners.end()), aListeners.end());
+
+    // Notify the listeners.
+    std::for_each(aListeners.begin(), aListeners.end(), RefMovedNotifier(rHint));
+
     for (SCTAB nTab = rSrcRange.aStart.Tab(); nTab <= rSrcRange.aEnd.Tab(); ++nTab)
     {
         ScTable* pTab = FetchTable(nTab);
@@ -157,8 +195,6 @@ void ScDocument::BroadcastRefMoved( const sc::RefMovedHint& rHint )
         if (!pDestTab)
             continue;
 
-        // Adjust the references.
-        pTab->BroadcastRefMoved(rHint);
         // Move the listeners from the old location to the new.
         pTab->TransferListeners(
             *pDestTab, rSrcRange.aStart.Col(), rSrcRange.aStart.Row(),
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index ce14a5f..657ab6f 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -1704,13 +1704,6 @@ void ScTable::BroadcastRecalcOnRefMove()
         aCol[i].BroadcastRecalcOnRefMove();
 }
 
-void ScTable::BroadcastRefMoved( const sc::RefMovedHint& rHint )
-{
-    const ScRange& rRange = rHint.getRange();
-    for (SCCOL nCol = rRange.aStart.Col(); nCol <= rRange.aEnd.Col(); ++nCol)
-        aCol[nCol].BroadcastRefMoved(rHint);
-}
-
 void ScTable::TransferListeners(
     ScTable& rDestTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
     SCCOL nColDelta, SCROW nRowDelta )
diff --git a/sc/source/core/data/table7.cxx b/sc/source/core/data/table7.cxx
index 6763565..407a8ba 100644
--- a/sc/source/core/data/table7.cxx
+++ b/sc/source/core/data/table7.cxx
@@ -149,4 +149,14 @@ void ScTable::RegroupFormulaCells( SCCOL nCol )
     aCol[nCol].RegroupFormulaCells();
 }
 
+void ScTable::CollectListeners(
+    std::vector<SvtListener*>& rListeners, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
+{
+    if (nCol2 < nCol1 || !ValidCol(nCol1) || !ValidCol(nCol2))
+        return;
+
+    for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
+        aCol[nCol].CollectListeners(rListeners, nRow1, nRow2);
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit d0125712494ac0be512aa5e3fd7315e0cab2b323
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Wed Jul 30 10:04:17 2014 -0400

    fdo#80501: Write test for this first.
    
    Change-Id: I43c0018f445394387ef28590b56ca38344e61c11

diff --git a/sc/qa/unit/ucalc.hxx b/sc/qa/unit/ucalc.hxx
index 471cf82..b067a22 100644
--- a/sc/qa/unit/ucalc.hxx
+++ b/sc/qa/unit/ucalc.hxx
@@ -289,6 +289,7 @@ public:
     void testSearchCells();
     void testSharedFormulas();
     void testSharedFormulasRefUpdate();
+    void testSharedFormulasRefUpdateMove();
     void testSharedFormulasRefUpdateRange();
     void testSharedFormulasRefUpdateExternal();
     void testSharedFormulasInsertRow();
@@ -497,6 +498,7 @@ public:
     CPPUNIT_TEST(testSearchCells);
     CPPUNIT_TEST(testSharedFormulas);
     CPPUNIT_TEST(testSharedFormulasRefUpdate);
+    CPPUNIT_TEST(testSharedFormulasRefUpdateMove);
     CPPUNIT_TEST(testSharedFormulasRefUpdateRange);
     CPPUNIT_TEST(testSharedFormulasRefUpdateExternal);
     CPPUNIT_TEST(testSharedFormulasInsertRow);
diff --git a/sc/qa/unit/ucalc_sharedformula.cxx b/sc/qa/unit/ucalc_sharedformula.cxx
index b4babd6..5fa1dfa 100644
--- a/sc/qa/unit/ucalc_sharedformula.cxx
+++ b/sc/qa/unit/ucalc_sharedformula.cxx
@@ -403,6 +403,62 @@ void Test::testSharedFormulasRefUpdate()
     m_pDoc->DeleteTab(0);
 }
 
+void Test::testSharedFormulasRefUpdateMove()
+{
+    sc::AutoCalcSwitch aACSwitch(*m_pDoc, true); // turn on auto calc.
+    FormulaGrammarSwitch aFGSwitch(m_pDoc, formula::FormulaGrammar::GRAM_ENGLISH_XL_R1C1);
+
+    m_pDoc->InsertTab(0, "Test");
+
+    // Set values in B2:B4.
+    for (SCROW i = 1; i <= 3; ++i)
+        m_pDoc->SetValue(ScAddress(1,i,0), i);
+
+    // Make sure the values are really there.
+    CPPUNIT_ASSERT_EQUAL(1.0, m_pDoc->GetValue(ScAddress(1,1,0)));
+    CPPUNIT_ASSERT_EQUAL(2.0, m_pDoc->GetValue(ScAddress(1,2,0)));
+    CPPUNIT_ASSERT_EQUAL(3.0, m_pDoc->GetValue(ScAddress(1,3,0)));
+
+    // Set formulas in C2:C4 that reference B2:B4 individually.
+    for (SCROW i = 1; i <= 3; ++i)
+        m_pDoc->SetString(ScAddress(2,i,0), "=RC[-1]");
+
+    // Check the formula results.
+    CPPUNIT_ASSERT_EQUAL(1.0, m_pDoc->GetValue(ScAddress(2,1,0)));
+    CPPUNIT_ASSERT_EQUAL(2.0, m_pDoc->GetValue(ScAddress(2,2,0)));
+    CPPUNIT_ASSERT_EQUAL(3.0, m_pDoc->GetValue(ScAddress(2,3,0)));
+
+    // Move B2:B4 to B1:B3.
+    bool bMoved = getDocShell().GetDocFunc().MoveBlock(ScRange(1,1,0,1,3,0), ScAddress(1,0,0), true, true, false, true);
+    CPPUNIT_ASSERT(bMoved);
+
+    // Make sure the values have been moved for real.
+    CPPUNIT_ASSERT_EQUAL(1.0, m_pDoc->GetValue(ScAddress(1,0,0)));
+    CPPUNIT_ASSERT_EQUAL(2.0, m_pDoc->GetValue(ScAddress(1,1,0)));
+    CPPUNIT_ASSERT_EQUAL(3.0, m_pDoc->GetValue(ScAddress(1,2,0)));
+
+    // The formulas should have been adjusted for the move.
+    CPPUNIT_ASSERT(checkFormula(*m_pDoc, ScAddress(2,1,0), "R[-1]C[-1]"));
+    CPPUNIT_ASSERT(checkFormula(*m_pDoc, ScAddress(2,2,0), "R[-1]C[-1]"));
+    CPPUNIT_ASSERT(checkFormula(*m_pDoc, ScAddress(2,3,0), "R[-1]C[-1]"));
+
+    SfxUndoManager* pUndoMgr = m_pDoc->GetUndoManager();
+    CPPUNIT_ASSERT(pUndoMgr);
+    pUndoMgr->Undo();
+
+    // The values should have moved back.
+    CPPUNIT_ASSERT_EQUAL(1.0, m_pDoc->GetValue(ScAddress(1,1,0)));
+    CPPUNIT_ASSERT_EQUAL(2.0, m_pDoc->GetValue(ScAddress(1,2,0)));
+    CPPUNIT_ASSERT_EQUAL(3.0, m_pDoc->GetValue(ScAddress(1,3,0)));
+
+    // And the formulas should have been re-adjusted to their original references.
+    CPPUNIT_ASSERT(checkFormula(*m_pDoc, ScAddress(2,1,0), "RC[-1]"));
+    CPPUNIT_ASSERT(checkFormula(*m_pDoc, ScAddress(2,2,0), "RC[-1]"));
+    CPPUNIT_ASSERT(checkFormula(*m_pDoc, ScAddress(2,3,0), "RC[-1]"));
+
+    m_pDoc->DeleteTab(0);
+}
+
 void Test::testSharedFormulasRefUpdateRange()
 {
     m_pDoc->InsertTab(0, "Test");


More information about the Libreoffice-commits mailing list