summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sc/inc/column.hxx2
-rw-r--r--sc/inc/formulacell.hxx3
-rw-r--r--sc/inc/table.hxx6
-rw-r--r--sc/source/core/data/column.cxx8
-rw-r--r--sc/source/core/data/document.cxx30
-rw-r--r--sc/source/core/data/formulacell.cxx36
-rw-r--r--sc/source/core/data/table2.cxx4
7 files changed, 51 insertions, 38 deletions
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index afe9f6abe828..3127cf49334c 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -445,7 +445,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 dbb52e45b107..68c620cd67c8 100644
--- a/sc/inc/formulacell.hxx
+++ b/sc/inc/formulacell.hxx
@@ -121,6 +121,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
{
@@ -371,6 +372,8 @@ public:
SCROW GetSharedLength() const;
ScTokenArray* GetSharedCode();
const ScTokenArray* GetSharedCode() const;
+
+ bool IsPostponedDirty() const;
};
#endif
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 19dbb00d01be..f7d338953e6a 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -882,10 +882,10 @@ public:
void StartNeededListeners();
/**
- * Mark dirty those formula cells that has named ranges with relative
- * references.
+ * Mark formula cells dirty that have the mbPostponedDirty flag set or
+ * contain named ranges with relative references.
*/
- void SetRelNameDirty();
+ void SetDirtyIfPostponed();
/**
* Broadcast dirty formula cells that contain functions such as CELL(),
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index aafb3149abc0..007e9e317cf2 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -2806,11 +2806,11 @@ struct SetDirtyAfterLoadHandler
}
};
-struct SetRelNameDirtyHandler
+struct SetDirtyIfPostponedHandler
{
void operator() (size_t /*nRow*/, ScFormulaCell* pCell)
{
- if (pCell->HasRelNameReference())
+ if (pCell->IsPostponedDirty() || pCell->HasRelNameReference())
pCell->SetDirty();
}
};
@@ -3144,10 +3144,10 @@ public:
}
-void ScColumn::SetRelNameDirty()
+void ScColumn::SetDirtyIfPostponed()
{
sc::AutoCalcSwitch aSwitch(*pDocument, false);
- SetRelNameDirtyHandler aFunc;
+ SetDirtyIfPostponedHandler aFunc;
sc::ProcessFormula(maCells, aFunc);
}
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 4d45f565ffaf..7a4cbf06fa09 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -1167,12 +1167,12 @@ struct StartNeededListenersHandler : std::unary_function<ScTable*, void>
}
};
-struct SetRelNameDirtyHandler : std::unary_function<ScTable*, void>
+struct SetDirtyIfPostponedHandler : std::unary_function<ScTable*, void>
{
void operator() (ScTable* p)
{
if (p)
- p->SetRelNameDirty();
+ p->SetDirtyIfPostponed();
}
};
@@ -1262,12 +1262,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();
std::for_each(maTabs.begin(), maTabs.end(), BroadcastRecalcOnRefMoveHandler());
}
@@ -1357,12 +1358,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();
std::for_each(maTabs.begin(), maTabs.end(), BroadcastRecalcOnRefMoveHandler());
}
@@ -1464,9 +1465,10 @@ bool ScDocument::InsertCol( SCROW nStartRow, SCTAB nStartTab,
{
// 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());
+ // At least all cells using range names pointing relative to the
+ // moved range must be recalculated, and all cells marked postponed
+ // dirty.
+ std::for_each(maTabs.begin(), maTabs.end(), SetDirtyIfPostponedHandler());
// 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());
@@ -1556,12 +1558,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();
std::for_each(maTabs.begin(), maTabs.end(), BroadcastRecalcOnRefMoveHandler());
}
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index 14ccad41bca4..75f01d2e11dd 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -503,6 +503,7 @@ ScFormulaCell::ScFormulaCell( ScDocument* pDoc, const ScAddress& rPos ) :
bTableOpDirty(false),
bNeedListening(false),
mbNeedsNumberFormat(false),
+ mbPostponedDirty(false),
aPos(rPos)
{
}
@@ -531,6 +532,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
@@ -562,6 +564,7 @@ ScFormulaCell::ScFormulaCell(
bTableOpDirty( false ),
bNeedListening( false ),
mbNeedsNumberFormat( false ),
+ mbPostponedDirty(false),
aPos( rPos )
{
assert(pArray); // Never pass a NULL pointer here.
@@ -610,6 +613,7 @@ ScFormulaCell::ScFormulaCell(
bTableOpDirty( false ),
bNeedListening( false ),
mbNeedsNumberFormat( false ),
+ mbPostponedDirty(false),
aPos( rPos )
{
// RPN array generation
@@ -657,6 +661,7 @@ ScFormulaCell::ScFormulaCell(
bTableOpDirty( false ),
bNeedListening( false ),
mbNeedsNumberFormat( false ),
+ mbPostponedDirty(false),
aPos( rPos )
{
if (bSubTotal)
@@ -685,6 +690,7 @@ ScFormulaCell::ScFormulaCell( const ScFormulaCell& rCell, ScDocument& rDoc, cons
bTableOpDirty( false ),
bNeedListening( false ),
mbNeedsNumberFormat( false ),
+ mbPostponedDirty(false),
aPos( rPos )
{
pCode = rCell.pCode->Clone();
@@ -891,7 +897,7 @@ void ScFormulaCell::GetResultDimensions( SCSIZE& rCols, SCSIZE& rRows )
}
bool ScFormulaCell::GetDirty() const { return bDirty; }
-void ScFormulaCell::ResetDirty() { bDirty = false; }
+void ScFormulaCell::ResetDirty() { bDirty = bTableOpDirty = mbPostponedDirty = false; }
bool ScFormulaCell::NeedsListening() const { return bNeedListening; }
void ScFormulaCell::SetNeedsListening( bool bVar ) { bNeedListening = bVar; }
void ScFormulaCell::SetNeedNumberFormat( bool bVal ) { mbNeedsNumberFormat = bVal; }
@@ -1290,8 +1296,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;
}
@@ -1448,8 +1453,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())
@@ -1472,8 +1476,7 @@ void ScFormulaCell::InterpretTail( ScInterpretTailParameter eTailParam )
if (nSeenInIteration > 1 ||
pDocument->GetDocOptions().GetIterCount() == 1)
{
- bDirty = false;
- bTableOpDirty = false;
+ ResetDirty();
}
}
}
@@ -1574,8 +1577,7 @@ void ScFormulaCell::InterpretTail( ScInterpretTailParameter eTailParam )
}
if (eTailParam == SCITP_NORMAL)
{
- bDirty = false;
- bTableOpDirty = false;
+ ResetDirty();
}
if( aResult.GetMatrix() )
{
@@ -1654,8 +1656,7 @@ void ScFormulaCell::InterpretTail( ScInterpretTailParameter eTailParam )
{
// Cells with compiler errors should not be marked dirty forever
OSL_ENSURE( pCode->GetCodeError(), "no RPN code und no errors ?!?!" );
- bDirty = false;
- bTableOpDirty = false;
+ ResetDirty();
}
}
@@ -1757,7 +1758,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();
@@ -1774,6 +1775,7 @@ void ScFormulaCell::SetDirty( bool bDirtyFlag )
void ScFormulaCell::SetDirtyVar()
{
bDirty = true;
+ mbPostponedDirty = false;
if (mxGroup && mxGroup->meCalcState == sc::GroupCalcRunning)
mxGroup->meCalcState = sc::GroupCalcEnabled;
@@ -2566,8 +2568,9 @@ bool ScFormulaCell::UpdateReferenceOnShift(
if (bNeedDirty && !bHasRelName)
{ // Cut off references, invalid or similar?
- sc::AutoCalcSwitch(*pDocument, false);
- SetDirty();
+ // Postpone SetDirty() until all listeners have been re-established in
+ // Inserts/Deletes.
+ mbPostponedDirty = true;
}
return bCellStateChanged;
@@ -3862,4 +3865,9 @@ const ScTokenArray* ScFormulaCell::GetSharedCode() const
return mxGroup ? mxGroup->mpCode : NULL;
}
+bool ScFormulaCell::IsPostponedDirty() const
+{
+ return mbPostponedDirty;
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index 27233f77c94e..f96d913b2cc5 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 );
}