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