summaryrefslogtreecommitdiff
path: root/sc/source/core/data
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@gmail.com>2013-07-23 16:02:37 -0400
committerKohei Yoshida <kohei.yoshida@gmail.com>2013-07-24 23:29:39 -0400
commitab24a2c25900948bb71acbedbdecd84bda3217f7 (patch)
tree229230be711f168dae64b984f915dab4c903cb66 /sc/source/core/data
parenta6b0568eca2b025f556fa4d0b702b67a01262618 (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.cxx30
-rw-r--r--sc/source/core/data/document.cxx50
-rw-r--r--sc/source/core/data/table2.cxx7
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)
{