[Libreoffice-commits] core.git: Branch 'private/swe/libreoffice-5-2+backports' - sw/inc sw/source

Jan-Marek Glogowski glogow at fbihome.de
Fri Oct 6 17:33:38 UTC 2017


Rebased ref, commits from common ancestor:
commit c8377d3cada65d20786f52db0a14b7e7de6d8324
Author: Jan-Marek Glogowski <glogow at fbihome.de>
Date:   Fri Oct 6 11:00:19 2017 +0200

    Don't schedule the Idle job for busy documents
    
    This refactors DocumentTimerManager to export the busy status
    independent of the Idle function. This way it can be ignored in
    the Scheduler while the document is busy,
    
    Reviewed-on: https://gerrit.libreoffice.org/43197
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Jan-Marek Glogowski <glogow at fbihome.de>
    (cherry picked from commit 53da556c600fa82ba84bc7fdce6a594b43f2b097)
    
    Conflicts:
            sw/inc/doc.hxx
            sw/source/core/doc/DocumentTimerManager.cxx
            sw/source/core/inc/DocumentTimerManager.hxx
    
    Change-Id: Icec2075d3338ad8dd4440678eb0570d7fe887778

diff --git a/sw/inc/IDocumentTimerAccess.hxx b/sw/inc/IDocumentTimerAccess.hxx
index 2cdb33e5ab7d..94947b35ac30 100644
--- a/sw/inc/IDocumentTimerAccess.hxx
+++ b/sw/inc/IDocumentTimerAccess.hxx
@@ -55,6 +55,11 @@ public:
     */
     virtual void StartBackgroundJobs() = 0;
 
+    /**
+     * Is the document ready to be processed?
+     */
+    virtual bool IsDocIdle() const = 0;
+
 protected:
     virtual ~IDocumentTimerAccess() {};
 };
diff --git a/sw/inc/doc.hxx b/sw/inc/doc.hxx
index f154c4379021..9ce4526fcd80 100644
--- a/sw/inc/doc.hxx
+++ b/sw/inc/doc.hxx
@@ -238,9 +238,6 @@ typedef std::vector<std::unique_ptr<SwPageDesc>> SwPageDescs;
 
 void SetAllScriptItem( SfxItemSet& rSet, const SfxPoolItem& rItem );
 
-// global function to start grammar checking in the document
-void StartGrammarChecking( SwDoc &rDoc );
-
 // Represents the model of a Writer document.
 class SW_DLLPUBLIC SwDoc :
     public IInterface
@@ -1651,6 +1648,12 @@ public:
         std::swap(mvUnoCursorTable, unoCursorTable);
     }
 
+    /**
+     * @param bSkipStart don't actually start the jobs, just check
+     * @returns true if new background checking jobs were started
+     */
+    bool StartGrammarChecking( bool bSkipStart = false );
+
 private:
     // Copies master header to left / first one, if necessary - used by ChgPageDesc().
     void CopyMasterHeader(const SwPageDesc &rChged, const SwFormatHeader &rHead, SwPageDesc &pDesc, bool bLeft, bool bFirst);
diff --git a/sw/source/core/doc/DocumentTimerManager.cxx b/sw/source/core/doc/DocumentTimerManager.cxx
index f3d71cd48a47..66018bcefca1 100644
--- a/sw/source/core/doc/DocumentTimerManager.cxx
+++ b/sw/source/core/doc/DocumentTimerManager.cxx
@@ -80,27 +80,16 @@ void DocumentTimerManager::StartBackgroundJobs()
         maDocIdle.Start();
 }
 
