LibreOffice Module sw (master)  1
pagechg.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 <comphelper/lok.hxx>
21 #include <ndole.hxx>
22 #include <sal/log.hxx>
23 #include <svl/itemiter.hxx>
24 #include <fmtfsize.hxx>
25 #include <fmthdft.hxx>
26 #include <fmtclds.hxx>
27 #include <fmtpdsc.hxx>
28 #include <fmtornt.hxx>
29 #include <fmtsrnd.hxx>
30 #include <ftninfo.hxx>
31 #include <frmtool.hxx>
32 #include <tgrditem.hxx>
33 #include <viewopt.hxx>
34 #include <docsh.hxx>
35 #include <wrtsh.hxx>
36 #include <view.hxx>
37 #include <edtwin.hxx>
38 #include <frameformats.hxx>
39 
40 #include <viewimp.hxx>
41 #include <pagefrm.hxx>
42 #include <rootfrm.hxx>
46 #include <dcontact.hxx>
47 #include <hints.hxx>
48 #include <FrameControlsManager.hxx>
49 
50 #include <ftnidx.hxx>
51 #include <bodyfrm.hxx>
52 #include <ftnfrm.hxx>
53 #include <tabfrm.hxx>
54 #include <txtfrm.hxx>
55 #include <notxtfrm.hxx>
56 #include <layact.hxx>
57 #include <flyfrms.hxx>
58 #include <htmltbl.hxx>
59 #include <pagedesc.hxx>
60 #include <editeng/frmdiritem.hxx>
61 #include <sortedobjs.hxx>
62 #include <calbck.hxx>
63 #include <txtfly.hxx>
64 
65 using namespace ::com::sun::star;
66 
68  SwLayoutFrame( pFormat, pSib )
69 {
71 }
72 
73 void SwBodyFrame::Format( vcl::RenderContext* /*pRenderContext*/, const SwBorderAttrs * )
74 {
75  // Formatting of the body is too simple, thus, it gets its own format method.
76  // Borders etc. are not taken into account here.
77  // Width is taken from the PrtArea of the Upper. Height is the height of the
78  // PrtArea of the Upper minus any neighbors (for robustness).
79  // The PrtArea has always the size of the frame.
80 
81  if ( !isFrameAreaSizeValid() )
82  {
83  SwTwips nHeight = GetUpper()->getFramePrintArea().Height();
84  SwTwips nWidth = GetUpper()->getFramePrintArea().Width();
85  const SwFrame *pFrame = GetUpper()->Lower();
86  do
87  {
88  if ( pFrame != this )
89  {
90  if( pFrame->IsVertical() )
91  nWidth -= pFrame->getFrameArea().Width();
92  else
93  nHeight -= pFrame->getFrameArea().Height();
94  }
95  pFrame = pFrame->GetNext();
96  } while ( pFrame );
97 
98  if ( nHeight < 0 )
99  {
100  nHeight = 0;
101  }
102 
104  aFrm.Height( nHeight );
105 
106  if( IsVertical() && !IsVertLR() && nWidth != aFrm.Width() )
107  {
108  aFrm.Pos().setX(aFrm.Pos().getX() + aFrm.Width() - nWidth);
109  }
110 
111  aFrm.Width( nWidth );
112  }
113 
114  bool bNoGrid = true;
115  if( GetUpper()->IsPageFrame() && static_cast<SwPageFrame*>(GetUpper())->HasGrid() )
116  {
117  SwTextGridItem const*const pGrid(
118  GetGridItem(static_cast<SwPageFrame*>(GetUpper())));
119  if( pGrid )
120  {
121  bNoGrid = false;
122  tools::Long nSum = pGrid->GetBaseHeight() + pGrid->GetRubyHeight();
123  SwRectFnSet aRectFnSet(this);
124  tools::Long nSize = aRectFnSet.GetWidth(getFrameArea());
125  tools::Long nBorder = 0;
126  if( GRID_LINES_CHARS == pGrid->GetGridType() )
127  {
128  //for textgrid refactor
129  SwDoc *pDoc = GetFormat()->GetDoc();
130  nBorder = nSize % (GetGridWidth(*pGrid, *pDoc));
131  nSize -= nBorder;
132  nBorder /= 2;
133  }
134 
136  aRectFnSet.SetPosX( aPrt, nBorder );
137  aRectFnSet.SetWidth( aPrt, nSize );
138 
139  // Height of body frame:
140  nBorder = aRectFnSet.GetHeight(getFrameArea());
141 
142  // Number of possible lines in area of body frame:
143  tools::Long nNumberOfLines = nBorder / nSum;
144  if( nNumberOfLines > pGrid->GetLines() )
145  nNumberOfLines = pGrid->GetLines();
146 
147  // Space required for nNumberOfLines lines:
148  nSize = nNumberOfLines * nSum;
149  nBorder -= nSize;
150  nBorder /= 2;
151 
152  // #i21774# Footnotes and centering the grid does not work together:
153  const bool bAdjust = static_cast<SwPageFrame*>(GetUpper())->GetFormat()->GetDoc()->
154  GetFootnoteIdxs().empty();
155 
156  aRectFnSet.SetPosY( aPrt, bAdjust ? nBorder : 0 );
157  aRectFnSet.SetHeight( aPrt, nSize );
158  }
159  }
160 
161  if( bNoGrid )
162  {
164  aPrt.Pos().setX(0);
165  aPrt.Pos().setY(0);
166  aPrt.Height( getFrameArea().Height() );
167  aPrt.Width( getFrameArea().Width() );
168  }
169 
170  setFrameAreaSizeValid(true);
172 }
173 
175  SwFootnoteBossFrame( pFormat, pSib ),
176  m_pDesc( pPgDsc ),
177  m_nPhyPageNum( 0 )
178 {
179  SetDerivedVert( false );
180  SetDerivedR2L( false );
181  if( m_pDesc )
182  {
183  m_bHasGrid = true;
184  SwTextGridItem const*const pGrid(GetGridItem(this));
185  if( !pGrid )
186  m_bHasGrid = false;
187  }
188  else
189  m_bHasGrid = false;
191  pPgDsc->GetFootnoteInfo().GetHeight() : LONG_MAX );
195 
197  const bool bBrowseMode = pSh && pSh->GetViewOptions()->getBrowseMode();
198  vcl::RenderContext* pRenderContext = pSh ? pSh->GetOut() : nullptr;
199 
200  {
202 
203  if ( bBrowseMode )
204  {
205  aFrm.Height( 0 );
206  tools::Long nWidth = pSh->VisArea().Width();
207 
208  if ( !nWidth )
209  {
210  nWidth = 5000; // changes anyway
211  }
212 
213  aFrm.Width ( nWidth );
214  }
215  else
216  {
217  aFrm.SSize( pFormat->GetFrameSize().GetSize() );
218  }
219  }
220 
221  // create and insert body area if it is not a blank page
222  SwDoc* pDoc(pFormat->GetDoc());
223  m_bEmptyPage = (pFormat == pDoc->GetEmptyPageFormat());
224 
225  if(m_bEmptyPage)
226  {
227  return;
228  }
229 
230  Calc(pRenderContext); // so that the PrtArea is correct
231  SwBodyFrame *pBodyFrame = new SwBodyFrame( pDoc->GetDfltFrameFormat(), this );
232  pBodyFrame->ChgSize( getFramePrintArea().SSize() );
233  pBodyFrame->Paste( this );
234  pBodyFrame->Calc(pRenderContext); // so that the columns can be inserted correctly
235  pBodyFrame->InvalidatePos();
236 
237  if ( bBrowseMode )
238  InvalidateSize_();
239 
240  // insert header/footer,, but only if active.
241  if ( pFormat->GetHeader().IsActive() )
242  PrepareHeader();
243  if ( pFormat->GetFooter().IsActive() )
244  PrepareFooter();
245 
246  const SwFormatCol &rCol = pFormat->GetCol();
247  if ( rCol.GetNumCols() > 1 )
248  {
249  const SwFormatCol aOld; //ChgColumns() needs an old value
250  pBodyFrame->ChgColumns( aOld, rCol );
251  }
252 
253 }
254 
256 {
257  // Cleanup the header-footer controls in the SwEditWin
259  SwWrtShell* pWrtSh = dynamic_cast< SwWrtShell* >( pSh );
260  if ( pWrtSh )
261  {
262  SwEditWin& rEditWin = pWrtSh->GetView().GetEditWin();
263  rEditWin.GetFrameControlsManager( ).RemoveControls( this );
264  }
265 
266  // empty FlyContainer, deletion of the Flys is done by the anchor (in base class SwFrame)
267  if (m_pSortedObjs)
268  {
269  // Objects can be anchored at pages that are before their anchors (why ever...).
270  // In such cases, we would access already freed memory.
271  for (SwAnchoredObject* pAnchoredObj : *m_pSortedObjs)
272  {
273  pAnchoredObj->SetPageFrame( nullptr );
274  }
275  m_pSortedObjs.reset(); // reset to zero to prevent problems when detaching the Flys
276  }
277 
278  // prevent access to destroyed pages
279  SwDoc *pDoc = GetFormat() ? GetFormat()->GetDoc() : nullptr;
280  if( pDoc && !pDoc->IsInDtor() )
281  {
282  if ( pSh )
283  {
284  SwViewShellImp *pImp = pSh->Imp();
285  pImp->SetFirstVisPageInvalid();
286  if ( pImp->IsAction() )
287  pImp->GetLayAction().SetAgain();
288  // #i9719# - retouche area of page
289  // including border and shadow area.
290  const bool bRightSidebar = (SidebarPosition() == sw::sidebarwindows::SidebarPosition::RIGHT);
291  SwRect aRetoucheRect;
292  SwPageFrame::GetBorderAndShadowBoundRect( getFrameArea(), pSh, pSh->GetOut(), aRetoucheRect, IsLeftShadowNeeded(), IsRightShadowNeeded(), bRightSidebar );
293  pSh->AddPaintRect( aRetoucheRect );
294  }
295  }
296 
298 }
299 
301 {
302 }
303 
304 void SwPageFrame::CheckGrid( bool bInvalidate )
305 {
306  bool bOld = m_bHasGrid;
307  m_bHasGrid = true;
308  SwTextGridItem const*const pGrid(GetGridItem(this));
309  m_bHasGrid = nullptr != pGrid;
310  if( !(bInvalidate || bOld != m_bHasGrid) )
311  return;
312 
313  SwLayoutFrame* pBody = FindBodyCont();
314  if( pBody )
315  {
316  pBody->InvalidatePrt();
317  SwContentFrame* pFrame = pBody->ContainsContent();
318  while( pBody->IsAnLower( pFrame ) )
319  {
320  static_cast<SwTextFrame*>(pFrame)->Prepare();
321  pFrame = pFrame->GetNextContentFrame();
322  }
323  }
325 }
326 
327 void SwPageFrame::CheckDirection( bool bVert )
328 {
329  SvxFrameDirection nDir = GetFormat()->GetFormatAttr( RES_FRAMEDIR ).GetValue();
330  if( bVert )
331  {
332  if( SvxFrameDirection::Horizontal_LR_TB == nDir || SvxFrameDirection::Horizontal_RL_TB == nDir )
333  {
334  mbVertLR = false;
335  mbVertical = false;
336  }
337  else
338  {
339  const SwViewShell *pSh = getRootFrame()->GetCurrShell();
340  if( pSh && pSh->GetViewOptions()->getBrowseMode() )
341  {
342  mbVertLR = false;
343  mbVertical = false;
344  }
345  else
346  {
347  mbVertical = true;
348 
349  if(SvxFrameDirection::Vertical_RL_TB == nDir)
350  mbVertLR = false;
351  else if(SvxFrameDirection::Vertical_LR_TB==nDir)
352  mbVertLR = true;
353  }
354  }
355 
356  mbInvalidVert = false;
357  }
358  else
359  {
360  if( SvxFrameDirection::Horizontal_RL_TB == nDir )
361  mbRightToLeft = true;
362  else
363  mbRightToLeft = false;
364  mbInvalidR2L = false;
365  }
366 }
367 
369 static void lcl_FormatLay( SwLayoutFrame *pLay )
370 {
371  vcl::RenderContext* pRenderContext = pLay->getRootFrame()->GetCurrShell()->GetOut();
372  // format all LayoutFrames - no tables, Flys etc.
373 
374  SwFrame *pTmp = pLay->Lower();
375  // first the low-level ones
376  while ( pTmp )
377  {
381  if ( pTmp->GetType() & nTypes )
382  ::lcl_FormatLay( static_cast<SwLayoutFrame*>(pTmp) );
383  pTmp = pTmp->GetNext();
384  }
385  pLay->Calc(pRenderContext);
386 }
387 
389 static void lcl_MakeObjs( const SwFrameFormats &rTable, SwPageFrame *pPage )
390 {
391  // formats are in the special table of the document
392 
393  for ( size_t i = 0; i < rTable.size(); ++i )
394  {
395  SwFrameFormat *pFormat = rTable[i];
396  const SwFormatAnchor &rAnch = pFormat->GetAnchor();
397  if ( rAnch.GetPageNum() == pPage->GetPhyPageNum() )
398  {
399  if( rAnch.GetContentAnchor() )
400  {
401  if (RndStdIds::FLY_AT_PAGE == rAnch.GetAnchorId())
402  {
403  SwFormatAnchor aAnch( rAnch );
404  aAnch.SetAnchor( nullptr );
405  pFormat->SetFormatAttr( aAnch );
406  }
407  else
408  continue;
409  }
410 
411  // is it a border or a SdrObject?
412  bool bSdrObj = RES_DRAWFRMFMT == pFormat->Which();
413  SdrObject *pSdrObj = nullptr;
414  if ( bSdrObj && nullptr == (pSdrObj = pFormat->FindSdrObject()) )
415  {
416  OSL_FAIL( "DrawObject not found." );
417  pFormat->GetDoc()->DelFrameFormat( pFormat );
418  --i;
419  continue;
420  }
421  // The object might be anchored to another page, e.g. when inserting
422  // a new page due to a page descriptor change. In such cases, the
423  // object needs to be moved.
424  // In some cases the object is already anchored to the correct page.
425  // This will be handled here and does not need to be coded extra.
426  SwPageFrame *pPg = pPage->IsEmptyPage() ? static_cast<SwPageFrame*>(pPage->GetNext()) : pPage;
427  if ( bSdrObj )
428  {
429  // OD 23.06.2003 #108784# - consider 'virtual' drawing objects
430  SwDrawContact *pContact =
431  static_cast<SwDrawContact*>(::GetUserCall(pSdrObj));
432  if ( auto pDrawVirtObj = dynamic_cast<SwDrawVirtObj *>( pSdrObj ) )
433  {
434  if ( pContact )
435  {
436  pDrawVirtObj->RemoveFromWriterLayout();
437  pDrawVirtObj->RemoveFromDrawingPage();
438  pPg->AppendDrawObj( *(pContact->GetAnchoredObj( pDrawVirtObj )) );
439  }
440  }
441  else
442  {
443  if ( pContact->GetAnchorFrame() )
444  pContact->DisconnectFromLayout( false );
445  pPg->AppendDrawObj( *(pContact->GetAnchoredObj( pSdrObj )) );
446  }
447  }
448  else
449  {
450  SwIterator<SwFlyFrame,SwFormat> aIter( *pFormat );
451  SwFlyFrame *pFly = aIter.First();
452  if ( pFly)
453  {
454  if( pFly->GetAnchorFrame() )
455  pFly->AnchorFrame()->RemoveFly( pFly );
456  }
457  else
458  pFly = new SwFlyLayFrame( static_cast<SwFlyFrameFormat*>(pFormat), pPg, pPg );
459  pPg->AppendFly( pFly );
460  ::RegistFlys( pPg, pFly );
461  }
462  }
463  }
464 }
465 
467 {
468  SetFootnotePage( bFootnote );
469 
470  // #i82258#
471  // Due to made change on OOo 2.0 code line, method <::lcl_FormatLay(..)> has
472  // the side effect, that the content of page header and footer are formatted.
473  // For this formatting it is needed that the anchored objects are registered
474  // at the <SwPageFrame> instance.
475  // Thus, first calling <::RegistFlys(..)>, then call <::lcl_FormatLay(..)>
476  ::RegistFlys( this, this );
477 
478  if ( Lower() )
479  {
480  ::lcl_FormatLay( this );
481  }
482 
483  // Flys and draw objects that are still attached to the document.
484  // Footnote pages do not have page-bound Flys!
485  // There might be Flys or draw objects that want to be placed on
486  // empty pages, however, the empty pages ignore that and the following
487  // pages take care of them.
488  if ( !bFootnote && !IsEmptyPage() )
489  {
490  SwDoc *pDoc = GetFormat()->GetDoc();
491 
492  if ( GetPrev() && static_cast<SwPageFrame*>(GetPrev())->IsEmptyPage() )
493  lcl_MakeObjs( *pDoc->GetSpzFrameFormats(), static_cast<SwPageFrame*>(GetPrev()) );
494  lcl_MakeObjs( *pDoc->GetSpzFrameFormats(), this );
495  }
496 }
497 
498 void SwPageFrame::Modify( const SfxPoolItem* pOld, const SfxPoolItem * pNew )
499 {
501  if ( pSh )
502  pSh->SetFirstVisPageInvalid();
503  sal_uInt8 nInvFlags = 0;
504 
505  if( pNew && RES_ATTRSET_CHG == pNew->Which() )
506  {
507  SfxItemIter aNIter( *static_cast<const SwAttrSetChg*>(pNew)->GetChgSet() );
508  SfxItemIter aOIter( *static_cast<const SwAttrSetChg*>(pOld)->GetChgSet() );
509  const SfxPoolItem* pNItem = aNIter.GetCurItem();
510  const SfxPoolItem* pOItem = aOIter.GetCurItem();
511  SwAttrSetChg aOldSet( *static_cast<const SwAttrSetChg*>(pOld) );
512  SwAttrSetChg aNewSet( *static_cast<const SwAttrSetChg*>(pNew) );
513  do
514  {
515  UpdateAttr_(pOItem, pNItem, nInvFlags, &aOldSet, &aNewSet);
516  pNItem = aNIter.NextItem();
517  pOItem = aOIter.NextItem();
518  } while (pNItem);
519  if ( aOldSet.Count() || aNewSet.Count() )
520  SwLayoutFrame::Modify( &aOldSet, &aNewSet );
521  }
522  else
523  UpdateAttr_( pOld, pNew, nInvFlags );
524 
525  if ( nInvFlags == 0 )
526  return;
527 
528  InvalidatePage( this );
529  if ( nInvFlags & 0x01 )
530  InvalidatePrt_();
531  if ( nInvFlags & 0x02 )
533  if ( nInvFlags & 0x04 && GetNext() )
534  GetNext()->InvalidatePos();
535  if ( nInvFlags & 0x08 )
536  PrepareHeader();
537  if ( nInvFlags & 0x10 )
538  PrepareFooter();
539  if ( nInvFlags & 0x20 )
540  CheckGrid( nInvFlags & 0x40 );
541 }
542 
543 
544 void SwPageFrame::SwClientNotify(const SwModify& rModify, const SfxHint& rHint)
545 {
546  if(typeid(sw::PageFootnoteHint) == typeid(rHint))
547  {
548  // currently the savest way:
549  static_cast<SwRootFrame*>(GetUpper())->SetSuperfluous();
551  if(!GetMaxFootnoteHeight())
554  // here, the page might be destroyed:
555  static_cast<SwRootFrame*>(GetUpper())->RemoveFootnotes(nullptr, false, true);
556  }
557  else
558  SwFrame::SwClientNotify(rModify, rHint);
559 }
560 
561 void SwPageFrame::UpdateAttr_( const SfxPoolItem *pOld, const SfxPoolItem *pNew,
562  sal_uInt8 &rInvFlags,
563  SwAttrSetChg *pOldSet, SwAttrSetChg *pNewSet )
564 {
565  bool bClear = true;
566  const sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
567  switch( nWhich )
568  {
569  case RES_FMT_CHG:
570  {
571  // state of m_bEmptyPage needs to be determined newly
572  const bool bNewState(GetFormat() == GetFormat()->GetDoc()->GetEmptyPageFormat());
573 
574  if(m_bEmptyPage != bNewState)
575  {
576  // copy new state
577  m_bEmptyPage = bNewState;
578 
579  if(nullptr == GetLower())
580  {
581  // if we were an empty page before there is not yet a BodyArea in the
582  // form of a SwBodyFrame, see constructor
583  SwViewShell* pSh(getRootFrame()->GetCurrShell());
584  vcl::RenderContext* pRenderContext(pSh ? pSh->GetOut() : nullptr);
585  Calc(pRenderContext); // so that the PrtArea is correct
586  SwBodyFrame* pBodyFrame = new SwBodyFrame(GetFormat(), this);
587  pBodyFrame->ChgSize(getFramePrintArea().SSize());
588  pBodyFrame->Paste(this);
589  pBodyFrame->InvalidatePos();
590  }
591  }
592 
593  // If the frame format is changed, several things might also change:
594  // 1. columns:
595  assert(pOld && pNew); //FMT_CHG Missing Format
596  const SwFormat *const pOldFormat = static_cast<const SwFormatChg*>(pOld)->pChangedFormat;
597  const SwFormat *const pNewFormat = static_cast<const SwFormatChg*>(pNew)->pChangedFormat;
598  assert(pOldFormat && pNewFormat); //FMT_CHG Missing Format
599  const SwFormatCol &rOldCol = pOldFormat->GetCol();
600  const SwFormatCol &rNewCol = pNewFormat->GetCol();
601  if( rOldCol != rNewCol )
602  {
603  SwLayoutFrame *pB = FindBodyCont();
604  assert(pB && "Page without Body.");
605  pB->ChgColumns( rOldCol, rNewCol );
606  rInvFlags |= 0x20;
607  }
608 
609  // 2. header and footer:
610  const SwFormatHeader &rOldH = pOldFormat->GetHeader();
611  const SwFormatHeader &rNewH = pNewFormat->GetHeader();
612  if( rOldH != rNewH )
613  rInvFlags |= 0x08;
614 
615  const SwFormatFooter &rOldF = pOldFormat->GetFooter();
616  const SwFormatFooter &rNewF = pNewFormat->GetFooter();
617  if( rOldF != rNewF )
618  rInvFlags |= 0x10;
619  CheckDirChange();
620 
621  [[fallthrough]];
622  }
623  case RES_FRM_SIZE:
624  {
625  const SwRect aOldPageFrameRect( getFrameArea() );
627  if( pSh && pSh->GetViewOptions()->getBrowseMode() )
628  {
629  setFrameAreaSizeValid(false);
630  // OD 28.10.2002 #97265# - Don't call <SwPageFrame::MakeAll()>
631  // Calculation of the page is not necessary, because its size is
632  // invalidated here and further invalidation is done in the
633  // calling method <SwPageFrame::Modify(..)> and probably by calling
634  // <SwLayoutFrame::Modify(..)> at the end.
635  // It can also causes inconsistences, because the lowers are
636  // adjusted, but not calculated, and a <SwPageFrame::MakeAll()> of
637  // a next page is called. This is performed on the switch to the
638  // online layout.
639  //MakeAll();
640  }
641  else if (pNew)
642  {
643  const SwFormatFrameSize &rSz = nWhich == RES_FMT_CHG ?
644  static_cast<const SwFormatChg*>(pNew)->pChangedFormat->GetFrameSize() :
645  static_cast<const SwFormatFrameSize&>(*pNew);
646 
647  {
649  aFrm.Height( std::max( rSz.GetHeight(), tools::Long(MINLAY) ) );
650  aFrm.Width ( std::max( rSz.GetWidth(), tools::Long(MINLAY) ) );
651  }
652 
653  if ( GetUpper() )
654  {
655  static_cast<SwRootFrame*>(GetUpper())->CheckViewLayout( nullptr, nullptr );
656  }
657  }
658  // cleanup Window
659  if( pSh && pSh->GetWin() && aOldPageFrameRect.HasArea() )
660  {
661  // #i9719# - consider border and shadow of
662  // page frame for determine 'old' rectangle - it's used for invalidating.
663  const bool bRightSidebar = (SidebarPosition() == sw::sidebarwindows::SidebarPosition::RIGHT);
664  SwRect aOldRectWithBorderAndShadow;
665  SwPageFrame::GetBorderAndShadowBoundRect( aOldPageFrameRect, pSh, pSh->GetOut(), aOldRectWithBorderAndShadow,
666  IsLeftShadowNeeded(), IsRightShadowNeeded(), bRightSidebar );
667  pSh->InvalidateWindows( aOldRectWithBorderAndShadow );
668  }
669  rInvFlags |= 0x03;
670  if ( aOldPageFrameRect.Height() != getFrameArea().Height() )
671  rInvFlags |= 0x04;
672  }
673  break;
674 
675  case RES_COL:
676  assert(pOld && pNew); //COL Missing Format
677  if (pOld && pNew)
678  {
679  SwLayoutFrame *pB = FindBodyCont();
680  assert(pB); //page without body
681  pB->ChgColumns( *static_cast<const SwFormatCol*>(pOld), *static_cast<const SwFormatCol*>(pNew) );
682  rInvFlags |= 0x22;
683  }
684  break;
685 
686  case RES_HEADER:
687  rInvFlags |= 0x08;
688  break;
689 
690  case RES_FOOTER:
691  rInvFlags |= 0x10;
692  break;
693  case RES_TEXTGRID:
694  rInvFlags |= 0x60;
695  break;
696  case RES_FRAMEDIR :
697  CheckDirChange();
698  break;
699 
700  default:
701  bClear = false;
702  }
703  if ( bClear )
704  {
705  if ( pOldSet || pNewSet )
706  {
707  if ( pOldSet )
708  pOldSet->ClearItem( nWhich );
709  if ( pNewSet )
710  pNewSet->ClearItem( nWhich );
711  }
712  else
713  SwLayoutFrame::Modify( pOld, pNew );
714  }
715 }
716 
718 bool SwPageFrame::GetInfo( SfxPoolItem & rInfo ) const
719 {
720  if( RES_AUTOFMT_DOCNODE == rInfo.Which() )
721  {
722  // a page frame exists, so use this one
723  return false;
724  }
725  return true; // continue searching
726 }
727 
729 {
730  m_pDesc = pNew;
731  if ( pFormat )
732  SetFrameFormat( pFormat );
733 }
734 
735 /* determine the right PageDesc:
736  * 0. from the document for footnote and endnote pages
737  * 1. from the first BodyContent below a page
738  * 2. from PageDesc of the predecessor page
739  * 3. from PageDesc of the previous page if blank page
740  * 3.1 from PageDesc of the next page if no predecessor exists
741  * 4. default PageDesc
742  * 5. In BrowseMode use the first paragraph or default PageDesc.
743  */
745 {
746  // 0.
747  if ( IsFootnotePage() )
748  {
749  SwDoc *pDoc = GetFormat()->GetDoc();
750  if ( IsEndNotePage() )
751  return pDoc->GetEndNoteInfo().GetPageDesc( *pDoc );
752  else
753  return pDoc->GetFootnoteInfo().GetPageDesc( *pDoc );
754  }
755 
756  SwPageDesc *pRet = nullptr;
757 
758  //5.
759  const SwViewShell *pSh = getRootFrame()->GetCurrShell();
760  if( pSh && pSh->GetViewOptions()->getBrowseMode() )
761  {
762  SwContentFrame *pFrame = GetUpper()->ContainsContent();
763  while (pFrame && !pFrame->IsInDocBody())
764  pFrame = pFrame->GetNextContentFrame();
765  if (pFrame)
766  {
767  SwFrame *pFlow = pFrame;
768  if ( pFlow->IsInTab() )
769  pFlow = pFlow->FindTabFrame();
770  pRet = const_cast<SwPageDesc*>(pFlow->GetPageDescItem().GetPageDesc());
771  }
772  if ( !pRet )
773  pRet = &GetFormat()->GetDoc()->GetPageDesc( 0 );
774  return pRet;
775  }
776 
777  SwFrame *pFlow = FindFirstBodyContent();
778  if ( pFlow && pFlow->IsInTab() )
779  pFlow = pFlow->FindTabFrame();
780 
781  //1.
782  if ( pFlow )
783  {
784  SwFlowFrame *pTmp = SwFlowFrame::CastFlowFrame( pFlow );
785  if ( !pTmp->IsFollow() )
786  pRet = const_cast<SwPageDesc*>(pFlow->GetPageDescItem().GetPageDesc());
787  }
788 
789  //3. and 3.1
790  if ( !pRet && IsEmptyPage() )
791  // FME 2008-03-03 #i81544# lijian/fme: an empty page should have
792  // the same page description as its prev, just like after construction
793  // of the empty page.
794  pRet = GetPrev() ? static_cast<SwPageFrame*>(GetPrev())->GetPageDesc() :
795  GetNext() ? static_cast<SwPageFrame*>(GetNext())->GetPageDesc() : nullptr;
796 
797  //2.
798  if ( !pRet )
799  pRet = GetPrev() ?
800  static_cast<SwPageFrame*>(GetPrev())->GetPageDesc()->GetFollow() : nullptr;
801 
802  //4.
803  if ( !pRet )
804  pRet = &GetFormat()->GetDoc()->GetPageDesc( 0 );
805 
806  OSL_ENSURE( pRet, "could not find page descriptor." );
807  return pRet;
808 }
809 
810 // Notify if the RootFrame changes its size
812 {
813  const bool bOld = pRoot->IsSuperfluous();
814  pRoot->mbCheckSuperfluous = false;
815  if ( pRoot->GetCurrShell() )
816  {
817  for(SwViewShell& rSh : pRoot->GetCurrShell()->GetRingContainer())
818  {
819  if( pRoot == rSh.GetLayout() )
820  {
821  rSh.SizeChgNotify();
822  if ( rSh.Imp() )
823  rSh.Imp()->NotifySizeChg( pRoot->getFrameArea().SSize() );
824  }
825  }
826  }
827  pRoot->mbCheckSuperfluous = bOld;
828 }
829 
830 inline void SetLastPage( SwPageFrame *pPage )
831 {
832  static_cast<SwRootFrame*>(pPage->GetUpper())->mpLastPage = pPage;
833 }
834 
836 {
838  if ( !IsEmptyPage() )
839  {
840  if ( GetNext() )
841  GetNext()->InvalidatePos();
842 
843  // move Flys whose anchor is on a different page (draw objects are not relevant here)
844  if ( GetSortedObjs() )
845  {
846  size_t i = 0;
847  while ( GetSortedObjs() && i < GetSortedObjs()->size() )
848  {
849  // #i28701#
850  SwAnchoredObject* pAnchoredObj = (*GetSortedObjs())[i];
851 
852  if ( auto pFly = dynamic_cast<SwFlyAtContentFrame *>( pAnchoredObj ) )
853  {
854  SwPageFrame *pAnchPage = pFly->GetAnchorFrame() ?
855  pFly->AnchorFrame()->FindPageFrame() : nullptr;
856  if ( pAnchPage && (pAnchPage != this) )
857  {
858  MoveFly( pFly, pAnchPage );
859  pFly->InvalidateSize();
860  pFly->InvalidatePos_();
861  // Do not increment index, in this case
862  continue;
863  }
864  }
865  ++i;
866  }
867  }
868  // cleanup Window
869  if ( pSh && pSh->GetWin() )
871  }
872 
873  // decrease the root's page number
874  static_cast<SwRootFrame*>(GetUpper())->DecrPhyPageNums();
875  SwPageFrame *pPg = static_cast<SwPageFrame*>(GetNext());
876  if ( pPg )
877  {
878  while ( pPg )
879  {
880  --pPg->m_nPhyPageNum;
881  pPg = static_cast<SwPageFrame*>(pPg->GetNext());
882  }
883  }
884  else
885  ::SetLastPage( static_cast<SwPageFrame*>(GetPrev()) );
886 
887  SwFrame* pRootFrame = GetUpper();
888 
889  // cut all connections
891 
892  if ( pRootFrame )
893  static_cast<SwRootFrame*>(pRootFrame)->CheckViewLayout( nullptr, nullptr );
894 }
895 
896 void SwPageFrame::Paste( SwFrame* pParent, SwFrame* pSibling )
897 {
898  OSL_ENSURE( pParent->IsRootFrame(), "Parent is no Root." );
899  OSL_ENSURE( pParent, "No parent for Paste()." );
900  OSL_ENSURE( pParent != this, "I'm my own parent." );
901  OSL_ENSURE( pSibling != this, "I'm my own neighbour." );
902  OSL_ENSURE( !GetPrev() && !GetNext() && !GetUpper(),
903  "I am still registered somewhere." );
904 
905  // insert into tree structure
906  InsertBefore( static_cast<SwLayoutFrame*>(pParent), pSibling );
907 
908  // increase the root's page number
909  static_cast<SwRootFrame*>(GetUpper())->IncrPhyPageNums();
910  if( GetPrev() )
911  SetPhyPageNum( static_cast<SwPageFrame*>(GetPrev())->GetPhyPageNum() + 1 );
912  else
913  SetPhyPageNum( 1 );
914  SwPageFrame *pPg = static_cast<SwPageFrame*>(GetNext());
915  if ( pPg )
916  {
917  while ( pPg )
918  {
919  ++pPg->m_nPhyPageNum;
920  pPg->InvalidatePos_();
921  pPg->InvalidateLayout();
922  pPg = static_cast<SwPageFrame*>(pPg->GetNext());
923  }
924  }
925  else
926  ::SetLastPage( this );
927 
928  if( getFrameArea().Width() != pParent->getFramePrintArea().Width() )
929  InvalidateSize_();
930 
931  InvalidatePos();
932 
934  if ( pSh )
935  pSh->SetFirstVisPageInvalid();
936 
937  getRootFrame()->CheckViewLayout( nullptr, nullptr );
938 }
939 
941 {
942  pFrame->Prepare( PrepareHint::Register );
943  if( !pFrame->GetDrawObjs() )
944  return;
945 
946  for(SwAnchoredObject* pAnchoredObj : *pFrame->GetDrawObjs())
947  {
948  // #i28701#
949  if ( auto pFly = dynamic_cast<SwFlyInContentFrame *>( pAnchoredObj ) )
950  {
951  SwContentFrame *pCnt = pFly->ContainsContent();
952  while ( pCnt )
953  {
954  lcl_PrepFlyInCntRegister( pCnt );
955  pCnt = pCnt->GetNextContentFrame();
956  }
957  }
958  }
959 }
960 
962 {
964  while( pFrame )
965  {
966  lcl_PrepFlyInCntRegister( pFrame );
967  pFrame = pFrame->GetNextContentFrame();
968  if( !IsAnLower( pFrame ) )
969  break;
970  }
971  if( !GetSortedObjs() )
972  return;
973 
974  for(SwAnchoredObject* pAnchoredObj : *GetSortedObjs())
975  {
976  // #i28701#
977  if ( auto pFly = dynamic_cast<SwFlyFrame *>( pAnchoredObj ) )
978  {
979  pFrame = pFly->ContainsContent();
980  while ( pFrame )
981  {
982  ::lcl_PrepFlyInCntRegister( pFrame );
983  pFrame = pFrame->GetNextContentFrame();
984  }
985  }
986  }
987 }
988 
989 namespace sw {
990 
992 bool IsPageFrameEmpty(SwPageFrame const& rPage)
993 {
994  bool bExistEssentialObjs = (nullptr != rPage.GetSortedObjs());
995  if (bExistEssentialObjs)
996  {
997  // Only because the page has Flys does not mean that it is needed. If all Flys are
998  // attached to generic content it is also superfluous (checking DocBody should be enough)
999  // OD 19.06.2003 - consider that drawing objects in
1000  // header/footer are supported now.
1001  bool bOnlySuperfluousObjs = true;
1002  SwSortedObjs const& rObjs = *rPage.GetSortedObjs();
1003  for (size_t i = 0; bOnlySuperfluousObjs && i < rObjs.size(); ++i)
1004  {
1005  // #i28701#
1006  SwAnchoredObject* pAnchoredObj = rObjs[i];
1007  // do not consider hidden objects
1009  pAnchoredObj->GetDrawObj()->GetLayer() ) &&
1010  !pAnchoredObj->GetAnchorFrame()->FindFooterOrHeader() )
1011  {
1012  bOnlySuperfluousObjs = false;
1013  }
1014  }
1015  bExistEssentialObjs = !bOnlySuperfluousObjs;
1016  }
1017 
1018  // optimization: check first if essential objects exist.
1019  const SwLayoutFrame* pBody = nullptr;
1020  if ( bExistEssentialObjs ||
1021  rPage.FindFootnoteCont() ||
1022  (nullptr != (pBody = rPage.FindBodyCont()) &&
1023  ( pBody->ContainsContent() ||
1024  // #i47580#
1025  // Do not delete page if there's an empty tabframe
1026  // left. I think it might be correct to use ContainsAny()
1027  // instead of ContainsContent() to cover the empty-table-case,
1028  // but I'm not fully sure, since ContainsAny() also returns
1029  // SectionFrames. Therefore I prefer to do it the safe way:
1030  ( pBody->Lower() && pBody->Lower()->IsTabFrame() ) ) ) )
1031  {
1032  return false;
1033  }
1034  else
1035  {
1036  return true;
1037  }
1038 }
1039 
1040 } // namespace sw
1041 
1042 //FIXME: provide missing documentation
1053 void SwFrame::CheckPageDescs( SwPageFrame *pStart, bool bNotifyFields, SwPageFrame** ppPrev )
1054 {
1055  SAL_INFO( "sw.pageframe", "(CheckPageDescs in phy: " << pStart->GetPhyPageNum() );
1056  assert(pStart && "no starting page.");
1057 
1058  SwViewShell *pSh = pStart->getRootFrame()->GetCurrShell();
1059  SwViewShellImp *pImp = pSh ? pSh->Imp() : nullptr;
1060 
1061  if ( pImp && pImp->IsAction() && !pImp->GetLayAction().IsCheckPages() )
1062  {
1063  pImp->GetLayAction().SetCheckPageNum( pStart->GetPhyPageNum() );
1064  SAL_INFO( "sw.pageframe", "CheckPageDescs out fast - via SetCheckPageNum: "
1065  << pStart->GetPhyPageNum() << ")" );
1066  return;
1067  }
1068 
1069  // For the update of page numbering fields, nDocPos provides
1070  // the page position from where invalidation should start.
1071  SwTwips nDocPos = LONG_MAX;
1072 
1073  SwRootFrame *pRoot = static_cast<SwRootFrame*>(pStart->GetUpper());
1074  SwDoc* pDoc = pStart->GetFormat()->GetDoc();
1075  const bool bFootnotes = !pDoc->GetFootnoteIdxs().empty();
1076 
1077  SwPageFrame *pPage = pStart;
1078  if( pPage->GetPrev() && static_cast<SwPageFrame*>(pPage->GetPrev())->IsEmptyPage() )
1079  pPage = static_cast<SwPageFrame*>(pPage->GetPrev());
1080  while ( pPage )
1081  {
1082  SwPageFrame *pPrevPage = static_cast<SwPageFrame*>(pPage->GetPrev());
1083  SwPageFrame *pNextPage = static_cast<SwPageFrame*>(pPage->GetNext());
1084 
1085  SwPageDesc *pDesc = pPage->FindPageDesc();
1087  bool bIsEmpty = pPage->IsEmptyPage();
1088  // false for intentionally empty pages, they need additional check
1089  bool isPageFrameEmpty(!bIsEmpty && sw::IsPageFrameEmpty(*pPage));
1090  bool bIsOdd = pPage->OnRightPage();
1091  bool bWantOdd = pPage->WannaRightPage();
1092  bool bFirst = pPage->OnFirstPage();
1093  SwFrameFormat *pFormatWish = bWantOdd
1094  ? pDesc->GetRightFormat(bFirst) : pDesc->GetLeftFormat(bFirst);
1095 
1096  if ( bIsOdd != bWantOdd ||
1097  pDesc != pPage->GetPageDesc() || // wrong Desc
1098  ( pFormatWish != pPage->GetFormat() && // wrong format and
1099  ( !bIsEmpty || pFormatWish ) // not blank /empty
1100  )
1101  )
1102  {
1103  // Updating a page might take a while, so check the WaitCursor
1104  if( pImp )
1105  pImp->CheckWaitCursor();
1106 
1107  // invalidate the field, starting from here
1108  if ( nDocPos == LONG_MAX )
1109  nDocPos = pPrevPage ? pPrevPage->getFrameArea().Top() : pPage->getFrameArea().Top();
1110 
1111  // Cases:
1112  // 1. Empty page should be "normal" page -> remove empty page and take next one
1113  // 2. Empty page should have different descriptor -> change
1114  // 3. Normal page should be empty -> insert empty page if previous page
1115  // is not empty, otherwise see (6).
1116  // 4. Normal page should have different descriptor -> change
1117  // 5. Normal page should have different format -> change
1118  // 6. No "wish" format provided -> take the "other" format (left/right) of the PageDesc
1119 
1120  if ( bIsEmpty && ( pFormatWish || //1.
1121  ( !bWantOdd && !pPrevPage ) ) )
1122  {
1123  // Check all cases for the next page, so we don't oscillate empty pages
1124  // Skip case 1 and 2, as we require a non-empty next page to save the empty page
1125  // Case 3 is the one we actually want to predict and skip
1126  // We can skip the empty check of case 3, as we just work on an existing next page
1127  bool bNextWantOdd;
1128  SwPageDesc *pNextDesc;
1129  if ( pNextPage && !pNextPage->IsEmptyPage() && //3.
1130  pNextPage->OnRightPage() == (bNextWantOdd = pNextPage->WannaRightPage()) &&
1131  pNextPage->GetPageDesc() == (pNextDesc = pNextPage->FindPageDesc()) ) //4.
1132  {
1133  bool bNextFirst = pNextPage->OnFirstPage();
1134  SwFrameFormat *pNextFormatWish = bNextWantOdd ? //5.
1135  pNextDesc->GetRightFormat(bNextFirst) : pNextDesc->GetLeftFormat(bNextFirst);
1136  if ( !pNextFormatWish ) // 6.
1137  pNextFormatWish = bNextWantOdd ? pNextDesc->GetLeftFormat() : pNextDesc->GetRightFormat();
1138  if ( pNextFormatWish && pNextPage->GetFormat() == pNextFormatWish )
1139  {
1140  SAL_INFO( "sw.pageframe", "CheckPageDescs phys: " << pPage->GetPhyPageNum()
1141  << " c: 1+3 - skip next page of p: " << pPage );
1142  if (pPrevPage && pPage->GetPageDesc() != pPrevPage->GetPageDesc())
1143  pPage->SetPageDesc( pPrevPage->GetPageDesc(), nullptr );
1144  // We can skip the next page, as all checks were already done!
1145  pPage = static_cast<SwPageFrame*>(pNextPage->GetNext());
1146  continue;
1147  }
1148  }
1149 
1150  pPage->Cut();
1151  bool bUpdatePrev = false;
1152  if (ppPrev && *ppPrev == pPage)
1153  bUpdatePrev = true;
1154  SAL_INFO( "sw.pageframe", "CheckPageDescs phys: " << pPage->GetPhyPageNum()
1155  << " c: 1 - destroy p: " << pPage );
1156  SwFrame::DestroyFrame(pPage);
1157  if ( pStart == pPage )
1158  pStart = pNextPage;
1159  pPage = pNextPage;
1160  if (bUpdatePrev)
1161  *ppPrev = pNextPage;
1162  continue;
1163  }
1164  else if ( bIsEmpty && !pFormatWish && //2.
1165  pDesc != pPage->GetPageDesc() )
1166  {
1167  SAL_INFO( "sw.pageframe", "CheckPageDescs phys: " << pPage->GetPhyPageNum()
1168  << " c: 2 - set desc p: " << pPage << " d: " << pDesc );
1169  pPage->SetPageDesc( pDesc, nullptr );
1170  }
1171  else if ( !bIsEmpty && //3.
1172  bIsOdd != bWantOdd &&
1173  ( ( !pPrevPage && !bWantOdd ) ||
1174  ( pPrevPage && !pPrevPage->IsEmptyPage() )
1175  )
1176  )
1177  {
1178  if ( pPrevPage )
1179  pDesc = pPrevPage->GetPageDesc();
1180  SwPageFrame *pTmp = new SwPageFrame( pDoc->GetEmptyPageFormat(), pRoot, pDesc );
1181  SAL_INFO( "sw.pageframe", "CheckPageDescs phys: " << pPage->GetPhyPageNum()
1182  << " c: 3 - insert empty p: " << pTmp << " d: " << pDesc );
1183  pTmp->Paste( pRoot, pPage );
1184  pTmp->PreparePage( false );
1185  pPage = pTmp;
1186  isPageFrameEmpty = false; // don't delete it right away!
1187  }
1188  else if ( pPage->GetPageDesc() != pDesc ) //4.
1189  {
1190  SwPageDesc *pOld = pPage->GetPageDesc();
1191  pPage->SetPageDesc( pDesc, pFormatWish );
1192  SAL_INFO( "sw.pageframe", "CheckPageDescs phys: " << pPage->GetPhyPageNum()
1193  << " c: 4 - set desc + format p: " << pPage
1194  << " d: " << pDesc << " f: " << pFormatWish );
1195  if ( bFootnotes )
1196  {
1197  // If specific values of the FootnoteInfo are changed, something has to happen.
1198  // We try to limit the damage...
1199  // If the page has no FootnoteCont it might be problematic.
1200  // Let's hope that invalidation is enough.
1201  SwFootnoteContFrame *pCont = pPage->FindFootnoteCont();
1202  if ( pCont && !(pOld->GetFootnoteInfo() == pDesc->GetFootnoteInfo()) )
1203  pCont->InvalidateAll_();
1204  }
1205  }
1206  else if ( pFormatWish && pPage->GetFormat() != pFormatWish ) //5.
1207  {
1208  pPage->SetFrameFormat( pFormatWish );
1209  SAL_INFO( "sw.pageframe", "CheckPageDescs phys: " << pPage->GetPhyPageNum()
1210  << " c: 5 - set format p: " << pPage << " f: " << pFormatWish );
1211  }
1212  else if ( !pFormatWish ) //6.
1213  {
1214  // get format with inverted logic
1215  pFormatWish = bWantOdd ? pDesc->GetLeftFormat() : pDesc->GetRightFormat();
1216  if ( pFormatWish && pPage->GetFormat() != pFormatWish )
1217  {
1218  pPage->SetFrameFormat( pFormatWish );
1219  SAL_INFO( "sw.pageframe", "CheckPageDescs phys: " << pPage->GetPhyPageNum()
1220  << " c: 6 - set format p: " << pPage << " f: " << pFormatWish );
1221  }
1222  }
1223 #if OSL_DEBUG_LEVEL > 0
1224  else
1225  {
1226  OSL_FAIL( "CheckPageDescs, missing solution" );
1227  }
1228 #endif
1229  }
1230  assert(!bIsEmpty || !isPageFrameEmpty);
1231  const bool bWantRemovePage = bIsEmpty || isPageFrameEmpty;
1232  if (bWantRemovePage && !pPage->IsDeleteForbidden())
1233  {
1234  // It also might be that an empty page is not needed at all.
1235  // However, the algorithm above cannot determine that. It is not needed if the following
1236  // page can live without it. Do obtain that information, we need to dig deeper...
1237  SwPageFrame *pPg = static_cast<SwPageFrame*>(pPage->GetNext());
1238  if (isPageFrameEmpty || !pPg || pPage->OnRightPage() == pPg->WannaRightPage())
1239  {
1240  // The following page can find a FrameFormat or has no successor -> empty page not needed
1241  SwPageFrame *pTmp = static_cast<SwPageFrame*>(pPage->GetNext());
1242  if (isPageFrameEmpty && pPage->GetPrev())
1243  { // check previous *again* vs. its new next! see "ooo321_stylepagenumber.odt"
1244  pTmp = static_cast<SwPageFrame*>(pPage->GetPrev());
1245  }
1246  pPage->Cut();
1247  bool bUpdatePrev = false;
1248  if (ppPrev && *ppPrev == pPage)
1249  bUpdatePrev = true;
1250  SwFrame::DestroyFrame(pPage);
1251  SAL_INFO( "sw.pageframe", "CheckPageDescs - handle bIsEmpty - destroy p: " << pPage );
1252  if ( pStart == pPage )
1253  pStart = pTmp;
1254  pPage = pTmp;
1255  if (bUpdatePrev)
1256  *ppPrev = pTmp;
1257  continue;
1258  }
1259  }
1260  pPage = static_cast<SwPageFrame*>(pPage->GetNext());
1261  }
1262 
1263  pRoot->SetAssertFlyPages();
1264  SwRootFrame::AssertPageFlys( pStart );
1265 
1266  if ( bNotifyFields && (!pImp || !pImp->IsUpdateExpFields()) )
1267  {
1268  SwDocPosUpdate aMsgHint( nDocPos );
1269  pDoc->getIDocumentFieldsAccess().UpdatePageFields( &aMsgHint );
1270  }
1271 
1272 #if OSL_DEBUG_LEVEL > 0
1273  //1. check if two empty pages are behind one another
1274  bool bEmpty = false;
1275  SwPageFrame *pPg = pStart;
1276  while ( pPg )
1277  {
1278  if ( pPg->IsEmptyPage() )
1279  {
1280  if ( bEmpty )
1281  {
1282  OSL_FAIL( "double empty pages." );
1283  break; // once is enough
1284  }
1285  bEmpty = true;
1286  }
1287  else
1288  bEmpty = false;
1289 
1290  pPg = static_cast<SwPageFrame*>(pPg->GetNext());
1291  }
1292 #endif
1293  SAL_INFO( "sw.pageframe", "CheckPageDescs out)" );
1294 }
1295 
1296 namespace
1297 {
1298  bool isDeleteForbidden(const SwPageFrame *pDel)
1299  {
1300  if (pDel->IsDeleteForbidden())
1301  return true;
1302  const SwLayoutFrame* pBody = pDel->FindBodyCont();
1303  const SwFrame* pBodyContent = pBody ? pBody->Lower() : nullptr;
1304  return pBodyContent && pBodyContent->IsDeleteForbidden();
1305  }
1306 
1307  bool doInsertPage( SwRootFrame *pRoot, SwPageFrame **pRefSibling,
1308  SwFrameFormat *pFormat, SwPageDesc *pDesc,
1309  bool bFootnote, SwPageFrame **pRefPage )
1310  {
1311  SwPageFrame *pPage = new SwPageFrame(pFormat, pRoot, pDesc);
1312  SwPageFrame *pSibling = *pRefSibling;
1313  if ( pRefPage )
1314  {
1315  *pRefPage = pPage;
1316  SAL_INFO( "sw.pageframe", "doInsertPage p: " << pPage
1317  << " d: " << pDesc << " f: " << pFormat );
1318  }
1319  else
1320  SAL_INFO( "sw.pageframe", "doInsertPage - insert empty p: "
1321  << pPage << " d: " << pDesc );
1322  pPage->Paste( pRoot, pSibling );
1323 
1324  SwViewShell* pViewShell = pRoot->GetCurrShell();
1325  if (pViewShell && pViewShell->GetViewOptions()->IsHideWhitespaceMode())
1326  {
1327  // Hide-whitespace mode does not shrink the last page, so resize the page that used to
1328  // be the last one.
1329  if (SwFrame* pPrevPage = pPage->GetPrev())
1330  {
1331  pPrevPage->InvalidateSize();
1332  }
1333  }
1334 
1335  pPage->PreparePage( bFootnote );
1336  // If the sibling has no body text, destroy it as long as it is no footnote page.
1337  if ( pSibling && !pSibling->IsFootnotePage() &&
1338  !pSibling->FindFirstBodyContent() &&
1339  (!pRefPage || !isDeleteForbidden(pSibling)) )
1340  {
1341  pRoot->RemovePage( pRefSibling, SwRemoveResult::Next ) ;
1342  return false;
1343  }
1344  return true;
1345  }
1346 }
1347 
1348 SwPageFrame *SwFrame::InsertPage( SwPageFrame *pPrevPage, bool bFootnote )
1349 {
1350  SwRootFrame *pRoot = static_cast<SwRootFrame*>(pPrevPage->GetUpper());
1351  SwPageFrame *pSibling = static_cast<SwPageFrame*>(pPrevPage->GetNext());
1352  SwPageDesc *pDesc = nullptr;
1353 
1354  // insert right (odd) or left (even) page?
1355  bool bNextRightPage = !pPrevPage->OnRightPage();
1356  bool bWishedRightPage = bNextRightPage;
1357 
1358  // Which PageDesc is relevant?
1359  // For ContentFrame take the one from format if provided,
1360  // otherwise from the Follow of the PrevPage
1361  if ( IsFlowFrame() && !SwFlowFrame::CastFlowFrame( this )->IsFollow() )
1362  {
1363  SwFormatPageDesc &rDesc = const_cast<SwFormatPageDesc&>(GetPageDescItem());
1364  pDesc = rDesc.GetPageDesc();
1365  if ( rDesc.GetNumOffset() )
1366  {
1367  ::std::optional<sal_uInt16> oNumOffset = rDesc.GetNumOffset();
1368  bWishedRightPage = sw::IsRightPageByNumber(*pRoot, *oNumOffset);
1369  // use the opportunity to set the flag at root
1370  pRoot->SetVirtPageNum( true );
1371  }
1372  }
1373  if ( !pDesc )
1374  pDesc = pPrevPage->GetPageDesc()->GetFollow();
1375 
1376  assert(pDesc && "Missing PageDesc");
1377  if( !(bWishedRightPage ? pDesc->GetRightFormat() : pDesc->GetLeftFormat()) )
1378  bWishedRightPage = !bWishedRightPage;
1379  bool const bWishedFirst = pDesc != pPrevPage->GetPageDesc();
1380 
1381  SwDoc *pDoc = pPrevPage->GetFormat()->GetDoc();
1382  bool bCheckPages = false;
1383  // If there is no FrameFormat for this page, create an empty page.
1384  if (bWishedRightPage != bNextRightPage)
1385  {
1386  if( doInsertPage( pRoot, &pSibling, pDoc->GetEmptyPageFormat(),
1387  pPrevPage->GetPageDesc(), bFootnote, nullptr ) )
1388  bCheckPages = true;
1389  }
1390  SwFrameFormat *const pFormat( bWishedRightPage
1391  ? pDesc->GetRightFormat(bWishedFirst)
1392  : pDesc->GetLeftFormat(bWishedFirst) );
1393  assert(pFormat);
1394  SwPageFrame *pPage = nullptr;
1395  if( doInsertPage( pRoot, &pSibling, pFormat, pDesc, bFootnote, &pPage ) )
1396  bCheckPages = true;
1397 
1398  if ( pSibling )
1399  {
1400  if ( bCheckPages )
1401  {
1402  CheckPageDescs( pSibling, false );
1404  SwViewShellImp *pImp = pSh ? pSh->Imp() : nullptr;
1405  if ( pImp && pImp->IsAction() && !pImp->GetLayAction().IsCheckPages() )
1406  {
1407  const sal_uInt16 nNum = pImp->GetLayAction().GetCheckPageNum();
1408  if ( nNum == pPrevPage->GetPhyPageNum() + 1 )
1409  {
1411  pSibling->GetPhyPageNum() );
1412  SAL_INFO( "sw.pageframe", "InsertPage - SetCheckPageNumDirect: "
1413  << pSibling->GetPhyPageNum() );
1414  }
1415  return pPage;
1416  }
1417  }
1418  else
1419  SwRootFrame::AssertPageFlys( pSibling );
1420  }
1421 
1422  // For the update of page numbering fields, nDocPos provides
1423  // the page position from where invalidation should start.
1425  if ( !pSh || !pSh->Imp()->IsUpdateExpFields() )
1426  {
1427  SwDocPosUpdate aMsgHint( pPrevPage->getFrameArea().Top() );
1428  pDoc->getIDocumentFieldsAccess().UpdatePageFields( &aMsgHint );
1429  }
1430  return pPage;
1431 }
1432 
1434 {
1436  if( !pSh || pSh->GetViewOptions()->getBrowseMode() )
1437  {
1439  }
1440  else
1441  {
1442  const bool bLTR = getRootFrame()->IsLeftToRightViewLayout();
1443  const bool bBookMode = pSh->GetViewOptions()->IsViewLayoutBookMode();
1444  const bool bRightSidebar = bLTR ? (!bBookMode || OnRightPage()) : (bBookMode && !OnRightPage());
1445 
1446  return bRightSidebar
1449  }
1450 }
1451 
1452 SwTwips SwRootFrame::GrowFrame( SwTwips nDist, bool bTst, bool )
1453 {
1454  if ( !bTst )
1455  {
1457  aFrm.AddHeight(nDist );
1458  }
1459 
1460  return nDist;
1461 }
1462 
1463 SwTwips SwRootFrame::ShrinkFrame( SwTwips nDist, bool bTst, bool )
1464 {
1465  OSL_ENSURE( nDist >= 0, "nDist < 0." );
1466  OSL_ENSURE( nDist <= getFrameArea().Height(), "nDist greater than current size." );
1467 
1468  if ( !bTst )
1469  {
1471  aFrm.AddHeight( -nDist );
1472  }
1473 
1474  return nDist;
1475 }
1476 
1478 {
1479  SwPageFrame *pDel = *pDelRef;
1480  (*pDelRef) = static_cast<SwPageFrame*>(
1481  eResult == SwRemoveResult::Next ? pDel->GetNext() : pDel->GetPrev() );
1482  if ( !GetFormat()->GetDoc()->GetFootnoteIdxs().empty() )
1483  RemoveFootnotes( pDel, true );
1484  pDel->Cut();
1485  SwFrame::DestroyFrame( pDel );
1486 }
1487 
1490 {
1491  // A page is empty if the body text area has no ContentFrame, but not if there
1492  // is at least one Fly or one footnote attached to the page. Two runs are
1493  // needed: one for endnote pages and one for the pages of the body text.
1494 
1495  if ( !IsSuperfluous() )
1496  return;
1497  mbCheckSuperfluous = false;
1498 
1499  SwPageFrame *pPage = GetLastPage();
1500  tools::Long nDocPos = LONG_MAX;
1501 
1502  // Check the corresponding last page if it is empty and stop loop at the last non-empty page.
1503  do
1504  {
1505  if (!sw::IsPageFrameEmpty(*pPage))
1506  {
1507  if ( pPage->IsFootnotePage() )
1508  {
1509  while ( pPage->IsFootnotePage() )
1510  {
1511  pPage = static_cast<SwPageFrame*>(pPage->GetPrev());
1512  OSL_ENSURE( pPage, "only endnote pages remain." );
1513  }
1514  continue;
1515  }
1516  else
1517  pPage = nullptr;
1518  }
1519 
1520  if ( pPage )
1521  {
1522  SAL_INFO( "sw.pageframe", "RemoveSuperfluous - DestroyFrm p: " << pPage );
1523  RemovePage( &pPage, SwRemoveResult::Prev );
1524  nDocPos = pPage ? pPage->getFrameArea().Top() : 0;
1525  }
1526  } while ( pPage );
1527 
1529  if ( nDocPos != LONG_MAX &&
1530  (!pSh || !pSh->Imp()->IsUpdateExpFields()) )
1531  {
1532  SwDocPosUpdate aMsgHint( nDocPos );
1534  }
1535 }
1536 
1539 {
1540  if ( !IsAssertFlyPages() )
1541  return;
1542  mbAssertFlyPages = false;
1543 
1544  SwDoc *pDoc = GetFormat()->GetDoc();
1545  const SwFrameFormats *pTable = pDoc->GetSpzFrameFormats();
1546 
1547  // what page targets the "last" Fly?
1548  // note the needed pages in a set
1549  sal_uInt16 nMaxPg(0);
1551  neededPages.reserve(pTable->size());
1552 
1553  for ( size_t i = 0; i < pTable->size(); ++i )
1554  {
1555  const SwFormatAnchor &rAnch = (*pTable)[i]->GetAnchor();
1556  if(!rAnch.GetContentAnchor())
1557  {
1558  const sal_uInt16 nPageNum(rAnch.GetPageNum());
1559 
1560  // calc MaxPage (as before)
1561  nMaxPg = std::max(nMaxPg, nPageNum);
1562 
1563  // note as needed page
1564  neededPages.insert(nPageNum);
1565  }
1566  }
1567 
1568  // How many pages exist at the moment?
1569  // And are there EmptyPages that are needed?
1570  SwPageFrame* pPage(static_cast<SwPageFrame*>(Lower()));
1571  SwPageFrame* pPrevPage(nullptr);
1572  SwPageFrame* pFirstRevivedEmptyPage(nullptr);
1573 
1574  while(pPage) // moved two while-conditions to break-statements (see below)
1575  {
1576  const sal_uInt16 nPageNum(pPage->GetPhyPageNum());
1577 
1578  if(pPage->IsEmptyPage() &&
1579  nullptr != pPrevPage &&
1580  neededPages.find(nPageNum) != neededPages.end())
1581  {
1582  // This is an empty page, but it *is* needed since a SwFrame
1583  // is anchored at it directly. Initially these SwFrames are
1584  // not fully initialized. Need to change the format of this SwFrame
1585  // and let the ::Notify mechanism newly evaluate
1586  // m_bEmptyPage (see SwPageFrame::UpdateAttr_). Code is taken and
1587  // adapted from ::InsertPage (used below), this needs previous page
1588  bool bWishedRightPage(!pPrevPage->OnRightPage());
1589  SwPageDesc* pDesc(pPrevPage->GetPageDesc()->GetFollow());
1590  assert(pDesc && "Missing PageDesc");
1591 
1592  if (!(bWishedRightPage ? pDesc->GetRightFormat() : pDesc->GetLeftFormat()))
1593  {
1594  bWishedRightPage = !bWishedRightPage;
1595  }
1596 
1597  bool const bWishedFirst(pDesc != pPrevPage->GetPageDesc());
1598  SwFrameFormat* pFormat(bWishedRightPage ? pDesc->GetRightFormat(bWishedFirst) : pDesc->GetLeftFormat(bWishedFirst));
1599 
1600  // set SwFrameFormat, this will trigger SwPageFrame::UpdateAttr_ and re-evaluate
1601  // m_bEmptyPage, too
1602  pPage->SetFrameFormat(pFormat);
1603 
1604  if(nullptr == pFirstRevivedEmptyPage)
1605  {
1606  // remember first (lowest) SwPageFrame which needed correction
1607  pFirstRevivedEmptyPage = pPage;
1608  }
1609  }
1610 
1611  // original while-condition II
1612  if(nullptr == pPage->GetNext())
1613  {
1614  break;
1615  }
1616 
1617  // original while-condition III
1618  if(static_cast< SwPageFrame* >(pPage->GetNext())->IsFootnotePage())
1619  {
1620  break;
1621  }
1622 
1623  pPrevPage = pPage;
1624  pPage = static_cast<SwPageFrame*>(pPage->GetNext());
1625  }
1626 
1627  if ( nMaxPg > pPage->GetPhyPageNum() )
1628  {
1629  for ( sal_uInt16 i = pPage->GetPhyPageNum(); i < nMaxPg; ++i )
1630  pPage = InsertPage( pPage, false );
1631 
1632  // If the endnote pages are now corrupt, destroy them.
1633  if ( !pDoc->GetFootnoteIdxs().empty() )
1634  {
1635  pPage = static_cast<SwPageFrame*>(Lower());
1636  while ( pPage && !pPage->IsFootnotePage() )
1637  pPage = static_cast<SwPageFrame*>(pPage->GetNext());
1638 
1639  if ( pPage )
1640  {
1641  SwPageDesc *pTmpDesc = pPage->FindPageDesc();
1642  bool isRightPage = pPage->OnRightPage();
1643  if ( pPage->GetFormat() !=
1644  (isRightPage ? pTmpDesc->GetRightFormat() : pTmpDesc->GetLeftFormat()) )
1645  RemoveFootnotes( pPage, false, true );
1646  }
1647  }
1648  }
1649 
1650  // if we corrected SwFrameFormat and changed one (or more) m_bEmptyPage
1651  // flags, we need to correct evtl. currently wrong positioned SwFrame(s)
1652  // which did think until now that these Page(s) are empty.
1653  // After trying to correct myself I found SwRootFrame::AssertPageFlys
1654  // directly below that already does that, so use it.
1655  if(nullptr != pFirstRevivedEmptyPage)
1656  {
1657  AssertPageFlys(pFirstRevivedEmptyPage);
1658  }
1659 
1660 #if OSL_DEBUG_LEVEL > 0
1661  pPage = static_cast<SwPageFrame*>(Lower());
1662  while ( pPage && pPage->GetNext() &&
1663  !static_cast<SwPageFrame*>(pPage->GetNext())->IsFootnotePage() )
1664  {
1665  SAL_INFO( "sw.pageframe", "AssertFlyPages p: " << pPage << " d: " << pPage->GetPageDesc()
1666  << " f: " << pPage->GetFormat() << " virt: " << pPage->GetVirtPageNum()
1667  << " phys: " << pPage->GetPhyPageNum() << " empty: " << pPage->IsEmptyPage() );
1668  pPage = static_cast<SwPageFrame*>(pPage->GetNext());
1669  }
1670  SAL_INFO( "sw.pageframe", "AssertFlyPages p: " << pPage << " d: " << pPage->GetPageDesc()
1671  << " f: " << pPage->GetFormat() << " virt: " << pPage->GetVirtPageNum()
1672  << " phys: " << pPage->GetPhyPageNum() << " empty: " << pPage->IsEmptyPage() );
1673 #endif
1674 }
1675 
1678 {
1679  SAL_INFO( "sw.pageframe", "(AssertPageFlys in" );
1680  while ( pPage )
1681  {
1682  if (pPage->GetSortedObjs())
1683  {
1684  size_t i = 0;
1685  while ( pPage->GetSortedObjs() && i< pPage->GetSortedObjs()->size() )
1686  {
1687  // #i28701#
1688  SwFrameFormat& rFormat = (*pPage->GetSortedObjs())[i]->GetFrameFormat();
1689  const SwFormatAnchor &rAnch = rFormat.GetAnchor();
1690  const sal_uInt16 nPg = rAnch.GetPageNum();
1691  if ((rAnch.GetAnchorId() == RndStdIds::FLY_AT_PAGE) &&
1692  nPg != pPage->GetPhyPageNum() )
1693  {
1694  SAL_INFO( "sw.pageframe", nPg << " " << pPage->GetPhyPageNum() );
1695  // If on the wrong page, check if previous page is empty
1696  if( nPg && !(pPage->GetPhyPageNum()-1 == nPg &&
1697  static_cast<SwPageFrame*>(pPage->GetPrev())->IsEmptyPage()) )
1698  {
1699  // It can move by itself. Just send a modify to its anchor attribute.
1700 #if OSL_DEBUG_LEVEL > 1
1701  const size_t nCnt = pPage->GetSortedObjs()->size();
1702  rFormat.NotifyClients( nullptr, &rAnch );
1703  OSL_ENSURE( !pPage->GetSortedObjs() ||
1704  nCnt != pPage->GetSortedObjs()->size(),
1705  "Object couldn't be reattached!" );
1706 #else
1707  rFormat.NotifyClients( nullptr, &rAnch );
1708 #endif
1709  // Do not increment index, in this case
1710  continue;
1711  }
1712  }
1713  ++i;
1714  }
1715  }
1716  pPage = static_cast<SwPageFrame*>(pPage->GetNext());
1717  }
1718  SAL_INFO( "sw.pageframe", "AssertPageFlys out)" );
1719 }
1720 
1721 Size SwRootFrame::ChgSize( const Size& aNewSize )
1722 {
1723  {
1725  aFrm.SSize(aNewSize);
1726  }
1727 
1728  InvalidatePrt_();
1729  mbFixSize = false;
1730  return getFrameArea().SSize();
1731 }
1732 
1733 void SwRootFrame::MakeAll(vcl::RenderContext* /*pRenderContext*/)
1734 {
1735  if ( !isFrameAreaPositionValid() )
1736  {
1739  aFrm.Pos().setX(DOCUMENTBORDER);
1740  aFrm.Pos().setY(DOCUMENTBORDER);
1741  }
1742 
1743  if ( !isFramePrintAreaValid() )
1744  {
1745  setFramePrintAreaValid(true);
1747  aPrt.Pos().setX(0);
1748  aPrt.Pos().setY(0);
1749  aPrt.SSize( getFrameArea().SSize() );
1750  }
1751 
1752  if ( !isFrameAreaSizeValid() )
1753  {
1754  // SSize is set by the pages (Cut/Paste).
1755  setFrameAreaSizeValid(true);
1756  }
1757 }
1758 
1760 {
1761  mbBrowseWidthValid = false;
1762  SwFrame *pPg = Lower();
1763  while ( pPg )
1764  {
1765  pPg->InvalidateSize();
1766  pPg = pPg->GetNext();
1767  }
1768 }
1769 
1771 {
1772  OSL_ENSURE( GetCurrShell() && GetCurrShell()->GetViewOptions()->getBrowseMode(),
1773  "CalcBrowseWidth and not in BrowseView" );
1774 
1775  // The (minimal) with is determined from borders, tables and paint objects.
1776  // It is calculated based on the attributes. Thus, it is not relevant how wide they are
1777  // currently but only how wide they want to be.
1778  // Frames and paint objects inside other objects (frames, tables) do not count.
1779  // Borders and columns are not taken into account.
1780 
1781  SwFrame *pFrame = ContainsContent();
1782  while ( pFrame && !pFrame->IsInDocBody() )
1783  pFrame = static_cast<SwContentFrame*>(pFrame)->GetNextContentFrame();
1784  if ( !pFrame )
1785  return;
1786 
1787  mbBrowseWidthValid = true;
1789  mnBrowseWidth = (!comphelper::LibreOfficeKit::isActive() && pSh)? MINLAY + 2 * pSh->GetOut()-> PixelToLogic( pSh->GetBrowseBorder() ).Width(): MIN_BROWSE_WIDTH;
1790 
1791  do
1792  {
1793  if ( pFrame->IsInTab() )
1794  pFrame = pFrame->FindTabFrame();
1795 
1796  if ( pFrame->IsTabFrame() &&
1797  !static_cast<SwLayoutFrame*>(pFrame)->GetFormat()->GetFrameSize().GetWidthPercent() )
1798  {
1799  SwBorderAttrAccess aAccess( SwFrame::GetCache(), pFrame );
1800  const SwBorderAttrs &rAttrs = *aAccess.Get();
1801  const SwFormatHoriOrient &rHori = rAttrs.GetAttrSet().GetHoriOrient();
1802  tools::Long nWidth = rAttrs.GetSize().Width();
1803  if ( nWidth < int(USHRT_MAX)-2000 && //-2k, because USHRT_MAX gets missing while trying to resize! (and cast to int to avoid -Wsign-compare due to broken USHRT_MAX on Android)
1804  text::HoriOrientation::FULL != rHori.GetHoriOrient() )
1805  {
1806  const SwHTMLTableLayout *pLayoutInfo =
1807  static_cast<const SwTabFrame *>(pFrame)->GetTable()
1808  ->GetHTMLTableLayout();
1809  if ( pLayoutInfo )
1810  nWidth = std::min( nWidth, pLayoutInfo->GetBrowseWidthMin() );
1811 
1812  switch ( rHori.GetHoriOrient() )
1813  {
1815  // OD 23.01.2003 #106895# - add 1st param to <SwBorderAttrs::CalcRight(..)>
1816  nWidth += rAttrs.CalcLeft( pFrame ) + rAttrs.CalcRight( pFrame );
1817  break;
1818  case text::HoriOrientation::LEFT_AND_WIDTH:
1819  nWidth += rAttrs.CalcLeft( pFrame );
1820  break;
1821  default:
1822  break;
1823  }
1824  mnBrowseWidth = std::max( mnBrowseWidth, nWidth );
1825  }
1826  }
1827  else if ( pFrame->GetDrawObjs() )
1828  {
1829  for ( size_t i = 0; i < pFrame->GetDrawObjs()->size(); ++i )
1830  {
1831  // #i28701#
1832  SwAnchoredObject* pAnchoredObj = (*pFrame->GetDrawObjs())[i];
1833  const SwFrameFormat& rFormat = pAnchoredObj->GetFrameFormat();
1834  const bool bFly = dynamic_cast< const SwFlyFrame *>( pAnchoredObj ) != nullptr;
1835  if ((bFly && (FAR_AWAY == pAnchoredObj->GetObjRect().Width()))
1836  || rFormat.GetFrameSize().GetWidthPercent())
1837  {
1838  continue;
1839  }
1840 
1841  tools::Long nWidth = 0;
1842  switch ( rFormat.GetAnchor().GetAnchorId() )
1843  {
1844  case RndStdIds::FLY_AS_CHAR:
1845  nWidth = bFly ? rFormat.GetFrameSize().GetWidth() :
1846  pAnchoredObj->GetObjRect().Width();
1847  break;
1848  case RndStdIds::FLY_AT_PARA:
1849  {
1850  // #i33170#
1851  // Reactivated old code because
1852  // nWidth = pAnchoredObj->GetObjRect().Right()
1853  // gives wrong results for objects that are still
1854  // at position FAR_AWAY.
1855  if ( bFly )
1856  {
1857  nWidth = rFormat.GetFrameSize().GetWidth();
1858  const SwFormatHoriOrient &rHori = rFormat.GetHoriOrient();
1859  switch ( rHori.GetHoriOrient() )
1860  {
1862  nWidth += rHori.GetPos();
1863  break;
1864  case text::HoriOrientation::INSIDE:
1865  case text::HoriOrientation::LEFT:
1866  if ( text::RelOrientation::PRINT_AREA == rHori.GetRelationOrient() )
1867  nWidth += pFrame->getFramePrintArea().Left();
1868  break;
1869  default:
1870  break;
1871  }
1872  }
1873  else
1874  // Paint objects to not have attributes and
1875  // are defined by their current size
1876  nWidth = pAnchoredObj->GetObjRect().Right() -
1877  pAnchoredObj->GetDrawObj()->GetAnchorPos().X();
1878  }
1879  break;
1880  default: /* do nothing */;
1881  }
1882  mnBrowseWidth = std::max( mnBrowseWidth, nWidth );
1883  }
1884  }
1885  pFrame = pFrame->FindNextCnt();
1886  } while ( pFrame );
1887 }
1888 
1890 {
1891  if ( GetCurrShell() )
1892  for(SwViewShell& rSh : GetCurrShell()->GetRingContainer())
1893  {
1894  if ( auto pCursorShell = dynamic_cast<SwCursorShell*>( &rSh) )
1895  pCursorShell->StartAction();
1896  else
1897  rSh.StartAction();
1898  }
1899 }
1900 
1901 void SwRootFrame::EndAllAction( bool bVirDev )
1902 {
1903  if ( !GetCurrShell() )
1904  return;
1905 
1906  for(SwViewShell& rSh : GetCurrShell()->GetRingContainer())
1907  {
1908  const bool bOldEndActionByVirDev = rSh.IsEndActionByVirDev();
1909  rSh.SetEndActionByVirDev( bVirDev );
1910  if ( auto pCursorShell = dynamic_cast<SwCursorShell*>( &rSh) )
1911  {
1912  pCursorShell->EndAction();
1913  pCursorShell->CallChgLnk();
1914  if ( auto pFEShell = dynamic_cast<SwFEShell*>( &rSh) )
1915  pFEShell->SetChainMarker();
1916  }
1917  else
1918  rSh.EndAction();
1919  rSh.SetEndActionByVirDev( bOldEndActionByVirDev );
1920  }
1921 }
1922 
1924 {
1925  if ( !GetCurrShell() )
1926  return;
1927 
1928  for(SwViewShell& rSh : GetCurrShell()->GetRingContainer())
1929  {
1930  // #i84729#
1931  // No end action, if <SwViewShell> instance is currently in its end action.
1932  // Recursives calls to <::EndAction()> are not allowed.
1933  if ( !rSh.IsInEndAction() )
1934  {
1935  OSL_ENSURE(!rSh.GetRestoreActions(), "Restore action count is already set!");
1936  bool bCursor = dynamic_cast<const SwCursorShell*>( &rSh) != nullptr;
1937  bool bFE = dynamic_cast<const SwFEShell*>( &rSh) != nullptr;
1938  sal_uInt16 nRestore = 0;
1939  while( rSh.ActionCount() )
1940  {
1941  if( bCursor )
1942  {
1943  static_cast<SwCursorShell*>(&rSh)->EndAction();
1944  static_cast<SwCursorShell*>(&rSh)->CallChgLnk();
1945  if ( bFE )
1946  static_cast<SwFEShell*>(&rSh)->SetChainMarker();
1947  }
1948  else
1949  rSh.EndAction();
1950  nRestore++;
1951  }
1952  rSh.SetRestoreActions(nRestore);
1953  }
1954  rSh.LockView(true);
1955  }
1956 }
1957 
1959 {
1960  if ( !GetCurrShell() )
1961  return;
1962 
1963  for(SwViewShell& rSh : GetCurrShell()->GetRingContainer())
1964  {
1965  sal_uInt16 nActions = rSh.GetRestoreActions();
1966  while( nActions-- )
1967  {
1968  if ( auto pCursorShell = dynamic_cast<SwCursorShell*>( &rSh) )
1969  pCursorShell->StartAction();
1970  else
1971  rSh.StartAction();
1972  }
1973  rSh.SetRestoreActions(0);
1974  rSh.LockView(false);
1975  }
1976 }
1977 
1978 // Helper functions for SwRootFrame::CheckViewLayout
1979 static void lcl_MoveAllLowers( SwFrame* pFrame, const Point& rOffset );
1980 
1981 static void lcl_MoveAllLowerObjs( SwFrame* pFrame, const Point& rOffset )
1982 {
1983  const bool bPage = pFrame->IsPageFrame();
1984  const SwSortedObjs* pSortedObj = bPage
1985  ? static_cast<SwPageFrame*>(pFrame)->GetSortedObjs()
1986  : pFrame->GetDrawObjs();
1987  if (pSortedObj == nullptr)
1988  return;
1989 
1990  // note: pSortedObj elements may be removed and inserted from
1991  // MoveObjectIfActive(), invalidating iterators
1992  // DO NOT CONVERT THIS TO A C++11 FOR LOOP, IT DID NOT WORK THE LAST 2 TIMES
1993  for (size_t i = 0; i < pSortedObj->size(); ++i)
1994  {
1995  SwAnchoredObject *const pAnchoredObj = (*pSortedObj)[i];
1996  const SwFrameFormat& rObjFormat = pAnchoredObj->GetFrameFormat();
1997  const SwFormatAnchor& rAnchor = rObjFormat.GetAnchor();
1998 
1999  // all except from the as character anchored objects are moved
2000  // when processing the page frame:
2001  if ( !bPage && (rAnchor.GetAnchorId() != RndStdIds::FLY_AS_CHAR) )
2002  continue;
2003 
2004  SwObjPositioningInProgress aPosInProgress( *pAnchoredObj );
2005 
2006  if ( auto pFlyFrame = dynamic_cast<SwFlyFrame *>( pAnchoredObj ) )
2007  {
2008  lcl_MoveAllLowers( pFlyFrame, rOffset );
2009  pFlyFrame->NotifyDrawObj();
2010  // --> let the active embedded object be moved
2011  SwFrame* pLower = pFlyFrame->Lower();
2012  if ( pLower && pLower->IsNoTextFrame() )
2013  {
2014  SwRootFrame* pRoot = pLower->getRootFrame();
2015  SwViewShell *pSh = pRoot ? pRoot->GetCurrShell() : nullptr;
2016  if ( pSh )
2017  {
2018  SwNoTextFrame *const pContentFrame = static_cast<SwNoTextFrame*>(pLower);
2019  SwOLENode* pNode = pContentFrame->GetNode()->GetOLENode();
2020  if ( pNode )
2021  {
2022  svt::EmbeddedObjectRef& xObj = pNode->GetOLEObj().GetObject();
2023  if ( xObj.is() )
2024  {
2025  for(SwViewShell& rSh : pSh->GetRingContainer())
2026  {
2027  SwFEShell* pFEShell = dynamic_cast< SwFEShell* >( &rSh );
2028  if ( pFEShell )
2029  pFEShell->MoveObjectIfActive( xObj, rOffset );
2030  }
2031  }
2032  }
2033  }
2034  }
2035  }
2036  else if ( auto pAnchoredDrawObj = dynamic_cast<SwAnchoredDrawObject *>( pAnchoredObj ) )
2037  {
2038  // don't touch objects that are not yet positioned:
2039  if ( pAnchoredDrawObj->NotYetPositioned() )
2040  continue;
2041 
2042  const Point& aCurrAnchorPos = pAnchoredDrawObj->GetDrawObj()->GetAnchorPos();
2043  const Point aNewAnchorPos( aCurrAnchorPos + rOffset );
2044  pAnchoredDrawObj->DrawObj()->SetAnchorPos( aNewAnchorPos );
2045  pAnchoredDrawObj->SetLastObjRect( pAnchoredDrawObj->GetObjRect().SVRect() );
2046 
2047  // clear contour cache
2048  if ( pAnchoredDrawObj->GetFrameFormat().GetSurround().IsContour() )
2049  ClrContourCache( pAnchoredDrawObj->GetDrawObj() );
2050  }
2051  // #i92511#
2052  // cache for object rectangle inclusive spaces has to be invalidated.
2053  pAnchoredObj->InvalidateObjRectWithSpaces();
2054  }
2055 }
2056 
2057 static void lcl_MoveAllLowers( SwFrame* pFrame, const Point& rOffset )
2058 {
2059  const SwRect aFrame( pFrame->getFrameArea() );
2060 
2061  // first move the current frame
2062  // RotateFlyFrame3: moved to transform_translate instead of
2063  // direct modification to allow the SwFrame evtl. needed own reactions
2064  pFrame->transform_translate(rOffset);
2065 
2066  // Don't forget accessibility:
2067  if( pFrame->IsAccessibleFrame() )
2068  {
2069  SwRootFrame *pRootFrame = pFrame->getRootFrame();
2070  if( pRootFrame && pRootFrame->IsAnyShellAccessible() &&
2071  pRootFrame->GetCurrShell() )
2072  {
2073  pRootFrame->GetCurrShell()->Imp()->MoveAccessibleFrame( pFrame, aFrame );
2074  }
2075  }
2076 
2077  // the move any objects
2078  lcl_MoveAllLowerObjs( pFrame, rOffset );
2079 
2080  // finally, for layout frames we have to call this function recursively:
2081  if ( dynamic_cast< const SwLayoutFrame *>( pFrame ) != nullptr )
2082  {
2083  SwFrame* pLowerFrame = pFrame->GetLower();
2084  while ( pLowerFrame )
2085  {
2086  lcl_MoveAllLowers( pLowerFrame, rOffset );
2087  pLowerFrame = pLowerFrame->GetNext();
2088  }
2089  }
2090 }
2091 
2092 // Calculate how the pages have to be positioned
2093 void SwRootFrame::CheckViewLayout( const SwViewOption* pViewOpt, const SwRect* pVisArea )
2094 {
2095  SwViewShell* pSh = GetCurrShell();
2096  vcl::RenderContext* pRenderContext = pSh ? pSh->GetOut() : nullptr;
2097  // #i91432#
2098  // No calculation of page positions, if only an empty page is present.
2099  // This situation occurs when <SwRootFrame> instance is in construction
2100  // and the document contains only left pages.
2101  if ( Lower()->GetNext() == nullptr &&
2102  static_cast<SwPageFrame*>(Lower())->IsEmptyPage() )
2103  {
2104  return;
2105  }
2106 
2107  if ( !pVisArea )
2108  {
2109  // no early return for bNewPage
2110  if ( mnViewWidth < 0 )
2111  mnViewWidth = 0;
2112  }
2113  else
2114  {
2115  assert(pViewOpt && "CheckViewLayout required ViewOptions");
2116 
2117  const sal_uInt16 nColumns = pViewOpt->GetViewLayoutColumns();
2118  const bool bBookMode = pViewOpt->IsViewLayoutBookMode();
2119 
2120  if ( nColumns == mnColumns && bBookMode == mbBookMode && pVisArea->Width() == mnViewWidth && !mbSidebarChanged )
2121  return;
2122 
2123  mnColumns = nColumns;
2124  mbBookMode = bBookMode;
2125  mnViewWidth = pVisArea->Width();
2126  mbSidebarChanged = false;
2127  }
2128 
2129  if( GetFormat()->getIDocumentSettingAccess().get(DocumentSettingId::BROWSE_MODE ) )
2130  {
2131  mnColumns = 1;
2132  mbBookMode = false;
2133  }
2134 
2135  Calc(pRenderContext);
2136 
2137  const bool bOldCallbackActionEnabled = IsCallbackActionEnabled();
2138  SetCallbackActionEnabled( false );
2139 
2140  maPageRects.clear();
2141 
2142  const tools::Long nBorder = getFrameArea().Pos().getX();
2143  const tools::Long nVisWidth = mnViewWidth - 2 * nBorder;
2144  const tools::Long nGapBetweenPages = pViewOpt ? pViewOpt->GetGapBetweenPages()
2145  : (pSh ? pSh->GetViewOptions()->GetGapBetweenPages()
2147 
2148  // check how many pages fit into the first page layout row:
2149  SwPageFrame* pPageFrame = static_cast<SwPageFrame*>(Lower());
2150 
2151  // will contain the number of pages per row. 0 means that
2152  // the page does not fit.
2153  tools::Long nWidthRemain = nVisWidth;
2154 
2155  // after one row has been processed, these variables contain
2156  // the width of the row and the maximum of the page heights
2157  tools::Long nCurrentRowHeight = 0;
2158  tools::Long nCurrentRowWidth = 0;
2159 
2160  // these variables are used to finally set the size of the
2161  // root frame
2162  tools::Long nSumRowHeight = 0;
2163  SwTwips nMinPageLeft = TWIPS_MAX;
2164  SwTwips nMaxPageRight = 0;
2165  SwPageFrame* pStartOfRow = pPageFrame;
2166  sal_uInt16 nNumberOfPagesInRow = mbBookMode ? 1 : 0; // in book view, start with right page
2167  bool bFirstRow = true;
2168 
2169  bool bPageChanged = false;
2170  const bool bRTL = !IsLeftToRightViewLayout();
2171  const SwTwips nSidebarWidth = SwPageFrame::GetSidebarBorderWidth( pSh );
2172 
2173  while ( pPageFrame )
2174  {
2175  // we consider the current page to be "start of row" if
2176  // 1. it is the first page in the current row or
2177  // 2. it is the second page in the row and the first page is an empty page in non-book view:
2178  const bool bStartOfRow = pPageFrame == pStartOfRow ||
2179  ( pStartOfRow->IsEmptyPage() && pPageFrame == pStartOfRow->GetNext() && !mbBookMode );
2180 
2181  const bool bEmptyPage = pPageFrame->IsEmptyPage() && !mbBookMode;
2182 
2183  // no half doc border space for first page in each row and
2184  tools::Long nPageWidth = 0;
2185  tools::Long nPageHeight = 0;
2186 
2187  if ( mbBookMode )
2188  {
2189  const SwFrame& rFormatPage = pPageFrame->GetFormatPage();
2190 
2191  nPageWidth = rFormatPage.getFrameArea().Width() + nSidebarWidth + ((bStartOfRow || 1 == (pPageFrame->GetPhyPageNum()%2)) ? 0 : nGapBetweenPages);
2192  nPageHeight = rFormatPage.getFrameArea().Height() + nGapBetweenPages;
2193  }
2194  else
2195  {
2196  if ( !pPageFrame->IsEmptyPage() )
2197  {
2198  nPageWidth = pPageFrame->getFrameArea().Width() + nSidebarWidth + (bStartOfRow ? 0 : nGapBetweenPages);
2199  nPageHeight = pPageFrame->getFrameArea().Height() + nGapBetweenPages;
2200  }
2201  }
2202 
2203  if ( !bEmptyPage )
2204  ++nNumberOfPagesInRow;
2205 
2206  // finish current row if
2207  // 1. in dynamic mode the current page does not fit anymore or
2208  // 2. the current page exceeds the maximum number of columns
2209  bool bRowFinished = (0 == mnColumns && nWidthRemain < nPageWidth ) ||
2210  (0 != mnColumns && mnColumns < nNumberOfPagesInRow);
2211 
2212  // make sure that at least one page goes to the current row:
2213  if ( !bRowFinished || bStartOfRow )
2214  {
2215  // current page is allowed to be in current row
2216  nWidthRemain = nWidthRemain - nPageWidth;
2217 
2218  nCurrentRowWidth = nCurrentRowWidth + nPageWidth;
2219  nCurrentRowHeight = std::max( nCurrentRowHeight, nPageHeight );
2220 
2221  pPageFrame = static_cast<SwPageFrame*>(pPageFrame->GetNext());
2222 
2223  if ( !pPageFrame )
2224  bRowFinished = true;
2225  }
2226 
2227  if ( bRowFinished )
2228  {
2229  // pPageFrame now points to the first page in the new row or null
2230  // pStartOfRow points to the first page in the current row
2231 
2232  // special centering for last row. pretend to fill the last row with virtual copies of the last page before centering:
2233  if ( !pPageFrame && nWidthRemain > 0 )
2234  {
2235  // find last page in current row:
2236  const SwPageFrame* pLastPageInCurrentRow = pStartOfRow;
2237  while( pLastPageInCurrentRow->GetNext() )
2238  pLastPageInCurrentRow = static_cast<const SwPageFrame*>(pLastPageInCurrentRow->GetNext());
2239 
2240  if ( pLastPageInCurrentRow->IsEmptyPage() )
2241  pLastPageInCurrentRow = static_cast<const SwPageFrame*>(pLastPageInCurrentRow->GetPrev());
2242 
2243  // check how many times the last page would still fit into the remaining space:
2244  sal_uInt16 nNumberOfVirtualPages = 0;
2245  const sal_uInt16 nMaxNumberOfVirtualPages = mnColumns > 0 ? mnColumns - nNumberOfPagesInRow : USHRT_MAX;
2246  SwTwips nRemain = nWidthRemain;
2247  SwTwips nVirtualPagesWidth = 0;
2248  SwTwips nLastPageWidth = pLastPageInCurrentRow->getFrameArea().Width() + nSidebarWidth;
2249 
2250  while ( ( mnColumns > 0 || nRemain > 0 ) && nNumberOfVirtualPages < nMaxNumberOfVirtualPages )
2251  {
2252  SwTwips nLastPageWidthWithGap = nLastPageWidth;
2253  if ( !mbBookMode || ( 0 == (nNumberOfVirtualPages + nNumberOfPagesInRow) %2) )
2254  nLastPageWidthWithGap += nGapBetweenPages;
2255 
2256  if ( mnColumns > 0 || nLastPageWidthWithGap < nRemain )
2257  {
2258  ++nNumberOfVirtualPages;
2259  nVirtualPagesWidth += nLastPageWidthWithGap;
2260  }
2261  nRemain = nRemain - nLastPageWidthWithGap;
2262  }
2263 
2264  nCurrentRowWidth = nCurrentRowWidth + nVirtualPagesWidth;
2265  }
2266 
2267  // first page in book mode is always special:
2268  if ( bFirstRow && mbBookMode )
2269  {
2270  // #i88036#
2271  nCurrentRowWidth +=
2272  pStartOfRow->GetFormatPage().getFrameArea().Width() + nSidebarWidth;
2273  }
2274 
2275  // center page if possible
2276  tools::Long nSizeDiff = 0;
2277  if (nVisWidth > nCurrentRowWidth && !comphelper::LibreOfficeKit::isActive())
2278  nSizeDiff = ( nVisWidth - nCurrentRowWidth ) / 2;
2279 
2280  // adjust positions of pages in current row
2281  tools::Long nX = nSizeDiff;
2282 
2283  const tools::Long nRowStart = nBorder + nSizeDiff;
2284  const tools::Long nRowEnd = nRowStart + nCurrentRowWidth;
2285 
2286  if ( bFirstRow && mbBookMode )
2287  {
2288  // #i88036#
2289  nX += pStartOfRow->GetFormatPage().getFrameArea().Width() + nSidebarWidth;
2290  }
2291 
2292  SwPageFrame* pEndOfRow = pPageFrame;
2293  SwPageFrame* pPageToAdjust = pStartOfRow;
2294 
2295  do
2296  {
2297  const SwPageFrame* pFormatPage = pPageToAdjust;
2298  if ( mbBookMode )
2299  pFormatPage = &pPageToAdjust->GetFormatPage();
2300 
2301  const SwTwips nCurrentPageWidth = pFormatPage->getFrameArea().Width() + (pFormatPage->IsEmptyPage() ? 0 : nSidebarWidth);
2302  const Point aOldPagePos = pPageToAdjust->getFrameArea().Pos();
2303  const bool bLeftSidebar = pPageToAdjust->SidebarPosition() == sw::sidebarwindows::SidebarPosition::LEFT;
2304  const SwTwips nLeftPageAddOffset = bLeftSidebar ?
2305  nSidebarWidth :
2306  0;
2307 
2308  Point aNewPagePos( nBorder + nX, nBorder + nSumRowHeight );
2309  Point aNewPagePosWithLeftOffset( nBorder + nX + nLeftPageAddOffset, nBorder + nSumRowHeight );
2310 
2311  // RTL view layout: Calculate mirrored page position
2312  if ( bRTL )
2313  {
2314  const tools::Long nXOffsetInRow = aNewPagePos.getX() - nRowStart;
2315  aNewPagePos.setX(nRowEnd - nXOffsetInRow - nCurrentPageWidth);
2316  aNewPagePosWithLeftOffset = aNewPagePos;
2317  aNewPagePosWithLeftOffset.setX(aNewPagePosWithLeftOffset.getX() + nLeftPageAddOffset);
2318  }
2319 
2320  if ( aNewPagePosWithLeftOffset != aOldPagePos )
2321  {
2322  lcl_MoveAllLowers( pPageToAdjust, aNewPagePosWithLeftOffset - aOldPagePos );
2323  pPageToAdjust->SetCompletePaint();
2324  bPageChanged = true;
2325  }
2326 
2327  // calculate area covered by the current page and store to
2328  // maPageRects. This is used e.g., for cursor setting
2329  const bool bFirstColumn = pPageToAdjust == pStartOfRow;
2330  const bool bLastColumn = pPageToAdjust->GetNext() == pEndOfRow;
2331  const bool bLastRow = !pEndOfRow;
2332 
2333  nMinPageLeft = std::min( nMinPageLeft, SwTwips(aNewPagePos.getX()) );
2334  nMaxPageRight = std::max( nMaxPageRight, SwTwips(aNewPagePos.getX() + nCurrentPageWidth));
2335 
2336  // border of nGapBetweenPages around the current page:
2337  SwRect aPageRectWithBorders( aNewPagePos.getX() - nGapBetweenPages,
2338  aNewPagePos.getY(),
2339  pPageToAdjust->getFrameArea().SSize().Width() + nGapBetweenPages + nSidebarWidth,
2340  nCurrentRowHeight );
2341 
2342  static const tools::Long nOuterClickDiff = 1000000;
2343 
2344  // adjust borders for these special cases:
2345  if ( (bFirstColumn && !bRTL) || (bLastColumn && bRTL) )
2346  aPageRectWithBorders.SubLeft( nOuterClickDiff );
2347  if ( (bLastColumn && !bRTL) || (bFirstColumn && bRTL) )
2348  aPageRectWithBorders.AddRight( nOuterClickDiff );
2349  if ( bFirstRow )
2350  aPageRectWithBorders.SubTop( nOuterClickDiff );
2351  if ( bLastRow )
2352  aPageRectWithBorders.AddBottom( nOuterClickDiff );
2353 
2354  maPageRects.push_back( aPageRectWithBorders );
2355 
2356  nX = nX + nCurrentPageWidth;
2357  pPageToAdjust = static_cast<SwPageFrame*>(pPageToAdjust->GetNext());
2358 
2359  // distance to next page
2360  if ( pPageToAdjust && pPageToAdjust != pEndOfRow )
2361  {
2362  // in book view, we add the x gap before left (even) pages:
2363  if ( mbBookMode )
2364  {
2365  if ( 0 == (pPageToAdjust->GetPhyPageNum()%2) )
2366  nX = nX + nGapBetweenPages;
2367  }
2368  else
2369  {
2370  // in non-book view, don't add x gap before
2371  // 1. the last empty page in a row
2372  // 2. after an empty page
2373  const bool bDontAddGap = ( pPageToAdjust->IsEmptyPage() && pPageToAdjust->GetNext() == pEndOfRow ) ||
2374  ( static_cast<SwPageFrame*>(pPageToAdjust->GetPrev())->IsEmptyPage() );
2375 
2376  if ( !bDontAddGap )
2377  nX = nX + nGapBetweenPages;
2378  }
2379  }
2380  }
2381  while (pPageToAdjust && pPageToAdjust != pEndOfRow);
2382 
2383  // adjust values for root frame size
2384  nSumRowHeight = nSumRowHeight + nCurrentRowHeight;
2385 
2386  // start new row:
2387  nCurrentRowHeight = 0;
2388  nCurrentRowWidth = 0;
2389  pStartOfRow = pEndOfRow;
2390  nWidthRemain = nVisWidth;
2391  nNumberOfPagesInRow = 0;
2392  bFirstRow = false;
2393  } // end row finished
2394  } // end while
2395 
2396  // set size of root frame:
2397  const Size aOldSize( getFrameArea().SSize() );
2398  const Size aNewSize( nMaxPageRight - nBorder, nSumRowHeight - nGapBetweenPages );
2399 
2400  if ( bPageChanged || aNewSize != aOldSize )
2401  {
2402  ChgSize( aNewSize );
2403  ::AdjustSizeChgNotify( this );
2404  Calc(pRenderContext);
2405 
2406  if ( pSh && pSh->GetDoc()->GetDocShell() )
2407  {
2408  pSh->SetFirstVisPageInvalid();
2409  if (bOldCallbackActionEnabled)
2410  {
2412  pSh->GetDoc()->GetDocShell()->Broadcast(SfxHint(SfxHintId::DocChanged));
2413  }
2414  }
2415  }
2416 
2418  maPagesArea.SSize( aNewSize );
2419  if ( TWIPS_MAX != nMinPageLeft )
2420  maPagesArea.Left_( nMinPageLeft );
2421 
2422  SetCallbackActionEnabled( bOldCallbackActionEnabled );
2423 }
2424 
2426 {
2427  // Layout direction determined by layout direction of the first page.
2428  // #i88036#
2429  // Only ask a non-empty page frame for its layout direction
2430  assert(dynamic_cast<const SwPageFrame *>(Lower()) != nullptr);
2431  const SwPageFrame& rPage = static_cast<const SwPageFrame&>(*Lower()).GetFormatPage();
2432  return !rPage.IsRightToLeft() && !rPage.IsVertical();
2433 }
2434 
2436 {
2437  const SwPageFrame* pRet = this;
2438  if ( IsEmptyPage() )
2439  {
2440  pRet = static_cast<const SwPageFrame*>( OnRightPage() ? GetNext() : GetPrev() );
2441  // #i88035#
2442  // Typically a right empty page frame has a next non-empty page frame and
2443  // a left empty page frame has a previous non-empty page frame.
2444  // But under certain circumstances this assumption is not true -
2445  // e.g. during insertion of a left page at the end of the document right
2446  // after a left page in an intermediate state a right empty page does not
2447  // have a next page frame.
2448  if ( pRet == nullptr )
2449  {
2450  if ( OnRightPage() )
2451  {
2452  pRet = static_cast<const SwPageFrame*>( GetPrev() );
2453  }
2454  else
2455  {
2456  pRet = static_cast<const SwPageFrame*>( GetNext() );
2457  }
2458  }
2459  assert(pRet &&
2460  "<SwPageFrame::GetFormatPage()> - inconsistent layout: empty page without previous and next page frame --> crash.");
2461  }
2462  return *pRet;
2463 }
2464 
2465 bool SwPageFrame::IsOverHeaderFooterArea( const Point& rPt, FrameControlType &rControl ) const
2466 {
2467  tools::Long nUpperLimit = 0;
2468  tools::Long nLowerLimit = 0;
2469  const SwFrame* pFrame = Lower();
2470  while ( pFrame )
2471  {
2472  if ( pFrame->IsBodyFrame() )
2473  {
2474  nUpperLimit = pFrame->getFrameArea().Top();
2475  nLowerLimit = pFrame->getFrameArea().Bottom();
2476  }
2477  else if ( pFrame->IsFootnoteContFrame() )
2478  nLowerLimit = pFrame->getFrameArea().Bottom();
2479 
2480  pFrame = pFrame->GetNext();
2481  }
2482 
2483  SwRect aHeaderArea( getFrameArea().TopLeft(),
2484  Size( getFrameArea().Width(), nUpperLimit - getFrameArea().Top() ) );
2485 
2486  SwViewShell* pViewShell = getRootFrame()->GetCurrShell();
2487  const bool bHideWhitespaceMode = pViewShell->GetViewOptions()->IsHideWhitespaceMode();
2488  if ( aHeaderArea.IsInside( rPt ) )
2489  {
2490  if (!bHideWhitespaceMode || static_cast<const SwFrameFormat*>(GetDep())->GetHeader().IsActive())
2491  {
2492  rControl = FrameControlType::Header;
2493  return true;
2494  }
2495  }
2496  else
2497  {
2498  SwRect aFooterArea( Point( getFrameArea().Left(), nLowerLimit ),
2499  Size( getFrameArea().Width(), getFrameArea().Bottom() - nLowerLimit ) );
2500 
2501  if ( aFooterArea.IsInside( rPt ) &&
2502  (!bHideWhitespaceMode || static_cast<const SwFrameFormat*>(GetDep())->GetFooter().IsActive()) )
2503  {
2504  rControl = FrameControlType::Footer;
2505  return true;
2506  }
2507  }
2508 
2509  return false;
2510 }
2511 
2513 {
2514  SwViewShell* pShell = getRootFrame()->GetCurrShell();
2515  if (pShell && pShell->GetViewOptions()->IsWhitespaceHidden())
2516  {
2517  // When whitespace is hidden, the page frame has two heights: the
2518  // nominal (defined by the frame format), and the actual (which is
2519  // at most the nominal height, but can be smaller in case there is
2520  // no content for the whole page).
2521  // The layout size is the actual one, but we want to move the
2522  // content frame to a new page only in case it doesn't fit the
2523  // nominal size.
2524  if (nDiff < 0)
2525  {
2526  // Content frame doesn't fit the actual size, check if it fits the nominal one.
2527  const SwFrameFormat* pPageFormat = static_cast<const SwFrameFormat*>(GetDep());
2528  const Size& rPageSize = pPageFormat->GetFrameSize().GetSize();
2529  tools::Long nWhitespace = rPageSize.getHeight() - getFrameArea().Height();
2530  if (nWhitespace > -nDiff)
2531  {
2532  // It does: don't move it and invalidate our page frame so
2533  // that it gets a larger height.
2534  return false;
2535  }
2536  }
2537  }
2538 
2539  return true;
2540 }
2541 
2543 {
2544  const SwFrame* pLowerFrame = Lower();
2545  while (pLowerFrame)
2546  {
2547  if (pLowerFrame->IsHeaderFrame())
2548  return dynamic_cast<const SwHeaderFrame*>(pLowerFrame);
2549  pLowerFrame = pLowerFrame->GetNext();
2550  }
2551  return nullptr;
2552 }
2553 
2555 {
2556  const SwFrame* pLowerFrame = Lower();
2557  while (pLowerFrame)
2558  {
2559  if (pLowerFrame->IsFooterFrame())
2560  return dynamic_cast<const SwFooterFrame*>(pLowerFrame);
2561  pLowerFrame = pLowerFrame->GetNext();
2562  }
2563  return nullptr;
2564 }
2565 
2566 SwTextGridItem const* GetGridItem(SwPageFrame const*const pPage)
2567 {
2568  if (pPage && pPage->HasGrid())
2569  {
2570  SwTextGridItem const& rGridItem(
2571  pPage->GetPageDesc()->GetMaster().GetTextGrid());
2572  if (GRID_NONE != rGridItem.GetGridType())
2573  {
2574  return &rGridItem;
2575  }
2576  }
2577  return nullptr;
2578 }
2579 
2580 sal_uInt16 GetGridWidth(SwTextGridItem const& rG, SwDoc const& rDoc)
2581 {
2582  return (rDoc.IsSquaredPageMode()) ? rG.GetBaseHeight() : rG.GetBaseWidth();
2583 }
2584 
2585 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void InsertBefore(SwLayoutFrame *pParent, SwFrame *pBehind)
Insert SwFrame into existing structure.
Definition: wsfrm.cxx:822
static SwTwips GetSidebarBorderWidth(const SwViewShell *)
Definition: paintfrm.cxx:6125
bool IsAnLower(const SwFrame *) const
Definition: findfrm.cxx:207
vcl::RenderContext * GetOut() const
Definition: viewsh.hxx:338
void SetPageDesc(SwPageDesc *, SwFrameFormat *)
Definition: pagechg.cxx:728
SwFrame * FindFooterOrHeader()
Definition: findfrm.cxx:548
Base class of the Writer layout elements.
Definition: frame.hxx:298
Base class that provides the general functionalities for frames that are allowed at page breaks (flow...
Definition: flowfrm.hxx:58
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:151
constexpr TypedWhichId< SvxFrameDirectionItem > RES_FRAMEDIR(120)
tools::Long GetWidth() const
const ::std::optional< sal_uInt16 > & GetNumOffset() const
Definition: fmtpdsc.hxx:65
virtual SwRect GetObjRect() const =0
bool IsOverHeaderFooterArea(const Point &rPt, FrameControlType &rControl) const
If in header or footer area, it also indicates the exact area in rControl.
Definition: pagechg.cxx:2465
void Right(const tools::Long nRight)
Definition: swrect.hxx:200
void SetFootnotePage(bool b)
Definition: pagefrm.hxx:188
bool IsFollow() const
Definition: flowfrm.hxx:166
const SwSortedObjs * GetDrawObjs() const
Definition: frame.hxx:548
void SetCallbackActionEnabled(bool b)
Definition: rootfrm.hxx:385
const SwFormatCol & GetCol(bool=true) const
Definition: fmtclds.hxx:168
bool m_bHasGrid
Definition: pagefrm.hxx:64
SwPageDesc * FindPageDesc()
Definition: pagechg.cxx:744
SwContentFrame * GetNextContentFrame() const
Definition: cntfrm.hxx:98
bool IsInDocBody() const
Definition: frame.hxx:924
Header in the document layout, inside a page.
Definition: hffrm.hxx:43
bool IsRootFrame() const
Definition: frame.hxx:1155
Pagedescriptor Client of SwPageDesc that is "described" by the attribute.
Definition: fmtpdsc.hxx:35
void SetPosY(SwRect &rRect, tools::Long nNew) const
Definition: frame.hxx:1382
tools::Long mnBrowseWidth
For BrowseMode mnBrowseWidth is the outer margin of the object most to the right. ...
Definition: rootfrm.hxx:130
const SwTextGridItem & GetTextGrid(bool=true) const
Definition: tgrditem.hxx:112
void RemoveFootnotes(SwPageFrame *pPage=nullptr, bool bPageOnly=false, bool bEndNotes=false)
Remove all footnotes (but no references)
Definition: ftnfrm.cxx:960
SwOLENode * GetOLENode()
Inline methods from Node.hxx.
Definition: ndole.hxx:161
bool IsAnyShellAccessible() const
Definition: rootfrm.hxx:388
SwPageDesc * GetPageDesc()
Definition: fmtpdsc.hxx:62
const SwOLEObj & GetOLEObj() const
Definition: ndole.hxx:112
SwViewShellImp * Imp()
Definition: viewsh.hxx:182
bool mbInvalidVert
Definition: frame.hxx:404
void DisconnectFromLayout(bool _bMoveMasterToInvisibleLayer=true)
Definition: dcontact.cxx:1622
virtual void Format(vcl::RenderContext *pRenderContext, const SwBorderAttrs *pAttrs=nullptr) override
"Formats" the Frame; Frame and PrtArea.
Definition: pagechg.cxx:73
void Left_(const tools::Long nLeft)
Definition: swrect.cxx:148
static void CheckPageDescs(SwPageFrame *pStart, bool bNotifyFields=true, SwPageFrame **ppPrev=nullptr)
Check all pages (starting from the given one) if they use the appropriate frame format.
Definition: pagechg.cxx:1053
const SwFormatHeader & GetHeader(bool=true) const
Definition: fmthdft.hxx:97
sal_uInt16 GetBaseWidth() const
Definition: tgrditem.hxx:97
SwDocShell * GetDocShell()
Definition: doc.hxx:1350
constexpr TypedWhichId< SwFormatHeader > RES_HEADER(96)
constexpr TypedWhichId< SwFormatCol > RES_COL(109)
void SubLeft(const tools::Long nSub)
Definition: swrect.cxx:163
bool mbBrowseWidthValid
Definition: rootfrm.hxx:114
virtual void UpdatePageFields(SfxPoolItem *)=0
void Left(const tools::Long nLeft)
Definition: swrect.hxx:195
virtual void MoveObjectIfActive(svt::EmbeddedObjectRef &xObj, const Point &rOffset)
The layout has been changed, so the active object has to be moved after that.
Definition: fews.cxx:1313
constexpr TypedWhichId< SwFormatFrameSize > RES_FRM_SIZE(89)
void SetCompletePaint() const
Definition: frame.hxx:975
virtual bool Prepare(const PrepareHint ePrep=PrepareHint::Clear, const void *pVoid=nullptr, bool bNotify=true)
Definition: wsfrm.cxx:589
sal_uInt16 char char * pDesc
virtual void DestroyImpl() override
Definition: pagechg.cxx:255
SwFrameType GetType() const
Definition: frame.hxx:503
sal_uInt16 GetPageNum() const
Definition: fmtanchr.hxx:66
bool m_bInvalidFlyLayout
Definition: pagefrm.hxx:55
void SetDerivedR2L(bool bNew)
Definition: frame.hxx:615
SwTwips GetPos() const
Definition: fmtornt.hxx:92
long Long
const SwRect & getFramePrintArea() const
Definition: frame.hxx:179
bool mbSidebarChanged
Definition: rootfrm.hxx:101
#define MINLAY
Definition: swtypes.hxx:66
static SwCache & GetCache()
Definition: frame.hxx:505
SwTabFrame is one table in the document layout, containing rows (which contain cells).
Definition: tabfrm.hxx:30
tools::Long CalcRight(const SwFrame *pCaller) const
Definition: frmtool.cxx:2217
virtual void Modify(const SfxPoolItem *, const SfxPoolItem *) override
Definition: wsfrm.cxx:476
void InvalidateSize_()
Definition: frame.hxx:754
Definition: doc.hxx:186
void SetColMaxFootnoteHeight()
Adapt the max. footnote height in each single column.
Definition: ftnfrm.cxx:2634
void SetMaxFootnoteHeight(const SwTwips nNewMax)
Definition: ftnboss.hxx:77
bool IsLeftToRightViewLayout() const
Definition: pagechg.cxx:2425
void InvalidatePos()
Definition: frame.hxx:1024
const SwPageFrame & GetFormatPage() const
Definition: pagechg.cxx:2435
bool mbAssertFlyPages
Definition: rootfrm.hxx:116
const_iterator find(const Value &x) const
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:1433
virtual void Paste(SwFrame *pParent, SwFrame *pSibling=nullptr) override
Definition: wsfrm.cxx:1320
#define TWIPS_MAX
Definition: swtypes.hxx:53
SwTextGridItem const * GetGridItem(SwPageFrame const *const pPage)
Definition: pagechg.cxx:2566
SwEditWin & GetEditWin()
Definition: view.hxx:402
SvxFrameDirection
static void DestroyFrame(SwFrame *const pFrame)
this is the only way to delete a SwFrame instance
Definition: ssfrm.cxx:383
void Pos(const Point &rNew)
Definition: swrect.hxx:169
Dialog to specify the properties of date form field.
SwTwips GetMaxFootnoteHeight() const
Definition: ftnboss.hxx:96
Helper class for notify that positioning of an anchored object is in progress.
virtual void Calc(vcl::RenderContext *pRenderContext) const
Definition: trvlfrm.cxx:1787
virtual void SwClientNotify(const SwModify &, const SfxHint &rHint) override
Definition: calbck.cxx:111
bool IsFootnotePage() const
Foot note interface.
Definition: pagefrm.hxx:186
virtual Size ChgSize(const Size &aNewSize) override
Definition: pagechg.cxx:1721
Of course Writer needs its own rectangles.
Definition: swrect.hxx:35
void AssertFlyPages()
Ensures that enough pages exist, so that all page bound frames and draw objects can be placed...
Definition: pagechg.cxx:1538
SwContentFrame * FindFirstBodyContent()
Definition: pagefrm.hxx:337
virtual const SwFormatPageDesc & GetPageDescItem() const
Definition: findfrm.cxx:660
tools::Long GetWidth(const SwRect &rRect) const
Definition: frame.hxx:1362
void PrepareRegisterChg()
Definition: pagechg.cxx:961
static SwFlowFrame * CastFlowFrame(SwFrame *pFrame)
Definition: flowfrm.cxx:2647
bool mbVertLR
Definition: frame.hxx:408
The root element of a Writer document layout.
Definition: rootfrm.hxx:82
SwContact * GetUserCall(const SdrObject *pObj)
Returns the UserCall if applicable from the group object.
Definition: dcontact.cxx:171
bool m_bInvalidLayout
Definition: pagefrm.hxx:53
virtual SwTwips ShrinkFrame(SwTwips, bool bTst=false, bool bInfo=false) override
Definition: pagechg.cxx:1463
const SwFrameFormats * GetSpzFrameFormats() const
Definition: doc.hxx:741
void RemoveControls(const SwFrame *pFrame)
static bool bFootnote
Definition: insfnote.cxx:33
bool m_bInvalidWordCount
Definition: pagefrm.hxx:63
void CheckDirChange()
checks the layout direction and invalidates the lower frames recursively, if necessary.
Definition: ssfrm.cxx:191
IDocumentDrawModelAccess const & getIDocumentDrawModelAccess() const
Definition: doc.cxx:155
bool IsActive() const
Definition: fmthdft.hxx:89
void CheckViewLayout(const SwViewOption *pViewOpt, const SwRect *pVisArea)
Definition: pagechg.cxx:2093
sal_uInt16 GetPhyPageNum() const
Definition: pagefrm.hxx:191
void CheckGrid(bool bInvalidate)
Definition: pagechg.cxx:304
Used by the UI to modify the document model.
Definition: wrtsh.hxx:90
bool AddPaintRect(const SwRect &rRect)
Definition: viewsh.cxx:525
std::vector< SwRect > maPageRects
Definition: rootfrm.hxx:94
IDocumentFieldsAccess const & getIDocumentFieldsAccess() const
Definition: doc.cxx:357
const SwPageFootnoteInfo & GetFootnoteInfo() const
Definition: pagedesc.hxx:195
bool WannaRightPage() const
Decides if the page want to be a right page or not.
Definition: trvlfrm.cxx:1713
bool HasGrid() const
Definition: pagefrm.hxx:173
const SfxPoolItem * NextItem()
wrapper class for the positioning of Writer fly frames and drawing objects
void SetFirstVisPageInvalid()
Definition: viewimp.hxx:146
virtual bool IsVisibleLayerId(SdrLayerID _nLayerId) const =0
method to determine, if a layer ID belongs to the visible ones.
const SwView & GetView() const
Definition: wrtsh.hxx:428
void AppendFly(SwFlyFrame *pNew)
Definition: fly.cxx:2166
SwFrameControlsManager & GetFrameControlsManager()
Definition: edtwin.cxx:6666
void UnoRestoreAllActions()
Definition: pagechg.cxx:1958
const SwFrame * GetAnchorFrame(const SdrObject *_pDrawObj=nullptr) const
Definition: dcontact.cxx:783
const SwRect & getFrameArea() const
Definition: frame.hxx:178
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
SwFootnoteContFrame * FindFootnoteCont()
Definition: ftnfrm.cxx:1024
bool getBrowseMode() const
Definition: viewopt.hxx:458
virtual Size ChgSize(const Size &aNewSize)
Definition: wsfrm.cxx:723
bool IsEmptyPage() const
Definition: pagefrm.hxx:144
bool IsInTab() const
Definition: frame.hxx:936
sal_uInt16 GetCheckPageNum() const
Definition: layact.hxx:167
svt::EmbeddedObjectRef & GetObject()
Definition: ndole.cxx:966
const SwPageFrame * GetLastPage() const
Definition: rootfrm.hxx:361
Footer, for pageformats Client of FrameFormat describing the footer.
Definition: fmthdft.hxx:64
bool mbCheckSuperfluous
Definition: rootfrm.hxx:112
virtual ~SwPageFrame() override
Definition: pagechg.cxx:300
void reserve(size_type amount)
sal_uInt16 m_nPhyPageNum
Physical page number: index into list of SwRootFrame lowers.
Definition: pagefrm.hxx:50
constexpr TypedWhichId< SwAttrSetChg > RES_ATTRSET_CHG(161)
constexpr TypedWhichId< SwFormatChg > RES_FMT_CHG(160)
void Width(tools::Long nNew)
Definition: swrect.hxx:187
void setFramePrintAreaValid(bool bNew)
Definition: wsfrm.cxx:99
bool m_bInvalidSpelling
Definition: pagefrm.hxx:60
bool OnRightPage() const
Definition: frame.hxx:716
SwTwips GetHeight() const
Definition: pagedesc.hxx:61
sal_uInt16 GetGridWidth(SwTextGridItem const &rG, SwDoc const &rDoc)
Definition: pagechg.cxx:2580
SwDoc * GetDoc() const
Definition: viewsh.hxx:281
virtual void DestroyImpl() override
Definition: ssfrm.cxx:480
void CheckWaitCursor()
If an Action is running we ask it to check whether it's time to enable the WaitCursor.
Definition: viewimp.cxx:139
void PrepareFooter()
Creates or removes footer.
Definition: hffrm.cxx:723
void AdjustSizeChgNotify(SwRootFrame *pRoot)
Definition: pagechg.cxx:811
bool IsFlowFrame() const
Definition: frame.hxx:1223
void InvalidateLayout() const
Definition: pagefrm.hxx:363
SwBodyFrame(SwFrameFormat *, SwFrame *)
Definition: pagechg.cxx:67
SwFrame * AnchorFrame()
static void lcl_PrepFlyInCntRegister(SwContentFrame *pFrame)
Definition: pagechg.cxx:940
Specific frame formats (frames, DrawObjects).
bool IsCheckPages() const
Definition: layact.hxx:163
bool IsAssertFlyPages() const
Definition: rootfrm.hxx:281
Base class for various Writer styles.
Definition: format.hxx:43
sal_uInt16 GetVirtPageNum() const
Definition: trvlfrm.cxx:1805
tools::Long getHeight() const
void ImplInvalidateBrowseWidth()
Definition: pagechg.cxx:1759
void SetDerivedVert(bool bNew)
Definition: frame.hxx:612
Style of a layout element.
Definition: frmfmt.hxx:58
#define SAL_MAX_INT32
void SetCheckPageNumDirect(sal_uInt16 nNew)
Definition: layact.hxx:154
bool CheckPageHeightValidForHideWhitespace(SwTwips nDiff)
Is bottom-of-page-frame - bottom-of-text-frame difference valid in case whitespace is hidden...
Definition: pagechg.cxx:2512
void RemoveFly(SwFlyFrame *pToRemove)
Definition: fly.cxx:2184
const SdrObject * GetDrawObj() const
void InvalidatePrt()
Definition: frame.hxx:1017
const SwSortedObjs * GetSortedObjs() const
Definition: pagefrm.hxx:119
sw::BroadcastingModify * GetDep()
use these so we can grep for SwFrame's GetRegisteredIn accesses beware that SwTextFrame may return sw...
Definition: frame.hxx:460
const SwFormatAnchor & GetAnchor(bool=true) const
Definition: fmtanchr.hxx:81
int i
const SwFooterFrame * GetFooterFrame() const
Definition: pagechg.cxx:2554
void MoveAccessibleFrame(const SwFrame *pFrame, const SwRect &rOldFrame)
Definition: viewimp.hxx:288
const SwRect & VisArea() const
Definition: viewsh.cxx:560
void SetFrameFormat(SwFrameFormat *)
Definition: ssfrm.cxx:404
bool IsViewLayoutBookMode() const
Definition: viewopt.hxx:465
void SetAssertFlyPages()
Makes sure that all requested page-bound Flys find a Page.
Definition: rootfrm.hxx:279
SwFrameType
Definition: frame.hxx:73
void EndAction(const bool bIdleEnd=false, const bool DoSetPosX=false)
Definition: crsrsh.cxx:239
Window class for the Writer edit area, this is the one handling mouse and keyboard events and doing t...
Definition: edtwin.hxx:58
RndStdIds GetAnchorId() const
Definition: fmtanchr.hxx:65
const SwPageDesc & GetPageDesc(const size_t i) const
Definition: doc.hxx:880
void ImplCalcBrowseWidth()
Definition: pagechg.cxx:1770
const SwFormatHoriOrient & GetHoriOrient(bool=true) const
Definition: fmtornt.hxx:108
size_t size() const
Definition: sortedobjs.cxx:42
const SwPosition * GetContentAnchor() const
Definition: fmtanchr.hxx:67
tools::Long CalcLeft(const SwFrame *pCaller) const
Definition: frmtool.cxx:2264
SwPageFrame * FindPageFrame()
Definition: frame.hxx:663
virtual bool IsDeleteForbidden() const
Definition: frame.hxx:868
SwFrameFormat * GetLeftFormat(bool const bFirst=false)
Definition: pagedesc.cxx:361
virtual void Cut() override
Definition: pagechg.cxx:835
const SwFrame * Lower() const
Definition: layfrm.hxx:101
SwContentFrame * FindNextCnt(const bool _bInSameFootnote=false)
Definition: findfrm.cxx:191
TElementType * First()
Definition: calbck.hxx:346
SwPageDesc * GetPageDesc()
Definition: pagefrm.hxx:130
static void lcl_MoveAllLowers(SwFrame *pFrame, const Point &rOffset)
Definition: pagechg.cxx:2057
virtual void CheckDirection(bool bVert) override
Definition: pagechg.cxx:327
void InvalidatePage(const SwPageFrame *pPage=nullptr) const
Invalidates the page in which the Frame is currently placed.
Definition: wsfrm.cxx:599
tools::Long GetHeight(const SwRect &rRect) const
Definition: frame.hxx:1363
FlyAnchors.
Definition: fmtanchr.hxx:34
const SwFormatHoriOrient & GetHoriOrient(bool=true) const
Definition: fmtornt.hxx:103
SwRemoveResult
Definition: rootfrm.hxx:69
void ChgColumns(const SwFormatCol &rOld, const SwFormatCol &rNew, const bool bChgFootnote=false)
add or remove columns from a layoutframe.
Definition: colfrm.cxx:188
const SwFrameFormat * GetEmptyPageFormat() const
Definition: doc.hxx:746
static void lcl_MoveAllLowerObjs(SwFrame *pFrame, const Point &rOffset)
Definition: pagechg.cxx:1981
bool IsAction() const
SS for the Lay-/IdleAction and relatives.
Definition: viewimp.hxx:186
bool mbInvalidR2L
Definition: frame.hxx:401
bool m_bFootnotePage
Definition: pagefrm.hxx:57
SwLayoutFrame * GetUpper()
Definition: frame.hxx:661
bool HasArea() const
Definition: swrect.hxx:288
tools::Long Width() const
virtual void Modify(const SfxPoolItem *, const SfxPoolItem *) override
Definition: pagechg.cxx:498
bool mbVertical
Definition: frame.hxx:406
void AddHeight(const tools::Long nAdd)
Definition: swrect.cxx:161
bool isFramePrintAreaValid() const
Definition: frame.hxx:167
bool IsEndNotePage() const
Definition: pagefrm.hxx:187
const SwFormatFooter & GetFooter(bool=true) const
Definition: fmthdft.hxx:99
sal_Int16 GetHoriOrient() const
Definition: fmtornt.hxx:87
bool m_bInvalidFlyInCnt
Definition: pagefrm.hxx:56
tools::Long mnViewWidth
Definition: rootfrm.hxx:98
SwFrame * GetPrev()
Definition: frame.hxx:660
size
const SwAttrSet & GetAttrSet() const
Definition: frmtool.hxx:383
bool isFrameAreaPositionValid() const
Definition: frame.hxx:165
ring_container GetRingContainer()
Definition: ring.hxx:240
static constexpr sal_uInt16 defGapBetweenPages
Definition: viewopt.hxx:438
const_iterator end() const
void SetPhyPageNum(sal_uInt16 nNum)
Definition: pagefrm.hxx:192
SwPageFrame(SwFrameFormat *, SwFrame *, SwPageDesc *)
Definition: pagechg.cxx:174
void UpdateAttr_(const SfxPoolItem *, const SfxPoolItem *, sal_uInt8 &, SwAttrSetChg *pa=nullptr, SwAttrSetChg *pb=nullptr)
Definition: pagechg.cxx:561
bool IsUpdateExpFields()
Definition: viewimp.cxx:150
bool empty() const
void MoveFly(SwFlyFrame *pToMove, SwPageFrame *pDest)
Definition: flylay.cxx:949
const SwDoc * GetDoc() const
The document is set in SwAttrPool now, therefore you always can access it.
Definition: format.hxx:119
sal_uInt8 GetWidthPercent() const
Definition: fmtfsize.hxx:91
void SSize(const Size &rNew)
Definition: swrect.hxx:178
void PrepareHeader()
Make this public, so that the SwViewShell can access it when switching from browse mode Add/remove he...
Definition: hffrm.cxx:682
tools::Long GetHeight() const
bool isFrameAreaSizeValid() const
Definition: frame.hxx:166
virtual SwTwips GrowFrame(SwTwips, bool bTst=false, bool bInfo=false) override
Definition: pagechg.cxx:1452
void InvalidatePos_()
Definition: frame.hxx:770
SwPageDesc * m_pDesc
Definition: pagefrm.hxx:47
A page of the document layout.
Definition: pagefrm.hxx:41
tools::Long SwTwips
Definition: swtypes.hxx:49
bool IsLeftShadowNeeded() const
Definition: paintfrm.cxx:5700
void InvalidateWindows(const SwRect &rRect)
Definition: viewsh.cxx:541
const long LONG_MAX
sal_uInt16 GetLines() const
Definition: tgrditem.hxx:72
void SetVirtPageNum(const bool bOf) const
Definition: rootfrm.hxx:442
SwBorderAttrs * Get()
Definition: frmtool.cxx:2560
void InvalidateSize()
Definition: frame.hxx:1010
virtual SdrLayerID GetLayer() const
SwLayoutFrame * FindBodyCont()
Searches the first ContentFrame in BodyText below the page.
Definition: findfrm.cxx:43
const SwPageDesc * GetFollow() const
Definition: pagedesc.hxx:245
void NotifyClients(const SfxPoolItem *pOldValue, const SfxPoolItem *pNewValue)
Definition: calbck.cxx:170
bool m_bInvalidContent
Definition: pagefrm.hxx:52
tools::Long const nBorder
virtual bool SetFormatAttr(const SfxPoolItem &rAttr)
Definition: format.cxx:462
bool IsHideWhitespaceMode() const
Definition: viewopt.hxx:469
sal_uInt16 Which() const
for Querying of Writer-functions.
Definition: format.hxx:78
void setFrameAreaPositionValid(bool bNew)
Definition: wsfrm.cxx:83
sal_uInt16 Count() const
Definition: hints.hxx:283
void SetPosX(SwRect &rRect, tools::Long nNew) const
Definition: frame.hxx:1381
FrameControlType
Definition: swtypes.hxx:236
SwFrameFormat & GetMaster()
Definition: pagedesc.hxx:216
void Bottom(const tools::Long nBottom)
Definition: swrect.hxx:209
static constexpr sal_Int64 MIN_BROWSE_WIDTH
Width of the HTML / Web document if not defined otherwise: 20cm.
Definition: rootfrm.hxx:110
const SwContentNode * GetNode() const
Definition: notxtfrm.hxx:67
constexpr TypedWhichId< SwTextGridItem > RES_TEXTGRID(115)
tools::Long GetBrowseWidthMin() const
Definition: htmltbl.hxx:426
void SetWidth(SwRect &rRect, tools::Long nNew) const
Definition: frame.hxx:1371
virtual bool GetInfo(SfxPoolItem &) const override
Get info from Client.
Definition: pagechg.cxx:718
bool IsVertLR() const
Definition: frame.hxx:960
bool IsSquaredPageMode() const
Definition: docdesc.cxx:914
SwPageDesc * GetPageDesc(SwDoc &rDoc) const
Definition: docftn.cxx:105
bool m_bEmptyPage
Definition: pagefrm.hxx:58
SwLayAction & GetLayAction()
Definition: viewimp.hxx:188
bool IsTabFrame() const
Definition: frame.hxx:1199
general base class for all free-flowing frames
Definition: flyfrm.hxx:60
bool IsPageFrameEmpty(SwPageFrame const &rPage)
check if there's content on the page that requires it to exist
Definition: pagechg.cxx:992
bool IsRightPageByNumber(SwRootFrame const &rLayout, sal_uInt16 nPageNum)
Definition: frmtool.cxx:2989
sal_Int16 GetRelationOrient() const
Definition: fmtornt.hxx:88
void RemoveSuperfluous()
remove pages that are not needed at all
Definition: pagechg.cxx:1489
bool mbFixSize
Definition: frame.hxx:412
virtual SwFrameFormat & GetFrameFormat()=0
void SetAgain()
Definition: layact.hxx:150
unsigned char sal_uInt8
void UnoRemoveAllActions()
Certain UNO Actions (e.g.
Definition: pagechg.cxx:1923
void ClrContourCache(const SdrObject *pObj)
Definition: txtfly.cxx:134
const SwViewOption * GetViewOptions() const
Definition: viewsh.hxx:423
vcl::Window * GetWin() const
Definition: viewsh.hxx:337
const o3tl::enumarray< SvxAdjust, unsigned short > aSvxToUnoAdjust USHRT_MAX
Definition: unosett.cxx:254
void InvalidateAll_()
Definition: frame.hxx:786
virtual const SwAnchoredObject * GetAnchoredObj(const SdrObject *_pSdrObj) const override
Definition: dcontact.cxx:741
#define SAL_INFO(area, stream)
bool IsInside(const Point &rPOINT) const
Definition: swrect.cxx:105
SwFrameFormat * GetRightFormat(bool const bFirst=false)
Layout uses the following methods to obtain a format in order to be able to create a page...
Definition: pagedesc.cxx:368
void SetHeight(SwRect &rRect, tools::Long nNew) const
Definition: frame.hxx:1372
bool IsNoTextFrame() const
Definition: frame.hxx:1219
bool m_bInvalidAutoCmplWrds
Definition: pagefrm.hxx:62
void RemoveFromLayout()
Definition: wsfrm.cxx:999
bool mbBookMode
Definition: rootfrm.hxx:100
bool IsRightToLeft() const
Definition: frame.hxx:968
SwRect maPagesArea
Definition: rootfrm.hxx:97
void Top(const tools::Long nTop)
Definition: swrect.hxx:204
void setFrameAreaSizeValid(bool bNew)
Definition: wsfrm.cxx:91
void InvalidateObjRectWithSpaces() const
bool m_bInvalidFlyContent
Definition: pagefrm.hxx:54
SwFrame * GetLower()
Definition: findfrm.cxx:170
SwFrameType mnFrameType
Definition: frame.hxx:398
bool IsPageFrame() const
Definition: frame.hxx:1159
const Size & GetBrowseBorder() const
Definition: viewsh.cxx:1995
const SfxPoolItem & GetFormatAttr(sal_uInt16 nWhich, bool bInParents=true) const
If bInParents is FALSE, search only in this format for attribute.
Definition: format.cxx:381
constexpr TypedWhichId< SwAutoFormatGetDocNode > RES_AUTOFMT_DOCNODE(171)
constexpr TypedWhichId< SwDrawFrameFormat > RES_DRAWFRMFMT(157)
void PreparePage(bool bFootnote)
Always call after Paste Creates the page-bound frames and formats the generic content.
Definition: pagechg.cxx:466
Header, for PageFormats Client of FrameFormat describing the header.
Definition: fmthdft.hxx:33
#define FAR_AWAY
Definition: frmtool.hxx:52
const Point & GetAnchorPos() const
const SwFormatFrameSize & GetFrameSize(bool=true) const
Definition: fmtfsize.hxx:104
const Size & GetSize() const
Definition: frmtool.hxx:400
static void lcl_MakeObjs(const SwFrameFormats &rTable, SwPageFrame *pPage)
Create Flys or register draw objects.
Definition: pagechg.cxx:389
void AppendDrawObj(SwAnchoredObject &_rNewObj)
Definition: fly.cxx:2224
bool OnFirstPage() const
Definition: trvlfrm.cxx:1767
static void AssertPageFlys(SwPageFrame *)
Makes sure that, starting from the passed Page, all page-bound Frames are on the right Page (pagenumb...
Definition: pagechg.cxx:1677
void DelFrameFormat(SwFrameFormat *pFormat, bool bBroadcast=false)
Definition: docfmt.cxx:688
bool mbRightToLeft
Definition: frame.hxx:403
static void lcl_FormatLay(SwLayoutFrame *pLay)
create specific Flys for this page and format generic content
Definition: pagechg.cxx:369
bool IsVertical() const
Definition: frame.hxx:954
sal_uInt16 GetNumCols() const
Definition: fmtclds.hxx:114
bool IsInDtor() const
Definition: doc.hxx:400
SwDocPosUpdate is sent to signal that only the frames from or to a specified document-global position...
Definition: hints.hxx:221
bool IsAccessibleFrame() const
Definition: frame.hxx:1231
constexpr TypedWhichId< SwFormatFooter > RES_FOOTER(97)
void InvalidatePrt_()
Definition: frame.hxx:762
SwFootnoteIdxs & GetFootnoteIdxs()
Definition: doc.hxx:630
void ClearItem(sal_uInt16 nWhichL)
Definition: hints.cxx:128
void SetLastPage(SwPageFrame *pPage)
Definition: pagechg.cxx:830
size_t size() const
virtual void Paste(SwFrame *pParent, SwFrame *pSibling=nullptr) override
Definition: pagechg.cxx:896
A layout frame is a frame that contains other frames (m_pLower), e.g. SwPageFrame or SwTabFrame...
Definition: layfrm.hxx:35
SwTextGrid GetGridType() const
Definition: tgrditem.hxx:81
Left
void RegistFlys(SwPageFrame *, const SwLayoutFrame *)
Definition: frmtool.cxx:3105
void StartAllAction()
Set up Start-/EndAction for all Shells on an as high as possible (Shell section) level.
Definition: pagechg.cxx:1889
const SwFrame * GetAnchorFrame() const
void SetFirstVisPageInvalid()
Definition: viewsh.cxx:1026
SwPageFrame * InsertPage(SwPageFrame *pSibling, bool bFootnote)
Definition: pagechg.cxx:1348
bool IsActive() const
Definition: fmthdft.hxx:58
std::pair< const_iterator, bool > insert(Value &&x)
sal_uInt16 GetBaseHeight() const
Definition: tgrditem.hxx:75
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:6083
sal_uInt16 mnColumns
Definition: rootfrm.hxx:99
bool IsFootnoteContFrame() const
Definition: frame.hxx:1179
void EndAllAction(bool bVirDev=false)
Definition: pagechg.cxx:1901
friend void AdjustSizeChgNotify(SwRootFrame *pRoot)
Definition: pagechg.cxx:811
#define DOCUMENTBORDER
Definition: swtypes.hxx:82
bool IsWhitespaceHidden() const
Definition: viewopt.hxx:474
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:67
void RemovePage(SwPageFrame **pDel, SwRemoveResult eResult)
Definition: pagechg.cxx:1477
bool IsBodyFrame() const
Definition: frame.hxx:1187
bool m_bInvalidSmartTags
Definition: pagefrm.hxx:61
const SwHeaderFrame * GetHeaderFrame() const
Definition: pagechg.cxx:2542
SwViewShell * GetCurrShell() const
Definition: rootfrm.hxx:208
virtual void MakeAll(vcl::RenderContext *pRenderContext) override
Definition: pagechg.cxx:1733
class for collecting anchored objects
Definition: sortedobjs.hxx:48
void SetCheckPageNum(sal_uInt16 nNew)
Definition: layact.hxx:204
void Height(tools::Long nNew)
Definition: swrect.hxx:191
Container of body content (i.e.
Definition: bodyfrm.hxx:28
bool IsSuperfluous() const
Definition: rootfrm.hxx:301
SdrObject * FindSdrObject()
Definition: frmfmt.hxx:138
Footer in the document layout, inside a page.
Definition: hffrm.hxx:50
sal_uInt16 GetRubyHeight() const
Definition: tgrditem.hxx:78
sal_uInt16 GetViewLayoutColumns() const
Definition: viewopt.hxx:467
bool IsFooterFrame() const
Definition: frame.hxx:1175
const SwFootnoteInfo & GetFootnoteInfo() const
Definition: doc.hxx:626
virtual void SwClientNotify(const SwModify &, const SfxHint &) override
Definition: pagechg.cxx:544
sal_uInt16 Which() const
SwRootFrame * getRootFrame()
Definition: frame.hxx:662
const SwEndNoteInfo & GetEndNoteInfo() const
Definition: doc.hxx:628
virtual void transform_translate(const Point &rOffset)
Definition: wsfrm.cxx:147
bool IsCallbackActionEnabled() const
Definition: rootfrm.hxx:386
std::unique_ptr< SwSortedObjs > m_pSortedObjs
Definition: pagefrm.hxx:45
bool m_bEndNotePage
Definition: pagefrm.hxx:59
const Size & GetSize() const
const SfxPoolItem * GetCurItem() const
sal_uInt16 GetGapBetweenPages() const
Definition: viewopt.hxx:443
bool IsRightShadowNeeded() const
Definition: paintfrm.cxx:5687
bool IsHeaderFrame() const
Definition: frame.hxx:1171
void SetAnchor(const SwPosition *pPos)
Definition: atrfrm.cxx:1517
virtual const SwFrameFormat * GetFormat() const
Definition: ssfrm.cxx:394
SwTabFrame * FindTabFrame()
Definition: frame.hxx:1080
SwFrame * GetNext()
Definition: frame.hxx:659