[Libreoffice-commits] core.git: Branch 'feature/formula-core-rework' - sc/inc sc/qa sc/source
Kohei Yoshida
kohei.yoshida at gmail.com
Tue Jul 16 08:45:51 PDT 2013
sc/inc/refdata.hxx | 1
sc/inc/reftokenhelper.hxx | 2 -
sc/qa/unit/ucalc.cxx | 23 ++++++++------
sc/source/core/data/formulacell.cxx | 9 +----
sc/source/core/tool/compiler.cxx | 27 +++++++++++------
sc/source/core/tool/detfunc.cxx | 5 +--
sc/source/core/tool/refdata.cxx | 6 +++
sc/source/core/tool/reftokenhelper.cxx | 51 +++++++++++++++++++--------------
sc/source/filter/excel/xichart.cxx | 2 -
sc/source/ui/unoobj/chart2uno.cxx | 22 +++++++-------
10 files changed, 85 insertions(+), 63 deletions(-)
New commits:
commit 40c7aec3d3ef6ce76857b02c3d68fb24f1831414
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Tue Jul 16 11:37:22 2013 -0400
More on this.
Change-Id: I9571c903c11e92984ac29818c68d66c2fd9c30d2
diff --git a/sc/inc/refdata.hxx b/sc/inc/refdata.hxx
index 74028ac..77d03e6d 100644
--- a/sc/inc/refdata.hxx
+++ b/sc/inc/refdata.hxx
@@ -167,6 +167,7 @@ struct ScComplexRefData
inline bool ValidExternal() const;
SC_DLLPUBLIC ScRange toAbs( const ScAddress& rPos ) const;
+ void SetRange( const ScRange& rRange, const ScAddress& rPos );
/// Absolute references have to be up-to-date when calling this!
void PutInOrder();
diff --git a/sc/inc/reftokenhelper.hxx b/sc/inc/reftokenhelper.hxx
index d7cfa8e..cd1c9e8 100644
--- a/sc/inc/reftokenhelper.hxx
+++ b/sc/inc/reftokenhelper.hxx
@@ -62,7 +62,7 @@ public:
static bool SC_DLLPUBLIC intersects(
const ::std::vector<ScTokenRef>& rTokens, const ScTokenRef& pToken, const ScAddress& rPos);
- static void SC_DLLPUBLIC join(::std::vector<ScTokenRef>& rTokens, const ScTokenRef& pToken);
+ static void SC_DLLPUBLIC join(::std::vector<ScTokenRef>& rTokens, const ScTokenRef& pToken, const ScAddress& rPos);
static bool getDoubleRefDataFromToken(ScComplexRefData& rData, const ScTokenRef& pToken);
diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index fb34ca3..adecc55 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -3176,7 +3176,7 @@ void Test::testFormulaPosition()
namespace {
-bool hasRange(const std::vector<ScTokenRef>& rRefTokens, const ScRange& rRange)
+bool hasRange(const std::vector<ScTokenRef>& rRefTokens, const ScRange& rRange, const ScAddress& rPos)
{
std::vector<ScTokenRef>::const_iterator it = rRefTokens.begin(), itEnd = rRefTokens.end();
for (; it != itEnd; ++it)
@@ -3193,7 +3193,7 @@ bool hasRange(const std::vector<ScTokenRef>& rRefTokens, const ScRange& rRange)
if (rRange.aStart != rRange.aEnd)
break;
- ScAddress aThis(aData.nCol, aData.nRow, aData.nTab);
+ ScAddress aThis = aData.toAbs(rPos);
if (aThis == rRange.aStart)
return true;
}
@@ -3201,7 +3201,7 @@ bool hasRange(const std::vector<ScTokenRef>& rRefTokens, const ScRange& rRange)
case formula::svDoubleRef:
{
ScComplexRefData aData = p->GetDoubleRef();
- ScRange aThis(aData.Ref1.nCol, aData.Ref1.nRow, aData.Ref1.nTab, aData.Ref2.nCol, aData.Ref2.nRow, aData.Ref2.nTab);
+ ScRange aThis = aData.toAbs(rPos);
if (aThis == rRange)
return true;
}
@@ -3230,30 +3230,33 @@ void Test::testJumpToPrecedentsDependents()
{
// C1's precedent should be A1:A2,B3.
- ScRangeList aRange(ScRange(2, 0, 0));
+ ScAddress aC1(2, 0, 0);
+ ScRangeList aRange(aC1);
rDocFunc.DetectiveCollectAllPreds(aRange, aRefTokens);
CPPUNIT_ASSERT_MESSAGE("A1:A2 should be a precedent of C1.",
- hasRange(aRefTokens, ScRange(0, 0, 0, 0, 1, 0)));
+ hasRange(aRefTokens, ScRange(0, 0, 0, 0, 1, 0), aC1));
CPPUNIT_ASSERT_MESSAGE("B3 should be a precedent of C1.",
- hasRange(aRefTokens, ScRange(1, 2, 0)));
+ hasRange(aRefTokens, ScRange(1, 2, 0), aC1));
}
{
// C2's precedent should be A1 only.
- ScRangeList aRange(ScRange(2, 1, 0));
+ ScAddress aC2(2, 1, 0);
+ ScRangeList aRange(aC2);
rDocFunc.DetectiveCollectAllPreds(aRange, aRefTokens);
CPPUNIT_ASSERT_EQUAL_MESSAGE("there should only be one reference token.",
aRefTokens.size(), static_cast<size_t>(1));
CPPUNIT_ASSERT_MESSAGE("A1 should be a precedent of C1.",
- hasRange(aRefTokens, ScRange(0, 0, 0)));
+ hasRange(aRefTokens, ScRange(0, 0, 0), aC2));
}
{
// A1's dependent should be C1:C2.
- ScRangeList aRange(ScRange(0, 0, 0));
+ ScAddress aA1(0, 0, 0);
+ ScRangeList aRange(aA1);
rDocFunc.DetectiveCollectAllSuccs(aRange, aRefTokens);
CPPUNIT_ASSERT_MESSAGE("C1:C2 should be the only dependent of A1.",
- aRefTokens.size() == 1 && hasRange(aRefTokens, ScRange(2, 0, 0, 2, 1, 0)));
+ aRefTokens.size() == 1 && hasRange(aRefTokens, ScRange(2, 0, 0, 2, 1, 0), aA1));
}
m_pDoc->DeleteTab(0);
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index 6a77c715..bf3782e 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -2032,14 +2032,9 @@ bool ScFormulaCell::HasOneReference( ScRange& r ) const
ScToken* p = static_cast<ScToken*>(pCode->GetNextReferenceRPN());
if( p && !pCode->GetNextReferenceRPN() ) // only one!
{
- p->CalcAbsIfRel( aPos );
SingleDoubleRefProvider aProv( *p );
- r.aStart.Set( aProv.Ref1.nCol,
- aProv.Ref1.nRow,
- aProv.Ref1.nTab );
- r.aEnd.Set( aProv.Ref2.nCol,
- aProv.Ref2.nRow,
- aProv.Ref2.nTab );
+ r.aStart = aProv.Ref1.toAbs(aPos);
+ r.aEnd = aProv.Ref2.toAbs(aPos);
return true;
}
else
diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx
index 597028b..1787f5a 100644
--- a/sc/source/core/tool/compiler.cxx
+++ b/sc/source/core/tool/compiler.cxx
@@ -4243,10 +4243,18 @@ ScRangeData* ScCompiler::UpdateReference(UpdateRefMode eUpdateRefMode,
t->GetDoubleRef().Ref2.IsRelName()));
if (bRelName)
{
- t->CalcAbsIfRel( rOldPos);
- bool bValid = (t->GetType() == svSingleRef ?
- t->GetSingleRef().Valid() :
- t->GetDoubleRef().Valid());
+ bool bValid = false;
+ if (t->GetType() == svSingleRef)
+ {
+ ScAddress aAbs = t->GetSingleRef().toAbs(rOldPos);
+ bValid = ValidAddress(aAbs);
+ }
+ else
+ {
+ ScRange aAbs = t->GetDoubleRef().toAbs(rOldPos);
+ bValid = ValidRange(aAbs);
+ }
+
// If the reference isn't valid, copying the formula
// wrapped it. Replace SharedFormula.
if (!bValid)
@@ -4276,7 +4284,6 @@ ScRangeData* ScCompiler::UpdateReference(UpdateRefMode eUpdateRefMode,
}
else if( t->GetType() != svIndex ) // it may be a DB area!!!
{
- t->CalcAbsIfRel( rOldPos );
switch (t->GetType())
{
case svExternalSingleRef:
@@ -4286,10 +4293,10 @@ ScRangeData* ScCompiler::UpdateReference(UpdateRefMode eUpdateRefMode,
// In fact, calling ScRefUpdate::Update() for URM_MOVE
// may have negative side effects. Simply adapt
// relative references to the new position.
- t->CalcRelFromAbs( aPos);
break;
case svSingleRef:
{
+ t->CalcAbsIfRel( rOldPos );
if ( ScRefUpdate::Update( pDoc, eUpdateRefMode,
aPos, r, nDx, nDy, nDz,
SingleDoubleRefModifier(
@@ -4301,9 +4308,11 @@ ScRangeData* ScCompiler::UpdateReference(UpdateRefMode eUpdateRefMode,
default:
{
ScComplexRefData& rRef = t->GetDoubleRef();
- SCCOL nCols = rRef.Ref2.nCol - rRef.Ref1.nCol;
- SCROW nRows = rRef.Ref2.nRow - rRef.Ref1.nRow;
- SCTAB nTabs = rRef.Ref2.nTab - rRef.Ref1.nTab;
+ ScRange aAbs = rRef.toAbs(rOldPos);
+ SCCOL nCols = aAbs.aEnd.Col() - aAbs.aStart.Col();
+ SCROW nRows = aAbs.aEnd.Row() - aAbs.aStart.Row();
+ SCTAB nTabs = aAbs.aEnd.Tab() - aAbs.aStart.Tab();
+ t->CalcAbsIfRel( rOldPos );
if ( ScRefUpdate::Update( pDoc, eUpdateRefMode,
aPos, r, nDx, nDy, nDz,
t->GetDoubleRef()) != UR_NOTHING)
diff --git a/sc/source/core/tool/detfunc.cxx b/sc/source/core/tool/detfunc.cxx
index 9240811..2558031 100644
--- a/sc/source/core/tool/detfunc.cxx
+++ b/sc/source/core/tool/detfunc.cxx
@@ -1401,8 +1401,7 @@ void ScDetectiveFunc::GetAllPreds(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW n
for (ScToken* p = aRefIter.GetNextRefToken(); p; p = aRefIter.GetNextRefToken())
{
ScTokenRef pRef(static_cast<ScToken*>(p->Clone()));
- pRef->CalcAbsIfRel(aIter.GetPos());
- ScRefTokenHelper::join(rRefTokens, pRef);
+ ScRefTokenHelper::join(rRefTokens, pRef, aIter.GetPos());
}
}
}
@@ -1430,7 +1429,7 @@ void ScDetectiveFunc::GetAllSuccs(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW n
{
// This address is absolute.
pRef = ScRefTokenHelper::createRefToken(aPos);
- ScRefTokenHelper::join(rRefTokens, pRef);
+ ScRefTokenHelper::join(rRefTokens, pRef, ScAddress());
}
}
}
diff --git a/sc/source/core/tool/refdata.cxx b/sc/source/core/tool/refdata.cxx
index 9988b87..eab55ce 100644
--- a/sc/source/core/tool/refdata.cxx
+++ b/sc/source/core/tool/refdata.cxx
@@ -294,4 +294,10 @@ ScRange ScComplexRefData::toAbs( const ScAddress& rPos ) const
return ScRange(Ref1.toAbs(rPos), Ref2.toAbs(rPos));
}
+void ScComplexRefData::SetRange( const ScRange& rRange, const ScAddress& rPos )
+{
+ Ref1.SetAddress(rRange.aStart, rPos);
+ Ref2.SetAddress(rRange.aEnd, rPos);
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/tool/reftokenhelper.cxx b/sc/source/core/tool/reftokenhelper.cxx
index 4580c4f..0dcda68 100644
--- a/sc/source/core/tool/reftokenhelper.cxx
+++ b/sc/source/core/tool/reftokenhelper.cxx
@@ -287,9 +287,9 @@ public:
* @param rTokens existing list of reference tokens
* @param rToken new token
*/
- void operator() (vector<ScTokenRef>& rTokens, const ScTokenRef& pToken)
+ void operator() (vector<ScTokenRef>& rTokens, const ScTokenRef& pToken, const ScAddress& rPos)
{
- join(rTokens, pToken);
+ join(rTokens, pToken, rPos);
}
private:
@@ -322,15 +322,7 @@ private:
return true;
}
- bool isContained(const ScComplexRefData& aOldData, const ScComplexRefData& aData) const
- {
- // Check for containment.
- bool bRowsContained = (aOldData.Ref1.nRow <= aData.Ref1.nRow) && (aData.Ref2.nRow <= aOldData.Ref2.nRow);
- bool bColsContained = (aOldData.Ref1.nCol <= aData.Ref1.nCol) && (aData.Ref2.nCol <= aOldData.Ref2.nCol);
- return (bRowsContained && bColsContained);
- }
-
- void join(vector<ScTokenRef>& rTokens, const ScTokenRef& pToken)
+ void join(vector<ScTokenRef>& rTokens, const ScTokenRef& pToken, const ScAddress& rPos)
{
// Normalize the token to a double reference.
ScComplexRefData aData;
@@ -376,25 +368,42 @@ private:
// Sheet ranges differ.
continue;
- if (isContained(aOldData, aData))
+ ScRange aOld = aOldData.toAbs(rPos), aNew = aData.toAbs(rPos);
+ if (aOld.In(aNew))
// This new range is part of an existing range. Skip it.
return;
- bool bSameRows = (aData.Ref1.nRow == aOldData.Ref1.nRow) && (aData.Ref2.nRow == aOldData.Ref2.nRow);
- bool bSameCols = (aData.Ref1.nCol == aOldData.Ref1.nCol) && (aData.Ref2.nCol == aOldData.Ref2.nCol);
+ bool bSameRows = (aNew.aStart.Row() == aOld.aStart.Row()) && (aNew.aEnd.Row() == aOld.aEnd.Row());
+ bool bSameCols = (aNew.aStart.Col() == aOld.aStart.Col()) && (aNew.aEnd.Col() == aOld.aEnd.Col());
ScComplexRefData aNewData = aOldData;
bool bJoinRanges = false;
if (bSameRows)
{
+ SCCOL nNewMin, nNewMax;
bJoinRanges = overlaps(
- aData.Ref1.nCol, aData.Ref2.nCol, aOldData.Ref1.nCol, aOldData.Ref2.nCol,
- aNewData.Ref1.nCol, aNewData.Ref2.nCol);
+ aNew.aStart.Col(), aNew.aEnd.Col(), aOld.aStart.Col(), aOld.aEnd.Col(),
+ nNewMin, nNewMax);
+
+ if (bJoinRanges)
+ {
+ aNew.aStart.SetCol(nNewMin);
+ aNew.aEnd.SetCol(nNewMax);
+ aNewData.SetRange(aNew, rPos);
+ }
}
else if (bSameCols)
{
+ SCROW nNewMin, nNewMax;
bJoinRanges = overlaps(
- aData.Ref1.nRow, aData.Ref2.nRow, aOldData.Ref1.nRow, aOldData.Ref2.nRow,
- aNewData.Ref1.nRow, aNewData.Ref2.nRow);
+ aNew.aStart.Row(), aNew.aEnd.Row(), aOld.aStart.Row(), aOld.aEnd.Row(),
+ nNewMin, nNewMax);
+
+ if (bJoinRanges)
+ {
+ aNew.aStart.SetRow(nNewMin);
+ aNew.aEnd.SetRow(nNewMax);
+ aNewData.SetRange(aNew, rPos);
+ }
}
if (bJoinRanges)
@@ -418,7 +427,7 @@ private:
// Pop the last token from the list, and keep joining recursively.
ScTokenRef p = rTokens.back();
rTokens.pop_back();
- join(rTokens, p);
+ join(rTokens, p, rPos);
}
else
rTokens.push_back(pToken);
@@ -427,10 +436,10 @@ private:
}
-void ScRefTokenHelper::join(vector<ScTokenRef>& rTokens, const ScTokenRef& pToken)
+void ScRefTokenHelper::join(vector<ScTokenRef>& rTokens, const ScTokenRef& pToken, const ScAddress& rPos)
{
JoinRefTokenRanges join;
- join(rTokens, pToken);
+ join(rTokens, pToken, rPos);
}
bool ScRefTokenHelper::getDoubleRefDataFromToken(ScComplexRefData& rData, const ScTokenRef& pToken)
diff --git a/sc/source/filter/excel/xichart.cxx b/sc/source/filter/excel/xichart.cxx
index 66bd895..2ccd8c5 100644
--- a/sc/source/filter/excel/xichart.cxx
+++ b/sc/source/filter/excel/xichart.cxx
@@ -906,7 +906,7 @@ void XclImpChSourceLink::FillSourceLink( ::std::vector< ScTokenRef >& rTokens )
ScTokenRef pToken(static_cast<ScToken*>(p->Clone()));
if (ScRefTokenHelper::isRef(pToken))
// This is a reference token. Store it.
- ScRefTokenHelper::join(rTokens, pToken);
+ ScRefTokenHelper::join(rTokens, pToken, ScAddress());
}
}
diff --git a/sc/source/ui/unoobj/chart2uno.cxx b/sc/source/ui/unoobj/chart2uno.cxx
index 979b6b1..c2b8459 100644
--- a/sc/source/ui/unoobj/chart2uno.cxx
+++ b/sc/source/ui/unoobj/chart2uno.cxx
@@ -196,7 +196,7 @@ vector<ScTokenRef>* TokenTable::getColRanges(SCCOL nCol) const
continue;
ScTokenRef pCopy(static_cast<ScToken*>(p->Clone()));
- ScRefTokenHelper::join(*pTokens, pCopy);
+ ScRefTokenHelper::join(*pTokens, pCopy, ScAddress());
}
return pTokens.release();
}
@@ -219,7 +219,7 @@ vector<ScTokenRef>* TokenTable::getRowRanges(SCROW nRow) const
continue;
ScTokenRef p2(static_cast<ScToken*>(p->Clone()));
- ScRefTokenHelper::join(*pTokens, p2);
+ ScRefTokenHelper::join(*pTokens, p2, ScAddress());
}
return pTokens.release();
}
@@ -237,7 +237,7 @@ vector<ScTokenRef>* TokenTable::getAllRanges() const
continue;
ScTokenRef p2(static_cast<ScToken*>(p->Clone()));
- ScRefTokenHelper::join(*pTokens, p2);
+ ScRefTokenHelper::join(*pTokens, p2, ScAddress());
}
return pTokens.release();
}
@@ -1348,12 +1348,12 @@ bool lcl_addUpperLeftCornerIfMissing(vector<ScTokenRef>& rRefTokens,
{
ScTokenRef pCorner(
new ScExternalSingleRefToken(nFileId, aExtTabName, aData));
- ScRefTokenHelper::join(rRefTokens, pCorner);
+ ScRefTokenHelper::join(rRefTokens, pCorner, ScAddress());
}
else
{
ScTokenRef pCorner(new ScSingleRefToken(aData));
- ScRefTokenHelper::join(rRefTokens, pCorner);
+ ScRefTokenHelper::join(rRefTokens, pCorner, ScAddress());
}
}
else
@@ -1368,12 +1368,12 @@ bool lcl_addUpperLeftCornerIfMissing(vector<ScTokenRef>& rRefTokens,
{
ScTokenRef pCorner(
new ScExternalDoubleRefToken(nFileId, aExtTabName, r));
- ScRefTokenHelper::join(rRefTokens, pCorner);
+ ScRefTokenHelper::join(rRefTokens, pCorner, ScAddress());
}
else
{
ScTokenRef pCorner(new ScDoubleRefToken(r));
- ScRefTokenHelper::join(rRefTokens, pCorner);
+ ScRefTokenHelper::join(rRefTokens, pCorner, ScAddress());
}
}
@@ -1822,9 +1822,9 @@ uno::Sequence< beans::PropertyValue > SAL_CALL ScChart2DataProvider::detectArgum
vector<ScTokenRef>::const_iterator itr = aTokens.begin(), itrEnd = aTokens.end();
for (; itr != itrEnd; ++itr)
{
- ScRefTokenHelper::join(aAllTokens, *itr);
+ ScRefTokenHelper::join(aAllTokens, *itr, ScAddress());
if(!bThisIsCategories)
- ScRefTokenHelper::join(aAllSeriesLabelTokens, *itr);
+ ScRefTokenHelper::join(aAllSeriesLabelTokens, *itr, ScAddress());
}
if(bThisIsCategories)
bHasCategoriesLabels=true;
@@ -1841,9 +1841,9 @@ uno::Sequence< beans::PropertyValue > SAL_CALL ScChart2DataProvider::detectArgum
vector<ScTokenRef>::const_iterator itr = aTokens.begin(), itrEnd = aTokens.end();
for (; itr != itrEnd; ++itr)
{
- ScRefTokenHelper::join(aAllTokens, *itr);
+ ScRefTokenHelper::join(aAllTokens, *itr, ScAddress());
if(bThisIsCategories)
- ScRefTokenHelper::join(aAllCategoriesValuesTokens, *itr);
+ ScRefTokenHelper::join(aAllCategoriesValuesTokens, *itr, ScAddress());
}
}
//detect row source
More information about the Libreoffice-commits
mailing list