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