[PATCH] fdo#38837: Timers must end eventually [Writer idle timer]

pkoroau pkoroau pkoroau at gmail.com
Fri Dec 14 14:27:39 PST 2012


2012/12/12 Caolán McNamara <caolanm at redhat.com>:
> Could you submit a new patch with the fixups ?
>
> C.
Sure! Thank you for the review.

pkoroau
--
-------------- next part --------------
diff --git a/sw/inc/IDocumentTimerAccess.hxx b/sw/inc/IDocumentTimerAccess.hxx
index 84e3cd4..458ad79 100644
--- a/sw/inc/IDocumentTimerAccess.hxx
+++ b/sw/inc/IDocumentTimerAccess.hxx
@@ -20,31 +20,41 @@
  #ifndef IDOCUMENTTIMERACCESS_HXX_INCLUDED
  #define IDOCUMENTTIMERACCESS_HXX_INCLUDED
 
- /** Get information about the current document state
+ /** Manipulate background jobs of the document. It starts with a mode of
+ 'started' and a block count of 0.
  */
  class IDocumentTimerAccess
  {
  public:
     /**
-    Set modus to start, i.e. start timer if block count == 0
+    Set modus to 'start'.
     */
     virtual void StartIdling() = 0;
 
     /**
-    Set modus to stopped, i.e. stop timer if running
+    Set mode to 'stopped'.
     */
     virtual void StopIdling() = 0;
 
     /**
-    Increment block count, stop timer if running
+    Increment block count.
     */
     virtual void BlockIdling() = 0;
 
     /**
-    Decrement block count, start timer if block count == 0 AND modus == start
+    Decrement block count.
     */
     virtual void UnblockIdling() = 0;
 
+    /**
+    Do these jobs asynchronously: do grammar checking,
+    do layout, and update fields.
+    They will be delayed until mode is start AND block count == 0.
+    The implementation might delay them further, for example
+    it might wait until the application is idle.
+    */
+    virtual void StartBackgroundJobs() = 0;
+
  protected:
     virtual ~IDocumentTimerAccess() {};
  };
diff --git a/sw/inc/doc.hxx b/sw/inc/doc.hxx
index ae910d8..51d669c 100644
--- a/sw/inc/doc.hxx
+++ b/sw/inc/doc.hxx
@@ -972,6 +972,7 @@ public:
     virtual void StopIdling();
     virtual void BlockIdling();
     virtual void UnblockIdling();
+    virtual void StartBackgroundJobs();
 
     /** IDocumentChartDataProviderAccess
     */
diff --git a/sw/source/core/doc/docfld.cxx b/sw/source/core/doc/docfld.cxx
index 18953ad..7f6e6ac 100644
--- a/sw/source/core/doc/docfld.cxx
+++ b/sw/source/core/doc/docfld.cxx
@@ -2564,8 +2564,8 @@ void SwDocUpdtFld::RemoveFldType( const SwFieldType& rType )
     }
 }
 
-SwDocUpdtFld::SwDocUpdtFld()
-    : pFldSortLst(0), nFldLstGetMode(0)
+SwDocUpdtFld::SwDocUpdtFld(SwDoc* pDoc)
+    : pFldSortLst(0), nFldLstGetMode(0), pDocument(pDoc)
 {
     bInUpdateFlds = bFldsDirty = sal_False;
     memset( aFldTypeTable, 0, sizeof( aFldTypeTable ) );
diff --git a/sw/source/core/doc/doclay.cxx b/sw/source/core/doc/doclay.cxx
index 06b10d5..c4079c5 100644
--- a/sw/source/core/doc/doclay.cxx
+++ b/sw/source/core/doc/doclay.cxx
@@ -1826,6 +1826,11 @@ void SwDoc::UnblockIdling()
         aIdleTimer.Start();
 }
 
