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

Kohei Yoshida kohei.yoshida at gmail.com
Tue Aug 6 17:34:20 PDT 2013


 sc/inc/formulacell.hxx                |    6 ++++
 sc/inc/sharedformula.hxx              |    6 ----
 sc/qa/unit/ucalc_sharedformula.cxx    |   23 +++++++++++++++++++
 sc/source/core/data/column.cxx        |    6 ----
 sc/source/core/data/column3.cxx       |    7 -----
 sc/source/core/data/formulacell.cxx   |   41 ++++++++++++++++++++++++++++++++++
 sc/source/core/tool/sharedformula.cxx |   10 +++-----
 7 files changed, 77 insertions(+), 22 deletions(-)

New commits:
commit e97c5938be86bc44ee6ce2cf549589b8d6c1e80f
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Tue Aug 6 19:03:47 2013 -0400

    Handle shared token array correctly when adjusting formula grouping.
    
    Change-Id: Ib4b141f415b36565106e946ccbc47f2b9f80d89c

diff --git a/sc/inc/formulacell.hxx b/sc/inc/formulacell.hxx
index f857aff..3d70200 100644
--- a/sc/inc/formulacell.hxx
+++ b/sc/inc/formulacell.hxx
@@ -314,6 +314,10 @@ public:
 
     void            MaybeInterpret();
 
+    /**
+     * Turn a non-grouped cell into the top of a grouped cell.
+     */
+    ScFormulaCellGroupRef CreateCellGroup( SCROW nStart, SCROW nLen, bool bInvariant );
     ScFormulaCellGroupRef GetCellGroup();
     void SetCellGroup( const ScFormulaCellGroupRef &xRef );
 
@@ -333,6 +337,8 @@ public:
     bool IsSharedInvariant() const;
     SCROW GetSharedTopRow() const;
     SCROW GetSharedLength() const;
+    ScTokenArray* GetSharedCode();
+    const ScTokenArray* GetSharedCode() const;
 };
 
 #endif
diff --git a/sc/inc/sharedformula.hxx b/sc/inc/sharedformula.hxx
index 866c22f..232c4bc 100644
--- a/sc/inc/sharedformula.hxx
+++ b/sc/inc/sharedformula.hxx
@@ -46,11 +46,7 @@ public:
             }
 
             // Create a new group.
-            xGroup.reset(new ScFormulaCellGroup);
-            xGroup->mnStart = pPrev->aPos.Row();
-            xGroup->mnLength = 2;
-            xGroup->mbInvariant = (eState == ScFormulaCell::EqualInvariant);
-            pPrev->SetCellGroup(xGroup);
+            xGroup = pPrev->CreateCellGroup(pPrev->aPos.Row(), 2, eState == ScFormulaCell::EqualInvariant);
             pCur->SetCellGroup(xGroup);
         }
     }
diff --git a/sc/qa/unit/ucalc_sharedformula.cxx b/sc/qa/unit/ucalc_sharedformula.cxx
index 7934483..1eba457 100644
--- a/sc/qa/unit/ucalc_sharedformula.cxx
+++ b/sc/qa/unit/ucalc_sharedformula.cxx
@@ -32,6 +32,7 @@ void Test::testSharedFormulas()
     CPPUNIT_ASSERT_MESSAGE("This cell is expected to be a shared formula cell.", pFC && pFC->IsShared());
     CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(9), pFC->GetSharedTopRow());
     CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(2), pFC->GetSharedLength());
+    CPPUNIT_ASSERT_MESSAGE("The token is expected to be shared.", pFC->GetCode() == pFC->GetSharedCode());
 
     aPos.SetRow(8); // B9
     m_pDoc->SetString(aPos, "=A9*2");
@@ -39,6 +40,7 @@ void Test::testSharedFormulas()
     CPPUNIT_ASSERT_MESSAGE("This cell is expected to be a shared formula cell.", pFC && pFC->IsShared());
     CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(8), pFC->GetSharedTopRow());
     CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(3), pFC->GetSharedLength());
+    CPPUNIT_ASSERT_MESSAGE("The token is expected to be shared.", pFC->GetCode() == pFC->GetSharedCode());
 
     aPos.SetRow(12); // B13
     m_pDoc->SetString(aPos, "=A13*2");
