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