+void SwDoc::StartBackgroundJobs() {
+    // Trigger DoIdleJobs(), asynchronously.
+    aIdleTimer.Start();
+}
+
 /*************************************************************************
 |*
 |*  SwDoc::DoIdleJobs()
@@ -1846,11 +1851,10 @@ IMPL_LINK( SwDoc, DoIdleJobs, Timer *, pTimer )
         ViewShell *pSh, *pStartSh;
         pSh = pStartSh = GetCurrentViewShell();
         do {
             if( pSh->ActionPend() )
             {
-                if( pTimer )
-                    pTimer->Start();
+                pTimer->Start();
                 return 0;
             }
             pSh = (ViewShell*)pSh->GetNext();
         } while( pSh != pStartSh );
@@ -1865,28 +1869,35 @@ IMPL_LINK( SwDoc, DoIdleJobs, Timer *, pTimer )
             if (bIsOnlineSpell && bIsAutoGrammar)
                 StartGrammarChecking( *this );
         }
-        SwFldUpdateFlags nFldUpdFlag;
         std::set<SwRootFrm*> aAllLayouts = GetAllLayouts();//swmod 080320
         std::set<SwRootFrm*>::iterator pLayIter = aAllLayouts.begin();
         for ( ;pLayIter != aAllLayouts.end();++pLayIter )
         {
             if ((*pLayIter)->IsIdleFormat())
             {
                 (*pLayIter)->GetCurrShell()->LayoutIdle();
-                break;
+
+                // Defer the remaining work.
+                pTimer->Start();
+                return 0;
             }
         }
-        bool bAllValid = pLayIter == aAllLayouts.end() ? 1 : 0;
-        if( bAllValid && ( AUTOUPD_FIELD_ONLY ==
-                 ( nFldUpdFlag = getFieldUpdateFlags(true) )
+
+        SwFldUpdateFlags nFldUpdFlag = getFieldUpdateFlags(true);
+        if( ( AUTOUPD_FIELD_ONLY == nFldUpdFlag
                     || AUTOUPD_FIELD_AND_CHARTS == nFldUpdFlag ) &&
-                GetUpdtFlds().IsFieldsDirty() &&
-                !GetUpdtFlds().IsInUpdateFlds() &&
-                !IsExpFldsLocked()
+                GetUpdtFlds().IsFieldsDirty()
                 // If we switch the field name the Fields are not updated.
                 // So the "backgorund update" should always be carried out
                 /* && !pStartSh->GetViewOptions()->IsFldName()*/ )
         {
+            if ( GetUpdtFlds().IsInUpdateFlds() ||
+                 IsExpFldsLocked() )
+            {
+                pTimer->Start();
+                return 0;
+            }
+
             //  Action brackets!
             GetUpdtFlds().SetInUpdateFlds( true );
 
@@ -1912,9 +1923,7 @@ IMPL_LINK( SwDoc, DoIdleJobs, Timer *, pTimer )
 #ifdef TIMELOG
     if( pModLogFile && 1 != (long)pModLogFile )
         delete pModLogFile, ((long&)pModLogFile) = 1;
 #endif
-    if( pTimer )
-        pTimer->Start();
     return 0;
 }
 
diff --git a/sw/source/core/doc/docnew.cxx b/sw/source/core/doc/docnew.cxx
index f2ac06e..0519309 100644
--- a/sw/source/core/doc/docnew.cxx
+++ b/sw/source/core/doc/docnew.cxx
@@ -220,7 +220,7 @@ SwDoc::SwDoc()
     pDefTOXBases( new SwDefTOXBase_Impl() ),
     pCurrentView( 0 ),  //swmod 071225
     pDrawModel( 0 ),
-    pUpdtFlds( new SwDocUpdtFld() ),
+    pUpdtFlds( new SwDocUpdtFld( this ) ),
     pFldTypes( new SwFldTypes() ),
     pVirDev( 0 ),
     pPrt( 0 ),
