From ab24a2c25900948bb71acbedbdecd84bda3217f7 Mon Sep 17 00:00:00 2001 From: Kohei Yoshida Date: Tue, 23 Jul 2013 16:02:37 -0400 Subject: Broadcast on formula cells containing COLUMN functions on column insertion. To ensure that the change gets propagated properly. This fixes testFuncCOLUMN() cppunit test. Change-Id: Ia1ffc2880b7dae530ceb11c617c3963f7bfaeb00 --- sc/source/core/data/column.cxx | 30 +++++++++++++++++++++++- sc/source/core/data/document.cxx | 50 +++++++++++++++++++++++++++++++--------- sc/source/core/data/table2.cxx | 7 ++++++ 3 files changed, 75 insertions(+), 12 deletions(-) (limited to 'sc/source/core/data') diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx index 23a740f9ccc4..da3cb4927613 100644 --- a/sc/source/core/data/column.cxx +++ b/sc/source/core/data/column.cxx @@ -2144,6 +2144,7 @@ void resetColumnPosition(sc::CellStoreType& rCells, SCCOL nCol) void ScColumn::SwapCol(ScColumn& rCol) { + maBroadcasters.swap(rCol.maBroadcasters); maCells.swap(rCol.maCells); maCellTextAttrs.swap(rCol.maCellTextAttrs); @@ -2163,7 +2164,6 @@ void ScColumn::SwapCol(ScColumn& rCol) CellStorageModified(); rCol.CellStorageModified(); - } void ScColumn::MoveTo(SCROW nStartRow, SCROW nEndRow, ScColumn& rCol) @@ -3004,6 +3004,26 @@ void ScColumn::SetDirtyAfterLoad() sc::ProcessFormula(maCells, aFunc); } +namespace { + +class RecalcOnRefMoveCollector +{ + std::vector maDirtyRows; +public: + void operator() (size_t nRow, ScFormulaCell* pCell) + { + if (pCell->GetDirty() && pCell->GetCode()->IsRecalcModeOnRefMove()) + maDirtyRows.push_back(nRow); + } + + const std::vector& getDirtyRows() const + { + return maDirtyRows; + } +}; + +} + void ScColumn::SetRelNameDirty() { sc::AutoCalcSwitch aSwitch(*pDocument, false); @@ -3011,6 +3031,14 @@ void ScColumn::SetRelNameDirty() sc::ProcessFormula(maCells, aFunc); } +void ScColumn::BroadcastRecalcOnRefMove() +{ + sc::AutoCalcSwitch aSwitch(*pDocument, false); + RecalcOnRefMoveCollector aFunc; + sc::ProcessFormula(maCells, aFunc); + BroadcastCells(aFunc.getDirtyRows()); +} + void ScColumn::CalcAll() { CalcAllHandler aFunc; diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx index dfc17cf90766..9cba37457454 100644 --- a/sc/source/core/data/document.cxx +++ b/sc/source/core/data/document.cxx @@ -1334,6 +1334,36 @@ bool ScDocument::CanInsertCol( const ScRange& rRange ) const return bTest; } +namespace { + +struct StartNeededListenersHandler : std::unary_function +{ + void operator() (ScTable* p) + { + if (p) + p->StartNeededListeners(); + } +}; + +struct SetRelNameDirtyHandler : std::unary_function +{ + void operator() (ScTable* p) + { + if (p) + p->SetRelNameDirty(); + } +}; + +struct BroadcastRecalcOnRefMoveHandler : std::unary_function +{ + void operator() (ScTable* p) + { + if (p) + p->BroadcastRecalcOnRefMove(); + } +}; + +} bool ScDocument::InsertCol( SCROW nStartRow, SCTAB nStartTab, SCROW nEndRow, SCTAB nEndTab, @@ -1394,17 +1424,15 @@ bool ScDocument::InsertCol( SCROW nStartRow, SCTAB nStartTab, StartAllListeners(); } else - {// Listeners have been removed in UpdateReference - TableContainer::iterator it = maTabs.begin(); - for (; it != maTabs.end(); ++it) - if (*it) - (*it)->StartNeededListeners(); - // at least all cells using range names pointing relative - // to the moved range must recalculate - it = maTabs.begin(); - for (; it != maTabs.end(); ++it) - if (*it) - (*it)->SetRelNameDirty(); + { + // Listeners have been removed in UpdateReference + std::for_each(maTabs.begin(), maTabs.end(), StartNeededListenersHandler()); + // at least all cells using range names pointing relative to the + // moved range must recalculate. + std::for_each(maTabs.begin(), maTabs.end(), SetRelNameDirtyHandler()); + // Cells containing functions such as CELL, COLUMN or ROW may have + // changed their values on relocation. Broadcast them. + std::for_each(maTabs.begin(), maTabs.end(), BroadcastRecalcOnRefMoveHandler()); } bRet = true; } diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx index 96839f10f903..5bbb6d38086b 100644 --- a/sc/source/core/data/table2.cxx +++ b/sc/source/core/data/table2.cxx @@ -48,6 +48,7 @@ #include "editutil.hxx" #include "mtvcellfunc.hxx" #include "refupdatecontext.hxx" +#include "scopetools.hxx" #include "scitems.hxx" #include @@ -1705,6 +1706,12 @@ void ScTable::SetRelNameDirty() pDocument->SetAutoCalc( bOldAutoCalc ); } +void ScTable::BroadcastRecalcOnRefMove() +{ + sc::AutoCalcSwitch aSwitch(*pDocument, false); + for (SCCOL i = 0; i <= MAXCOL; ++i) + aCol[i].BroadcastRecalcOnRefMove(); +} void ScTable::SetLoadingMedium(bool bLoading) { -- cgit v1.2.3