@@ -52,6 +54,7 @@ void Test::testSharedFormulas()
     CPPUNIT_ASSERT_MESSAGE("This cell is expected to be a shared formula cell.", pFC && pFC->IsShared());
     CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(8), pFC->GetSharedTopRow());
     CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(5), pFC->GetSharedLength());
+    CPPUNIT_ASSERT_MESSAGE("The token is expected to be shared.", pFC->GetCode() == pFC->GetSharedCode());
 
     // Insert formulas to B15:B16.
     aPos.SetRow(14); // B15
@@ -62,6 +65,7 @@ void Test::testSharedFormulas()
     CPPUNIT_ASSERT_MESSAGE("This cell is expected to be a shared formula cell.", pFC && pFC->IsShared());
     CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(14), pFC->GetSharedTopRow());
     CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(2), pFC->GetSharedLength());
+    CPPUNIT_ASSERT_MESSAGE("The token is expected to be shared.", pFC->GetCode() == pFC->GetSharedCode());
 
     // Insert a formula to B14, and B9:B16 should be shared.
     aPos.SetRow(13); // B14
@@ -70,6 +74,7 @@ void Test::testSharedFormulas()
     CPPUNIT_ASSERT_MESSAGE("This cell is expected to be a shared formula cell.", pFC && pFC->IsShared());
     CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(8), pFC->GetSharedTopRow());
     CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(8), pFC->GetSharedLength());
+    CPPUNIT_ASSERT_MESSAGE("The token is expected to be shared.", pFC->GetCode() == pFC->GetSharedCode());
 
     // Insert an incompatible formula to B12, to split the shared range to B9:B11 and B13:B16.
     aPos.SetRow(11); // B12
@@ -82,12 +87,14 @@ void Test::testSharedFormulas()
     CPPUNIT_ASSERT_MESSAGE("This cell is expected to be a shared formula cell.", pFC && pFC->IsShared());
     CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(8), pFC->GetSharedTopRow());
     CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(3), pFC->GetSharedLength());
+    CPPUNIT_ASSERT_MESSAGE("The token is expected to be shared.", pFC->GetCode() == pFC->GetSharedCode());
 
     aPos.SetRow(12); // B13
     pFC = m_pDoc->GetFormulaCell(aPos);
     CPPUNIT_ASSERT_MESSAGE("This cell is expected to be a shared formula cell.", pFC && pFC->IsShared());
     CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(12), pFC->GetSharedTopRow());
     CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(4), pFC->GetSharedLength());
+    CPPUNIT_ASSERT_MESSAGE("The token is expected to be shared.", pFC->GetCode() == pFC->GetSharedCode());
 
     // Extend B13:B16 to B13:B20.
     aPos.SetRow(16); // B17
@@ -103,6 +110,7 @@ void Test::testSharedFormulas()
     // B13:B20 shuld be shared.
     CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(12), pFC->GetSharedTopRow());
     CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(8), pFC->GetSharedLength());
+    CPPUNIT_ASSERT_MESSAGE("The token is expected to be shared.", pFC->GetCode() == pFC->GetSharedCode());
 
     // Empty B19. This should split it into B13:B18, and B20 non-shared.
     aPos.SetRow(18);
@@ -113,6 +121,7 @@ void Test::testSharedFormulas()
     // B13:B18 should be shared.
     CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(12), pFC->GetSharedTopRow());
     CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(6), pFC->GetSharedLength());
+    CPPUNIT_ASSERT_MESSAGE("The token is expected to be shared.", pFC->GetCode() == pFC->GetSharedCode());
     // B20 shold be non-shared.
     aPos.SetRow(19); // B20
     pFC = m_pDoc->GetFormulaCell(aPos);
@@ -132,6 +141,7 @@ void Test::testSharedFormulas()
     pFC = m_pDoc->GetFormulaCell(aPos);
     CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(14), pFC->GetSharedTopRow());
     CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(4), pFC->GetSharedLength());
+    CPPUNIT_ASSERT_MESSAGE("The token is expected to be shared.", pFC->GetCode() == pFC->GetSharedCode());
 
     // Set numeric value to B15, to make B16:B18 shared.
     aPos.SetRow(14);