diff --git a/sw/source/core/inc/docfld.hxx b/sw/source/core/inc/docfld.hxx
index 4ded5cc..a823c55 100644
--- a/sw/source/core/inc/docfld.hxx
+++ b/sw/source/core/inc/docfld.hxx
@@ -30,6 +30,7 @@
 #define _DOCFLD_HXX
 
 #include <calc.hxx>
+#include <doc.hxx>
 #include <o3tl/sorted_vector.hxx>
 
 class SwTxtFld;
@@ -155,6 +156,7 @@ class SwDocUpdtFld
 
     sal_uLong nNodes;               // if the node count is different
     sal_uInt8 nFldLstGetMode;
+    SwDoc* pDocument;
 
     bool bInUpdateFlds : 1;     // currently there is an UpdateFlds
     bool bFldsDirty : 1;        // some fields are invalid
@@ -164,7 +166,7 @@ class SwDocUpdtFld
     void GetBodyNode( const SwSectionNode&);
 
 public:
-    SwDocUpdtFld();
+    SwDocUpdtFld(SwDoc* pDocument);
     ~SwDocUpdtFld();
 
     const _SetGetExpFlds* GetSortLst() const { return pFldSortLst; }
@@ -180,7 +182,15 @@ public:
     void SetInUpdateFlds( bool b )      { bInUpdateFlds = b; }
 
     bool IsFieldsDirty() const          { return bFldsDirty; }
-    void SetFieldsDirty( bool b )       { bFldsDirty = b; }
+    void SetFieldsDirty( bool b )
+    {
+        bFldsDirty = b;
+
+        if (b)
+        {
+            pDocument->StartBackgroundJobs();
+        }
+    }
 
     SwHash** GetFldTypeTable() const { return (SwHash**)aFldTypeTable; }
 };
diff --git a/sw/source/core/inc/rootfrm.hxx b/sw/source/core/inc/rootfrm.hxx
index 02014dc..1672c4c 100644
--- a/sw/source/core/inc/rootfrm.hxx
+++ b/sw/source/core/inc/rootfrm.hxx
@@ -29,6 +29,8 @@
 #define SW_ROOTFRM_HXX
 
 #include "layfrm.hxx"
+#include <viewsh.hxx>
+#include <doc.hxx>
 
 class SwCntntFrm;
 class ViewShell;
@@ -212,12 +214,33 @@ public:
 
     virtual Size ChgSize( const Size& aNewSize );
 
-    void SetIdleFlags() { bIdleFormat = sal_True; }
+    void SetIdleFlags()
+    {
+        bIdleFormat = sal_True;
+
+        ViewShell* lcl_pCurrShell = GetCurrShell();
+        // May be NULL if called from SfxBaseModel::dispose
+        // (this happens in the build test 'rtfexport').
+        if (lcl_pCurrShell != NULL)
+            lcl_pCurrShell->GetDoc()->StartBackgroundJobs();
+    }
     sal_Bool IsIdleFormat()  const { return bIdleFormat; }
     void ResetIdleFormat()     { bIdleFormat = sal_False; }
 
     bool IsNeedGrammarCheck() const         { return mbNeedGrammarCheck; }
-    void SetNeedGrammarCheck( bool bVal )   { mbNeedGrammarCheck = bVal; }
+    void SetNeedGrammarCheck( bool bVal )
+    {
+        mbNeedGrammarCheck = bVal;
+
+        if ( bVal )
+        {
+            ViewShell* lcl_pCurrShell = GetCurrShell();
+            // May be NULL if called from SfxBaseModel::dispose
+            // (this happens in the build test 'rtfexport').
+            if (lcl_pCurrShell != NULL)
+                lcl_pCurrShell->GetDoc()->StartBackgroundJobs();
+        }
+    }
 
     //Sorgt dafuer, dass alle gewuenschten Seitengebunden Flys eine Seite finden
     void SetAssertFlyPages() { bAssertFlyPages = sal_True; }


More information about the LibreOffice mailing list