sc/inc/column.hxx | 2 + sc/source/core/data/column.cxx | 77 +++++++++++++++++++++++++++++----------- sc/source/core/data/column2.cxx | 4 -- sc/source/core/data/column3.cxx | 66 ++++++++++++++++++++++++++-------- 4 files changed, 109 insertions(+), 40 deletions(-)
New commits: commit 724077098c35e7edd4231ae95e7cddb1a1b95a0c Author: Kohei Yoshida <kohei.yosh...@gmail.com> Date: Thu Jul 4 02:17:03 2013 -0400 More on regrouping of formula cells. Change-Id: Icd3403e759841dce351c932ea8915ba9819e5a29 diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx index 62e1ddf..6bbfb6a 100644 --- a/sc/inc/column.hxx +++ b/sc/inc/column.hxx @@ -505,6 +505,8 @@ public: */ void SplitFormulaCellGroup( const sc::CellStoreType::position_type& aPos ) const; + void JoinFormulaCellAbove( const sc::CellStoreType::position_type& aPos ) const; + /** * Regroup formula cells for the entire column. */ diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx index bdfde88..7ce8668 100644 --- a/sc/source/core/data/column.cxx +++ b/sc/source/core/data/column.cxx @@ -2127,13 +2127,29 @@ void ScColumn::MoveTo(SCROW nStartRow, SCROW nEndRow, ScColumn& rCol) sc::SingleColumnSpanSet::SpansType aRanges; aNonEmpties.getSpans(aRanges); + // Split the formula grouping at the top and bottom boundaries. + sc::CellStoreType::position_type aPos = maCells.position(nStartRow); + SplitFormulaCellGroup(aPos); + aPos = maCells.position(aPos.first, nEndRow+1); + SplitFormulaCellGroup(aPos); + + // Do the same with the destination column. + aPos = rCol.maCells.position(nStartRow); + rCol.SplitFormulaCellGroup(aPos); + aPos = rCol.maCells.position(aPos.first, nEndRow+1); + rCol.SplitFormulaCellGroup(aPos); + // Move the broadcasters to the destination column. maBroadcasters.transfer(nStartRow, nEndRow, rCol.maBroadcasters, nStartRow); maCells.transfer(nStartRow, nEndRow, rCol.maCells, nStartRow); maCellTextAttrs.transfer(nStartRow, nEndRow, rCol.maCellTextAttrs, nStartRow); - RegroupFormulaCells(nStartRow, nEndRow); - rCol.RegroupFormulaCells(nStartRow, nEndRow); + // Re-group transferred formula cells. + aPos = rCol.maCells.position(nStartRow); + rCol.JoinFormulaCellAbove(aPos); + aPos = rCol.maCells.position(aPos.first, nEndRow+1); + rCol.JoinFormulaCellAbove(aPos); + CellStorageModified(); rCol.CellStorageModified(); @@ -2267,31 +2283,47 @@ namespace { class UpdateTransHandler { + ScColumn& mrColumn; + sc::CellStoreType::iterator miPos; ScRange maSource; ScAddress maDest; ScDocument* mpUndoDoc; public: - UpdateTransHandler(const ScRange& rSource, const ScAddress& rDest, ScDocument* pUndoDoc) : + UpdateTransHandler(ScColumn& rColumn, const ScRange& rSource, const ScAddress& rDest, ScDocument* pUndoDoc) : + mrColumn(rColumn), + miPos(rColumn.GetCellStore().begin()), maSource(rSource), maDest(rDest), mpUndoDoc(pUndoDoc) {} - void operator() (size_t, ScFormulaCell* pCell) + void operator() (size_t nRow, ScFormulaCell* pCell) { + sc::CellStoreType::position_type aPos = mrColumn.GetCellStore().position(miPos, nRow); + miPos = aPos.first; + mrColumn.UnshareFormulaCell(aPos, *pCell); pCell->UpdateTranspose(maSource, maDest, mpUndoDoc); + mrColumn.JoinNewFormulaCell(aPos, *pCell); } }; class UpdateGrowHandler { + ScColumn& mrColumn; + sc::CellStoreType::iterator miPos; ScRange maArea; SCCOL mnGrowX; SCROW mnGrowY; public: - UpdateGrowHandler(const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY) : + UpdateGrowHandler(ScColumn& rColumn, const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY) : + mrColumn(rColumn), + miPos(rColumn.GetCellStore().begin()), maArea(rArea), mnGrowX(nGrowX), mnGrowY(nGrowY) {} - void operator() (size_t, ScFormulaCell* pCell) + void operator() (size_t nRow, ScFormulaCell* pCell) { + sc::CellStoreType::position_type aPos = mrColumn.GetCellStore().position(miPos, nRow); + miPos = aPos.first; + mrColumn.UnshareFormulaCell(aPos, *pCell); pCell->UpdateGrow(maArea, mnGrowX, mnGrowY); + mrColumn.JoinNewFormulaCell(aPos, *pCell); } }; @@ -2638,14 +2670,22 @@ public: class CompileErrorCellsHandler { + ScColumn& mrColumn; + sc::CellStoreType::iterator miPos; sal_uInt16 mnErrCode; FormulaGrammar::Grammar meGram; bool mbCompiled; public: - CompileErrorCellsHandler(sal_uInt16 nErrCode, FormulaGrammar::Grammar eGram) : - mnErrCode(nErrCode), meGram(eGram), mbCompiled(false) {} + CompileErrorCellsHandler(ScColumn& rColumn, sal_uInt16 nErrCode, FormulaGrammar::Grammar eGram) : + mrColumn(rColumn), + miPos(mrColumn.GetCellStore().begin()), + mnErrCode(nErrCode), + meGram(eGram), + mbCompiled(false) + { + } - void operator() (size_t /*nRow*/, ScFormulaCell* pCell) + void operator() (size_t nRow, ScFormulaCell* pCell) { sal_uInt16 nCurError = pCell->GetRawError(); if (!nCurError) @@ -2656,10 +2696,14 @@ public: // Error code is specified, and it doesn't match. Skip it. return; + sc::CellStoreType::position_type aPos = mrColumn.GetCellStore().position(miPos, nRow); + miPos = aPos.first; + mrColumn.UnshareFormulaCell(aPos, *pCell); pCell->GetCode()->SetCodeError(0); OUStringBuffer aBuf; pCell->GetFormula(aBuf, meGram); pCell->Compile(aBuf.makeStringAndClear(), false, meGram); + mrColumn.JoinNewFormulaCell(aPos, *pCell); mbCompiled = true; } @@ -2734,17 +2778,15 @@ public: void ScColumn::UpdateTranspose( const ScRange& rSource, const ScAddress& rDest, ScDocument* pUndoDoc ) { - UpdateTransHandler aFunc(rSource, rDest, pUndoDoc); + UpdateTransHandler aFunc(*this, rSource, rDest, pUndoDoc); sc::ProcessFormula(maCells, aFunc); - RegroupFormulaCells(); } void ScColumn::UpdateGrow( const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY ) { - UpdateGrowHandler aFunc(rArea, nGrowX, nGrowY); + UpdateGrowHandler aFunc(*this, rArea, nGrowX, nGrowY); sc::ProcessFormula(maCells, aFunc); - RegroupFormulaCells(); } @@ -2764,10 +2806,7 @@ void ScColumn::UpdateInsertTabOnlyCells(SCTAB nInsPos, SCTAB nNewSheets) InsertTabUpdater aFunc(maCellTextAttrs, nTab, nInsPos, nNewSheets); sc::ProcessFormulaEditText(maCells, aFunc); if (aFunc.isModified()) - { - RegroupFormulaCells(); CellStorageModified(); - } } void ScColumn::UpdateDeleteTab(SCTAB nDelPos, bool bIsMove, ScColumn* /*pRefUndo*/, SCTAB nSheets) @@ -2910,12 +2949,8 @@ void ScColumn::CompileXML( ScProgress& rProgress ) bool ScColumn::CompileErrorCells(sal_uInt16 nErrCode) { - CompileErrorCellsHandler aHdl(nErrCode, pDocument->GetGrammar()); + CompileErrorCellsHandler aHdl(*this, nErrCode, pDocument->GetGrammar()); sc::ProcessFormula(maCells, aHdl); - if (aHdl.isCompiled()) - // TODO: Probably more efficient to do this individually rather than the whole column. - RegroupFormulaCells(); - return aHdl.isCompiled(); } diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx index 98081356..a651fa6 100644 --- a/sc/source/core/data/column2.cxx +++ b/sc/source/core/data/column2.cxx @@ -1530,10 +1530,6 @@ void ScColumn::CellStorageModified() #endif } -void ScColumn::RegroupFormulaCells() -{ -} - void ScColumn::RegroupFormulaCells( SCROW /*nRow*/ ) { } diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx index 203bb96..f39d1f8 100644 --- a/sc/source/core/data/column3.cxx +++ b/sc/source/core/data/column3.cxx @@ -326,12 +326,14 @@ sc::CellStoreType::iterator ScColumn::GetPositionToInsert( SCROW nRow ) namespace { -void joinFormulaCells(SCROW nRow, ScFormulaCell& rCell1, ScFormulaCell& rCell2) +void joinFormulaCells(const sc::CellStoreType::position_type& rPos, ScFormulaCell& rCell1, ScFormulaCell& rCell2) { ScFormulaCell::CompareState eState = rCell1.CompareByTokenArray(rCell2); if (eState == ScFormulaCell::NotEqual) return; + SCROW nRow = rPos.first->position + rPos.second; + // Formula tokens equal those of the previous formula cell. ScFormulaCellGroupRef xGroup1 = rCell1.GetCellGroup(); ScFormulaCellGroupRef xGroup2 = rCell2.GetCellGroup(); @@ -339,13 +341,23 @@ void joinFormulaCells(SCROW nRow, ScFormulaCell& rCell1, ScFormulaCell& rCell2) { if (xGroup2) { - // Both cell1 and cell2 are shared. Merge them together. + // Both cell 1 and cell 2 are shared. Merge them together. + if (xGroup1.get() == xGroup2.get()) + // They belong to the same group. + return; + + // Set the group object from cell 1 to all cells in group 2. xGroup1->mnLength += xGroup2->mnLength; - rCell2.SetCellGroup(xGroup1); + size_t nOffset = rPos.second + 1; // position of cell 2 + for (size_t i = 0, n = xGroup2->mnLength; i < n; ++i) + { + ScFormulaCell& rCell = *sc::formula_block::at(*rPos.first->data, nOffset+i); + rCell.SetCellGroup(xGroup1); + } } else { - // cell1 is shared but cell2 is not. + // cell 1 is shared but cell 2 is not. rCell2.SetCellGroup(xGroup1); ++xGroup1->mnLength; } @@ -354,7 +366,7 @@ void joinFormulaCells(SCROW nRow, ScFormulaCell& rCell1, ScFormulaCell& rCell2) { if (xGroup2) { - // cell1 is not shared, but cell2 is already shared. + // cell 1 is not shared, but cell 2 is already shared. rCell1.SetCellGroup(xGroup2); xGroup2->mnStart = nRow; ++xGroup2->mnLength; @@ -378,20 +390,20 @@ void joinFormulaCells(SCROW nRow, ScFormulaCell& rCell1, ScFormulaCell& rCell2) 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); + sc::CellStoreType::position_type aPosPrev = aPos; + --aPosPrev.second; + joinFormulaCells(aPosPrev, 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); + joinFormulaCells(aPos, rCell, rNext); } } @@ -575,6 +587,26 @@ void ScColumn::SplitFormulaCellGroup( const sc::CellStoreType::position_type& aP } } +void ScColumn::JoinFormulaCellAbove( const sc::CellStoreType::position_type& aPos ) const +{ + if (aPos.first->type != sc::element_type_formula) + // This is not a formula cell. + return; + + if (aPos.second == 0) + // This cell is already the top cell in a formula block; the previous + // cell is not a formula cell. + return; + + SCROW nRow = aPos.first->position + aPos.second; + + ScFormulaCell& rPrev = *sc::formula_block::at(*aPos.first->data, aPos.second-1); + ScFormulaCell& rCell = *sc::formula_block::at(*aPos.first->data, aPos.second); + sc::CellStoreType::position_type aPosPrev = aPos; + --aPosPrev.second; + joinFormulaCells(aPosPrev, rPrev, rCell); +} + sc::CellStoreType::iterator ScColumn::GetPositionToInsert( const sc::CellStoreType::iterator& it, SCROW nRow ) { // See if we are overwriting an existing formula cell. @@ -740,7 +772,7 @@ class EmptyCells sc::ColumnBlockPosition& mrPos; sc::CellStoreType::iterator miPos; - void splitFormulaGrouping(sc::CellStoreType& rCells, const sc::CellStoreType::position_type& rPos) + void splitFormulaGrouping(const sc::CellStoreType::position_type& rPos) { if (rPos.first->type == sc::element_type_formula) { @@ -760,9 +792,9 @@ public: // First, split formula grouping at the top and bottom boundaries // before emptying the cells. sc::CellStoreType::position_type aPos = rCells.position(mrPos.miCellPos, rSpan.mnRow1); - splitFormulaGrouping(rCells, aPos); + splitFormulaGrouping(aPos); aPos = rCells.position(aPos.first, rSpan.mnRow2); - splitFormulaGrouping(rCells, aPos); + splitFormulaGrouping(aPos); mrPos.miCellPos = rCells.set_empty(mrPos.miCellPos, rSpan.mnRow1, rSpan.mnRow2); mrPos.miCellTextAttrPos = mrColumn.GetCellAttrStore().set_empty(mrPos.miCellTextAttrPos, rSpan.mnRow1, rSpan.mnRow2); @@ -2874,15 +2906,19 @@ void ScColumn::RebuildFormulaGroups() if (!mbDirtyGroups) return; - // clear previous formula groups. + RegroupFormulaCells(); + mbDirtyGroups = false; +} + +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()); - - mbDirtyGroups = false; } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits