diff options
author | Kohei Yoshida <kohei.yoshida@gmail.com> | 2013-07-23 16:02:37 -0400 |
---|---|---|
committer | Kohei Yoshida <kohei.yoshida@gmail.com> | 2013-07-24 23:29:39 -0400 |
commit | ab24a2c25900948bb71acbedbdecd84bda3217f7 (patch) | |
tree | 229230be711f168dae64b984f915dab4c903cb66 /sc/source/core/data | |
parent | a6b0568eca2b025f556fa4d0b702b67a01262618 (diff) |
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
Diffstat (limited to 'sc/source/core/data')
-rw-r--r-- | sc/source/core/data/column.cxx | 30 | ||||
-rw-r--r-- | sc/source/core/data/document.cxx | 50 | ||||
-rw-r--r-- | sc/source/core/data/table2.cxx | 7 |
3 files changed, 75 insertions, 12 deletions
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<SCROW> maDirtyRows; +public: + void operator() (size_t nRow, ScFormulaCell* pCell) + { + if (pCell->GetDirty() && pCell->GetCode()->IsRecalcModeOnRefMove()) + maDirtyRows.push_back(nRow); + } + + const std::vector<SCROW>& 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<ScTable*, void> +{ + void operator() (ScTable* p) + { + if (p) + p->StartNeededListeners(); + } +}; + +struct SetRelNameDirtyHandler : std::unary_function<ScTable*, void> +{ + void operator() (ScTable* p) + { + if (p) + p->SetRelNameDirty(); + } +}; + +struct BroadcastRecalcOnRefMoveHandler : std::unary_function<ScTable*, void> +{ + 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 <editeng/boxitem.hxx> @@ -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) { |