sc/inc/column.hxx | 16 +- sc/source/core/data/column.cxx | 99 +++++++++------- sc/source/core/data/column3.cxx | 245 +++++++++++++++++++++------------------- 3 files changed, 203 insertions(+), 157 deletions(-)
New commits: commit 1a61dd41f2ad03ea49658ddc427a331368d9aad2 Author: Kohei Yoshida <[email protected]> Date: Wed Jun 26 19:16:45 2013 -0400 Handle formula cells in SwapCell(). Change-Id: I9ddc69793e70bd399b93ce472a38060b1a946ff9 diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx index 876dc3b..3918cd2 100644 --- a/sc/source/core/data/column.cxx +++ b/sc/source/core/data/column.cxx @@ -1129,26 +1129,43 @@ void updateRefInFormulaCell( ScFormulaCell& rCell, SCCOL nCol, SCTAB nTab, SCCOL void ScColumn::SwapCell( SCROW nRow, ScColumn& rCol) { - ScFormulaCell* pCell1 = maCells.get<ScFormulaCell*>(nRow); - ScFormulaCell* pCell2 = rCol.maCells.get<ScFormulaCell*>(nRow); - if (pCell1) - updateRefInFormulaCell(*pCell1, rCol.nCol, nTab, rCol.nCol - nCol); + sc::CellStoreType::position_type aPos1 = maCells.position(nRow); + sc::CellStoreType::position_type aPos2 = rCol.maCells.position(nRow); - if (pCell2) - updateRefInFormulaCell(*pCell2, nCol, nTab, nCol - rCol.nCol); + if (aPos1.first->type == sc::element_type_formula) + { + ScFormulaCell& rCell = *sc::formula_block::at(*aPos1.first->data, aPos1.second); + updateRefInFormulaCell(rCell, rCol.nCol, nTab, rCol.nCol - nCol); + UnshareFormulaCell(aPos1, rCell); + } + + if (aPos2.first->type == sc::element_type_formula) + { + ScFormulaCell& rCell = *sc::formula_block::at(*aPos2.first->data, aPos2.second); + updateRefInFormulaCell(rCell, nCol, nTab, nCol - rCol.nCol); + UnshareFormulaCell(aPos2, rCell); + } maCells.swap(nRow, nRow, rCol.maCells, nRow); maCellTextAttrs.swap(nRow, nRow, rCol.maCellTextAttrs, nRow); - CellStorageModified(); - rCol.CellStorageModified(); + aPos1 = maCells.position(nRow); + aPos2 = rCol.maCells.position(nRow); - if (pCell1 || pCell2) + if (aPos1.first->type == sc::element_type_formula) { - // At least one of the two cells is a formula cell. Regroup them. - RegroupFormulaCells(nRow); - rCol.RegroupFormulaCells(nRow); + ScFormulaCell& rCell = *sc::formula_block::at(*aPos1.first->data, aPos1.second); + JoinNewFormulaCell(aPos1, rCell); } + + if (aPos2.first->type == sc::element_type_formula) + { + ScFormulaCell& rCell = *sc::formula_block::at(*aPos2.first->data, aPos2.second); + rCol.JoinNewFormulaCell(aPos2, rCell); + } + + CellStorageModified(); + rCol.CellStorageModified(); } commit 566f2948d9c692d876470068b49dc56586e5da8e Author: Kohei Yoshida <[email protected]> Date: Wed Jun 26 18:59:57 2013 -0400 Proper handling of formula cells in SwapRow(). Change-Id: Id295160b69cc5cb40cd9e0403928dac8b0e58807 diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx index 2e1f0f1..5354a07 100644 --- a/sc/inc/column.hxx +++ b/sc/inc/column.hxx @@ -147,8 +147,7 @@ public: const sc::CellTextAttrStoreType& GetCellAttrStore() const { return maCellTextAttrs; } ScRefCellValue GetCellValue( SCROW nRow ) const; - ScRefCellValue GetCellValue( sc::CellStoreType::const_iterator& itPos, SCROW nRow ) const; - ScRefCellValue GetCellValue( sc::CellStoreType::const_iterator& itPos, size_t nOffset ) const; + ScRefCellValue GetCellValue( const sc::CellStoreType::const_iterator& itPos, size_t nOffset ) const; void Delete( SCROW nRow ); void FreeAll(); @@ -461,6 +460,12 @@ public: void JoinNewFormulaCell( const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell ) const; + /** + * Detouch a formula cell that's about to be deleted, or removed from + * document storage (if that ever happens). + */ + void DetouchFormulaCell( const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell ) const; + void UnshareFormulaCell( const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell ) const; /** @@ -490,6 +495,7 @@ private: sc::CellStoreType::iterator GetPositionToInsert( SCROW nRow ); sc::CellStoreType::iterator GetPositionToInsert( const sc::CellStoreType::iterator& it, SCROW nRow ); void ActivateNewFormulaCell( const sc::CellStoreType::iterator& itPos, SCROW nRow, ScFormulaCell& rCell ); + void ActivateNewFormulaCell( const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell ); void BroadcastNewCell( SCROW nRow ); bool UpdateScriptType( sc::CellTextAttr& rAttr, SCROW nRow ); diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx index f3fb8cf..876dc3b 100644 --- a/sc/source/core/data/column.cxx +++ b/sc/source/core/data/column.cxx @@ -763,17 +763,7 @@ ScRefCellValue ScColumn::GetCellValue( SCROW nRow ) const return GetCellValue(aPos.first, aPos.second); } -ScRefCellValue ScColumn::GetCellValue( sc::CellStoreType::const_iterator& itPos, SCROW nRow ) const -{ - std::pair<sc::CellStoreType::const_iterator,size_t> aPos = maCells.position(itPos, nRow); - itPos = aPos.first; - if (aPos.first == maCells.end()) - return ScRefCellValue(); - - return GetCellValue(itPos, aPos.second); -} - -ScRefCellValue ScColumn::GetCellValue( sc::CellStoreType::const_iterator& itPos, size_t nOffset ) const +ScRefCellValue ScColumn::GetCellValue( const sc::CellStoreType::const_iterator& itPos, size_t nOffset ) const { ScRefCellValue aVal; // Defaults to empty cell. switch (itPos->type) @@ -820,8 +810,6 @@ ScFormulaCell* cloneFormulaCell(ScDocument* pDoc, const ScAddress& rNewPos, ScFo void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2) { - typedef std::pair<sc::CellStoreType::iterator,size_t> CellPosType; - if (nRow1 == nRow2) // Nothing to swap. return; @@ -832,11 +820,11 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2) // Broadcasters (if exist) should NOT be swapped. - CellPosType aPos1 = maCells.position(nRow1); + sc::CellStoreType::position_type aPos1 = maCells.position(nRow1); if (aPos1.first == maCells.end()) return; - CellPosType aPos2 = maCells.position(aPos1.first, nRow2); + sc::CellStoreType::position_type aPos2 = maCells.position(aPos1.first, nRow2); if (aPos2.first == maCells.end()) return; @@ -881,13 +869,15 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2) // TODO: Find out a way to adjust references without cloning new instances. boost::scoped_ptr<ScFormulaCell> pOld1(*itf1); boost::scoped_ptr<ScFormulaCell> pOld2(*itf2); + DetouchFormulaCell(aPos1, **itf1); + DetouchFormulaCell(aPos2, **itf2); ScFormulaCell* pNew1 = cloneFormulaCell(pDocument, ScAddress(nCol, nRow1, nTab), *pOld2); ScFormulaCell* pNew2 = cloneFormulaCell(pDocument, ScAddress(nCol, nRow2, nTab), *pOld1); *itf1 = pNew1; *itf2 = pNew2; - RegroupFormulaCells(nRow1); - RegroupFormulaCells(nRow2); + ActivateNewFormulaCell(aPos1, *pNew1); + ActivateNewFormulaCell(aPos2, *pNew2); } break; default: @@ -902,10 +892,10 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2) // The two cells are of different types. - sc::CellStoreType::const_iterator cit = it1; - ScRefCellValue aCell1 = GetCellValue(cit, nRow1); - cit = it2; - ScRefCellValue aCell2 = GetCellValue(cit, nRow2); + ScRefCellValue aCell1 = GetCellValue(aPos1.first, aPos1.second); + ScRefCellValue aCell2 = GetCellValue(aPos2.first, aPos2.second); + + // Make sure to put cells in row 1 first then row 2! if (aCell1.meType == CELLTYPE_NONE) { @@ -929,11 +919,12 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2) break; case CELLTYPE_FORMULA: { + // cell 1 is empty and cell 2 is a formula cell. ScFormulaCell* pNew = cloneFormulaCell(pDocument, ScAddress(nCol, nRow1, nTab), *aCell2.mpFormula); + DetouchFormulaCell(aPos2, *aCell2.mpFormula); it1 = maCells.set(it1, nRow1, pNew); maCells.set_empty(it1, nRow2, nRow2); // original formula cell gets deleted. - - RegroupFormulaCells(nRow2); + ActivateNewFormulaCell(it1, nRow1, *pNew); } break; default: @@ -972,12 +963,12 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2) break; case CELLTYPE_FORMULA: { + // cell 1 is a formula cell and cell 2 is empty. ScFormulaCell* pNew = cloneFormulaCell(pDocument, ScAddress(nCol, nRow2, nTab), *aCell1.mpFormula); + DetouchFormulaCell(aPos1, *aCell1.mpFormula); it1 = maCells.set_empty(it1, nRow1, nRow1); // original formula cell is gone. - maCells.set(it1, nRow2, pNew); - - RegroupFormulaCells(nRow1); - RegroupFormulaCells(nRow2); + it1 = maCells.set(it1, nRow2, pNew); + ActivateNewFormulaCell(it1, nRow2, *pNew); } break; default: @@ -1009,8 +1000,10 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2) break; case CELLTYPE_FORMULA: { + DetouchFormulaCell(aPos2, *aCell2.mpFormula); ScFormulaCell* pNew = cloneFormulaCell(pDocument, ScAddress(nCol, nRow1, nTab), *aCell2.mpFormula); it1 = maCells.set(it1, nRow1, pNew); + ActivateNewFormulaCell(it1, nRow1, *pNew); // The old formula cell will get overwritten below. } break; @@ -1040,8 +1033,10 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2) case CELLTYPE_FORMULA: { // cell 1 - string, cell 2 - formula + DetouchFormulaCell(aPos2, *aCell2.mpFormula); ScFormulaCell* pNew = cloneFormulaCell(pDocument, ScAddress(nCol, nRow1, nTab), *aCell2.mpFormula); it1 = maCells.set(it1, nRow1, pNew); + ActivateNewFormulaCell(it1, nRow1, *pNew); // Old formula cell will get overwritten below. } break; @@ -1067,8 +1062,10 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2) break; case CELLTYPE_FORMULA: { + DetouchFormulaCell(aPos2, *aCell2.mpFormula); ScFormulaCell* pNew = cloneFormulaCell(pDocument, ScAddress(nCol, nRow1, nTab), *aCell2.mpFormula); it1 = maCells.set(it1, nRow1, pNew); + ActivateNewFormulaCell(it1, nRow1, *pNew); // Old formula cell will get overwritten below. } break; @@ -1081,6 +1078,8 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2) break; case CELLTYPE_FORMULA: { + // cell 1 is a formula cell and cell 2 is not. + DetouchFormulaCell(aPos1, *aCell1.mpFormula); ScFormulaCell* pNew = cloneFormulaCell(pDocument, ScAddress(nCol, nRow2, nTab), *aCell1.mpFormula); switch (aCell2.meType) { @@ -1101,7 +1100,8 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2) ; } - maCells.set(it1, nRow2, pNew); + it1 = maCells.set(it1, nRow2, pNew); + ActivateNewFormulaCell(it1, nRow2, *pNew); } break; default: @@ -1109,8 +1109,6 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2) } SwapCellTextAttrs(nRow1, nRow2); - RegroupFormulaCells(nRow1); - RegroupFormulaCells(nRow2); CellStorageModified(); BroadcastCells(aRows); } diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx index ee0ec33..ff152ff 100644 --- a/sc/source/core/data/column3.cxx +++ b/sc/source/core/data/column3.cxx @@ -398,6 +398,17 @@ void ScColumn::JoinNewFormulaCell( } } +void ScColumn::DetouchFormulaCell( + const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell ) const +{ + if (!pDocument->IsClipOrUndo()) + // Have the dying formula cell stop listening. + rCell.EndListeningTo(pDocument); + + if (rCell.IsShared()) + UnshareFormulaCell(aPos, rCell); +} + void ScColumn::UnshareFormulaCell( const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell ) const { @@ -498,12 +509,7 @@ sc::CellStoreType::iterator ScColumn::GetPositionToInsert( const sc::CellStoreTy if (itRet->type == sc::element_type_formula) { ScFormulaCell& rCell = *sc::formula_block::at(*itRet->data, aPos.second); - if (!pDocument->IsClipOrUndo()) - // Have the dying formula cell stop listening. - rCell.EndListeningTo(pDocument); - - if (rCell.IsShared()) - UnshareFormulaCell(aPos, rCell); + DetouchFormulaCell(aPos, rCell); } return itRet; @@ -512,9 +518,13 @@ sc::CellStoreType::iterator ScColumn::GetPositionToInsert( const sc::CellStoreTy void ScColumn::ActivateNewFormulaCell( const sc::CellStoreType::iterator& itPos, SCROW nRow, ScFormulaCell& rCell ) { - // See if this new formula cell can join an existing shared formula group. - sc::CellStoreType::position_type aPos = maCells.position(itPos, nRow); + ActivateNewFormulaCell(maCells.position(itPos, nRow), rCell); +} +void ScColumn::ActivateNewFormulaCell( + const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell ) +{ + // See if this new formula cell can join an existing shared formula group. JoinNewFormulaCell(aPos, rCell); // When we insert from the Clipboard we still have wrong (old) References! commit f4e30d145fd4cc3e7ad3f067d8cef4204200e88c Author: Kohei Yoshida <[email protected]> Date: Wed Jun 26 18:06:04 2013 -0400 Make this a member method too. Change-Id: Ib1b16ce5a7a36560b04d4d57b585fdcf2a2b294d diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx index a80cd66..2e1f0f1 100644 --- a/sc/inc/column.hxx +++ b/sc/inc/column.hxx @@ -459,6 +459,8 @@ public: void InterpretDirtyCells( SCROW nRow1, SCROW nRow2 ); + void JoinNewFormulaCell( const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell ) const; + void UnshareFormulaCell( const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell ) const; /** diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx index ddf59af..ee0ec33 100644 --- a/sc/source/core/data/column3.cxx +++ b/sc/source/core/data/column3.cxx @@ -327,6 +327,77 @@ sc::CellStoreType::iterator ScColumn::GetPositionToInsert( SCROW nRow ) return GetPositionToInsert(maCells.begin(), nRow); } +namespace { + +void joinFormulaCells(SCROW nRow, ScFormulaCell& rCell1, ScFormulaCell& rCell2) +{ + ScFormulaCell::CompareState eState = rCell1.CompareByTokenArray(rCell2); + if (eState == ScFormulaCell::NotEqual) + return; + + // Formula tokens equal those of the previous formula cell. + ScFormulaCellGroupRef xGroup1 = rCell1.GetCellGroup(); + ScFormulaCellGroupRef xGroup2 = rCell2.GetCellGroup(); + if (xGroup1) + { + if (xGroup2) + { + // Both cell1 and cell2 are shared. Merge them together. + xGroup1->mnLength += xGroup2->mnLength; + rCell2.SetCellGroup(xGroup1); + } + else + { + // cell1 is shared but cell2 is not. + rCell2.SetCellGroup(xGroup1); + ++xGroup1->mnLength; + } + } + else + { + if (xGroup2) + { + // cell1 is not shared, but cell2 is already shared. + rCell1.SetCellGroup(xGroup2); + xGroup2->mnStart = nRow; + ++xGroup2->mnLength; + } + else + { + // neither cells are shared. + xGroup1.reset(new ScFormulaCellGroup); + xGroup1->mnStart = nRow; + xGroup1->mbInvariant = (eState == ScFormulaCell::EqualInvariant); + xGroup1->mnLength = 2; + + rCell1.SetCellGroup(xGroup1); + rCell2.SetCellGroup(xGroup1); + } + } +} + +} + +void ScColumn::JoinNewFormulaCell( + const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell ) const +{ + SCROW nRow = aPos.first->position + aPos.second; + + // Check the previous row position for possible grouping. + if (aPos.first->type == sc::element_type_formula && aPos.second > 0) + { + ScFormulaCell& rPrev = *sc::formula_block::at(*aPos.first->data, aPos.second-1); + joinFormulaCells(nRow-1, rPrev, rCell); + } + + // Check the next row position for possible grouping. + if (aPos.first->type == sc::element_type_formula && aPos.second+1 < aPos.first->size) + { + ScFormulaCell& rNext = *sc::formula_block::at(*aPos.first->data, aPos.second+1); + joinFormulaCells(nRow, rCell, rNext); + } +} + void ScColumn::UnshareFormulaCell( const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell ) const { @@ -438,76 +509,13 @@ sc::CellStoreType::iterator ScColumn::GetPositionToInsert( const sc::CellStoreTy return itRet; } -namespace { - -void joinFormulaCells(SCROW nRow, ScFormulaCell& rCell1, ScFormulaCell& rCell2) -{ - ScFormulaCell::CompareState eState = rCell1.CompareByTokenArray(rCell2); - if (eState == ScFormulaCell::NotEqual) - return; - - // Formula tokens equal those of the previous formula cell. - ScFormulaCellGroupRef xGroup1 = rCell1.GetCellGroup(); - ScFormulaCellGroupRef xGroup2 = rCell2.GetCellGroup(); - if (xGroup1) - { - if (xGroup2) - { - // Both cell1 and cell2 are shared. Merge them together. - xGroup1->mnLength += xGroup2->mnLength; - rCell2.SetCellGroup(xGroup1); - } - else - { - // cell1 is shared but cell2 is not. - rCell2.SetCellGroup(xGroup1); - ++xGroup1->mnLength; - } - } - else - { - if (xGroup2) - { - // cell1 is not shared, but cell2 is already shared. - rCell1.SetCellGroup(xGroup2); - xGroup2->mnStart = nRow; - ++xGroup2->mnLength; - } - else - { - // neither cells are shared. - xGroup1.reset(new ScFormulaCellGroup); - xGroup1->mnStart = nRow; - xGroup1->mbInvariant = (eState == ScFormulaCell::EqualInvariant); - xGroup1->mnLength = 2; - - rCell1.SetCellGroup(xGroup1); - rCell2.SetCellGroup(xGroup1); - } - } -} - -} - void ScColumn::ActivateNewFormulaCell( const sc::CellStoreType::iterator& itPos, SCROW nRow, ScFormulaCell& rCell ) { // See if this new formula cell can join an existing shared formula group. sc::CellStoreType::position_type aPos = maCells.position(itPos, nRow); - // Check the previous row position for possible grouping. - if (aPos.first->type == sc::element_type_formula && aPos.second > 0) - { - ScFormulaCell& rPrev = *sc::formula_block::at(*aPos.first->data, aPos.second-1); - joinFormulaCells(nRow-1, rPrev, rCell); - } - - // Check the next row position for possible grouping. - if (aPos.first->type == sc::element_type_formula && aPos.second+1 < aPos.first->size) - { - ScFormulaCell& rNext = *sc::formula_block::at(*aPos.first->data, aPos.second+1); - joinFormulaCells(nRow, rCell, rNext); - } + JoinNewFormulaCell(aPos, rCell); // When we insert from the Clipboard we still have wrong (old) References! // First they are rewired in CopyBlockFromClip via UpdateReference and the commit 310f44a5e833fc29e34907c5e4d41ddc9ab4e995 Author: Kohei Yoshida <[email protected]> Date: Wed Jun 26 17:57:34 2013 -0400 Make this a member method of ScColumn. Change-Id: I5d0a573d277338ddef60fdd58bfb1f5ba7fc695e diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx index 781e1a7..a80cd66 100644 --- a/sc/inc/column.hxx +++ b/sc/inc/column.hxx @@ -459,6 +459,8 @@ public: void InterpretDirtyCells( SCROW nRow1, SCROW nRow2 ); + void UnshareFormulaCell( const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell ) const; + /** * Regroup formula cells for the entire column. */ diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx index c6dae67..ddf59af 100644 --- a/sc/source/core/data/column3.cxx +++ b/sc/source/core/data/column3.cxx @@ -327,13 +327,13 @@ sc::CellStoreType::iterator ScColumn::GetPositionToInsert( SCROW nRow ) return GetPositionToInsert(maCells.begin(), nRow); } -namespace { - -/** - * Re-group a shared formula cell that's being overwritten. - */ -void adjustSharedFormulaCell(const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell) +void ScColumn::UnshareFormulaCell( + const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell ) const { + if (!rCell.IsShared()) + return; + + ScFormulaCellGroupRef xNone; sc::CellStoreType::iterator it = aPos.first; // This formula cell is shared. Adjust the shared group. @@ -352,7 +352,6 @@ void adjustSharedFormulaCell(const sc::CellStoreType::position_type& aPos, ScFor abort(); } #endif - ScFormulaCellGroupRef xNone; ScFormulaCell& rNext = *sc::formula_block::at(*it->data, aPos.second+1); rNext.SetCellGroup(xNone); } @@ -378,7 +377,6 @@ void adjustSharedFormulaCell(const sc::CellStoreType::position_type& aPos, ScFor abort(); } #endif - ScFormulaCellGroupRef xNone; ScFormulaCell& rPrev = *sc::formula_block::at(*it->data, aPos.second-1); rPrev.SetCellGroup(xNone); } @@ -417,8 +415,8 @@ void adjustSharedFormulaCell(const sc::CellStoreType::position_type& aPos, ScFor rCell2.SetCellGroup(xGroup2); } } -} + rCell.SetCellGroup(xNone); } sc::CellStoreType::iterator ScColumn::GetPositionToInsert( const sc::CellStoreType::iterator& it, SCROW nRow ) @@ -434,7 +432,7 @@ sc::CellStoreType::iterator ScColumn::GetPositionToInsert( const sc::CellStoreTy rCell.EndListeningTo(pDocument); if (rCell.IsShared()) - adjustSharedFormulaCell(aPos, rCell); + UnshareFormulaCell(aPos, rCell); } return itRet; commit 12fc0ca3f5e52f03882f447d23afd9029c416a1a Author: Kohei Yoshida <[email protected]> Date: Wed Jun 26 17:43:18 2013 -0400 We don't need this formula group vector. Change-Id: I96f3b19a5bb0d761b7abd943df6a2e48cfcbf9bd diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx index 6b46cc8..781e1a7 100644 --- a/sc/inc/column.hxx +++ b/sc/inc/column.hxx @@ -110,8 +110,6 @@ class ScColumn SCCOL nCol; SCTAB nTab; - std::vector<ScFormulaCellGroupRef> maFnGroups; - ScAttrArray* pAttrArray; ScDocument* pDocument; bool mbDirtyGroups; /// formula groups are dirty. diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx index 574dcd8..c6dae67 100644 --- a/sc/source/core/data/column3.cxx +++ b/sc/source/core/data/column3.cxx @@ -2713,11 +2713,9 @@ public: class GroupFormulaCells { - std::vector<ScFormulaCellGroupRef>& mrFnGroups; ScFormulaCellGroupRef mxNone; public: - GroupFormulaCells(std::vector<ScFormulaCellGroupRef>& rFnGroups) : mrFnGroups(rFnGroups) {} void operator() (sc::CellStoreType::value_type& node) { @@ -2755,8 +2753,6 @@ public: xGroup->mbInvariant = (eCompState == ScFormulaCell::EqualInvariant); xGroup->mnLength = 2; - mrFnGroups.push_back(xGroup); - pCur->SetCellGroup(xGroup); pPrev->SetCellGroup(xGroup); } @@ -2783,10 +2779,9 @@ void ScColumn::RebuildFormulaGroups() ScFormulaCellGroupRef xNone; CellGroupSetter aFunc(xNone); sc::ProcessFormula(maCells, aFunc); - maFnGroups.clear(); // re-build formula groups. - std::for_each(maCells.begin(), maCells.end(), GroupFormulaCells(maFnGroups)); + std::for_each(maCells.begin(), maCells.end(), GroupFormulaCells()); mbDirtyGroups = false; } commit c7641bac30f95ac85bd5d462f6083378ee30db4b Author: Kohei Yoshida <[email protected]> Date: Wed Jun 26 17:37:23 2013 -0400 Extract this code block into an own function. Change-Id: I6abe520ad6392e4f9163434b73f3b3ab88a71297 diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx index 7fd16f0..574dcd8 100644 --- a/sc/source/core/data/column3.cxx +++ b/sc/source/core/data/column3.cxx @@ -327,103 +327,115 @@ sc::CellStoreType::iterator ScColumn::GetPositionToInsert( SCROW nRow ) return GetPositionToInsert(maCells.begin(), nRow); } -sc::CellStoreType::iterator ScColumn::GetPositionToInsert( const sc::CellStoreType::iterator& it, SCROW nRow ) +namespace { + +/** + * Re-group a shared formula cell that's being overwritten. + */ +void adjustSharedFormulaCell(const sc::CellStoreType::position_type& aPos, ScFormulaCell& rCell) { - // See if we are overwriting an existing formula cell. - sc::CellStoreType::position_type aRet = maCells.position(it, nRow); - sc::CellStoreType::iterator itRet = aRet.first; - if (itRet->type == sc::element_type_formula) - { - ScFormulaCell& rCell = *sc::formula_block::at(*itRet->data, aRet.second); - if (!pDocument->IsClipOrUndo()) - // Have the dying formula cell stop listening. - rCell.EndListeningTo(pDocument); + sc::CellStoreType::iterator it = aPos.first; - if (rCell.IsShared()) + // This formula cell is shared. Adjust the shared group. + if (rCell.aPos.Row() == rCell.GetSharedTopRow()) + { + // Top of the shared range. + ScFormulaCellGroupRef xGroup = rCell.GetCellGroup(); + if (xGroup->mnLength == 2) { - // This formula cell is shared. Adjust the shared group. - if (rCell.aPos.Row() == rCell.GetSharedTopRow()) - { - // Top of the shared range. - ScFormulaCellGroupRef xGroup = rCell.GetCellGroup(); - if (xGroup->mnLength == 2) - { - // Group consists only only two cells. Mark the second one non-shared. + // Group consists only only two cells. Mark the second one non-shared. #if DEBUG_COLUMN_STORAGE - if (aRet.second+1 >= aRet.first->size) - { - cerr << "ScColumn::GetPositionToInsert: There is no next formula cell but there should be!" << endl; - cerr.flush(); - abort(); - } -#endif - ScFormulaCellGroupRef xNone; - ScFormulaCell& rNext = *sc::formula_block::at(*itRet->data, aRet.second+1); - rNext.SetCellGroup(xNone); - } - else - { - // Move the top cell to the next formula cell down. - --xGroup->mnLength; - ++xGroup->mnStart; - } - } - else if (rCell.aPos.Row() == rCell.GetSharedTopRow() + rCell.GetSharedLength() - 1) + if (aPos.second+1 >= aPos.first->size) { - // Bottom of the shared range. - ScFormulaCellGroupRef xGroup = rCell.GetCellGroup(); - if (xGroup->mnLength == 2) - { - // Mark the top cell non-shared. -#if DEBUG_COLUMN_STORAGE - if (aRet.second == 0) - { - cerr << "ScColumn::GetPositionToInsert: There is no previous formula cell but there should be!" << endl; - cerr.flush(); - abort(); - } -#endif - ScFormulaCellGroupRef xNone; - ScFormulaCell& rPrev = *sc::formula_block::at(*itRet->data, aRet.second-1); - rPrev.SetCellGroup(xNone); - } - else - { - // Just shortern the shared range length by one. - --xGroup->mnLength; - } + cerr << "ScColumn::GetPositionToInsert: There is no next formula cell but there should be!" << endl; + cerr.flush(); + abort(); } - else +#endif + ScFormulaCellGroupRef xNone; + ScFormulaCell& rNext = *sc::formula_block::at(*it->data, aPos.second+1); + rNext.SetCellGroup(xNone); + } + else + { + // Move the top cell to the next formula cell down. + --xGroup->mnLength; + ++xGroup->mnStart; + } + } + else if (rCell.aPos.Row() == rCell.GetSharedTopRow() + rCell.GetSharedLength() - 1) + { + // Bottom of the shared range. + ScFormulaCellGroupRef xGroup = rCell.GetCellGroup(); + if (xGroup->mnLength == 2) + { + // Mark the top cell non-shared. +#if DEBUG_COLUMN_STORAGE + if (aPos.second == 0) { - // In the middle of the shared range. Split it into two groups. - ScFormulaCellGroupRef xGroup = rCell.GetCellGroup(); - SCROW nEndRow = xGroup->mnStart + xGroup->mnLength - 1; - xGroup->mnLength = rCell.aPos.Row() - xGroup->mnStart; // Shorten the top group. - - ScFormulaCellGroupRef xGroup2(new ScFormulaCellGroup); - xGroup2->mnStart = rCell.aPos.Row() + 1; - xGroup2->mnLength = nEndRow - rCell.aPos.Row(); - xGroup2->mbInvariant = xGroup->mbInvariant; + cerr << "ScColumn::GetPositionToInsert: There is no previous formula cell but there should be!" << endl; + cerr.flush(); + abort(); + } +#endif + ScFormulaCellGroupRef xNone; + ScFormulaCell& rPrev = *sc::formula_block::at(*it->data, aPos.second-1); + rPrev.SetCellGroup(xNone); + } + else + { + // Just shortern the shared range length by one. + --xGroup->mnLength; + } + } + else + { + // In the middle of the shared range. Split it into two groups. + ScFormulaCellGroupRef xGroup = rCell.GetCellGroup(); + SCROW nEndRow = xGroup->mnStart + xGroup->mnLength - 1; + xGroup->mnLength = rCell.aPos.Row() - xGroup->mnStart; // Shorten the top group. + + ScFormulaCellGroupRef xGroup2(new ScFormulaCellGroup); + xGroup2->mnStart = rCell.aPos.Row() + 1; + xGroup2->mnLength = nEndRow - rCell.aPos.Row(); + xGroup2->mbInvariant = xGroup->mbInvariant; #if DEBUG_COLUMN_STORAGE - if (xGroup2->mnStart + xGroup2->mnLength > itRet->position + itRet->size) - { - cerr << "ScColumn::GetPositionToInsert: Shared formula region goes beyond the formula block. Not good." << endl; - cerr.flush(); - abort(); - } + if (xGroup2->mnStart + xGroup2->mnLength > it->position + it->size) + { + cerr << "ScColumn::GetPositionToInsert: Shared formula region goes beyond the formula block. Not good." << endl; + cerr.flush(); + abort(); + } #endif - sc::formula_block::iterator itCell = sc::formula_block::begin(*itRet->data); - std::advance(itCell, aRet.second+1); - sc::formula_block::iterator itCellEnd = itCell; - std::advance(itCellEnd, xGroup2->mnLength); - for (; itCell != itCellEnd; ++itCell) - { - ScFormulaCell& rCell2 = **itCell; - rCell2.SetCellGroup(xGroup2); - } - } + sc::formula_block::iterator itCell = sc::formula_block::begin(*it->data); + std::advance(itCell, aPos.second+1); + sc::formula_block::iterator itCellEnd = itCell; + std::advance(itCellEnd, xGroup2->mnLength); + for (; itCell != itCellEnd; ++itCell) + { + ScFormulaCell& rCell2 = **itCell; + rCell2.SetCellGroup(xGroup2); } } +} + +} + +sc::CellStoreType::iterator ScColumn::GetPositionToInsert( const sc::CellStoreType::iterator& it, SCROW nRow ) +{ + // See if we are overwriting an existing formula cell. + sc::CellStoreType::position_type aPos = maCells.position(it, nRow); + sc::CellStoreType::iterator itRet = aPos.first; + if (itRet->type == sc::element_type_formula) + { + ScFormulaCell& rCell = *sc::formula_block::at(*itRet->data, aPos.second); + if (!pDocument->IsClipOrUndo()) + // Have the dying formula cell stop listening. + rCell.EndListeningTo(pDocument); + + if (rCell.IsShared()) + adjustSharedFormulaCell(aPos, rCell); + } return itRet; } _______________________________________________ Libreoffice-commits mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
