LibreOffice Module sw (master)  1
sectfrm.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 <sal/config.h>
21 #include <sal/log.hxx>
22 
23 #include <o3tl/safeint.hxx>
24 #include <osl/diagnose.h>
25 #include <svl/itemiter.hxx>
26 #include <txtftn.hxx>
27 #include <fmtftn.hxx>
28 #include <fmtclbl.hxx>
29 #include <sectfrm.hxx>
30 #include <cellfrm.hxx>
31 #include <section.hxx>
33 #include <rootfrm.hxx>
34 #include <pagefrm.hxx>
35 #include <txtfrm.hxx>
36 #include <fmtclds.hxx>
37 #include <colfrm.hxx>
38 #include <tabfrm.hxx>
39 #include <ftnfrm.hxx>
40 #include <layouter.hxx>
41 #include <dbg_lay.hxx>
42 #include <viewopt.hxx>
43 #include <viewimp.hxx>
44 #include <editeng/brushitem.hxx>
45 #include <fmtftntx.hxx>
46 #include <flyfrm.hxx>
47 #include <sortedobjs.hxx>
48 #include <hints.hxx>
49 #include <frmatr.hxx>
50 #include <frmtool.hxx>
51 
52 namespace
53 {
58 void InvalidateFramePos(SwFrame* pFrame, bool bInCalcContent)
59 {
60  if (bInCalcContent)
61  pFrame->InvalidatePos_();
62  else
63  pFrame->InvalidatePos();
64 }
65 }
66 
68  : SwLayoutFrame( rSect.GetFormat(), pSib )
69  , SwFlowFrame( static_cast<SwFrame&>(*this) )
70  , m_pSection( &rSect )
71  , m_bFootnoteAtEnd(false)
72  , m_bEndnAtEnd(false)
73  , m_bContentLock(false)
74  , m_bOwnFootnoteNum(false)
75  , m_bFootnoteLock(false)
76 {
78 
81 }
82 
84  SwLayoutFrame( rSect.GetFormat(), rSect.getRootFrame() ),
85  SwFlowFrame( static_cast<SwFrame&>(*this) ),
86  m_pSection( rSect.GetSection() ),
87  m_bFootnoteAtEnd( rSect.IsFootnoteAtEnd() ),
88  m_bEndnAtEnd( rSect.IsEndnAtEnd() ),
89  m_bContentLock( false ),
90  m_bOwnFootnoteNum( false ),
91  m_bFootnoteLock( false )
92 {
94 
96 
97  if( bMaster )
98  {
99  SwSectionFrame* pMaster = rSect.IsFollow() ? rSect.FindMaster() : nullptr;
100  if (pMaster)
101  pMaster->SetFollow( this );
102  SetFollow( &rSect );
103  }
104  else
105  {
106  SetFollow( rSect.GetFollow() );
107  rSect.SetFollow( this );
108  if( !GetFollow() )
109  rSect.SimpleFormat();
110  if( !rSect.IsColLocked() )
111  rSect.InvalidateSize();
112  }
113 }
114 
115 // NOTE: call <SwSectionFrame::Init()> directly after creation of a new section
116 // frame and its insert in the layout.
118 {
119  assert(GetUpper() && "SwSectionFrame::Init before insertion?!");
120  SwRectFnSet aRectFnSet(this);
121  tools::Long nWidth = aRectFnSet.GetWidth(GetUpper()->getFramePrintArea());
122 
123  {
125  aRectFnSet.SetWidth( aFrm, nWidth );
126  aRectFnSet.SetHeight( aFrm, 0 );
127  }
128 
129  // #109700# LRSpace for sections
130  const SvxLRSpaceItem& rLRSpace = GetFormat()->GetLRSpace();
131 
132  {
134  aRectFnSet.SetLeft( aPrt, rLRSpace.GetLeft() );
135  aRectFnSet.SetWidth( aPrt, nWidth - rLRSpace.GetLeft() - rLRSpace.GetRight() );
136  aRectFnSet.SetHeight( aPrt, 0 );
137  }
138 
139  const SwFormatCol &rCol = GetFormat()->GetCol();
140  if( ( rCol.GetNumCols() > 1 || IsAnyNoteAtEnd() ) && !IsInFootnote() )
141  {
142  const SwFormatCol *pOld = Lower() ? &rCol : new SwFormatCol;
143  ChgColumns( *pOld, rCol, IsAnyNoteAtEnd() );
144  if( pOld != &rCol )
145  delete pOld;
146  }
147 }
148 
150 {
151  if( GetFormat() && !GetFormat()->GetDoc()->IsInDtor() )
152  {
153  SwRootFrame *pRootFrame = getRootFrame();
154  if( pRootFrame )
155  pRootFrame->RemoveFromList( this );
156  if( IsFollow() )
157  {
158  SwSectionFrame *pMaster = FindMaster();
159  if( pMaster )
160  {
161  PROTOCOL( this, PROT::Section, DbgAction::DelFollow, pMaster )
162  pMaster->SetFollow( GetFollow() );
163  // A Master always grabs the space until the lower edge of his
164  // Upper. If he doesn't have a Follow anymore, he can
165  // release it, which is why the Size of the Master is
166  // invalidated.
167  if( !GetFollow() )
168  pMaster->InvalidateSize();
169  }
170  }
171 #if defined DBG_UTIL
172  else if( HasFollow() )
173  {
175  }
176 #endif
177  }
178 
180 }
181 
183 {
184 }
185 
186 void SwSectionFrame::DelEmpty( bool bRemove )
187 {
188  if( IsColLocked() )
189  {
190  OSL_ENSURE( !bRemove, "Don't delete locked SectionFrames" );
191  return;
192  }
193  SwFrame* pUp = GetUpper();
194  if( pUp )
195  {
196  // #i27138#
197  // notify accessibility paragraphs objects about changed
198  // CONTENT_FLOWS_FROM/_TO relation.
199  // Relation CONTENT_FLOWS_FROM for current next paragraph will change
200  // and relation CONTENT_FLOWS_TO for current previous paragraph will change.
201  {
202  SwViewShell* pViewShell( getRootFrame()->GetCurrShell() );
203  if ( pViewShell && pViewShell->GetLayout() &&
204  pViewShell->GetLayout()->IsAnyShellAccessible() )
205  {
206  auto pNext = FindNextCnt( true );
207  auto pPrev = FindPrevCnt();
209  pNext ? pNext->DynCastTextFrame() : nullptr,
210  pPrev ? pPrev->DynCastTextFrame() : nullptr );
211  }
212  }
213  Cut_( bRemove );
214  }
215  SwSectionFrame *pMaster = IsFollow() ? FindMaster() : nullptr;
216  if (pMaster)
217  {
218  pMaster->SetFollow( GetFollow() );
219  // A Master always grabs the space until the lower edge of his
220  // Upper. If he doesn't have a Follow anymore, he can
221  // release it, which is why the Size of the Master is
222  // invalidated.
223  if( !GetFollow() && !pMaster->IsColLocked() )
224  pMaster->InvalidateSize();
225  }
226  SetFollow(nullptr);
227  if( !pUp )
228  return;
229 
230  {
232  aFrm.Height( 0 );
233  }
234 
235  // If we are destroyed immediately anyway, we don't need
236  // to put us into the list
237  if( bRemove )
238  { // If we already were half dead before this DelEmpty,
239  // we are likely in the list and have to remove us from
240  // it
241  if( !m_pSection && getRootFrame() )
242  getRootFrame()->RemoveFromList( this );
243  }
244  else if( getRootFrame() )
245  {
246  getRootFrame()->InsertEmptySct( this );
247  }
248 
249  m_pSection = nullptr; // like this a reanimation is virtually impossible though
250 }
251 
253 {
254  Cut_( true );
255 }
256 
257 void SwSectionFrame::Cut_( bool bRemove )
258 {
259  OSL_ENSURE( GetUpper(), "Cut without Upper()." );
260 
262 
263  SwPageFrame *pPage = FindPageFrame();
264  InvalidatePage( pPage );
265  SwFrame *pFrame = GetNext();
266  SwFrame* pPrepFrame = nullptr;
267  while( pFrame && pFrame->IsSctFrame() && !static_cast<SwSectionFrame*>(pFrame)->GetSection() )
268  pFrame = pFrame->GetNext();
269  if( pFrame )
270  { // The former successor might have calculated a gap to the predecessor
271  // which is now obsolete since he becomes the first
272  pFrame->InvalidatePrt_();
273  pFrame->InvalidatePos_();
274  if( pFrame->IsSctFrame() )
275  pFrame = static_cast<SwSectionFrame*>(pFrame)->ContainsAny();
276  if ( pFrame && pFrame->IsContentFrame() )
277  {
278  pFrame->InvalidatePage( pPage );
279  if( IsInFootnote() && !GetIndPrev() )
280  pPrepFrame = pFrame;
281  }
282  }
283  else
284  {
286  // Someone has to take over the retouching: predecessor or Upper
287  pFrame = GetPrev();
288  if ( nullptr != pFrame )
289  {
290  pFrame->SetRetouche();
292  if ( pFrame->IsContentFrame() )
293  pFrame->InvalidatePage( pPage );
294  }
295  // If I am (was) the only FlowFrame in my Upper, then he has to take over
296  // the retouching.
297  // Furthermore a blank page could have emerged
298  else
299  { SwRootFrame *pRoot = static_cast<SwRootFrame*>(pPage->GetUpper());
300  pRoot->SetSuperfluous();
302  }
303  }
304  // First remove, then shrink Upper
305  SwLayoutFrame *pUp = GetUpper();
306  if( bRemove )
307  {
309  if( pUp && !pUp->Lower() && pUp->IsFootnoteFrame() && !pUp->IsColLocked() &&
310  pUp->GetUpper() )
311  {
312  pUp->Cut();
314  pUp = nullptr;
315  }
316  }
317  if( pPrepFrame )
319  if ( !pUp )
320  return;
321 
322  SwRectFnSet aRectFnSet(this);
323  SwTwips nFrameHeight = aRectFnSet.GetHeight(getFrameArea());
324  if( nFrameHeight <= 0 )
325  return;
326 
327  if( !bRemove )
328  {
330  aRectFnSet.SetHeight( aFrm, 0 );
331 
333  aRectFnSet.SetHeight( aPrt, 0 );
334  }
335 
336  pUp->Shrink( nFrameHeight );
337 }
338 
339 void SwSectionFrame::Paste( SwFrame* pParent, SwFrame* pSibling )
340 {
341  OSL_ENSURE( pParent, "No parent for Paste()." );
342  OSL_ENSURE( pParent->IsLayoutFrame(), "Parent is ContentFrame." );
343  OSL_ENSURE( pParent != this, "I'm my own parent." );
344  OSL_ENSURE( pSibling != this, "I'm my own neighbour." );
345  OSL_ENSURE( !GetPrev() && !GetUpper(),
346  "I am still registered somewhere." );
347 
349 
350  // Add to the tree
351  SwSectionFrame* pSect = pParent->FindSctFrame();
352  // Assure that parent is not inside a table frame, which is inside the found section frame.
353  if ( pSect )
354  {
355  SwTabFrame* pTableFrame = pParent->FindTabFrame();
356  if ( pTableFrame &&
357  pSect->IsAnLower( pTableFrame ) )
358  {
359  pSect = nullptr;
360  }
361  }
362 
363  SwRectFnSet aRectFnSet(pParent);
364  if( pSect && HasToBreak( pSect ) )
365  {
366  if( pParent->IsColBodyFrame() ) // dealing with a single-column area
367  {
368  // If we are coincidentally at the end of a column, pSibling
369  // has to point to the first frame of the next column in order
370  // for the content of the next column to be moved correctly to the
371  // newly created pSect by the InsertGroup
372  SwColumnFrame *pCol = static_cast<SwColumnFrame*>(pParent->GetUpper());
373  while( !pSibling && nullptr != ( pCol = static_cast<SwColumnFrame*>(pCol->GetNext()) ) )
374  pSibling = static_cast<SwLayoutFrame*>(pCol->Lower())->Lower();
375  if( pSibling )
376  {
377  // Even worse: every following column content has to
378  // be attached to the pSibling-chain in order to be
379  // taken along
380  SwFrame *pTmp = pSibling;
381  while ( nullptr != ( pCol = static_cast<SwColumnFrame*>(pCol->GetNext()) ) )
382  {
383  while ( pTmp->GetNext() )
384  pTmp = pTmp->GetNext();
385  SwFrame* pSave = ::SaveContent( pCol );
386  if (pSave)
387  ::RestoreContent( pSave, pSibling->GetUpper(), pTmp );
388  }
389  }
390  }
391  pParent = pSect;
392  pSect = new SwSectionFrame( *static_cast<SwSectionFrame*>(pParent)->GetSection(), pParent );
393  // if pParent is decomposed into two parts, its Follow has to be attached
394  // to the new second part
395  pSect->SetFollow( static_cast<SwSectionFrame*>(pParent)->GetFollow() );
396  static_cast<SwSectionFrame*>(pParent)->SetFollow( nullptr );
397  if( pSect->GetFollow() )
398  pParent->InvalidateSize_();
399 
400  const bool bInserted = InsertGroupBefore( pParent, pSibling, pSect );
401  if (bInserted)
402  {
403  pSect->Init();
404  aRectFnSet.MakePos( *pSect, pSect->GetUpper(), pSect->GetPrev(), true);
405  }
406  if( !static_cast<SwLayoutFrame*>(pParent)->Lower() )
407  {
408  SwSectionFrame::MoveContentAndDelete( static_cast<SwSectionFrame*>(pParent), false );
409  pParent = this;
410  }
411  }
412  else
413  InsertGroupBefore( pParent, pSibling, nullptr );
414 
415  InvalidateAll_();
416  SwPageFrame *pPage = FindPageFrame();
417  InvalidatePage( pPage );
418 
419  if ( pSibling )
420  {
421  pSibling->InvalidatePos_();
422  pSibling->InvalidatePrt_();
423  if ( pSibling->IsContentFrame() )
424  pSibling->InvalidatePage( pPage );
425  }
426 
427  SwTwips nFrameHeight = aRectFnSet.GetHeight(getFrameArea());
428  if( nFrameHeight )
429  pParent->Grow( nFrameHeight );
430 
431  if ( GetPrev() && !IsFollow() )
432  {
433  GetPrev()->InvalidateSize();
434  if ( GetPrev()->IsContentFrame() )
435  GetPrev()->InvalidatePage( pPage );
436  }
437 }
438 
445 bool SwSectionFrame::HasToBreak( const SwFrame* pFrame ) const
446 {
447  if( !pFrame->IsSctFrame() )
448  return false;
449 
450  const SwSectionFormat *pTmp = static_cast<const SwSectionFormat*>(GetFormat());
451 
452  const SwFrameFormat *pOtherFormat = static_cast<const SwSectionFrame*>(pFrame)->GetFormat();
453  do
454  {
455  pTmp = pTmp->GetParent();
456  if( !pTmp )
457  return false;
458  if( pTmp == pOtherFormat )
459  return true;
460  } while( true ); // ( pTmp->GetSect().GetValue() );
461 }
462 
469 {
470  if (pNxt->IsDeleteForbidden())
471  return;
472 
473  if (pNxt->IsJoinLocked() || GetSection() != pNxt->GetSection())
474  return;
475 
476  PROTOCOL( this, PROT::Section, DbgAction::Merge, pNxt )
477 
478  SwFrame* pTmp = ::SaveContent( pNxt );
479  if( pTmp )
480  {
481  SwFrame* pLast = Lower();
482  SwLayoutFrame* pLay = this;
483  if( pLast )
484  {
485  while( pLast->GetNext() )
486  pLast = pLast->GetNext();
487  if( pLast->IsColumnFrame() )
488  { // Columns now with BodyFrame
489  pLay = static_cast<SwLayoutFrame*>(static_cast<SwLayoutFrame*>(pLast)->Lower());
490  pLast = pLay->Lower();
491  if( pLast )
492  while( pLast->GetNext() )
493  pLast = pLast->GetNext();
494  }
495  }
496  ::RestoreContent( pTmp, pLay, pLast );
497  }
498  SetFollow( pNxt->GetFollow() );
499  pNxt->SetFollow( nullptr );
500  pNxt->Cut();
501  SwFrame::DestroyFrame(pNxt);
502  InvalidateSize();
503 }
504 
511 bool SwSectionFrame::SplitSect( SwFrame* pFrame, bool bApres )
512 {
513  assert(pFrame && "SplitSect: Why?");
514  SwFrame* pOther = bApres ? pFrame->FindNext() : pFrame->FindPrev();
515  if( !pOther )
516  return false;
517  SwSectionFrame* pSect = pOther->FindSctFrame();
518  if( pSect != this )
519  return false;
520  // Put the content aside
521  SwFrame* pSav = ::SaveContent( this, bApres ? pOther : pFrame );
522  OSL_ENSURE( pSav, "SplitSect: What's on?" );
523  if( pSav ) // be robust
524  { // Create a new SctFrame, not as a Follower/master
525  SwSectionFrame* pNew = new SwSectionFrame( *pSect->GetSection(), pSect );
526  pNew->InsertBehind( pSect->GetUpper(), pSect );
527  pNew->Init();
528  SwRectFnSet aRectFnSet(this);
529  aRectFnSet.MakePos( *pNew, nullptr, pSect, true );
530  // OD 25.03.2003 #108339# - restore content:
531  // determine layout frame for restoring content after the initialization
532  // of the section frame. In the section initialization the columns are
533  // created.
534  {
535  SwLayoutFrame* pLay = pNew;
536  // Search for last layout frame, e.g. for columned sections.
537  while( pLay->Lower() && pLay->Lower()->IsLayoutFrame() )
538  pLay = static_cast<SwLayoutFrame*>(pLay->Lower());
539  ::RestoreContent( pSav, pLay, nullptr );
540  }
541  InvalidateSize_();
542  if( HasFollow() )
543  {
544  pNew->SetFollow( GetFollow() );
545  SetFollow( nullptr );
546  }
547  return true;
548  }
549  return false;
550 }
551 
559 // If a multi-column section is cancelled, the ContentFrames have to be
560 // invalidated
561 static void lcl_InvalidateInfFlags( SwFrame* pFrame, bool bInva )
562 {
563  while ( pFrame )
564  {
565  pFrame->InvalidateInfFlags();
566  if( bInva )
567  {
568  pFrame->InvalidatePos_();
569  pFrame->InvalidateSize_();
570  pFrame->InvalidatePrt_();
571  }
572  if( pFrame->IsLayoutFrame() )
573  lcl_InvalidateInfFlags( static_cast<SwLayoutFrame*>(pFrame)->GetLower(), false );
574  pFrame = pFrame->GetNext();
575  }
576 }
577 
578 // Works like SwContentFrame::ImplGetNextContentFrame, but starts with a LayoutFrame
579 static SwContentFrame* lcl_GetNextContentFrame( const SwLayoutFrame* pLay, bool bFwd )
580 {
581  if ( bFwd )
582  {
583  if ( pLay->GetNext() && pLay->GetNext()->IsContentFrame() )
584  return const_cast<SwContentFrame*>(static_cast<const SwContentFrame*>(pLay->GetNext()));
585  }
586  else
587  {
588  if ( pLay->GetPrev() && pLay->GetPrev()->IsContentFrame() )
589  return const_cast<SwContentFrame*>(static_cast<const SwContentFrame*>(pLay->GetPrev()));
590  }
591 
592  const SwFrame* pFrame = pLay;
593  SwContentFrame *pContentFrame = nullptr;
594  bool bGoingUp = true;
595  do {
596  const SwFrame *p = nullptr;
597  bool bGoingFwdOrBwd = false;
598 
599  bool bGoingDown = !bGoingUp && pFrame->IsLayoutFrame();
600  if (bGoingDown)
601  {
602  p = static_cast<const SwLayoutFrame*>(pFrame)->Lower();
603  bGoingDown = nullptr != p;
604  }
605  if ( !bGoingDown )
606  {
607  p = pFrame->IsFlyFrame() ?
608  ( bFwd ? static_cast<const SwFlyFrame*>(pFrame)->GetNextLink() : static_cast<const SwFlyFrame*>(pFrame)->GetPrevLink() ) :
609  ( bFwd ? pFrame->GetNext() :pFrame->GetPrev() );
610  bGoingFwdOrBwd = nullptr != p;
611  if ( !bGoingFwdOrBwd )
612  {
613  p = pFrame->GetUpper();
614  bGoingUp = nullptr != p;
615  if ( !bGoingUp )
616  return nullptr;
617  }
618  }
619 
620  bGoingUp = !( bGoingFwdOrBwd || bGoingDown );
621  assert(p);
622  if (!bFwd && bGoingDown)
623  while ( p->GetNext() )
624  p = p->GetNext();
625 
626  pFrame = p;
627  } while ( nullptr == (pContentFrame = (pFrame->IsContentFrame() ? const_cast<SwContentFrame*>(static_cast<const SwContentFrame*>(pFrame)) : nullptr) ));
628 
629  return pContentFrame;
630 }
631 
632 namespace
633 {
634  SwLayoutFrame* FirstLeaf(SwSectionFrame* pLayFrame)
635  {
636  if (pLayFrame->Lower() && pLayFrame->Lower()->IsColumnFrame())
637  return pLayFrame->GetNextLayoutLeaf();
638  return pLayFrame;
639  }
640 
642  bool CanContainSplitSection(const SwFrame* pFrame)
643  {
644  if (!pFrame->IsInTab())
645  return true;
646 
647  // The frame is in a table, see if the table is in a section.
648  bool bRet = !pFrame->FindTabFrame()->IsInSct();
649 
650  if (bRet)
651  {
652  // Don't try to split if the frame itself is a section frame with
653  // multiple columns.
654  if (pFrame->IsSctFrame())
655  {
656  const SwFrame* pLower = pFrame->GetLower();
657  if (pLower && pLower->IsColumnFrame())
658  bRet = false;
659  }
660  }
661 
662  return bRet;
663  }
664 }
665 
667 {
668  bool bSize = pDel->Lower() && pDel->Lower()->IsColumnFrame();
669  SwFrame* pPrv = pDel->GetPrev();
670  SwLayoutFrame* pUp = pDel->GetUpper();
671  // OD 27.03.2003 #i12711# - initialize local pointer variables.
672  SwSectionFrame* pPrvSct = nullptr;
673  SwSectionFrame* pNxtSct = nullptr;
674  SwSectionFormat* pParent = static_cast<SwSectionFormat*>(pDel->GetFormat())->GetParent();
675  if( pDel->IsInTab() && pParent )
676  {
677  SwTabFrame *pTab = pDel->FindTabFrame();
678  // If we are within a table, we can only have broken up sections that
679  // are inside as well, but not a section that contains the whole table.
680  if( pTab->IsInSct() && pParent == pTab->FindSctFrame()->GetFormat() )
681  pParent = nullptr;
682  }
683  // If our Format has a parent, we have probably broken up another
684  // SectionFrame, which has to be checked. To do so we first acquire the
685  // succeeding and the preceding ContentFrame, let's see if they
686  // lay in the SectionFrames.
687  // OD 27.03.2003 #i12711# - check, if previous and next section belonging
688  // together and can be joined, *not* only if deleted section contains content.
689  if ( pParent )
690  {
691  SwFrame* pPrvContent = lcl_GetNextContentFrame( pDel, false );
692  pPrvSct = pPrvContent ? pPrvContent->FindSctFrame() : nullptr;
693  SwFrame* pNxtContent = lcl_GetNextContentFrame( pDel, true );
694  pNxtSct = pNxtContent ? pNxtContent->FindSctFrame() : nullptr;
695  }
696  else
697  {
698  pParent = nullptr;
699  pPrvSct = pNxtSct = nullptr;
700  }
701 
702  // Now the content is put aside and the frame is destroyed
703  SwFrame *pSave = bSave ? ::SaveContent( pDel ) : nullptr;
704  bool bOldFootnote = true;
705  if( pSave && pUp->IsFootnoteFrame() )
706  {
707  bOldFootnote = static_cast<SwFootnoteFrame*>(pUp)->IsColLocked();
708  static_cast<SwFootnoteFrame*>(pUp)->ColLock();
709  }
710  pDel->DelEmpty( true );
711  SwFrame::DestroyFrame(pDel);
712  if( pParent )
713  { // Search for the appropriate insert position
714  if( pNxtSct && pNxtSct->GetFormat() == pParent )
715  { // Here we can insert ourselves at the beginning
716  pUp = FirstLeaf( pNxtSct );
717  pPrv = nullptr;
718  if( pPrvSct && ( pPrvSct->GetFormat() != pParent ) )
719  pPrvSct = nullptr; // In order that nothing is merged
720  }
721  else if( pPrvSct && pPrvSct->GetFormat() == pParent )
722  { // Wonderful, here we can insert ourselves at the end
723  pUp = pPrvSct;
724  if( pUp->Lower() && pUp->Lower()->IsColumnFrame() )
725  {
726  pUp = static_cast<SwLayoutFrame*>(pUp->GetLastLower());
727  // The body of the last column
728  pUp = static_cast<SwLayoutFrame*>(pUp->Lower());
729  }
730  // In order to perform the insertion after the last one
731  pPrv = pUp->GetLastLower();
732  pPrvSct = nullptr; // Such that nothing is merged
733  }
734  else
735  {
736  if( pSave )
737  { // Following situations: before and after the section-to-be
738  // deleted there is the section boundary of the enclosing
739  // section, or another (sibling) section connects subsequently,
740  // that derives from the same Parent.
741  // In that case, there's not (yet) a part of our parent available
742  // that can store the content, so we create it here.
743  pPrvSct = new SwSectionFrame( *pParent->GetSection(), pUp );
744  pPrvSct->InsertBehind( pUp, pPrv );
745  pPrvSct->Init();
746  SwRectFnSet aRectFnSet(pUp);
747  aRectFnSet.MakePos( *pPrvSct, pUp, pPrv, true );
748  pUp = FirstLeaf( pPrvSct );
749  pPrv = nullptr;
750  }
751  pPrvSct = nullptr; // Such that nothing will be merged
752  }
753  }
754  // The content is going to be inserted...
755  if( pSave )
756  {
757  lcl_InvalidateInfFlags( pSave, bSize );
758  ::RestoreContent( pSave, pUp, pPrv );
760  if( !bOldFootnote )
761  static_cast<SwFootnoteFrame*>(pUp)->ColUnlock();
762  }
763  // Now two parts of the superior section could possibly be merged
764  if( pPrvSct && !pPrvSct->IsJoinLocked() )
765  {
766  OSL_ENSURE( pNxtSct, "MoveContent: No Merge" );
767  pPrvSct->MergeNext( pNxtSct );
768  }
769 }
770 
772 {
773  if ( IsJoinLocked() || IsColLocked() || StackHack::IsLocked() || StackHack::Count() > 50 )
774  return;
775  if( !m_pSection ) // Via DelEmpty
776  {
777 #ifdef DBG_UTIL
778  OSL_ENSURE( getRootFrame()->IsInDelList( this ), "SectionFrame without Section" );
779 #endif
780  if( !isFrameAreaPositionValid() )
781  {
782  if( GetUpper() )
783  {
784  SwRectFnSet aRectFnSet(GetUpper());
785  aRectFnSet.MakePos( *this, GetUpper(), GetPrev(), false );
786  }
787 
788  if (getFrameArea().Height() == 0)
789  {
790  // SwLayoutFrame::MakeAll() is not called for to-be-deleted
791  // section frames (which would invalidate the position of the
792  // next frame via the SwLayNotify dtor), so call it manually.
793  if (SwFrame* pNext = GetNext())
794  pNext->InvalidatePos();
795  }
796  }
797 
799  setFrameAreaSizeValid(true);
801  return;
802  }
803  LockJoin(); // I don't let myself to be destroyed on the way
804 
805  while( GetNext() && GetNext() == GetFollow() )
806  {
807  const SwFrame* pFoll = GetFollow();
808  MergeNext( static_cast<SwSectionFrame*>(GetNext()) );
809  if( pFoll == GetFollow() )
810  break;
811  }
812 
813  // OD 2004-03-15 #116561# - In online layout join the follows, if section
814  // can grow.
815  const SwViewShell *pSh = getRootFrame()->GetCurrShell();
816 
817  // Split sections inside table cells: need to merge all follows of the
818  // section here, as later we won't attempt doing so.
819  bool bCanContainSplitSection = false;
820  if (IsInTab() && GetUpper())
821  bCanContainSplitSection = CanContainSplitSection(GetUpper());
822 
823  if( pSh && (pSh->GetViewOptions()->getBrowseMode() || bCanContainSplitSection) &&
824  ( Grow( LONG_MAX, true ) > 0 ) )
825  {
826  while( GetFollow() )
827  {
828  const SwFrame* pFoll = GetFollow();
829  MergeNext( GetFollow() );
830  if( pFoll == GetFollow() )
831  break;
832  }
833  }
834 
835  // A section with Follow uses all the space until the lower edge of the
836  // Upper. If it moves, its size can grow or decrease...
837  if( !isFrameAreaPositionValid() && ToMaximize( false ) )
838  {
839  setFrameAreaSizeValid(false);
840  }
841 
842  SwLayoutFrame::MakeAll(getRootFrame()->GetCurrShell()->GetOut());
843 
844  if (IsInTab())
845  {
846  // In case the section is in a table, then calculate the lower right
847  // now. Just setting the valid size flag of the lower to false may not
848  // be enough, as lcl_RecalcRow() can call
849  // SwFrame::ValidateThisAndAllLowers(), and then we don't attempt
850  // calculating the proper position of the lower.
851  SwFrame* pLower = Lower();
852  if (pLower && !pLower->isFrameAreaPositionValid())
853  pLower->Calc(pRenderContext);
854  }
855 
856  UnlockJoin();
857  if( m_pSection && IsSuperfluous() )
858  DelEmpty( false );
859 }
860 
862 {
863  OSL_FAIL( "Oops, where is my tinfoil hat?" );
864  return false;
865 }
866 
868 {
869  const SwSectionFormat *pFormat = m_pSection->GetFormat();
870  while( !pFormat->GetEndAtTextEnd().IsAtEnd() )
871  {
872  if( auto pNewFormat = dynamic_cast< const SwSectionFormat *>( pFormat->GetRegisteredIn()) )
873  pFormat = pNewFormat;
874  else
875  return nullptr;
876  }
877  return pFormat;
878 }
879 
880 static void lcl_FindContentFrame( SwContentFrame* &rpContentFrame, SwFootnoteFrame* &rpFootnoteFrame,
881  SwFrame* pFrame, bool &rbChkFootnote )
882 {
883  if( !pFrame )
884  return;
885 
886  while( pFrame->GetNext() )
887  pFrame = pFrame->GetNext();
888  while( !rpContentFrame && pFrame )
889  {
890  if( pFrame->IsContentFrame() )
891  rpContentFrame = static_cast<SwContentFrame*>(pFrame);
892  else if( pFrame->IsLayoutFrame() )
893  {
894  if( pFrame->IsFootnoteFrame() )
895  {
896  if( rbChkFootnote )
897  {
898  rpFootnoteFrame = static_cast<SwFootnoteFrame*>(pFrame);
899  rbChkFootnote = rpFootnoteFrame->GetAttr()->GetFootnote().IsEndNote();
900  }
901  }
902  else
903  lcl_FindContentFrame( rpContentFrame, rpFootnoteFrame,
904  static_cast<SwLayoutFrame*>(pFrame)->Lower(), rbChkFootnote );
905  }
906  pFrame = pFrame->GetPrev();
907  }
908 }
909 
911 {
912  SwContentFrame *pRet = nullptr;
913  SwFootnoteFrame *pFootnoteFrame = nullptr;
914  SwSectionFrame *pSect = this;
915  if( nMode != SwFindMode::None )
916  {
917  const SwSectionFormat *pFormat = IsEndnAtEnd() ? GetEndSectFormat() :
919  do {
920  while( pSect->HasFollow() )
921  pSect = pSect->GetFollow();
922  SwFrame* pTmp = pSect->FindNext();
923  while( pTmp && pTmp->IsSctFrame() &&
924  !static_cast<SwSectionFrame*>(pTmp)->GetSection() )
925  pTmp = pTmp->FindNext();
926  if( pTmp && pTmp->IsSctFrame() &&
927  static_cast<SwSectionFrame*>(pTmp)->IsDescendantFrom( pFormat ) )
928  pSect = static_cast<SwSectionFrame*>(pTmp);
929  else
930  break;
931  } while( true );
932  }
933  bool bFootnoteFound = nMode == SwFindMode::EndNote;
934  do
935  {
936  lcl_FindContentFrame( pRet, pFootnoteFrame, pSect->Lower(), bFootnoteFound );
937  if( pRet || !pSect->IsFollow() || nMode == SwFindMode::None ||
938  ( SwFindMode::MyLast == nMode && this == pSect ) )
939  break;
940  pSect = pSect->FindMaster();
941  } while( pSect );
942  if( ( nMode == SwFindMode::EndNote ) && pFootnoteFrame )
943  pRet = pFootnoteFrame->ContainsContent();
944  return pRet;
945 }
946 
947 bool SwSectionFrame::CalcMinDiff( SwTwips& rMinDiff ) const
948 {
949  if( ToMaximize( true ) )
950  {
951  SwRectFnSet aRectFnSet(this);
952  rMinDiff = aRectFnSet.GetPrtBottom(*GetUpper());
953  rMinDiff = aRectFnSet.BottomDist( getFrameArea(), rMinDiff );
954  return true;
955  }
956  return false;
957 }
958 
965 static SwFootnoteFrame* lcl_FindEndnote( SwSectionFrame* &rpSect, bool &rbEmpty,
966  SwLayouter *pLayouter )
967 {
968  // if rEmpty is set, the rpSect is already searched
969  SwSectionFrame* pSect = rbEmpty ? rpSect->GetFollow() : rpSect;
970  while( pSect )
971  {
972  OSL_ENSURE( (pSect->Lower() && pSect->Lower()->IsColumnFrame()) || pSect->GetUpper()->IsFootnoteFrame(),
973  "InsertEndnotes: Where's my column?" );
974 
975  // i73332: Columned section in endnote
976  SwColumnFrame* pCol = nullptr;
977  if(pSect->Lower() && pSect->Lower()->IsColumnFrame())
978  pCol = static_cast<SwColumnFrame*>(pSect->Lower());
979 
980  while( pCol ) // check all columns
981  {
982  SwFootnoteContFrame* pFootnoteCont = pCol->FindFootnoteCont();
983  if( pFootnoteCont )
984  {
985  SwFootnoteFrame* pRet = static_cast<SwFootnoteFrame*>(pFootnoteCont->Lower());
986  while( pRet ) // look for endnotes
987  {
988  /* CollectEndNode can destroy pRet so we need to get the
989  next early
990  */
991  SwFootnoteFrame* pRetNext = static_cast<SwFootnoteFrame*>(pRet->GetNext());
992  if( pRet->GetAttr()->GetFootnote().IsEndNote() )
993  {
994  if( pRet->GetMaster() )
995  {
996  if( pLayouter )
997  pLayouter->CollectEndnote( pRet );
998  else
999  return nullptr;
1000  }
1001  else
1002  return pRet; // Found
1003  }
1004  pRet = pRetNext;
1005  }
1006  }
1007  pCol = static_cast<SwColumnFrame*>(pCol->GetNext());
1008  }
1009  rpSect = pSect;
1010  pSect = pLayouter ? pSect->GetFollow() : nullptr;
1011  rbEmpty = true;
1012  }
1013  return nullptr;
1014 }
1015 
1016 static void lcl_ColumnRefresh( SwSectionFrame* pSect, bool bFollow )
1017 {
1018  vcl::RenderContext* pRenderContext = pSect->getRootFrame()->GetCurrShell()->GetOut();
1019  while( pSect )
1020  {
1021  bool bOldLock = pSect->IsColLocked();
1022  pSect->ColLock();
1023  if( pSect->Lower() && pSect->Lower()->IsColumnFrame() )
1024  {
1025  SwColumnFrame *pCol = static_cast<SwColumnFrame*>(pSect->Lower());
1026  do
1027  { pCol->InvalidateSize_();
1028  pCol->InvalidatePos_();
1029  static_cast<SwLayoutFrame*>(pCol)->Lower()->InvalidateSize_();
1030  pCol->Calc(pRenderContext); // calculation of column and
1031  static_cast<SwLayoutFrame*>(pCol)->Lower()->Calc(pRenderContext); // body
1032  pCol = static_cast<SwColumnFrame*>(pCol->GetNext());
1033  } while ( pCol );
1034  }
1035  if( !bOldLock )
1036  pSect->ColUnlock();
1037  if( bFollow )
1038  pSect = pSect->GetFollow();
1039  else
1040  pSect = nullptr;
1041  }
1042 }
1043 
1045 {
1046  OSL_ENSURE( IsColLocked(), "CollectEndnotes: You love the risk?" );
1047  // i73332: Section in footnode does not have columns!
1048  OSL_ENSURE( (Lower() && Lower()->IsColumnFrame()) || GetUpper()->IsFootnoteFrame(), "Where's my column?" );
1049 
1050  SwSectionFrame* pSect = this;
1051  SwFootnoteFrame* pFootnote;
1052  bool bEmpty = false;
1053  // pSect is the last sectionfrm without endnotes or the this-pointer
1054  // the first sectionfrm with endnotes may be destroyed, when the endnotes
1055  // is cutted
1056  while( nullptr != (pFootnote = lcl_FindEndnote( pSect, bEmpty, pLayouter )) )
1057  pLayouter->CollectEndnote( pFootnote );
1058  if( pLayouter->HasEndnotes() )
1059  lcl_ColumnRefresh( this, true );
1060 }
1061 
1072 void SwSectionFrame::CheckClipping( bool bGrow, bool bMaximize )
1073 {
1074  SwRectFnSet aRectFnSet(this);
1075  tools::Long nDiff;
1076  SwTwips nDeadLine = aRectFnSet.GetPrtBottom(*GetUpper());
1077  if( bGrow && ( !IsInFly() || !GetUpper()->IsColBodyFrame() ||
1078  !FindFlyFrame()->IsLocked() ) )
1079  {
1080  nDiff = -aRectFnSet.BottomDist( getFrameArea(), nDeadLine );
1081  if( !bMaximize )
1082  nDiff += Undersize();
1083  if( nDiff > 0 )
1084  {
1085  tools::Long nAdd = GetUpper()->Grow( nDiff );
1086  if( aRectFnSet.IsVert() )
1087  nDeadLine -= nAdd;
1088  else
1089  nDeadLine += nAdd;
1090  }
1091  }
1092  nDiff = -aRectFnSet.BottomDist( getFrameArea(), nDeadLine );
1093  SetUndersized( !bMaximize && nDiff >= 0 );
1094  const bool bCalc = ( IsUndersized() || bMaximize ) &&
1095  ( nDiff ||
1096  aRectFnSet.GetTop(getFramePrintArea()) > aRectFnSet.GetHeight(getFrameArea()) );
1097  // OD 03.11.2003 #i19737# - introduce local variable <bExtraCalc> to indicate
1098  // that a calculation has to be done beside the value of <bCalc>.
1099  bool bExtraCalc = false;
1100  if( !bCalc && !bGrow && IsAnyNoteAtEnd() && !IsInFootnote() )
1101  {
1102  SwSectionFrame *pSect = this;
1103  bool bEmpty = false;
1104  SwLayoutFrame* pFootnote = IsEndnAtEnd() ?
1105  lcl_FindEndnote( pSect, bEmpty, nullptr ) : nullptr;
1106  if( pFootnote )
1107  {
1108  pFootnote = pFootnote->FindFootnoteBossFrame();
1110  // OD 08.11.2002 #104840# - use <SwLayoutFrame::IsBefore(..)>
1111  if ( pTmp && pFootnote->IsBefore( pTmp->FindFootnoteBossFrame() ) )
1112  bExtraCalc = true;
1113  }
1114  else if( GetFollow() && !GetFollow()->ContainsAny() )
1115  bExtraCalc = true;
1116  }
1117  if ( !(bCalc || bExtraCalc) )
1118  return;
1119 
1120  nDiff = aRectFnSet.YDiff( nDeadLine, aRectFnSet.GetTop(getFrameArea()) );
1121  if( nDiff < 0 )
1122  nDeadLine = aRectFnSet.GetTop(getFrameArea());
1123  const Size aOldSz( getFramePrintArea().SSize() );
1124  tools::Long nTop = aRectFnSet.GetTopMargin(*this);
1125 
1126  {
1128  aRectFnSet.SetBottom( aFrm, nDeadLine );
1129  }
1130 
1131  nDiff = aRectFnSet.GetHeight(getFrameArea());
1132  if( nTop > nDiff )
1133  nTop = nDiff;
1134  aRectFnSet.SetYMargins( *this, nTop, 0 );
1135 
1136  // OD 18.09.2002 #100522#
1137  // Determine, if height has changed.
1138  // Note: In vertical layout the height equals the width value.
1139  bool bHeightChanged = aRectFnSet.IsVert() ?
1140  (aOldSz.Width() != getFramePrintArea().Width()) :
1141  (aOldSz.Height() != getFramePrintArea().Height());
1142  // Last but not least we have changed the height again, thus the inner
1143  // layout (columns) is calculated and the content as well.
1144  // OD 18.09.2002 #100522#
1145  // calculate content, only if height has changed.
1146  // OD 03.11.2003 #i19737# - restriction of content calculation too strong.
1147  // If an endnote has an incorrect position or a follow section contains
1148  // no content except footnotes/endnotes, the content has also been calculated.
1149  if ( !(( bHeightChanged || bExtraCalc ) && Lower()) )
1150  return;
1151 
1152  if( Lower()->IsColumnFrame() )
1153  {
1154  lcl_ColumnRefresh( this, false );
1155  ::CalcContent( this );
1156  }
1157  else
1158  {
1159  ChgLowersProp( aOldSz );
1160  if( !bMaximize && !IsContentLocked() )
1161  ::CalcContent( this );
1162  }
1163 }
1164 
1166 {
1167  if ( IsJoinLocked() || IsColLocked() )
1168  return;
1169  LockJoin();
1170  SwRectFnSet aRectFnSet(this);
1171  if( GetPrev() || GetUpper() )
1172  {
1173  // assure notifications on position changes.
1174  const SwLayNotify aNotify( this );
1175  aRectFnSet.MakePos( *this, GetUpper(), GetPrev(), false );
1177  }
1178  SwTwips nDeadLine = aRectFnSet.GetPrtBottom(*GetUpper());
1179  // OD 22.10.2002 #97265# - call always method <lcl_ColumnRefresh(..)>, in
1180  // order to get calculated lowers, not only if there space left in its upper.
1181  if( aRectFnSet.BottomDist( getFrameArea(), nDeadLine ) >= 0 )
1182  {
1183  {
1185  aRectFnSet.SetBottom( aFrm, nDeadLine );
1186  }
1187 
1188  tools::Long nHeight = aRectFnSet.GetHeight(getFrameArea());
1189  tools::Long nTop = CalcUpperSpace();
1190  if( nTop > nHeight )
1191  nTop = nHeight;
1192  aRectFnSet.SetYMargins( *this, nTop, 0 );
1193  }
1194  lcl_ColumnRefresh( this, false );
1195  UnlockJoin();
1196 }
1197 
1198 namespace {
1199 
1200 // #i40147# - helper class to perform extra section format
1201 // to position anchored objects and to keep the position of whose objects locked.
1202 class ExtraFormatToPositionObjs
1203 {
1204  private:
1205  SwSectionFrame* mpSectFrame;
1206  bool mbExtraFormatPerformed;
1207 
1208  public:
1209  explicit ExtraFormatToPositionObjs( SwSectionFrame& _rSectFrame)
1210  : mpSectFrame( &_rSectFrame ),
1211  mbExtraFormatPerformed( false )
1212  {}
1213 
1214  ~ExtraFormatToPositionObjs()
1215  {
1216  if ( !mbExtraFormatPerformed )
1217  return;
1218 
1219  // release keep locked position of lower floating screen objects
1220  SwPageFrame* pPageFrame = mpSectFrame->FindPageFrame();
1221  SwSortedObjs* pObjs = pPageFrame ? pPageFrame->GetSortedObjs() : nullptr;
1222  if ( pObjs )
1223  {
1224  for (SwAnchoredObject* pAnchoredObj : *pObjs)
1225  {
1226  if ( mpSectFrame->IsAnLower( pAnchoredObj->GetAnchorFrame() ) )
1227  {
1228  pAnchoredObj->SetKeepPosLocked( false );
1229  }
1230  }
1231  }
1232  }
1233 
1234  // #i81555#
1235  void InitObjs( SwFrame& rFrame )
1236  {
1237  SwSortedObjs* pObjs = rFrame.GetDrawObjs();
1238  if ( pObjs )
1239  {
1240  for (SwAnchoredObject* pAnchoredObj : *pObjs)
1241  {
1242  pAnchoredObj->UnlockPosition();
1243  pAnchoredObj->SetClearedEnvironment( false );
1244  }
1245  }
1246  if ( rFrame.IsLayoutFrame() )
1247  {
1248  SwFrame* pLowerFrame = rFrame.GetLower();
1249  while ( pLowerFrame != nullptr )
1250  {
1251  InitObjs( *pLowerFrame );
1252 
1253  pLowerFrame = pLowerFrame->GetNext();
1254  }
1255  }
1256  }
1257 
1258  void FormatSectionToPositionObjs()
1259  {
1260  vcl::RenderContext* pRenderContext = mpSectFrame->getRootFrame()->GetCurrShell()->GetOut();
1261  // perform extra format for multi-columned section.
1262  if ( !(mpSectFrame->Lower() && mpSectFrame->Lower()->IsColumnFrame() &&
1263  mpSectFrame->Lower()->GetNext()) )
1264  return;
1265 
1266  // grow section till bottom of printing area of upper frame
1267  SwRectFnSet aRectFnSet(mpSectFrame);
1268  SwTwips nTopMargin = aRectFnSet.GetTopMargin(*mpSectFrame);
1269  Size aOldSectPrtSize( mpSectFrame->getFramePrintArea().SSize() );
1270  SwTwips nDiff = aRectFnSet.BottomDist( mpSectFrame->getFrameArea(), aRectFnSet.GetPrtBottom(*mpSectFrame->GetUpper()) );
1271 
1272  {
1274  aRectFnSet.AddBottom( aFrm, nDiff );
1275  }
1276 
1277  aRectFnSet.SetYMargins( *mpSectFrame, nTopMargin, 0 );
1278  // #i59789#
1279  // suppress formatting, if printing area of section is too narrow
1280  if ( aRectFnSet.GetHeight(mpSectFrame->getFramePrintArea()) <= 0 )
1281  {
1282  return;
1283  }
1284  mpSectFrame->ChgLowersProp( aOldSectPrtSize );
1285 
1286  // format column frames and its body and footnote container
1287  SwColumnFrame* pColFrame = static_cast<SwColumnFrame*>(mpSectFrame->Lower());
1288  while ( pColFrame )
1289  {
1290  pColFrame->Calc(pRenderContext);
1291  pColFrame->Lower()->Calc(pRenderContext);
1292  if ( pColFrame->Lower()->GetNext() )
1293  {
1294  pColFrame->Lower()->GetNext()->Calc(pRenderContext);
1295  }
1296 
1297  pColFrame = static_cast<SwColumnFrame*>(pColFrame->GetNext());
1298  }
1299 
1300  // unlock position of lower floating screen objects for the extra format
1301  // #i81555#
1302  // Section frame can already have changed the page and its content
1303  // can still be on the former page.
1304  // Thus, initialize objects via lower-relationship
1305  InitObjs( *mpSectFrame );
1306 
1307  // format content - first with collecting its foot-/endnotes before content
1308  // format, second without collecting its foot-/endnotes.
1309  ::CalcContent( mpSectFrame );
1310  ::CalcContent( mpSectFrame, true );
1311 
1312  // keep locked position of lower floating screen objects
1313  SwPageFrame* pPageFrame = mpSectFrame->FindPageFrame();
1314  SwSortedObjs* pObjs = pPageFrame ? pPageFrame->GetSortedObjs() : nullptr;
1315  if ( pObjs )
1316  {
1317  for (SwAnchoredObject* pAnchoredObj : *pObjs)
1318  {
1319  if ( mpSectFrame->IsAnLower( pAnchoredObj->GetAnchorFrame() ) )
1320  {
1321  pAnchoredObj->SetKeepPosLocked( true );
1322  }
1323  }
1324  }
1325 
1326  mbExtraFormatPerformed = true;
1327 
1328  }
1329 };
1330 
1331 }
1332 
1334 void SwSectionFrame::Format( vcl::RenderContext* pRenderContext, const SwBorderAttrs *pAttr )
1335 {
1336  if( !m_pSection ) // via DelEmpty
1337  {
1338 #ifdef DBG_UTIL
1339  OSL_ENSURE( getRootFrame()->IsInDelList( this ), "SectionFrame without Section" );
1340 #endif
1342  setFrameAreaSizeValid(true);
1343  setFramePrintAreaValid(true);
1344  return;
1345  }
1346 
1347  SwRectFnSet aRectFnSet(this);
1348 
1349  if ( !isFramePrintAreaValid() )
1350  {
1351  PROTOCOL( this, PROT::PrintArea, DbgAction::NONE, nullptr )
1352  setFramePrintAreaValid(true);
1353  SwTwips nUpper = CalcUpperSpace();
1354 
1355  // #109700# LRSpace for sections
1356  const SvxLRSpaceItem& rLRSpace = GetFormat()->GetLRSpace();
1357  aRectFnSet.SetXMargins( *this, rLRSpace.GetLeft(), rLRSpace.GetRight() );
1358 
1359  if( nUpper != aRectFnSet.GetTopMargin(*this) )
1360  {
1361  setFrameAreaSizeValid(false);
1362  SwFrame* pOwn = ContainsAny();
1363  if( pOwn )
1364  pOwn->InvalidatePos_();
1365  }
1366  aRectFnSet.SetYMargins( *this, nUpper, 0 );
1367  }
1368 
1369  if ( isFrameAreaSizeValid() )
1370  return;
1371 
1372  PROTOCOL_ENTER( this, PROT::Size, DbgAction::NONE, nullptr )
1373  const tools::Long nOldHeight = aRectFnSet.GetHeight(getFrameArea());
1374  bool bOldLock = IsColLocked();
1375  ColLock();
1376 
1377  setFrameAreaSizeValid(true);
1378 
1379  // The size is only determined by the content, if the SectFrame does not have a
1380  // Follow. Otherwise it fills (occupies) the Upper down to the lower edge.
1381  // It is not responsible for the text flow, but the content is.
1382  bool bMaximize = ToMaximize( false );
1383 
1384  // OD 2004-05-17 #i28701# - If the wrapping style has to be considered
1385  // on object positioning, an extra formatting has to be performed
1386  // to determine the correct positions the floating screen objects.
1387  // #i40147#
1388  // use new helper class <ExtraFormatToPositionObjs>.
1389  // This class additionally keep the locked position of the objects
1390  // and releases this position lock keeping on destruction.
1391  ExtraFormatToPositionObjs aExtraFormatToPosObjs( *this );
1392  if ( !bMaximize &&
1393  GetFormat()->getIDocumentSettingAccess().get(DocumentSettingId::CONSIDER_WRAP_ON_OBJECT_POSITION) &&
1394  !GetFormat()->GetBalancedColumns().GetValue() )
1395  {
1396  aExtraFormatToPosObjs.FormatSectionToPositionObjs();
1397  }
1398 
1399  // Column widths have to be adjusted before calling CheckClipping.
1400  // CheckClipping can cause the formatting of the lower frames
1401  // which still have a width of 0.
1402  const bool bHasColumns = Lower() && Lower()->IsColumnFrame();
1403  if ( bHasColumns && Lower()->GetNext() )
1404  AdjustColumns( nullptr, false );
1405 
1406  if( GetUpper() )
1407  {
1408  const tools::Long nWidth = aRectFnSet.GetWidth(GetUpper()->getFramePrintArea());
1409 
1410  {
1412  aRectFnSet.SetWidth( aFrm, nWidth );
1413  }
1414 
1415  // #109700# LRSpace for sections
1416  {
1417  const SvxLRSpaceItem& rLRSpace = GetFormat()->GetLRSpace();
1419  aRectFnSet.SetWidth( aPrt, nWidth - rLRSpace.GetLeft() - rLRSpace.GetRight() );
1420  }
1421 
1422  // OD 15.10.2002 #103517# - allow grow in online layout
1423  // Thus, set <..IsBrowseMode()> as parameter <bGrow> on calling
1424  // method <CheckClipping(..)>.
1425  const SwViewShell *pSh = getRootFrame()->GetCurrShell();
1426  CheckClipping( pSh && pSh->GetViewOptions()->getBrowseMode(), bMaximize );
1427  bMaximize = ToMaximize( false );
1428  setFrameAreaSizeValid(true);
1429  }
1430 
1431  // Check the width of the columns and adjust if necessary
1432  if ( bHasColumns && ! Lower()->GetNext() && bMaximize )
1433  static_cast<SwColumnFrame*>(Lower())->Lower()->Calc(pRenderContext);
1434 
1435  if ( !bMaximize )
1436  {
1437  SwTwips nRemaining = aRectFnSet.GetTopMargin(*this);
1438  SwFrame *pFrame = m_pLower;
1439  if( pFrame )
1440  {
1441  if( pFrame->IsColumnFrame() && pFrame->GetNext() )
1442  {
1443  // #i61435#
1444  // suppress formatting, if upper frame has height <= 0
1445  if ( aRectFnSet.GetHeight(GetUpper()->getFrameArea()) > 0 )
1446  {
1447  FormatWidthCols( *pAttr, nRemaining, MINLAY );
1448  }
1449  // #126020# - adjust check for empty section
1450  // #130797# - correct fix #126020#
1451  while( HasFollow() && !GetFollow()->ContainsContent() &&
1452  !GetFollow()->ContainsAny( true ) )
1453  {
1454  SwFrame* pOld = GetFollow();
1455  GetFollow()->DelEmpty( false );
1456  if( pOld == GetFollow() )
1457  break;
1458  }
1459  bMaximize = ToMaximize( false );
1460  nRemaining += aRectFnSet.GetHeight(pFrame->getFrameArea());
1461  }
1462  else
1463  {
1464  if( pFrame->IsColumnFrame() )
1465  {
1466  pFrame->Calc(pRenderContext);
1467  pFrame = static_cast<SwColumnFrame*>(pFrame)->Lower();
1468  pFrame->Calc(pRenderContext);
1469  pFrame = static_cast<SwLayoutFrame*>(pFrame)->Lower();
1471  }
1472  // If we are in a columned frame which calls a CalcContent
1473  // in the FormatWidthCols, the content might need calculating
1474  if( pFrame && !pFrame->isFrameAreaDefinitionValid() && IsInFly() &&
1475  FindFlyFrame()->IsColLocked() )
1476  ::CalcContent( this );
1477  nRemaining += InnerHeight();
1478  bMaximize = HasFollow();
1479  }
1480  }
1481 
1482  SwTwips nDiff = aRectFnSet.GetHeight(getFrameArea()) - nRemaining;
1483  if( nDiff < 0)
1484  {
1485  SwTwips nDeadLine = aRectFnSet.GetPrtBottom(*GetUpper());
1486  {
1487  tools::Long nBottom = aRectFnSet.GetBottom(getFrameArea());
1488  nBottom = aRectFnSet.YInc( nBottom, -nDiff );
1489  tools::Long nTmpDiff = aRectFnSet.YDiff( nBottom, nDeadLine );
1490  if( nTmpDiff > 0 )
1491  {
1492  nTmpDiff = GetUpper()->Grow( nTmpDiff, true );
1493  nDeadLine = aRectFnSet.YInc( nDeadLine, nTmpDiff );
1494  nTmpDiff = aRectFnSet.YDiff( nBottom, nDeadLine );
1495  if( nTmpDiff > 0 )
1496  nDiff += nTmpDiff;
1497  if( nDiff > 0 )
1498  nDiff = 0;
1499  }
1500  }
1501  }
1502  if( nDiff )
1503  {
1504  tools::Long nTmp = nRemaining - aRectFnSet.GetHeight(getFrameArea());
1505  tools::Long nTop = aRectFnSet.GetTopMargin(*this);
1506 
1507  {
1509  aRectFnSet.AddBottom( aFrm, nTmp );
1510  }
1511 
1512  aRectFnSet.SetYMargins( *this, nTop, 0 );
1514 
1515  if (m_pLower && (!m_pLower->IsColumnFrame() || !m_pLower->GetNext()))
1516  {
1517  // If a single-column section just created the space that
1518  // was requested by the "undersized" paragraphs, then they
1519  // have to be invalidated and calculated, so they fully cover it
1520  pFrame = m_pLower;
1521  if( pFrame->IsColumnFrame() )
1522  {
1523  pFrame->InvalidateSize_();
1524  pFrame->InvalidatePos_();
1525  pFrame->Calc(pRenderContext);
1526  pFrame = static_cast<SwColumnFrame*>(pFrame)->Lower();
1527  pFrame->Calc(pRenderContext);
1528  pFrame = static_cast<SwLayoutFrame*>(pFrame)->Lower();
1530  }
1531  bool bUnderSz = false;
1532  while( pFrame )
1533  {
1534  if( pFrame->IsTextFrame() && static_cast<SwTextFrame*>(pFrame)->IsUndersized() )
1535  {
1537  bUnderSz = true;
1538  }
1539  pFrame = pFrame->GetNext();
1540  }
1541  if( bUnderSz && !IsContentLocked() )
1542  ::CalcContent( this );
1543  }
1544  }
1545  }
1546 
1547  // Do not exceed the lower edge of the Upper.
1548  // Do not extend below the lower edge with Sections with Follows
1549  if ( GetUpper() )
1550  CheckClipping( true, bMaximize );
1551  if( !bOldLock )
1552  ColUnlock();
1553  tools::Long nDiff = nOldHeight - aRectFnSet.GetHeight(getFrameArea());
1554 
1555  if( nDiff > 0 )
1556  {
1557  if( !GetNext() )
1558  SetRetouche(); // Take over the retouching ourselves
1559  if( GetUpper() && !GetUpper()->IsFooterFrame() )
1560  GetUpper()->Shrink( nDiff );
1561  }
1562 
1563  if( IsUndersized() )
1564  {
1565  setFramePrintAreaValid(true);
1566  }
1567 
1568 }
1569 
1573 {
1574  // Attention: Nested sections are currently not supported
1575 
1577 
1578  // Shortcuts for "columned" sections, if we're not in the last column
1579  // Can we slide to the next column of the section?
1580  if( IsColBodyFrame() && GetUpper()->GetNext() )
1581  return static_cast<SwLayoutFrame*>(static_cast<SwLayoutFrame*>(GetUpper()->GetNext())->Lower());
1582  if( GetUpper()->IsColBodyFrame() && GetUpper()->GetUpper()->GetNext() )
1583  return static_cast<SwLayoutFrame*>(static_cast<SwLayoutFrame*>(GetUpper()->GetUpper()->GetNext())->Lower());
1584  // Inside a table-in-section, or sections of headers/footers, there can be only
1585  // one column shift be made, one of the above shortcuts should have applied!
1586  if( !CanContainSplitSection(GetUpper()) || FindFooterOrHeader() )
1587  return nullptr;
1588 
1589  SwSectionFrame *pSect = FindSctFrame();
1590  bool bWrongPage = false;
1591  assert(pSect && "GetNextSctLeaf: Missing SectionFrame");
1592 
1593  // Shortcut for sections with Follows. That's ok,
1594  // if no columns or pages (except dummy pages) lie in between.
1595  // In case of linked frames and in footnotes the shortcut would get
1596  // even more costly
1597  if( pSect->HasFollow() && pSect->IsInDocBody() && !pSect->IsInTab() )
1598  {
1599  if( pSect->GetFollow() == pSect->GetNext() )
1600  {
1601  SwPageFrame *pPg = pSect->GetFollow()->FindPageFrame();
1602  if( WrongPageDesc( pPg ) )
1603  bWrongPage = true;
1604  else
1605  return FirstLeaf( pSect->GetFollow() );
1606  }
1607  else
1608  {
1609  SwFrame* pTmp;
1610  if( !pSect->GetUpper()->IsColBodyFrame() ||
1611  nullptr == ( pTmp = pSect->GetUpper()->GetUpper()->GetNext() ) )
1612  pTmp = pSect->FindPageFrame()->GetNext();
1613  if( pTmp ) // is now the next column or page
1614  {
1615  SwFrame* pTmpX = pTmp;
1616  if( pTmp->IsPageFrame() && static_cast<SwPageFrame*>(pTmp)->IsEmptyPage() )
1617  pTmp = pTmp->GetNext(); // skip dummy pages
1618  SwFrame *pUp = pSect->GetFollow()->GetUpper();
1619  // pUp becomes the next column if the Follow lies in a column
1620  // that is not a "not first" one, otherwise the page
1621  if( !pUp->IsColBodyFrame() ||
1622  !( pUp = pUp->GetUpper() )->GetPrev() )
1623  pUp = pUp->FindPageFrame();
1624  // Now pUp and pTmp have to be the same page/column, otherwise
1625  // pages or columns lie between Master and Follow
1626  if( pUp == pTmp || pUp->GetNext() == pTmpX )
1627  {
1628  SwPageFrame* pNxtPg = pUp->IsPageFrame() ?
1629  static_cast<SwPageFrame*>(pUp) : pUp->FindPageFrame();
1630  if( WrongPageDesc( pNxtPg ) )
1631  bWrongPage = true;
1632  else
1633  return FirstLeaf( pSect->GetFollow() );
1634  }
1635  }
1636  }
1637  }
1638 
1639 #ifndef NDEBUG
1640  std::vector<SwFrame *> parents;
1641  for (SwFrame * pTmp = GetUpper(); pTmp && !pTmp->IsPageFrame(); pTmp = pTmp->GetUpper())
1642  {
1643  parents.push_back(pTmp);
1644  }
1645 #endif
1646 
1647  // Always end up in the same section: Body again inside Body etc.
1648  const bool bBody = IsInDocBody();
1649  const bool bFootnotePage = FindPageFrame()->IsFootnotePage();
1650 
1651  // The "pLayLeaf is in a table" case is rejected by default, so that it
1652  // can't happen that we try to move a table to one of its own cells.
1653  bool bLayLeafTableAllowed = false;
1654  SwLayoutFrame *pLayLeaf;
1655 
1656  SwLayoutFrame* pCellLeaf = nullptr;
1657  if (GetUpper()->IsInTab())
1658  {
1659  if (IsTabFrame())
1660  {
1661  return nullptr; // table in section in table: split disabled for now
1662  }
1663  // We are *in* a table (not an outermost SwTabFrame), see if there
1664  // is a follow cell frame created already.
1665  pCellLeaf = GetNextCellLeaf();
1666  if (!pCellLeaf)
1667  {
1668  SAL_WARN("sw.layout", "section is in table, but the table is not split");
1669  return nullptr;
1670  }
1671  }
1672 
1673  // A shortcut for TabFrames such that not all cells need to be visited
1674  if( bWrongPage )
1675  pLayLeaf = nullptr;
1676  else if( IsTabFrame() )
1677  {
1678  SwFrame *const pTmpCnt = static_cast<SwTabFrame*>(this)->FindLastContentOrTable();
1679  pLayLeaf = pTmpCnt ? pTmpCnt->GetUpper() : nullptr;
1680  }
1681  else if (pCellLeaf && CanContainSplitSection(this))
1682  {
1683  // This frame is in a table-not-in-section, its follow should be
1684  // inserted under the follow of the frame's cell.
1685  pLayLeaf = pCellLeaf;
1686  if (pLayLeaf->FindTabFrame() == FindTabFrame())
1687  SAL_WARN("sw.layout", "my table frame and my follow's table frame is the same");
1688  // In this case pLayLeaf pointing to an in-table frame is OK.
1689  bLayLeafTableAllowed = true;
1690  }
1691  else
1692  {
1693  pLayLeaf = GetNextLayoutLeaf();
1694  if( IsColumnFrame() )
1695  {
1696  while( pLayLeaf && static_cast<SwColumnFrame*>(this)->IsAnLower( pLayLeaf ) )
1697  pLayLeaf = pLayLeaf->GetNextLayoutLeaf();
1698  }
1699  }
1700 
1701  SwLayoutFrame *pOldLayLeaf = nullptr; // Such that in case of newly
1702  // created pages, the search is
1703  // not started over at the beginning
1704 
1705  while( true )
1706  {
1707  if( pLayLeaf )
1708  {
1709  // A layout leaf was found, let's see whether it can store me or
1710  // another SectionFrame can be inserted here, or we have to continue
1711  // searching
1712  SwPageFrame* pNxtPg = pLayLeaf->FindPageFrame();
1713  if ( !bFootnotePage && pNxtPg->IsFootnotePage() )
1714  { // If I reached the end note pages it's over
1715  pLayLeaf = nullptr;
1716  continue;
1717  }
1718  // Once inBody always inBody, don't step into tables-in-sections and not into other sections
1719  if ( (bBody && !pLayLeaf->IsInDocBody()) ||
1720  (IsInFootnote() != pLayLeaf->IsInFootnote() ) ||
1721  (pLayLeaf->IsInTab() && !bLayLeafTableAllowed) ||
1722  ( pLayLeaf->IsInSct() && ( !pSect->HasFollow()
1723  || pSect->GetFollow() != pLayLeaf->FindSctFrame() ) ) )
1724  {
1725  // Rejected - try again.
1726  pOldLayLeaf = pLayLeaf;
1727  pLayLeaf = pLayLeaf->GetNextLayoutLeaf();
1728  continue;
1729  }
1730  // Page desc is never wrong in case of sections-in-tables: in that
1731  // case pLayLeaf points to our section's cell's follow, which is
1732  // fine to be on the same page. New page creation is handled when
1733  // creating / moving the cell frame.
1734  if( WrongPageDesc( pNxtPg ) && !bLayLeafTableAllowed )
1735  {
1736  if( bWrongPage )
1737  break; // there's a column between me and my right page
1738  pLayLeaf = nullptr;
1739  bWrongPage = true;
1740  pOldLayLeaf = nullptr;
1741  continue;
1742  }
1743  }
1744  // There is no further LayoutFrame that fits, so a new page
1745  // has to be created, although new pages are worthless within a frame
1746  else if( !pSect->IsInFly() &&
1747  ( eMakePage == MAKEPAGE_APPEND || eMakePage == MAKEPAGE_INSERT ) )
1748  {
1749  InsertPage(pOldLayLeaf ? pOldLayLeaf->FindPageFrame() : FindPageFrame(),
1750  false );
1751  // and again the whole thing
1752  if (pCellLeaf && CanContainSplitSection(this))
1753  // GetNextLayoutLeaf() would refer to the next cell in the same
1754  // row, avoid that. pCellLeaf points to the correct cell in the
1755  // follow table, and in the next round it'll be used, as we now
1756  // have a next page.
1757  pLayLeaf = pCellLeaf;
1758  else
1759  pLayLeaf = pOldLayLeaf ? pOldLayLeaf : GetNextLayoutLeaf();
1760  continue;
1761  }
1762  break;
1763  }
1764 
1765  if( pLayLeaf )
1766  {
1767  // We have found the suitable layout sheet. If there (in the sheet) is
1768  // already a Follow of our section, we take its first layout sheet,
1769  // otherwise it is time to create a section follow
1770  SwSectionFrame* pNew = nullptr;
1771 
1772  // This can be omitted if existing Follows were cut short
1773  SwFrame* pFirst = pLayLeaf->Lower();
1774  // Here SectionFrames that are to be deleted must be ignored
1775  while( pFirst && pFirst->IsSctFrame() && !static_cast<SwSectionFrame*>(pFirst)->GetSection() )
1776  pFirst = pFirst->GetNext();
1777  if( pFirst && pFirst->IsSctFrame() && pSect->GetFollow() == pFirst )
1778  pNew = pSect->GetFollow();
1779  else if( MAKEPAGE_NOSECTION == eMakePage )
1780  return pLayLeaf;
1781  else if (pSect->GetSection())
1782  {
1783  pNew = new SwSectionFrame( *pSect, false );
1784  pNew->InsertBefore( pLayLeaf, pLayLeaf->Lower() );
1785  pNew->Init();
1786  SwRectFnSet aRectFnSet(pNew);
1787  aRectFnSet.MakePos( *pNew, pLayLeaf, nullptr, true );
1788 
1789 #ifndef NDEBUG
1790  { // sanity check the parents of the new frame vs. the old frame
1791  SwFrame * pTmp = pNew;
1792  auto iter(parents.begin());
1793  if (parents.size() >= 2 &&
1794  parents[0]->IsBodyFrame() && parents[1]->IsColumnFrame())
1795  { // this only inserts section frame - remove column
1796  assert(parents[2]->IsSctFrame() || IsSctFrame());
1797  if (parents[2]->IsSctFrame())
1798  std::advance(iter, +2);
1799  else
1800  pTmp = pTmp->GetUpper();
1801  }
1802  else if (IsBodyFrame() && parents.size() >= 1
1803  && parents[0]->IsColumnFrame())
1804  { // same as above, special case: "this" is the body frame
1805  assert(parents[1]->IsSctFrame());
1806  std::advance(iter, +1);
1807  }
1808  else if (IsSctFrame()) // special case: "this" is the section
1809  {
1810  pTmp = pTmp->GetUpper();
1811  }
1812 
1813  for ( ; iter != parents.end(); ++iter)
1814  {
1815  if (pTmp->IsPageFrame())
1816  {
1817  if ((*iter)->IsColumnFrame() &&
1818  (iter + 1) != parents.end() && (*(iter + 1))->IsBodyFrame())
1819  { // page style has columns - evidently these are
1820  break; // added later?
1821  }
1822  assert(!pTmp->IsPageFrame());
1823  }
1824  assert(pTmp->GetType() == (*iter)->GetType());
1825  // for cell frames and table frames:
1826  // 1) there may be multiple follow frames of the old one
1827  // 2) the new frame may be identical to the old one
1828  // (not sure if this is allowed, but it happens now
1829  // for the outer table of a nested table)
1830  if (pTmp->IsCellFrame())
1831  {
1832  SwCellFrame const*const pNewF(static_cast<SwCellFrame*>(pTmp));
1833  SwCellFrame const*const pOldF(static_cast<SwCellFrame*>(*iter));
1834  bool bFollowFound(false);
1835  for (SwCellFrame const* pOldIter = pOldF;
1836  pOldIter; pOldIter = pOldIter->GetFollowCell())
1837  {
1838  if (pOldIter == pNewF)
1839  {
1840  bFollowFound = true;
1841  break;
1842  }
1843  }
1844  assert(bFollowFound);
1845  }
1846  else if (pTmp->IsFlowFrame())
1847  {
1848  SwFlowFrame const*const pNewF(SwFlowFrame::CastFlowFrame(pTmp));
1849  SwFlowFrame const*const pOldF(SwFlowFrame::CastFlowFrame(*iter));
1850  bool bFollowFound(false);
1851  for (SwFlowFrame const* pOldIter = pOldF;
1852  pOldIter; pOldIter = pOldIter->GetFollow())
1853  {
1854  if (pOldIter == pNewF)
1855  {
1856  bFollowFound = true;
1857  break;
1858  }
1859  }
1860  assert(bFollowFound);
1861  }
1862  pTmp = pTmp->GetUpper();
1863  }
1864  assert(pTmp == nullptr /* SwFlyAtContentFrame case */
1865  || pTmp->IsPageFrame() // usual case
1866  // the new page has columns, but the old page did not
1867  || (pTmp->IsColumnFrame() && pTmp->GetUpper()->IsBodyFrame()
1868  && pTmp->GetUpper()->GetUpper()->IsPageFrame()));
1869  }
1870 #endif
1871 
1872  // If our section frame has a successor then that has to be
1873  // moved behind the new Follow of the section frames
1874  SwFrame* pTmp = pSect->GetNext();
1875  if( pTmp && pTmp != pSect->GetFollow() )
1876  {
1877  SwFlowFrame* pNxt;
1878  SwContentFrame* pNxtContent = nullptr;
1879  if( pTmp->IsContentFrame() )
1880  {
1881  pNxt = static_cast<SwContentFrame*>(pTmp);
1882  pNxtContent = static_cast<SwContentFrame*>(pTmp);
1883  }
1884  else
1885  {
1886  pNxtContent = static_cast<SwLayoutFrame*>(pTmp)->ContainsContent();
1887  if( pTmp->IsSctFrame() )
1888  pNxt = static_cast<SwSectionFrame*>(pTmp);
1889  else
1890  {
1891  assert(pTmp->IsTabFrame());
1892  pNxt = static_cast<SwTabFrame*>(pTmp);
1893  }
1894  while( !pNxtContent && nullptr != ( pTmp = pTmp->GetNext() ) )
1895  {
1896  if( pTmp->IsContentFrame() )
1897  pNxtContent = static_cast<SwContentFrame*>(pTmp);
1898  else
1899  pNxtContent = static_cast<SwLayoutFrame*>(pTmp)->ContainsContent();
1900  }
1901  }
1902  if( pNxtContent )
1903  {
1904  SwFootnoteBossFrame* pOldBoss = pSect->FindFootnoteBossFrame( true );
1905  if( pOldBoss == pNxtContent->FindFootnoteBossFrame( true ) )
1906  {
1907  SwSaveFootnoteHeight aHeight( pOldBoss,
1908  pOldBoss->getFrameArea().Top() + pOldBoss->getFrameArea().Height() );
1909  pSect->GetUpper()->MoveLowerFootnotes( pNxtContent, pOldBoss,
1910  pLayLeaf->FindFootnoteBossFrame( true ), false );
1911  }
1912  }
1913  pNxt->MoveSubTree( pLayLeaf, pNew->GetNext() );
1914  }
1915  if( pNew->GetFollow() )
1916  pNew->SimpleFormat();
1917  }
1918  // The wanted layout sheet is now the first of the determined SctFrames:
1919  pLayLeaf = pNew ? FirstLeaf(pNew) : nullptr;
1920  }
1921  return pLayLeaf;
1922 }
1923 
1926 {
1928 
1929  SwLayoutFrame* pCol;
1930  // ColumnFrame always contain a BodyFrame now
1931  if( IsColBodyFrame() )
1932  pCol = GetUpper();
1933  else if( GetUpper()->IsColBodyFrame() )
1934  pCol = GetUpper()->GetUpper();
1935  else
1936  pCol = nullptr;
1937  bool bJump = false;
1938  if( pCol )
1939  {
1940  if( pCol->GetPrev() )
1941  {
1942  do
1943  {
1944  pCol = static_cast<SwLayoutFrame*>(pCol->GetPrev());
1945  // Is there any content?
1946  if( static_cast<SwLayoutFrame*>(pCol->Lower())->Lower() )
1947  {
1948  if( bJump ) // Did we skip a blank page?
1950  return static_cast<SwLayoutFrame*>(pCol->Lower()); // The columnm body
1951  }
1952  bJump = true;
1953  } while( pCol->GetPrev() );
1954 
1955  // We get here when all columns are empty, pCol is now the
1956  // first column, we need the body though
1957  pCol = static_cast<SwLayoutFrame*>(pCol->Lower());
1958  }
1959  else
1960  pCol = nullptr;
1961  }
1962 
1963  if( bJump ) // Did we skip a blank page?
1965 
1966  SwSectionFrame *pSect = FindSctFrame();
1967  if (!pCol && pSect && IsInTab() && CanContainSplitSection(this))
1968  {
1969  // We don't have a previous section yet, and we're in a
1970  // section-in-table.
1971  if (SwFlowFrame* pPrecede = pSect->GetPrecede())
1972  {
1973  // Our section has a precede, work with that.
1974  if (pPrecede->GetFrame().IsLayoutFrame())
1975  pCol = static_cast<SwLayoutFrame*>(&pPrecede->GetFrame());
1976  }
1977  }
1978 
1979  // Within sections in tables or section in headers/footers there can
1980  // be only one column change be made, one of the above shortcuts should
1981  // have applied, also when the section has a pPrev.
1982  // Now we even consider an empty column...
1983  OSL_ENSURE( pSect, "GetNextSctLeaf: Missing SectionFrame" );
1984  if (!pSect || (IsInTab() && !IsTabFrame()) || FindFooterOrHeader())
1985  return pCol;
1986 
1987  // === IMPORTANT ===
1988  // Precondition, which needs to be hold, is that the <this> frame can be
1989  // inside a table, but then the found section frame <pSect> is also inside
1990  // this table.
1991 
1992  // #i95698#
1993  // A table cell containing directly a section does not break - see lcl_FindSectionsInRow(..)
1994  // Thus, a table inside a section, which is inside another table can only
1995  // flow backward in the columns of its section.
1996  // Note: The table cell, which contains the section, can not have a master table cell.
1997  if ( IsTabFrame() && pSect->IsInTab() )
1998  {
1999  return pCol;
2000  }
2001 
2002  {
2003  if (SwFrame *pPrv = pSect->GetIndPrev())
2004  {
2005  // Mooching, half dead SectionFrames shouldn't confuse us
2006  while( pPrv && pPrv->IsSctFrame() && !static_cast<SwSectionFrame*>(pPrv)->GetSection() )
2007  pPrv = pPrv->GetPrev();
2008  if( pPrv )
2009  return pCol;
2010  }
2011  }
2012 
2013  const bool bBody = IsInDocBody();
2014  const bool bFly = IsInFly();
2015 
2016  SwLayoutFrame *pLayLeaf = GetPrevLayoutLeaf();
2017  SwLayoutFrame *pPrevLeaf = nullptr;
2018 
2019  while ( pLayLeaf )
2020  {
2021  // Never step into tables or sections
2022  if ( pLayLeaf->IsInTab() || pLayLeaf->IsInSct() )
2023  {
2024  pLayLeaf = pLayLeaf->GetPrevLayoutLeaf();
2025  }
2026  else if ( bBody && pLayLeaf->IsInDocBody() )
2027  {
2028  // If there is a pLayLeaf has a lower pLayLeaf is the frame we are looking for.
2029  // Exception: pLayLeaf->Lower() is a zombie section frame
2030  const SwFrame* pTmp = pLayLeaf->Lower();
2031  // OD 11.04.2003 #108824# - consider, that the zombie section frame
2032  // can have frame below it in the found layout leaf.
2033  // Thus, skipping zombie section frame, if possible.
2034  while ( pTmp && pTmp->IsSctFrame() &&
2035  !( static_cast<const SwSectionFrame*>(pTmp)->GetSection() ) &&
2036  pTmp->GetNext()
2037  )
2038  {
2039  pTmp = pTmp->GetNext();
2040  }
2041  if ( pTmp &&
2042  ( !pTmp->IsSctFrame() ||
2043  ( static_cast<const SwSectionFrame*>(pTmp)->GetSection() )
2044  )
2045  )
2046  {
2047  break;
2048  }
2049  pPrevLeaf = pLayLeaf;
2050  pLayLeaf = pLayLeaf->GetPrevLayoutLeaf();
2051  if ( pLayLeaf )
2053  }
2054  else if ( bFly )
2055  break; // Contents in Flys every layout sheet should be right. Why?
2056  else
2057  pLayLeaf = pLayLeaf->GetPrevLayoutLeaf();
2058  }
2059  if( !pLayLeaf )
2060  {
2061  if( !pPrevLeaf )
2062  return pCol;
2063  pLayLeaf = pPrevLeaf;
2064  }
2065 
2066  SwSectionFrame* pNew = nullptr;
2067  // At first go to the end of the layout sheet
2068  SwFrame *pTmp = pLayLeaf->Lower();
2069  if( pTmp )
2070  {
2071  while( pTmp->GetNext() )
2072  pTmp = pTmp->GetNext();
2073  if( pTmp->IsSctFrame() )
2074  {
2075  // Half dead ones only interfere here
2076  while( !static_cast<SwSectionFrame*>(pTmp)->GetSection() && pTmp->GetPrev() &&
2077  pTmp->GetPrev()->IsSctFrame() )
2078  pTmp = pTmp->GetPrev();
2079  if( static_cast<SwSectionFrame*>(pTmp)->GetFollow() == pSect )
2080  pNew = static_cast<SwSectionFrame*>(pTmp);
2081  }
2082  }
2083  if( !pNew )
2084  {
2085  pNew = new SwSectionFrame( *pSect, true );
2086  pNew->InsertBefore( pLayLeaf, nullptr );
2087  pNew->Init();
2088  SwRectFnSet aRectFnSet(pNew);
2089  aRectFnSet.MakePos( *pNew, pLayLeaf, pNew->GetPrev(), true );
2090 
2091  pLayLeaf = FirstLeaf( pNew );
2092  if( !pNew->Lower() ) // Format single column sections
2093  {
2094  pNew->MakePos();
2095  pLayLeaf->Format(getRootFrame()->GetCurrShell()->GetOut()); // In order that the PrtArea is correct for the MoveBwd
2096  }
2097  else
2098  pNew->SimpleFormat();
2099  }
2100  else
2101  {
2102  pLayLeaf = FirstLeaf( pNew );
2103  if( pLayLeaf->IsColBodyFrame() )
2104  {
2105  // In existent section columns we're looking for the last not empty
2106  // column.
2107  SwLayoutFrame *pTmpLay = pLayLeaf;
2108  while( pLayLeaf->GetUpper()->GetNext() )
2109  {
2110  pLayLeaf = static_cast<SwLayoutFrame*>(static_cast<SwLayoutFrame*>(pLayLeaf->GetUpper()->GetNext())->Lower());
2111  if( pLayLeaf->Lower() )
2112  pTmpLay = pLayLeaf;
2113  }
2114  // If we skipped an empty column, we've to set the jump-flag
2115  if( pLayLeaf != pTmpLay )
2116  {
2117  pLayLeaf = pTmpLay;
2119  }
2120  }
2121  }
2122  return pLayLeaf;
2123 }
2124 
2125 static SwTwips lcl_DeadLine( const SwFrame* pFrame )
2126 {
2127  const SwLayoutFrame* pUp = pFrame->GetUpper();
2128  while( pUp && pUp->IsInSct() )
2129  {
2130  if( pUp->IsSctFrame() )
2131  pUp = pUp->GetUpper();
2132  // Columns now with BodyFrame
2133  else if( pUp->IsColBodyFrame() && pUp->GetUpper()->GetUpper()->IsSctFrame() )
2134  pUp = pUp->GetUpper()->GetUpper();
2135  else
2136  break;
2137  }
2138  SwRectFnSet aRectFnSet(pFrame);
2139  return pUp ? aRectFnSet.GetPrtBottom(*pUp) :
2140  aRectFnSet.GetBottom(pFrame->getFrameArea());
2141 }
2142 
2145 {
2146  SwRectFnSet aRectFnSet(this);
2147  if( aRectFnSet.YDiff( lcl_DeadLine( this ),
2148  aRectFnSet.GetBottom(getFrameArea()) ) > 0 )
2149  return true;
2150 
2151  return ( GetUpper() && const_cast<SwFrame*>(static_cast<SwFrame const *>(GetUpper()))->Grow( LONG_MAX, true ) );
2152 }
2153 
2155 {
2156  if ( !IsColLocked() && !HasFixSize() )
2157  {
2158  SwRectFnSet aRectFnSet(this);
2159  tools::Long nFrameHeight = aRectFnSet.GetHeight(getFrameArea());
2160  if( nFrameHeight > 0 && nDist > (LONG_MAX - nFrameHeight) )
2161  nDist = LONG_MAX - nFrameHeight;
2162 
2163  if ( nDist <= 0 )
2164  return 0;
2165 
2166  bool bInCalcContent = GetUpper() && IsInFly() && FindFlyFrame()->IsLocked();
2167  // OD 2004-03-15 #116561# - allow grow in online layout
2168  bool bGrow = !Lower() || !Lower()->IsColumnFrame() || !Lower()->GetNext();
2169  if (!bGrow)
2170  {
2171  SwSection* pSection = GetSection();
2172  bGrow = pSection && pSection->GetFormat()->GetBalancedColumns().GetValue();
2173  }
2174  if( !bGrow )
2175  {
2176  const SwViewShell *pSh = getRootFrame()->GetCurrShell();
2177  bGrow = pSh && pSh->GetViewOptions()->getBrowseMode();
2178  }
2179  if( bGrow )
2180  {
2181  SwTwips nGrow;
2182  if( IsInFootnote() )
2183  nGrow = 0;
2184  else
2185  {
2186  nGrow = lcl_DeadLine( this );
2187  nGrow = aRectFnSet.YDiff( nGrow, aRectFnSet.GetBottom(getFrameArea()) );
2188  }
2189  SwTwips nSpace = nGrow;
2190  if( !bInCalcContent && nGrow < nDist && GetUpper() )
2191  nGrow = o3tl::saturating_add(
2192  nGrow, GetUpper()->Grow( LONG_MAX, true ));
2193 
2194  if( nGrow > nDist )
2195  nGrow = nDist;
2196  if( nGrow <= 0 )
2197  {
2198  nGrow = 0;
2199  if (!bTst)
2200  {
2201  if( bInCalcContent )
2202  InvalidateSize_();
2203  else
2204  InvalidateSize();
2205  }
2206  }
2207  else if( !bTst )
2208  {
2209  if( bInCalcContent )
2210  InvalidateSize_();
2211  else if( nSpace < nGrow && nDist != nSpace + GetUpper()->
2212  Grow( nGrow - nSpace ) )
2213  InvalidateSize();
2214  else
2215  {
2216  const SvxGraphicPosition ePos =
2218  if ( GPOS_RT < ePos && GPOS_TILED != ePos )
2219  {
2220  SetCompletePaint();
2221  InvalidatePage();
2222  }
2223  if( GetUpper() && GetUpper()->IsHeaderFrame() )
2224  GetUpper()->InvalidateSize();
2225  }
2226 
2227  {
2229  aRectFnSet.AddBottom( aFrm, nGrow );
2230  }
2231 
2232  {
2233  const tools::Long nPrtHeight = aRectFnSet.GetHeight(getFramePrintArea()) + nGrow;
2235  aRectFnSet.SetHeight( aPrt, nPrtHeight );
2236  }
2237 
2238  if( Lower() && Lower()->IsColumnFrame() && Lower()->GetNext() )
2239  {
2240  SwFrame* pTmp = Lower();
2241  do
2242  {
2243  pTmp->InvalidateSize_();
2244  pTmp = pTmp->GetNext();
2245  } while ( pTmp );
2246  InvalidateSize_();
2247  }
2248  if( GetNext() )
2249  {
2250  // Own height changed, need to invalidate the position of
2251  // next frames.
2252  SwFrame *pFrame = GetNext();
2253  while( pFrame && pFrame->IsSctFrame() && !static_cast<SwSectionFrame*>(pFrame)->GetSection() )
2254  {
2255  // Invalidate all in-between frames, otherwise position
2256  // calculation (which only looks back to one relative
2257  // frame) will have an incorrect result.
2258  InvalidateFramePos(pFrame, bInCalcContent);
2259  pFrame = pFrame->GetNext();
2260  }
2261  if( pFrame )
2262  {
2263  InvalidateFramePos(pFrame, bInCalcContent);
2264  }
2265  }
2266  // #i28701# - Due to the new object positioning
2267  // the frame on the next page/column can flow backward (e.g. it
2268  // was moved forward due to the positioning of its objects ).
2269  // Thus, invalivate this next frame, if document compatibility
2270  // option 'Consider wrapping style influence on object positioning' is ON.
2271  else if ( GetFormat()->getIDocumentSettingAccess().get(DocumentSettingId::CONSIDER_WRAP_ON_OBJECT_POSITION) )
2272  {
2274  }
2275  }
2276  return nGrow;
2277  }
2278  if ( !bTst )
2279  {
2280  if( bInCalcContent )
2281  InvalidateSize_();
2282  else
2283  InvalidateSize();
2284  }
2285  }
2286  return 0;
2287 }
2288 
2290 {
2291  if ( Lower() && !IsColLocked() && !HasFixSize() )
2292  {
2293  if( ToMaximize( false ) )
2294  {
2295  if( !bTst )
2296  InvalidateSize();
2297  }
2298  else
2299  {
2300  SwRectFnSet aRectFnSet(this);
2301  tools::Long nFrameHeight = aRectFnSet.GetHeight(getFrameArea());
2302  if ( nDist > nFrameHeight )
2303  nDist = nFrameHeight;
2304 
2305  if ( Lower()->IsColumnFrame() && Lower()->GetNext() && // FootnoteAtEnd
2306  !GetSection()->GetFormat()->GetBalancedColumns().GetValue() )
2307  { // With column bases the format takes over the control of the
2308  // growth (because of the balance)
2309  if ( !bTst )
2310  InvalidateSize();
2311  return nDist;
2312  }
2313  else if( !bTst )
2314  {
2315  const SvxGraphicPosition ePos =
2317  if ( GPOS_RT < ePos && GPOS_TILED != ePos )
2318  {
2319  SetCompletePaint();
2320  InvalidatePage();
2321  }
2322 
2323  {
2325  aRectFnSet.AddBottom( aFrm, -nDist );
2326  }
2327 
2328  {
2329  const tools::Long nPrtHeight = aRectFnSet.GetHeight(getFramePrintArea()) - nDist;
2331  aRectFnSet.SetHeight( aPrt, nPrtHeight );
2332  }
2333 
2334  // We do not allow a section frame to shrink the its upper
2335  // footer frame. This is because in the calculation of a
2336  // footer frame, the content of the section frame is _not_
2337  // calculated. If there is a fly frame overlapping with the
2338  // footer frame, the section frame is not affected by this
2339  // during the calculation of the footer frame size.
2340  // The footer frame does not grow in its FormatSize function
2341  // but during the calculation of the content of the section
2342  // frame. The section frame grows until some of its text is
2343  // located on top of the fly frame. The next call of CalcContent
2344  // tries to shrink the section and here it would also shrink
2345  // the footer. This may not happen, because shrinking the footer
2346  // would cause the top of the section frame to overlap with the
2347  // fly frame again, this would result in a perfect loop.
2348  if( GetUpper() && !GetUpper()->IsFooterFrame() )
2349  GetUpper()->Shrink( nDist, bTst );
2350 
2351  if( Lower() && Lower()->IsColumnFrame() && Lower()->GetNext() )
2352  {
2353  SwFrame* pTmp = Lower();
2354  do
2355  {
2356  pTmp->InvalidateSize_();
2357  pTmp = pTmp->GetNext();
2358  } while ( pTmp );
2359  }
2360  if( GetNext() )
2361  {
2362  SwFrame* pFrame = GetNext();
2363  while( pFrame && pFrame->IsSctFrame() && !static_cast<SwSectionFrame*>(pFrame)->GetSection() )
2364  pFrame = pFrame->GetNext();
2365  if( pFrame )
2366  pFrame->InvalidatePos();
2367  else
2368  SetRetouche();
2369  }
2370  else
2371  SetRetouche();
2372  return nDist;
2373  }
2374  }
2375  }
2376  return 0;
2377 }
2378 
2379 /*
2380 |* When are Frames within a SectionFrames moveable?
2381 |* If they are not in the last column of a SectionFrames yet,
2382 |* if there is no Follow,
2383 |* if the SectionFrame cannot grow anymore, then it gets more complicated,
2384 |* in that case it depends on whether the SectionFrame can find a next
2385 |* layout sheet. In (column based/chained) Flys this is checked via
2386 |* GetNextLayout, in tables and headers/footers there is none, however in the
2387 |* DocBody and in foot notes there is always one.
2388 |*
2389 |* This routine is used in the TextFormatter to decided whether it's allowed to
2390 |* create a (paragraph-)Follow or whether the paragraph has to stick together
2391 |*/
2392 bool SwSectionFrame::MoveAllowed( const SwFrame* pFrame) const
2393 {
2394  // Is there a Follow or is the Frame not in the last column?
2395  if( HasFollow() || ( pFrame->GetUpper()->IsColBodyFrame() &&
2396  pFrame->GetUpper()->GetUpper()->GetNext() ) )
2397  return true;
2398  if( pFrame->IsInFootnote() )
2399  {
2400  if( IsInFootnote() )
2401  {
2402  if( GetUpper()->IsInSct() )
2403  {
2404  if( Growable() )
2405  return false;
2406  return GetUpper()->FindSctFrame()->MoveAllowed( this );
2407  }
2408  else
2409  return true;
2410  }
2411  // The content of footnote inside a columned sectionfrm is moveable
2412  // except in the last column
2413  const SwLayoutFrame *pLay = pFrame->FindFootnoteFrame()->GetUpper()->GetUpper();
2414  if( pLay->IsColumnFrame() && pLay->GetNext() )
2415  {
2416  // The first paragraph in the first footnote in the first column
2417  // in the sectionfrm at the top of the page is not moveable,
2418  // if the columnbody is empty.
2419  bool bRet = false;
2420  if( pLay->GetIndPrev() || pFrame->GetIndPrev() ||
2421  pFrame->FindFootnoteFrame()->GetPrev() )
2422  bRet = true;
2423  else
2424  {
2425  const SwLayoutFrame* pBody = static_cast<const SwColumnFrame*>(pLay)->FindBodyCont();
2426  if( pBody && pBody->Lower() )
2427  bRet = true;
2428  }
2429  if( bRet && ( IsFootnoteAtEnd() || !Growable() ) )
2430  return true;
2431  }
2432  }
2433  // Or can the section still grow?
2434  if( !IsColLocked() && Growable() )
2435  return false;
2436  // Now it has to be examined whether there is a layout sheet wherein
2437  // a section Follow can be created
2438  if( !CanContainSplitSection(this) || ( !IsInDocBody() && FindFooterOrHeader() ) )
2439  return false; // It doesn't work in table-in-sections/nested tables/headers/footers
2440  if( IsInFly() ) // In column based or chained frames
2441  return nullptr != const_cast<SwFrame*>(static_cast<SwFrame const *>(GetUpper()))->GetNextLeaf( MAKEPAGE_NONE );
2442  return true;
2443 }
2444 
2453 {
2454  SwFrame *pRet = nullptr;
2455  // #i79774#
2456  // Do not assert, if the frame has a direct previous frame, because it
2457  // could be an empty section frame. The caller has to assure, that the
2458  // frame has no direct previous frame or only empty section frames as
2459  // previous frames.
2460  OSL_ENSURE( IsInSct(), "Why?" );
2461  const SwFrame* pSct = GetUpper();
2462  if( !pSct )
2463  return nullptr;
2464  if( pSct->IsSctFrame() )
2465  pRet = pSct->GetIndPrev();
2466  else if( pSct->IsColBodyFrame() && (pSct = pSct->GetUpper()->GetUpper())->IsSctFrame() )
2467  {
2468  // Do not return the previous frame of the outer section, if in one
2469  // of the previous columns is content.
2470  const SwFrame* pCol = GetUpper()->GetUpper()->GetPrev();
2471  while( pCol )
2472  {
2473  assert(pCol->IsColumnFrame());
2474  assert(pCol->GetLower() && pCol->GetLower()->IsBodyFrame());
2475  if( static_cast<const SwLayoutFrame*>(static_cast<const SwLayoutFrame*>(pCol)->Lower())->Lower() )
2476  return nullptr;
2477  pCol = pCol->GetPrev();
2478  }
2479  pRet = pSct->GetIndPrev();
2480  }
2481 
2482  // skip empty section frames
2483  while( pRet && pRet->IsSctFrame() && !static_cast<SwSectionFrame*>(pRet)->GetSection() )
2484  pRet = pRet->GetIndPrev();
2485  return pRet;
2486 }
2487 
2489 {
2490  OSL_ENSURE( !mpNext && IsInSct(), "Why?" );
2491  SwFrame* pSct = GetUpper();
2492  if( !pSct )
2493  return nullptr;
2494  if( pSct->IsSctFrame() )
2495  return pSct->GetIndNext();
2496  if( pSct->IsColBodyFrame() && (pSct = pSct->GetUpper()->GetUpper())->IsSctFrame() )
2497  { // We can only return the successor of the SectionFrames if there is no
2498  // content in the successive columns
2499  SwFrame* pCol = GetUpper()->GetUpper()->GetNext();
2500  while( pCol )
2501  {
2502  assert(pCol->IsColumnFrame());
2503  assert(pCol->GetLower() && pCol->GetLower()->IsBodyFrame());
2504  if( static_cast<SwLayoutFrame*>(static_cast<SwLayoutFrame*>(pCol)->Lower())->Lower() )
2505  return nullptr;
2506  pCol = pCol->GetNext();
2507  }
2508  return pSct->GetIndNext();
2509  }
2510  return nullptr;
2511 }
2512 
2514 {
2515  if( !m_pSection || !pFormat )
2516  return false;
2517  const SwSectionFormat *pMyFormat = m_pSection->GetFormat();
2518  while( pFormat != pMyFormat )
2519  {
2520  if( auto pNewFormat = dynamic_cast< const SwSectionFormat *>( pMyFormat->GetRegisteredIn()) )
2521  pMyFormat = pNewFormat;
2522  else
2523  return false;
2524  }
2525  return true;
2526 }
2527 
2529 {
2530  SwSectionFormat *pFormat = GetSection()->GetFormat();
2531  sal_uInt16 nVal = pFormat->GetFootnoteAtTextEnd( false ).GetValue();
2535  while( !m_bFootnoteAtEnd && !m_bOwnFootnoteNum )
2536  {
2537  if( auto pNewFormat = dynamic_cast<SwSectionFormat *>( pFormat->GetRegisteredIn()) )
2538  pFormat = pNewFormat;
2539  else
2540  break;
2541  nVal = pFormat->GetFootnoteAtTextEnd( false ).GetValue();
2542  if( FTNEND_ATPGORDOCEND != nVal )
2543  {
2544  m_bFootnoteAtEnd = true;
2547  }
2548  }
2549 }
2550 
2552 {
2553  return m_pSection->GetFormat()->GetEndAtTextEnd( false ).IsAtEnd();
2554 }
2555 
2557 {
2558  SwSectionFormat *pFormat = GetSection()->GetFormat();
2559  m_bEndnAtEnd = pFormat->GetEndAtTextEnd( false ).IsAtEnd();
2560  while( !m_bEndnAtEnd )
2561  {
2562  if( auto pNewFormat = dynamic_cast<SwSectionFormat *>( pFormat->GetRegisteredIn()) )
2563  pFormat = pNewFormat;
2564  else
2565  break;
2566  m_bEndnAtEnd = pFormat->GetEndAtTextEnd( false ).IsAtEnd();
2567  }
2568 }
2569 
2570 void SwSectionFrame::SwClientNotify(const SwModify& rMod, const SfxHint& rHint)
2571 {
2572  if (rHint.GetId() == SfxHintId::SwLegacyModify)
2573  {
2574  auto pLegacy = static_cast<const sw::LegacyModifyHint*>(&rHint);
2576  if(pLegacy->m_pNew && RES_ATTRSET_CHG == pLegacy->m_pNew->Which())
2577  {
2578  auto& rOldSetChg = *static_cast<const SwAttrSetChg*>(pLegacy->m_pOld);
2579  auto& rNewSetChg = *static_cast<const SwAttrSetChg*>(pLegacy->m_pNew);
2580  SfxItemIter aOIter(*rOldSetChg.GetChgSet());
2581  SfxItemIter aNIter(*rNewSetChg.GetChgSet());
2582  const SfxPoolItem* pOItem = aOIter.GetCurItem();
2583  const SfxPoolItem* pNItem = aNIter.GetCurItem();
2584  SwAttrSetChg aOldSet(rOldSetChg);
2585  SwAttrSetChg aNewSet(rNewSetChg);
2586  do
2587  {
2588  UpdateAttr_(pOItem, pNItem, eInvFlags, &aOldSet, &aNewSet);
2589  pNItem = aNIter.NextItem();
2590  pOItem = aOIter.NextItem();
2591  } while (pNItem);
2592  if(aOldSet.Count() || aNewSet.Count())
2593  SwLayoutFrame::SwClientNotify(rMod, sw::LegacyModifyHint(&aOldSet, &aNewSet));
2594  }
2595  else
2596  UpdateAttr_(pLegacy->m_pOld, pLegacy->m_pNew, eInvFlags);
2597 
2598  if (eInvFlags != SwSectionFrameInvFlags::NONE)
2599  {
2601  InvalidateSize();
2603  SetCompletePaint();
2604  }
2605  }
2606  else if(const auto pHint = dynamic_cast<const SwSectionFrameMoveAndDeleteHint*>(&rHint))
2607  {
2608  // #i117863#
2609  if(&rMod != GetDep())
2610  return;
2611  SwSectionFrame::MoveContentAndDelete(this, pHint->IsSaveContent());
2612  }
2613  else
2614  SwFrame::SwClientNotify(rMod, rHint);
2615 }
2616 
2617 void SwSectionFrame::UpdateAttr_( const SfxPoolItem *pOld, const SfxPoolItem *pNew,
2618  SwSectionFrameInvFlags &rInvFlags,
2619  SwAttrSetChg *pOldSet, SwAttrSetChg *pNewSet )
2620 {
2621  bool bClear = true;
2622  const sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
2623  switch( nWhich )
2624  { // Suppress multi columns in foot notes
2625  case RES_FMT_CHG:
2626  {
2627  const SwFormatCol& rNewCol = GetFormat()->GetCol();
2628  if( !IsInFootnote() )
2629  {
2630  // Nasty case. When allocating a template we can not count
2631  // on the old column attribute. We're left with creating a
2632  // temporary attribute here.
2633  SwFormatCol aCol;
2634  if ( Lower() && Lower()->IsColumnFrame() )
2635  {
2636  sal_uInt16 nCol = 0;
2637  SwFrame *pTmp = Lower();
2638  do
2639  { ++nCol;
2640  pTmp = pTmp->GetNext();
2641  } while ( pTmp );
2642  aCol.Init( nCol, 0, 1000 );
2643  }
2644  bool bChgFootnote = IsFootnoteAtEnd();
2645  bool const bChgEndn = IsEndnAtEnd();
2646  bool const bChgMyEndn = IsEndnoteAtMyEnd();
2648  CalcEndAtEndFlag();
2649  bChgFootnote = ( bChgFootnote != IsFootnoteAtEnd() ) ||
2650  ( bChgEndn != IsEndnAtEnd() ) ||
2651  ( bChgMyEndn != IsEndnoteAtMyEnd() );
2652  ChgColumns( aCol, rNewCol, bChgFootnote );
2654  }
2656  bClear = false;
2657  }
2658  break;
2659 
2660  case RES_COL:
2661  if( !IsInFootnote() )
2662  {
2663  assert(pOld && pNew);
2664  if (pOld && pNew)
2665  {
2666  ChgColumns( *static_cast<const SwFormatCol*>(pOld), *static_cast<const SwFormatCol*>(pNew) );
2668  }
2669  }
2670  break;
2671 
2672  case RES_FTN_AT_TXTEND:
2673  if( !IsInFootnote() )
2674  {
2675  bool const bOld = IsFootnoteAtEnd();
2677  if (bOld != IsFootnoteAtEnd())
2678  {
2679  const SwFormatCol& rNewCol = GetFormat()->GetCol();
2680  ChgColumns( rNewCol, rNewCol, true );
2682  }
2683  }
2684  break;
2685 
2686  case RES_END_AT_TXTEND:
2687  if( !IsInFootnote() )
2688  {
2689  bool const bOld = IsEndnAtEnd();
2690  bool const bMyOld = IsEndnoteAtMyEnd();
2691  CalcEndAtEndFlag();
2692  if (bOld != IsEndnAtEnd() || bMyOld != IsEndnoteAtMyEnd())
2693  {
2694  const SwFormatCol& rNewCol = GetFormat()->GetCol();
2695  ChgColumns( rNewCol, rNewCol, true );
2697  }
2698  }
2699  break;
2700  case RES_COLUMNBALANCE:
2702  break;
2703 
2704  case RES_FRAMEDIR :
2705  SetDerivedR2L( false );
2706  CheckDirChange();
2707  break;
2708 
2709  case RES_PROTECT:
2710  {
2712  if( pSh && pSh->GetLayout()->IsAnyShellAccessible() )
2713  pSh->Imp()->InvalidateAccessibleEditableState( true, this );
2714  }
2715  break;
2716 
2717  default:
2718  bClear = false;
2719  }
2720  if ( !bClear )
2721  return;
2722 
2723  if ( pOldSet || pNewSet )
2724  {
2725  if ( pOldSet )
2726  pOldSet->ClearItem( nWhich );
2727  if ( pNewSet )
2728  pNewSet->ClearItem( nWhich );
2729  }
2730  else
2731  {
2732  SwModify aMod;
2734  }
2735 }
2736 
2738 bool SwSectionFrame::ToMaximize( bool bCheckFollow ) const
2739 {
2740  if( HasFollow() )
2741  {
2742  if( !bCheckFollow ) // Don't check superfluous follows
2743  return true;
2744  const SwSectionFrame* pFoll = GetFollow();
2745  while( pFoll && pFoll->IsSuperfluous() )
2746  pFoll = pFoll->GetFollow();
2747  if( pFoll )
2748  return true;
2749  }
2750  if( IsFootnoteAtEnd() )
2751  return false;
2752  const SwFootnoteContFrame* pCont = ContainsFootnoteCont();
2753  if( !IsEndnAtEnd() )
2754  return nullptr != pCont;
2755  bool bRet = false;
2756  while( pCont && !bRet )
2757  {
2758  if( pCont->FindFootNote() )
2759  bRet = true;
2760  else
2761  pCont = ContainsFootnoteCont( pCont );
2762  }
2763  return bRet;
2764 }
2765 
2768 {
2769  SwFootnoteContFrame* pRet = nullptr;
2770  const SwLayoutFrame* pLay;
2771  if( pCont )
2772  {
2773  pLay = pCont->FindFootnoteBossFrame();
2774  OSL_ENSURE( IsAnLower( pLay ), "ContainsFootnoteCont: Wrong FootnoteContainer" );
2775  pLay = static_cast<const SwLayoutFrame*>(pLay->GetNext());
2776  }
2777  else if( Lower() && Lower()->IsColumnFrame() )
2778  pLay = static_cast<const SwLayoutFrame*>(Lower());
2779  else
2780  pLay = nullptr;
2781  while ( !pRet && pLay )
2782  {
2783  if( pLay->Lower() && pLay->Lower()->GetNext() )
2784  {
2785  OSL_ENSURE( pLay->Lower()->GetNext()->IsFootnoteContFrame(),
2786  "ToMaximize: Unexpected Frame" );
2787  pRet = const_cast<SwFootnoteContFrame*>(static_cast<const SwFootnoteContFrame*>(pLay->Lower()->GetNext()));
2788  }
2789  OSL_ENSURE( !pLay->GetNext() || pLay->GetNext()->IsLayoutFrame(),
2790  "ToMaximize: ColFrame expected" );
2791  pLay = static_cast<const SwLayoutFrame*>(pLay->GetNext());
2792  }
2793  return pRet;
2794 }
2795 
2797 {
2799  if( pCont )
2800  {
2801  SwFrame *pTmp = pCont->ContainsContent();
2802  if( pTmp )
2803  pTmp->InvalidatePos_();
2804  }
2805 }
2806 
2808 {
2809  SwRectFnSet aRectFnSet(this);
2810  return InnerHeight() - aRectFnSet.GetHeight(getFramePrintArea());
2811 }
2812 
2814 {
2815  const auto nRet = CalcUndersize();
2816  m_bUndersized = (nRet > 0);
2817  return nRet <= 0 ? 0 : nRet;
2818 }
2819 
2821 {
2822  vcl::RenderContext* pRenderContext = getRootFrame()->GetCurrShell()->GetOut();
2824  if( !pCont )
2825  return;
2826 
2827  SwFrame* pFrame = pCont->ContainsAny();
2828  if( pFrame )
2829  pCont->Calc(pRenderContext);
2830  while( pFrame && IsAnLower( pFrame ) )
2831  {
2832  SwFootnoteFrame* pFootnote = pFrame->FindFootnoteFrame();
2833  if( pFootnote )
2834  pFootnote->Calc(pRenderContext);
2835  pFrame->Calc(pRenderContext);
2836  if( pFrame->IsSctFrame() )
2837  {
2838  SwFrame *pTmp = static_cast<SwSectionFrame*>(pFrame)->ContainsAny();
2839  if( pTmp )
2840  {
2841  pFrame = pTmp;
2842  continue;
2843  }
2844  }
2845  pFrame = pFrame->FindNext();
2846  }
2847 }
2848 
2849 /*
2850  * If a SectionFrame gets empty, e.g. because its content changes the page/column,
2851  * it is not destroyed immediately (there could be a pointer left to it on the
2852  * stack), instead it puts itself in a list at the RootFrame, which is processed
2853  * later on (in Layaction::Action among others). Its size is set to Null and
2854  * the pointer to its page as well. Such SectionFrames that are to be deleted
2855  * must be ignored by the layout/during formatting.
2856  *
2857  * With InsertEmptySct the RootFrame stores a SectionFrame in the list,
2858  * with RemoveFromList it can be removed from the list (Dtor),
2859  * with DeleteEmptySct the list is processed and the SectionFrames are destroyed.
2860  */
2862 {
2863  if( !mpDestroy )
2864  mpDestroy.reset( new SwDestroyList );
2865  mpDestroy->insert( pDel );
2866 }
2867 
2869 {
2870  assert(mpDestroy);
2871  while( !mpDestroy->empty() )
2872  {
2873  SwSectionFrame* pSect = *mpDestroy->begin();
2874  mpDestroy->erase( mpDestroy->begin() );
2875  OSL_ENSURE( !pSect->IsColLocked() && !pSect->IsJoinLocked(),
2876  "DeleteEmptySct: Locked SectionFrame" );
2877  if( !pSect->getFrameArea().HasArea() && !pSect->ContainsContent() )
2878  {
2879  SwLayoutFrame* pUp = pSect->GetUpper();
2880  pSect->RemoveFromLayout();
2881  SwFrame::DestroyFrame(pSect);
2882  if( pUp && !pUp->Lower() )
2883  {
2884  if( pUp->IsPageBodyFrame() )
2885  pUp->getRootFrame()->SetSuperfluous();
2886  else if( pUp->IsFootnoteFrame() && !pUp->IsColLocked() &&
2887  pUp->GetUpper() )
2888  {
2889  pUp->Cut();
2890  SwFrame::DestroyFrame(pUp);
2891  }
2892  }
2893  }
2894  else {
2895  OSL_ENSURE( pSect->GetSection(), "DeleteEmptySct: Half-dead SectionFrame?!" );
2896  }
2897  }
2898 }
2899 
2901 {
2902  assert(mpDestroy && "Where's my list?");
2903  mpDestroy->erase( pSct );
2904 }
2905 
2906 #ifdef DBG_UTIL
2908 {
2909  return mpDestroy && mpDestroy->find( pSct ) != mpDestroy->end();
2910 }
2911 #endif
2912 
2914 {
2915  bool bRet = false;
2916  if ( GetSection() && Lower() && Lower()->IsColumnFrame() && Lower()->GetNext() )
2917  {
2918  bRet = !GetSection()->GetFormat()->GetBalancedColumns().GetValue();
2919  }
2920  return bRet;
2921 }
2922 
2923 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void InsertBefore(SwLayoutFrame *pParent, SwFrame *pBehind)
Insert SwFrame into existing structure.
Definition: wsfrm.cxx:830
bool IsAnLower(const SwFrame *) const
Definition: findfrm.cxx:207
vcl::RenderContext * GetOut() const
Definition: viewsh.hxx:338
bool GetValue() const
SwFrame * FindFooterOrHeader()
Definition: findfrm.cxx:548
SwSectionFrame * FindMaster() const
Definition: flowfrm.cxx:754
constexpr TypedWhichId< SvxProtectItem > RES_PROTECT(100)
Base class of the Writer layout elements.
Definition: frame.hxx:315
Base class that provides the general functionalities for frames that are allowed at page breaks (flow...
Definition: flowfrm.hxx:58
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:158
constexpr TypedWhichId< SvxFrameDirectionItem > RES_FRAMEDIR(120)
constexpr TypedWhichId< SwFormatEndAtTextEnd > RES_END_AT_TXTEND(118)
void InvalidateInfFlags()
Definition: frame.hxx:609
static void lcl_InvalidateInfFlags(SwFrame *pFrame, bool bInva)
|* MoveContent is called for destroying a SectionFrames, due to |* the cancellation or hiding of a se...
Definition: sectfrm.cxx:561
void CalcFootnoteAtEndFlag()
Definition: sectfrm.cxx:2528
virtual void SwClientNotify(const SwModify &, const SfxHint &) override
Definition: sectfrm.cxx:2570
bool MoveAllowed(const SwFrame *) const
Definition: sectfrm.cxx:2392
bool IsFollow() const
Definition: flowfrm.hxx:166
SwTwips Shrink_(SwTwips, bool bTst)
Definition: sectfrm.cxx:2289
const SwSortedObjs * GetDrawObjs() const
Definition: frame.hxx:565
void RemoveFromList(SwSectionFrame *pSct)
Definition: rootfrm.hxx:382
const SwFormatCol & GetCol(bool=true) const
Definition: fmtclds.hxx:168
SwFrame * mpNext
Definition: frame.hxx:339
bool IsEndnAtEnd() const
Definition: sectfrm.hxx:157
bool IsInDocBody() const
Definition: frame.hxx:944
bool IsInFly() const
Definition: frame.hxx:962
virtual ~SwSectionFrame() override
Definition: sectfrm.cxx:182
SwTwips Grow(SwTwips, bool bTst=false, bool bInfo=false)
Definition: wsfrm.cxx:1503
SwFindMode
Definition: sectfrm.hxx:31
bool IsInSct() const
Definition: frame.hxx:968
virtual void Format(vcl::RenderContext *pRenderContext, const SwBorderAttrs *pAttrs=nullptr) override
"Formats" the Frame; Frame and PrtArea.
Definition: wsfrm.cxx:3411
static void SetMoveBwdJump(bool bNew)
Definition: flowfrm.hxx:155
tools::Long BottomDist(const SwRect &rRect, tools::Long nPos) const
Definition: frame.hxx:1415
bool IsAnyShellAccessible() const
Definition: rootfrm.hxx:390
SwViewShellImp * Imp()
Definition: viewsh.hxx:182
void DelEmpty(bool bRemove)
Definition: sectfrm.cxx:186
const SvxBrushItem & GetBackground(bool=true) const
Definition: frmatr.hxx:58
virtual void Format(vcl::RenderContext *pRenderContext, const SwBorderAttrs *pAttrs=nullptr) override
"formats" the frame; Frame and PrtArea
Definition: sectfrm.cxx:1334
constexpr TypedWhichId< SwFormatChg > RES_FMT_CHG(162)
void ColLock()
Definition: sectfrm.hxx:95
std::string GetValue
bool IsColLocked() const
Definition: frame.hxx:887
bool SplitSect(SwFrame *pFrame, bool bApres)
Splits the SectionFrame surrounding the pFrame up in two parts: pFrame and the start of the 2nd part...
Definition: sectfrm.cxx:511
constexpr TypedWhichId< SwFormatCol > RES_COL(109)
bool IsBefore(const SwLayoutFrame *_pCheckRefLayFrame) const
method to check relative position of layout frame to a given layout frame.
Definition: findfrm.cxx:234
void InvalidateFootnotePos()
Definition: sectfrm.cxx:2796
SwSectionFrameInvFlags
Definition: sectfrm.hxx:36
void SetCompletePaint() const
Definition: frame.hxx:995
bool IsInFootnote() const
Definition: frame.hxx:950
virtual bool Prepare(const PrepareHint ePrep=PrepareHint::Clear, const void *pVoid=nullptr, bool bNotify=true)
Definition: wsfrm.cxx:597
void FormatWidthCols(const SwBorderAttrs &, const SwTwips nBorder, const SwTwips nMinHeight)
Called by Format for Frames and Areas with columns.
Definition: wsfrm.cxx:3676
SwFrameType GetType() const
Definition: frame.hxx:520
void SetDerivedR2L(bool bNew)
Definition: frame.hxx:633
#define PROTOCOL(pFrame, nFunc, nAct, pPar)
Definition: dbg_lay.hxx:88
-""- and with own numberformat
Definition: fmtftntx.hxx:33
long Long
tools::Long GetRight() const
const SwRect & getFramePrintArea() const
Definition: frame.hxx:181
#define MINLAY
Definition: swtypes.hxx:63
SwTabFrame is one table in the document layout, containing rows (which contain cells).
Definition: tabfrm.hxx:46
void InvalidateSize_()
Definition: frame.hxx:772
SwFrame * FindPrev()
Definition: frame.hxx:1156
bool HasFollow() const
Definition: flowfrm.hxx:165
void InvalidatePos()
Definition: frame.hxx:1044
void UpdateAttr_(const SfxPoolItem *, const SfxPoolItem *, SwSectionFrameInvFlags &, SwAttrSetChg *pa=nullptr, SwAttrSetChg *pb=nullptr)
Definition: sectfrm.cxx:2617
void Cut_(bool bRemove)
Definition: sectfrm.cxx:257
bool IsSuperfluous() const
Definition: sectfrm.hxx:61
SwTwips Undersize()
Returns the size delta that the section would like to be greater if it has undersized TextFrames in i...
Definition: sectfrm.cxx:2813
bool IsVert() const
Definition: frame.hxx:1368
SwSectionFormat * GetFormat()
Definition: section.hxx:336
static void DestroyFrame(SwFrame *const pFrame)
this is the only way to delete a SwFrame instance
Definition: ssfrm.cxx:384
virtual void DestroyImpl() override
Definition: sectfrm.cxx:149
bool IsEndNote() const
Definition: fmtftn.hxx:71
SwFrame * FindNext()
Definition: frame.hxx:1142
virtual void Calc(vcl::RenderContext *pRenderContext) const
Definition: trvlfrm.cxx:1788
bool IsCellFrame() const
Definition: frame.hxx:1227
bool IsFootnotePage() const
Foot note interface.
Definition: pagefrm.hxx:199
tools::Long GetWidth(const SwRect &rRect) const
Definition: frame.hxx:1382
static SwFlowFrame * CastFlowFrame(SwFrame *pFrame)
Definition: flowfrm.cxx:2703
void AddBottom(SwRect &rRect, tools::Long nNew) const
Definition: frame.hxx:1395
The root element of a Writer document layout.
Definition: rootfrm.hxx:82
bool HasToBreak(const SwFrame *pFrame) const
|* Here it's decided whether the this-SectionFrame should break up |* the passed (Section)frm (or not...
Definition: sectfrm.cxx:445
css::chart::ChartAxisLabelPosition ePos
bool IsFootnoteFrame() const
Definition: frame.hxx:1203
void SetXMargins(SwFrame &rFrame, tools::Long nLeft, tools::Long nRight) const
Definition: frame.hxx:1408
bool ToMaximize(bool bCheckFollow) const
A sectionfrm has to maximize, if he has a follow or a ftncontainer at the end of the page...
Definition: sectfrm.cxx:2738
SfxHintId GetId() const
bool isFrameAreaDefinitionValid() const
Definition: frame.hxx:172
SwLayoutFrame * GetPrevSctLeaf()
Returns the preceding layout sheet where the frame can be moved into.
Definition: sectfrm.cxx:1925
void CheckDirChange()
checks the layout direction and invalidates the lower frames recursively, if necessary.
Definition: ssfrm.cxx:192
tools::Long GetTop(const SwRect &rRect) const
Definition: frame.hxx:1378
constexpr tools::Long Width() const
void SetRetouche() const
Definition: frame.hxx:1004
GPOS_TILED
SwTwips CalcUpperSpace(const SwBorderAttrs *pAttrs=nullptr, const SwFrame *pPr=nullptr, const bool _bConsiderGrid=true) const
method to determine the upper space hold by the frame
Definition: flowfrm.cxx:1446
bool IsFlyFrame() const
Definition: frame.hxx:1211
void ChgLowersProp(const Size &rOldSize)
Change size of lowers proportionally.
Definition: wsfrm.cxx:3012
void SetBottom(SwRect &rRect, tools::Long nNew) const
Definition: frame.hxx:1388
wrapper class for the positioning of Writer fly frames and drawing objects
friend SwFrame * SaveContent(SwLayoutFrame *, SwFrame *)
Definition: frmtool.cxx:2820
SvxGraphicPosition GetGraphicPos() const
SwSection * m_pSection
Definition: sectfrm.hxx:49
SwTwips Grow_(SwTwips, bool bTst)
Definition: sectfrm.cxx:2154
const SwFormatNoBalancedColumns & GetBalancedColumns(bool=true) const
Definition: fmtclbl.hxx:42
const SwLayoutFrame * GetPrevLayoutLeaf() const
Definition: frame.hxx:1025
const SwRect & getFrameArea() const
Definition: frame.hxx:180
bool getBrowseMode() const
Definition: viewopt.hxx:472
SwLayoutFrame * GetNextLeaf(MakePageType eMakePage)
Returns the next layout leaf in which we can move the frame.
Definition: flowfrm.cxx:960
void CollectEndnote(SwFootnoteFrame *pFootnote)
Definition: layouter.cxx:225
bool IsInTab() const
Definition: frame.hxx:956
bool m_bUndersized
Definition: flowfrm.hxx:121
at page or document end
Definition: fmtftntx.hxx:30
static SwTwips lcl_DeadLine(const SwFrame *pFrame)
Definition: sectfrm.cxx:2125
void RemoveFromList_(SwSectionFrame *pSct)
Definition: sectfrm.cxx:2900
virtual bool ShouldBwdMoved(SwLayoutFrame *pNewUpper, bool &rReformat) override
Definition: sectfrm.cxx:861
const SwContentFrame * FindLastContent() const
Definition: sectfrm.hxx:177
static SwFootnoteFrame * lcl_FindEndnote(SwSectionFrame *&rpSect, bool &rbEmpty, SwLayouter *pLayouter)
CollectEndnotes looks for endnotes in the sectionfrm and his follows, the endnotes will cut off the l...
Definition: sectfrm.cxx:965
bool IsTextFrame() const
Definition: frame.hxx:1235
void SetSuperfluous()
Remove superfluous Pages.
Definition: rootfrm.hxx:302
void Width(tools::Long nNew)
Definition: swrect.hxx:186
static void lcl_FindContentFrame(SwContentFrame *&rpContentFrame, SwFootnoteFrame *&rpFootnoteFrame, SwFrame *pFrame, bool &rbChkFootnote)
Definition: sectfrm.cxx:880
void setFramePrintAreaValid(bool bNew)
Definition: wsfrm.cxx:99
const SwFormatFootnoteAtTextEnd & GetFootnoteAtTextEnd(bool=true) const
Definition: fmtftntx.hxx:111
bool IsPageBodyFrame() const
Definition: layfrm.hxx:214
bool IsSctFrame() const
Definition: frame.hxx:1215
SwFlyFrame * FindFlyFrame()
Definition: frame.hxx:1112
virtual void DestroyImpl() override
Definition: ssfrm.cxx:481
SwFrame * GetIndPrev_() const
Called for a frame inside a section with no direct previous frame (or only previous empty section fra...
Definition: sectfrm.cxx:2452
SwTwips CalcUndersize() const
Definition: sectfrm.cxx:2807
bool IsFlowFrame() const
Definition: frame.hxx:1243
static void MoveContentAndDelete(SwSectionFrame *pDel, bool bSave)
Definition: sectfrm.cxx:666
SwLayoutFrame * GetNextCellLeaf()
Definition: findfrm.cxx:1525
SwLayoutFrame * GetNextSctLeaf(MakePageType eMakePage)
Returns the next layout sheet where the frame can be moved in.
Definition: sectfrm.cxx:1572
bool IsDescendantFrom(const SwSectionFormat *pSect) const
Definition: sectfrm.cxx:2513
const SwAttrSet * GetAttrSet() const
WARNING: this may not return correct RES_PAGEDESC/RES_BREAK items for SwTextFrame, use GetBreakItem()/GetPageDescItem() instead.
Definition: findfrm.cxx:677
void InvalidateContent() const
Definition: pagefrm.hxx:380
void SetUndersized(const bool bNew)
Definition: flowfrm.hxx:157
bool IsColumnFrame() const
Definition: frame.hxx:1183
SwFootnoteFrame * FindFootnoteFrame()
Definition: frame.hxx:1108
bool IsInDtor() const
Definition: frame.hxx:893
void CalcContent(SwLayoutFrame *pLay, bool bNoColl=false)
Definition: fly.cxx:1411
static SwContentFrame * lcl_GetNextContentFrame(const SwLayoutFrame *pLay, bool bFwd)
Definition: sectfrm.cxx:579
Style of a layout element.
Definition: frmfmt.hxx:59
bool IsBalancedSection() const
Definition: sectfrm.cxx:2913
bool IsContentFrame() const
Definition: frame.hxx:1231
bool m_bFootnoteAtEnd
Definition: sectfrm.hxx:50
SwFrame * GetIndPrev() const
Definition: frame.hxx:725
const SwSortedObjs * GetSortedObjs() const
Definition: pagefrm.hxx:132
sw::BroadcastingModify * GetDep()
use these so we can grep for SwFrame's GetRegisteredIn accesses beware that SwTextFrame may return sw...
Definition: frame.hxx:477
tools::Long GetPrtBottom(const SwFrame &rFrame) const
Definition: frame.hxx:1411
const SwFrame * GetLastLower() const
Definition: findfrm.cxx:1831
virtual void Paste(SwFrame *pParent, SwFrame *pSibling=nullptr) override
Definition: sectfrm.cxx:339
SwTwips InnerHeight() const
InnerHeight returns the height of the content and may be bigger or less than the PrtArea-Height of th...
Definition: wsfrm.cxx:2587
virtual void MakeAll(vcl::RenderContext *pRenderContext) override
Definition: sectfrm.cxx:771
SwFrame * GetIndNext()
Definition: frame.hxx:728
const SwSectionFrame * GetFollow() const
Definition: sectfrm.hxx:169
SwPageFrame * FindPageFrame()
Definition: frame.hxx:681
virtual bool IsDeleteForbidden() const
Definition: frame.hxx:888
SwFrame * m_pLower
Definition: layfrm.hxx:53
virtual void Cut() override
Definition: wsfrm.cxx:1434
tools::Long YInc(tools::Long n1, tools::Long n2) const
Definition: frame.hxx:1426
const SwFrame * Lower() const
Definition: layfrm.hxx:101
SwContentFrame * FindNextCnt(const bool _bInSameFootnote=false)
Definition: findfrm.cxx:191
virtual void SwClientNotify(const SwModify &, const SfxHint &) override
Definition: wsfrm.cxx:474
void InvalidatePage(const SwPageFrame *pPage=nullptr) const
Invalidates the page in which the Frame is currently placed.
Definition: wsfrm.cxx:607
tools::Long GetHeight(const SwRect &rRect) const
Definition: frame.hxx:1383
SwSection * GetSection()
Definition: sectfrm.hxx:93
bool IsJoinLocked() const
Definition: flowfrm.hxx:175
void ChgColumns(const SwFormatCol &rOld, const SwFormatCol &rNew, const bool bChgFootnote=false)
add or remove columns from a layoutframe.
Definition: colfrm.cxx:188
void SetFollow(SwFlowFrame *const pFollow)
Definition: flowfrm.cxx:92
tools::Long GetLeft() const
SwLayoutFrame * GetUpper()
Definition: frame.hxx:679
void InsertEmptySct(SwSectionFrame *pDel)
Empty SwSectionFrames are registered here for deletion and destroyed later on or deregistered.
Definition: sectfrm.cxx:2861
bool HasArea() const
Definition: swrect.hxx:280
constexpr TypedWhichId< SwAttrSetChg > RES_ATTRSET_CHG(163)
SvxGraphicPosition
bool isFramePrintAreaValid() const
Definition: frame.hxx:169
bool IsUndersized() const
Definition: flowfrm.hxx:158
static sal_uInt8 Count()
Definition: frmtool.hxx:470
void LockJoin()
Definition: flowfrm.hxx:139
SwFootnoteBossFrame * FindFootnoteBossFrame(bool bFootnotes=false)
Definition: findfrm.cxx:436
friend void RestoreContent(SwFrame *, SwLayoutFrame *, SwFrame *pSibling)
Definition: frmtool.cxx:2982
SwFrame * GetPrev()
Definition: frame.hxx:678
tools::Long GetTopMargin(const SwFrame &rFrame) const
Definition: frame.hxx:1404
bool isFrameAreaPositionValid() const
Definition: frame.hxx:167
tools::Long YDiff(tools::Long n1, tools::Long n2) const
Definition: frame.hxx:1424
void CalcEndAtEndFlag()
Definition: sectfrm.cxx:2556
void SSize(const Size &rNew)
Definition: swrect.hxx:177
const SwFormatEndAtTextEnd & GetEndAtTextEnd(bool=true) const
Definition: fmtftntx.hxx:113
bool HasFixSize() const
Definition: frame.hxx:671
bool isFrameAreaSizeValid() const
Definition: frame.hxx:168
bool InsertGroupBefore(SwFrame *pParent, SwFrame *pWhere, SwFrame *pSct)
Insert a chain of SwFrames into an existing structure.
Definition: wsfrm.cxx:905
void InvalidatePos_()
Definition: frame.hxx:788
SwCellFrame * GetFollowCell() const
Definition: findfrm.cxx:1593
A page of the document layout.
Definition: pagefrm.hxx:57
const SwFormatFootnote & GetFootnote() const
Definition: txatbase.hxx:204
tools::Long SwTwips
Definition: swtypes.hxx:52
const long LONG_MAX
SwTwips Shrink(SwTwips, bool bTst=false, bool bInfo=false)
Definition: wsfrm.cxx:1547
void InvalidateSize()
Definition: frame.hxx:1030
SwSectionFrame * FindSctFrame()
Definition: frame.hxx:1116
SwSectionFormat * GetParent() const
Definition: section.hxx:355
const SwFootnoteFrame * GetMaster() const
Definition: ftnfrm.hxx:119
void InvalidateAccessibleParaFlowRelation(const SwTextFrame *_pFromTextFrame, const SwTextFrame *_pToTextFrame)
invalidate CONTENT_FLOWS_FROM/_TO relation for paragraphs
Definition: viewsh.cxx:2492
void CollectEndnotes(SwLayouter *pLayouter)
Definition: sectfrm.cxx:1044
const SwFootnoteFrame * FindFootNote() const
Definition: findfrm.cxx:565
void setFrameAreaPositionValid(bool bNew)
Definition: wsfrm.cxx:83
static void lcl_ColumnRefresh(SwSectionFrame *pSect, bool bFollow)
Definition: sectfrm.cxx:1016
sal_uInt16 Count() const
Definition: hints.hxx:305
bool IsLayoutFrame() const
Definition: frame.hxx:1171
T saturating_add(T a, T b)
bool Growable() const
checks whether the SectionFrame is still able to grow, as case may be the environment has to be asked...
Definition: sectfrm.cxx:2144
void SetYMargins(SwFrame &rFrame, tools::Long nTop, tools::Long nBottom) const
Definition: frame.hxx:1409
const SwFlowFrame * GetPrecede() const
Definition: flowfrm.hxx:172
void SetWidth(SwRect &rRect, tools::Long nNew) const
Definition: frame.hxx:1391
tools::Long const nTopMargin
void MoveSubTree(SwLayoutFrame *pParent, SwFrame *pSibling=nullptr)
hook tree onto new parent with minimal operations and notifications
Definition: flowfrm.cxx:635
MakePageType
Definition: frame.hxx:113
bool IsTabFrame() const
Definition: frame.hxx:1219
general base class for all free-flowing frames
Definition: flyfrm.hxx:78
void UnlockJoin()
Definition: flowfrm.hxx:140
bool m_bEndnAtEnd
Definition: sectfrm.hxx:51
void SimpleFormat()
Definition: sectfrm.cxx:1165
bool IsLocked() const
Definition: flyfrm.hxx:213
constexpr tools::Long Height() const
void ColUnlock()
Definition: sectfrm.hxx:96
bool MoveLowerFootnotes(SwContentFrame *pStart, SwFootnoteBossFrame *pOldBoss, SwFootnoteBossFrame *pNewBoss, const bool bFootnoteNums)
Moving the Footnotes of all Lowers - starting from StartContent.
Definition: ftnfrm.cxx:2650
const SwSectionFormat * GetEndSectFormat_() const
Definition: sectfrm.cxx:867
friend void CalcContent(SwLayoutFrame *pLay, bool bNoColl)
Definition: fly.cxx:1411
const SwViewOption * GetViewOptions() const
Definition: viewsh.hxx:423
const SwFrame * ContainsAny(const bool _bInvestigateFootnoteForSections=false) const
Method doesn't investigate content of footnotes by default.
Definition: findfrm.cxx:126
constexpr TypedWhichId< SwFormatNoBalancedColumns > RES_COLUMNBALANCE(119)
void InvalidateAll_()
Definition: frame.hxx:804
void InsertBehind(SwLayoutFrame *pParent, SwFrame *pBefore)
Insert SwFrame into existing structure.
Definition: wsfrm.cxx:866
const SwSectionFormat * GetEndSectFormat() const
Definition: sectfrm.hxx:145
void DeleteEmptySct_()
Definition: sectfrm.cxx:2868
void SetHeight(SwRect &rRect, tools::Long nNew) const
Definition: frame.hxx:1392
void RemoveFromLayout()
Definition: wsfrm.cxx:1007
bool m_bOwnFootnoteNum
Definition: sectfrm.hxx:53
bool IsAnyNoteAtEnd() const
Definition: sectfrm.hxx:158
void InvalidateNextPos(bool bNoFootnote=false)
Definition: frame.hxx:1073
void Top(const tools::Long nTop)
Definition: swrect.hxx:203
const SwModify * GetRegisteredIn() const
Definition: calbck.hxx:165
bool IsColBodyFrame() const
These SwFrame inlines are here, so that frame.hxx does not need to include layfrm.hxx.
Definition: layfrm.hxx:209
void setFrameAreaSizeValid(bool bNew)
Definition: wsfrm.cxx:91
void CheckClipping(bool bGrow, bool bMaximize)
Adapt size to surroundings.
Definition: sectfrm.cxx:1072
SwFrame * GetLower()
Definition: findfrm.cxx:170
SwFrameType mnFrameType
Definition: frame.hxx:415
bool IsPageFrame() const
Definition: frame.hxx:1179
void * p
const SwTextFootnote * GetAttr() const
Definition: ftnfrm.hxx:122
virtual void Cut() override
Definition: sectfrm.cxx:252
static bool IsLocked()
Definition: frmtool.hxx:469
-""- and with own number sequence
Definition: fmtftntx.hxx:32
void CalcFootnoteContent()
Definition: sectfrm.cxx:2820
bool IsContentLocked() const
Definition: sectfrm.hxx:161
void MakePos(SwFrame &rFrame, const SwFrame *pUp, const SwFrame *pPrv, bool bNotify) const
Definition: frame.hxx:1422
void InvalidateAccessibleEditableState(bool bAllShells, const SwFrame *pFrame=nullptr)
Invalidate editable state for all accessible frames.
Definition: viewimp.cxx:350
tools::Long GetBottom(const SwRect &rRect) const
Definition: frame.hxx:1379
sal_uInt16 GetNumCols() const
Definition: fmtclds.hxx:114
SwFootnoteContFrame * ContainsFootnoteCont(const SwFootnoteContFrame *pCont=nullptr) const
Check every Column for FootnoteContFrames.
Definition: sectfrm.cxx:2767
void InvalidatePrt_()
Definition: frame.hxx:780
void ClearItem(sal_uInt16 nWhichL)
Definition: hints.cxx:128
#define SAL_WARN(area, stream)
void SetLeft(SwRect &rRect, tools::Long nNew) const
Definition: frame.hxx:1389
bool IsFootnoteAtEnd() const
Definition: sectfrm.hxx:156
bool IsInDelList(SwSectionFrame *pSct) const
Definition: sectfrm.cxx:2907
void AdjustColumns(const SwFormatCol *pCol, bool bAdjustAttributes)
Definition: colfrm.cxx:298
SwContentFrame * FindPrevCnt()
Definition: findfrm.cxx:175
SwFrame * GetIndNext_()
Definition: sectfrm.cxx:2488
A layout frame is a frame that contains other frames (m_pLower), e.g. SwPageFrame or SwTabFrame...
Definition: layfrm.hxx:35
void MergeNext(SwSectionFrame *pNxt)
|* Merges two SectionFrames, in case it's about the same section.
Definition: sectfrm.cxx:468
const SwLayoutFrame * GetNextLayoutLeaf() const
Definition: frame.hxx:1021
bool IsEndnoteAtMyEnd() const
Definition: sectfrm.cxx:2551
virtual void MakePos()
Definition: calcmove.cxx:539
SwPageFrame * InsertPage(SwPageFrame *pSibling, bool bFootnote)
Definition: pagechg.cxx:1351
SwSection * GetSection() const
Definition: section.cxx:669
bool CalcMinDiff(SwTwips &rMinDiff) const
Definition: sectfrm.cxx:947
bool IsFootnoteContFrame() const
Definition: frame.hxx:1199
void Init(sal_uInt16 nNumCols, sal_uInt16 nGutterWidth, sal_uInt16 nAct)
This function allows to (repeatedly) initialize the columns.
Definition: atrfrm.cxx:969
bool WrongPageDesc(SwPageFrame *pNew)
Definition: flowfrm.cxx:884
const SwContentFrame * ContainsContent() const
Checks if the frame contains one or more ContentFrame's anywhere in his subsidiary structure; if so t...
Definition: findfrm.cxx:67
SwSectionFrame(SwSection &, SwFrame *)
Definition: sectfrm.cxx:67
SwRootFrame * GetLayout() const
Definition: viewsh.cxx:2074
const SwFlowFrame * GetFollow() const
Definition: flowfrm.hxx:168
bool IsBodyFrame() const
Definition: frame.hxx:1207
GPOS_RT
virtual void MakeAll(vcl::RenderContext *pRenderContext) override
Definition: calcmove.cxx:957
SwViewShell * GetCurrShell() const
Definition: rootfrm.hxx:207
class for collecting anchored objects
Definition: sortedobjs.hxx:48
void Height(tools::Long nNew)
Definition: swrect.hxx:190
bool HasEndnotes() const
Definition: layouter.cxx:220
constexpr TypedWhichId< SwFormatFootnoteAtTextEnd > RES_FTN_AT_TXTEND(117)
bool IsFooterFrame() const
Definition: frame.hxx:1195
sal_uInt16 Which() const
SwRootFrame * getRootFrame()
Definition: frame.hxx:680
SwCellFrame is one table cell in the document layout.
Definition: cellfrm.hxx:30
std::unique_ptr< SwDestroyList > mpDestroy
Definition: rootfrm.hxx:171
bool IsHeaderFrame() const
Definition: frame.hxx:1191
virtual const SwFrameFormat * GetFormat() const
Definition: ssfrm.cxx:395
#define PROTOCOL_ENTER(pFrame, nFunc, nAct, pPar)
Definition: dbg_lay.hxx:92
SwTabFrame * FindTabFrame()
Definition: frame.hxx:1100
SwFrame * GetNext()
Definition: frame.hxx:677
const SvxLRSpaceItem & GetLRSpace(bool=true) const
Definition: frmatr.hxx:74
EnumT GetValue() const