@@ -141,6 +151,7 @@ void Test::testSharedFormulas()
     // B16:B18 should be shared.
     CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(15), pFC->GetSharedTopRow());
     CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(3), pFC->GetSharedLength());
+    CPPUNIT_ASSERT_MESSAGE("The token is expected to be shared.", pFC->GetCode() == pFC->GetSharedCode());
 
     // Set string value to B16 to make B17:B18 shared.
     aPos.SetRow(15);
@@ -153,6 +164,7 @@ void Test::testSharedFormulas()
     // B17:B18 should be shared.
     CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(16), pFC->GetSharedTopRow());
     CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(2), pFC->GetSharedLength());
+    CPPUNIT_ASSERT_MESSAGE("The token is expected to be shared.", pFC->GetCode() == pFC->GetSharedCode());
 
     // Set edit text to B17. Now B18 should be non-shared.
     ScFieldEditEngine& rEditEngine = m_pDoc->GetEditEngine();
@@ -191,6 +203,7 @@ void Test::testSharedFormulas()
     CPPUNIT_ASSERT_MESSAGE("B10 should be a formula cell.", pFC);
     CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(1), pFC->GetSharedTopRow());
     CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(9), pFC->GetSharedLength());
+    CPPUNIT_ASSERT_MESSAGE("The token is expected to be shared.", pFC->GetCode() == pFC->GetSharedCode());
 
     // Delete A4:B8. This should splite the grouping to B2:B3 and B9:B10.
     clearRange(m_pDoc, ScRange(0,3,0,1,7,0));
@@ -199,12 +212,14 @@ void Test::testSharedFormulas()
     CPPUNIT_ASSERT_MESSAGE("B2 should be a formula cell.", pFC);
     CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(1), pFC->GetSharedTopRow());
     CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(2), pFC->GetSharedLength());
+    CPPUNIT_ASSERT_MESSAGE("The token is expected to be shared.", pFC->GetCode() == pFC->GetSharedCode());
 
     aPos.SetRow(8);
     pFC = m_pDoc->GetFormulaCell(aPos);
     CPPUNIT_ASSERT_MESSAGE("B9 should be a formula cell.", pFC);
     CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(8), pFC->GetSharedTopRow());
     CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(2), pFC->GetSharedLength());
+    CPPUNIT_ASSERT_MESSAGE("The token is expected to be shared.", pFC->GetCode() == pFC->GetSharedCode());
 
     // Delete rows 4:8 and shift row 9 and below up to row 4.  This should
     // re-merge the two into a group of B2:B5.
@@ -214,6 +229,7 @@ void Test::testSharedFormulas()
     CPPUNIT_ASSERT_MESSAGE("B2 should be a formula cell.", pFC);
     CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(1), pFC->GetSharedTopRow());
     CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(4), pFC->GetSharedLength());
+    CPPUNIT_ASSERT_MESSAGE("The token is expected to be shared.", pFC->GetCode() == pFC->GetSharedCode());
 
     // Insert 2 rows at row 4, to split it into B2:B3 and B6:B7.
     m_pDoc->InsertRow(ScRange(0,3,0,MAXCOL,4,0));
@@ -221,12 +237,14 @@ void Test::testSharedFormulas()
     CPPUNIT_ASSERT_MESSAGE("B2 should be a formula cell.", pFC);
     CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(1), pFC->GetSharedTopRow());
     CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(2), pFC->GetSharedLength());
+    CPPUNIT_ASSERT_MESSAGE("The token is expected to be shared.", pFC->GetCode() == pFC->GetSharedCode());
 
     aPos.SetRow(5);
     pFC = m_pDoc->GetFormulaCell(aPos);
     CPPUNIT_ASSERT_MESSAGE("B6 should be a formula cell.", pFC);
     CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(5), pFC->GetSharedTopRow());
     CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(2), pFC->GetSharedLength());
+    CPPUNIT_ASSERT_MESSAGE("The token is expected to be shared.", pFC->GetCode() == pFC->GetSharedCode());
 
     m_pDoc->DeleteTab(0);
 }
@@ -245,6 +263,7 @@ void Test::testSharedFormulasCopyPaste()
     CPPUNIT_ASSERT_MESSAGE("B9 should be a formula cell.", pFC);
     CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(0), pFC->GetSharedTopRow());
     CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(10), pFC->GetSharedLength());
+    CPPUNIT_ASSERT_MESSAGE("The token is expected to be shared.", pFC->GetCode() == pFC->GetSharedCode());
 
     // Copy formulas in B6:B9 to the clipboard doc.
     ScRange aSrcRange(1,5,0,1,8,0); // B6:B9
@@ -254,6 +273,7 @@ void Test::testSharedFormulasCopyPaste()
     CPPUNIT_ASSERT_MESSAGE("B9 in the clip doc should be a formula cell.", pFC);
     CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(5), pFC->GetSharedTopRow());
     CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(4), pFC->GetSharedLength());
+    CPPUNIT_ASSERT_MESSAGE("The token is expected to be shared.", pFC->GetCode() == pFC->GetSharedCode());
 
     // Paste them to C2:C10.
     ScRange aDestRange(2,1,0,2,9,0);
@@ -266,6 +286,7 @@ void Test::testSharedFormulasCopyPaste()
     CPPUNIT_ASSERT_MESSAGE("C2 should be a formula cell.", pFC);
     CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(1), pFC->GetSharedTopRow());
     CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(9), pFC->GetSharedLength());
+    CPPUNIT_ASSERT_MESSAGE("The token is expected to be shared.", pFC->GetCode() == pFC->GetSharedCode());
 
     ScRange aRange(1,0,0,1,9,0); // B1:B10
     ScDocument* pUndoDoc = new ScDocument(SCDOCMODE_UNDO);
@@ -282,6 +303,7 @@ void Test::testSharedFormulasCopyPaste()
         CPPUNIT_ASSERT_MESSAGE("Must be a formula cell.", pFC);
         CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(0), pFC->GetSharedTopRow());
         CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(10), pFC->GetSharedLength());
+        CPPUNIT_ASSERT_MESSAGE("The token is expected to be shared.", pFC->GetCode() == pFC->GetSharedCode());
     }
 
     // Overwrite B1:B10.
@@ -302,6 +324,7 @@ void Test::testSharedFormulasCopyPaste()
         CPPUNIT_ASSERT_MESSAGE("This should be a formula cell.", pFC);
         CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(0), pFC->GetSharedTopRow());
         CPPUNIT_ASSERT_EQUAL(static_cast<SCROW>(10), pFC->GetSharedLength());
+        CPPUNIT_ASSERT_MESSAGE("The token is expected to be shared.", pFC->GetCode() == pFC->GetSharedCode());
     }
 
     m_pDoc->DeleteTab(0);
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index 66343a7..0171fab 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -1287,11 +1287,7 @@ class CopyToClipHandler
             }
 
             // Create a new group.
