sc/qa/unit/ucalc_formula.cxx | 92 ++++++++++++++++++++++++++++++++++++++++++ sc/source/core/tool/token.cxx | 41 ++++++++++++++++++ 2 files changed, 133 insertions(+)
New commits: commit d13e67d7a3591626b165462e42ce77ddbf6dfed2 Author: Kohei Yoshida <kohei.yosh...@gmail.com> Date: Fri Jul 19 11:32:58 2013 -0400 Add test for shrinking of range references on row/column deletion. Change-Id: I096aa1aa548f0166c02de5b923d0ab8a710cfd98 diff --git a/sc/qa/unit/ucalc_formula.cxx b/sc/qa/unit/ucalc_formula.cxx index a902cae..6310297 100644 --- a/sc/qa/unit/ucalc_formula.cxx +++ b/sc/qa/unit/ucalc_formula.cxx @@ -467,6 +467,9 @@ void Test::testFormulaRefUpdateRange() if (!checkFormula(*m_pDoc, ScAddress(0,7,0), "SUM($B$2:$C$5)")) CPPUNIT_FAIL("Wrong formula in A8."); + CPPUNIT_ASSERT_EQUAL(36.0, m_pDoc->GetValue(ScAddress(0,6,0))); + CPPUNIT_ASSERT_EQUAL(36.0, m_pDoc->GetValue(ScAddress(0,7,0))); + // Delete row 3. This should shrink the range references by one row. m_pDoc->DeleteRow(ScRange(0,2,0,MAXCOL,2,0)); @@ -476,6 +479,95 @@ void Test::testFormulaRefUpdateRange() if (!checkFormula(*m_pDoc, ScAddress(0,6,0), "SUM($B$2:$C$4)")) CPPUNIT_FAIL("Wrong formula in A7."); + CPPUNIT_ASSERT_EQUAL(28.0, m_pDoc->GetValue(ScAddress(0,5,0))); + CPPUNIT_ASSERT_EQUAL(28.0, m_pDoc->GetValue(ScAddress(0,6,0))); + + // Delete row 4 - bottom of range + m_pDoc->DeleteRow(ScRange(0,3,0,MAXCOL,3,0)); + + if (!checkFormula(*m_pDoc, ScAddress(0,4,0), "SUM(B2:C3)")) + CPPUNIT_FAIL("Wrong formula in A5."); + + if (!checkFormula(*m_pDoc, ScAddress(0,5,0), "SUM($B$2:$C$3)")) + CPPUNIT_FAIL("Wrong formula in A6."); + + CPPUNIT_ASSERT_EQUAL(16.0, m_pDoc->GetValue(ScAddress(0,4,0))); + CPPUNIT_ASSERT_EQUAL(16.0, m_pDoc->GetValue(ScAddress(0,5,0))); + + // Delete row 2 - top of range + m_pDoc->DeleteRow(ScRange(0,1,0,MAXCOL,1,0)); + + if (!checkFormula(*m_pDoc, ScAddress(0,3,0), "SUM(B2:C2)")) + CPPUNIT_FAIL("Wrong formula in A4."); + + if (!checkFormula(*m_pDoc, ScAddress(0,4,0), "SUM($B$2:$C$2)")) + CPPUNIT_FAIL("Wrong formula in A5."); + + CPPUNIT_ASSERT_EQUAL(10.0, m_pDoc->GetValue(ScAddress(0,3,0))); + CPPUNIT_ASSERT_EQUAL(10.0, m_pDoc->GetValue(ScAddress(0,4,0))); + + // Clear the range and start over. + clearRange(m_pDoc, ScRange(0,0,0,20,20,0)); + + // Fill C2:F3 with values. + m_pDoc->SetValue(ScAddress(2,1,0), 1); + m_pDoc->SetValue(ScAddress(3,1,0), 2); + m_pDoc->SetValue(ScAddress(4,1,0), 3); + m_pDoc->SetValue(ScAddress(5,1,0), 4); + m_pDoc->SetValue(ScAddress(2,2,0), 5); + m_pDoc->SetValue(ScAddress(3,2,0), 6); + m_pDoc->SetValue(ScAddress(4,2,0), 7); + m_pDoc->SetValue(ScAddress(5,2,0), 8); + + // Set formulas to A2 and A3. + m_pDoc->SetString(ScAddress(0,1,0), "=SUM(C2:F3)"); + m_pDoc->SetString(ScAddress(0,2,0), "=SUM($C$2:$F$3)"); + + if (!checkFormula(*m_pDoc, ScAddress(0,1,0), "SUM(C2:F3)")) + CPPUNIT_FAIL("Wrong formula in A2."); + + if (!checkFormula(*m_pDoc, ScAddress(0,2,0), "SUM($C$2:$F$3)")) + CPPUNIT_FAIL("Wrong formula in A3."); + + CPPUNIT_ASSERT_EQUAL(36.0, m_pDoc->GetValue(ScAddress(0,1,0))); + CPPUNIT_ASSERT_EQUAL(36.0, m_pDoc->GetValue(ScAddress(0,2,0))); + + // Delete column D. + m_pDoc->DeleteCol(ScRange(3,0,0,3,MAXROW,0)); + + if (!checkFormula(*m_pDoc, ScAddress(0,1,0), "SUM(C2:E3)")) + CPPUNIT_FAIL("Wrong formula in A2."); + + if (!checkFormula(*m_pDoc, ScAddress(0,2,0), "SUM($C$2:$E$3)")) + CPPUNIT_FAIL("Wrong formula in A3."); + + CPPUNIT_ASSERT_EQUAL(28.0, m_pDoc->GetValue(ScAddress(0,1,0))); + CPPUNIT_ASSERT_EQUAL(28.0, m_pDoc->GetValue(ScAddress(0,2,0))); + + // Delete column E - the right edge of reference range. + m_pDoc->DeleteCol(ScRange(4,0,0,4,MAXROW,0)); + + if (!checkFormula(*m_pDoc, ScAddress(0,1,0), "SUM(C2:D3)")) + CPPUNIT_FAIL("Wrong formula in A2."); + + if (!checkFormula(*m_pDoc, ScAddress(0,2,0), "SUM($C$2:$D$3)")) + CPPUNIT_FAIL("Wrong formula in A3."); + + CPPUNIT_ASSERT_EQUAL(16.0, m_pDoc->GetValue(ScAddress(0,1,0))); + CPPUNIT_ASSERT_EQUAL(16.0, m_pDoc->GetValue(ScAddress(0,2,0))); + + // Delete column C - the left edge of reference range. + m_pDoc->DeleteCol(ScRange(2,0,0,2,MAXROW,0)); + + if (!checkFormula(*m_pDoc, ScAddress(0,1,0), "SUM(C2:C3)")) + CPPUNIT_FAIL("Wrong formula in A2."); + + if (!checkFormula(*m_pDoc, ScAddress(0,2,0), "SUM($C$2:$C$3)")) + CPPUNIT_FAIL("Wrong formula in A3."); + + CPPUNIT_ASSERT_EQUAL(10.0, m_pDoc->GetValue(ScAddress(0,1,0))); + CPPUNIT_ASSERT_EQUAL(10.0, m_pDoc->GetValue(ScAddress(0,2,0))); + m_pDoc->DeleteTab(0); } commit 1ac273fdd9805ba3536d5f67fed7269a1581d1f9 Author: Kohei Yoshida <kohei.yosh...@gmail.com> Date: Fri Jul 19 11:31:12 2013 -0400 Handle shrinking of range references on row/column deletion. Change-Id: Id53de2b24e02f6d8a078dceadf2d8399a0348b72 diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx index 2d1a236..981e898 100644 --- a/sc/source/core/tool/token.cxx +++ b/sc/source/core/tool/token.cxx @@ -2248,6 +2248,37 @@ void setRefDeleted( ScComplexRefData& rRef, const sc::RefUpdateContext& rCxt ) } } +bool shrinkRange( const sc::RefUpdateContext& rCxt, ScRange& rRefRange, const ScRange& rDeletedRange ) +{ + if (rCxt.mnColDelta < 0) + { + // Shifting left. + if (rRefRange.aStart.Row() < rDeletedRange.aStart.Row() || rDeletedRange.aEnd.Row() < rRefRange.aEnd.Row()) + // Deleted range is only partially overlapping in vertical direction. Bail out. + return false; + + // Move the last column position to the left. + SCCOL nDelta = rDeletedRange.aStart.Col() - rDeletedRange.aEnd.Col() - 1; + rRefRange.aEnd.IncCol(nDelta); + return true; + } + else if (rCxt.mnRowDelta < 0) + { + // Shifting up. + + if (rRefRange.aStart.Col() < rDeletedRange.aStart.Col() || rDeletedRange.aEnd.Col() < rRefRange.aEnd.Col()) + // Deleted range is only partially overlapping in horizontal direction. Bail out. + return false; + + // Move the last row position up. + SCROW nDelta = rDeletedRange.aStart.Row() - rDeletedRange.aEnd.Row() - 1; + rRefRange.aEnd.IncRow(nDelta); + return true; + } + + return false; +} + } sc::RefUpdateResult ScTokenArray::AdjustReferenceOnShift( const sc::RefUpdateContext& rCxt, const ScAddress& rOldPos ) @@ -2298,6 +2329,16 @@ sc::RefUpdateResult ScTokenArray::AdjustReferenceOnShift( const sc::RefUpdateCon aRes.mbValueChanged = true; break; } + else if (aDeletedRange.Intersects(aAbs)) + { + if (shrinkRange(rCxt, aAbs, aDeletedRange)) + { + // The reference range has been shrunk. + rRef.SetRange(aAbs, aNewPos); + aRes.mbValueChanged = true; + break; + } + } if (rCxt.maRange.In(aAbs)) aAbs.Move(rCxt.mnColDelta, rCxt.mnRowDelta, rCxt.mnTabDelta); _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits