[Libreoffice-commits] core.git: sc/inc sc/source

Eike Rathke erack at redhat.com
Tue Aug 18 05:01:55 PDT 2015


 sc/inc/document.hxx                 |   15 ++++++++++++---
 sc/source/core/data/bcaslot.cxx     |   23 +++++++++++------------
 sc/source/core/data/documen2.cxx    |    2 +-
 sc/source/core/data/documen7.cxx    |    8 ++++----
 sc/source/core/data/document.cxx    |   10 ++++------
 sc/source/core/data/formulacell.cxx |    8 ++++----
 sc/source/core/inc/bcaslot.hxx      |    6 +++---
 sc/source/ui/docshell/docsh.cxx     |   12 +++++++-----
 sc/source/ui/docshell/docsh4.cxx    |    2 +-
 9 files changed, 47 insertions(+), 39 deletions(-)

New commits:
commit 1bea8310747b65516f40f6457ab1d174ef7ddce4
Author: Eike Rathke <erack at redhat.com>
Date:   Tue Aug 18 13:54:32 2015 +0200

    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

diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index aa1664a..a2b7800 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 f9d6a19..6ae65c7 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 bfea26f..a38f712 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 7d0315a..cb3ba05 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 b0b3aa3..976c63a 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 bfda996..2483382 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 e91b067..0b23725 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 2094ac3..c9c6b70 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 585fe94..f2ade2a 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() ) );


More information about the Libreoffice-commits mailing list