[Libreoffice-commits] core.git: Branch 'feature/formula-core-rework' - sc/inc sc/source
Kohei Yoshida
kohei.yoshida at gmail.com
Tue Jul 23 13:06:33 PDT 2013
sc/inc/column.hxx | 1
sc/inc/table.hxx | 20 ++++++++++++++-
sc/source/core/data/column.cxx | 30 ++++++++++++++++++++++-
sc/source/core/data/document.cxx | 50 ++++++++++++++++++++++++++++++---------
sc/source/core/data/table2.cxx | 7 +++++
5 files changed, 94 insertions(+), 14 deletions(-)
New commits:
commit fd340291c4ef579ee42850f9b7842d6afe98877d
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Tue Jul 23 16:02:37 2013 -0400
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
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 00b2a63..5ef6cce 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -431,6 +431,7 @@ public:
void StartAllListeners();
void StartNeededListeners(); // only for cells where NeedsListening()==true
void SetRelNameDirty();
+ void BroadcastRecalcOnRefMove();
void CompileDBFormula();
void CompileDBFormula( bool bCreateFormulaString );
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 0e4305a..00cc7e5 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -862,6 +862,24 @@ public:
void SetFormulaResults( SCCOL nCol, SCROW nRow, const double* pResults, size_t nLen );
+ /**
+ * Have formula cells with NeedsListening() == true start listening to the
+ * document.
+ */
+ void StartNeededListeners();
+
+ /**
+ * Mark dirty those formula cells that has named ranges with relative
+ * references.
+ */
+ void SetRelNameDirty();
+
+ /**
+ * Broadcast dirty formula cells that contain functions such as CELL(),
+ * COLUMN() or ROW() which may change its value on move.
+ */
+ void BroadcastRecalcOnRefMove();
+
#if DEBUG_COLUMN_STORAGE
void DumpFormulaGroups( SCCOL nCol ) const;
#endif
@@ -968,8 +986,6 @@ private:
void StartListening( sc::StartListeningContext& rCxt, SCCOL nCol, SCROW nRow, SvtListener& rListener );
void EndListening( sc::EndListeningContext& rCxt, SCCOL nCol, SCROW nRow, SvtListener& rListener );
void StartAllListeners();
- void StartNeededListeners(); // only for cells where NeedsListening()==TRUE
- void SetRelNameDirty();
void SetLoadingMedium(bool bLoading);
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index 23a740f..da3cb49 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 dfc17cf..9cba374 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 96839f1..5bbb6d3 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)
{
More information about the Libreoffice-commits
mailing list