diff options
author | Kohei Yoshida <kohei.yoshida@gmail.com> | 2013-07-11 00:46:46 -0400 |
---|---|---|
committer | Kohei Yoshida <kohei.yoshida@gmail.com> | 2013-07-11 12:30:16 -0400 |
commit | 67ffff37ed16dff6529daf36835554f54a28fe5e (patch) | |
tree | 0c67b55817631941bb57266237892d6e80269ed2 /sc/source/core/tool | |
parent | d35cf5e19652989419aa598119ccd978307111fe (diff) |
Move UnshareFormulaCell() out of ScColumn into SharedFormulaUtil.
This one too doesn't operate on column.
Change-Id: Ieb23641ca4860d6f137b266813ad56f4984e0523
Diffstat (limited to 'sc/source/core/tool')
-rw-r--r-- | sc/source/core/tool/sharedformula.cxx | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/sc/source/core/tool/sharedformula.cxx b/sc/source/core/tool/sharedformula.cxx index 5cdfc78522b5..2ea5cf881907 100644 --- a/sc/source/core/tool/sharedformula.cxx +++ b/sc/source/core/tool/sharedformula.cxx @@ -139,6 +139,124 @@ void SharedFormulaUtil::joinFormulaCellAbove(const CellStoreType::position_type& joinFormulaCells(aPosPrev, rPrev, rCell); } +void SharedFormulaUtil::unshareFormulaCell(const CellStoreType::position_type& aPos, ScFormulaCell& rCell) +{ + if (!rCell.IsShared()) + return; + + ScFormulaCellGroupRef xNone; + sc::CellStoreType::iterator it = aPos.first; + + // 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. +#if DEBUG_COLUMN_STORAGE + if (aPos.second+1 >= aPos.first->size) + { + cerr << "ScColumn::UnshareFormulaCell: There is no next formula cell but there should be!" << endl; + cerr.flush(); + abort(); + } +#endif + 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) + { + cerr << "ScColumn::UnshareFormulaCell: There is no previous formula cell but there should be!" << endl; + cerr.flush(); + abort(); + } +#endif + 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. + if (xGroup->mnLength == 1) + { + // Make the top cell non-shared. +#if DEBUG_COLUMN_STORAGE + if (aPos.second == 0) + { + cerr << "ScColumn::UnshareFormulaCell: There is no previous formula cell but there should be!" << endl; + cerr.flush(); + abort(); + } +#endif + ScFormulaCell& rPrev = *sc::formula_block::at(*it->data, aPos.second-1); + rPrev.SetCellGroup(xNone); + } + + SCROW nLength2 = nEndRow - rCell.aPos.Row(); + if (nLength2 >= 2) + { + ScFormulaCellGroupRef xGroup2; + xGroup2.reset(new ScFormulaCellGroup); + xGroup2->mnStart = rCell.aPos.Row() + 1; + xGroup2->mnLength = nLength2; + xGroup2->mbInvariant = xGroup->mbInvariant; +#if DEBUG_COLUMN_STORAGE + if (xGroup2->mnStart + xGroup2->mnLength > it->position + it->size) + { + cerr << "ScColumn::UnshareFormulaCell: Shared formula region goes beyond the formula block. Not good." << endl; + cerr.flush(); + abort(); + } +#endif + 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); + } + } + else + { + // Make the next cell non-shared. + sc::formula_block::iterator itCell = sc::formula_block::begin(*it->data); + std::advance(itCell, aPos.second+1); + ScFormulaCell& rCell2 = **itCell; + rCell2.SetCellGroup(xNone); + } + } + + rCell.SetCellGroup(xNone); +} + } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |