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