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
54namespace
55{
60void 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 {
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
192void 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
265void 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
347void 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
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 {
442 if ( GetPrev()->IsContentFrame() )
443 GetPrev()->InvalidatePage( pPage );
444 }
445}
446
453bool 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
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();
511}
512
519bool 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 }
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
569static 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
587static 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
640namespace
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 );
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{
782 return;
783 if( !m_pSection ) // Via DelEmpty
784 {
785#ifdef DBG_UTIL
786 OSL_ENSURE( getRootFrame()->IsInDelList( this ), "SectionFrame without Section" );
787#endif
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
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 {
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
888static 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
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
973static 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
1024static 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
1080void 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
1206namespace {
1207
1208// #i40147# - helper class to perform extra section format
1209// to position anchored objects and to keep the position of whose objects locked.
1210class 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
1342void 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
1352 return;
1353 }
1354
1355 SwRectFnSet aRectFnSet(this);
1356
1357 if ( !isFramePrintAreaValid() )
1358 {
1359 PROTOCOL( this, PROT::PrintArea, DbgAction::NONE, nullptr )
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
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 );
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() &&
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 {
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
2133static 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 )
2211 else
2213 }
2214 }
2215 else if( !bTst )
2216 {
2217 if( bInCalcContent )
2219 else if( nSpace < nGrow && nDist != nSpace + GetUpper()->
2220 Grow( nGrow - nSpace ) )
2222 else
2223 {
2224 const SvxGraphicPosition ePos =
2226 if ( GPOS_RT < ePos && GPOS_TILED != ePos )
2227 {
2230 }
2231 if( GetUpper() && GetUpper()->IsHeaderFrame() )
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 );
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 )
2290 else
2292 }
2293 }
2294 return 0;
2295}
2296
2298{
2299 if ( Lower() && !IsColLocked() && !HasFixSize() )
2300 {
2301 if( ToMaximize( false ) )
2302 {
2303 if( !bTst )
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 )
2319 return nDist;
2320 }
2321 else if( !bTst )
2322 {
2323 const SvxGraphicPosition ePos =
2325 if ( GPOS_RT < ePos && GPOS_TILED != ePos )
2326 {
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|*/
2400bool 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();
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
2585void 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 {
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
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();
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();
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 );
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
2755bool 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;
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();
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 {
2937 }
2938 return bRet;
2939}
2940
2941/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
css::chart::ChartAxisLabelPosition ePos
@ CONSIDER_WRAP_ON_OBJECT_POSITION
SvxGraphicPosition
GPOS_RT
GPOS_TILED
bool GetValue() const
EnumT GetValue() const
SfxHintId GetId() const
const SfxPoolItem * GetCurItem() const
const SfxPoolItem * NextItem()
sal_uInt16 Which() const
constexpr tools::Long Height() const
constexpr tools::Long Width() const
static bool IsLocked()
Definition: frmtool.hxx:478
static sal_uInt8 Count()
Definition: frmtool.hxx:479
bool StartListening(SvtBroadcaster &rBroadcaster)
SvxGraphicPosition GetGraphicPos() const
tools::Long GetRight() const
tools::Long GetLeft() const
wrapper class for the positioning of Writer fly frames and drawing objects
sal_uInt16 Count() const
Definition: hints.hxx:308
void ClearItem(sal_uInt16 nWhichL)
Definition: hints.cxx:132
const SvxBrushItem & GetBackground(bool=true) const
Definition: frmatr.hxx:58
SwCellFrame is one table cell in the document layout.
Definition: cellfrm.hxx:31
SwCellFrame * GetFollowCell() const
Definition: findfrm.cxx:1647
const SwModify * GetRegisteredIn() const
Definition: calbck.hxx:164
SwContentFrame is the layout for content nodes: a common base class for text (paragraph) and non-text...
Definition: cntfrm.hxx:58
Base class that provides the general functionalities for frames that are allowed at page breaks (flow...
Definition: flowfrm.hxx:60
bool IsJoinLocked() const
Definition: flowfrm.hxx:176
static void SetMoveBwdJump(bool bNew)
Definition: flowfrm.hxx:156
void MoveSubTree(SwLayoutFrame *pParent, SwFrame *pSibling=nullptr)
hook tree onto new parent with minimal operations and notifications
Definition: flowfrm.cxx:634
friend void CalcContent(SwLayoutFrame *pLay, bool bNoColl)
Definition: fly.cxx:1423
const SwFlowFrame * GetFollow() const
Definition: flowfrm.hxx:169
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
void SetUndersized(const bool bNew)
Definition: flowfrm.hxx:158
bool HasFollow() const
Definition: flowfrm.hxx:166
bool IsFollow() const
Definition: flowfrm.hxx:167
void SetFollow(SwFlowFrame *const pFollow)
Definition: flowfrm.cxx:91
static SwFlowFrame * CastFlowFrame(SwFrame *pFrame)
Definition: flowfrm.cxx:2709
void UnlockJoin()
Definition: flowfrm.hxx:141
const SwFlowFrame * GetPrecede() const
Definition: flowfrm.hxx:173
bool IsUndersized() const
Definition: flowfrm.hxx:159
bool m_bUndersized
Definition: flowfrm.hxx:122
void LockJoin()
Definition: flowfrm.hxx:140
general base class for all free-flowing frames
Definition: flyfrm.hxx:79
bool IsLocked() const
Definition: flyfrm.hxx:213
SwFootnoteContFrame * FindFootnoteCont()
Definition: ftnfrm.cxx:1036
const SwFootnoteFrame * FindFootNote() const
Definition: findfrm.cxx:619
const SwFootnoteFrame * GetMaster() const
Definition: ftnfrm.hxx:119
const SwTextFootnote * GetAttr() const
Definition: ftnfrm.hxx:122
void Init(sal_uInt16 nNumCols, sal_uInt16 nGutterWidth, sal_uInt16 nAct)
This function allows to (repeatedly) initialize the columns.
Definition: atrfrm.cxx:969
sal_uInt16 GetNumCols() const
Definition: fmtclds.hxx:114
bool IsEndNote() const
Definition: fmtftn.hxx:73
const SvxLRSpaceItem & GetLRSpace(bool=true) const
Definition: frmatr.hxx:74
const SwFormatFootnoteAtTextEnd & GetFootnoteAtTextEnd(bool=true) const
Definition: fmtftntx.hxx:116
const SwFormatEndAtTextEnd & GetEndAtTextEnd(bool=true) const
Definition: fmtftntx.hxx:118
const SwFormatCol & GetCol(bool=true) const
Definition: fmtclds.hxx:168
const SwFormatNoBalancedColumns & GetBalancedColumns(bool=true) const
Definition: fmtclbl.hxx:42
const SwRect & getFrameArea() const
Definition: frame.hxx:179
bool isFrameAreaDefinitionValid() const
Definition: frame.hxx:171
bool isFrameAreaPositionValid() const
Definition: frame.hxx:166
const SwRect & getFramePrintArea() const
Definition: frame.hxx:180
void setFramePrintAreaValid(bool bNew)
Definition: wsfrm.cxx:100
void setFrameAreaPositionValid(bool bNew)
Definition: wsfrm.cxx:84
bool isFramePrintAreaValid() const
Definition: frame.hxx:168
bool isFrameAreaSizeValid() const
Definition: frame.hxx:167
void setFrameAreaSizeValid(bool bNew)
Definition: wsfrm.cxx:92
Style of a layout element.
Definition: frmfmt.hxx:62
Base class of the Writer layout elements.
Definition: frame.hxx:315
SwTwips Grow(SwTwips, bool bTst=false, bool bInfo=false)
Definition: wsfrm.cxx:1510
bool IsCellFrame() const
Definition: frame.hxx:1226
void InvalidateInfFlags()
Definition: frame.hxx:608
bool IsFootnoteContFrame() const
Definition: frame.hxx:1198
void InsertBehind(SwLayoutFrame *pParent, SwFrame *pBefore)
Insert SwFrame into existing structure.
Definition: wsfrm.cxx:872
SwFrame * GetIndNext_()
Definition: sectfrm.cxx:2496
bool IsTextFrame() const
Definition: frame.hxx:1234
virtual bool Prepare(const PrepareHint ePrep=PrepareHint::Clear, const void *pVoid=nullptr, bool bNotify=true)
Definition: wsfrm.cxx:603
void SetDerivedR2L(bool bNew)
Definition: frame.hxx:632
SwFrame * GetIndPrev() const
Definition: frame.hxx:724
bool IsInDtor() const
Definition: frame.hxx:892
void CheckDirChange()
checks the layout direction and invalidates the lower frames recursively, if necessary.
Definition: ssfrm.cxx:194
bool IsInDocBody() const
Definition: frame.hxx:943
SwTwips Shrink(SwTwips, bool bTst=false, bool bInfo=false)
Definition: wsfrm.cxx:1554
SwFlyFrame * FindFlyFrame()
Definition: frame.hxx:1111
SwSectionFrame * FindSctFrame()
Definition: frame.hxx:1115
SwContentFrame * FindPrevCnt()
Definition: findfrm.cxx:199
SwTabFrame * FindTabFrame()
Definition: frame.hxx:1099
SwFrame * FindNext()
Definition: frame.hxx:1141
SwFrame * GetNext()
Definition: frame.hxx:676
bool InsertGroupBefore(SwFrame *pParent, SwFrame *pWhere, SwFrame *pSct)
Insert a chain of SwFrames into an existing structure.
Definition: wsfrm.cxx:911
bool HasFixSize() const
Definition: frame.hxx:670
SwLayoutFrame * GetNextSctLeaf(MakePageType eMakePage)
Returns the next layout sheet where the frame can be moved in.
Definition: sectfrm.cxx:1580
bool IsPageFrame() const
Definition: frame.hxx:1178
bool IsColLocked() const
Definition: frame.hxx:886
bool IsColumnFrame() const
Definition: frame.hxx:1182
SwFrameType mnFrameType
Definition: frame.hxx:414
void InvalidateNextPos(bool bNoFootnote=false)
Definition: frame.hxx:1072
bool IsTabFrame() const
Definition: frame.hxx:1218
void InvalidatePos_()
Definition: frame.hxx:787
SwFrameType GetType() const
Definition: frame.hxx:519
bool IsInFootnote() const
Definition: frame.hxx:949
bool IsHeaderFrame() const
Definition: frame.hxx:1190
SwPageFrame * InsertPage(SwPageFrame *pSibling, bool bFootnote)
Definition: pagechg.cxx:1367
virtual void Calc(vcl::RenderContext *pRenderContext) const
Definition: trvlfrm.cxx:1798
const SwSortedObjs * GetDrawObjs() const
Definition: frame.hxx:564
bool IsInTab() const
Definition: frame.hxx:955
virtual void SwClientNotify(const SwModify &, const SfxHint &) override
Definition: wsfrm.cxx:480
SwFrame * FindPrev()
Definition: frame.hxx:1155
virtual void MakePos()
Definition: calcmove.cxx:526
SwFrame * GetLower()
Definition: findfrm.cxx:194
bool IsInFly() const
Definition: frame.hxx:961
void InsertBefore(SwLayoutFrame *pParent, SwFrame *pBehind)
Insert SwFrame into existing structure.
Definition: wsfrm.cxx:836
virtual bool IsDeleteForbidden() const
Definition: frame.hxx:887
bool IsPageBodyFrame() const
Definition: layfrm.hxx:215
const SwAttrSet * GetAttrSet() const
WARNING: this may not return correct RES_PAGEDESC/RES_BREAK items for SwTextFrame,...
Definition: findfrm.cxx:731
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
void RemoveFromLayout()
Definition: wsfrm.cxx:1013
bool IsFlowFrame() const
Definition: frame.hxx:1242
bool WrongPageDesc(SwPageFrame *pNew)
Definition: flowfrm.cxx:883
SwLayoutFrame * GetNextCellLeaf()
Definition: findfrm.cxx:1579
bool IsFooterFrame() const
Definition: frame.hxx:1194
void InvalidatePos()
Definition: frame.hxx:1043
bool IsFootnoteFrame() const
Definition: frame.hxx:1202
SwLayoutFrame * GetUpper()
Definition: frame.hxx:678
const SwLayoutFrame * GetNextLayoutLeaf() const
Definition: frame.hxx:1020
SwFrame * mpNext
Definition: frame.hxx:338
void InvalidatePage(const SwPageFrame *pPage=nullptr) const
Invalidates the page in which the Frame is currently placed.
Definition: wsfrm.cxx:613
SwLayoutFrame * GetNextLeaf(MakePageType eMakePage)
Returns the next layout leaf in which we can move the frame.
Definition: flowfrm.cxx:959
SwRootFrame * getRootFrame()
Definition: frame.hxx:679
void SetCompletePaint() const
Definition: frame.hxx:994
bool IsFlyFrame() const
Definition: frame.hxx:1210
bool IsContentFrame() const
Definition: frame.hxx:1230
void InvalidatePrt_()
Definition: frame.hxx:779
SwFrame * GetPrev()
Definition: frame.hxx:677
void InvalidateSize_()
Definition: frame.hxx:771
bool IsSctFrame() const
Definition: frame.hxx:1214
void InvalidateSize()
Definition: frame.hxx:1029
SwContentFrame * FindNextCnt(const bool _bInSameFootnote=false)
Definition: findfrm.cxx:215
const SwLayoutFrame * GetPrevLayoutLeaf() const
Definition: frame.hxx:1024
SwPageFrame * FindPageFrame()
Definition: frame.hxx:680
sw::BroadcastingModify * GetDep()
use these so we can grep for SwFrame's GetRegisteredIn accesses beware that SwTextFrame may return sw...
Definition: frame.hxx:476
SwFrame * FindFooterOrHeader()
Definition: findfrm.cxx:602
SwFootnoteFrame * FindFootnoteFrame()
Definition: frame.hxx:1107
SwFrame * GetIndNext()
Definition: frame.hxx:727
SwFootnoteBossFrame * FindFootnoteBossFrame(bool bFootnotes=false)
Definition: findfrm.cxx:460
void InvalidateAll_()
Definition: frame.hxx:803
static void DestroyFrame(SwFrame *const pFrame)
this is the only way to delete a SwFrame instance
Definition: ssfrm.cxx:388
void SetRetouche() const
Definition: frame.hxx:1003
bool IsLayoutFrame() const
Definition: frame.hxx:1170
SwLayoutFrame * GetPrevSctLeaf()
Returns the preceding layout sheet where the frame can be moved into.
Definition: sectfrm.cxx:1933
bool IsBodyFrame() const
Definition: frame.hxx:1206
bool IsColBodyFrame() const
These SwFrame inlines are here, so that frame.hxx does not need to include layfrm....
Definition: layfrm.hxx:210
bool IsInSct() const
Definition: frame.hxx:967
A layout frame is a frame that contains other frames (m_pLower), e.g. SwPageFrame or SwTabFrame.
Definition: layfrm.hxx:36
void ChgLowersProp(const Size &rOldSize)
Change size of lowers proportionally.
Definition: wsfrm.cxx:3044
void AdjustColumns(const SwFormatCol *pCol, bool bAdjustAttributes)
Definition: colfrm.cxx:298
virtual void Format(vcl::RenderContext *pRenderContext, const SwBorderAttrs *pAttrs=nullptr) override
"Formats" the Frame; Frame and PrtArea.
Definition: wsfrm.cxx:3443
bool IsAnLower(const SwFrame *) const
Definition: findfrm.cxx:231
virtual void MakeAll(vcl::RenderContext *pRenderContext) override
Definition: calcmove.cxx:944
virtual const SwFrameFormat * GetFormat() const
Definition: ssfrm.cxx:399
const SwFrame * ContainsAny(const bool _bInvestigateFootnoteForSections=false) const
Method <ContainsAny()> doesn't investigate content of footnotes by default.
Definition: findfrm.cxx:129
virtual void DestroyImpl() override
Definition: ssfrm.cxx:485
friend void RestoreContent(SwFrame *, SwLayoutFrame *, SwFrame *pSibling)
Definition: frmtool.cxx:3016
bool IsBefore(const SwLayoutFrame *_pCheckRefLayFrame) const
method to check relative position of layout frame to a given layout frame.
Definition: findfrm.cxx:258
const SwFrame * GetLastLower() const
Definition: findfrm.cxx:1885
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
SwFrame * m_pLower
Definition: layfrm.hxx:53
friend SwFrame * SaveContent(SwLayoutFrame *, SwFrame *)
Definition: frmtool.cxx:2854
void ChgColumns(const SwFormatCol &rOld, const SwFormatCol &rNew, const bool bChgFootnote=false)
add or remove columns from a layoutframe.
Definition: colfrm.cxx:188
bool MoveLowerFootnotes(SwContentFrame *pStart, SwFootnoteBossFrame *pOldBoss, SwFootnoteBossFrame *pNewBoss, const bool bFootnoteNums)
Moving the Footnotes of all Lowers - starting from StartContent.
Definition: ftnfrm.cxx:2660
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:2594
const SwFrame * Lower() const
Definition: layfrm.hxx:101
virtual void Cut() override
Definition: wsfrm.cxx:1441
void FormatWidthCols(const SwBorderAttrs &, const SwTwips nBorder, const SwTwips nMinHeight)
Called by Format for Frames and Areas with columns.
Definition: wsfrm.cxx:3708
bool HasEndnotes() const
Definition: layouter.cxx:220
void CollectEndnote(SwFootnoteFrame *pFootnote)
Definition: layouter.cxx:225
A page of the document layout.
Definition: pagefrm.hxx:58
void InvalidateContent() const
Definition: pagefrm.hxx:380
const SwSortedObjs * GetSortedObjs() const
Definition: pagefrm.hxx:132
bool IsEmptyPage() const
Definition: pagefrm.hxx:157
bool IsFootnotePage() const
Foot note interface.
Definition: pagefrm.hxx:199
bool IsVert() const
Definition: frame.hxx:1366
tools::Long GetHeight(const SwRect &rRect) const
Definition: frame.hxx:1381
tools::Long YInc(tools::Long n1, tools::Long n2) const
Definition: frame.hxx:1424
void SetWidth(SwRect &rRect, tools::Long nNew) const
Definition: frame.hxx:1389
tools::Long GetTopMargin(const SwFrame &rFrame) const
Definition: frame.hxx:1402
void SetBottom(SwRect &rRect, tools::Long nNew) const
Definition: frame.hxx:1386
tools::Long GetWidth(const SwRect &rRect) const
Definition: frame.hxx:1380
void SetYMargins(SwFrame &rFrame, tools::Long nTop, tools::Long nBottom) const
Definition: frame.hxx:1407
void SetHeight(SwRect &rRect, tools::Long nNew) const
Definition: frame.hxx:1390
tools::Long GetTop(const SwRect &rRect) const
Definition: frame.hxx:1376
void SetXMargins(SwFrame &rFrame, tools::Long nLeft, tools::Long nRight) const
Definition: frame.hxx:1406
void AddBottom(SwRect &rRect, tools::Long nNew) const
Definition: frame.hxx:1393
tools::Long YDiff(tools::Long n1, tools::Long n2) const
Definition: frame.hxx:1422
void MakePos(SwFrame &rFrame, const SwFrame *pUp, const SwFrame *pPrv, bool bNotify) const
Definition: frame.hxx:1420
tools::Long GetBottom(const SwRect &rRect) const
Definition: frame.hxx:1377
tools::Long BottomDist(const SwRect &rRect, tools::Long nPos) const
Definition: frame.hxx:1413
tools::Long GetPrtBottom(const SwFrame &rFrame) const
Definition: frame.hxx:1409
void SetLeft(SwRect &rRect, tools::Long nNew) const
Definition: frame.hxx:1387
void Height(tools::Long nNew)
Definition: swrect.hxx:193
bool HasArea() const
Definition: swrect.hxx:300
void Top(const tools::Long nTop)
Definition: swrect.hxx:206
void SSize(const Size &rNew)
Definition: swrect.hxx:180
void Width(tools::Long nNew)
Definition: swrect.hxx:189
The root element of a Writer document layout.
Definition: rootfrm.hxx:82
void DeleteEmptySct_()
Definition: sectfrm.cxx:2885
bool IsInDelList(SwSectionFrame *pSct) const
Definition: sectfrm.cxx:2925
SwViewShell * GetCurrShell() const
Definition: rootfrm.hxx:206
std::unique_ptr< SwDestroyList > mpDestroy
Definition: rootfrm.hxx:170
void SetSuperfluous()
Remove superfluous Pages.
Definition: rootfrm.hxx:301
void InsertEmptySct(SwSectionFrame *pDel)
Empty SwSectionFrames are registered here for deletion and destroyed later on or deregistered.
Definition: sectfrm.cxx:2878
bool IsAnyShellAccessible() const
Definition: rootfrm.hxx:389
void RemoveFromList_(SwSectionFrame *pSct)
Definition: sectfrm.cxx:2918
void RemoveFromList(SwSectionFrame *pSct)
Definition: rootfrm.hxx:381
SwSection * GetSection() const
Definition: section.cxx:641
SwSectionFormat * GetParent() const
Definition: section.hxx:356
SwSection * GetSection()
Definition: sectfrm.hxx:97
bool IsAnyNoteAtEnd() const
Definition: sectfrm.hxx:162
void CheckClipping(bool bGrow, bool bMaximize)
Adapt size to surroundings.
Definition: sectfrm.cxx:1080
bool MoveAllowed(const SwFrame *) const
Definition: sectfrm.cxx:2400
bool IsEndnAtEnd() const
Definition: sectfrm.hxx:161
void DelEmpty(bool bRemove)
Definition: sectfrm.cxx:192
bool IsContentLocked() const
Definition: sectfrm.hxx:165
bool m_bFootnoteAtEnd
Definition: sectfrm.hxx:53
virtual void MakeAll(vcl::RenderContext *pRenderContext) override
Definition: sectfrm.cxx:779
virtual void Notify(SfxHint const &rHint) override
Definition: sectfrm.cxx:2578
const SwSectionFormat * GetEndSectFormat() const
Definition: sectfrm.hxx:149
bool CalcMinDiff(SwTwips &rMinDiff) const
Definition: sectfrm.cxx:955
SwSection * m_pSection
Definition: sectfrm.hxx:52
SwTwips Shrink_(SwTwips, bool bTst)
Definition: sectfrm.cxx:2297
virtual ~SwSectionFrame() override
Definition: sectfrm.cxx:188
bool m_bEndnAtEnd
Definition: sectfrm.hxx:54
void CalcFootnoteAtEndFlag()
Definition: sectfrm.cxx:2536
void CollectEndnotes(SwLayouter *pLayouter)
Definition: sectfrm.cxx:1052
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
virtual void Cut() override
Definition: sectfrm.cxx:260
void MergeNext(SwSectionFrame *pNxt)
|* Merges two SectionFrames, in case it's about the same section.
Definition: sectfrm.cxx:476
SwTwips Grow_(SwTwips, bool bTst)
Definition: sectfrm.cxx:2162
const SwSectionFormat * GetEndSectFormat_() const
Definition: sectfrm.cxx:875
bool IsEndnoteAtMyEnd() const
Definition: sectfrm.cxx:2559
bool IsBalancedSection() const
Definition: sectfrm.cxx:2931
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
bool IsSuperfluous() const
Definition: sectfrm.hxx:64
void CalcEndAtEndFlag()
Definition: sectfrm.cxx:2564
virtual void DestroyImpl() override
Definition: sectfrm.cxx:155
void ColUnlock()
Definition: sectfrm.hxx:100
const SwContentFrame * FindLastContent() const
Definition: sectfrm.hxx:181
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
bool m_bOwnFootnoteNum
Definition: sectfrm.hxx:56
SwTwips CalcUndersize() const
Definition: sectfrm.cxx:2824
void CalcFootnoteContent()
Definition: sectfrm.cxx:2837
SwSectionFrame(SwSection &, SwFrame *)
Definition: sectfrm.cxx:69
void SimpleFormat()
Definition: sectfrm.cxx:1173
virtual void Format(vcl::RenderContext *pRenderContext, const SwBorderAttrs *pAttrs=nullptr) override
"formats" the frame; Frame and PrtArea
Definition: sectfrm.cxx:1342
virtual bool ShouldBwdMoved(SwLayoutFrame *pNewUpper, bool &rReformat) override
Definition: sectfrm.cxx:869
void UpdateAttr_(const SfxPoolItem *, const SfxPoolItem *, SwSectionFrameInvFlags &, SwAttrSetChg *pa=nullptr, SwAttrSetChg *pb=nullptr)
Definition: sectfrm.cxx:2632
SwFootnoteContFrame * ContainsFootnoteCont(const SwFootnoteContFrame *pCont=nullptr) const
Check every Column for FootnoteContFrames.
Definition: sectfrm.cxx:2784
static void MoveContentAndDelete(SwSectionFrame *pDel, bool bSave)
Definition: sectfrm.cxx:674
virtual void Paste(SwFrame *pParent, SwFrame *pSibling=nullptr) override
Definition: sectfrm.cxx:347
SwSectionFrame * FindMaster() const
Definition: flowfrm.cxx:753
void InvalidateFootnotePos()
Definition: sectfrm.cxx:2813
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
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 IsFootnoteAtEnd() const
Definition: sectfrm.hxx:160
bool IsDescendantFrom(const SwSectionFormat *pSect) const
Definition: sectfrm.cxx:2521
void Cut_(bool bRemove)
Definition: sectfrm.cxx:265
void ColLock()
Definition: sectfrm.hxx:99
virtual void SwClientNotify(const SwModify &, const SfxHint &) override
Definition: sectfrm.cxx:2585
const SwSectionFrame * GetFollow() const
Definition: sectfrm.hxx:173
SwSectionFormat * GetFormat()
Definition: section.hxx:337
class for collecting anchored objects
Definition: sortedobjs.hxx:49
SwTabFrame is one table in the document layout, containing rows (which contain cells).
Definition: tabfrm.hxx:47
const SwFormatFootnote & GetFootnote() const
Definition: txatbase.hxx:208
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:165
bool getBrowseMode() const
Definition: viewopt.hxx:472
void InvalidateAccessibleEditableState(bool bAllShells, const SwFrame *pFrame=nullptr)
Invalidate editable state for all accessible frames.
Definition: viewimp.cxx:418
vcl::RenderContext * GetOut() const
Definition: viewsh.hxx:347
const SwViewOption * GetViewOptions() const
Definition: viewsh.hxx:436
SwViewShellImp * Imp()
Definition: viewsh.hxx:190
SwRootFrame * GetLayout() const
Definition: viewsh.cxx:2172
void InvalidateAccessibleParaFlowRelation(const SwTextFrame *_pFromTextFrame, const SwTextFrame *_pToTextFrame)
invalidate CONTENT_FLOWS_FROM/_TO relation for paragraphs
Definition: viewsh.cxx:2600
SvtBroadcaster & GetNotifier()
Definition: calbck.hxx:101
#define PROTOCOL(pFrame, nFunc, nAct, pPar)
Definition: dbg_lay.hxx:88
@ PrintArea
@ Section
#define PROTOCOL_ENTER(pFrame, nFunc, nAct, pPar)
Definition: dbg_lay.hxx:92
virtual SotClipboardFormatId GetFormat(const TransferableDataHelper &aHelper) override
@ FTNEND_ATTXTEND_OWNNUMANDFMT
-""- and with own numberformat
Definition: fmtftntx.hxx:33
@ FTNEND_ATTXTEND_OWNNUMSEQ
-""- and with own number sequence
Definition: fmtftntx.hxx:32
@ FTNEND_ATPGORDOCEND
at page or document end
Definition: fmtftntx.hxx:30
MakePageType
Definition: frame.hxx:113
@ MAKEPAGE_INSERT
Definition: frame.hxx:116
@ MAKEPAGE_NONE
Definition: frame.hxx:114
@ MAKEPAGE_NOSECTION
Definition: frame.hxx:118
@ MAKEPAGE_APPEND
Definition: frame.hxx:115
void CalcContent(SwLayoutFrame *pLay, bool bNoColl=false)
Definition: fly.cxx:1423
constexpr TypedWhichId< SvxFrameDirectionItem > RES_FRAMEDIR(120)
constexpr TypedWhichId< SwFormatNoBalancedColumns > RES_COLUMNBALANCE(119)
constexpr TypedWhichId< SwFormatCol > RES_COL(109)
constexpr TypedWhichId< SwFormatChg > RES_FMT_CHG(162)
constexpr TypedWhichId< SwAttrSetChg > RES_ATTRSET_CHG(163)
constexpr TypedWhichId< SvxProtectItem > RES_PROTECT(100)
constexpr TypedWhichId< SwFormatEndAtTextEnd > RES_END_AT_TXTEND(118)
constexpr TypedWhichId< SwFormatFootnoteAtTextEnd > RES_FTN_AT_TXTEND(117)
void * p
const long LONG_MAX
#define SAL_WARN_IF(condition, area, stream)
#define SAL_WARN(area, stream)
tools::Long const nTopMargin
T saturating_add(T a, T b)
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
long Long
const char GetValue[]
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
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
static SwTwips lcl_DeadLine(const SwFrame *pFrame)
Definition: sectfrm.cxx:2133
static void lcl_FindContentFrame(SwContentFrame *&rpContentFrame, SwFootnoteFrame *&rpFootnoteFrame, SwFrame *pFrame, bool &rbChkFootnote)
Definition: sectfrm.cxx:888
static SwContentFrame * lcl_GetNextContentFrame(const SwLayoutFrame *pLay, bool bFwd)
Definition: sectfrm.cxx:587
static void lcl_ColumnRefresh(SwSectionFrame *pSect, bool bFollow)
Definition: sectfrm.cxx:1024
SwFindMode
Definition: sectfrm.hxx:34
SwSectionFrameInvFlags
Definition: sectfrm.hxx:39
#define MINLAY
Definition: swtypes.hxx:62
tools::Long SwTwips
Definition: swtypes.hxx:51
@ FootnoteInvalidation
@ AdjustSizeWithoutFormatting