-IMPL_LINK_TYPED( DocumentTimerManager, DoIdleJobs, Timer*, pIdle, void )
+DocumentTimerManager::IdleJob DocumentTimerManager::GetNextIdleJob() const
 {
-#ifdef TIMELOG
-    static ::rtl::Logfile* pModLogFile = 0;
-    if( !pModLogFile )
-        pModLogFile = new ::rtl::Logfile( "First DoIdleJobs" );
-#endif
-
     SwRootFrame* pTmpRoot = m_rDoc.getIDocumentLayoutAccess().GetCurrentLayout();
     if( pTmpRoot &&
         !SfxProgress::GetActiveProgress( m_rDoc.GetDocShell() ) )
     {
         SwViewShell* pShell(m_rDoc.getIDocumentLayoutAccess().GetCurrentViewShell());
         for(SwViewShell& rSh : pShell->GetRingContainer())
-        {
             if( rSh.ActionPend() )
-            {
-                pIdle->Start();
-                return;
-            }
-        }
+                return IdleJob::Busy;
 
         if( pTmpRoot->IsNeedGrammarCheck() )
         {
@@ -109,59 +98,93 @@ IMPL_LINK_TYPED( DocumentTimerManager, DoIdleJobs, Timer*, pIdle, void )
             SvtLinguConfig().GetProperty( OUString(
                         UPN_IS_GRAMMAR_AUTO ) ) >>= bIsAutoGrammar;
 
-            if (bIsOnlineSpell && bIsAutoGrammar)
-                StartGrammarChecking( m_rDoc );
+            if( bIsOnlineSpell && bIsAutoGrammar && m_rDoc.StartGrammarChecking( true ) )
+                return IdleJob::Grammar;
         }
-        std::set<SwRootFrame*> aAllLayouts = m_rDoc.GetAllLayouts();
-        std::set<SwRootFrame*>::iterator pLayIter = aAllLayouts.begin();
-        for ( ;pLayIter != aAllLayouts.end();++pLayIter )
+
+        for ( auto pLayout : m_rDoc.GetAllLayouts() )
         {
-            if ((*pLayIter)->IsIdleFormat())
-            {
-                (*pLayIter)->GetCurrShell()->LayoutIdle();
-                // Defer the remaining work.
-                pIdle->Start();
-                return;
-            }
+            if( pLayout->IsIdleFormat() )
+                return IdleJob::Layout;
         }
 
         SwFieldUpdateFlags nFieldUpdFlag = m_rDoc.GetDocumentSettingManager().getFieldUpdateFlags(true);
         if( ( AUTOUPD_FIELD_ONLY == nFieldUpdFlag
-                    || AUTOUPD_FIELD_AND_CHARTS == nFieldUpdFlag ) &&
-                m_rDoc.getIDocumentFieldsAccess().GetUpdateFields().IsFieldsDirty()
-                // If we switch the field name the Fields are not updated.
-                // So the "background update" should always be carried out
-                /* && !pStartSh->GetViewOptions()->IsFieldName()*/ )
+                    || AUTOUPD_FIELD_AND_CHARTS == nFieldUpdFlag )
+                && m_rDoc.getIDocumentFieldsAccess().GetUpdateFields().IsFieldsDirty() )
         {
-            if ( m_rDoc.getIDocumentFieldsAccess().GetUpdateFields().IsInUpdateFields() ||
-                      m_rDoc.getIDocumentFieldsAccess().IsExpFieldsLocked() )
+            if( m_rDoc.getIDocumentFieldsAccess().GetUpdateFields().IsInUpdateFields()
+                    || m_rDoc.getIDocumentFieldsAccess().IsExpFieldsLocked() )
+                return IdleJob::Busy;
+            return IdleJob::Fields;
+        }
+    }
+
+    return IdleJob::None;
+}
+
+IMPL_LINK_TYPED( DocumentTimerManager, DoIdleJobs, Timer*, pIdle, void )
+{
+#ifdef TIMELOG
+    static ::rtl::Logfile* pModLogFile = 0;
+    if( !pModLogFile )
+        pModLogFile = new ::rtl::Logfile( "First DoIdleJobs" );
+#endif
+
+    IdleJob eJob = GetNextIdleJob();
+
+    switch ( eJob )
+    {
+    case IdleJob::Grammar:
+        m_rDoc.StartGrammarChecking();
+        break;
+
+    case IdleJob::Layout:
+        for ( auto pLayout : m_rDoc.GetAllLayouts() )
+            if( pLayout->IsIdleFormat() )
             {
-                pIdle->Start();
-                return;
+                pLayout->GetCurrShell()->LayoutIdle();
+                break;
             }
+         break;
 
-            //  Action brackets!
-            m_rDoc.getIDocumentFieldsAccess().GetUpdateFields().SetInUpdateFields( true );
+    case IdleJob::Fields:
+    {
+        SwViewShell* pShell( m_rDoc.getIDocumentLayoutAccess().GetCurrentViewShell() );
+        SwRootFrame* pTmpRoot = m_rDoc.getIDocumentLayoutAccess().GetCurrentLayout();
 
-            pTmpRoot->StartAllAction();
+        //  Action brackets!
+        m_rDoc.getIDocumentFieldsAccess().GetUpdateFields().SetInUpdateFields( true );
 
-            // no jump on update of fields #i85168#
-            const bool bOldLockView = pShell->IsViewLocked();
-            pShell->LockView( true );
+        pTmpRoot->StartAllAction();
 
-            m_rDoc.getIDocumentFieldsAccess().GetSysFieldType( RES_CHAPTERFLD )->ModifyNotification( nullptr, nullptr );    // ChapterField
-            m_rDoc.getIDocumentFieldsAccess().UpdateExpFields( nullptr, false );      // Updates ExpressionFields
-            m_rDoc.getIDocumentFieldsAccess().UpdateTableFields(nullptr);                // Tables
-            m_rDoc.getIDocumentFieldsAccess().UpdateRefFields(nullptr);                // References
+        // no jump on update of fields #i85168#
+        const bool bOldLockView = pShell->IsViewLocked();
+        pShell->LockView( true );
 
-            pTmpRoot->EndAllAction();
+        m_rDoc.getIDocumentFieldsAccess().GetSysFieldType( RES_CHAPTERFLD )->ModifyNotification( nullptr, nullptr );    // ChapterField
+        m_rDoc.getIDocumentFieldsAccess().UpdateExpFields( nullptr, false );      // Updates ExpressionFields
+        m_rDoc.getIDocumentFieldsAccess().UpdateTableFields(nullptr);                // Tables
+        m_rDoc.getIDocumentFieldsAccess().UpdateRefFields(nullptr);                // References
 
-            pShell->LockView( bOldLockView );
+        pTmpRoot->EndAllAction();
 
-            m_rDoc.getIDocumentFieldsAccess().GetUpdateFields().SetInUpdateFields( false );
-            m_rDoc.getIDocumentFieldsAccess().GetUpdateFields().SetFieldsDirty( false );
-        }
+        pShell->LockView( bOldLockView );
+
+        m_rDoc.getIDocumentFieldsAccess().GetUpdateFields().SetInUpdateFields( false );
+        m_rDoc.getIDocumentFieldsAccess().GetUpdateFields().SetFieldsDirty( false );
+        break;
     }
+
+    case IdleJob::Busy:
+        break;
+    case IdleJob::None:
+        break;
+    }
+
+    if ( IdleJob::None != eJob )
+        pIdle->Start();
+
 #ifdef TIMELOG
     if( pModLogFile && 1 != (long)pModLogFile )
         delete pModLogFile, static_cast<long&>(pModLogFile) = 1;
