[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