sc/qa/unit/ucalc.cxx | 57 ++++++++++++++++++++++++++++++++++++++++ sc/qa/unit/ucalc.hxx | 3 ++ sc/source/core/data/column3.cxx | 22 --------------- 3 files changed, 60 insertions(+), 22 deletions(-)
New commits: commit cb167ac784f9b16944da4494b65e56b2a5b66bb7 Author: Kohei Yoshida <kohei.yosh...@collabora.com> Date: Thu May 22 20:56:04 2014 -0400 fdo#78903: Don't broadcast prematurely during cell deletion. We need to wait until all the affected cells get marked dirty at the end of the deletion process. Change-Id: I49618fcc386ec2209f5f0267d50257ecb8dd21d1 diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx index 3d447d1..2d54fd5 100644 --- a/sc/source/core/data/column3.cxx +++ b/sc/source/core/data/column3.cxx @@ -169,11 +169,6 @@ public: maRows.push_back(i + nTopRow); } - void endFormulas() - { - mrDoc.EndListeningFormulaCells(maFormulaCells); - } - const std::vector<SCROW>& getNonEmptyRows() const { return maRows; @@ -266,12 +261,6 @@ void ScColumn::DeleteRow( SCROW nStartRow, SCSIZE nSize ) sc::AutoCalcSwitch aACSwitch(*pDocument, false); - // Parse all non-empty cells in the range to pick up their row positions, - // and end all formula cells. - DeleteRowsHandler aDeleteRowsFunc(*pDocument); - sc::ProcessFormula(itCell, maCells, nStartRow, nEndRow, aDeleteRowsFunc, aDeleteRowsFunc); - aDeleteRowsFunc.endFormulas(); - // Remove the cells. maCells.erase(nStartRow, nEndRow); maCells.resize(MAXROWCOUNT); @@ -285,22 +274,11 @@ void ScColumn::DeleteRow( SCROW nStartRow, SCSIZE nSize ) sc::SharedFormulaUtil::joinFormulaCellAbove(aPos); - // Single cell broadcasts on deleted cells. - BroadcastCells(aDeleteRowsFunc.getNonEmptyRows(), SC_HINT_DATACHANGED); - // Shift the text attribute array too (before the broadcast). maCellTextAttrs.erase(nStartRow, nEndRow); maCellTextAttrs.resize(MAXROWCOUNT); CellStorageModified(); - - if (!bShiftCells) - return; - - // Do area broadcast on the old non-empty cell ranges prior to the shift. - sc::SingleColumnSpanSet::SpansType aSpans; - aNonEmptySpans.getSpans(aSpans); - std::for_each(aSpans.begin(), aSpans.end(), RangeBroadcaster(*pDocument, nTab, nCol)); } sc::CellStoreType::iterator ScColumn::GetPositionToInsert( SCROW nRow ) commit fa2751ea5ce9066002a250f06bf5d056f6e0b71b Author: Kohei Yoshida <kohei.yosh...@collabora.com> Date: Thu May 22 20:54:08 2014 -0400 fdo#78903: Write test for this. Change-Id: If8ed8b74b58efd948772376a14172b52ff588f82 diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx index 8e65f68..38f7a3b 100644 --- a/sc/qa/unit/ucalc.cxx +++ b/sc/qa/unit/ucalc.cxx @@ -1352,6 +1352,63 @@ void Test::testFormulaDepTracking2() m_pDoc->DeleteTab(0); } +void Test::testFormulaDepTrackingDeleteRow() +{ + sc::AutoCalcSwitch aACSwitch(*m_pDoc, true); // turn on auto calculation. + + m_pDoc->InsertTab(0, "Test"); + + // Values in A1:A3. + m_pDoc->SetValue(ScAddress(0,0,0), 1.0); + m_pDoc->SetValue(ScAddress(0,1,0), 3.0); + m_pDoc->SetValue(ScAddress(0,2,0), 5.0); + + // SUM(A1:A3) in A5. + m_pDoc->SetString(ScAddress(0,4,0), "=SUM(A1:A3)"); + + // A6 to reference A5. + m_pDoc->SetString(ScAddress(0,5,0), "=A5*10"); + const ScFormulaCell* pFC = m_pDoc->GetFormulaCell(ScAddress(0,5,0)); + CPPUNIT_ASSERT(pFC); + + // A4 should have a broadcaster with A5 listening to it. + SvtBroadcaster* pBC = m_pDoc->GetBroadcaster(ScAddress(0,4,0)); + fprintf(stdout, "Test::testFormulaDepTrackingDeleteRow: broadcaster at A5 = %p\n", pBC); + CPPUNIT_ASSERT(pBC); + SvtBroadcaster::ListenersType* pListeners = &pBC->GetAllListeners(); + CPPUNIT_ASSERT_MESSAGE("A5 should have one listener.", pListeners->size() == 1); + SvtListener* pListener = pListeners->at(0); + CPPUNIT_ASSERT_MESSAGE("A6 should be listening to A5.", pListener == pFC); + + // Check initial values. + CPPUNIT_ASSERT_EQUAL(9.0, m_pDoc->GetValue(ScAddress(0,4,0))); + CPPUNIT_ASSERT_EQUAL(90.0, m_pDoc->GetValue(ScAddress(0,5,0))); + + fprintf(stdout, "Test::testFormulaDepTrackingDeleteRow: Deleting row 2....\n"); + // Delete row 2. + ScDocFunc& rFunc = getDocShell().GetDocFunc(); + ScMarkData aMark; + aMark.SelectOneTable(0); + rFunc.DeleteCells(ScRange(0,1,0,MAXCOL,1,0), &aMark, DEL_CELLSUP, true, true); + fprintf(stdout, "Test::testFormulaDepTrackingDeleteRow: Done deleting row 2.\n"); + + pBC = m_pDoc->GetBroadcaster(ScAddress(0,3,0)); + fprintf(stdout, "Test::testFormulaDepTrackingDeleteRow: broadcaster at A4 = %p\n", pBC); + CPPUNIT_ASSERT_MESSAGE("Broadcaster at A5 should have shifted to A4.", pBC); + pListeners = &pBC->GetAllListeners(); + CPPUNIT_ASSERT_MESSAGE("A3 should have one listener.", pListeners->size() == 1); + pFC = m_pDoc->GetFormulaCell(ScAddress(0,4,0)); + CPPUNIT_ASSERT(pFC); + pListener = pListeners->at(0); + CPPUNIT_ASSERT_MESSAGE("A5 should be listening to A4.", pFC == pListener); + + // Check values after row deletion. + CPPUNIT_ASSERT_EQUAL(6.0, m_pDoc->GetValue(ScAddress(0,3,0))); + CPPUNIT_ASSERT_EQUAL(60.0, m_pDoc->GetValue(ScAddress(0,4,0))); + + m_pDoc->DeleteTab(0); +} + void Test::testFormulaMatrixResultUpdate() { m_pDoc->InsertTab(0, "Test"); diff --git a/sc/qa/unit/ucalc.hxx b/sc/qa/unit/ucalc.hxx index 66fbfd5..39862ee 100644 --- a/sc/qa/unit/ucalc.hxx +++ b/sc/qa/unit/ucalc.hxx @@ -179,6 +179,8 @@ public: */ void testFormulaDepTracking2(); + void testFormulaDepTrackingDeleteRow(); + void testFormulaMatrixResultUpdate(); /** @@ -431,6 +433,7 @@ public: CPPUNIT_TEST(testValueIterator); CPPUNIT_TEST(testFormulaDepTracking); CPPUNIT_TEST(testFormulaDepTracking2); + CPPUNIT_TEST(testFormulaDepTrackingDeleteRow); CPPUNIT_TEST(testFormulaMatrixResultUpdate); CPPUNIT_TEST(testCellBroadcaster); CPPUNIT_TEST(testFuncParam); _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits