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