[Libreoffice-commits] core.git: 2 commits - sc/inc sc/qa sc/source

Kohei Yoshida kohei.yoshida at collabora.com
Sun Jul 27 11:39:39 PDT 2014


 sc/inc/table.hxx               |    1 
 sc/qa/unit/ucalc.cxx           |   75 +++++++++++++++++++++++++++++++++++++++++
 sc/qa/unit/ucalc.hxx           |    2 +
 sc/source/core/data/table3.cxx |    8 ++++
 sc/source/core/data/table7.cxx |    8 ++++
 5 files changed, 94 insertions(+)

New commits:
commit a3fc7f20089062afa4f778e70ba8be84032a30a7
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Sun Jul 27 14:35:37 2014 -0400

    fdo#81617: Split formula groups at sort range boundaries.
    
    Otherwise, partially sorting a range may crash, or at best incorrectly
    update formula references.
    
    Change-Id: Iefcb86d205d83ccc5b684048bfd9aadabf6e13eb

diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 44c4951..9701463 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -884,6 +884,7 @@ public:
     formula::FormulaTokenRef ResolveStaticReference( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 );
     formula::VectorRefArray FetchVectorRefArray( SCCOL nCol, SCROW nRow1, SCROW nRow2 );
 
+    void SplitFormulaGroups( SCCOL nCol, std::vector<SCROW>& rRows );
     void UnshareFormulaCells( SCCOL nCol, std::vector<SCROW>& rRows );
     void RegroupFormulaCells( SCCOL nCol );
 
diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
index a842d82..25e088f 100644
--- a/sc/source/core/data/table3.cxx
+++ b/sc/source/core/data/table3.cxx
@@ -751,6 +751,14 @@ void ScTable::SortReorderByRow(
     ScSortInfoArray::RowsType* pRows = pArray->GetDataRows();
     assert(pRows); // In sort-by-row mode we must have data rows already populated.
 
+    // Split formula groups at the sort range boundaries (if applicable).
+    std::vector<SCROW> aRowBounds;
+    aRowBounds.reserve(2);
+    aRowBounds.push_back(nRow1);
+    aRowBounds.push_back(nRow2+1);
+    for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol)
+        SplitFormulaGroups(nCol, aRowBounds);
+
     // Cells in the data rows only reference values in the document. Make
     // a copy before updating the document.
 
diff --git a/sc/source/core/data/table7.cxx b/sc/source/core/data/table7.cxx
index f39e529..6ff53de 100644
--- a/sc/source/core/data/table7.cxx
+++ b/sc/source/core/data/table7.cxx
@@ -118,6 +118,14 @@ bool ScTable::HasUniformRowHeight( SCROW nRow1, SCROW nRow2 ) const
     return nRow2 <= aData.mnRow2;
 }
 
+void ScTable::SplitFormulaGroups( SCCOL nCol, std::vector<SCROW>& rRows )
+{
+    if (!ValidCol(nCol))
+        return;
+
+    sc::SharedFormulaUtil::splitFormulaCellGroups(aCol[nCol].maCells, rRows);
+}
+
 void ScTable::UnshareFormulaCells( SCCOL nCol, std::vector<SCROW>& rRows )
 {
     if (!ValidCol(nCol))
commit 97f700721e942912101d5acd73433448e57e39e5
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date:   Sun Jul 27 14:25:23 2014 -0400

    fdo#81617: Write test for this first.
    
    This test currently crashes.
    
    Change-Id: I57133495b483664c960a15e638520d195eb02070

diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index 65c91a4..bbed0c7 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -5705,6 +5705,81 @@ void Test::testSortOutOfPlaceResult()
     m_pDoc->DeleteTab(0);
 }
 
+void Test::testSortPartialFormulaGroup()
+{
+    sc::AutoCalcSwitch aACSwitch(*m_pDoc, true); // turn auto calc on.
+    FormulaGrammarSwitch aFGSwitch(m_pDoc, formula::FormulaGrammar::GRAM_ENGLISH_XL_R1C1);
+
+    m_pDoc->InsertTab(0, "Sort");
+
+    // Set up the sheet.
+    const char* aData[][2] = {
+        { "F1", "F2" },
+        { "43", "=RC[-1]" },
+        { "50", "=RC[-1]" },
+        {  "8", "=RC[-1]" },
+        { "47", "=RC[-1]" },
+        { "28", "=RC[-1]" },
+        { 0, 0 } // terminator
+    };
+
+    // A1:B6.
+    for (SCROW i = 0; aData[i][0]; ++i)
+    {
+        m_pDoc->SetString(0, i, 0, OUString::createFromAscii(aData[i][0]));
+        m_pDoc->SetString(1, i, 0, OUString::createFromAscii(aData[i][1]));
+    }
+
+    // Check the initial condition.
+    for (SCROW i = 1; i <= 5; ++i)
+        // A2:A6 should equal B2:B6.
+        CPPUNIT_ASSERT_EQUAL(m_pDoc->GetValue(ScAddress(0,i,0)), m_pDoc->GetValue(ScAddress(1,i,0)));
+
+    const ScFormulaCell* pFC = m_pDoc->GetFormulaCell(ScAddress(1,1,0));
+    CPPUNIT_ASSERT(pFC);
+    CPPUNIT_ASSERT_MESSAGE("This formula cell should be the first in a group.", pFC->IsSharedTop());
+    CPPUNIT_ASSERT_MESSAGE("Incorrect formula group length.", pFC->GetSharedLength() == 5);
+
+    ScDBDocFunc aFunc(getDocShell());
+
+    // Sort only B2:B4.  This caused crash at one point (c.f. fdo#81617).
+
+    m_pDoc->SetAnonymousDBData(0, new ScDBData(STR_DB_LOCAL_NONAME, 0, 1, 1, 1, 3));
+
+    ScSortParam aSortData;
+    aSortData.nCol1 = 1;
+    aSortData.nCol2 = 1;
+    aSortData.nRow1 = 1;
+    aSortData.nRow2 = 3;
+    aSortData.bHasHeader = false;
+    aSortData.bInplace = true;
+    aSortData.maKeyState[0].bDoSort = true;
+    aSortData.maKeyState[0].nField = 0;
+    aSortData.maKeyState[0].bAscending = true;
+    bool bSorted = aFunc.Sort(0, aSortData, true, true, true);
+    CPPUNIT_ASSERT(bSorted);
+
+    m_pDoc->CalcAll(); // just in case...
+
+    // Check the cell values after the partial sort.
+
+    // Column A
+    CPPUNIT_ASSERT_EQUAL(43.0, m_pDoc->GetValue(ScAddress(0,1,0)));
+    CPPUNIT_ASSERT_EQUAL(50.0, m_pDoc->GetValue(ScAddress(0,2,0)));
+    CPPUNIT_ASSERT_EQUAL( 8.0, m_pDoc->GetValue(ScAddress(0,3,0)));
+    CPPUNIT_ASSERT_EQUAL(47.0, m_pDoc->GetValue(ScAddress(0,4,0)));
+    CPPUNIT_ASSERT_EQUAL(28.0, m_pDoc->GetValue(ScAddress(0,5,0)));
+
+    // Column B
+    CPPUNIT_ASSERT_EQUAL( 8.0, m_pDoc->GetValue(ScAddress(1,1,0)));
+    CPPUNIT_ASSERT_EQUAL(43.0, m_pDoc->GetValue(ScAddress(1,2,0)));
+    CPPUNIT_ASSERT_EQUAL(50.0, m_pDoc->GetValue(ScAddress(1,3,0)));
+    CPPUNIT_ASSERT_EQUAL(47.0, m_pDoc->GetValue(ScAddress(1,4,0)));
+    CPPUNIT_ASSERT_EQUAL(28.0, m_pDoc->GetValue(ScAddress(1,5,0)));
+
+    m_pDoc->DeleteTab(0);
+}
+
 void Test::testShiftCells()
 {
     m_pDoc->InsertTab(0, "foo");
diff --git a/sc/qa/unit/ucalc.hxx b/sc/qa/unit/ucalc.hxx
index 92342c4..3197990 100644
--- a/sc/qa/unit/ucalc.hxx
+++ b/sc/qa/unit/ucalc.hxx
@@ -350,6 +350,7 @@ public:
     void testSortRefUpdate2();
     void testSortRefUpdate3();
     void testSortOutOfPlaceResult();
+    void testSortPartialFormulaGroup();
     void testShiftCells();
 
     void testNoteBasic();
@@ -523,6 +524,7 @@ public:
     CPPUNIT_TEST(testSortRefUpdate2);
     CPPUNIT_TEST(testSortRefUpdate3);
     CPPUNIT_TEST(testSortOutOfPlaceResult);
+    CPPUNIT_TEST(testSortPartialFormulaGroup);
     CPPUNIT_TEST(testShiftCells);
     CPPUNIT_TEST(testNoteBasic);
     CPPUNIT_TEST(testNoteDeleteRow);


More information about the Libreoffice-commits mailing list