diff options
author | Kohei Yoshida <kohei.yoshida@gmail.com> | 2013-08-13 19:47:04 -0400 |
---|---|---|
committer | Kohei Yoshida <kohei.yoshida@gmail.com> | 2013-08-13 23:01:21 -0400 |
commit | f110e4190e575915a584e60cd2fb58dcb5eb5eaa (patch) | |
tree | d61139d55e5777d81a8c48634a24ea21ab2cce71 /sc | |
parent | 77e8422947a83d6db3c528fd5d773aeb14178f37 (diff) |
Try to re-group without ungrouping all cells.
Change-Id: I8e5c4e240e64a1d70e599c4a8791133dddc0b75b
Diffstat (limited to 'sc')
-rw-r--r-- | sc/source/core/data/column3.cxx | 108 |
1 files changed, 77 insertions, 31 deletions
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx index 9282cf32e8c5..0ac06e7e4726 100644 --- a/sc/source/core/data/column3.cxx +++ b/sc/source/core/data/column3.cxx @@ -2627,18 +2627,6 @@ xub_StrLen ScColumn::GetMaxNumberStringLen( namespace { -class CellGroupSetter -{ - ScFormulaCellGroupRef mxGroup; -public: - CellGroupSetter(const ScFormulaCellGroupRef& xGroup) : mxGroup(xGroup) {} - - void operator() (size_t, ScFormulaCell* pCell) - { - pCell->SetCellGroup(mxGroup); - } -}; - class GroupFormulaCells { ScFormulaCellGroupRef mxNone; @@ -2651,40 +2639,103 @@ public: // We are only interested in formula cells. return; - ScFormulaCell* pPrev = NULL; - ScFormulaCell* pCur = NULL; size_t nRow = node.position; // start row position. sc::formula_block::iterator it = sc::formula_block::begin(*node.data); sc::formula_block::iterator itEnd = sc::formula_block::end(*node.data); - for (; it != itEnd; ++it, ++nRow, pPrev = pCur) + + // This block should never be empty. + + ScFormulaCell* pPrev = *it; + ScFormulaCellGroupRef xPrevGrp = pPrev->GetCellGroup(); + if (xPrevGrp) + { + // Move to the cell after the last cell of the current group. + std::advance(it, xPrevGrp->mnLength); + nRow += xPrevGrp->mnLength; + } + else + { + ++it; + ++nRow; + } + + ScFormulaCell* pCur = NULL; + ScFormulaCellGroupRef xCurGrp; + for (; it != itEnd; pPrev = pCur, xPrevGrp = xCurGrp) { pCur = *it; - if (!pPrev) - continue; + xCurGrp = pCur->GetCellGroup(); ScFormulaCell::CompareState eCompState = pPrev->CompareByTokenArray(*pCur); if (eCompState == ScFormulaCell::NotEqual) { // different formula tokens. pCur->SetCellGroup(mxNone); + if (xCurGrp) + { + // Move to the cell after the last cell of the current group. + std::advance(it, xCurGrp->mnLength); + nRow += xCurGrp->mnLength; + } + else + { + ++it; + ++nRow; + } + continue; } - // Formula tokens equal those of the previous formula cell. - ScFormulaCellGroupRef xGroup = pPrev->GetCellGroup(); - if (!xGroup) + // Formula tokens equal those of the previous formula cell or cell group. + if (xPrevGrp) + { + // Previous cell is a group. + if (xCurGrp) + { + // The current cell is a group. Merge these two groups. + xPrevGrp->mnLength += xCurGrp->mnLength; + pCur->SetCellGroup(xPrevGrp); + sc::formula_block::iterator itGrpEnd = it; + std::advance(itGrpEnd, xCurGrp->mnLength); + for (++it; it != itGrpEnd; ++it) + { + ScFormulaCell* pCell = *it; + pCell->SetCellGroup(xPrevGrp); + } + nRow += xCurGrp->mnLength; + } + else + { + // Add this cell to the previous group. + pCur->SetCellGroup(xPrevGrp); + ++xPrevGrp->mnLength; + ++nRow; + ++it; + } + + } + else if (xCurGrp) { - // create a new group ... - xGroup = pPrev->CreateCellGroup(nRow - 1, 2, eCompState == ScFormulaCell::EqualInvariant); - pCur->SetCellGroup(xGroup); + // Previous cell is a regular cell and current cell is a group. + nRow += xCurGrp->mnLength; + std::advance(it, xCurGrp->mnLength); + pPrev->SetCellGroup(xCurGrp); + --xCurGrp->mnStart; + ++xCurGrp->mnLength; + xPrevGrp = xCurGrp; } else { - // existing group. extend its length. - pCur->SetCellGroup(xGroup); - ++xGroup->mnLength; + // Both previous and current cells are regular cells. + xPrevGrp = pPrev->CreateCellGroup(nRow - 1, 2, eCompState == ScFormulaCell::EqualInvariant); + pCur->SetCellGroup(xPrevGrp); + ++nRow; + ++it; } + + pCur = pPrev; + xCurGrp = xPrevGrp; } } }; @@ -2704,11 +2755,6 @@ void ScColumn::RebuildFormulaGroups() void ScColumn::RegroupFormulaCells() { - // clear previous formula groups (if any) - ScFormulaCellGroupRef xNone; - CellGroupSetter aFunc(xNone); - sc::ProcessFormula(maCells, aFunc); - // re-build formula groups. std::for_each(maCells.begin(), maCells.end(), GroupFormulaCells()); } |