summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEike Rathke <erack@redhat.com>2015-08-18 13:54:32 +0200
committerEike Rathke <erack@redhat.com>2015-08-18 14:01:10 +0200
commit1bea8310747b65516f40f6457ab1d174ef7ddce4 (patch)
treea9d20d33222ad140a82a04f224a5e21c3429d3af
parentba5fd0cc77d7d53004f46e4ca867a22d56c5baa7 (diff)
introduce temporary hard-recalc state, tdf#92749 follow-up
This allows listeners to be setup and initial lookup caches to be kept, which were thrown away after the initial calculation as an interim fix for tdf#92749. Change-Id: I34068b3f6b833a46f3c526579efbdc342a2e71df
-rw-r--r--sc/inc/document.hxx15
-rw-r--r--sc/source/core/data/bcaslot.cxx23
-rw-r--r--sc/source/core/data/documen2.cxx2
-rw-r--r--sc/source/core/data/documen7.cxx8
-rw-r--r--sc/source/core/data/document.cxx10
-rw-r--r--sc/source/core/data/formulacell.cxx8
-rw-r--r--sc/source/core/inc/bcaslot.hxx6
-rw-r--r--sc/source/ui/docshell/docsh.cxx12
-rw-r--r--sc/source/ui/docshell/docsh4.cxx2
9 files changed, 47 insertions, 39 deletions
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index aa1664a2c0b3..a2b78006d142 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -275,6 +275,15 @@ friend class sc::EditTextIterator;
friend class sc::FormulaGroupAreaListener;
typedef ::std::vector<ScTable*> TableContainer;
+
+public:
+ enum HardRecalcState
+ {
+ HARDRECALCSTATE_OFF = 0, /// normal calculation of dependencies
+ HARDRECALCSTATE_TEMPORARY, /// CalcAll() without broadcast/notify but setting up new listeners
+ HARDRECALCSTATE_ETERNAL /// no new listeners are setup, no broadcast/notify
+ };
+
private:
rtl::Reference<ScPoolHelper> xPoolHelper;
@@ -391,7 +400,7 @@ private:
sal_uInt16 nSrcVer; // file version (load/save)
SCROW nSrcMaxRow; // number of lines to load/save
sal_uInt16 nFormulaTrackCount;
- bool bHardRecalcState; // false: soft, true: hard
+ HardRecalcState eHardRecalcState; // off, temporary, eternal
SCTAB nVisibleTab; // for OLE etc., don't use inside ScDocument
ScLkUpdMode eLinkMode;
@@ -1949,8 +1958,8 @@ public:
void TrackFormulas( sal_uLong nHintId = SC_HINT_DATACHANGED );
bool IsInFormulaTree( ScFormulaCell* pCell ) const;
bool IsInFormulaTrack( ScFormulaCell* pCell ) const;
- bool GetHardRecalcState() { return bHardRecalcState; }
- void SetHardRecalcState( bool bVal ) { bHardRecalcState = bVal; }
+ HardRecalcState GetHardRecalcState() { return eHardRecalcState; }
+ void SetHardRecalcState( HardRecalcState eVal ) { eHardRecalcState = eVal; }
void StartAllListeners();
void StartNeededListeners();
void StartAllListeners( const ScRange& rRange );
diff --git a/sc/source/core/data/bcaslot.cxx b/sc/source/core/data/bcaslot.cxx
index f9d6a19518e8..6ae65c7d20e4 100644
--- a/sc/source/core/data/bcaslot.cxx
+++ b/sc/source/core/data/bcaslot.cxx
@@ -166,14 +166,13 @@ ScBroadcastAreaSlot::~ScBroadcastAreaSlot()
}
}
-bool ScBroadcastAreaSlot::CheckHardRecalcStateCondition() const
+ScDocument::HardRecalcState ScBroadcastAreaSlot::CheckHardRecalcStateCondition() const
{
- if ( pDoc->GetHardRecalcState() )
- return true;
- if (aBroadcastAreaTbl.size() >= aBroadcastAreaTbl.max_size())
- { // this is more hypothetical now, check existed for old SV_PTRARR_SORT
- if ( !pDoc->GetHardRecalcState() )
- {
+ ScDocument::HardRecalcState eState = pDoc->GetHardRecalcState();
+ if (eState == ScDocument::HARDRECALCSTATE_OFF)
+ {
+ if (aBroadcastAreaTbl.size() >= aBroadcastAreaTbl.max_size())
+ { // this is more hypothetical now, check existed for old SV_PTRARR_SORT
SfxObjectShell* pShell = pDoc->GetDocumentShell();
OSL_ENSURE( pShell, "Missing DocShell :-/" );
@@ -181,11 +180,11 @@ bool ScBroadcastAreaSlot::CheckHardRecalcStateCondition() const
pShell->SetError( SCWARN_CORE_HARD_RECALC, OUString( OSL_LOG_PREFIX ) );
pDoc->SetAutoCalc( false );
- pDoc->SetHardRecalcState( true );
+ eState = ScDocument::HARDRECALCSTATE_ETERNAL;
+ pDoc->SetHardRecalcState( eState );
}
- return true;
}
- return false;
+ return eState;
}
bool ScBroadcastAreaSlot::StartListeningArea(
@@ -193,7 +192,7 @@ bool ScBroadcastAreaSlot::StartListeningArea(
{
bool bNewArea = false;
OSL_ENSURE(pListener, "StartListeningArea: pListener Null");
- if (CheckHardRecalcStateCondition())
+ if (CheckHardRecalcStateCondition() == ScDocument::HARDRECALCSTATE_ETERNAL)
return false;
if ( !rpArea )
{
@@ -234,7 +233,7 @@ bool ScBroadcastAreaSlot::StartListeningArea(
void ScBroadcastAreaSlot::InsertListeningArea( ScBroadcastArea* pArea )
{
OSL_ENSURE( pArea, "InsertListeningArea: pArea NULL");
- if (CheckHardRecalcStateCondition())
+ if (CheckHardRecalcStateCondition() == ScDocument::HARDRECALCSTATE_ETERNAL)
return;
if (aBroadcastAreaTbl.insert( pArea).second)
pArea->IncRef();
diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx
index bfea26f843bc..a38f7121bb86 100644
--- a/sc/source/core/data/documen2.cxx
+++ b/sc/source/core/data/documen2.cxx
@@ -179,7 +179,7 @@ ScDocument::ScDocument( ScDocumentMode eMode, SfxObjectShell* pDocShell ) :
nSrcVer( SC_CURRENT_VERSION ),
nSrcMaxRow( MAXROW ),
nFormulaTrackCount(0),
- bHardRecalcState(false),
+ eHardRecalcState(HARDRECALCSTATE_OFF),
nVisibleTab( 0 ),
eLinkMode(LM_UNKNOWN),
bAutoCalc( eMode == SCDOCMODE_DOCUMENT ),
diff --git a/sc/source/core/data/documen7.cxx b/sc/source/core/data/documen7.cxx
index 7d0315a9ff5e..cb3ba0536111 100644
--- a/sc/source/core/data/documen7.cxx
+++ b/sc/source/core/data/documen7.cxx
@@ -62,7 +62,7 @@ void ScDocument::Broadcast( const ScHint& rHint )
{
if ( !pBASM )
return ; // Clipboard or Undo
- if ( !bHardRecalcState )
+ if ( eHardRecalcState == HARDRECALCSTATE_OFF )
{
ScBulkBroadcast aBulkBroadcast( pBASM); // scoped bulk broadcast
bool bIsBroadcasted = false;
@@ -110,7 +110,7 @@ void ScDocument::BroadcastCells( const ScRange& rRange, sal_uLong nHint, bool bB
SCCOL nCol1 = rRange.aStart.Col();
SCCOL nCol2 = rRange.aEnd.Col();
- if (!bHardRecalcState)
+ if (eHardRecalcState == HARDRECALCSTATE_OFF)
{
ScBulkBroadcast aBulkBroadcast( pBASM); // scoped bulk broadcast
bool bIsBroadcasted = false;
@@ -260,7 +260,7 @@ void ScDocument::AreaBroadcast( const ScHint& rHint )
{
if ( !pBASM )
return ; // Clipboard or Undo
- if ( !bHardRecalcState )
+ if (eHardRecalcState == HARDRECALCSTATE_OFF)
{
ScBulkBroadcast aBulkBroadcast( pBASM); // scoped bulk broadcast
if ( pBASM->AreaBroadcast( rHint ) )
@@ -418,7 +418,7 @@ void ScDocument::CalcFormulaTree( bool bOnlyForced, bool bProgressBar, bool bSet
//ATTENTION: _not_ SetAutoCalc( true ) because this might call CalcFormulaTree( true )
//ATTENTION: if it was disabled before and bHasForcedFormulas is set
bAutoCalc = true;
- if ( bHardRecalcState )
+ if (eHardRecalcState != HARDRECALCSTATE_OFF)
CalcAll();
else
{
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index b0b3aa3db2a8..976c63ab2381 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -3781,12 +3781,10 @@ void ScDocument::CalcAll()
(*it)->CalcAll();
ClearFormulaTree();
- // In hard recalc state caches were not added as listeners, invalidate them
- // so the next non-CalcAll() normal lookup will not be presented with
- // outdated data.
- /* TODO: come up with more detailed hard recalc states so we can
- * differentiate between hard recalc after load and others. */
- if (GetHardRecalcState())
+ // In eternal hard recalc state caches were not added as listeners,
+ // invalidate them so the next non-CalcAll() normal lookup will not be
+ // presented with outdated data.
+ if (GetHardRecalcState() == HARDRECALCSTATE_ETERNAL)
ClearLookupCaches();
}
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index bfda996c3715..2483382ac26d 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -2228,7 +2228,7 @@ void ScFormulaCell::Notify( const SfxHint& rHint )
return;
}
- if ( !pDocument->IsInDtorClear() && !pDocument->GetHardRecalcState() )
+ if ( !pDocument->IsInDtorClear() && pDocument->GetHardRecalcState() == ScDocument::HARDRECALCSTATE_OFF )
{
if (nHint & (SC_HINT_DATACHANGED | SC_HINT_TABLEOPDIRTY))
{
@@ -2285,7 +2285,7 @@ void ScFormulaCell::SetDirty( bool bDirtyFlag )
if (IsInChangeTrack())
return;
- if ( pDocument->GetHardRecalcState() )
+ if ( pDocument->GetHardRecalcState() != ScDocument::HARDRECALCSTATE_OFF )
{
SetDirtyVar();
pDocument->SetStreamValid(aPos.Tab(), false);
@@ -2328,7 +2328,7 @@ void ScFormulaCell::SetDirtyVar()
void ScFormulaCell::SetDirtyAfterLoad()
{
bDirty = true;
- if ( !pDocument->GetHardRecalcState() )
+ if ( pDocument->GetHardRecalcState() == ScDocument::HARDRECALCSTATE_OFF )
pDocument->PutInFormulaTree( this );
}
@@ -2341,7 +2341,7 @@ void ScFormulaCell::SetTableOpDirty()
{
if ( !IsInChangeTrack() )
{
- if ( pDocument->GetHardRecalcState() )
+ if ( pDocument->GetHardRecalcState() != ScDocument::HARDRECALCSTATE_OFF )
bTableOpDirty = true;
else
{
diff --git a/sc/source/core/inc/bcaslot.hxx b/sc/source/core/inc/bcaslot.hxx
index e91b067020f5..0b23725b6e22 100644
--- a/sc/source/core/inc/bcaslot.hxx
+++ b/sc/source/core/inc/bcaslot.hxx
@@ -165,10 +165,10 @@ private:
whether there would be an overflow when adding an area, setting the
proper state if so.
- @return true if a HardRecalcState is effective and area is not to be
- added.
+ @return HARDRECALCSTATE_ETERNAL if a HardRecalcState is effective and
+ area is not to be added.
*/
- bool CheckHardRecalcStateCondition() const;
+ ScDocument::HardRecalcState CheckHardRecalcStateCondition() const;
/** Finally erase all areas pushed as to-be-erased. */
void FinallyEraseAreas();
diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx
index 2094ac3ab721..c9c6b7029f53 100644
--- a/sc/source/ui/docshell/docsh.cxx
+++ b/sc/source/ui/docshell/docsh.cxx
@@ -362,13 +362,15 @@ void ScDocShell::AfterXMLLoading(bool bRet)
if (pModificator)
{
- bool bRecalcState = aDocument.GetHardRecalcState();
- //temporarily set hard-recalc to prevent calling ScFormulaCell::Notify()
- //which will set the cells dirty.
- aDocument.SetHardRecalcState(true);
+ ScDocument::HardRecalcState eRecalcState = aDocument.GetHardRecalcState();
+ // Temporarily set hard-recalc to prevent calling
+ // ScFormulaCell::Notify() during destruction of the Modificator which
+ // will set the cells dirty.
+ if (eRecalcState == ScDocument::HARDRECALCSTATE_OFF)
+ aDocument.SetHardRecalcState(ScDocument::HARDRECALCSTATE_TEMPORARY);
delete pModificator;
- aDocument.SetHardRecalcState(bRecalcState);
pModificator = NULL;
+ aDocument.SetHardRecalcState(eRecalcState);
}
else
{
diff --git a/sc/source/ui/docshell/docsh4.cxx b/sc/source/ui/docshell/docsh4.cxx
index 585fe94bc502..f2ade2a7072c 100644
--- a/sc/source/ui/docshell/docsh4.cxx
+++ b/sc/source/ui/docshell/docsh4.cxx
@@ -1786,7 +1786,7 @@ void ScDocShell::GetState( SfxItemSet &rSet )
switch (nWhich)
{
case FID_AUTO_CALC:
- if ( aDocument.GetHardRecalcState() )
+ if ( aDocument.GetHardRecalcState() != ScDocument::HARDRECALCSTATE_OFF )
rSet.DisableItem( nWhich );
else
rSet.Put( SfxBoolItem( nWhich, aDocument.GetAutoCalc() ) );