diff --git a/sw/source/core/doc/SwDocIdle.cxx b/sw/source/core/doc/SwDocIdle.cxx
index 9461807943d8..5987274a6b3d 100644
--- a/sw/source/core/doc/SwDocIdle.cxx
+++ b/sw/source/core/doc/SwDocIdle.cxx
@@ -24,6 +24,7 @@
 #include <vcl/scheduler.hxx>
 
 #include "SwDocIdle.hxx"
+#include "IDocumentTimerAccess.hxx"
 
 namespace sw
 {
@@ -31,12 +32,17 @@ namespace sw
 sal_uInt64 SwDocIdle::UpdateMinPeriod( sal_uInt64 /* nMinPeriod */, sal_uInt64 /* nTimeNow */ ) const
 {
     bool bReadyForSchedule = true;
+
     SwView* pView = m_rDoc.GetDocShell() ? m_rDoc.GetDocShell()->GetView() : nullptr;
     if( pView )
     {
         SwWrtShell& rWrtShell = pView->GetWrtShell();
         bReadyForSchedule = rWrtShell.GetViewOptions()->IsIdle();
     }
+
+    if( bReadyForSchedule && !m_rDoc.getIDocumentTimerAccess().IsDocIdle() )
+        bReadyForSchedule = false;
+
     return bReadyForSchedule
         ? Scheduler::ImmediateTimeoutMs : Scheduler::InfiniteTimeoutMs;
 }
diff --git a/sw/source/core/doc/docnew.cxx b/sw/source/core/doc/docnew.cxx
index 37cd90a72573..53b173b7ba28 100644
--- a/sw/source/core/doc/docnew.cxx
+++ b/sw/source/core/doc/docnew.cxx
@@ -154,11 +154,12 @@ const sal_Char sGrfCollStr[] = "Graphikformatvorlage";
     return m_xGCIterator;
 }
 
