sc/inc/column.hxx | 7 +++++ sc/qa/unit/ucalc.cxx | 31 ++++++++++++++++++++++ sc/source/core/data/column.cxx | 10 +------ sc/source/core/data/column3.cxx | 56 +++++++++++++++++++++++++++++++++++++--- 4 files changed, 93 insertions(+), 11 deletions(-)
New commits: commit a6f996db16bc6a84d28dde7aef15a23536f8f0b2 Author: Kohei Yoshida <kohei.yosh...@gmail.com> Date: Wed Jun 26 21:50:38 2013 -0400 More on shared formula cell handling. Change-Id: Ifb0feff8c7016e3cadfa219ea6421852112ca189 diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx index 5354a07..c0dea00 100644 --- a/sc/inc/column.hxx +++ b/sc/inc/column.hxx @@ -469,6 +469,13 @@ public: void UnshareFormulaCell( const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell ) const; /** + * Split existing shared formula range at specified position. The cell at + * specified position becomes the top cell of the lower shared formula + * range after this call. + */ + void SplitFormulaCellGroup( const sc::CellStoreType::position_type& aPos ) const; + + /** * Regroup formula cells for the entire column. */ void RegroupFormulaCells(); diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx index 5286965..36c3628 100644 --- a/sc/qa/unit/ucalc.cxx +++ b/sc/qa/unit/ucalc.cxx @@ -6369,6 +6369,37 @@ void Test::testSharedFormulas() CPPUNIT_ASSERT_EQUAL(12, pFC->GetSharedTopRow()); CPPUNIT_ASSERT_EQUAL(4, pFC->GetSharedLength()); + // Extend B13:B16 to B13:B20. + aPos.SetRow(16); // B17 + m_pDoc->SetString(aPos, "=A17*2"); + aPos.IncRow(); + m_pDoc->SetString(aPos, "=A18*2"); + aPos.IncRow(); + m_pDoc->SetString(aPos, "=A19*2"); + aPos.IncRow(); + m_pDoc->SetString(aPos, "=A20*2"); + pFC = m_pDoc->GetFormulaCell(aPos); + CPPUNIT_ASSERT_MESSAGE("This cell is expected to be a shared formula cell.", pFC && pFC->IsShared()); + CPPUNIT_ASSERT_EQUAL(12, pFC->GetSharedTopRow()); + CPPUNIT_ASSERT_EQUAL(8, pFC->GetSharedLength()); + +#if 0 + // Insert empty rows at B16 to split B13:B20 into B13:B15 and B21:B25. + m_pDoc->InsertRow(1, 0, 1, 0, 15, 5); + + 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(12, pFC->GetSharedTopRow()); + CPPUNIT_ASSERT_EQUAL(3, pFC->GetSharedLength()); + + aPos.SetRow(23); // B24 + pFC = m_pDoc->GetFormulaCell(aPos); + CPPUNIT_ASSERT_MESSAGE("This cell is expected to be a shared formula cell.", pFC && pFC->IsShared()); + CPPUNIT_ASSERT_EQUAL(20, pFC->GetSharedTopRow()); + CPPUNIT_ASSERT_EQUAL(5, pFC->GetSharedLength()); +#endif + m_pDoc->DeleteTab(0); } diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx index 3918cd2..de330f5 100644 --- a/sc/source/core/data/column.cxx +++ b/sc/source/core/data/column.cxx @@ -1233,10 +1233,7 @@ void ScColumn::InsertRow( SCROW nStartRow, SCSIZE nSize ) maCellTextAttrs.insert_empty(nStartRow, nSize); maCellTextAttrs.resize(MAXROWCOUNT); - // Check if this insertion will split an existing formula block. sc::CellStoreType::position_type aPos = maCells.position(nStartRow); - bool bSplitFormulaBlock = aPos.second != 0; - sc::CellStoreType::iterator it = maCells.insert_empty(aPos.first, nStartRow, nSize); maCells.resize(MAXROWCOUNT); @@ -1254,8 +1251,8 @@ void ScColumn::InsertRow( SCROW nStartRow, SCSIZE nSize ) std::advance(itf, aPos.second); for (; itf != itfEnd; ++itf) { - ScFormulaCell* pCell = *itf; - pCell->aPos.IncRow(nSize); + ScFormulaCell& rCell = **itf; + rCell.aPos.IncRow(nSize); } } @@ -1273,9 +1270,6 @@ void ScColumn::InsertRow( SCROW nStartRow, SCSIZE nSize ) } } - if (bSplitFormulaBlock) - RegroupFormulaCells(nStartRow, nStartRow+nSize-1); - CellStorageModified(); // We *probably* don't need to broadcast here since the parent call seems diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx index ff152ff..16d4ada 100644 --- a/sc/source/core/data/column3.cxx +++ b/sc/source/core/data/column3.cxx @@ -429,7 +429,7 @@ void ScColumn::UnshareFormulaCell( #if DEBUG_COLUMN_STORAGE if (aPos.second+1 >= aPos.first->size) { - cerr << "ScColumn::GetPositionToInsert: There is no next formula cell but there should be!" << endl; + cerr << "ScColumn::UnshareFormulaCell: There is no next formula cell but there should be!" << endl; cerr.flush(); abort(); } @@ -454,7 +454,7 @@ void ScColumn::UnshareFormulaCell( #if DEBUG_COLUMN_STORAGE if (aPos.second == 0) { - cerr << "ScColumn::GetPositionToInsert: There is no previous formula cell but there should be!" << endl; + cerr << "ScColumn::UnshareFormulaCell: There is no previous formula cell but there should be!" << endl; cerr.flush(); abort(); } @@ -482,7 +482,7 @@ void ScColumn::UnshareFormulaCell( #if DEBUG_COLUMN_STORAGE if (xGroup2->mnStart + xGroup2->mnLength > it->position + it->size) { - cerr << "ScColumn::GetPositionToInsert: Shared formula region goes beyond the formula block. Not good." << endl; + cerr << "ScColumn::UnshareFormulaCell: Shared formula region goes beyond the formula block. Not good." << endl; cerr.flush(); abort(); } @@ -501,6 +501,56 @@ void ScColumn::UnshareFormulaCell( rCell.SetCellGroup(xNone); } +void ScColumn::SplitFormulaCellGroup( const sc::CellStoreType::position_type& aPos ) const +{ + SCROW nRow = aPos.first->position + aPos.second; + + if (aPos.first->type != sc::element_type_formula) + // Not a formula cell block. + return; + + if (aPos.second == 0) + // Split position coincides with the block border. Nothing to do. + return; + + sc::formula_block::iterator it = sc::formula_block::begin(*aPos.first->data); + std::advance(it, aPos.second); + ScFormulaCell& rTop = **it; + if (!rTop.IsShared()) + // Not a shared formula. + return; + + if (nRow == rTop.GetSharedTopRow()) + // Already the top cell of a shared group. + return; + + ScFormulaCellGroupRef xGroup = rTop.GetCellGroup(); + + ScFormulaCellGroupRef xGroup2(new ScFormulaCellGroup); + xGroup2->mbInvariant = xGroup->mbInvariant; + xGroup2->mnStart = nRow; + xGroup2->mnLength = xGroup->mnStart + xGroup->mnLength - nRow; + + xGroup->mnLength = nRow - xGroup->mnStart; + + // Apply the lower group object to the lower cells. +#if DEBUG_COLUMN_STORAGE + if (xGroup2->mnStart + xGroup2->mnLength > aPos.first->position + aPos.first->size) + { + cerr << "ScColumn::SplitFormulaCellGroup: Shared formula region goes beyond the formula block. Not good." << endl; + cerr.flush(); + abort(); + } +#endif + sc::formula_block::iterator itEnd = it; + std::advance(itEnd, xGroup2->mnLength); + for (; it != itEnd; ++it) + { + ScFormulaCell& rCell = **it; + rCell.SetCellGroup(xGroup2); + } +} + sc::CellStoreType::iterator ScColumn::GetPositionToInsert( const sc::CellStoreType::iterator& it, SCROW nRow ) { // See if we are overwriting an existing formula cell. _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits