[Libreoffice-commits] core.git: Branch 'feature/formula-core-rework' - 2 commits - sc/inc sc/qa sc/source
Kohei Yoshida
kohei.yoshida at gmail.com
Fri Jul 19 12:37:16 PDT 2013
sc/inc/refupdatecontext.hxx | 3
sc/qa/unit/ucalc_formula.cxx | 85 +++++++++++++++++++++++++
sc/source/core/data/documen3.cxx | 2
sc/source/core/data/refupdatecontext.cxx | 9 ++
sc/source/core/tool/token.cxx | 104 +++++++++++++++++++++++++------
5 files changed, 182 insertions(+), 21 deletions(-)
New commits:
commit 57f9317a487f23f3f675de81bc045f3869568376
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Fri Jul 19 15:39:36 2013 -0400
Handle range reference expansion on insertion.
Change-Id: I128ed26b6d6319a7e227885801e0683b517eb439
diff --git a/sc/inc/refupdatecontext.hxx b/sc/inc/refupdatecontext.hxx
index 2f33767..91607ea 100644
--- a/sc/inc/refupdatecontext.hxx
+++ b/sc/inc/refupdatecontext.hxx
@@ -40,7 +40,8 @@ struct RefUpdateContext
RefUpdateContext();
- bool hasDelta() const;
+ bool isInserted() const;
+ bool isDeleted() const;
};
struct RefUpdateResult
diff --git a/sc/source/core/data/documen3.cxx b/sc/source/core/data/documen3.cxx
index 53769ef..04973f4 100644
--- a/sc/source/core/data/documen3.cxx
+++ b/sc/source/core/data/documen3.cxx
@@ -981,7 +981,7 @@ void ScDocument::UpdateReference(
return;
boost::scoped_ptr<sc::ExpandRefsSwitch> pExpandRefsSwitch;
- if (rCxt.meMode == URM_INSDEL && rCxt.hasDelta())
+ if (rCxt.isInserted())
pExpandRefsSwitch.reset(new sc::ExpandRefsSwitch(*this, SC_MOD()->GetInputOptions().GetExpandRefs()));
size_t nFirstTab, nLastTab;
diff --git a/sc/source/core/data/refupdatecontext.cxx b/sc/source/core/data/refupdatecontext.cxx
index 9f39f44..1ba6a6b 100644
--- a/sc/source/core/data/refupdatecontext.cxx
+++ b/sc/source/core/data/refupdatecontext.cxx
@@ -14,9 +14,14 @@ namespace sc {
RefUpdateContext::RefUpdateContext() :
meMode(URM_INSDEL), mnColDelta(0), mnRowDelta(0), mnTabDelta(0) {}
-bool RefUpdateContext::hasDelta() const
+bool RefUpdateContext::isInserted() const
{
- return (mnColDelta > 0 || mnRowDelta > 0 || mnTabDelta > 0);
+ return (meMode == URM_INSDEL) && (mnColDelta > 0 || mnRowDelta > 0 || mnTabDelta > 0);
+}
+
+bool RefUpdateContext::isDeleted() const
+{
+ return (meMode == URM_INSDEL) && (mnColDelta < 0 || mnRowDelta < 0 || mnTabDelta < 0);
}
RefUpdateResult::RefUpdateResult() : mbValueChanged(false), mbRangeSizeModified(false) {}
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index 981e898..30bef7b 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -2195,28 +2195,45 @@ void ScTokenArray::AdjustAbsoluteRefs( const ScDocument* pOldDoc, const ScAddres
namespace {
-ScRange getDeletedRange( const sc::RefUpdateContext& rCxt )
+ScRange getSelectedRange( const sc::RefUpdateContext& rCxt )
{
- ScRange aDeletedRange(ScAddress::INITIALIZE_INVALID);
+ ScRange aSelectedRange(ScAddress::INITIALIZE_INVALID);
if (rCxt.mnColDelta < 0)
{
// Delete and shift to left.
- aDeletedRange.aStart = ScAddress(rCxt.maRange.aStart.Col()+rCxt.mnColDelta, rCxt.maRange.aStart.Row(), rCxt.maRange.aStart.Tab());
- aDeletedRange.aEnd = ScAddress(rCxt.maRange.aStart.Col()-1, rCxt.maRange.aEnd.Row(), rCxt.maRange.aEnd.Tab());
+ aSelectedRange.aStart = ScAddress(rCxt.maRange.aStart.Col()+rCxt.mnColDelta, rCxt.maRange.aStart.Row(), rCxt.maRange.aStart.Tab());
+ aSelectedRange.aEnd = ScAddress(rCxt.maRange.aStart.Col()-1, rCxt.maRange.aEnd.Row(), rCxt.maRange.aEnd.Tab());
}
else if (rCxt.mnRowDelta < 0)
{
// Delete and shift up.
- aDeletedRange.aStart = ScAddress(rCxt.maRange.aStart.Col(), rCxt.maRange.aStart.Row()+rCxt.mnRowDelta, rCxt.maRange.aStart.Tab());
- aDeletedRange.aEnd = ScAddress(rCxt.maRange.aEnd.Col(), rCxt.maRange.aStart.Row()-1, rCxt.maRange.aEnd.Tab());
+ aSelectedRange.aStart = ScAddress(rCxt.maRange.aStart.Col(), rCxt.maRange.aStart.Row()+rCxt.mnRowDelta, rCxt.maRange.aStart.Tab());
+ aSelectedRange.aEnd = ScAddress(rCxt.maRange.aEnd.Col(), rCxt.maRange.aStart.Row()-1, rCxt.maRange.aEnd.Tab());
}
else if (rCxt.mnTabDelta < 0)
{
// Deleting sheets.
// TODO : Figure out what to do here.
}
+ else if (rCxt.mnColDelta > 0)
+ {
+ // Insert and shift to the right.
+ aSelectedRange.aStart = rCxt.maRange.aStart;
+ aSelectedRange.aEnd = ScAddress(rCxt.maRange.aStart.Col()+rCxt.mnColDelta-1, rCxt.maRange.aEnd.Row(), rCxt.maRange.aEnd.Tab());
+ }
+ else if (rCxt.mnRowDelta > 0)
+ {
+ // Insert and shift down.
+ aSelectedRange.aStart = rCxt.maRange.aStart;
+ aSelectedRange.aEnd = ScAddress(rCxt.maRange.aEnd.Col(), rCxt.maRange.aStart.Row()+rCxt.mnRowDelta-1, rCxt.maRange.aEnd.Tab());
+ }
+ else if (rCxt.mnTabDelta > 0)
+ {
+ // Inserting sheets.
+ // TODO : Figure out what to do here.
+ }
- return aDeletedRange;
+ return aSelectedRange;
}
void setRefDeleted( ScSingleRefData& rRef, const sc::RefUpdateContext& rCxt )
@@ -2279,11 +2296,48 @@ bool shrinkRange( const sc::RefUpdateContext& rCxt, ScRange& rRefRange, const Sc
return false;
}
+bool expandRange( const sc::RefUpdateContext& rCxt, ScRange& rRefRange, const ScRange& rInsertedRange )
+{
+ if (rCxt.mnColDelta > 0)
+ {
+ // Insert and shifting right.
+ if (rRefRange.aStart.Row() < rInsertedRange.aStart.Row() || rInsertedRange.aEnd.Row() < rRefRange.aEnd.Row())
+ // Inserted range is only partially overlapping in vertical direction. Bail out.
+ return false;
+
+ if (rInsertedRange.aStart.Col() == rRefRange.aStart.Col())
+ // Inserted range is at the left end. No expansion.
+ return false;
+
+ // Move the last column position to the right.
+ SCCOL nDelta = rInsertedRange.aEnd.Col() - rInsertedRange.aStart.Col() + 1;
+ rRefRange.aEnd.IncCol(nDelta);
+ return true;
+ }
+ else if (rCxt.mnRowDelta > 0)
+ {
+ // Insert and shifting down.
+ if (rRefRange.aStart.Col() < rInsertedRange.aStart.Col() || rInsertedRange.aEnd.Col() < rRefRange.aEnd.Col())
+ // Inserted range is only partially overlapping in horizontal direction. Bail out.
+ return false;
+
+ if (rInsertedRange.aStart.Row() == rRefRange.aStart.Row())
+ // Inserted range is at the top end. No expansion.
+ return false;
+
+ // Move the last row position down.
+ SCROW nDelta = rInsertedRange.aEnd.Row() - rInsertedRange.aStart.Row() + 1;
+ rRefRange.aEnd.IncRow(nDelta);
+ return true;
+ }
+ return false;
+}
+
}
sc::RefUpdateResult ScTokenArray::AdjustReferenceOnShift( const sc::RefUpdateContext& rCxt, const ScAddress& rOldPos )
{
- ScRange aDeletedRange = getDeletedRange(rCxt);
+ ScRange aSelectedRange = getSelectedRange(rCxt);
sc::RefUpdateResult aRes;
ScAddress aNewPos = rOldPos;
@@ -2303,7 +2357,7 @@ sc::RefUpdateResult ScTokenArray::AdjustReferenceOnShift( const sc::RefUpdateCon
ScSingleRefData& rRef = pToken->GetSingleRef();
ScAddress aAbs = rRef.toAbs(rOldPos);
- if (aDeletedRange.In(aAbs))
+ if (rCxt.isDeleted() && aSelectedRange.In(aAbs))
{
// This reference is in the deleted region.
setRefDeleted(rRef, rCxt);
@@ -2322,20 +2376,36 @@ sc::RefUpdateResult ScTokenArray::AdjustReferenceOnShift( const sc::RefUpdateCon
ScComplexRefData& rRef = pToken->GetDoubleRef();
ScRange aAbs = rRef.toAbs(rOldPos);
- if (aDeletedRange.In(aAbs))
+ if (rCxt.isDeleted())
{
- // This reference is in the deleted region.
- setRefDeleted(rRef, rCxt);
- aRes.mbValueChanged = true;
- break;
+ if (aSelectedRange.In(aAbs))
+ {
+ // This reference is in the deleted region.
+ setRefDeleted(rRef, rCxt);
+ aRes.mbValueChanged = true;
+ break;
+ }
+ else if (aSelectedRange.Intersects(aAbs))
+ {
+ if (shrinkRange(rCxt, aAbs, aSelectedRange))
+ {
+ // The reference range has been shrunk.
+ rRef.SetRange(aAbs, aNewPos);
+ aRes.mbValueChanged = true;
+ aRes.mbRangeSizeModified = true;
+ break;
+ }
+ }
}
- else if (aDeletedRange.Intersects(aAbs))
+
+ if (rCxt.isInserted() && aSelectedRange.Intersects(aAbs))
{
- if (shrinkRange(rCxt, aAbs, aDeletedRange))
+ if (expandRange(rCxt, aAbs, aSelectedRange))
{
- // The reference range has been shrunk.
+ // The reference range has been expanded.
rRef.SetRange(aAbs, aNewPos);
aRes.mbValueChanged = true;
+ aRes.mbRangeSizeModified = true;
break;
}
}
commit 043e733c15255122d6d28ca3c7f34e46449ffc08
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Fri Jul 19 15:38:03 2013 -0400
Add test for range reference expansion on cell insertions.
Change-Id: Idd8d37be518cef87ea00633774c3de846b27083a
diff --git a/sc/qa/unit/ucalc_formula.cxx b/sc/qa/unit/ucalc_formula.cxx
index 6310297..07335d4 100644
--- a/sc/qa/unit/ucalc_formula.cxx
+++ b/sc/qa/unit/ucalc_formula.cxx
@@ -568,6 +568,91 @@ void Test::testFormulaRefUpdateRange()
CPPUNIT_ASSERT_EQUAL(10.0, m_pDoc->GetValue(ScAddress(0,1,0)));
CPPUNIT_ASSERT_EQUAL(10.0, m_pDoc->GetValue(ScAddress(0,2,0)));
+ // Clear the range and start over.
+ clearRange(m_pDoc, ScRange(0,0,0,20,20,0));
+
+ // Disable expansion of range reference on insertion in adjacent areas.
+ m_pDoc->SetExpandRefs(false);
+
+ // Fill C2:D3 with values.
+ m_pDoc->SetValue(ScAddress(2,1,0), 1);
+ m_pDoc->SetValue(ScAddress(3,1,0), 2);
+ m_pDoc->SetValue(ScAddress(2,2,0), 3);
+ m_pDoc->SetValue(ScAddress(3,2,0), 4);
+
+ // Set formulas at A5 and A6.
+ m_pDoc->SetString(ScAddress(0,4,0), "=SUM(C2:D3)");
+ m_pDoc->SetString(ScAddress(0,5,0), "=SUM($C$2:$D$3)");
+
+ if (!checkFormula(*m_pDoc, ScAddress(0,4,0), "SUM(C2:D3)"))
+ CPPUNIT_FAIL("Wrong formula in A5.");
+
+ if (!checkFormula(*m_pDoc, ScAddress(0,5,0), "SUM($C$2:$D$3)"))
+ CPPUNIT_FAIL("Wrong formula in A6.");
+
+ // Insert a column at column C. This should simply shift the reference without expansion.
+ m_pDoc->InsertCol(ScRange(2,0,0,2,MAXROW,0));
+
+ if (!checkFormula(*m_pDoc, ScAddress(0,4,0), "SUM(D2:E3)"))
+ CPPUNIT_FAIL("Wrong formula in A5.");
+
+ if (!checkFormula(*m_pDoc, ScAddress(0,5,0), "SUM($D$2:$E$3)"))
+ CPPUNIT_FAIL("Wrong formula in A6.");
+
+ // Shift it back.
+ m_pDoc->DeleteCol(ScRange(2,0,0,2,MAXROW,0));
+
+ if (!checkFormula(*m_pDoc, ScAddress(0,4,0), "SUM(C2:D3)"))
+ CPPUNIT_FAIL("Wrong formula in A5.");
+
+ if (!checkFormula(*m_pDoc, ScAddress(0,5,0), "SUM($C$2:$D$3)"))
+ CPPUNIT_FAIL("Wrong formula in A6.");
+
+ // Insert at column D. This should expand the reference by one column length.
+ m_pDoc->InsertCol(ScRange(3,0,0,3,MAXROW,0));
+
+ if (!checkFormula(*m_pDoc, ScAddress(0,4,0), "SUM(C2:E3)"))
+ CPPUNIT_FAIL("Wrong formula in A5.");
+
+ if (!checkFormula(*m_pDoc, ScAddress(0,5,0), "SUM($C$2:$E$3)"))
+ CPPUNIT_FAIL("Wrong formula in A6.");
+
+ // Insert at column F. No expansion should occur since the edge expansion is turned off.
+ m_pDoc->InsertCol(ScRange(5,0,0,5,MAXROW,0));
+
+ if (!checkFormula(*m_pDoc, ScAddress(0,4,0), "SUM(C2:E3)"))
+ CPPUNIT_FAIL("Wrong formula in A5.");
+
+ if (!checkFormula(*m_pDoc, ScAddress(0,5,0), "SUM($C$2:$E$3)"))
+ CPPUNIT_FAIL("Wrong formula in A6.");
+
+ // Insert at row 2. No expansion should occur with edge expansion turned off.
+ m_pDoc->InsertRow(ScRange(0,1,0,MAXCOL,1,0));
+
+ if (!checkFormula(*m_pDoc, ScAddress(0,5,0), "SUM(C3:E4)"))
+ CPPUNIT_FAIL("Wrong formula in A6.");
+
+ if (!checkFormula(*m_pDoc, ScAddress(0,6,0), "SUM($C$3:$E$4)"))
+ CPPUNIT_FAIL("Wrong formula in A7.");
+
+ // Insert at row 4 to expand the reference range.
+ m_pDoc->InsertRow(ScRange(0,3,0,MAXCOL,3,0));
+
+ if (!checkFormula(*m_pDoc, ScAddress(0,6,0), "SUM(C3:E5)"))
+ CPPUNIT_FAIL("Wrong formula in A7.");
+
+ if (!checkFormula(*m_pDoc, ScAddress(0,7,0), "SUM($C$3:$E$5)"))
+ CPPUNIT_FAIL("Wrong formula in A8.");
+
+ // Insert at row 6. No expansion with edge expansion turned off.
+ m_pDoc->InsertRow(ScRange(0,5,0,MAXCOL,5,0));
+
+ if (!checkFormula(*m_pDoc, ScAddress(0,7,0), "SUM(C3:E5)"))
+ CPPUNIT_FAIL("Wrong formula in A8.");
+
+ if (!checkFormula(*m_pDoc, ScAddress(0,8,0), "SUM($C$3:$E$5)"))
+ CPPUNIT_FAIL("Wrong formula in A9.");
+
m_pDoc->DeleteTab(0);
}
More information about the Libreoffice-commits
mailing list