summaryrefslogtreecommitdiff
path: root/sc/source/core/tool/sharedformula.cxx
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@gmail.com>2013-07-11 00:46:46 -0400
committerKohei Yoshida <kohei.yoshida@gmail.com>2013-07-11 12:30:16 -0400
commit67ffff37ed16dff6529daf36835554f54a28fe5e (patch)
tree0c67b55817631941bb57266237892d6e80269ed2 /sc/source/core/tool/sharedformula.cxx
parentd35cf5e19652989419aa598119ccd978307111fe (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/sharedformula.cxx')
-rw-r--r--sc/source/core/tool/sharedformula.cxx118
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: */