sc/inc/column.hxx | 22 +++++++++++++ sc/source/core/data/column.cxx | 63 +++++++++++++++++++++++++++++++++++----- sc/source/core/data/column2.cxx | 24 ++++++++++++++- sc/source/core/data/column3.cxx | 32 ++++++++++++++++---- 4 files changed, 127 insertions(+), 14 deletions(-)
New commits: commit 8406603b8e73b7ac169d569f82d423b34b4745f5 Author: Kohei Yoshida <kohei.yosh...@gmail.com> Date: Tue Jun 25 17:06:45 2013 -0400 Identify spots where we may need to regroup formula cells. Change-Id: Ib448480bb3a3e39638dd42cafc272934a226cc1e diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx index 3cbd7b8..69f3420 100644 --- a/sc/inc/column.hxx +++ b/sc/inc/column.hxx @@ -457,6 +457,28 @@ public: void InterpretDirtyCells( SCROW nRow1, SCROW nRow2 ); + /** + * Regroup formula cells for the entire column. + */ + void RegroupFormulaCells(); + + /** + * Regroup existing formula cells when a new cell is inserted. + * + * @param nRow row at which a new cell is inserted. + */ + void RegroupFormulaCells( SCROW nRow ); + + /** + * Regroup existing formula cells when a range of new cells are inserted. + * + * @param nRow1 first row of inserted new cell span. + * @param nRow2 last row of inserted new cell span. + */ + void RegroupFormulaCells( SCROW nRow1, SCROW nRow2 ); + + void FormulaCellsUndecided( SCROW nRow1, SCROW nRow2 ); + private: void CopyCellsInRangeToColumn( diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx index bd1eeae..ac3ab98 100644 --- a/sc/source/core/data/column.cxx +++ b/sc/source/core/data/column.cxx @@ -886,6 +886,9 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2) ScFormulaCell* pNew2 = cloneFormulaCell(pDocument, ScAddress(nCol, nRow2, nTab), *pOld1); *itf1 = pNew1; *itf2 = pNew2; + + RegroupFormulaCells(nRow1); + RegroupFormulaCells(nRow2); } break; default: @@ -930,6 +933,8 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2) ScFormulaCell* pNew = cloneFormulaCell(pDocument, ScAddress(nCol, nRow1, nTab), *aCell2.mpFormula); it1 = maCells.set(it1, nRow1, pNew); maCells.set_empty(it1, nRow2, nRow2); // original formula cell gets deleted. + + RegroupFormulaCells(nRow2); } break; default: @@ -971,6 +976,9 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2) ScFormulaCell* pNew = cloneFormulaCell(pDocument, ScAddress(nCol, nRow2, nTab), *aCell1.mpFormula); it1 = maCells.set_empty(it1, nRow1, nRow1); // original formula cell is gone. maCells.set(it1, nRow2, pNew); + + RegroupFormulaCells(nRow1); + RegroupFormulaCells(nRow2); } break; default: @@ -1012,6 +1020,7 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2) } maCells.set(it1, nRow2, aCell1.mfValue); + } break; case CELLTYPE_STRING: @@ -1101,6 +1110,8 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2) } SwapCellTextAttrs(nRow1, nRow2); + RegroupFormulaCells(nRow1); + RegroupFormulaCells(nRow2); CellStorageModified(); BroadcastCells(aRows); } @@ -1125,6 +1136,7 @@ void ScColumn::SwapCell( SCROW nRow, ScColumn& rCol) ScFormulaCell* pCell2 = rCol.maCells.get<ScFormulaCell*>(nRow); if (pCell1) updateRefInFormulaCell(*pCell1, rCol.nCol, nTab, rCol.nCol - nCol); + if (pCell2) updateRefInFormulaCell(*pCell2, nCol, nTab, nCol - rCol.nCol); @@ -1133,6 +1145,13 @@ void ScColumn::SwapCell( SCROW nRow, ScColumn& rCol) CellStorageModified(); rCol.CellStorageModified(); + + if (pCell1 || pCell2) + { + // At least one of the two cells is a formula cell. Regroup them. + RegroupFormulaCells(nRow); + rCol.RegroupFormulaCells(nRow); + } } @@ -1200,15 +1219,18 @@ void ScColumn::InsertRow( SCROW nStartRow, SCSIZE nSize ) maCellTextAttrs.insert_empty(nStartRow, nSize); maCellTextAttrs.resize(MAXROWCOUNT); - maCells.insert_empty(nStartRow, nSize); + // Check if this insertion will split an existing formula block. + sc::CellStoreType::position_type aPos = maCells.position(nStartRow); + bool bSplitFormulaBlock = aPos.second != 0; + + sc::CellStoreType::iterator it = maCells.insert_empty(aPos.first, nStartRow, nSize); maCells.resize(MAXROWCOUNT); - bool bOldAutoCalc = pDocument->GetAutoCalc(); - pDocument->SetAutoCalc( false ); // avoid recalculations + sc::AutoCalcSwitch aSwitch(*pDocument, false); // Get the position of the first affected cell. - std::pair<sc::CellStoreType::iterator,size_t> aPos = maCells.position(nStartRow+nSize); - sc::CellStoreType::iterator it = aPos.first; + aPos = maCells.position(it, nStartRow+nSize); + it = aPos.first; // Update the positions of all affected formula cells. if (it->type == sc::element_type_formula) @@ -1237,9 +1259,10 @@ void ScColumn::InsertRow( SCROW nStartRow, SCSIZE nSize ) } } - CellStorageModified(); + if (bSplitFormulaBlock) + RegroupFormulaCells(nStartRow, nStartRow+nSize-1); - pDocument->SetAutoCalc( bOldAutoCalc ); + CellStorageModified(); // We *probably* don't need to broadcast here since the parent call seems // to take care of it. @@ -1370,6 +1393,7 @@ void ScColumn::CopyStaticToDocument(SCROW nRow1, SCROW nRow2, ScColumn& rDestCol break; } + rDestCol.RegroupFormulaCells(nRow1, nRow2); rDestCol.CellStorageModified(); } @@ -1419,6 +1443,7 @@ void ScColumn::CopyCellToDocument( SCROW nSrcRow, SCROW nDestRow, ScColumn& rDes else rDestCol.maCellTextAttrs.set_empty(nDestRow, nDestRow); + rDestCol.RegroupFormulaCells(nDestRow); rDestCol.CellStorageModified(); } @@ -1956,6 +1981,8 @@ void ScColumn::MoveTo(SCROW nStartRow, SCROW nEndRow, ScColumn& rCol) maCells.transfer(nStartRow, nEndRow, rCol.maCells, nStartRow); maCellTextAttrs.transfer(nStartRow, nEndRow, rCol.maCellTextAttrs, nStartRow); + RegroupFormulaCells(nStartRow, nEndRow); + rCol.RegroupFormulaCells(nStartRow, nEndRow); CellStorageModified(); rCol.CellStorageModified(); @@ -2064,11 +2091,13 @@ bool ScColumn::UpdateReference( UpdateRefMode eUpdateRefMode, SCCOL nCol1, SCROW if (eUpdateRefMode == URM_COPY) { UpdateRefOnCopy aHandler(aRange, nDx, nDy, nDz, pUndoDoc); + FormulaCellsUndecided(nRow1, nRow2); sc::ProcessBlock(maCells.begin(), maCells, aHandler, nRow1, nRow2); return aHandler.isUpdated(); } UpdateRefOnNonCopy aHandler(nCol, nTab, aRange, nDx, nDy, nDz, eUpdateRefMode, pUndoDoc); + FormulaCellsUndecided(0, MAXROW); sc::ProcessFormula(maCells, aHandler); return aHandler.isUpdated(); } @@ -2547,6 +2576,7 @@ void ScColumn::UpdateTranspose( const ScRange& rSource, const ScAddress& rDest, { UpdateTransHandler aFunc(rSource, rDest, pUndoDoc); sc::ProcessFormula(maCells, aFunc); + RegroupFormulaCells(); } @@ -2554,6 +2584,7 @@ void ScColumn::UpdateGrow( const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY ) { UpdateGrowHandler aFunc(rArea, nGrowX, nGrowY); sc::ProcessFormula(maCells, aFunc); + RegroupFormulaCells(); } @@ -2573,7 +2604,10 @@ 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) @@ -2587,7 +2621,10 @@ void ScColumn::UpdateDeleteTab(SCTAB nDelPos, bool bIsMove, ScColumn* /*pRefUndo DeleteTabUpdater aFunc(maCellTextAttrs, nDelPos, nSheets, nTab, bIsMove); sc::ProcessFormulaEditText(maCells, aFunc); if (aFunc.isModified()) + { + RegroupFormulaCells(); CellStorageModified(); + } } void ScColumn::UpdateInsertTabAbs(SCTAB nNewPos) @@ -2595,7 +2632,10 @@ void ScColumn::UpdateInsertTabAbs(SCTAB nNewPos) InsertAbsTabUpdater aFunc(maCellTextAttrs, nTab, nNewPos); sc::ProcessFormulaEditText(maCells, aFunc); if (aFunc.isModified()) + { + RegroupFormulaCells(); CellStorageModified(); + } } void ScColumn::UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos, SCTAB nTabNo ) @@ -2606,7 +2646,10 @@ void ScColumn::UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos, SCTAB nTabNo ) MoveTabUpdater aFunc(maCellTextAttrs, nTab, nOldPos, nNewPos); sc::ProcessFormulaEditText(maCells, aFunc); if (aFunc.isModified()) + { + RegroupFormulaCells(); CellStorageModified(); + } } @@ -2614,6 +2657,7 @@ void ScColumn::UpdateCompile( bool bForceIfNameInUse ) { UpdateCompileHandler aFunc(bForceIfNameInUse); sc::ProcessFormula(maCells, aFunc); + RegroupFormulaCells(); } @@ -2711,12 +2755,17 @@ void ScColumn::CompileXML( ScProgress& rProgress ) { CompileXMLHandler aFunc(rProgress); sc::ProcessFormula(maCells, aFunc); + RegroupFormulaCells(); } bool ScColumn::CompileErrorCells(sal_uInt16 nErrCode) { CompileErrorCellsHandler aHdl(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 a946e93..80491b5 100644 --- a/sc/source/core/data/column2.cxx +++ b/sc/source/core/data/column2.cxx @@ -1466,6 +1466,8 @@ SCROW ScColumn::FindNextVisibleRowWithContent( void ScColumn::CellStorageModified() { + // TODO: Update column's "last updated" timestamp here. + mbDirtyGroups = true; #if DEBUG_COLUMN_STORAGE @@ -1526,6 +1528,22 @@ void ScColumn::CellStorageModified() #endif } +void ScColumn::RegroupFormulaCells() +{ +} + +void ScColumn::RegroupFormulaCells( SCROW nRow ) +{ +} + +void ScColumn::RegroupFormulaCells( SCROW nRow1, SCROW nRow2 ) +{ +} + +void ScColumn::FormulaCellsUndecided( SCROW nRow1, SCROW nRow2 ) +{ +} + void ScColumn::CopyCellTextAttrsToDocument(SCROW nRow1, SCROW nRow2, ScColumn& rDestCol) const { rDestCol.maCellTextAttrs.set_empty(nRow1, nRow2); // Empty the destination range first. @@ -1988,7 +2006,7 @@ public: sc::formula_block::const_iterator itEnd = it; std::advance(itEnd, nDataSize); - size_t nPrevRow, nThisRow = node.position + nOffset; + size_t nPrevRow = 0, nThisRow = node.position + nOffset; for (; it != itEnd; ++it, nPrevRow = nThisRow, ++nThisRow) { ScFormulaCell& rCell = const_cast<ScFormulaCell&>(**it); @@ -2393,24 +2411,28 @@ void ScColumn::CompileDBFormula() { CompileDBFormulaHandler aFunc; sc::ProcessFormula(maCells, aFunc); + RegroupFormulaCells(); } void ScColumn::CompileDBFormula( bool bCreateFormulaString ) { CompileDBFormula2Handler aFunc(bCreateFormulaString); sc::ProcessFormula(maCells, aFunc); + RegroupFormulaCells(); } void ScColumn::CompileNameFormula( bool bCreateFormulaString ) { CompileNameFormulaHandler aFunc(bCreateFormulaString); sc::ProcessFormula(maCells, aFunc); + RegroupFormulaCells(); } void ScColumn::CompileColRowNameFormula() { CompileColRowNameFormulaHandler aFunc; sc::ProcessFormula(maCells, aFunc); + RegroupFormulaCells(); } namespace { diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx index 16a4d0a..b8e8e10 100644 --- a/sc/source/core/data/column3.cxx +++ b/sc/source/core/data/column3.cxx @@ -137,7 +137,8 @@ void ScColumn::Delete( SCROW nRow ) if (it == maCells.end()) return; - if (it->type == sc::element_type_formula) + bool bFormulaCell = it->type == sc::element_type_formula; + if (bFormulaCell) { ScFormulaCell* p = sc::formula_block::at(*it->data, aPos.second); p->EndListeningTo(pDocument); @@ -148,6 +149,9 @@ void ScColumn::Delete( SCROW nRow ) pDocument->Broadcast( ScHint(SC_HINT_DATACHANGED, ScAddress(nCol, nRow, nTab))); + if (bFormulaCell) + RegroupFormulaCells(nRow); + CellStorageModified(); } @@ -244,7 +248,7 @@ void ScColumn::DeleteRow( SCROW nStartRow, SCSIZE nSize ) maBroadcasters.resize(MAXROWCOUNT); // See if we have any cells that would get deleted or shifted by deletion. - std::pair<sc::CellStoreType::iterator,size_t> aPos = maCells.position(nStartRow); + sc::CellStoreType::position_type aPos = maCells.position(nStartRow); sc::CellStoreType::iterator itCell = aPos.first; if (itCell->type == sc::element_type_empty) { @@ -307,6 +311,7 @@ void ScColumn::DeleteRow( SCROW nStartRow, SCSIZE nSize ) maCellTextAttrs.erase(nStartRow, nEndRow); maCellTextAttrs.resize(MAXROWCOUNT); + RegroupFormulaCells(nStartRow); CellStorageModified(); if (!bShiftCells) @@ -419,6 +424,7 @@ void ScColumn::CopyCellsInRangeToColumn( *pDestColPos = aDestColPos; } + rColumn.RegroupFormulaCells(nRow1, nRow2); rColumn.CellStorageModified(); } @@ -430,7 +436,7 @@ sc::CellStoreType::iterator ScColumn::GetPositionToInsert( SCROW nRow ) sc::CellStoreType::iterator ScColumn::GetPositionToInsert( const sc::CellStoreType::iterator& it, SCROW nRow ) { // See if we are overwriting an existing formula cell. - std::pair<sc::CellStoreType::iterator,size_t> aRet = maCells.position(it, nRow); + sc::CellStoreType::position_type aRet = maCells.position(it, nRow); sc::CellStoreType::iterator itRet = aRet.first; if (itRet->type == sc::element_type_formula && !pDocument->IsClipOrUndo()) { @@ -580,18 +586,20 @@ public: class EmptyCells { + ScColumn& mrColumn; sc::ColumnBlockPosition& mrPos; sc::CellStoreType::iterator miPos; sc::CellStoreType& mrCells; sc::CellTextAttrStoreType& mrAttrs; public: - EmptyCells(sc::ColumnBlockPosition& rPos, sc::CellStoreType& rCells, sc::CellTextAttrStoreType& rAttrs) : - mrPos(rPos), mrCells(rCells), mrAttrs(rAttrs) {} + EmptyCells(sc::ColumnBlockPosition& rPos, ScColumn& rColumn, sc::CellStoreType& rCells, sc::CellTextAttrStoreType& rAttrs) : + mrColumn(rColumn), mrPos(rPos), mrCells(rCells), mrAttrs(rAttrs) {} void operator() (const sc::SingleColumnSpanSet::Span& rSpan) { mrPos.miCellPos = mrCells.set_empty(mrPos.miCellPos, rSpan.mnRow1, rSpan.mnRow2); mrPos.miCellTextAttrPos = mrAttrs.set_empty(mrPos.miCellTextAttrPos, rSpan.mnRow1, rSpan.mnRow2); + mrColumn.RegroupFormulaCells(rSpan.mnRow1, rSpan.mnRow2); } }; @@ -625,7 +633,7 @@ void ScColumn::DeleteArea(SCROW nStartRow, SCROW nEndRow, sal_uInt16 nDelFlag) aBlockPos.miCellTextAttrPos = maCellTextAttrs.begin(); // Delete the cells for real. - std::for_each(aSpans.begin(), aSpans.end(), EmptyCells(aBlockPos, maCells, maCellTextAttrs)); + std::for_each(aSpans.begin(), aSpans.end(), EmptyCells(aBlockPos, *this, maCells, maCellTextAttrs)); CellStorageModified(); } @@ -1362,6 +1370,7 @@ void ScColumn::MixData( sc::ParseAll(rSrcCol.maCells.begin(), rSrcCol.maCells, nRow1, nRow2, aFunc, aFunc); aFunc.commit(p); + RegroupFormulaCells(nRow1, nRow2); CellStorageModified(); } @@ -1604,6 +1613,7 @@ void ScColumn::SetEditText( SCROW nRow, EditTextObject* pEditText ) sc::CellStoreType::iterator it = GetPositionToInsert(nRow); maCells.set(it, nRow, pEditText); maCellTextAttrs.set(nRow, sc::CellTextAttr()); + RegroupFormulaCells(nRow); CellStorageModified(); BroadcastNewCell(nRow); @@ -1615,6 +1625,7 @@ void ScColumn::SetEditText( sc::ColumnBlockPosition& rBlockPos, SCROW nRow, Edit rBlockPos.miCellPos = maCells.set(rBlockPos.miCellPos, nRow, pEditText); rBlockPos.miCellTextAttrPos = maCellTextAttrs.set( rBlockPos.miCellTextAttrPos, nRow, sc::CellTextAttr()); + RegroupFormulaCells(nRow); CellStorageModified(); BroadcastNewCell(nRow); @@ -1695,6 +1706,7 @@ void ScColumn::SetFormula( SCROW nRow, const ScTokenArray& rArray, formula::Form pCell->SetNeedNumberFormat(true); maCells.set(it, nRow, pCell); maCellTextAttrs.set(nRow, sc::CellTextAttr()); + RegroupFormulaCells(nRow); CellStorageModified(); ActivateNewFormulaCell(pCell); @@ -1711,6 +1723,7 @@ void ScColumn::SetFormula( SCROW nRow, const OUString& rFormula, formula::Formul pCell->SetNeedNumberFormat(true); maCells.set(it, nRow, pCell); maCellTextAttrs.set(nRow, sc::CellTextAttr()); + RegroupFormulaCells(nRow); CellStorageModified(); ActivateNewFormulaCell(pCell); @@ -1721,6 +1734,7 @@ void ScColumn::SetFormulaCell( SCROW nRow, ScFormulaCell* pCell ) sc::CellStoreType::iterator it = GetPositionToInsert(nRow); maCells.set(it, nRow, pCell); maCellTextAttrs.set(nRow, sc::CellTextAttr()); + RegroupFormulaCells(nRow); CellStorageModified(); ActivateNewFormulaCell(pCell); @@ -1732,6 +1746,7 @@ void ScColumn::SetFormulaCell( sc::ColumnBlockPosition& rBlockPos, SCROW nRow, S rBlockPos.miCellPos = maCells.set(rBlockPos.miCellPos, nRow, pCell); rBlockPos.miCellTextAttrPos = maCellTextAttrs.set( rBlockPos.miCellTextAttrPos, nRow, sc::CellTextAttr()); + RegroupFormulaCells(nRow); CellStorageModified(); ActivateNewFormulaCell(pCell); @@ -2123,6 +2138,7 @@ void ScColumn::SetError( SCROW nRow, const sal_uInt16 nError) sc::CellStoreType::iterator it = GetPositionToInsert(nRow); maCells.set(it, nRow, pCell); maCellTextAttrs.set(nRow, sc::CellTextAttr()); + RegroupFormulaCells(nRow); CellStorageModified(); ActivateNewFormulaCell(pCell); @@ -2136,6 +2152,7 @@ void ScColumn::SetRawString( SCROW nRow, const OUString& rStr, bool bBroadcast ) sc::CellStoreType::iterator it = GetPositionToInsert(nRow); maCells.set(it, nRow, rStr); maCellTextAttrs.set(nRow, sc::CellTextAttr()); + RegroupFormulaCells(nRow); CellStorageModified(); if (bBroadcast) @@ -2152,6 +2169,7 @@ void ScColumn::SetRawString( rBlockPos.miCellPos = maCells.set(rBlockPos.miCellPos, nRow, rStr); rBlockPos.miCellTextAttrPos = maCellTextAttrs.set( rBlockPos.miCellTextAttrPos, nRow, sc::CellTextAttr()); + RegroupFormulaCells(nRow); CellStorageModified(); if (bBroadcast) @@ -2166,6 +2184,7 @@ void ScColumn::SetValue( SCROW nRow, double fVal ) sc::CellStoreType::iterator it = GetPositionToInsert(nRow); maCells.set(it, nRow, fVal); maCellTextAttrs.set(nRow, sc::CellTextAttr()); + RegroupFormulaCells(nRow); CellStorageModified(); BroadcastNewCell(nRow); @@ -2181,6 +2200,7 @@ void ScColumn::SetValue( rBlockPos.miCellPos = maCells.set(rBlockPos.miCellPos, nRow, fVal); rBlockPos.miCellTextAttrPos = maCellTextAttrs.set( rBlockPos.miCellTextAttrPos, nRow, sc::CellTextAttr()); + RegroupFormulaCells(nRow); CellStorageModified(); if (bBroadcast) _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits