summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEike Rathke <erack@redhat.com>2014-01-23 22:40:16 +0100
committerMichael Meeks <michael.meeks@collabora.com>2014-01-27 09:41:54 +0000
commitb99a2691484e9b0533530ad4f02e15ad4031b74b (patch)
tree043fc851c3b88eb1546e1a345233c5fc998a3eaf
parent24245120e7d6f4ed2efa33df589daa7d1ea4e1f5 (diff)
resolved fdo#71598 postpone SetDirty during Insert/Delete
... until after all listeners are re-established. (cherry picked from commit 20b7476142f75b49d10a75e48429a94cff0cec32) Conflicts: sc/inc/formulacell.hxx sc/inc/table.hxx sc/source/core/data/column.cxx sc/source/core/data/document.cxx sc/source/core/data/formulacell.cxx Backported. Change-Id: I9f6036d4bcc9206191959a88ed5439b9860ca268 Reviewed-on: https://gerrit.libreoffice.org/7624 Reviewed-by: Michael Meeks <michael.meeks@collabora.com> Tested-by: Michael Meeks <michael.meeks@collabora.com>
-rw-r--r--sc/inc/column.hxx2
-rw-r--r--sc/inc/formulacell.hxx5
-rw-r--r--sc/inc/table.hxx7
-rw-r--r--sc/source/core/data/column.cxx4
-rw-r--r--sc/source/core/data/document.cxx26
-rw-r--r--sc/source/core/data/formulacell.cxx40
-rw-r--r--sc/source/core/data/table2.cxx4
7 files changed, 52 insertions, 36 deletions
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 1dd462d1b7b4..83ccf09589d3 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -446,7 +446,7 @@ public:
void MoveListeners( SvtBroadcaster& rSource, SCROW nDestRow );
void StartAllListeners();
void StartNeededListeners(); // only for cells where NeedsListening()==true
- void SetRelNameDirty();
+ void SetDirtyIfPostponed();
void BroadcastRecalcOnRefMove();
void CompileDBFormula();
diff --git a/sc/inc/formulacell.hxx b/sc/inc/formulacell.hxx
index 747d67f977d6..fd4af058f41d 100644
--- a/sc/inc/formulacell.hxx
+++ b/sc/inc/formulacell.hxx
@@ -90,6 +90,7 @@ private:
bool bTableOpDirty : 1; // Dirty flag for TableOp
bool bNeedListening : 1; // Listeners need to be re-established after UpdateReference
bool mbNeedsNumberFormat : 1; // set the calculated number format as hard number format
+ bool mbPostponedDirty : 1; // if cell needs to be set dirty later
enum ScInterpretTailParameter
{
@@ -149,7 +150,7 @@ public:
void SetTableOpDirty();
bool IsDirtyOrInTableOpDirty() const;
bool GetDirty() const { return bDirty; }
- void ResetDirty() { bDirty = false; }
+ void ResetDirty() { bDirty = bTableOpDirty = mbPostponedDirty = false; }
bool NeedsListening() const { return bNeedListening; }
void SetNeedsListening( bool bVar ) { bNeedListening = bVar; }
void SetNeedNumberFormat( bool bVal ) { mbNeedsNumberFormat = bVal; }
@@ -304,6 +305,8 @@ public:
void EndListeningTo(
ScDocument* pDoc, ScTokenArray* pArr = NULL, ScAddress aPos = ScAddress() );
void EndListeningTo( sc::EndListeningContext& rCxt );
+
+ bool IsPostponedDirty() const { return mbPostponedDirty; }
};
#endif
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 20b0ed7bda67..7f95d7f58bdd 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -854,6 +854,12 @@ public:
bool HasBroadcaster( SCCOL nCol ) const;
/**
+ * Mark formula cells dirty that have the mbPostponedDirty flag set or
+ * contain named ranges with relative references.
+ */
+ void SetDirtyIfPostponed();
+
+ /**
* Broadcast dirty formula cells that contain functions such as CELL(),
* COLUMN() or ROW() which may change its value on move.
*/
@@ -961,7 +967,6 @@ private:
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 305eeb50caaa..984633ce454b 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -2168,14 +2168,14 @@ void ScColumn::SetDirtyAfterLoad()
}
-void ScColumn::SetRelNameDirty()
+void ScColumn::SetDirtyIfPostponed()
{
bool bOldAutoCalc = pDocument->GetAutoCalc();
pDocument->SetAutoCalc( false ); // no multiple recalculation
for (SCSIZE i=0; i<maItems.size(); i++)
{
ScFormulaCell* p = (ScFormulaCell*) maItems[i].pCell;
- if( p->GetCellType() == CELLTYPE_FORMULA && p->HasRelNameReference() )
+ if( p->GetCellType() == CELLTYPE_FORMULA && (p->IsPostponedDirty() || p->HasRelNameReference()) )
p->SetDirty();
}
pDocument->SetAutoCalc( bOldAutoCalc );
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 02d6e21e35bc..6369388f159b 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -1200,12 +1200,13 @@ bool ScDocument::InsertRow( SCCOL nStartCol, SCTAB nStartTab,
for (; it != maTabs.end(); ++it)
if (*it)
(*it)->StartNeededListeners();
- // at least all cells using range names pointing relative
- // to the moved range must recalculate
+ // At least all cells using range names pointing relative to the
+ // moved range must be recalculated, and all cells marked postponed
+ // dirty.
it = maTabs.begin();
for (; it != maTabs.end(); ++it)
if (*it)
- (*it)->SetRelNameDirty();
+ (*it)->SetDirtyIfPostponed();
// Cells containing functions such as CELL, COLUMN or ROW may have
// changed their values on relocation. Broadcast them.
@@ -1295,12 +1296,12 @@ void ScDocument::DeleteRow( SCCOL nStartCol, SCTAB nStartTab,
for (; it != maTabs.end(); ++it)
if (*it)
(*it)->StartNeededListeners();
- // at least all cells using range names pointing relative
- // to the moved range must recalculate
+ // At least all cells using range names pointing relative to the moved
+ // range must be recalculated, and all cells marked postponed dirty.
it = maTabs.begin();
for (; it != maTabs.end(); ++it)
if (*it)
- (*it)->SetRelNameDirty();
+ (*it)->SetDirtyIfPostponed();
// Cells containing functions such as CELL, COLUMN or ROW may have
// changed their values on relocation. Broadcast them.
@@ -1404,12 +1405,13 @@ bool ScDocument::InsertCol( SCROW nStartRow, SCTAB nStartTab,
for (; it != maTabs.end(); ++it)
if (*it)
(*it)->StartNeededListeners();
- // at least all cells using range names pointing relative
- // to the moved range must recalculate
+ // At least all cells using range names pointing relative to the
+ // moved range must be recalculated, and all cells marked postponed
+ // dirty.
it = maTabs.begin();
for (; it != maTabs.end(); ++it)
if (*it)
- (*it)->SetRelNameDirty();
+ (*it)->SetDirtyIfPostponed();
// Cells containing functions such as CELL, COLUMN or ROW may have
// changed their values on relocation. Broadcast them.
@@ -1497,12 +1499,12 @@ void ScDocument::DeleteCol(SCROW nStartRow, SCTAB nStartTab, SCROW nEndRow, SCTA
for (; it != maTabs.end(); ++it)
if (*it)
(*it)->StartNeededListeners();
- // at least all cells using range names pointing relative
- // to the moved range must recalculate
+ // At least all cells using range names pointing relative to the moved
+ // range must be recalculated, and all cells marked postponed dirty.
it = maTabs.begin();
for (; it != maTabs.end(); ++it)
if (*it)
- (*it)->SetRelNameDirty();
+ (*it)->SetDirtyIfPostponed();
// Cells containing functions such as CELL, COLUMN or ROW may have
// changed their values on relocation. Broadcast them.
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index b75bdcc08f06..5ebf9b337fbc 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -414,6 +414,7 @@ ScFormulaCell::ScFormulaCell( ScDocument* pDoc, const ScAddress& rPos,
bTableOpDirty( false ),
bNeedListening( false ),
mbNeedsNumberFormat( false ),
+ mbPostponedDirty(false),
aPos( rPos )
{
Compile( rFormula, true, eGrammar ); // bNoListening, Insert does that
@@ -448,6 +449,7 @@ ScFormulaCell::ScFormulaCell( ScDocument* pDoc, const ScAddress& rPos,
bTableOpDirty( false ),
bNeedListening( false ),
mbNeedsNumberFormat( false ),
+ mbPostponedDirty(false),
aPos( rPos )
{
// UPN-Array generation
@@ -494,6 +496,7 @@ ScFormulaCell::ScFormulaCell( const ScFormulaCell& rCell, ScDocument& rDoc, cons
bTableOpDirty( false ),
bNeedListening( false ),
mbNeedsNumberFormat( false ),
+ mbPostponedDirty(false),
aPos( rPos )
{
pCode = rCell.pCode->Clone();
@@ -1094,8 +1097,7 @@ void ScFormulaCell::Interpret()
// If one cell didn't converge, all cells of this
// circular dependency don't, no matter whether
// single cells did.
- pIterCell->bDirty = false;
- pIterCell->bTableOpDirty = false;
+ pIterCell->ResetDirty();
pIterCell->aResult.SetResultError( errNoConvergence);
pIterCell->bChanged = true;
pDocument->SetTextWidth(pIterCell->aPos, TEXTWIDTH_DIRTY);
@@ -1251,8 +1253,7 @@ void ScFormulaCell::InterpretTail( ScInterpretTailParameter eTailParam )
if( p->GetError() && p->GetError() != errCircularReference)
{
- bDirty = false;
- bTableOpDirty = false;
+ ResetDirty();
bChanged = true;
}
if (eTailParam == SCITP_FROM_ITERATION && IsDirtyOrInTableOpDirty())
@@ -1275,8 +1276,7 @@ void ScFormulaCell::InterpretTail( ScInterpretTailParameter eTailParam )
if (nSeenInIteration > 1 ||
pDocument->GetDocOptions().GetIterCount() == 1)
{
- bDirty = false;
- bTableOpDirty = false;
+ ResetDirty();
}
}
}
@@ -1377,8 +1377,7 @@ void ScFormulaCell::InterpretTail( ScInterpretTailParameter eTailParam )
}
if (eTailParam == SCITP_NORMAL)
{
- bDirty = false;
- bTableOpDirty = false;
+ ResetDirty();
}
if( aResult.GetMatrix() )
{
@@ -1460,9 +1459,8 @@ void ScFormulaCell::InterpretTail( ScInterpretTailParameter eTailParam )
else
{
// Cells with compiler errors should not be marked dirty forever
- OSL_ENSURE( pCode->GetCodeError(), "no UPN-Code und no errors ?!?!" );
- bDirty = false;
- bTableOpDirty = false;
+ OSL_ENSURE( pCode->GetCodeError(), "no RPN code und no errors ?!?!" );
+ ResetDirty();
}
}
@@ -1546,7 +1544,7 @@ void ScFormulaCell::SetDirty( bool bDirtyFlag )
// by Scenario and Copy Block From Clip.
// If unconditional required Formula tracking is set before SetDirty
// bDirty = false, eg in CompileTokenArray
- if ( !bDirty || !pDocument->IsInFormulaTree( this ) )
+ if ( !bDirty || mbPostponedDirty || !pDocument->IsInFormulaTree( this ) )
{
if( bDirtyFlag )
SetDirtyVar();
@@ -1563,6 +1561,7 @@ void ScFormulaCell::SetDirty( bool bDirtyFlag )
void ScFormulaCell::SetDirtyVar()
{
bDirty = true;
+ mbPostponedDirty = false;
// mark the sheet of this cell to be calculated
//#FIXME do we need to revert this remnant of old fake vba events? pDocument->AddCalculateTable( aPos.Tab() );
}
@@ -2293,11 +2292,18 @@ bool ScFormulaCell::UpdateReference(UpdateRefMode eUpdateRefMode,
}
if ( bNeedDirty && (!(eUpdateRefMode == URM_INSDEL && bHasRelName) || pRangeData) )
{ // Cut off references, invalid or similar?
- bool bOldAutoCalc = pDocument->GetAutoCalc();
- // No Interpret in SubMinimalRecalc because of eventual wrong reference
- pDocument->SetAutoCalc( false );
- SetDirty();
- pDocument->SetAutoCalc( bOldAutoCalc );
+ if (eUpdateRefMode == URM_INSDEL)
+ {
+ mbPostponedDirty = true;
+ }
+ else
+ {
+ bool bOldAutoCalc = pDocument->GetAutoCalc();
+ // No Interpret in SubMinimalRecalc because of eventual wrong reference
+ pDocument->SetAutoCalc( false );
+ SetDirty();
+ pDocument->SetAutoCalc( bOldAutoCalc );
+ }
}
delete pOld;
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index 6c530d350e1a..821ab9261c76 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -1670,12 +1670,12 @@ void ScTable::SetDirtyAfterLoad()
}
-void ScTable::SetRelNameDirty()
+void ScTable::SetDirtyIfPostponed()
{
bool bOldAutoCalc = pDocument->GetAutoCalc();
pDocument->SetAutoCalc( false ); // Mehrfachberechnungen vermeiden
for (SCCOL i=0; i<=MAXCOL; i++)
- aCol[i].SetRelNameDirty();
+ aCol[i].SetDirtyIfPostponed();
pDocument->SetAutoCalc( bOldAutoCalc );
}