diff options
author | Eike Rathke <erack@redhat.com> | 2015-08-18 13:54:32 +0200 |
---|---|---|
committer | Eike Rathke <erack@redhat.com> | 2015-08-18 14:01:10 +0200 |
commit | 1bea8310747b65516f40f6457ab1d174ef7ddce4 (patch) | |
tree | a9d20d33222ad140a82a04f224a5e21c3429d3af | |
parent | ba5fd0cc77d7d53004f46e4ca867a22d56c5baa7 (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.hxx | 15 | ||||
-rw-r--r-- | sc/source/core/data/bcaslot.cxx | 23 | ||||
-rw-r--r-- | sc/source/core/data/documen2.cxx | 2 | ||||
-rw-r--r-- | sc/source/core/data/documen7.cxx | 8 | ||||
-rw-r--r-- | sc/source/core/data/document.cxx | 10 | ||||
-rw-r--r-- | sc/source/core/data/formulacell.cxx | 8 | ||||
-rw-r--r-- | sc/source/core/inc/bcaslot.hxx | 6 | ||||
-rw-r--r-- | sc/source/ui/docshell/docsh.cxx | 12 | ||||
-rw-r--r-- | sc/source/ui/docshell/docsh4.cxx | 2 |
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() ) ); |