[Libreoffice-commits] core.git: Branch 'feature/formula-core-rework' - sc/qa sc/source

Kohei Yoshida kohei.yoshida at gmail.com
Tue May 7 20:21:59 PDT 2013


 sc/qa/unit/ucalc.cxx            |   94 ++++++++++++++++++++++++++++++++++------
 sc/source/core/data/column.cxx  |   21 ++++----
 sc/source/core/data/column3.cxx |    2 
 3 files changed, 94 insertions(+), 23 deletions(-)

New commits:
commit 7b57f7f5e941232e8a94c18f8bf856200d58fbf8
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Tue May 7 23:23:18 2013 -0400

    More test and more fix wrt broadcaster rework.
    
    Much of the fix went into mdds actually.
    
    Change-Id: Ia27b0bde31081a5a28fb4afb80960777bd4fdd4f

diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index 27fa863..8aba718 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -1527,6 +1527,67 @@ void Test::testFormulaDepTracking2()
     m_pDoc->DeleteTab(0);
 }
 
+namespace {
+
+bool broadcasterShifted(const ScDocument& rDoc, const ScAddress& rFrom, const ScAddress& rTo)
+{
+    const SvtBroadcaster* pBC = rDoc.GetBroadcaster(rFrom);
+    if (pBC)
+    {
+        cerr << "Broadcaster shouldn't be here." << endl;
+        return false;
+    }
+
+    pBC = rDoc.GetBroadcaster(rTo);
+    if (!pBC)
+    {
+        cerr << "Broadcaster should be here." << endl;
+        return false;
+    }
+    return true;
+}
+
+bool checkRelativeRefToken(ScDocument& rDoc, const ScAddress& rPos, SCsCOL nRelCol, SCsROW nRelRow)
+{
+    ScFormulaCell* pFC = rDoc.GetFormulaCell(rPos);
+    if (!pFC)
+    {
+        cerr << "Formula cell expected, but not found." << endl;
+        return false;
+    }
+
+    ScTokenArray* pTokens = pFC->GetCode();
+    if (!pTokens)
+    {
+        cerr << "Token array is not present." << endl;
+        return false;
+    }
+
+    ScToken* pToken = static_cast<ScToken*>(pTokens->First());
+    if (!pToken || pToken->GetType() != formula::svSingleRef)
+    {
+        cerr << "Not a single reference token." << endl;
+        return false;
+    }
+
+    ScSingleRefData& rRef = pToken->GetSingleRef();
+    if (!rRef.IsColRel() || rRef.nRelCol != nRelCol)
+    {
+        cerr << "Unexpected relative column address." << endl;
+        return false;
+    }
+
+    if (!rRef.IsRowRel() || rRef.nRelRow != nRelRow)
+    {
+        cerr << "Unexpected relative row address." << endl;
+        return false;
+    }
+
+    return true;
+}
+
+}
+
 void Test::testCellBroadcaster()
 {
     CPPUNIT_ASSERT_MESSAGE ("failed to insert sheet", m_pDoc->InsertTab (0, "foo"));
@@ -1546,28 +1607,35 @@ void Test::testCellBroadcaster()
 
     // Move column A down 5 cells. Make sure B1 now references A6, not A1.
     m_pDoc->InsertRow(0, 0, 0, 0, 0, 5);
-    ScFormulaCell* pFC = m_pDoc->GetFormulaCell(ScAddress(1,0,0));
-    CPPUNIT_ASSERT_MESSAGE("Expected a formula cell.", pFC);
-    ScTokenArray* pTokens = pFC->GetCode();
-    ScToken* pToken = static_cast<ScToken*>(pTokens->First());
-    CPPUNIT_ASSERT_MESSAGE("Reference token not found.", pToken && pToken->GetType() == formula::svSingleRef);
-    ScSingleRefData& rRef = pToken->GetSingleRef();
-    CPPUNIT_ASSERT_EQUAL(static_cast<SCsCOL>(-1), rRef.nRelCol);
-    CPPUNIT_ASSERT_EQUAL(static_cast<SCsROW>(5), rRef.nRelRow);
+    CPPUNIT_ASSERT_MESSAGE("Relative reference check failed.",
+                           checkRelativeRefToken(*m_pDoc, ScAddress(1,0,0), -1, 5));
 
     // Make sure the broadcaster has also moved.
-    pBC = m_pDoc->GetBroadcaster(ScAddress(0,0,0));
-    CPPUNIT_ASSERT_MESSAGE("Broadcaster shouldn't exist at A1.", !pBC);
-    pBC = m_pDoc->GetBroadcaster(ScAddress(0,5,0));
-    CPPUNIT_ASSERT_MESSAGE("Broadcaster should exist at A6.", pBC);
+    CPPUNIT_ASSERT_MESSAGE("Broadcaster relocation failed.",
+                           broadcasterShifted(*m_pDoc, ScAddress(0,0,0), ScAddress(0,5,0)));
 
     // Set new value to A6 and make sure B1 gets updated.
     m_pDoc->SetValue(ScAddress(0,5,0), 45.6);
     val = m_pDoc->GetValue(ScAddress(1,0,0));
     CPPUNIT_ASSERT_EQUAL(45.6, val);
 
+    // Move column A up 3 cells, and make sure B1 now references A3, not A6.
+    m_pDoc->DeleteRow(0, 0, 0, 0, 0, 3);
+    CPPUNIT_ASSERT_MESSAGE("Relative reference check failed.",
+                           checkRelativeRefToken(*m_pDoc, ScAddress(1,0,0), -1, 2));
+
+    // The broadcaster should also have been relocated from A6 to A3.
+    CPPUNIT_ASSERT_MESSAGE("Broadcaster relocation failed.",
+                           broadcasterShifted(*m_pDoc, ScAddress(0,5,0), ScAddress(0,2,0)));
+
+    // Insert cells over A1:A10 and shift cells to right.
+    m_pDoc->InsertCol(ScRange(0, 0, 0, 0, 10, 0));
+    CPPUNIT_ASSERT_MESSAGE("Relative reference check failed.",
+                           checkRelativeRefToken(*m_pDoc, ScAddress(2,0,0), -1, 2));
+    CPPUNIT_ASSERT_MESSAGE("Broadcaster relocation failed.",
+                           broadcasterShifted(*m_pDoc, ScAddress(0,2,0), ScAddress(1,2,0)));
+
     m_pDoc->DeleteTab(0);
-    CPPUNIT_ASSERT_MESSAGE("good, all test passed.", false);
 }
 
 void Test::testFuncParam()
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index 55fe296..297fd66 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -1687,6 +1687,9 @@ void ScColumn::MoveTo(SCROW nStartRow, SCROW nEndRow, ScColumn& rCol)
 {
     pAttrArray->MoveTo(nStartRow, nEndRow, *rCol.pAttrArray);
 
+    // Move the broadcasters to the destination column.
+    maBroadcasters.transfer(nStartRow, nEndRow, rCol.maBroadcasters, nStartRow);
+
     if (maItems.empty())
         // No cells to move.
         return;
@@ -1702,10 +1705,17 @@ void ScColumn::MoveTo(SCROW nStartRow, SCROW nEndRow, ScColumn& rCol)
         aRows.push_back( nRow);
         rCol.Insert( nRow, maItems[i].pCell);
     }
