summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@gmail.com>2013-06-25 17:06:45 -0400
committerKohei Yoshida <kohei.yoshida@gmail.com>2013-06-27 15:47:55 -0400
commit21a04e7ba394da27907d1be12b9fc43414db580e (patch)
tree1577fbe623c09fb9fb0b0e2e3f083c0d60f0e5ff /sc
parent9e57b12f21264651a33a6ea52db4eb07618056f8 (diff)
Identify spots where we may need to regroup formula cells.
Change-Id: Ib448480bb3a3e39638dd42cafc272934a226cc1e
Diffstat (limited to 'sc')
-rw-r--r--sc/inc/column.hxx22
-rw-r--r--sc/source/core/data/column.cxx63
-rw-r--r--sc/source/core/data/column2.cxx24
-rw-r--r--sc/source/core/data/column3.cxx32
4 files changed, 127 insertions, 14 deletions
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 36ec5f53fda4..e8dded3d7ef8 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -464,6 +464,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 8cc4786a20b5..c538d24738aa 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();
}
@@ -2546,6 +2575,7 @@ void ScColumn::UpdateTranspose( const ScRange& rSource, const ScAddress& rDest,
{
UpdateTransHandler aFunc(rSource, rDest, pUndoDoc);
sc::ProcessFormula(maCells, aFunc);
+ RegroupFormulaCells();
}
@@ -2553,6 +2583,7 @@ void ScColumn::UpdateGrow( const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY )
{
UpdateGrowHandler aFunc(rArea, nGrowX, nGrowY);
sc::ProcessFormula(maCells, aFunc);
+ RegroupFormulaCells();
}
@@ -2572,7 +2603,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)
@@ -2586,7 +2620,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)
@@ -2594,7 +2631,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 )
@@ -2605,7 +2645,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();
+ }
}
@@ -2613,6 +2656,7 @@ void ScColumn::UpdateCompile( bool bForceIfNameInUse )
{
UpdateCompileHandler aFunc(bForceIfNameInUse);
sc::ProcessFormula(maCells, aFunc);
+ RegroupFormulaCells();
}
@@ -2710,12 +2754,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 a946e9334afc..80491b5092c4 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 7251bbd7c0cc..9d234149ca68 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())
{
@@ -578,18 +584,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);
}
};
@@ -623,7 +631,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();
}
@@ -1361,6 +1369,7 @@ void ScColumn::MixData(
sc::ParseAll(rSrcCol.maCells.begin(), rSrcCol.maCells, nRow1, nRow2, aFunc, aFunc);
aFunc.commit(p);
+ RegroupFormulaCells(nRow1, nRow2);
CellStorageModified();
}
@@ -1603,6 +1612,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);
@@ -1614,6 +1624,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);
@@ -1694,6 +1705,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);
@@ -1710,6 +1722,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);
@@ -1720,6 +1733,7 @@ ScFormulaCell* 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);
@@ -1733,6 +1747,7 @@ ScFormulaCell* ScColumn::SetFormulaCell( sc::ColumnBlockPosition& rBlockPos, SCR
rBlockPos.miCellPos = maCells.set(rBlockPos.miCellPos, nRow, pCell);
rBlockPos.miCellTextAttrPos = maCellTextAttrs.set(
rBlockPos.miCellTextAttrPos, nRow, sc::CellTextAttr());
+ RegroupFormulaCells(nRow);
CellStorageModified();
ActivateNewFormulaCell(pCell);
@@ -2125,6 +2140,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);
@@ -2138,6 +2154,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)
@@ -2154,6 +2171,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)
@@ -2168,6 +2186,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);
@@ -2183,6 +2202,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)