diff options
author | Kohei Yoshida <kohei.yoshida@gmail.com> | 2013-08-06 19:03:47 -0400 |
---|---|---|
committer | Kohei Yoshida <kohei.yoshida@gmail.com> | 2013-08-12 19:46:25 -0400 |
commit | 027f8cd9442aec9c432bfcfc69f7d6e81b760eb5 (patch) | |
tree | f6e5ed97b1f9e74f33219d5310b844e768fff55b /sc | |
parent | 417d1c2b13cbd70300d2921b5667dfadc7e25895 (diff) |
Handle shared token array correctly when adjusting formula grouping.
Change-Id: Ib4b141f415b36565106e946ccbc47f2b9f80d89c
Diffstat (limited to 'sc')
-rw-r--r-- | sc/inc/formulacell.hxx | 6 | ||||
-rw-r--r-- | sc/inc/sharedformula.hxx | 6 | ||||
-rw-r--r-- | sc/qa/unit/ucalc_sharedformula.cxx | 23 | ||||
-rw-r--r-- | sc/source/core/data/column.cxx | 6 | ||||
-rw-r--r-- | sc/source/core/data/column3.cxx | 7 | ||||
-rw-r--r-- | sc/source/core/data/formulacell.cxx | 41 | ||||
-rw-r--r-- | sc/source/core/tool/sharedformula.cxx | 10 |
7 files changed, 77 insertions, 22 deletions
diff --git a/sc/inc/formulacell.hxx b/sc/inc/formulacell.hxx index f857aff36410..3d702009820b 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 866c22f6486d..232c4bc59be1 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 793448338a8e..1eba457902f0 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 66343a756d13..0171fab7a1c7 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 461193c77267..25af317f5d7b 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 b9db55ab74ee..485d45ccb781 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 2ea5cf881907..3e77934f894d 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) { |