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