LibreOffice Module sw (master)  1
layact.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 
20 #include <config_features.h>
21 
22 #include <ctime>
23 #include <rootfrm.hxx>
24 #include <pagefrm.hxx>
25 #include <viewimp.hxx>
26 #include <crsrsh.hxx>
27 #include <dflyobj.hxx>
28 #include <frmatr.hxx>
29 #include <frmtool.hxx>
30 #include <dcontact.hxx>
31 #include <viewopt.hxx>
32 #include <dbg_lay.hxx>
33 #include <layouter.hxx>
34 #include <docstat.hxx>
35 #include <swevent.hxx>
37 #include <IDocumentStatistics.hxx>
39 
40 #include <sfx2/event.hxx>
41 
42 #include <ftnidx.hxx>
43 #include <vcl/svapp.hxx>
44 #include <editeng/opaqitem.hxx>
45 #include <SwSmartTagMgr.hxx>
46 #include <sal/log.hxx>
47 
48 #include <layact.hxx>
49 #include <swwait.hxx>
50 #include <fmtsrnd.hxx>
51 #include <docsh.hxx>
52 
53 #include <ndtxt.hxx>
54 #include <tabfrm.hxx>
55 #include <ftnfrm.hxx>
56 #include <txtfrm.hxx>
57 #include <notxtfrm.hxx>
58 #include <flyfrms.hxx>
59 #include <mdiexp.hxx>
60 #include <sectfrm.hxx>
61 #include <acmplwrd.hxx>
62 #include <sortedobjs.hxx>
63 #include <objectformatter.hxx>
64 #include <fntcache.hxx>
65 #include <vector>
66 #include <tools/diagnose_ex.h>
67 
68 // Save some typing work to avoid accessing destroyed pages.
69 #define XCHECKPAGE \
70  { if ( IsAgain() ) \
71  { \
72  if( bNoLoop ) \
73  rLayoutAccess.GetLayouter()->EndLoopControl(); \
74  return; \
75  } \
76  }
77 
79 {
80  if (IsReschedule())
81  {
83  }
84  if ( !m_pWait && IsWaitAllowed() && IsPaint() &&
85  ((std::clock() - m_nStartTicks) * 1000 / CLOCKS_PER_SEC >= CLOCKS_PER_SEC/2) )
86  {
87  m_pWait.reset( new SwWait( *m_pRoot->GetFormat()->GetDoc()->GetDocShell(), true ) );
88  }
89 }
90 
91 void SwLayAction::SetStatBar( bool bNew )
92 {
93  if ( bNew )
94  {
96  m_nEndPage += m_nEndPage * 10 / 100;
97  }
98  else
100 }
101 
102 bool SwLayAction::PaintWithoutFlys( const SwRect &rRect, const SwContentFrame *pCnt,
103  const SwPageFrame *pPage )
104 {
105  SwRegionRects aTmp( rRect );
106  const SwSortedObjs &rObjs = *pPage->GetSortedObjs();
107  const SwFlyFrame *pSelfFly = pCnt->FindFlyFrame();
108 
109  for ( size_t i = 0; i < rObjs.size() && !aTmp.empty(); ++i )
110  {
111  SdrObject *pO = rObjs[i]->DrawObj();
112  if ( dynamic_cast< const SwVirtFlyDrawObj *>( pO ) == nullptr )
113  continue;
114 
115  // do not consider invisible objects
117  if ( !rIDDMA.IsVisibleLayerId( pO->GetLayer() ) )
118  {
119  continue;
120  }
121 
122  SwFlyFrame *pFly = static_cast<SwVirtFlyDrawObj*>(pO)->GetFlyFrame();
123 
124  if ( pFly == pSelfFly || !rRect.IsOver( pFly->getFrameArea() ) )
125  continue;
126 
127  if ( pSelfFly && pSelfFly->IsLowerOf( pFly ) )
128  continue;
129 
130  if ( pFly->GetVirtDrawObj()->GetLayer() == rIDDMA.GetHellId() )
131  continue;
132 
133  if ( pSelfFly )
134  {
135  const SdrObject *pTmp = pSelfFly->GetVirtDrawObj();
136  if ( pO->GetLayer() == pTmp->GetLayer() )
137  {
138  if ( pO->GetOrdNumDirect() < pTmp->GetOrdNumDirect() )
139  // Only look at things above us, if inside the same layer
140  continue;
141  }
142  else
143  {
144  const bool bLowerOfSelf = pFly->IsLowerOf( pSelfFly );
145  if ( !bLowerOfSelf && !pFly->GetFormat()->GetOpaque().GetValue() )
146  // Things from other layers are only interesting to us if
147  // they're not transparent or lie inwards
148  continue;
149  }
150  }
151 
152  // Fly frame without a lower have to be subtracted from paint region.
153  // For checking, if fly frame contains transparent graphic or
154  // has surrounded contour, assure that fly frame has a lower
155  if ( pFly->Lower() &&
156  pFly->Lower()->IsNoTextFrame() &&
157  ( static_cast<SwNoTextFrame*>(pFly->Lower())->IsTransparent() ||
158  pFly->GetFormat()->GetSurround().IsContour() )
159  )
160  {
161  continue;
162  }
163 
164  // vcl::Region of a fly frame with transparent background or a transparent
165  // shadow have not to be subtracted from paint region
166  if ( pFly->IsBackgroundTransparent() )
167  {
168  continue;
169  }
170 
171  aTmp -= pFly->getFrameArea();
172  }
173 
174  bool bRetPaint = false;
175  for ( const auto& rRegionRect : aTmp )
176  bRetPaint |= m_pImp->GetShell()->AddPaintRect( rRegionRect );
177  return bRetPaint;
178 }
179 
180 inline bool SwLayAction::PaintContent_( const SwContentFrame *pContent,
181  const SwPageFrame *pPage,
182  const SwRect &rRect )
183 {
184  if ( rRect.HasArea() )
185  {
186  if ( pPage->GetSortedObjs() )
187  return PaintWithoutFlys( rRect, pContent, pPage );
188  else
189  return m_pImp->GetShell()->AddPaintRect( rRect );
190  }
191  return false;
192 }
193 
199  const SwPageFrame *pPage,
200  const SwRect &rOldRect,
201  long nOldBottom )
202 {
203  SwRectFnSet aRectFnSet(pCnt);
204 
205  if ( pCnt->IsCompletePaint() || !pCnt->IsTextFrame() )
206  {
207  SwRect aPaint( pCnt->GetPaintArea() );
208  if ( !PaintContent_( pCnt, pPage, aPaint ) )
209  pCnt->ResetCompletePaint();
210  }
211  else
212  {
213  // paint the area between printing bottom and frame bottom and
214  // the area left and right beside the frame, if its height changed.
215  long nOldHeight = aRectFnSet.GetHeight(rOldRect);
216  long nNewHeight = aRectFnSet.GetHeight(pCnt->getFrameArea());
217  const bool bHeightDiff = nOldHeight != nNewHeight;
218  if( bHeightDiff )
219  {
220  // consider whole potential paint area.
221  SwRect aDrawRect( pCnt->GetPaintArea() );
222  if( nOldHeight > nNewHeight )
223  nOldBottom = aRectFnSet.GetPrtBottom(*pCnt);
224  aRectFnSet.SetTop( aDrawRect, nOldBottom );
225  PaintContent_( pCnt, pPage, aDrawRect );
226  }
227  // paint content area
228  SwRect aPaintRect = static_cast<SwTextFrame*>(const_cast<SwContentFrame*>(pCnt))->GetPaintSwRect();
229  PaintContent_( pCnt, pPage, aPaintRect );
230  }
231 
232  if ( pCnt->IsRetouche() && !pCnt->GetNext() )
233  {
234  const SwFrame *pTmp = pCnt;
235  if( pCnt->IsInSct() )
236  {
237  const SwSectionFrame* pSct = pCnt->FindSctFrame();
238  if( pSct->IsRetouche() && !pSct->GetNext() )
239  pTmp = pSct;
240  }
241  SwRect aRect( pTmp->GetUpper()->GetPaintArea() );
242  aRectFnSet.SetTop( aRect, aRectFnSet.GetPrtBottom(*pTmp) );
243  if ( !PaintContent_( pCnt, pPage, aRect ) )
244  pCnt->ResetRetouche();
245  }
246 }
247 
249  : m_pRoot(pRt),
250  m_pImp( pI ),
251  m_pWatch(pWatch),
252  m_pOptTab( nullptr ),
253  m_nPreInvaPage( USHRT_MAX ),
254  m_nStartTicks( std::clock() ),
255  m_nEndPage( USHRT_MAX ),
256  m_nCheckPageNum( USHRT_MAX ),
257  m_pCurPage( nullptr ),
258  m_nTabLevel( 0 ),
259  m_nCallCount( 0 )
260 {
265  // init new flag <mbFormatContentOnInterrupt>.
267 
268  assert(!m_pImp->m_pLayAction); // there can be only one SwLayAction
269  m_pImp->m_pLayAction = this; // register there
270 }
271 
273 {
274  OSL_ENSURE( !m_pWait, "Wait object not destroyed" );
275  m_pImp->m_pLayAction = nullptr; // unregister
276 }
277 
279 {
280  return m_bInterrupt || (m_pWatch && m_pWatch->exceededRuntime());
281 }
282 
284 {
285  m_pOptTab = nullptr;
286  m_nStartTicks = std::clock();
291  m_pCurPage = nullptr;
292 }
293 
295 {
296  // switching from the normal to the browser mode, empty pages may be
297  // retained for an annoyingly long time, so delete them here
298  bool bRet = false;
299  const SwViewShell *pSh = m_pRoot->GetCurrShell();
300  if( pSh && pSh->GetViewOptions()->getBrowseMode() )
301  {
302  SwPageFrame *pPage = static_cast<SwPageFrame*>(m_pRoot->Lower());
303  do
304  {
305  if ( (pPage->GetSortedObjs() && pPage->GetSortedObjs()->size()) ||
306  pPage->ContainsContent() )
307  pPage = static_cast<SwPageFrame*>(pPage->GetNext());
308  else
309  {
310  bRet = true;
311  SwPageFrame *pDel = pPage;
312  pPage = static_cast<SwPageFrame*>(pPage->GetNext());
313  pDel->Cut();
314  SwFrame::DestroyFrame(pDel);
315  }
316  } while ( pPage );
317  }
318  return bRet;
319 }
320 
321 void SwLayAction::Action(OutputDevice* pRenderContext)
322 {
323  m_bActionInProgress = true;
324 
325  //TurboMode? Hands-off during idle-format
326  if ( IsPaint() && !IsIdle() && TurboAction() )
327  {
328  m_pWait.reset();
330  m_bActionInProgress = false;
332  return;
333  }
334  else if ( m_pRoot->GetTurbo() )
335  {
337  const SwFrame *pFrame = m_pRoot->GetTurbo();
338  m_pRoot->ResetTurbo();
339  pFrame->InvalidatePage();
340  }
342 
343  if ( IsCalcLayout() )
344  SetCheckPages( false );
345 
346  InternalAction(pRenderContext);
348  while ( IsAgain() )
349  {
350  m_bAgain = m_bNextCycle = false;
351  InternalAction(pRenderContext);
353  }
355 
356  m_pWait.reset();
357 
358  //Turbo-Action permitted again for all cases.
360  m_pRoot->ResetTurbo();
361 
362  SetCheckPages( true );
363 
364  m_bActionInProgress = false;
365 }
366 
368 {
369  SwContentFrame *pCnt = pPage->FindFirstBodyContent();
370  SwContentFrame *pChk = pCnt;
371  bool bPageChgd = false;
372  while ( pCnt && pCnt->IsFollow() )
373  pCnt = pCnt->FindMaster();
374  if ( pCnt && pChk != pCnt )
375  { bPageChgd = true;
376  pPage = pCnt->FindPageFrame();
377  }
378 
379  if ( !pPage->GetFormat()->GetDoc()->GetFootnoteIdxs().empty() )
380  {
381  SwFootnoteContFrame *pCont = pPage->FindFootnoteCont();
382  if ( pCont )
383  {
384  pCnt = pCont->ContainsContent();
385  pChk = pCnt;
386  while ( pCnt && pCnt->IsFollow() )
387  pCnt = static_cast<SwContentFrame*>(pCnt->FindPrev());
388  if ( pCnt && pCnt != pChk )
389  {
390  if ( bPageChgd )
391  {
392  // Use the 'topmost' page
393  SwPageFrame *pTmp = pCnt->FindPageFrame();
394  if ( pPage->GetPhyPageNum() > pTmp->GetPhyPageNum() )
395  pPage = pTmp;
396  }
397  else
398  pPage = pCnt->FindPageFrame();
399  }
400  }
401  }
402  return pPage;
403 }
404 
405 // unlock position on start and end of page
406 // layout process.
407 static void unlockPositionOfObjects( SwPageFrame *pPageFrame )
408 {
409  assert( pPageFrame );
410 
411  SwSortedObjs* pObjs = pPageFrame->GetSortedObjs();
412  if ( pObjs )
413  {
414  for (SwAnchoredObject* pObj : *pObjs)
415  {
416  pObj->UnlockPosition();
417  }
418  }
419 }
420 
422 {
423  OSL_ENSURE( m_pRoot->Lower()->IsPageFrame(), ":-( No page below the root.");
424 
425  m_pRoot->Calc(pRenderContext);
426 
427  // Figure out the first invalid page or the first one to be formatted,
428  // respectively. A complete-action means the first invalid page.
429  // However, the first page to be formatted might be the one having the
430  // number 1. If we're doing a fake formatting, the number of the first
431  // page is the number of the first visible page.
432  SwPageFrame *pPage = IsComplete() ? static_cast<SwPageFrame*>(m_pRoot->Lower()) :
433  m_pImp->GetFirstVisPage(pRenderContext);
434  if ( !pPage )
435  pPage = static_cast<SwPageFrame*>(m_pRoot->Lower());
436 
437  // If there's a first-flow-Content in the first visible page that's also a Follow,
438  // we switch the page back to the original master of that Content.
439  if ( !IsComplete() )
440  pPage = CheckFirstVisPage( pPage );
441  sal_uInt16 nFirstPageNum = pPage->GetPhyPageNum();
442 
443  while ( pPage && !pPage->IsInvalid() && !pPage->IsInvalidFly() )
444  pPage = static_cast<SwPageFrame*>(pPage->GetNext());
445 
447  bool bNoLoop = pPage && SwLayouter::StartLoopControl( m_pRoot->GetFormat()->GetDoc(), pPage );
448  sal_uInt16 nPercentPageNum = 0;
449  while ((!IsInterrupt() && pPage) || (m_nCheckPageNum != USHRT_MAX))
450  {
451  if (!pPage && m_nCheckPageNum != USHRT_MAX)
452  {
453  SwPageFrame *pPg = static_cast<SwPageFrame*>(m_pRoot->Lower());
454  while (pPg && pPg->GetPhyPageNum() < m_nCheckPageNum)
455  pPg = static_cast<SwPageFrame*>(pPg->GetNext());
456  if (pPg)
457  pPage = pPg;
458  if (!pPage)
459  break;
460 
461  SwPageFrame *pTmp = pPage->GetPrev() ?
462  static_cast<SwPageFrame*>(pPage->GetPrev()) : pPage;
463  SetCheckPages( true );
464  SwFrame::CheckPageDescs( pPage, true, &pTmp );
465  SetCheckPages( false );
467  pPage = pTmp;
468  continue;
469  }
470 
471  if ( m_nEndPage != USHRT_MAX && pPage->GetPhyPageNum() > nPercentPageNum )
472  {
473  nPercentPageNum = pPage->GetPhyPageNum();
474  ::SetProgressState( nPercentPageNum, m_pImp->GetShell()->GetDoc()->GetDocShell());
475  }
476  m_pOptTab = nullptr;
477 
478  // No Shortcut for Idle or CalcLayout
479  if ( !IsIdle() && !IsComplete() && IsShortCut( pPage ) )
480  {
482  XCHECKPAGE;
483  if ( !IsInterrupt() &&
485  {
486  if ( m_pRoot->IsAssertFlyPages() )
488  if ( m_pRoot->IsSuperfluous() )
489  {
490  bool bOld = IsAgain();
492  m_bAgain = bOld;
493  }
494  if ( IsAgain() )
495  {
496  if( bNoLoop )
497  rLayoutAccess.GetLayouter()->EndLoopControl();
498  return;
499  }
500  pPage = static_cast<SwPageFrame*>(m_pRoot->Lower());
501  while ( pPage && !pPage->IsInvalid() && !pPage->IsInvalidFly() )
502  pPage = static_cast<SwPageFrame*>(pPage->GetNext());
503  while ( pPage && pPage->GetNext() &&
504  pPage->GetPhyPageNum() < nFirstPageNum )
505  pPage = static_cast<SwPageFrame*>(pPage->GetNext());
506  continue;
507  }
508  break;
509  }
510  else
511  {
513  XCHECKPAGE;
514 
515  while ( !IsInterrupt() && !IsNextCycle() &&
516  ((pPage->GetSortedObjs() && pPage->IsInvalidFly()) || pPage->IsInvalid()) )
517  {
518  unlockPositionOfObjects( pPage );
519 
520  SwObjectFormatter::FormatObjsAtFrame( *pPage, *pPage, this );
521  if ( !pPage->GetSortedObjs() )
522  {
523  // If there are no (more) Flys, the flags are superfluous.
524  pPage->ValidateFlyLayout();
525  pPage->ValidateFlyContent();
526  }
527  // change condition
528  while ( !IsInterrupt() && !IsNextCycle() &&
529  ( pPage->IsInvalid() ||
530  (pPage->GetSortedObjs() && pPage->IsInvalidFly()) ) )
531  {
532  PROTOCOL( pPage, PROT::FileInit, DbgAction::NONE, nullptr)
533  XCHECKPAGE;
534 
535  // new loop control
536  int nLoopControlRuns_1 = 0;
537  const int nLoopControlMax = 20;
538 
539  while ( !IsNextCycle() && pPage->IsInvalidLayout() )
540  {
541  pPage->ValidateLayout();
542 
543  if ( ++nLoopControlRuns_1 > nLoopControlMax )
544  {
545  OSL_FAIL( "LoopControl_1 in SwLayAction::InternalAction" );
546  break;
547  }
548 
549  FormatLayout( pRenderContext, pPage );
550  XCHECKPAGE;
551  }
552  // change condition
553  if ( !IsNextCycle() &&
554  ( pPage->IsInvalidContent() ||
555  (pPage->GetSortedObjs() && pPage->IsInvalidFly()) ) )
556  {
557  pPage->ValidateFlyInCnt();
558  pPage->ValidateContent();
559  pPage->ValidateFlyLayout();
560  pPage->ValidateFlyContent();
561  if ( !FormatContent( pPage ) )
562  {
563  XCHECKPAGE;
564  pPage->InvalidateContent();
565  pPage->InvalidateFlyInCnt();
566  pPage->InvalidateFlyLayout();
567  pPage->InvalidateFlyContent();
568  if ( IsBrowseActionStop() )
569  m_bInterrupt = true;
570  }
571  }
572  if( bNoLoop )
573  rLayoutAccess.GetLayouter()->LoopControl( pPage );
574  }
575 
576  unlockPositionOfObjects( pPage );
577  }
578 
579  // A previous page may be invalid again.
580  XCHECKPAGE;
581  if ( !pPage->GetSortedObjs() )
582  {
583  // If there are no (more) Flys, the flags are superfluous.
584  pPage->ValidateFlyLayout();
585  pPage->ValidateFlyContent();
586  }
587 
588  if (!IsInterrupt())
589  {
590  SetNextCycle( false );
591 
592  if ( m_nPreInvaPage != USHRT_MAX )
593  {
594  if( !IsComplete() && m_nPreInvaPage + 2 < nFirstPageNum )
595  {
597  SwPageFrame *pTmpPage = m_pImp->GetFirstVisPage(pRenderContext);
598  nFirstPageNum = pTmpPage->GetPhyPageNum();
599  if( m_nPreInvaPage < nFirstPageNum )
600  {
601  m_nPreInvaPage = nFirstPageNum;
602  pPage = pTmpPage;
603  }
604  }
605  while ( pPage->GetPrev() && pPage->GetPhyPageNum() > m_nPreInvaPage )
606  pPage = static_cast<SwPageFrame*>(pPage->GetPrev());
608  }
609 
610  while ( pPage->GetPrev() &&
611  ( static_cast<SwPageFrame*>(pPage->GetPrev())->IsInvalid() ||
612  ( static_cast<SwPageFrame*>(pPage->GetPrev())->GetSortedObjs() &&
613  static_cast<SwPageFrame*>(pPage->GetPrev())->IsInvalidFly())) &&
614  (static_cast<SwPageFrame*>(pPage->GetPrev())->GetPhyPageNum() >=
615  nFirstPageNum) )
616  {
617  pPage = static_cast<SwPageFrame*>(pPage->GetPrev());
618  }
619 
620  // Continue to the next invalid page
621  while ( pPage && !pPage->IsInvalid() &&
622  (!pPage->GetSortedObjs() || !pPage->IsInvalidFly()) )
623  {
624  pPage = static_cast<SwPageFrame*>(pPage->GetNext());
625  }
626  if( bNoLoop )
627  rLayoutAccess.GetLayouter()->LoopControl( pPage );
628  }
629  }
630 
631  if ( !pPage && !IsInterrupt() &&
633  {
634  if ( m_pRoot->IsAssertFlyPages() )
636  if ( m_pRoot->IsSuperfluous() )
637  {
638  bool bOld = IsAgain();
640  m_bAgain = bOld;
641  }
642  if ( IsAgain() )
643  {
644  if( bNoLoop )
645  rLayoutAccess.GetLayouter()->EndLoopControl();
646  return;
647  }
648  pPage = static_cast<SwPageFrame*>(m_pRoot->Lower());
649  while ( pPage && !pPage->IsInvalid() && !pPage->IsInvalidFly() )
650  pPage = static_cast<SwPageFrame*>(pPage->GetNext());
651  while ( pPage && pPage->GetNext() &&
652  pPage->GetPhyPageNum() < nFirstPageNum )
653  pPage = static_cast<SwPageFrame*>(pPage->GetNext());
654  }
655  }
656 
657  if ( IsInterrupt() && pPage )
658  {
659  // If we have input, we don't want to format content anymore, but
660  // we still should clean the layout.
661  // Otherwise, the following situation might arise:
662  // The user enters some text at the end of the paragraph of the last
663  // page, causing the paragraph to create a Follow for the next page.
664  // Meanwhile the user continues typing, so we have input while
665  // still formatting.
666  // The paragraph on the new page has already been partially formatted,
667  // and the new page has been fully formatted and is set to CompletePaint,
668  // but hasn't added itself to the area to be output. Then we paint,
669  // the CompletePaint of the page is reset because the new paragraph
670  // already added itself, but the borders of the page haven't been painted
671  // yet.
672  // Oh well, with the inevitable following LayAction, the page doesn't
673  // register itself, because it's (LayoutFrame) flags have been reset
674  // already - the border of the page will never be painted.
675  SwPageFrame *pPg = pPage;
676  XCHECKPAGE;
677  const SwRect &rVis = m_pImp->GetShell()->VisArea();
678 
679  while( pPg && pPg->getFrameArea().Bottom() < rVis.Top() )
680  pPg = static_cast<SwPageFrame*>(pPg->GetNext());
681  if( pPg != pPage )
682  pPg = pPg ? static_cast<SwPageFrame*>(pPg->GetPrev()) : pPage;
683 
684  // set flag for interrupt content formatting
686  long nBottom = rVis.Bottom();
687  // #i42586# - format current page, if idle action is active
688  // This is an optimization for the case that the interrupt is created by
689  // the move of a form control object, which is represented by a window.
690  while ( pPg && ( pPg->getFrameArea().Top() < nBottom ||
691  ( IsIdle() && pPg == pPage ) ) )
692  {
694 
695  XCHECKPAGE;
696 
697  // new loop control
698  int nLoopControlRuns_2 = 0;
699  const int nLoopControlMax = 20;
700 
701  // special case: interrupt content formatting
702  // conditions are incorrect and are too strict.
703  // adjust interrupt formatting to normal page formatting - see above.
704  while ( ( mbFormatContentOnInterrupt &&
705  ( pPg->IsInvalid() ||
706  ( pPg->GetSortedObjs() && pPg->IsInvalidFly() ) ) ) ||
707  ( !mbFormatContentOnInterrupt && pPg->IsInvalidLayout() ) )
708  {
709  XCHECKPAGE;
710  // format also at-page anchored objects
711  SwObjectFormatter::FormatObjsAtFrame( *pPg, *pPg, this );
712  if ( !pPg->GetSortedObjs() )
713  {
714  pPg->ValidateFlyLayout();
715  pPg->ValidateFlyContent();
716  }
717 
718  // new loop control
719  int nLoopControlRuns_3 = 0;
720 
721  while ( pPg->IsInvalidLayout() )
722  {
723  pPg->ValidateLayout();
724 
725  if ( ++nLoopControlRuns_3 > nLoopControlMax )
726  {
727  OSL_FAIL( "LoopControl_3 in Interrupt formatting in SwLayAction::InternalAction" );
728  break;
729  }
730 
731  FormatLayout( pRenderContext, pPg );
732  XCHECKPAGE;
733  }
734 
735  if ( mbFormatContentOnInterrupt &&
736  ( pPg->IsInvalidContent() ||
737  ( pPg->GetSortedObjs() && pPg->IsInvalidFly() ) ) )
738  {
739  pPg->ValidateFlyInCnt();
740  pPg->ValidateContent();
741  pPg->ValidateFlyLayout();
742  pPg->ValidateFlyContent();
743 
744  if ( ++nLoopControlRuns_2 > nLoopControlMax )
745  {
746  OSL_FAIL( "LoopControl_2 in Interrupt formatting in SwLayAction::InternalAction" );
747  break;
748  }
749 
750  if ( !FormatContent( pPg ) )
751  {
752  XCHECKPAGE;
753  pPg->InvalidateContent();
754  pPg->InvalidateFlyInCnt();
755  pPg->InvalidateFlyLayout();
756  pPg->InvalidateFlyContent();
757  }
758  // we are satisfied if the content is formatted once complete.
759  else
760  {
761  break;
762  }
763  }
764  }
765 
767  pPg = static_cast<SwPageFrame*>(pPg->GetNext());
768  }
769  // reset flag for special interrupt content formatting.
770  mbFormatContentOnInterrupt = false;
771  }
772  m_pOptTab = nullptr;
773  if( bNoLoop )
774  rLayoutAccess.GetLayouter()->EndLoopControl();
775 }
776 
778 {
779  const SwPageFrame *pPage = nullptr;
780  if ( !pCnt->isFrameAreaDefinitionValid() || pCnt->IsCompletePaint() || pCnt->IsRetouche() )
781  {
782  const SwRect aOldRect( pCnt->UnionFrame( true ) );
783  const long nOldBottom = pCnt->getFrameArea().Top() + pCnt->getFramePrintArea().Bottom();
784  pCnt->Calc(m_pImp->GetShell()->GetOut());
785  if ( pCnt->getFrameArea().Bottom() < aOldRect.Bottom() )
786  pCnt->SetRetouche();
787 
788  pPage = pCnt->FindPageFrame();
789  PaintContent( pCnt, pPage, aOldRect, nOldBottom );
790 
791  if ( !pCnt->GetValidLineNumFlag() && pCnt->IsTextFrame() )
792  {
793  const sal_uLong nAllLines = static_cast<const SwTextFrame*>(pCnt)->GetAllLines();
794  const_cast<SwTextFrame*>(static_cast<const SwTextFrame*>(pCnt))->RecalcAllLines();
795  if ( nAllLines != static_cast<const SwTextFrame*>(pCnt)->GetAllLines() )
796  {
797  if ( IsPaintExtraData() )
798  m_pImp->GetShell()->AddPaintRect( pCnt->getFrameArea() );
799  // This is to calculate the remaining LineNums on the page,
800  // and we don't stop processing here. To perform this inside RecalcAllLines
801  // would be expensive, because we would have to notify the page even
802  // in unnecessary cases (normal actions).
803  const SwContentFrame *pNxt = pCnt->GetNextContentFrame();
804  while ( pNxt &&
805  (pNxt->IsInTab() || pNxt->IsInDocBody() != pCnt->IsInDocBody()) )
806  pNxt = pNxt->GetNextContentFrame();
807  if ( pNxt )
808  pNxt->InvalidatePage();
809  }
810  return false;
811  }
812 
813  if ( pPage->IsInvalidLayout() || (pPage->GetSortedObjs() && pPage->IsInvalidFly()) )
814  return false;
815  }
816  if ( !pPage )
817  pPage = pCnt->FindPageFrame();
818 
819  // format floating screen objects at content frame.
820  if ( pCnt->IsTextFrame() &&
821  !SwObjectFormatter::FormatObjsAtFrame( *const_cast<SwContentFrame*>(pCnt),
822  *pPage, this ) )
823  {
824  return false;
825  }
826 
827  if ( pPage->IsInvalidContent() )
828  return false;
829  return true;
830 }
831 
833 {
834  bool bRet = true;
835 
836  if ( m_pRoot->GetTurbo() )
837  {
838  if ( !TurboAction_( m_pRoot->GetTurbo() ) )
839  bRet = false;
840  m_pRoot->ResetTurbo();
841  }
842  else
843  bRet = false;
844  return bRet;
845 }
846 
847 static bool lcl_IsInvaLay( const SwFrame *pFrame, long nBottom )
848 {
849  return !pFrame->isFrameAreaDefinitionValid() ||
850  (pFrame->IsCompletePaint() && ( pFrame->getFrameArea().Top() < nBottom ) );
851 }
852 
853 static const SwFrame *lcl_FindFirstInvaLay( const SwFrame *pFrame, long nBottom )
854 {
855  OSL_ENSURE( pFrame->IsLayoutFrame(), "FindFirstInvaLay, no LayFrame" );
856 
857  if (lcl_IsInvaLay(pFrame, nBottom))
858  return pFrame;
859  pFrame = static_cast<const SwLayoutFrame*>(pFrame)->Lower();
860  while ( pFrame )
861  {
862  if ( pFrame->IsLayoutFrame() )
863  {
864  if (lcl_IsInvaLay(pFrame, nBottom))
865  return pFrame;
866  const SwFrame *pTmp;
867  if ( nullptr != (pTmp = lcl_FindFirstInvaLay( pFrame, nBottom )) )
868  return pTmp;
869  }
870  pFrame = pFrame->GetNext();
871  }
872  return nullptr;
873 }
874 
875 static const SwFrame *lcl_FindFirstInvaContent( const SwLayoutFrame *pLay, long nBottom,
876  const SwContentFrame *pFirst )
877 {
878  const SwContentFrame *pCnt = pFirst ? pFirst->GetNextContentFrame() :
879  pLay->ContainsContent();
880  while ( pCnt )
881  {
882  if ( !pCnt->isFrameAreaDefinitionValid() || pCnt->IsCompletePaint() )
883  {
884  if ( pCnt->getFrameArea().Top() <= nBottom )
885  return pCnt;
886  }
887 
888  if ( pCnt->GetDrawObjs() )
889  {
890  const SwSortedObjs &rObjs = *pCnt->GetDrawObjs();
891  for (SwAnchoredObject* pObj : rObjs)
892  {
893  if ( auto pFly = dynamic_cast< const SwFlyFrame *>( pObj ) )
894  {
895  if ( pFly->IsFlyInContentFrame() )
896  {
897  if ( static_cast<const SwFlyInContentFrame*>(pFly)->IsInvalid() ||
898  pFly->IsCompletePaint() )
899  {
900  if ( pFly->getFrameArea().Top() <= nBottom )
901  return pFly;
902  }
903  const SwFrame *pFrame = lcl_FindFirstInvaContent( pFly, nBottom, nullptr );
904  if ( pFrame && pFrame->getFrameArea().Bottom() <= nBottom )
905  return pFrame;
906  }
907  }
908  }
909  }
910  if ( pCnt->getFrameArea().Top() > nBottom && !pCnt->IsInTab() )
911  return nullptr;
912  pCnt = pCnt->GetNextContentFrame();
913  if ( !pLay->IsAnLower( pCnt ) )
914  break;
915  }
916  return nullptr;
917 }
918 
919 // consider drawing objects
920 static const SwAnchoredObject* lcl_FindFirstInvaObj( const SwPageFrame* _pPage,
921  long _nBottom )
922 {
923  OSL_ENSURE( _pPage->GetSortedObjs(), "FindFirstInvaObj, no Objs" );
924 
925  for (SwAnchoredObject* pObj : *_pPage->GetSortedObjs())
926  {
927  if ( auto pFly = dynamic_cast< const SwFlyFrame *>( pObj ) )
928  {
929  if ( pFly->getFrameArea().Top() <= _nBottom )
930  {
931  if ( pFly->IsInvalid() || pFly->IsCompletePaint() )
932  return pFly;
933 
934  const SwFrame* pTmp;
935  if ( nullptr != (pTmp = lcl_FindFirstInvaContent( pFly, _nBottom, nullptr )) &&
936  pTmp->getFrameArea().Top() <= _nBottom )
937  return pFly;
938  }
939  }
940  else if ( auto pDrawObject = dynamic_cast< const SwAnchoredDrawObject *>( pObj ) )
941  {
942  if ( !pDrawObject->IsValidPos() )
943  {
944  return pObj;
945  }
946  }
947  }
948  return nullptr;
949 }
950 
951 /* Returns True if the page lies directly below or right of the visible area.
952  *
953  * It's possible for things to change in such a way that the processing
954  * (of the caller!) has to continue with the predecessor of the passed page.
955  * The parameter might therefore get modified!
956  * For BrowseMode, you may even activate the ShortCut if the invalid content
957  * of the page lies below the visible area.
958  */
960 {
961  vcl::RenderContext* pRenderContext = m_pImp->GetShell()->GetOut();
962  bool bRet = false;
963  const SwViewShell *pSh = m_pRoot->GetCurrShell();
964  const bool bBrowse = pSh && pSh->GetViewOptions()->getBrowseMode();
965 
966  // If the page is not valid, we quickly format it, otherwise
967  // there's gonna be no end of trouble
968  if ( !prPage->isFrameAreaDefinitionValid() )
969  {
970  if ( bBrowse )
971  {
972  // format complete page
973  // Thus, loop on all lowers of the page <prPage>, instead of only
974  // format its first lower.
975  // NOTE: In online layout (bBrowse == true) a page can contain
976  // a header frame and/or a footer frame beside the body frame.
977  prPage->Calc(pRenderContext);
978  SwFrame* pPageLowerFrame = prPage->Lower();
979  while ( pPageLowerFrame )
980  {
981  pPageLowerFrame->Calc(pRenderContext);
982  pPageLowerFrame = pPageLowerFrame->GetNext();
983  }
984  }
985  else
986  FormatLayout( pSh ? pSh->GetOut() : nullptr, prPage );
987  if ( IsAgain() )
988  return false;
989  }
990 
991  const SwRect &rVis = m_pImp->GetShell()->VisArea();
992  if ( (prPage->getFrameArea().Top() >= rVis.Bottom()) ||
993  (prPage->getFrameArea().Left()>= rVis.Right()) )
994  {
995  bRet = true;
996 
997  // This is going to be a bit nasty: The first ContentFrame of this
998  // page in the Body text needs formatting; if it changes the page during
999  // that process, I need to start over a page further back, because we
1000  // have been processing a PageBreak.
1001  // Even more uncomfortable: The next ContentFrame must be formatted,
1002  // because it's possible for empty pages to exist temporarily (for example
1003  // a paragraph across multiple pages gets deleted or reduced in size).
1004 
1005  // This is irrelevant for the browser, if the last Cnt above it
1006  // isn't visible anymore.
1007 
1008  const SwPageFrame *p2ndPage = prPage;
1009  const SwContentFrame *pContent;
1010  const SwLayoutFrame* pBody = p2ndPage->FindBodyCont();
1011  if( p2ndPage->IsFootnotePage() && pBody )
1012  pBody = static_cast<const SwLayoutFrame*>(pBody->GetNext());
1013  pContent = pBody ? pBody->ContainsContent() : nullptr;
1014  while ( p2ndPage && !pContent )
1015  {
1016  p2ndPage = static_cast<const SwPageFrame*>(p2ndPage->GetNext());
1017  if( p2ndPage )
1018  {
1019  pBody = p2ndPage->FindBodyCont();
1020  if( p2ndPage->IsFootnotePage() && pBody )
1021  pBody = static_cast<const SwLayoutFrame*>(pBody->GetNext());
1022  pContent = pBody ? pBody->ContainsContent() : nullptr;
1023  }
1024  }
1025  if ( pContent )
1026  {
1027  bool bTstCnt = true;
1028  if ( bBrowse )
1029  {
1030  // Is the Cnt before already invisible?
1031  const SwFrame *pLst = pContent;
1032  if ( pLst->IsInTab() )
1033  pLst = pContent->FindTabFrame();
1034  if ( pLst->IsInSct() )
1035  pLst = pContent->FindSctFrame();
1036  pLst = pLst->FindPrev();
1037  if ( pLst &&
1038  (pLst->getFrameArea().Top() >= rVis.Bottom() ||
1039  pLst->getFrameArea().Left()>= rVis.Right()) )
1040  {
1041  bTstCnt = false;
1042  }
1043  }
1044 
1045  if ( bTstCnt )
1046  {
1047  // check after each frame calculation,
1048  // if the content frame has changed the page. If yes, no other
1049  // frame calculation is performed
1050  bool bPageChg = false;
1051 
1052  if ( pContent->IsInSct() )
1053  {
1054  const SwSectionFrame *pSct = const_cast<SwFrame*>(static_cast<SwFrame const *>(pContent))->ImplFindSctFrame();
1055  if ( !pSct->isFrameAreaDefinitionValid() )
1056  {
1057  pSct->Calc(pRenderContext);
1058  pSct->SetCompletePaint();
1059  if ( IsAgain() )
1060  return false;
1061 
1062  bPageChg = pContent->FindPageFrame() != p2ndPage &&
1063  prPage->GetPrev();
1064  }
1065  }
1066 
1067  if ( !bPageChg && !pContent->isFrameAreaDefinitionValid() )
1068  {
1069  pContent->Calc(pRenderContext);
1070  pContent->SetCompletePaint();
1071  if ( IsAgain() )
1072  return false;
1073 
1074  bPageChg = pContent->FindPageFrame() != p2ndPage &&
1075  prPage->GetPrev();
1076  }
1077 
1078  if ( !bPageChg && pContent->IsInTab() )
1079  {
1080  const SwTabFrame *pTab = const_cast<SwFrame*>(static_cast<SwFrame const *>(pContent))->ImplFindTabFrame();
1081  if ( !pTab->isFrameAreaDefinitionValid() )
1082  {
1083  pTab->Calc(pRenderContext);
1084  pTab->SetCompletePaint();
1085  if ( IsAgain() )
1086  return false;
1087 
1088  bPageChg = pContent->FindPageFrame() != p2ndPage &&
1089  prPage->GetPrev();
1090  }
1091  }
1092 
1093  if ( !bPageChg && pContent->IsInSct() )
1094  {
1095  const SwSectionFrame *pSct = const_cast<SwFrame*>(static_cast<SwFrame const *>(pContent))->ImplFindSctFrame();
1096  if ( !pSct->isFrameAreaDefinitionValid() )
1097  {
1098  pSct->Calc(pRenderContext);
1099  pSct->SetCompletePaint();
1100  if ( IsAgain() )
1101  return false;
1102 
1103  bPageChg = pContent->FindPageFrame() != p2ndPage &&
1104  prPage->GetPrev();
1105  }
1106  }
1107 
1108  if ( bPageChg )
1109  {
1110  bRet = false;
1111  const SwPageFrame* pTmp = pContent->FindPageFrame();
1112  if ( pTmp->GetPhyPageNum() < prPage->GetPhyPageNum() &&
1113  pTmp->IsInvalid() )
1114  {
1115  prPage = const_cast<SwPageFrame*>(pTmp);
1116  }
1117  else
1118  {
1119  prPage = static_cast<SwPageFrame*>(prPage->GetPrev());
1120  }
1121  }
1122  // no shortcut, if at previous page
1123  // an anchored object is registered, whose anchor is <pContent>.
1124  else if ( prPage->GetPrev() )
1125  {
1126  SwSortedObjs* pObjs =
1127  static_cast<SwPageFrame*>(prPage->GetPrev())->GetSortedObjs();
1128  if ( pObjs )
1129  {
1130  for (SwAnchoredObject* pObj : *pObjs)
1131  {
1132  if ( pObj->GetAnchorFrameContainingAnchPos() == pContent )
1133  {
1134  bRet = false;
1135  break;
1136  }
1137  }
1138  }
1139  }
1140  }
1141  }
1142  }
1143 
1144  if ( !bRet && bBrowse )
1145  {
1146  const long nBottom = rVis.Bottom();
1147  const SwAnchoredObject* pObj( nullptr );
1148  if ( prPage->GetSortedObjs() &&
1149  (prPage->IsInvalidFlyLayout() || prPage->IsInvalidFlyContent()) &&
1150  nullptr != (pObj = lcl_FindFirstInvaObj( prPage, nBottom )) &&
1151  pObj->GetObjRect().Top() <= nBottom )
1152  {
1153  return false;
1154  }
1155  const SwFrame* pFrame( nullptr );
1156  if ( prPage->IsInvalidLayout() &&
1157  nullptr != (pFrame = lcl_FindFirstInvaLay( prPage, nBottom )) &&
1158  pFrame->getFrameArea().Top() <= nBottom )
1159  {
1160  return false;
1161  }
1162  if ( (prPage->IsInvalidContent() || prPage->IsInvalidFlyInCnt()) &&
1163  nullptr != (pFrame = lcl_FindFirstInvaContent( prPage, nBottom, nullptr )) &&
1164  pFrame->getFrameArea().Top() <= nBottom )
1165  {
1166  return false;
1167  }
1168  bRet = true;
1169  }
1170  return bRet;
1171 }
1172 
1173 // introduce support for vertical layout
1174 bool SwLayAction::FormatLayout( OutputDevice *pRenderContext, SwLayoutFrame *pLay, bool bAddRect )
1175 {
1176  // save page for loop control
1177  if( pLay->IsPageFrame() && static_cast<SwPageFrame*>(pLay) != m_pCurPage )
1178  {
1179  m_nCallCount = 0;
1180  m_pCurPage = static_cast<SwPageFrame*>(pLay);
1181  }
1182  OSL_ENSURE( !IsAgain(), "Attention to the invalid page." );
1183  if ( IsAgain() )
1184  return false;
1185 
1186  bool bChanged = false;
1187  bool bAlreadyPainted = false;
1188  // remember frame at complete paint
1189  SwRect aFrameAtCompletePaint;
1190 
1191  if ( !pLay->isFrameAreaDefinitionValid() || pLay->IsCompletePaint() )
1192  {
1193  if ( pLay->GetPrev() && !pLay->GetPrev()->isFrameAreaDefinitionValid() )
1194  pLay->GetPrev()->SetCompletePaint();
1195 
1196  SwRect aOldFrame( pLay->getFrameArea() );
1197  SwRect aOldRect( aOldFrame );
1198  if( pLay->IsPageFrame() )
1199  {
1200  aOldRect = static_cast<SwPageFrame*>(pLay)->GetBoundRect(pRenderContext);
1201  }
1202 
1203  {
1204  SwFrameDeleteGuard aDeleteGuard(pLay);
1205  pLay->Calc(pRenderContext);
1206  }
1207 
1208  if ( aOldFrame != pLay->getFrameArea() )
1209  bChanged = true;
1210 
1211  bool bNoPaint = false;
1212  if ( pLay->IsPageBodyFrame() &&
1213  pLay->getFrameArea().Pos() == aOldRect.Pos() &&
1214  pLay->Lower() )
1215  {
1216  const SwViewShell *pSh = pLay->getRootFrame()->GetCurrShell();
1217  // Limitations because of headers / footers
1218  if( pSh && pSh->GetViewOptions()->getBrowseMode() &&
1219  !( pLay->IsCompletePaint() && pLay->FindPageFrame()->FindFootnoteCont() ) )
1220  bNoPaint = true;
1221  }
1222 
1223  if ( !bNoPaint && IsPaint() && bAddRect && (pLay->IsCompletePaint() || bChanged) )
1224  {
1225  SwRect aPaint( pLay->getFrameArea() );
1226  // consider border and shadow for
1227  // page frames -> enlarge paint rectangle correspondingly.
1228  if ( pLay->IsPageFrame() )
1229  {
1230  SwPageFrame* pPageFrame = static_cast<SwPageFrame*>(pLay);
1231  aPaint = pPageFrame->GetBoundRect(pRenderContext);
1232  }
1233 
1234  bool bPageInBrowseMode = pLay->IsPageFrame();
1235  if( bPageInBrowseMode )
1236  {
1237  const SwViewShell *pSh = pLay->getRootFrame()->GetCurrShell();
1238  if( !pSh || !pSh->GetViewOptions()->getBrowseMode() )
1239  bPageInBrowseMode = false;
1240  }
1241  if( bPageInBrowseMode )
1242  {
1243  // NOTE: no vertical layout in online layout
1244  // Is the change even visible?
1245  if ( pLay->IsCompletePaint() )
1246  {
1247  m_pImp->GetShell()->AddPaintRect( aPaint );
1248  bAddRect = false;
1249  }
1250  else
1251  {
1252  SwRegionRects aRegion( aOldRect );
1253  aRegion -= aPaint;
1254  for ( size_t i = 0; i < aRegion.size(); ++i )
1255  m_pImp->GetShell()->AddPaintRect( aRegion[i] );
1256  aRegion.ChangeOrigin( aPaint );
1257  aRegion.clear();
1258  aRegion.push_back( aPaint );
1259  aRegion -= aOldRect;
1260  for ( size_t i = 0; i < aRegion.size(); ++i )
1261  m_pImp->GetShell()->AddPaintRect( aRegion[i] );
1262  }
1263  }
1264  else
1265  {
1266  m_pImp->GetShell()->AddPaintRect( aPaint );
1267  bAlreadyPainted = true;
1268  // remember frame at complete paint
1269  aFrameAtCompletePaint = pLay->getFrameArea();
1270  }
1271 
1272  // provide paint of spacing
1273  // between pages (not only for in online mode).
1274  if ( pLay->IsPageFrame() )
1275  {
1276  const SwViewShell *pSh = pLay->getRootFrame()->GetCurrShell();
1277  const SwTwips nHalfDocBorder = pSh ? pSh->GetViewOptions()->GetGapBetweenPages()
1279  const bool bLeftToRightViewLayout = m_pRoot->IsLeftToRightViewLayout();
1280  const bool bPrev = bLeftToRightViewLayout ? pLay->GetPrev() : pLay->GetNext();
1281  const bool bNext = bLeftToRightViewLayout ? pLay->GetNext() : pLay->GetPrev();
1282  SwPageFrame* pPageFrame = static_cast<SwPageFrame*>(pLay);
1283  SwRect aPageRect( pLay->getFrameArea() );
1284 
1285  if(pSh)
1286  {
1288  pRenderContext,
1289  aPageRect, pPageFrame->IsLeftShadowNeeded(), pPageFrame->IsRightShadowNeeded(),
1291  }
1292 
1293  if ( bPrev )
1294  {
1295  // top
1296  SwRect aSpaceToPrevPage( aPageRect );
1297  aSpaceToPrevPage.Top( aSpaceToPrevPage.Top() - nHalfDocBorder );
1298  aSpaceToPrevPage.Bottom( pLay->getFrameArea().Top() );
1299  if(aSpaceToPrevPage.Height() > 0 && aSpaceToPrevPage.Width() > 0)
1300  m_pImp->GetShell()->AddPaintRect( aSpaceToPrevPage );
1301 
1302  // left
1303  aSpaceToPrevPage = aPageRect;
1304  aSpaceToPrevPage.Left( aSpaceToPrevPage.Left() - nHalfDocBorder );
1305  aSpaceToPrevPage.Right( pLay->getFrameArea().Left() );
1306  if(aSpaceToPrevPage.Height() > 0 && aSpaceToPrevPage.Width() > 0)
1307  m_pImp->GetShell()->AddPaintRect( aSpaceToPrevPage );
1308  }
1309  if ( bNext )
1310  {
1311  // bottom
1312  SwRect aSpaceToNextPage( aPageRect );
1313  aSpaceToNextPage.Bottom( aSpaceToNextPage.Bottom() + nHalfDocBorder );
1314  aSpaceToNextPage.Top( pLay->getFrameArea().Bottom() );
1315  if(aSpaceToNextPage.Height() > 0 && aSpaceToNextPage.Width() > 0)
1316  m_pImp->GetShell()->AddPaintRect( aSpaceToNextPage );
1317 
1318  // right
1319  aSpaceToNextPage = aPageRect;
1320  aSpaceToNextPage.Right( aSpaceToNextPage.Right() + nHalfDocBorder );
1321  aSpaceToNextPage.Left( pLay->getFrameArea().Right() );
1322  if(aSpaceToNextPage.Height() > 0 && aSpaceToNextPage.Width() > 0)
1323  m_pImp->GetShell()->AddPaintRect( aSpaceToNextPage );
1324  }
1325  }
1326  }
1327  pLay->ResetCompletePaint();
1328  }
1329 
1330  if ( IsPaint() && bAddRect &&
1331  !pLay->GetNext() && pLay->IsRetoucheFrame() && pLay->IsRetouche() )
1332  {
1333  // vertical layout support
1334  SwRectFnSet aRectFnSet(pLay);
1335  SwRect aRect( pLay->GetUpper()->GetPaintArea() );
1336  aRectFnSet.SetTop( aRect, aRectFnSet.GetPrtBottom(*pLay) );
1337  if ( !m_pImp->GetShell()->AddPaintRect( aRect ) )
1338  pLay->ResetRetouche();
1339  }
1340 
1341  if( bAlreadyPainted )
1342  bAddRect = false;
1343 
1344  CheckWaitCursor();
1345 
1346  if ( IsAgain() )
1347  return false;
1348 
1349  // Now, deal with the lowers that are LayoutFrames
1350 
1351  if ( pLay->IsFootnoteFrame() ) // no LayFrames as Lower
1352  return bChanged;
1353 
1354  SwFrame *pLow = pLay->Lower();
1355  bool bTabChanged = false;
1356  while ( pLow && pLow->GetUpper() == pLay )
1357  {
1358  if ( pLow->IsLayoutFrame() )
1359  {
1360  if ( pLow->IsTabFrame() )
1361  {
1362  // loop control for embedded tables
1363  if ( m_nTabLevel > 0 && ++m_nCallCount > 50 ) {
1364  static_cast<SwTabFrame*>(pLow)->SetSplitRowDisabled();
1365  }
1366 
1367  ++m_nTabLevel;
1368  bTabChanged |= FormatLayoutTab( static_cast<SwTabFrame*>(pLow), bAddRect );
1369  --m_nTabLevel;
1370  }
1371  // Skip the ones already registered for deletion
1372  else if( !pLow->IsSctFrame() || static_cast<SwSectionFrame*>(pLow)->GetSection() )
1373  bChanged |= FormatLayout( pRenderContext, static_cast<SwLayoutFrame*>(pLow), bAddRect );
1374  }
1375  else if ( m_pImp->GetShell()->IsPaintLocked() )
1376  // Shortcut to minimize the cycles. With Lock, the
1377  // paint is coming either way (primarily for browse)
1378  pLow->OptCalc();
1379 
1380  if ( IsAgain() )
1381  return false;
1382  pLow = pLow->GetNext();
1383  }
1384  // add complete frame area as paint area, if frame
1385  // area has been already added and after formatting its lowers the frame area
1386  // is enlarged.
1387  SwRect aBoundRect(pLay->IsPageFrame() ? static_cast<SwPageFrame*>(pLay)->GetBoundRect(pRenderContext) : pLay->getFrameArea() );
1388 
1389  if ( bAlreadyPainted &&
1390  ( aBoundRect.Width() > aFrameAtCompletePaint.Width() ||
1391  aBoundRect.Height() > aFrameAtCompletePaint.Height() )
1392  )
1393  {
1394  m_pImp->GetShell()->AddPaintRect( aBoundRect );
1395  }
1396  return bChanged || bTabChanged;
1397 }
1398 
1400 {
1401  vcl::RenderContext* pRenderContext = m_pImp->GetShell()->GetOut();
1402  OSL_ENSURE( !IsAgain(), "Attention to the invalid page." );
1403  if ( IsAgain() )
1404  return;
1405 
1406  bool bChanged = false;
1407  bool bAddRect = true;
1408 
1409  if ( !pFly->isFrameAreaDefinitionValid() || pFly->IsCompletePaint() || pFly->IsInvalid() )
1410  {
1411  // The Frame has changed, now it's getting formatted.
1412  const SwRect aOldRect( pFly->getFrameArea() );
1413  pFly->Calc(pRenderContext);
1414  bChanged = aOldRect != pFly->getFrameArea();
1415 
1416  if ( IsPaint() && (pFly->IsCompletePaint() || bChanged) &&
1417  pFly->getFrameArea().Top() > 0 && pFly->getFrameArea().Left() > 0 )
1418  m_pImp->GetShell()->AddPaintRect( pFly->getFrameArea() );
1419 
1420  if ( bChanged )
1421  pFly->Invalidate();
1422  else
1423  pFly->Validate();
1424 
1425  bAddRect = false;
1426  pFly->ResetCompletePaint();
1427  }
1428 
1429  if ( IsAgain() )
1430  return;
1431 
1432  // Now, deal with the lowers that are LayoutFrames
1433  bool bTabChanged = false;
1434  SwFrame *pLow = pFly->Lower();
1435  while ( pLow )
1436  {
1437  if ( pLow->IsLayoutFrame() )
1438  {
1439  if ( pLow->IsTabFrame() )
1440  bTabChanged |= FormatLayoutTab( static_cast<SwTabFrame*>(pLow), bAddRect );
1441  else
1442  bChanged |= FormatLayout( m_pImp->GetShell()->GetOut(), static_cast<SwLayoutFrame*>(pLow), bAddRect );
1443  }
1444  pLow = pLow->GetNext();
1445  }
1446 }
1447 
1448 // Implement vertical layout support
1449 bool SwLayAction::FormatLayoutTab( SwTabFrame *pTab, bool bAddRect )
1450 {
1451  OSL_ENSURE( !IsAgain(), "8-) Attention to the invalid page." );
1452  if ( IsAgain() || !pTab->Lower() )
1453  return false;
1454 
1455  vcl::RenderContext* pRenderContext = m_pImp->GetShell()->GetOut();
1457  rTimerAccess.BlockIdling();
1458 
1459  bool bChanged = false;
1460  bool bPainted = false;
1461 
1462  const SwPageFrame *pOldPage = pTab->FindPageFrame();
1463 
1464  // vertical layout support
1465  SwRectFnSet aRectFnSet(pTab);
1466 
1467  if ( !pTab->isFrameAreaDefinitionValid() || pTab->IsCompletePaint() || pTab->IsComplete() )
1468  {
1469  if ( pTab->GetPrev() && !pTab->GetPrev()->isFrameAreaDefinitionValid() )
1470  {
1471  pTab->GetPrev()->SetCompletePaint();
1472  }
1473 
1474  const SwRect aOldRect( pTab->getFrameArea() );
1475  pTab->SetLowersFormatted( false );
1476  pTab->Calc(pRenderContext);
1477  if ( aOldRect != pTab->getFrameArea() )
1478  {
1479  bChanged = true;
1480  }
1481  const SwRect aPaintFrame = pTab->GetPaintArea();
1482 
1483  if ( IsPaint() && bAddRect )
1484  {
1485  // add condition <pTab->getFrameArea().HasArea()>
1486  if ( !pTab->IsCompletePaint() &&
1487  pTab->IsComplete() &&
1488  ( pTab->getFrameArea().SSize() != pTab->getFramePrintArea().SSize() ||
1489  // vertical layout support
1490  aRectFnSet.GetLeftMargin(*pTab) ) &&
1491  pTab->getFrameArea().HasArea()
1492  )
1493  {
1494  // re-implement calculation of margin rectangles.
1495  SwRect aMarginRect;
1496 
1497  SwTwips nLeftMargin = aRectFnSet.GetLeftMargin(*pTab);
1498  if ( nLeftMargin > 0)
1499  {
1500  aMarginRect = pTab->getFrameArea();
1501  aRectFnSet.SetWidth( aMarginRect, nLeftMargin );
1502  m_pImp->GetShell()->AddPaintRect( aMarginRect );
1503  }
1504 
1505  if ( aRectFnSet.GetRightMargin(*pTab) > 0)
1506  {
1507  aMarginRect = pTab->getFrameArea();
1508  aRectFnSet.SetLeft( aMarginRect, aRectFnSet.GetPrtRight(*pTab) );
1509  m_pImp->GetShell()->AddPaintRect( aMarginRect );
1510  }
1511 
1512  SwTwips nTopMargin = aRectFnSet.GetTopMargin(*pTab);
1513  if ( nTopMargin > 0)
1514  {
1515  aMarginRect = pTab->getFrameArea();
1516  aRectFnSet.SetHeight( aMarginRect, nTopMargin );
1517  m_pImp->GetShell()->AddPaintRect( aMarginRect );
1518  }
1519 
1520  if ( aRectFnSet.GetBottomMargin(*pTab) > 0)
1521  {
1522  aMarginRect = pTab->getFrameArea();
1523  aRectFnSet.SetTop( aMarginRect, aRectFnSet.GetPrtBottom(*pTab) );
1524  m_pImp->GetShell()->AddPaintRect( aMarginRect );
1525  }
1526  }
1527  else if ( pTab->IsCompletePaint() )
1528  {
1529  m_pImp->GetShell()->AddPaintRect( aPaintFrame );
1530  bAddRect = false;
1531  bPainted = true;
1532  }
1533 
1534  if ( pTab->IsRetouche() && !pTab->GetNext() )
1535  {
1536  SwRect aRect( pTab->GetUpper()->GetPaintArea() );
1537  // vertical layout support
1538  aRectFnSet.SetTop( aRect, aRectFnSet.GetPrtBottom(*pTab) );
1539  if ( !m_pImp->GetShell()->AddPaintRect( aRect ) )
1540  pTab->ResetRetouche();
1541  }
1542  }
1543  else
1544  bAddRect = false;
1545 
1546  if ( pTab->IsCompletePaint() && !m_pOptTab )
1547  m_pOptTab = pTab;
1548  pTab->ResetCompletePaint();
1549  }
1550  if ( IsPaint() && bAddRect && pTab->IsRetouche() && !pTab->GetNext() )
1551  {
1552  // set correct rectangle for retouche: area between bottom of table frame
1553  // and bottom of paint area of the upper frame.
1554  SwRect aRect( pTab->GetUpper()->GetPaintArea() );
1555  // vertical layout support
1556  aRectFnSet.SetTop( aRect, aRectFnSet.GetPrtBottom(*pTab) );
1557  if ( !m_pImp->GetShell()->AddPaintRect( aRect ) )
1558  pTab->ResetRetouche();
1559  }
1560 
1561  CheckWaitCursor();
1562 
1563  rTimerAccess.UnblockIdling();
1564 
1565  // Ugly shortcut!
1566  if ( pTab->IsLowersFormatted() &&
1567  (bPainted || !m_pImp->GetShell()->VisArea().IsOver( pTab->getFrameArea())) )
1568  return false;
1569 
1570  // Now, deal with the lowers
1571  if ( IsAgain() )
1572  return false;
1573 
1574  // for safety reasons:
1575  // check page number before formatting lowers.
1576  if ( pOldPage->GetPhyPageNum() > (pTab->FindPageFrame()->GetPhyPageNum() + 1) )
1577  SetNextCycle( true );
1578 
1579  // format lowers, only if table frame is valid
1580  if ( pTab->isFrameAreaDefinitionValid() )
1581  {
1582  FlowFrameJoinLockGuard tabG(pTab); // tdf#124675 prevent Join() if pTab becomes empty
1583  SwLayoutFrame *pLow = static_cast<SwLayoutFrame*>(pTab->Lower());
1584  while ( pLow )
1585  {
1586  SwFrameDeleteGuard rowG(pLow); // tdf#124675 prevent RemoveFollowFlowLine()
1587  bChanged |= FormatLayout( m_pImp->GetShell()->GetOut(), pLow, bAddRect );
1588  if ( IsAgain() )
1589  return false;
1590  pLow = static_cast<SwLayoutFrame*>(pLow->GetNext());
1591  }
1592  }
1593 
1594  return bChanged;
1595 }
1596 
1598 {
1599  const SwContentFrame *pContent = pPage->ContainsContent();
1600  const SwViewShell *pSh = m_pRoot->GetCurrShell();
1601  const bool bBrowse = pSh && pSh->GetViewOptions()->getBrowseMode();
1602 
1603  while ( pContent && pPage->IsAnLower( pContent ) )
1604  {
1605  // If the content didn't change, we can use a few shortcuts.
1606  const bool bFull = !pContent->isFrameAreaDefinitionValid() || pContent->IsCompletePaint() ||
1607  pContent->IsRetouche() || pContent->GetDrawObjs();
1608  if ( bFull )
1609  {
1610  // We do this so we don't have to search later on.
1611  const bool bNxtCnt = IsCalcLayout() && !pContent->GetFollow();
1612  const SwContentFrame *pContentNext = bNxtCnt ? pContent->GetNextContentFrame() : nullptr;
1613  const SwContentFrame *pContentPrev = pContent->GetPrev() ? pContent->GetPrevContentFrame() : nullptr;
1614 
1615  const SwLayoutFrame*pOldUpper = pContent->GetUpper();
1616  const SwTabFrame *pTab = pContent->FindTabFrame();
1617  const bool bInValid = !pContent->isFrameAreaDefinitionValid() || pContent->IsCompletePaint();
1618  const bool bOldPaint = IsPaint();
1619  m_bPaint = bOldPaint && !(pTab && pTab == m_pOptTab);
1620  FormatContent_( pContent, pPage );
1621  // reset <bPaint> before format objects
1622  m_bPaint = bOldPaint;
1623 
1624  // format floating screen object at content frame.
1625  // No format, if action flag <bAgain> is set or action is interrupted.
1626  // allow format on interruption of action, if
1627  // it's the format for this interrupt
1628  // pass correct page frame
1629  // to the object formatter.
1630  if ( !IsAgain() &&
1632  pContent->IsTextFrame() &&
1633  !SwObjectFormatter::FormatObjsAtFrame( *const_cast<SwContentFrame*>(pContent),
1634  *(pContent->FindPageFrame()), this ) )
1635  {
1636  return false;
1637  }
1638 
1639  if ( !pContent->GetValidLineNumFlag() && pContent->IsTextFrame() )
1640  {
1641  const sal_uLong nAllLines = static_cast<const SwTextFrame*>(pContent)->GetAllLines();
1642  const_cast<SwTextFrame*>(static_cast<const SwTextFrame*>(pContent))->RecalcAllLines();
1643  if ( IsPaintExtraData() && IsPaint() &&
1644  nAllLines != static_cast<const SwTextFrame*>(pContent)->GetAllLines() )
1645  m_pImp->GetShell()->AddPaintRect( pContent->getFrameArea() );
1646  }
1647 
1648  if ( IsAgain() )
1649  return false;
1650 
1651  // Temporarily interrupt processing if layout or Flys become invalid again.
1652  // However not for the BrowseView: The layout is getting invalid
1653  // all the time because the page height gets adjusted.
1654  // The same applies if the user wants to continue working and at least one
1655  // paragraph has been processed.
1656  if (!pTab || !bInValid)
1657  {
1658  // consider interrupt formatting.
1659  if ( ( IsInterrupt() && !mbFormatContentOnInterrupt ) ||
1660  ( !bBrowse && pPage->IsInvalidLayout() ) ||
1661  // consider interrupt formatting
1662  ( pPage->GetSortedObjs() && pPage->IsInvalidFly() && !mbFormatContentOnInterrupt )
1663  )
1664  return false;
1665  }
1666  if ( pOldUpper != pContent->GetUpper() )
1667  {
1668  const sal_uInt16 nCurNum = pContent->FindPageFrame()->GetPhyPageNum();
1669  if ( nCurNum < pPage->GetPhyPageNum() )
1670  m_nPreInvaPage = nCurNum;
1671 
1672  // If the frame flowed backwards more than one page, we need to
1673  // start over again from the beginning, so nothing gets left out.
1674  if ( !IsCalcLayout() && pPage->GetPhyPageNum() > nCurNum+1 )
1675  {
1676  SetNextCycle( true );
1677  // consider interrupt formatting
1679  {
1680  return false;
1681  }
1682  }
1683  }
1684  // If the frame moved forwards to the next page, we re-run through
1685  // the predecessor.
1686  // This way, we catch predecessors which are now responsible for
1687  // retouching, but the footers will be touched also.
1688  bool bSetContent = true;
1689  if ( pContentPrev )
1690  {
1691  if ( !pContentPrev->isFrameAreaDefinitionValid() && pPage->IsAnLower( pContentPrev ) )
1692  {
1693  pPage->InvalidateContent();
1694  }
1695 
1696  if ( pOldUpper != pContent->GetUpper() &&
1697  pPage->GetPhyPageNum() < pContent->FindPageFrame()->GetPhyPageNum() )
1698  {
1699  pContent = pContentPrev;
1700  bSetContent = false;
1701  }
1702  }
1703  if ( bSetContent )
1704  {
1705  if ( bBrowse && !IsIdle() && !IsCalcLayout() && !IsComplete() &&
1706  pContent->getFrameArea().Top() > m_pImp->GetShell()->VisArea().Bottom())
1707  {
1708  const long nBottom = m_pImp->GetShell()->VisArea().Bottom();
1709  const SwFrame *pTmp = lcl_FindFirstInvaContent( pPage,
1710  nBottom, pContent );
1711  if ( !pTmp )
1712  {
1713  if ( (!(pPage->GetSortedObjs() && pPage->IsInvalidFly()) ||
1714  !lcl_FindFirstInvaObj( pPage, nBottom )) &&
1715  (!pPage->IsInvalidLayout() ||
1716  !lcl_FindFirstInvaLay( pPage, nBottom )))
1717  SetBrowseActionStop( true );
1718  // consider interrupt formatting.
1720  {
1721  return false;
1722  }
1723  }
1724  }
1725  pContent = bNxtCnt ? pContentNext : pContent->GetNextContentFrame();
1726  }
1727 
1728  if (IsReschedule())
1729  {
1731  }
1732  }
1733  else
1734  {
1735  if ( !pContent->GetValidLineNumFlag() && pContent->IsTextFrame() )
1736  {
1737  const sal_uLong nAllLines = static_cast<const SwTextFrame*>(pContent)->GetAllLines();
1738  const_cast<SwTextFrame*>(static_cast<const SwTextFrame*>(pContent))->RecalcAllLines();
1739  if ( IsPaintExtraData() && IsPaint() &&
1740  nAllLines != static_cast<const SwTextFrame*>(pContent)->GetAllLines() )
1741  m_pImp->GetShell()->AddPaintRect( pContent->getFrameArea() );
1742  }
1743 
1744  // Do this if the frame has been formatted before.
1745  if ( pContent->IsTextFrame() && static_cast<const SwTextFrame*>(pContent)->HasRepaint() &&
1746  IsPaint() )
1747  PaintContent( pContent, pPage, pContent->getFrameArea(), pContent->getFrameArea().Bottom());
1748  if ( IsIdle() )
1749  {
1750  // consider interrupt formatting.
1752  return false;
1753  }
1754  if ( bBrowse && !IsIdle() && !IsCalcLayout() && !IsComplete() &&
1755  pContent->getFrameArea().Top() > m_pImp->GetShell()->VisArea().Bottom())
1756  {
1757  const long nBottom = m_pImp->GetShell()->VisArea().Bottom();
1758  const SwFrame *pTmp = lcl_FindFirstInvaContent( pPage,
1759  nBottom, pContent );
1760  if ( !pTmp )
1761  {
1762  if ( (!(pPage->GetSortedObjs() && pPage->IsInvalidFly()) ||
1763  !lcl_FindFirstInvaObj( pPage, nBottom )) &&
1764  (!pPage->IsInvalidLayout() ||
1765  !lcl_FindFirstInvaLay( pPage, nBottom )))
1766  SetBrowseActionStop( true );
1767  // consider interrupt formatting.
1769  {
1770  return false;
1771  }
1772  }
1773  }
1774  pContent = pContent->GetNextContentFrame();
1775  }
1776  }
1777  CheckWaitCursor();
1778  // consider interrupt formatting.
1780 }
1781 
1782 void SwLayAction::FormatContent_( const SwContentFrame *pContent, const SwPageFrame *pPage )
1783 {
1784  // We probably only ended up here because the Content holds DrawObjects.
1785  const bool bDrawObjsOnly = pContent->isFrameAreaDefinitionValid() && !pContent->IsCompletePaint() && !pContent->IsRetouche();
1786  SwRectFnSet aRectFnSet(pContent);
1787  if ( !bDrawObjsOnly && IsPaint() )
1788  {
1789  const SwRect aOldRect( pContent->UnionFrame() );
1790  const long nOldBottom = aRectFnSet.GetPrtBottom(*pContent);
1791  pContent->OptCalc();
1792  if( IsAgain() )
1793  return;
1794  if( aRectFnSet.YDiff( aRectFnSet.GetBottom(pContent->getFrameArea()),
1795  aRectFnSet.GetBottom(aOldRect) ) < 0 )
1796  {
1797  pContent->SetRetouche();
1798  }
1799  PaintContent( pContent, pContent->FindPageFrame(), aOldRect, nOldBottom);
1800  }
1801  else
1802  {
1803  if ( IsPaint() && pContent->IsTextFrame() && static_cast<const SwTextFrame*>(pContent)->HasRepaint() )
1804  PaintContent( pContent, pPage, pContent->getFrameArea(),
1805  aRectFnSet.GetBottom(pContent->getFrameArea()) );
1806  pContent->OptCalc();
1807  }
1808 }
1809 
1811 {
1812  const SwContentFrame *pContent = pFly->ContainsContent();
1813 
1814  while ( pContent )
1815  {
1816  FormatContent_( pContent, pContent->FindPageFrame() );
1817 
1818  // format floating screen objects at content text frame
1819  // pass correct page frame to the object formatter.
1820  if ( pContent->IsTextFrame() &&
1822  *const_cast<SwContentFrame*>(pContent),
1823  *(pContent->FindPageFrame()), this ) )
1824  {
1825  // restart format with first content
1826  pContent = pFly->ContainsContent();
1827  continue;
1828  }
1829 
1830  if ( !pContent->GetValidLineNumFlag() && pContent->IsTextFrame() )
1831  {
1832  const sal_uLong nAllLines = static_cast<const SwTextFrame*>(pContent)->GetAllLines();
1833  const_cast<SwTextFrame*>(static_cast<const SwTextFrame*>(pContent))->RecalcAllLines();
1834  if ( IsPaintExtraData() && IsPaint() &&
1835  nAllLines != static_cast<const SwTextFrame*>(pContent)->GetAllLines() )
1836  m_pImp->GetShell()->AddPaintRect( pContent->getFrameArea() );
1837  }
1838 
1839  if ( IsAgain() )
1840  return;
1841 
1842  // If there's input, we interrupt processing.
1843  if ( !pFly->IsFlyInContentFrame() )
1844  {
1845  // consider interrupt formatting.
1847  return;
1848  }
1849  pContent = pContent->GetNextContentFrame();
1850  }
1851  CheckWaitCursor();
1852 }
1853 
1855 {
1856  return m_aWatch.exceededRuntime();
1857 }
1858 
1860 {
1861  OSL_ENSURE( pCnt->IsTextFrame(), "NoText neighbour of Text" );
1862  // robust against misuse by e.g. #i52542#
1863  if( !pCnt->IsTextFrame() )
1864  return false;
1865 
1866  SwTextFrame const*const pTextFrame(static_cast<SwTextFrame const*>(pCnt));
1867  // sw_redlinehide: spell check only the nodes with visible content?
1868  SwTextNode* pTextNode = const_cast<SwTextNode*>(pTextFrame->GetTextNodeForParaProps());
1869 
1870  bool bProcess = false;
1871  for (size_t i = 0; pTextNode; )
1872  {
1873  switch ( eJob )
1874  {
1875  case ONLINE_SPELLING :
1876  bProcess = pTextNode->IsWrongDirty(); break;
1877  case AUTOCOMPLETE_WORDS :
1878  bProcess = pTextNode->IsAutoCompleteWordDirty(); break;
1879  case WORD_COUNT :
1880  bProcess = pTextNode->IsWordCountDirty(); break;
1881  case SMART_TAGS :
1882  bProcess = pTextNode->IsSmartTagDirty(); break;
1883  }
1884  if (bProcess)
1885  {
1886  break;
1887  }
1888  if (sw::MergedPara const* pMerged = pTextFrame->GetMergedPara())
1889  {
1890  while (true)
1891  {
1892  ++i;
1893  if (i < pMerged->extents.size())
1894  {
1895  if (pMerged->extents[i].pNode != pTextNode)
1896  {
1897  pTextNode = pMerged->extents[i].pNode;
1898  break;
1899  }
1900  }
1901  else
1902  {
1903  pTextNode = nullptr;
1904  break;
1905  }
1906  }
1907  }
1908  else
1909  pTextNode = nullptr;
1910  }
1911 
1912  if( bProcess )
1913  {
1914  assert(pTextNode);
1915  SwViewShell *pSh = pImp->GetShell();
1916  if( COMPLETE_STRING == nTextPos )
1917  {
1918  --nTextPos;
1919  if( dynamic_cast< const SwCursorShell *>( pSh ) != nullptr && !static_cast<SwCursorShell*>(pSh)->IsTableMode() )
1920  {
1921  SwPaM *pCursor = static_cast<SwCursorShell*>(pSh)->GetCursor();
1922  if( !pCursor->HasMark() && !pCursor->IsMultiSelection() )
1923  {
1924  pContentNode = pCursor->GetContentNode();
1925  nTextPos = pCursor->GetPoint()->nContent.GetIndex();
1926  }
1927  }
1928  }
1929  sal_Int32 const nPos((pContentNode && pTextNode == pContentNode)
1930  ? nTextPos
1931  : COMPLETE_STRING);
1932 
1933  switch ( eJob )
1934  {
1935  case ONLINE_SPELLING :
1936  {
1937  SwRect aRepaint( const_cast<SwTextFrame*>(pTextFrame)->AutoSpell_(*pTextNode, nPos) );
1938  // PENDING should stop idle spell checking
1940  if ( aRepaint.HasArea() )
1941  pImp->GetShell()->InvalidateWindows( aRepaint );
1942  if (IsInterrupt())
1943  return true;
1944  break;
1945  }
1946  case AUTOCOMPLETE_WORDS :
1947  const_cast<SwTextFrame*>(pTextFrame)->CollectAutoCmplWrds(*pTextNode, nPos);
1948  // note: bPageValid remains true here even if the cursor
1949  // position is skipped, so no PENDING state needed currently
1950  if (IsInterrupt())
1951  return true;
1952  break;
1953  case WORD_COUNT :
1954  {
1955  const sal_Int32 nEnd = pTextNode->GetText().getLength();
1956  SwDocStat aStat;
1957  pTextNode->CountWords( aStat, 0, nEnd );
1958  if (IsInterrupt())
1959  return true;
1960  break;
1961  }
1962  case SMART_TAGS :
1963  {
1964  try {
1965  const SwRect aRepaint( const_cast<SwTextFrame*>(pTextFrame)->SmartTagScan(*pTextNode) );
1966  bPageValid = bPageValid && !pTextNode->IsSmartTagDirty();
1967  if ( aRepaint.HasArea() )
1968  pImp->GetShell()->InvalidateWindows( aRepaint );
1969  } catch( const css::uno::RuntimeException&) {
1970  // handle smarttag problems gracefully and provide diagnostics
1971  TOOLS_WARN_EXCEPTION( "sw.core", "SMART_TAGS");
1972  }
1973  if (IsInterrupt())
1974  return true;
1975  break;
1976  }
1977  }
1978  }
1979 
1980  // The Flys that are anchored to the paragraph need to be considered too.
1981  if ( pCnt->GetDrawObjs() )
1982  {
1983  const SwSortedObjs &rObjs = *pCnt->GetDrawObjs();
1984  for (SwAnchoredObject* pObj : rObjs)
1985  {
1986  if ( dynamic_cast< const SwFlyFrame *>( pObj ) != nullptr )
1987  {
1988  SwFlyFrame* pFly = static_cast<SwFlyFrame*>(pObj);
1989  if ( pFly->IsFlyInContentFrame() )
1990  {
1991  const SwContentFrame *pC = pFly->ContainsContent();
1992  while( pC )
1993  {
1994  if ( pC->IsTextFrame() )
1995  {
1996  if ( DoIdleJob_( pC, eJob ) )
1997  return true;
1998  }
1999  pC = pC->GetNextContentFrame();
2000  }
2001  }
2002  }
2003  }
2004  }
2005  return false;
2006 }
2007 
2008 bool SwLayIdle::DoIdleJob( IdleJobType eJob, bool bVisAreaOnly )
2009 {
2010  // Spellcheck all contents of the pages. Either only the
2011  // visible ones or all of them.
2012  const SwViewShell* pViewShell = pImp->GetShell();
2013  const SwViewOption* pViewOptions = pViewShell->GetViewOptions();
2014  const SwDoc* pDoc = pViewShell->GetDoc();
2015 
2016  switch ( eJob )
2017  {
2018  case ONLINE_SPELLING :
2019  if( !pViewOptions->IsOnlineSpell() )
2020  return false;
2021  break;
2022  case AUTOCOMPLETE_WORDS :
2025  return false;
2026  break;
2027  case WORD_COUNT :
2028  if ( !pViewShell->getIDocumentStatistics().GetDocStat().bModified )
2029  return false;
2030  break;
2031  case SMART_TAGS :
2032  if ( pDoc->GetDocShell()->IsHelpDocument() ||
2033  pDoc->isXForms() ||
2035  return false;
2036  break;
2037  default: OSL_FAIL( "Unknown idle job type" );
2038  }
2039 
2040  SwPageFrame *pPage;
2041  if ( bVisAreaOnly )
2042  pPage = pImp->GetFirstVisPage(pViewShell->GetOut());
2043  else
2044  pPage = static_cast<SwPageFrame*>(pRoot->Lower());
2045 
2046  pContentNode = nullptr;
2048 
2049  while ( pPage )
2050  {
2051  bPageValid = true;
2052  const SwContentFrame *pCnt = pPage->ContainsContent();
2053  while( pCnt && pPage->IsAnLower( pCnt ) )
2054  {
2055  if ( DoIdleJob_( pCnt, eJob ) )
2056  return true;
2057  pCnt = pCnt->GetNextContentFrame();
2058  }
2059  if ( pPage->GetSortedObjs() )
2060  {
2061  for ( size_t i = 0; pPage->GetSortedObjs() &&
2062  i < pPage->GetSortedObjs()->size(); ++i )
2063  {
2064  const SwAnchoredObject* pObj = (*pPage->GetSortedObjs())[i];
2065  if ( auto pFly = dynamic_cast< const SwFlyFrame *>( pObj ) )
2066  {
2067  const SwContentFrame *pC = pFly->ContainsContent();
2068  while( pC )
2069  {
2070  if ( pC->IsTextFrame() )
2071  {
2072  if ( DoIdleJob_( pC, eJob ) )
2073  return true;
2074  }
2075  pC = pC->GetNextContentFrame();
2076  }
2077  }
2078  }
2079  }
2080 
2081  if( bPageValid )
2082  {
2083  switch ( eJob )
2084  {
2085  case ONLINE_SPELLING : pPage->ValidateSpelling(); break;
2086  case AUTOCOMPLETE_WORDS : pPage->ValidateAutoCompleteWords(); break;
2087  case WORD_COUNT : pPage->ValidateWordCount(); break;
2088  case SMART_TAGS : pPage->ValidateSmartTags(); break;
2089  }
2090  }
2091 
2092  pPage = static_cast<SwPageFrame*>(pPage->GetNext());
2093  if ( pPage && bVisAreaOnly &&
2094  !pPage->getFrameArea().IsOver( pImp->GetShell()->VisArea()))
2095  break;
2096  }
2097  return false;
2098 }
2099 
2100 #if HAVE_FEATURE_DESKTOP && defined DBG_UTIL
2101 void SwLayIdle::ShowIdle( Color eColor )
2102 {
2103  if ( !m_bIndicator )
2104  {
2105  m_bIndicator = true;
2106  vcl::Window *pWin = pImp->GetShell()->GetWin();
2107  if (pWin && !pWin->SupportsDoubleBuffering()) // FIXME make this work with double-buffering
2108  {
2109  tools::Rectangle aRect( 0, 0, 5, 5 );
2110  aRect = pWin->PixelToLogic( aRect );
2111  // Depending on if idle layout is in progress or not, draw a "red square" or a "green square".
2112  pWin->Push( PushFlags::FILLCOLOR|PushFlags::LINECOLOR );
2113  pWin->SetFillColor( eColor );
2114  pWin->SetLineColor();
2115  pWin->DrawRect( aRect );
2116  pWin->Pop();
2117  }
2118  }
2119 }
2120 #define SHOW_IDLE( Color ) ShowIdle( Color )
2121 #else
2122 #define SHOW_IDLE( Color )
2123 #endif // DBG_UTIL
2124 
2126  pRoot( pRt ),
2127  pImp( pI )
2128 #ifdef DBG_UTIL
2129  , m_bIndicator( false )
2130 #endif
2131 {
2132  SAL_INFO("sw.idle", "SwLayIdle() entry");
2133 
2134  pImp->m_pIdleAct = this;
2135 
2137 
2138  pImp->GetShell()->EnableSmooth( false );
2139 
2140  // First, spellcheck the visible area. Only if there's nothing
2141  // to do there, we trigger the IdleFormat.
2142  if ( !DoIdleJob( SMART_TAGS, true ) &&
2143  !DoIdleJob( ONLINE_SPELLING, true ) &&
2144  !DoIdleJob( AUTOCOMPLETE_WORDS, true ) )
2145  {
2146  // Format, then register repaint rectangles with the SwViewShell if necessary.
2147  // This requires running artificial actions, so we don't get undesired
2148  // effects when for instance the page count gets changed.
2149  // We remember the shells where the cursor is visible, so we can make
2150  // it visible again if needed after a document change.
2151  std::vector<bool> aBools;
2152  for(SwViewShell& rSh : pImp->GetShell()->GetRingContainer())
2153  {
2154  ++rSh.mnStartAction;
2155  bool bVis = false;
2156  if ( dynamic_cast<const SwCursorShell*>( &rSh) != nullptr )
2157  {
2158  bVis = static_cast<SwCursorShell*>(&rSh)->GetCharRect().IsOver(rSh.VisArea());
2159  }
2160  aBools.push_back( bVis );
2161  }
2162 
2163  bool bInterrupt(false);
2164  {
2165  SwLayAction aAction(pRoot, pImp, &m_aWatch);
2166  aAction.SetWaitAllowed( false );
2167  aAction.Action(pImp->GetShell()->GetOut());
2168  bInterrupt = aAction.IsInterrupt();
2169  }
2170 
2171  // Further start/end actions only happen if there were paints started
2172  // somewhere or if the visibility of the CharRects has changed.
2173  bool bActions = false;
2174  size_t nBoolIdx = 0;
2175  for(SwViewShell& rSh : pImp->GetShell()->GetRingContainer())
2176  {
2177  --rSh.mnStartAction;
2178 
2179  if ( rSh.Imp()->GetRegion() )
2180  bActions = true;
2181  else
2182  {
2183  SwRect aTmp( rSh.VisArea() );
2184  rSh.UISizeNotify();
2185 
2186  // Are we supposed to crash if rSh isn't a cursor shell?!
2187  // bActions |= aTmp != rSh.VisArea() ||
2188  // aBools[nBoolIdx] != ((SwCursorShell*)&rSh)->GetCharRect().IsOver( rSh.VisArea() );
2189 
2190  // aBools[ i ] is true, if the i-th shell is a cursor shell (!!!)
2191  // and the cursor is visible.
2192  bActions |= aTmp != rSh.VisArea();
2193  if ( aTmp == rSh.VisArea() && dynamic_cast<const SwCursorShell*>( &rSh) != nullptr )
2194  {
2195  bActions |= aBools[nBoolIdx] !=
2196  static_cast<SwCursorShell*>(&rSh)->GetCharRect().IsOver( rSh.VisArea() );
2197  }
2198  }
2199 
2200  ++nBoolIdx;
2201  }
2202 
2203  if ( bActions )
2204  {
2205  // Prepare start/end actions via CursorShell, so the cursor, selection
2206  // and VisArea can be set correctly.
2207  nBoolIdx = 0;
2208  for(SwViewShell& rSh : pImp->GetShell()->GetRingContainer())
2209  {
2210  SwCursorShell* pCursorShell = nullptr;
2211  if(dynamic_cast<const SwCursorShell*>( &rSh) != nullptr)
2212  pCursorShell = static_cast<SwCursorShell*>(&rSh);
2213 
2214  if ( pCursorShell )
2215  pCursorShell->SttCursorMove();
2216 
2217  // If there are accrued paints, it's best to simply invalidate
2218  // the whole window. Otherwise there would arise paint problems whose
2219  // solution would be disproportionally expensive.
2220  SwViewShellImp *pViewImp = rSh.Imp();
2221  bool bUnlock = false;
2222  if ( pViewImp->GetRegion() )
2223  {
2224  pViewImp->DelRegion();
2225 
2226  // Cause a repaint with virtual device.
2227  rSh.LockPaint();
2228  bUnlock = true;
2229  }
2230 
2231  if ( pCursorShell )
2232  // If the Cursor was visible, we need to make it visible again.
2233  // Otherwise, EndCursorMove with true for IdleEnd
2234  pCursorShell->EndCursorMove( !aBools[nBoolIdx] );
2235  if( bUnlock )
2236  {
2237  if( pCursorShell )
2238  {
2239  // UnlockPaint overwrite the selection from the
2240  // CursorShell and calls the virtual method paint
2241  // to fill the virtual device. This fill don't have
2242  // paint the selection! -> Set the focus flag at
2243  // CursorShell and it doesn't paint the selection.
2244  pCursorShell->ShellLoseFocus();
2245  pCursorShell->UnlockPaint( true );
2246  pCursorShell->ShellGetFocus();
2247  }
2248  else
2249  rSh.UnlockPaint( true );
2250  }
2251  ++nBoolIdx;
2252 
2253  }
2254  }
2255 
2256  if (!bInterrupt)
2257  {
2258  if ( !DoIdleJob( WORD_COUNT, false ) )
2259  if ( !DoIdleJob( SMART_TAGS, false ) )
2260  if ( !DoIdleJob( ONLINE_SPELLING, false ) )
2261  DoIdleJob( AUTOCOMPLETE_WORDS, false );
2262  }
2263 
2264  bool bInValid = false;
2265  const SwViewOption& rVOpt = *pImp->GetShell()->GetViewOptions();
2266  const SwViewShell* pViewShell = pImp->GetShell();
2267  // See conditions in DoIdleJob()
2268  const bool bSpell = rVOpt.IsOnlineSpell();
2269  const bool bACmplWrd = SwViewOption::IsAutoCompleteWords();
2270  const bool bWordCount = pViewShell->getIDocumentStatistics().GetDocStat().bModified;
2271  const bool bSmartTags = !pViewShell->GetDoc()->GetDocShell()->IsHelpDocument() &&
2272  !pViewShell->GetDoc()->isXForms() &&
2274 
2275  SwPageFrame *pPg = static_cast<SwPageFrame*>(pRoot->Lower());
2276  do
2277  {
2278  bInValid = pPg->IsInvalidContent() || pPg->IsInvalidLayout() ||
2279  pPg->IsInvalidFlyContent() || pPg->IsInvalidFlyLayout() ||
2280  pPg->IsInvalidFlyInCnt() ||
2281  (bSpell && pPg->IsInvalidSpelling()) ||
2282  (bACmplWrd && pPg->IsInvalidAutoCompleteWords()) ||
2283  (bWordCount && pPg->IsInvalidWordCount()) ||
2284  (bSmartTags && pPg->IsInvalidSmartTags());
2285 
2286  pPg = static_cast<SwPageFrame*>(pPg->GetNext());
2287 
2288  } while ( pPg && !bInValid );
2289 
2290  if ( !bInValid )
2291  {
2293  SfxObjectShell* pDocShell = pImp->GetShell()->GetDoc()->GetDocShell();
2294  pDocShell->Broadcast( SfxEventHint( SfxEventHintId::SwEventLayoutFinished, SwDocShell::GetEventName(STR_SW_EVENT_LAYOUT_FINISHED), pDocShell ) );
2295  // Limit lifetime of the text glyphs cache to a single run of the
2296  // layout.
2298  }
2299  }
2300 
2301  pImp->GetShell()->EnableSmooth( true );
2302 
2303  if( pImp->IsAccessible() )
2305 
2306  SAL_INFO("sw.idle", "SwLayIdle() return");
2307 
2308 #ifdef DBG_UTIL
2309  if ( m_bIndicator && pImp->GetShell()->GetWin() )
2310  {
2311  // Do not invalidate indicator, this may cause an endless loop. Instead, just repaint it
2312  // This should be replaced by an overlay object in the future, anyways. Since it's only for debug
2313  // purposes, it is not urgent.
2315  }
2316 #endif
2317 }
2318 
2320 {
2321  pImp->m_pIdleAct = nullptr;
2322 }
2323 
2324 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void InternalAction(OutputDevice *pRenderContext)
Definition: layact.cxx:421
bool IsAnLower(const SwFrame *) const
Definition: findfrm.cxx:206
vcl::RenderContext * GetOut() const
Definition: viewsh.hxx:341
bool IsPaintLocked() const
Definition: viewsh.hxx:471
bool IsContour() const
Definition: fmtsrnd.hxx:53
TaskStopwatch m_aWatch
Definition: layact.hxx:183
const SwVirtFlyDrawObj * GetVirtDrawObj() const
Definition: fly.cxx:2727
Base class of the Writer layout elements.
Definition: frame.hxx:295
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:149
void SwClearFntCacheTextGlyphs()
Clears the pre-calculated text glyphs in all SwFntObj instances.
Definition: fntcache.cxx:2713
virtual SwRect GetObjRect() const =0
bool PaintWithoutFlys(const SwRect &, const SwContentFrame *, const SwPageFrame *)
Definition: layact.cxx:102
void FireAccessibleEvents()
Fire all accessible events that have been collected so far.
Definition: viewimp.cxx:458
void DelRegion()
Definition: viewimp.cxx:123
bool IsFollow() const
Definition: flowfrm.hxx:166
bool m_bBrowseActionStop
Definition: layact.hxx:92
bool m_bCalcLayout
Definition: layact.hxx:85
virtual const SwFlyFrameFormat * GetFormat() const override
Definition: fly.cxx:2816
const SwSortedObjs * GetDrawObjs() const
Definition: frame.hxx:543
const SwPageFrame * m_pCurPage
Definition: layact.hxx:101
static const SwAnchoredObject * lcl_FindFirstInvaObj(const SwPageFrame *_pPage, long _nBottom)
Definition: layact.cxx:920
SwContentFrame * GetNextContentFrame() const
Definition: cntfrm.hxx:98
bool IsMultiSelection() const
Definition: pam.hxx:272
bool IsInDocBody() const
Definition: frame.hxx:919
void SetNextCycle(bool bNew)
Definition: layact.hxx:133
void DeleteEmptySct()
Definition: rootfrm.hxx:375
bool FormatLayout(OutputDevice *pRenderContext, SwLayoutFrame *, bool bAddRect=true)
Definition: layact.cxx:1174
void ShowIdle(Color eName)
void LoopControl(SwPageFrame *pPage)
Definition: layouter.cxx:236
bool TurboAction_(const SwContentFrame *)
Definition: layact.cxx:777
bool IsInSct() const
Definition: frame.hxx:943
void SetLowersFormatted(bool b)
Definition: tabfrm.hxx:152
const IDocumentStatistics & getIDocumentStatistics() const
Provides access to the document statistics interface.
Definition: viewsh.cxx:2601
bool IsComplete()
Definition: tabfrm.hxx:147
bool IsLowerOf(const SwLayoutFrame *pUpper) const
Definition: fly.cxx:2115
bool FormatLayoutTab(SwTabFrame *, bool bAddRect)
Definition: layact.cxx:1449
const OUString & GetText() const
Definition: ndtxt.hxx:211
static void CheckPageDescs(SwPageFrame *pStart, bool bNotifyFields=true, SwPageFrame **ppPrev=nullptr)
Check all pages (starting from the given one) if they use the right frame format. ...
Definition: pagechg.cxx:1004
void ResetTurboFlag() const
Definition: rootfrm.hxx:343
static SwAutoCompleteWord & GetAutoCompleteWords()
Definition: doc.hxx:1521
bool IsInvalidWordCount() const
Definition: pagefrm.hxx:225
bool IsWrongDirty() const
Definition: txtedt.cxx:2251
SwDocShell * GetDocShell()
Definition: doc.hxx:1341
bool m_bComplete
Definition: layact.hxx:84
constexpr::Color COL_LIGHTGREEN(0x00, 0xFF, 0x00)
void FormatFlyContent(const SwFlyFrame *)
Definition: layact.cxx:1810
void ValidateSpelling() const
Definition: pagefrm.hxx:404
void SetCompletePaint() const
Definition: frame.hxx:970
bool IsWaitAllowed() const
Definition: layact.hxx:135
#define PROTOCOL(pFrame, nFunc, nAct, pPar)
Definition: dbg_lay.hxx:88
bool DoIdleJob(IdleJobType, bool bVisAreaOnly)
Definition: layact.cxx:2008
sal_uIntPtr sal_uLong
sal_uInt16 m_nTabLevel
Definition: layact.hxx:102
const SwRect & getFramePrintArea() const
Definition: frame.hxx:176
Handle the background jobs of a Writer document.
SwTabFrame is one table in the document layout, containing rows (which contain cells).
Definition: tabfrm.hxx:30
sw::MergedPara * GetMergedPara()
Definition: txtfrm.hxx:438
bool m_bInterrupt
Definition: layact.hxx:89
static bool IsAutoCompleteWords()
Definition: viewopt.cxx:319
bool m_bReschedule
Definition: layact.hxx:88
Definition: doc.hxx:185
SwFrame * FindPrev()
Definition: frame.hxx:1131
bool IsComplete() const
Definition: layact.hxx:161
void ShellLoseFocus()
Definition: crsrsh.cxx:2408
void ValidateFlyContent() const
Definition: pagefrm.hxx:388
SwRootFrame * m_pRoot
Definition: layact.hxx:58
void ValidateContent() const
Definition: pagefrm.hxx:400
bool IsLeftToRightViewLayout() const
Definition: pagechg.cxx:2399
void Height(long nNew)
Definition: swrect.hxx:189
bool m_bPaintExtraData
Definition: layact.hxx:94
long GetBottom(const SwRect &rRect) const
Definition: frame.hxx:1354
sw::sidebarwindows::SidebarPosition SidebarPosition() const
asks the page on which side a margin should be shown, e.g for notes returns true for left side...
Definition: pagechg.cxx:1374
long SwTwips
Definition: swtypes.hxx:49
SwLayAction * m_pLayAction
Definition: viewimp.hxx:71
bool GetValidLineNumFlag() const
Definition: frame.hxx:740
void Invalidate() const
Definition: flyfrm.hxx:187
constexpr::Color COL_LIGHTRED(0xFF, 0x00, 0x00)
static void DestroyFrame(SwFrame *const pFrame)
this is the only way to delete a SwFrame instance
Definition: ssfrm.cxx:382
bool IsSmartTagDirty() const
Definition: txtedt.cxx:2277
static bool StartLoopControl(SwDoc *pDoc, SwPageFrame const *pPage)
Definition: layouter.cxx:290
void Pos(const Point &rNew)
Definition: swrect.hxx:167
bool IsBackgroundTransparent() const
SwFlyFrame::IsBackgroundTransparent.
Definition: paintfrm.cxx:3715
bool IsAccessible() const
Is this view accessible?
Definition: viewimp.hxx:220
virtual void Calc(vcl::RenderContext *pRenderContext) const
Definition: trvlfrm.cxx:1788
bool IsFootnotePage() const
Foot note interface.
Definition: pagefrm.hxx:185
Of course Writer needs its own rectangles.
Definition: swrect.hxx:34
void AssertFlyPages()
Ensures that enough pages exist, so that all page bound frames and draw objects can be placed...
Definition: pagechg.cxx:1516
SwContentFrame * FindFirstBodyContent()
Definition: pagefrm.hxx:333
bool IsLowersFormatted() const
Definition: tabfrm.hxx:151
IDocumentTimerAccess & getIDocumentTimerAccess()
Provides access to the document idle timer interface.
Definition: format.cxx:762
The root element of a Writer document layout.
Definition: rootfrm.hxx:79
bool IsCalcLayout() const
Definition: layact.hxx:163
void InvalidateFlyInCnt() const
Definition: pagefrm.hxx:355
bool IsFootnoteFrame() const
Definition: frame.hxx:1178
bool isFrameAreaDefinitionValid() const
Definition: frame.hxx:167
SwRootFrame * pRoot
Definition: layact.hxx:184
bool m_bAgain
Definition: layact.hxx:86
const SwPageFrame * GetFirstVisPage(OutputDevice const *pRenderContext) const
Management of the first visible Page.
Definition: viewimp.cxx:277
void EnableSmooth(bool b)
Definition: viewsh.hxx:250
void PaintContent(const SwContentFrame *, const SwPageFrame *, const SwRect &rOldRect, long nOldBottom)
Depending of the type, the Content is output according to its changes, or the area to be outputted is...
Definition: layact.cxx:198
void ValidateWordCount() const
Definition: pagefrm.hxx:417
bool IsReschedule() const
Definition: layact.hxx:138
sal_uInt16 GetPhyPageNum() const
Definition: pagefrm.hxx:190
bool RemoveEmptyBrowserPages()
Definition: layact.cxx:294
TaskStopwatch * m_pWatch
Definition: layact.hxx:60
SwContentNode * GetContentNode(bool bPoint=true) const
Definition: pam.hxx:229
SwSectionFrame * ImplFindSctFrame()
Definition: findfrm.cxx:480
long YDiff(long n1, long n2) const
Definition: frame.hxx:1399
bool AddPaintRect(const SwRect &rRect)
Definition: viewsh.cxx:534
virtual void UnblockIdling()=0
Decrement block count.
void ValidateAutoCompleteWords() const
Definition: pagefrm.hxx:413
bool m_bWaitAllowed
Definition: layact.hxx:93
void SetRetouche() const
Definition: frame.hxx:979
SwRect GetPaintArea() const
|* The paintarea is the area, in which the content of a frame is allowed |* to be displayed...
Definition: ssfrm.cxx:581
static const SwFrame * lcl_FindFirstInvaContent(const SwLayoutFrame *pLay, long nBottom, const SwContentFrame *pFirst)
Definition: layact.cxx:875
bool IsShortCut(SwPageFrame *&)
Definition: layact.cxx:959
wrapper class for the positioning of Writer fly frames and drawing objects
void SetFirstVisPageInvalid()
Definition: viewimp.hxx:148
virtual bool IsVisibleLayerId(SdrLayerID _nLayerId) const =0
method to determine, if a layer ID belongs to the visible ones.
static bool lcl_IsInvaLay(const SwFrame *pFrame, long nBottom)
Definition: layact.cxx:847
void ChangeOrigin(const SwRect &rRect)
Definition: swregion.hxx:48
long GetPrtBottom(const SwFrame &rFrame) const
Definition: frame.hxx:1386
bool IsInvalid() const
Definition: flyfrm.hxx:186
bool IsInvalidFlyInCnt() const
Definition: pagefrm.hxx:219
void Top(const long nTop)
Definition: swrect.hxx:202
void SttCursorMove()
Definition: crsrsh.cxx:290
bool IsInterrupt()
Definition: layact.cxx:1854
SwIndex nContent
Definition: pam.hxx:38
const SwRect & getFrameArea() const
Definition: frame.hxx:175
SwFootnoteContFrame * FindFootnoteCont()
Definition: ftnfrm.cxx:964
bool getBrowseMode() const
Definition: viewopt.hxx:433
#define XCHECKPAGE
Definition: layact.cxx:69
bool IsInTab() const
Definition: frame.hxx:931
void EndLoopControl()
Definition: layouter.cxx:261
long GetBottomMargin(const SwFrame &rFrame) const
Definition: frame.hxx:1380
bool IsInvalidAutoCompleteWords() const
Definition: pagefrm.hxx:224
bool IsTextFrame() const
Definition: frame.hxx:1210
void InvalidateFlyContent() const
Definition: pagefrm.hxx:351
void Action(OutputDevice *pRenderContext)
Definition: layact.cxx:321
~SwLayIdle()
Definition: layact.cxx:2319
sal_uInt16 m_nEndPage
Definition: layact.hxx:79
bool IsInvalidSpelling() const
Definition: pagefrm.hxx:222
const SwFormatSurround & GetSurround(bool=true) const
Definition: fmtsrnd.hxx:66
bool IsPageBodyFrame() const
Definition: layfrm.hxx:213
SwDoc * GetDoc() const
Definition: viewsh.hxx:284
bool IsInvalidSmartTags() const
Definition: pagefrm.hxx:223
Describes parts of multiple text nodes, which will form a text frame, even when redlines are hidden a...
Definition: txtfrm.hxx:954
SwContentFrame * GetPrevContentFrame() const
Definition: cntfrm.hxx:106
long GetLeftMargin(const SwFrame &rFrame) const
Definition: frame.hxx:1381
bool IsSctFrame() const
Definition: frame.hxx:1190
SwFlyFrame * FindFlyFrame()
Definition: frame.hxx:1087
bool IsWordCountDirty() const
Definition: txtedt.cxx:2233
void Right(const long nRight)
Definition: swrect.hxx:198
bool IsNextCycle() const
Definition: layact.hxx:136
bool IsFlyInContentFrame() const
Definition: flyfrm.hxx:193
void SetBrowseActionStop(bool bNew)
Definition: layact.hxx:132
void DrawRect(const tools::Rectangle &rRect)
void SetProgressState(long nPosition, SwDocShell const *pDocShell)
Definition: mainwn.cxx:78
sal_uInt32 GetOrdNumDirect() const
void InvalidateContent() const
Definition: pagefrm.hxx:363
const SwViewShell * GetShell() const
Only for SwViewShell::Init()
Definition: viewimp.hxx:140
bool IsInvalidContent() const
Definition: pagefrm.hxx:221
bool m_bIndicator
Definition: layact.hxx:190
void ValidateFlyLayout() const
Definition: pagefrm.hxx:384
SwRect GetPaintSwRect()
Page number etc.
Definition: frmpaint.cxx:411
long const nTopMargin
void EndCursorMove(const bool bIdleEnd=false)
Definition: crsrsh.cxx:299
void SetHeight(SwRect &rRect, long nNew) const
Definition: frame.hxx:1367
void ResetTurbo()
Definition: rootfrm.hxx:346
void SetStatBar(bool bNew)
Definition: layact.cxx:91
bool IsInvalidFly() const
Definition: pagefrm.hxx:426
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:136
sal_Int32 nTextPos
Definition: layact.hxx:187
bool IsInvalidFlyContent() const
Definition: pagefrm.hxx:218
SwTextNode const * GetTextNodeForParaProps() const
Definition: txtfrm.cxx:1300
void SetLineColor()
SwTabFrame * ImplFindTabFrame()
Definition: findfrm.cxx:468
#define TOOLS_WARN_EXCEPTION(area, stream)
void SetWidth(SwRect &rRect, long nNew) const
Definition: frame.hxx:1366
void SetTop(SwRect &rRect, long nNew) const
Definition: frame.hxx:1362
void CheckWaitCursor()
Definition: layact.cxx:78
void Reset()
Definition: layact.cxx:283
sal_uInt16 m_nPreInvaPage
Definition: layact.hxx:74
void Validate() const
Definition: flyfrm.hxx:188
#define SHOW_IDLE(Color)
Definition: layact.cxx:2122
const SwContentFrame * GetFollow() const
Definition: cntfrm.hxx:114
static SwPageFrame * CheckFirstVisPage(SwPageFrame *pPage)
Definition: layact.cxx:367
const SwSortedObjs * GetSortedObjs() const
Definition: pagefrm.hxx:118
void ResetIdleFormat()
Definition: rootfrm.hxx:257
void ValidateFlyInCnt() const
Definition: pagefrm.hxx:392
const SwRect & VisArea() const
Definition: viewsh.cxx:569
std::unique_ptr< SwWait > m_pWait
Definition: layact.hxx:69
const SwPosition * GetPoint() const
Definition: pam.hxx:207
The usage of LayAction is always the same:
Definition: layact.hxx:56
const IDocumentLayoutAccess & getIDocumentLayoutAccess() const
Provides access to the document layout interface.
Definition: format.cxx:760
SwRect GetBoundRect(OutputDevice const *pOutputDevice) const
Definition: paintfrm.cxx:6060
static SwSmartTagMgr & Get()
size_t size() const
Definition: sortedobjs.cxx:42
SwPageFrame * FindPageFrame()
Definition: frame.hxx:658
virtual void Cut() override
Definition: pagechg.cxx:838
bool IsCompletePaint() const
Definition: frame.hxx:579
const SwFrame * Lower() const
Definition: layfrm.hxx:100
virtual SwLayouter * GetLayouter()=0
int i
void InvalidatePage(const SwPageFrame *pPage=nullptr) const
Invalidates the page in which the Frame is currently placed.
Definition: wsfrm.cxx:598
bool HasMark() const
A PaM marks a selection if Point and Mark are distinct positions.
Definition: pam.hxx:205
void RescheduleProgress(SwDocShell const *pDocShell)
Definition: mainwn.cxx:119
SwLayoutFrame * GetUpper()
Definition: frame.hxx:656
bool HasArea() const
Definition: swrect.hxx:290
void SetFillColor()
bool m_bUpdateExpFields
Definition: layact.hxx:91
long GetTopMargin(const SwFrame &rFrame) const
Definition: frame.hxx:1379
bool IsSmartTagsEnabled() const
bool IsRetoucheFrame() const
Definition: frame.hxx:1222
SwFrame * GetPrev()
Definition: frame.hxx:655
void RecalcAllLines()
Definition: txtfrm.cxx:3816
bool IsExtraData(const SwDoc *pDoc)
Definition: frmtool.cxx:3629
ring_container GetRingContainer()
Definition: ring.hxx:240
static constexpr sal_uInt16 defGapBetweenPages
Definition: viewopt.hxx:413
bool IsOnlineSpell() const
Definition: viewopt.hxx:332
bool empty() const
const SwDoc * GetDoc() const
The document is set in SwAttrPool now, therefore you always can access it.
Definition: format.hxx:119
bool mbFormatContentOnInterrupt
Definition: layact.hxx:98
void SSize(const Size &rNew)
Definition: swrect.hxx:176
SwRect UnionFrame(bool bBorder=false) const
|* The unionframe is the framearea (getFrameArea()) of a frame expanded by the |* printarea...
Definition: ssfrm.cxx:675
void InvalidateFlyLayout() const
Validate, invalidate and query the Page status Layout/Content and Fly/non-Fly respectively are inspec...
Definition: pagefrm.hxx:347
bool isXForms() const
Definition: docxforms.cxx:44
A page of the document layout.
Definition: pagefrm.hxx:40
void OptCalc() const
Definition: frame.hxx:1056
sal_uInt16 m_nCheckPageNum
Definition: layact.hxx:80
long GetPrtRight(const SwFrame &rFrame) const
Definition: frame.hxx:1388
bool IsLeftShadowNeeded() const
Definition: paintfrm.cxx:5655
void InvalidateWindows(const SwRect &rRect)
Definition: viewsh.cxx:550
virtual SdrLayerID GetHellId() const =0
void ResetCompletePaint() const
Definition: frame.hxx:974
bool m_bActionInProgress
Definition: layact.hxx:95
SwSectionFrame * FindSctFrame()
Definition: frame.hxx:1091
virtual SdrLayerID GetLayer() const
SwLayoutFrame * FindBodyCont()
Searches the first ContentFrame in BodyText below the page.
Definition: findfrm.cxx:42
Point PixelToLogic(const Point &rDevicePt) const
void SetLeft(SwRect &rRect, long nNew) const
Definition: frame.hxx:1364
void ResetRetouche() const
Definition: frame.hxx:983
bool IsInvalidFlyLayout() const
Definition: pagefrm.hxx:217
void ValidateLayout() const
Definition: pagefrm.hxx:396
~SwLayAction()
Definition: layact.cxx:272
void ValidateSmartTags() const
Definition: pagefrm.hxx:409
void FormatContent_(const SwContentFrame *pContent, const SwPageFrame *pPage)
Definition: layact.cxx:1782
bool m_bPaint
Definition: layact.hxx:83
std::clock_t m_nStartTicks
Definition: layact.hxx:76
bool m_bCheckPages
Definition: layact.hxx:90
static bool FormatObjsAtFrame(SwFrame &_rAnchorFrame, const SwPageFrame &_rPageFrame, SwLayAction *_pLayAction=nullptr)
method to format all floating screen objects at the given anchor frame
bool IsLayoutFrame() const
Definition: frame.hxx:1146
void Left(const long nLeft)
Definition: swrect.hxx:193
bool IsInterrupt()
Definition: layact.cxx:278
bool exceededRuntime()
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:79
void Bottom(const long nBottom)
Definition: swrect.hxx:207
SwViewShellImp * m_pImp
Definition: layact.hxx:59
const SwContentFrame * GetTurbo()
Definition: rootfrm.hxx:347
sal_uInt32 m_nCallCount
Definition: layact.hxx:103
bool DoIdleJob_(const SwContentFrame *, IdleJobType)
Definition: layact.cxx:1859
const SwTabFrame * m_pOptTab
Definition: layact.hxx:67
const SvxOpaqueItem & GetOpaque(bool=true) const
Definition: frmatr.hxx:80
bool IsTabFrame() const
Definition: frame.hxx:1194
general base class for all free-flowing frames
Definition: flyfrm.hxx:60
long const nLeftMargin
SwViewShellImp * pImp
Definition: layact.hxx:185
void RemoveSuperfluous()
remove pages that are not needed at all
Definition: pagechg.cxx:1430
static void unlockPositionOfObjects(SwPageFrame *pPageFrame)
Definition: layact.cxx:407
bool IsBrowseActionStop() const
Definition: layact.hxx:165
SwTextFrame * FindMaster() const
Definition: flowfrm.cxx:679
WrongState GetWrongDirty() const
Definition: txtedt.cxx:2246
void ShellGetFocus()
Definition: crsrsh.cxx:2415
const SwViewOption * GetViewOptions() const
Definition: viewsh.hxx:426
void Width(long nNew)
Definition: swrect.hxx:185
vcl::Window * GetWin() const
Definition: viewsh.hxx:340
bool IsPaintExtraData() const
Definition: layact.hxx:140
const o3tl::enumarray< SvxAdjust, unsigned short > aSvxToUnoAdjust USHRT_MAX
Definition: unosett.cxx:261
virtual const SwDocStat & GetDocStat() const =0
Document - Statistics.
#define SAL_INFO(area, stream)
sal_Int32 GetIndex() const
Definition: index.hxx:95
bool IsNoTextFrame() const
Definition: frame.hxx:1214
bool IsHelpDocument() const
bool IsAgain() const
Definition: layact.hxx:160
bool IsLockWordLstLocked() const
Definition: acmplwrd.hxx:59
void SetWaitAllowed(bool bNew)
Definition: layact.hxx:149
bool IsPageFrame() const
Definition: frame.hxx:1154
bool IsAutoCompleteWordDirty() const
Definition: txtedt.cxx:2290
bool CountWords(SwDocStat &rStat, sal_Int32 nStart, sal_Int32 nEnd) const
count words in given range - returns true if we refreshed out count
Definition: txtedt.cxx:1980
bool PaintContent_(const SwContentFrame *, const SwPageFrame *, const SwRect &)
Definition: layact.cxx:180
bool IsPaint() const
Definition: layact.hxx:137
bool bModified
Definition: docstat.hxx:39
long GetHeight(const SwRect &rRect) const
Definition: frame.hxx:1358
static OUString GetEventName(sal_Int32 nId)
Definition: docsh.cxx:1348
void DisallowTurbo() const
Definition: rootfrm.hxx:342
bool IsRetouche() const
Definition: frame.hxx:583
bool FormatContent(const SwPageFrame *pPage)
Definition: layact.cxx:1597
SwContentNode * pContentNode
Definition: layact.hxx:186
virtual void Calc(vcl::RenderContext *pRenderContext) const override
Definition: fly.cxx:2826
Provides access to the layout of a document.
#define STR_SW_EVENT_LAYOUT_FINISHED
Definition: swevent.hxx:32
SwFootnoteIdxs & GetFootnoteIdxs()
Definition: doc.hxx:627
void FormatLayoutFly(SwFlyFrame *)
Definition: layact.cxx:1399
void SetCheckPages(bool bNew)
Definition: layact.hxx:131
SwLayAction(SwRootFrame *pRt, SwViewShellImp *pImp, TaskStopwatch *pWatch=nullptr)
Definition: layact.cxx:248
SwLayIdle * m_pIdleAct
Definition: viewimp.hxx:73
SwRegionRects * GetRegion()
Definition: viewimp.hxx:151
bool IsInvalid() const
Definition: pagefrm.hxx:422
bool IsIdle() const
Definition: layact.hxx:139
static void GetBorderAndShadowBoundRect(const SwRect &_rPageRect, const SwViewShell *_pViewShell, OutputDevice const *pRenderContext, SwRect &_orBorderAndShadowBoundRect, const bool bLeftShadow, const bool bRightShadow, const bool bRightSidebar)
get bound rectangle of border and shadow for repaints
Definition: paintfrm.cxx:6033
bool IsOver(const SwRect &rRect) const
Definition: swrect.cxx:125
long GetRightMargin(const SwFrame &rFrame) const
Definition: frame.hxx:1382
const SwContentFrame * ContainsContent() const
Checks if the frame contains one or more ContentFrame's anywhere in his subsidiary structure; if so t...
Definition: findfrm.cxx:66
void Push(PushFlags nFlags=PushFlags::ALL)
SwViewShell * GetCurrShell() const
Definition: rootfrm.hxx:204
bool IsAssertFlyPages()
Definition: rootfrm.hxx:277
sal_Int32 nPos
class for collecting anchored objects
Definition: sortedobjs.hxx:48
bool SupportsDoubleBuffering() const
bool IsSuperfluous() const
Definition: rootfrm.hxx:297
bool bPageValid
Definition: layact.hxx:188
sal_uInt16 GetPageNum() const
Definition: rootfrm.hxx:307
const sal_Int32 COMPLETE_STRING
Definition: swtypes.hxx:61
SwRootFrame * getRootFrame()
Definition: frame.hxx:657
bool IsInvalidLayout() const
Definition: pagefrm.hxx:220
static const SwFrame * lcl_FindFirstInvaLay(const SwFrame *pFrame, long nBottom)
Definition: layact.cxx:853
sal_uInt16 GetGapBetweenPages() const
Definition: viewopt.hxx:418
void UnlockPaint(bool bVirDev=false)
Definition: viewsh.hxx:609
SwLayIdle(SwRootFrame *pRt, SwViewShellImp *pImp)
Definition: layact.cxx:2125
bool IsRightShadowNeeded() const
Definition: paintfrm.cxx:5642
const IDocumentDrawModelAccess & getIDocumentDrawModelAccess() const
Provides access to the document draw model interface.
Definition: format.cxx:758
virtual const SwFrameFormat * GetFormat() const
Definition: ssfrm.cxx:393
SwTabFrame * FindTabFrame()
Definition: frame.hxx:1075
bool m_bNextCycle
Definition: layact.hxx:87
SwFrame * GetNext()
Definition: frame.hxx:654
virtual void BlockIdling()=0
Increment block count.
bool TurboAction()
Definition: layact.cxx:832