-void StartGrammarChecking( SwDoc &rDoc )
+bool SwDoc::StartGrammarChecking( bool bSkipStart )
 {
     // check for a visible view
     bool bVisible = false;
-    const SwDocShell *pDocShell = rDoc.GetDocShell();
+    bool bStarted = false;
+    const SwDocShell *pDocShell = GetDocShell();
     SfxViewFrame     *pFrame = SfxViewFrame::GetFirst( pDocShell, false );
     while (pFrame && !bVisible)
     {
@@ -173,17 +174,23 @@ void StartGrammarChecking( SwDoc &rDoc )
     //!! a uno reference to them)
     if (bVisible)
     {
-        uno::Reference< linguistic2::XProofreadingIterator > xGCIterator( rDoc.GetGCIterator() );
+        uno::Reference< linguistic2::XProofreadingIterator > xGCIterator( GetGCIterator() );
         if ( xGCIterator.is() )
         {
-            uno::Reference< lang::XComponent >  xDoc( rDoc.GetDocShell()->GetBaseModel(), uno::UNO_QUERY );
+            uno::Reference< lang::XComponent >  xDoc( GetDocShell()->GetBaseModel(), uno::UNO_QUERY );
             uno::Reference< text::XFlatParagraphIteratorProvider >  xFPIP( xDoc, uno::UNO_QUERY );
 
             // start automatic background checking if not active already
             if ( xFPIP.is() && !xGCIterator->isProofreading( xDoc ) )
-                xGCIterator->startProofreading( xDoc, xFPIP );
+            {
+                bStarted = true;
+                if ( !bSkipStart )
+                    xGCIterator->startProofreading( xDoc, xFPIP );
+            }
         }
     }
+
+    return bStarted;
 }
 
 /*
diff --git a/sw/source/core/inc/DocumentTimerManager.hxx b/sw/source/core/inc/DocumentTimerManager.hxx
index be7a852dee86..4e497c952cea 100644
--- a/sw/source/core/inc/DocumentTimerManager.hxx
+++ b/sw/source/core/inc/DocumentTimerManager.hxx
@@ -34,8 +34,17 @@ namespace sw
 class DocumentTimerManager : public IDocumentTimerAccess
 {
 public:
+    enum class IdleJob
+    {
+        None, ///< document has no idle jobs to do
+        Busy, ///< document is busy and idle jobs are postponed
+        Grammar,
+        Layout,
+        Fields,
+    };
 
     DocumentTimerManager( SwDoc& i_rSwdoc );
+    virtual ~DocumentTimerManager() override;
 
     void StartIdling() override;
 
@@ -47,15 +56,16 @@ public:
 
     void StartBackgroundJobs() override;
 
-    DECL_LINK_TYPED( DoIdleJobs, Timer *, void );
-
-    virtual ~DocumentTimerManager();
+    bool IsDocIdle() const override;
 
 private:
-
     DocumentTimerManager(DocumentTimerManager const&) = delete;
     DocumentTimerManager& operator=(DocumentTimerManager const&) = delete;
 
+    DECL_LINK_TYPED( DoIdleJobs, Timer *, void );
+
+    IdleJob GetNextIdleJob() const;
+
     SwDoc& m_rDoc;
 
     bool mbStartIdleTimer; //< idle timer mode start/stop
@@ -63,6 +73,11 @@ private:
     SwDocIdle maDocIdle;
 };
 
+inline bool DocumentTimerManager::IsDocIdle() const
+{
+    return( GetNextIdleJob() != IdleJob::Busy );
+}
+
 }
 
 #endif
diff --git a/sw/source/uibase/uiview/view0.cxx b/sw/source/uibase/uiview/view0.cxx
index 75cfffedcdfd..742b3b8b9711 100644
--- a/sw/source/uibase/uiview/view0.cxx
+++ b/sw/source/uibase/uiview/view0.cxx
@@ -539,7 +539,7 @@ void SwView::ExecViewOptions(SfxRequest &rReq)
                 aCfg.GetProperty( UPN_IS_GRAMMAR_AUTO ) >>= bIsAutoGrammar;
 
                 if (pDoc && bIsAutoGrammar)
-                    StartGrammarChecking( *pDoc );
+                    pDoc->StartGrammarChecking();
             }
         }
         break;


More information about the Libreoffice-commits mailing list