summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sw/inc/IDocumentTimerAccess.hxx5
-rw-r--r--sw/inc/doc.hxx9
-rw-r--r--sw/source/core/doc/DocumentTimerManager.cxx121
-rw-r--r--sw/source/core/doc/SwDocIdle.cxx6
-rw-r--r--sw/source/core/doc/docnew.cxx17
-rw-r--r--sw/source/core/inc/DocumentTimerManager.hxx23
-rw-r--r--sw/source/uibase/uiview/view0.cxx2
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;