[Libreoffice-commits] core.git: Branch 'libreoffice-4-1' - sc/inc sc/source
Kohei Yoshida
kohei.yoshida at gmail.com
Thu Jul 25 10:33:26 PDT 2013
sc/inc/column.hxx | 1 +
sc/inc/table.hxx | 6 ++++++
sc/source/core/data/column.cxx | 21 +++++++++++++++++++++
sc/source/core/data/document.cxx | 28 ++++++++++++++++++++++++++++
sc/source/core/data/table2.cxx | 8 ++++++++
5 files changed, 64 insertions(+)
New commits:
commit 7299db371e38d1a3ecd51eb3811344ee5bb3a086
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date: Thu Jul 25 12:24:01 2013 -0400
Propagate change on COLUMN() and ROW() functions on position change.
1) Insert =COLUMN() or =ROW() in arbitrary cell.
2) Have another cell reference that cell.
3) Insert or delete column or row to change the cell that contains
COLUMN or ROW function. This will change the result of that cell.
4) Check the result of the 2nd cell that references the first. The
value change is not propagated.
This commit fixes that.
NB: master has a similar but different fix. Due to the difference in
cell storage between master and 4.1, I had to devise a different fix
for the 4.1 branch.
Change-Id: Ib1b730e7a4a70a11b967b88730a68362e061a8a0
Reviewed-on: https://gerrit.libreoffice.org/5113
Reviewed-by: Fridrich Strba <fridrich at documentfoundation.org>
Tested-by: Fridrich Strba <fridrich at documentfoundation.org>
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index dfc46b0..935c07e 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -440,6 +440,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 b62fa1e..20b0ed7 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -853,6 +853,12 @@ public:
void DeleteBroadcasters( sc::ColumnBlockPosition& rBlockPos, SCCOL nCol, SCROW nRow1, SCROW nRow2 );
bool HasBroadcaster( SCCOL nCol ) const;
+ /**
+ * Broadcast dirty formula cells that contain functions such as CELL(),
+ * COLUMN() or ROW() which may change its value on move.
+ */
+ void BroadcastRecalcOnRefMove();
+
/** Replace behaves differently to the Search; adjust the rCol and rRow accordingly.
'Replace' replaces at the 'current' position, but in order to achieve
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index 88cb65d..b687489 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -2175,6 +2175,27 @@ void ScColumn::SetRelNameDirty()
pDocument->SetAutoCalc( bOldAutoCalc );
}
+void ScColumn::BroadcastRecalcOnRefMove()
+{
+ bool bOldAutoCalc = pDocument->GetAutoCalc();
+ pDocument->SetAutoCalc( false ); // no multiple recalculation
+
+ ScHint aHint(SC_HINT_DATACHANGED, ScAddress(nCol, 0, nTab));
+ for (SCSIZE i=0; i<maItems.size(); i++)
+ {
+ if (maItems[i].pCell->GetCellType() != CELLTYPE_FORMULA)
+ continue;
+
+ ScFormulaCell* p = static_cast<ScFormulaCell*>(maItems[i].pCell);
+ if (p->GetDirty() && p->GetCode()->IsRecalcModeOnRefMove())
+ {
+ aHint.GetAddress().SetRow(maItems[i].nRow);
+ pDocument->Broadcast(aHint);
+ }
+
+ }
+ pDocument->SetAutoCalc( bOldAutoCalc );
+}
void ScColumn::CalcAll()
{
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 4933e5d..02d6e21 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -1115,6 +1115,18 @@ bool ScDocument::CanInsertRow( const ScRange& rRange ) const
return bTest;
}
+namespace {
+
+struct BroadcastRecalcOnRefMoveHandler : std::unary_function<ScTable*, void>
+{
+ void operator() (ScTable* p)
+ {
+ if (p)
+ p->BroadcastRecalcOnRefMove();
+ }
+};
+
+}
bool ScDocument::InsertRow( SCCOL nStartCol, SCTAB nStartTab,
SCCOL nEndCol, SCTAB nEndTab,
@@ -1194,6 +1206,10 @@ bool ScDocument::InsertRow( SCCOL nStartCol, SCTAB nStartTab,
for (; it != maTabs.end(); ++it)
if (*it)
(*it)->SetRelNameDirty();
+
+ // 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;
}
@@ -1285,6 +1301,10 @@ void ScDocument::DeleteRow( SCCOL nStartCol, SCTAB nStartTab,
for (; it != maTabs.end(); ++it)
if (*it)
(*it)->SetRelNameDirty();
+
+ // 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());
}
SetAutoCalc( bOldAutoCalc );
@@ -1390,6 +1410,10 @@ bool ScDocument::InsertCol( SCROW nStartRow, SCTAB nStartTab,
for (; it != maTabs.end(); ++it)
if (*it)
(*it)->SetRelNameDirty();
+
+ // 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;
}
@@ -1479,6 +1503,10 @@ void ScDocument::DeleteCol(SCROW nStartRow, SCTAB nStartTab, SCROW nEndRow, SCTA
for (; it != maTabs.end(); ++it)
if (*it)
(*it)->SetRelNameDirty();
+
+ // 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());
}
SetAutoCalc( bOldAutoCalc );
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index a44c602..4786d30 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -1664,6 +1664,14 @@ void ScTable::SetRelNameDirty()
pDocument->SetAutoCalc( bOldAutoCalc );
}
+void ScTable::BroadcastRecalcOnRefMove()
+{
+ bool bOldAutoCalc = pDocument->GetAutoCalc();
+ pDocument->SetAutoCalc( false ); // Mehrfachberechnungen vermeiden
+ for (SCCOL i = 0; i <= MAXCOL; ++i)
+ aCol[i].BroadcastRecalcOnRefMove();
+ pDocument->SetAutoCalc( bOldAutoCalc );
+}
void ScTable::SetLoadingMedium(bool bLoading)
{
More information about the Libreoffice-commits
mailing list