LibreOffice Module sw (master)  1
DocumentTimerManager.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 #include <DocumentTimerManager.hxx>
20 
21 #include <doc.hxx>
25 #include <rootfrm.hxx>
26 #include <viewsh.hxx>
27 #include <unotools/lingucfg.hxx>
28 #include <unotools/linguprops.hxx>
29 #include <set>
30 #include <fldupde.hxx>
31 #include <sfx2/progress.hxx>
32 #include <viewopt.hxx>
33 #include <docsh.hxx>
34 #include <docfld.hxx>
35 #include <fldbas.hxx>
36 #include <vcl/scheduler.hxx>
37 #include <comphelper/lok.hxx>
38 #include <editsh.hxx>
39 
40 namespace sw
41 {
43  : m_rDoc(i_rSwdoc)
44  , m_nIdleBlockCount(0)
45  , m_bStartOnUnblock(false)
46  , m_aDocIdle(i_rSwdoc)
47  , m_aFireIdleJobsTimer("sw::DocumentTimerManager m_aFireIdleJobsTimer")
48  , m_bWaitForLokInit(true)
49 {
50  m_aDocIdle.SetPriority(TaskPriority::LOWEST);
52  m_aDocIdle.SetDebugName("sw::DocumentTimerManager m_aDocIdle");
53 
55  m_aFireIdleJobsTimer.SetTimeout(1000); // Enough time for LOK to render the first tiles.
56 }
57 
59 {
61  {
62  // Start the idle jobs only after a certain delay.
63  m_bWaitForLokInit = false;
64  StopIdling();
66  return;
67  }
68 
69  m_bWaitForLokInit = false;
70  m_bStartOnUnblock = true;
71  if (0 == m_nIdleBlockCount)
72  {
73  if (!m_aDocIdle.IsActive())
74  m_aDocIdle.Start();
75  else
77  }
78 }
79 
81 {
82  m_bStartOnUnblock = false;
83  m_aDocIdle.Stop();
84 }
85 
87 {
90 }
91 
93 {
94  assert(0 != m_nIdleBlockCount);
96 
98  {
99  if (!m_aDocIdle.IsActive())
100  m_aDocIdle.Start();
101  else
103  }
104 }
105 
106 IMPL_LINK(DocumentTimerManager, FireIdleJobsTimeout, Timer*, , void)
107 {
108  // Now we can run the idle jobs, assuming we finished LOK initialization.
109  StartIdling();
110 }
111 
113 {
115  if( pTmpRoot &&
117  {
119  for(const SwViewShell& rSh : pShell->GetRingContainer())
120  if( rSh.ActionPend() )
121  return IdleJob::Busy;
122 
123  if( pTmpRoot->IsNeedGrammarCheck() )
124  {
125  bool bIsOnlineSpell = pShell->GetViewOptions()->IsOnlineSpell();
126  bool bIsAutoGrammar = false;
127  SvtLinguConfig().GetProperty( UPN_IS_GRAMMAR_AUTO ) >>= bIsAutoGrammar;
128 
129  if( bIsOnlineSpell && bIsAutoGrammar && m_rDoc.StartGrammarChecking( true ) )
130  return IdleJob::Grammar;
131  }
132 
133  // If we're dragging re-layout doesn't occur so avoid a busy loop.
134  if (!pShell->HasDrawViewDrag())
135  {
136  for ( auto pLayout : m_rDoc.GetAllLayouts() )
137  {
138  if( pLayout->IsIdleFormat() )
139  return IdleJob::Layout;
140  }
141  }
142 
144  if( ( AUTOUPD_FIELD_ONLY == nFieldUpdFlag
145  || AUTOUPD_FIELD_AND_CHARTS == nFieldUpdFlag )
147  {
150  return IdleJob::Busy;
151  return IdleJob::Fields;
152  }
153  }
154 
155  return IdleJob::None;
156 }
157 
159 {
160 #ifdef TIMELOG
161  static ::rtl::Logfile* pModLogFile = new ::rtl::Logfile( "First DoIdleJobs" );
162 #endif
163  BlockIdling();
164  StopIdling();
165 
166  IdleJob eJob = GetNextIdleJob();
167 
168  switch ( eJob )
169  {
170  case IdleJob::Grammar:
171  m_rDoc.StartGrammarChecking();
172  break;
173 
174  case IdleJob::Layout:
175  for ( auto pLayout : m_rDoc.GetAllLayouts() )
176  if( pLayout->IsIdleFormat() )
177  {
178  pLayout->GetCurrShell()->LayoutIdle();
179  break;
180  }
181  break;
182 
183  case IdleJob::Fields:
184  {
185  SwViewShell* pShell( m_rDoc.getIDocumentLayoutAccess().GetCurrentViewShell() );
186  SwRootFrame* pTmpRoot = m_rDoc.getIDocumentLayoutAccess().GetCurrentLayout();
187 
188  // Action brackets!
189  m_rDoc.getIDocumentFieldsAccess().GetUpdateFields().SetInUpdateFields( true );
190 
191  pTmpRoot->StartAllAction();
192 
193  // no jump on update of fields #i85168#
194  const bool bOldLockView = pShell->IsViewLocked();
195  pShell->LockView( true );
196 
197  m_rDoc.getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::Chapter )->ModifyNotification( nullptr, nullptr ); // ChapterField
198  m_rDoc.getIDocumentFieldsAccess().UpdateExpFields( nullptr, false ); // Updates ExpressionFields
199  m_rDoc.getIDocumentFieldsAccess().UpdateTableFields(nullptr); // Tables
200  m_rDoc.getIDocumentFieldsAccess().UpdateRefFields(); // References
201 
202  // Validate and update the paragraph signatures.
203  if (m_rDoc.GetEditShell())
204  m_rDoc.GetEditShell()->ValidateAllParagraphSignatures(true);
205 
206  pTmpRoot->EndAllAction();
207 
208  pShell->LockView( bOldLockView );
209 
210  m_rDoc.getIDocumentFieldsAccess().GetUpdateFields().SetInUpdateFields( false );
211  m_rDoc.getIDocumentFieldsAccess().GetUpdateFields().SetFieldsDirty( false );
212  break;
213  }
214 
215  case IdleJob::Busy:
216  break;
217  case IdleJob::None:
218  break;
219  }
220 
221  if ( IdleJob::None != eJob )
222  StartIdling();
223  UnblockIdling();
224 
225 #ifdef TIMELOG
226  if( pModLogFile && 1 != (long)pModLogFile )
227  delete pModLogFile, static_cast<long&>(pModLogFile) = 1;
228 #endif
229 }
230 
232 
233 }
234 
235 
236 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static void Wakeup()
SwFieldUpdateFlags
Definition: fldupde.hxx:22
virtual const SwRootFrame * GetCurrentLayout() const =0
SwDocShell * GetDocShell()
Definition: doc.hxx:1341
bool IsInUpdateFields() const
Definition: docfld.hxx:160
bool IsFieldsDirty() const
Definition: docfld.hxx:163
Definition: doc.hxx:185
bool IsNeedGrammarCheck() const
Definition: rootfrm.hxx:259
Dialog to specify the properties of date form field.
Definition: accfrmobj.cxx:38
document has no idle jobs to do
bool m_bStartOnUnblock
true, if the last unblock should start the timer
The root element of a Writer document layout.
Definition: rootfrm.hxx:79
bool IsActive() const
#define SAL_MAX_UINT32
IDocumentFieldsAccess const & getIDocumentFieldsAccess() const
Definition: doc.cxx:389
bool m_bWaitForLokInit
true if we waited for LOK to initialize already.
#define UPN_IS_GRAMMAR_AUTO
IMPL_LINK(DocumentStatisticsManager, DoIdleStatsUpdate, Timer *, pIdle, void)
virtual void Start() override
virtual bool IsExpFieldsLocked() const =0
virtual ~DocumentTimerManager() override
sal_uInt32 m_nIdleBlockCount
Don't run the Idle, if > 0.
void UnblockIdling() override
Decrement block count.
IMPL_LINK_NOARG(DocumentTimerManager, DoIdleJobs, Timer *, void)
virtual void Start() override
std::set< SwRootFrame * > GetAllLayouts()
Definition: doclay.cxx:1673
ring_container GetRingContainer()
Definition: ring.hxx:240
void SetTimeout(sal_uInt64 nTimeoutMs)
void StopIdling() override
Stop idle processing.
void BlockIdling() override
Increment block count.
IDocumentLayoutAccess const & getIDocumentLayoutAccess() const
Definition: doc.cxx:437
void Stop()
virtual SwFieldUpdateFlags getFieldUpdateFlags(bool bGlobalSettings) const override
Get the current field update mode.
virtual const SwViewShell * GetCurrentViewShell() const =0
Returns the layout set at the document.
::sw::DocumentSettingManager & GetDocumentSettingManager()
Definition: doc.cxx:218
virtual SwDocUpdateField & GetUpdateFields() const =0
void SetInvokeHandler(const Link< Timer *, void > &rLink)
document is busy and idle jobs are postponed
static SfxProgress * GetActiveProgress(SfxObjectShell const *pDocSh=nullptr)
DocumentTimerManager(SwDoc &i_rSwdoc)
css::uno::Any GetProperty(const OUString &rPropertyName) const
void SetPriority(TaskPriority ePriority)
void StartAllAction()
Set up Start-/EndAction for all Shells on an as high as possible (Shell section) level.
Definition: pagechg.cxx:1866
bool StartGrammarChecking(bool bSkipStart=false)
Definition: docnew.cxx:149
void SetDebugName(const sal_Char *pDebugName)
void StartIdling() override
Start the idle task.