-            xGroup.reset(new ScFormulaCellGroup);
-            xGroup->mnStart = pPrev->aPos.Row();
-            xGroup->mnLength = 2;
-            xGroup->mbInvariant = (eState == ScFormulaCell::EqualInvariant);
-            pPrev->SetCellGroup(xGroup);
+            xGroup = pPrev->CreateCellGroup(pPrev->aPos.Row(), 2, eState == ScFormulaCell::EqualInvariant);
             pCur->SetCellGroup(xGroup);
         }
     }
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index 461193c..25af317 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -2677,13 +2677,8 @@ public:
             if (!xGroup)
             {
                 // create a new group ...
-                xGroup.reset(new ScFormulaCellGroup);
-                xGroup->mnStart = nRow - 1;
-                xGroup->mbInvariant = (eCompState == ScFormulaCell::EqualInvariant);
-                xGroup->mnLength = 2;
-
+                xGroup = pPrev->CreateCellGroup(nRow - 1, 2, eCompState == ScFormulaCell::EqualInvariant);
                 pCur->SetCellGroup(xGroup);
-                pPrev->SetCellGroup(xGroup);
             }
             else
             {
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index b9db55a..485d45c 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -3129,6 +3129,20 @@ ScFormulaCell*  ScFormulaCell::GetNextTrack() const                    { return
 void            ScFormulaCell::SetPreviousTrack( ScFormulaCell* pF )   { pPreviousTrack = pF; }
 void            ScFormulaCell::SetNextTrack( ScFormulaCell* pF )       { pNextTrack = pF; }
 
+ScFormulaCellGroupRef ScFormulaCell::CreateCellGroup( SCROW nStart, SCROW nLen, bool bInvariant )
+{
+    if (mxGroup)
+        // You can't create a new group if the cell is already a part of a group.
+        return ScFormulaCellGroupRef();
+
+    mxGroup.reset(new ScFormulaCellGroup);
+    mxGroup->mnStart = nStart;
+    mxGroup->mbInvariant = bInvariant;
+    mxGroup->mnLength = nLen;
+    mxGroup->mpCode = pCode; // Move this to the shared location.
+    return mxGroup;
+}
+
 ScFormulaCellGroupRef ScFormulaCell::GetCellGroup()
 {
     return mxGroup;
@@ -3136,7 +3150,23 @@ ScFormulaCellGroupRef ScFormulaCell::GetCellGroup()
 
 void ScFormulaCell::SetCellGroup( const ScFormulaCellGroupRef &xRef )
 {
+    if (!xRef)
+    {
+        // Make this cell a non-grouped cell.
+        if (mxGroup)
+            pCode = mxGroup->mpCode->Clone();
+
+        mxGroup = xRef;
+        return;
+    }
+
+    // Group object has shared token array.
+    if (!mxGroup)
+        // Currently not shared. Delete the existing token array first.
+        delete pCode;
+
     mxGroup = xRef;
+    pCode = mxGroup->mpCode;
 }
 
 ScFormulaCell::CompareState ScFormulaCell::CompareByTokenArray( ScFormulaCell& rOther ) const
@@ -3711,9 +3741,20 @@ SCROW ScFormulaCell::GetSharedTopRow() const
 {
     return mxGroup ? mxGroup->mnStart : -1;
 }
+
 SCROW ScFormulaCell::GetSharedLength() const
 {
     return mxGroup ? mxGroup->mnLength : 0;
 }
 
+ScTokenArray* ScFormulaCell::GetSharedCode()
+{
+    return mxGroup ? mxGroup->mpCode : NULL;
+}
+
+const ScTokenArray* ScFormulaCell::GetSharedCode() const
+{
+    return mxGroup ? mxGroup->mpCode : NULL;
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/tool/sharedformula.cxx b/sc/source/core/tool/sharedformula.cxx
index 2ea5cf8..3e77934 100644
--- a/sc/source/core/tool/sharedformula.cxx
+++ b/sc/source/core/tool/sharedformula.cxx
@@ -9,6 +9,7 @@
 
 #include "sharedformula.hxx"
 #include "calcmacros.hxx"
+#include "tokenarray.hxx"
 
 namespace sc {
 
@@ -41,6 +42,7 @@ void SharedFormulaUtil::splitFormulaCellGroup(const CellStoreType::position_type
     xGroup2->mbInvariant = xGroup->mbInvariant;
     xGroup2->mnStart = nRow;
     xGroup2->mnLength = xGroup->mnStart + xGroup->mnLength - nRow;
+    xGroup2->mpCode = xGroup->mpCode->Clone();
 
     xGroup->mnLength = nRow - xGroup->mnStart;
 
@@ -110,12 +112,7 @@ void SharedFormulaUtil::joinFormulaCells(const CellStoreType::position_type& rPo
         else
         {
             // neither cells are shared.
-            xGroup1.reset(new ScFormulaCellGroup);
-            xGroup1->mnStart = nRow;
-            xGroup1->mbInvariant = (eState == ScFormulaCell::EqualInvariant);
-            xGroup1->mnLength = 2;
-
-            rCell1.SetCellGroup(xGroup1);
+            xGroup1 = rCell1.CreateCellGroup(nRow, 2, eState == ScFormulaCell::EqualInvariant);
             rCell2.SetCellGroup(xGroup1);
         }
     }
@@ -226,6 +223,7 @@ void SharedFormulaUtil::unshareFormulaCell(const CellStoreType::position_type& a
             xGroup2->mnStart = rCell.aPos.Row() + 1;
             xGroup2->mnLength = nLength2;
             xGroup2->mbInvariant = xGroup->mbInvariant;
+            xGroup2->mpCode = xGroup->mpCode->Clone();
 #if DEBUG_COLUMN_STORAGE
             if (xGroup2->mnStart + xGroup2->mnLength > it->position + it->size)
             {


More information about the Libreoffice-commits mailing list