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