sc/inc/column.hxx | 3 +- sc/inc/table.hxx | 3 +- sc/qa/unit/ucalc_formula.cxx | 49 +++++++++++++++++++++++++++++++++++-- sc/qa/unit/ucalc_sharedformula.cxx | 6 ++++ sc/source/core/data/column.cxx | 24 +++++++++++------- sc/source/core/data/column4.cxx | 11 ++++++-- sc/source/core/data/document10.cxx | 3 +- sc/source/core/data/table7.cxx | 5 ++- 8 files changed, 85 insertions(+), 19 deletions(-)
New commits: commit dafce0665c852297d39cddf76f46c77c14a8f12a Author: Kohei Yoshida <[email protected]> Date: Fri Apr 25 00:54:47 2014 -0400 fdo#77728: Re-compile tokens when named range is updated. Change-Id: Icd9f8c60d9e105478abb5b5ad64e969623830a4c diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx index 2670dbb..a243598 100644 --- a/sc/source/core/data/column.cxx +++ b/sc/source/core/data/column.cxx @@ -2113,6 +2113,16 @@ class UpdateRefOnNonCopy : std::unary_function<sc::FormulaGroupEntry, void> ScDocument* mpUndoDoc; bool mbUpdated; + void recompileTokenArray( ScFormulaCell& rTopCell ) + { + // We need to re-compile the token array when a range name is + // modified, to correctly reflect the new references in the + // name. + ScCompiler aComp(&mpCxt->mrDoc, rTopCell.aPos, *rTopCell.GetCode()); + aComp.SetGrammar(mpCxt->mrDoc.GetGrammar()); + aComp.CompileTokenArray(); + } + void updateRefOnShift( sc::FormulaGroupEntry& rGroup ) { if (!rGroup.mbShared) @@ -2146,7 +2156,10 @@ class UpdateRefOnNonCopy : std::unary_function<sc::FormulaGroupEntry, void> aRes.mbValueChanged = true; } - if (aRes.mbReferenceModified) + if (aRes.mbNameModified) + recompileTokenArray(*pTop); + + if (aRes.mbReferenceModified || aRes.mbNameModified) { sc::StartListeningContext aStartCxt(mpCxt->mrDoc); sc::EndListeningContext aEndCxt(mpCxt->mrDoc, pOldCode.get()); @@ -2218,14 +2231,7 @@ class UpdateRefOnNonCopy : std::unary_function<sc::FormulaGroupEntry, void> sc::AutoCalcSwitch(mpCxt->mrDoc, false); if (aRes.mbNameModified) - { - // We need to re-compile the token array when a range name is - // modified, to correctly reflect the new references in the - // name. - ScCompiler aComp(&mpCxt->mrDoc, aPos, *pCode); - aComp.SetGrammar(mpCxt->mrDoc.GetGrammar()); - aComp.CompileTokenArray(); - } + recompileTokenArray(*pTop); // Perform end-listening, start-listening, and dirtying on all // formula cells in the group. commit 7608bf4660d11ccda56cb7c3edad4d78d3610139 Author: Kohei Yoshida <[email protected]> Date: Fri Apr 25 00:53:59 2014 -0400 fdo#77728: Add test case for named range expansion and formula update. Change-Id: Ia900ae5f1091ac220c4e08b667920affa2546261 diff --git a/sc/qa/unit/ucalc_formula.cxx b/sc/qa/unit/ucalc_formula.cxx index e3283db..9776715 100644 --- a/sc/qa/unit/ucalc_formula.cxx +++ b/sc/qa/unit/ucalc_formula.cxx @@ -1900,11 +1900,11 @@ void Test::testFormulaRefUpdateNamedExpressionMove() void Test::testFormulaRefUpdateNamedExpressionExpandRef() { + sc::AutoCalcSwitch aACSwitch(*m_pDoc, true); // turn auto calc on. + m_pDoc->InsertTab(0, "Test"); m_pDoc->SetExpandRefs(true); // turn on automatic range expansion. - sc::AutoCalcSwitch aACSwitch(*m_pDoc, true); // turn auto calc on. - bool bInserted = m_pDoc->InsertNewRangeName("MyRange", ScAddress(0,0,0), "$A$1:$A$3"); CPPUNIT_ASSERT(bInserted); @@ -1957,6 +1957,51 @@ void Test::testFormulaRefUpdateNamedExpressionExpandRef() pName->GetSymbol(aSymbol, m_pDoc->GetGrammar()); CPPUNIT_ASSERT_EQUAL(OUString("$B$4:$B$9"), aSymbol); + // Clear the document and start over. + m_pDoc->GetRangeName()->clear(); + clearSheet(m_pDoc, 0); + + // Set values to A1:A3. + m_pDoc->SetValue(ScAddress(0,0,0), 1.0); + m_pDoc->SetValue(ScAddress(0,1,0), 2.0); + m_pDoc->SetValue(ScAddress(0,2,0), 3.0); + + // Name A1:A3 'MyData'. + bInserted = m_pDoc->InsertNewRangeName("MyData", ScAddress(0,0,0), "$A$1:$A$3"); + CPPUNIT_ASSERT(bInserted); + + // Set formulas to C1:C2 and E1. + m_pDoc->SetString(ScAddress(2,0,0), "=SUM(MyData)"); + m_pDoc->SetString(ScAddress(2,1,0), "=SUM(MyData)"); + m_pDoc->SetString(ScAddress(4,0,0), "=SUM(MyData)"); + + // C1:C2 should be shared. + const ScFormulaCell* pFC = m_pDoc->GetFormulaCell(ScAddress(2,0,0)); + CPPUNIT_ASSERT(pFC); + CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(0), pFC->GetSharedTopRow()); + CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(2), pFC->GetSharedLength()); + + // E1 should not be shared. + pFC = m_pDoc->GetFormulaCell(ScAddress(4,0,0)); + CPPUNIT_ASSERT(pFC); + CPPUNIT_ASSERT(!pFC->IsShared()); + + // Check the results. + CPPUNIT_ASSERT_EQUAL(6.0, m_pDoc->GetValue(ScAddress(2,0,0))); + CPPUNIT_ASSERT_EQUAL(6.0, m_pDoc->GetValue(ScAddress(2,1,0))); + CPPUNIT_ASSERT_EQUAL(6.0, m_pDoc->GetValue(ScAddress(4,0,0))); + + // Insert a new row at row 3. This should expand MyData to A1:A4. + rFunc.InsertCells(ScRange(0,2,0,MAXCOL,2,0), &aMark, INS_INSROWS, false, true, false); + + // Set new value to A3. + m_pDoc->SetValue(ScAddress(0,2,0), 4.0); + + // Check the results again. + CPPUNIT_ASSERT_EQUAL(10.0, m_pDoc->GetValue(ScAddress(2,0,0))); + CPPUNIT_ASSERT_EQUAL(10.0, m_pDoc->GetValue(ScAddress(2,1,0))); + CPPUNIT_ASSERT_EQUAL(10.0, m_pDoc->GetValue(ScAddress(4,0,0))); + m_pDoc->DeleteTab(0); } commit 36e0d770928f71c932db5dea9f04645f65222ea6 Author: Kohei Yoshida <[email protected]> Date: Thu Apr 24 21:49:45 2014 -0400 fdo#77728: Don't forget to start listening after the named range update. Change-Id: I7a4160db0dd2b9ac2c98402bb6110c548e879b3d diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx index 80d9189..7f6f81c 100644 --- a/sc/inc/column.hxx +++ b/sc/inc/column.hxx @@ -378,7 +378,8 @@ public: void PreprocessRangeNameUpdate( sc::EndListeningContext& rEndListenCxt, sc::CompileFormulaContext& rCompileCxt ); - void PostprocessRangeNameUpdate( sc::CompileFormulaContext& rCompileCxt ); + void PostprocessRangeNameUpdate( + sc::StartListeningContext& rStartListenCxt, sc::CompileFormulaContext& rCompileCxt ); const SfxPoolItem* GetAttr( SCROW nRow, sal_uInt16 nWhich ) const; const ScPatternAttr* GetPattern( SCROW nRow ) const; diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx index b13e7d1..a8bef6e 100644 --- a/sc/inc/table.hxx +++ b/sc/inc/table.hxx @@ -854,7 +854,8 @@ public: void PreprocessRangeNameUpdate( sc::EndListeningContext& rEndListenCxt, sc::CompileFormulaContext& rCompileCxt ); - void PostprocessRangeNameUpdate( sc::CompileFormulaContext& rCompileCxt ); + void PostprocessRangeNameUpdate( + sc::StartListeningContext& rStartListenCxt, sc::CompileFormulaContext& rCompileCxt ); ScConditionalFormatList* GetCondFormList(); const ScConditionalFormatList* GetCondFormList() const; diff --git a/sc/source/core/data/column4.cxx b/sc/source/core/data/column4.cxx index cad94e5..b955344 100644 --- a/sc/source/core/data/column4.cxx +++ b/sc/source/core/data/column4.cxx @@ -645,11 +645,13 @@ public: class PostRangeNameUpdateHandler { ScDocument* mpDoc; + sc::StartListeningContext& mrStartListenCxt; sc::CompileFormulaContext& mrCompileFormulaCxt; public: - PostRangeNameUpdateHandler( ScDocument* pDoc, sc::CompileFormulaContext& rCompileCxt ) : + PostRangeNameUpdateHandler( ScDocument* pDoc, sc::StartListeningContext& rStartListenCxt, sc::CompileFormulaContext& rCompileCxt ) : mpDoc(pDoc), + mrStartListenCxt(rStartListenCxt), mrCompileFormulaCxt(rCompileCxt) {} void operator() ( sc::FormulaGroupEntry& rEntry ) @@ -677,6 +679,7 @@ public: { ScFormulaCell* p = *pp; p->SyncSharedCode(); + p->StartListeningTo(mrStartListenCxt); p->SetDirty(); } } @@ -697,6 +700,7 @@ public: aComp2.CompileTokenArray(); pCell->SetCode(pNewCode); + pCell->StartListeningTo(mrStartListenCxt); pCell->SetDirty(); } } @@ -715,12 +719,13 @@ void ScColumn::PreprocessRangeNameUpdate( std::for_each(aGroups.begin(), aGroups.end(), aFunc); } -void ScColumn::PostprocessRangeNameUpdate( sc::CompileFormulaContext& rCompileCxt ) +void ScColumn::PostprocessRangeNameUpdate( + sc::StartListeningContext& rStartListenCxt, sc::CompileFormulaContext& rCompileCxt ) { // Collect all formula groups. std::vector<sc::FormulaGroupEntry> aGroups = GetFormulaGroupEntries(); - PostRangeNameUpdateHandler aFunc(pDocument, rCompileCxt); + PostRangeNameUpdateHandler aFunc(pDocument, rStartListenCxt, rCompileCxt); std::for_each(aGroups.begin(), aGroups.end(), aFunc); } diff --git a/sc/source/core/data/document10.cxx b/sc/source/core/data/document10.cxx index 9513dfb..2046b31 100644 --- a/sc/source/core/data/document10.cxx +++ b/sc/source/core/data/document10.cxx @@ -255,12 +255,13 @@ void ScDocument::PreprocessRangeNameUpdate() void ScDocument::PostprocessRangeNameUpdate() { + sc::StartListeningContext aStartListenCxt(*this); sc::CompileFormulaContext aCompileCxt(this); TableContainer::iterator it = maTabs.begin(), itEnd = maTabs.end(); for (; it != itEnd; ++it) { ScTable* p = *it; - p->PostprocessRangeNameUpdate(aCompileCxt); + p->PostprocessRangeNameUpdate(aStartListenCxt, aCompileCxt); } } diff --git a/sc/source/core/data/table7.cxx b/sc/source/core/data/table7.cxx index 385bea1..59d2b36 100644 --- a/sc/source/core/data/table7.cxx +++ b/sc/source/core/data/table7.cxx @@ -96,10 +96,11 @@ void ScTable::PreprocessRangeNameUpdate( aCol[i].PreprocessRangeNameUpdate(rEndListenCxt, rCompileCxt); } -void ScTable::PostprocessRangeNameUpdate( sc::CompileFormulaContext& rCompileCxt ) +void ScTable::PostprocessRangeNameUpdate( + sc::StartListeningContext& rStartListenCxt, sc::CompileFormulaContext& rCompileCxt ) { for (SCCOL i = 0; i <= MAXCOL; ++i) - aCol[i].PostprocessRangeNameUpdate(rCompileCxt); + aCol[i].PostprocessRangeNameUpdate(rStartListenCxt, rCompileCxt); } void ScTable::UpdateScriptTypes( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ) commit 485dddac7048aa9a877d205b25bf0c98c4887160 Author: Kohei Yoshida <[email protected]> Date: Thu Apr 24 21:21:46 2014 -0400 fdo#77728: Write test for this. Change-Id: I42d0cb7f99dce62e0ac5aa471b190ee7d3cf1efe diff --git a/sc/qa/unit/ucalc_sharedformula.cxx b/sc/qa/unit/ucalc_sharedformula.cxx index d482216..a3b9049 100644 --- a/sc/qa/unit/ucalc_sharedformula.cxx +++ b/sc/qa/unit/ucalc_sharedformula.cxx @@ -1295,6 +1295,12 @@ void Test::testSharedFormulaUpdateOnNamedRangeChange() CPPUNIT_ASSERT_EQUAL(8.0, m_pDoc->GetValue(ScAddress(1,7,0))); CPPUNIT_ASSERT_EQUAL(2.5, m_pDoc->GetValue(ScAddress(2,0,0))); + // Change the value of A4 and make sure the value change gets propagated. + m_pDoc->SetValue(ScAddress(0,3,0), 0.0); + CPPUNIT_ASSERT_EQUAL(6.0, m_pDoc->GetValue(ScAddress(1,0,0))); + CPPUNIT_ASSERT_EQUAL(6.0, m_pDoc->GetValue(ScAddress(1,1,0))); + CPPUNIT_ASSERT_EQUAL(6.0, m_pDoc->GetValue(ScAddress(1,2,0))); + m_pDoc->DeleteTab(0); } _______________________________________________ Libreoffice-commits mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
