diff options
-rw-r--r-- | sw/inc/IDocumentTimerAccess.hxx | 5 | ||||
-rw-r--r-- | sw/inc/doc.hxx | 9 | ||||
-rw-r--r-- | sw/source/core/doc/DocumentTimerManager.cxx | 121 | ||||
-rw-r--r-- | sw/source/core/doc/SwDocIdle.cxx | 6 | ||||
-rw-r--r-- | sw/source/core/doc/docnew.cxx | 17 | ||||
-rw-r--r-- | sw/source/core/inc/DocumentTimerManager.hxx | 23 | ||||
-rw-r--r-- | sw/source/uibase/uiview/view0.cxx | 2 |
7 files changed, 121 insertions, 62 deletions
diff --git a/sw/inc/IDocumentTimerAccess.hxx b/sw/inc/IDocumentTimerAccess.hxx index 717728f83c99..6efe1a114963 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 b12d2f8d821b..7476a3665f20 100644 --- a/sw/inc/doc.hxx +++ b/sw/inc/doc.hxx @@ -223,9 +223,6 @@ namespace sfx2 { void SetAllScriptItem( SfxItemSet& rSet, const SfxPoolItem& rItem ); -// global function to start grammar checking in the document -void StartGrammarChecking( SwDoc &rDoc ); - using SwRubyList = std::vector<std::unique_ptr<SwRubyListEntry>>; // Represents the model of a Writer document. @@ -1630,6 +1627,12 @@ public: rTable.end()); } + /** + * @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 ec4874ea9ecc..5429c6edbda6 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( 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( 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( 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( SwFieldIds::Chapter )->ModifyNotification( nullptr, nullptr ); // ChapterField - m_rDoc.getIDocumentFieldsAccess().UpdateExpFields( nullptr, false ); // Updates ExpressionFields - m_rDoc.getIDocumentFieldsAccess().UpdateTableFields(nullptr); // Tables - m_rDoc.getIDocumentFieldsAccess().UpdateRefFields(); // References + // no jump on update of fields #i85168# + const bool bOldLockView = pShell->IsViewLocked(); + pShell->LockView( true ); - pTmpRoot->EndAllAction(); + m_rDoc.getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::Chapter )->ModifyNotification( nullptr, nullptr ); // ChapterField + m_rDoc.getIDocumentFieldsAccess().UpdateExpFields( nullptr, false ); // Updates ExpressionFields + m_rDoc.getIDocumentFieldsAccess().UpdateTableFields(nullptr); // Tables + m_rDoc.getIDocumentFieldsAccess().UpdateRefFields(); // 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 883fcbac9047..9e2a82d3083c 100644 --- a/sw/source/core/doc/docnew.cxx +++ b/sw/source/core/doc/docnew.cxx @@ -141,11 +141,12 @@ using namespace ::com::sun::star::document; 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) { @@ -160,17 +161,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 698762ab087e..d8c1a76b2a14 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( DoIdleJobs, Timer *, void ); - - virtual ~DocumentTimerManager() override; + bool IsDocIdle() const override; private: - DocumentTimerManager(DocumentTimerManager const&) = delete; DocumentTimerManager& operator=(DocumentTimerManager const&) = delete; + DECL_LINK( 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 8f859fafd6c2..491017981728 100644 --- a/sw/source/uibase/uiview/view0.cxx +++ b/sw/source/uibase/uiview/view0.cxx @@ -524,7 +524,7 @@ void SwView::ExecViewOptions(SfxRequest &rReq) aCfg.GetProperty( UPN_IS_GRAMMAR_AUTO ) >>= bIsAutoGrammar; if (pDoc && bIsAutoGrammar) - StartGrammarChecking( *pDoc ); + pDoc->StartGrammarChecking(); } } break; |