+
     SCSIZE nStopPos = i;
     if (nStartPos < nStopPos)
     {
-        // Create list of ranges of cell entry positions
+        // At least one cell gets copied to the destination column.
+        maTextWidths.set_empty(nStartRow, nEndRow);
+        maScriptTypes.set_empty(nStartRow, nEndRow);
+
+        CellStorageModified();
+
+        // Create list of ranges of cell entry positions.
         typedef ::std::pair<SCSIZE,SCSIZE> PosPair;
         typedef ::std::vector<PosPair> EntryPosPairs;
         EntryPosPairs aEntries;
@@ -1736,7 +1746,6 @@ void ScColumn::MoveTo(SCROW nStartRow, SCROW nEndRow, ScColumn& rCol)
         ScAddress& rAddress = aHint.GetAddress();
 
         // must iterate backwards, because indexes of following cells become invalid
-        bool bErased = false;
         for (EntryPosPairs::reverse_iterator it( aEntries.rbegin());
                 it != aEntries.rend(); ++it)
         {
@@ -1749,14 +1758,6 @@ void ScColumn::MoveTo(SCROW nStartRow, SCROW nEndRow, ScColumn& rCol)
             }
             // Erase the slots containing pointers to the dummy cell instance.
             maItems.erase(maItems.begin() + nStartPos, maItems.begin() + nStopPos);
-            bErased = true;
-        }
-
-        if (bErased)
-        {
-            maTextWidths.set_empty(nStartRow, nEndRow);
-            maScriptTypes.set_empty(nStartRow, nEndRow);
-            CellStorageModified();
         }
     }
 }
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index d9eb7f8..1c36346 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -215,6 +215,8 @@ void ScColumn::DeleteRow( SCROW nStartRow, SCSIZE nSize )
     maTextWidths.resize(MAXROWCOUNT);
     maScriptTypes.erase(nStartRow, nEndRow);
     maScriptTypes.resize(MAXROWCOUNT);
+    maBroadcasters.erase(nStartRow, nEndRow);
+    maBroadcasters.resize(MAXROWCOUNT);
 
     ScAddress aAdr( nCol, 0, nTab );
     ScHint aHint( SC_HINT_DATACHANGED, aAdr, NULL ); // only areas (ScBaseCell* == NULL)


More information about the Libreoffice-commits mailing list