Bug Summary

File:home/maarten/src/libreoffice/core/sw/source/core/layout/sectfrm.cxx
Warning:line 1445, column 21
Forming reference to null pointer

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name sectfrm.cxx -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/11.0.0 -isystem /usr/include/libxml2 -D BOOST_ERROR_CODE_HEADER_ONLY -D BOOST_SYSTEM_NO_DEPRECATED -D CPPU_ENV=gcc3 -D LINUX -D OSL_DEBUG_LEVEL=1 -D SAL_LOG_INFO -D SAL_LOG_WARN -D UNIX -D UNX -D X86_64 -D _PTHREADS -D _REENTRANT -D SW_DLLIMPLEMENTATION -D SWUI_DLL_NAME="libswuilo.so" -D SYSTEM_LIBXML -D EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/i18n -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/common -I /home/maarten/src/libreoffice/core/external/boost/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost -I /home/maarten/src/libreoffice/core/sw/source/core/inc -I /home/maarten/src/libreoffice/core/sw/source/filter/inc -I /home/maarten/src/libreoffice/core/sw/source/uibase/inc -I /home/maarten/src/libreoffice/core/sw/inc -I /home/maarten/src/libreoffice/core/workdir/SdiTarget/sw/sdi -I /home/maarten/src/libreoffice/core/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include/linux -I /home/maarten/src/libreoffice/core/config_host -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/officecfg/registry -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/sw/generated -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/udkapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/offapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/oovbaapi/normal -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/x86_64-redhat-linux -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/11.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wno-missing-braces -std=c++17 -fdeprecated-macro -fdebug-compilation-dir /home/maarten/src/libreoffice/core -ferror-limit 19 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -debug-info-kind=constructor -analyzer-output=html -faddrsig -o /home/maarten/tmp/wis/scan-build-libreoffice/output/report/2020-10-07-141433-9725-1 -x c++ /home/maarten/src/libreoffice/core/sw/source/core/layout/sectfrm.cxx

/home/maarten/src/libreoffice/core/sw/source/core/layout/sectfrm.cxx

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

/home/maarten/src/libreoffice/core/sw/source/core/inc/layfrm.hxx

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#ifndef INCLUDED_SW_SOURCE_CORE_INC_LAYFRM_HXX
20#define INCLUDED_SW_SOURCE_CORE_INC_LAYFRM_HXX
21
22#include "frame.hxx"
23#include <swdllapi.h>
24
25class SwAnchoredObject;
26class SwContentFrame;
27class SwFormatCol;
28struct SwCursorMoveState;
29class SwFrameFormat;
30class SwBorderAttrs;
31class SwFormatFrameSize;
32class SwCellFrame;
33
34/// A layout frame is a frame that contains other frames (m_pLower), e.g. SwPageFrame or SwTabFrame.
35class SW_DLLPUBLIC__attribute__ ((visibility("default"))) SwLayoutFrame: public SwFrame
36{
37 // The SwFrame in disguise
38 friend class SwFlowFrame;
39 friend class SwFrame;
40
41 // Releases the Lower while restructuring columns
42 friend SwFrame* SaveContent( SwLayoutFrame *, SwFrame * );
43 friend void RestoreContent( SwFrame *, SwLayoutFrame *, SwFrame *pSibling );
44
45protected:
46
47 virtual void DestroyImpl() override;
48 virtual ~SwLayoutFrame() override;
49
50 virtual void Format( vcl::RenderContext* pRenderContext, const SwBorderAttrs *pAttrs = nullptr ) override;
51 virtual void MakeAll(vcl::RenderContext* pRenderContext) override;
52
53 SwFrame * m_pLower;
54 std::vector<SwAnchoredObject*> m_VertPosOrientFramesFor;
55
56 virtual SwTwips ShrinkFrame( SwTwips, bool bTst = false, bool bInfo = false ) override;
57 virtual SwTwips GrowFrame ( SwTwips, bool bTst = false, bool bInfo = false ) override;
58
59 long CalcRel( const SwFormatFrameSize &rSz ) const;
60
61public:
62 // --> #i28701#
63
64 virtual void PaintSubsidiaryLines( const SwPageFrame*, const SwRect& ) const;
65 void RefreshLaySubsidiary( const SwPageFrame*, const SwRect& ) const;
66 void RefreshExtraData( const SwRect & ) const;
67
68 /// Change size of lowers proportionally
69 void ChgLowersProp( const Size& rOldSize );
70
71 void AdjustColumns( const SwFormatCol *pCol, bool bAdjustAttributes );
72
73 void ChgColumns( const SwFormatCol &rOld, const SwFormatCol &rNew,
74 const bool bChgFootnote = false );
75
76 /// Paints the column separation line for the inner columns
77 void PaintColLines( const SwRect &, const SwFormatCol &,
78 const SwPageFrame * ) const;
79
80 virtual bool FillSelection( SwSelectionList& rList, const SwRect& rRect ) const override;
81
82 virtual bool GetModelPositionForViewPoint( SwPosition *, Point&,
83 SwCursorMoveState* = nullptr, bool bTestBackground = false ) const override;
84
85 virtual void Cut() override;
86 virtual void Paste( SwFrame* pParent, SwFrame* pSibling = nullptr ) override;
87
88 /**
89 * Finds the closest Content for the SPoint
90 * Is used for Pages, Flys and Cells if GetModelPositionForViewPoint failed
91 */
92 const SwContentFrame* GetContentPos( Point &rPoint, const bool bDontLeave,
93 const bool bBodyOnly = false,
94 SwCursorMoveState *pCMS = nullptr,
95 const bool bDefaultExpand = true ) const;
96
97 SwLayoutFrame( SwFrameFormat*, SwFrame* );
98
99 virtual void PaintSwFrame( vcl::RenderContext& rRenderContext, SwRect const&,
100 SwPrintData const*const pPrintData = nullptr ) const override;
101 const SwFrame *Lower() const { return m_pLower; }
102 SwFrame *Lower() { return m_pLower; }
59
Returning null pointer, which participates in a condition later
103 const SwContentFrame *ContainsContent() const;
104 inline SwContentFrame *ContainsContent();
105 const SwCellFrame *FirstCell() const;
106 inline SwCellFrame *FirstCell();
107
108 /**
109 * Method <ContainsAny()> doesn't investigate content of footnotes by default.
110 * But under certain circumstances this investigation is intended.
111 * Thus, introduce new optional parameter <_bInvestigateFootnoteForSections>.
112 * It's default is <false>, still indicating that content of footnotes isn't
113 * investigated for sections.
114 */
115 const SwFrame *ContainsAny( const bool _bInvestigateFootnoteForSections = false ) const;
116 inline SwFrame *ContainsAny( const bool _bInvestigateFootnoteForSections = false );
117 bool IsAnLower( const SwFrame * ) const;
118
119 virtual const SwFrameFormat *GetFormat() const;
120 virtual SwFrameFormat *GetFormat();
121 void SetFrameFormat( SwFrameFormat* );
122
123 /**
124 * Moving the Footnotes of all Lowers - starting from StartContent
125 *
126 * @returns true if at least one Footnote was moved
127 * Calls the page number update if bFootnoteNums is set
128 */
129 bool MoveLowerFootnotes( SwContentFrame *pStart, SwFootnoteBossFrame *pOldBoss,
130 SwFootnoteBossFrame *pNewBoss, const bool bFootnoteNums );
131
132 // --> #i28701# - change purpose of method and its name
133 // --> #i44016# - add parameter <_bUnlockPosOfObjs> to
134 /// force an unlockposition call for the lower objects.
135 void NotifyLowerObjs( const bool _bUnlockPosOfObjs = false );
136
137 /**
138 * Invalidates the inner Frames, whose width and/or height are
139 * calculated using percentages.
140 * Frames that are anchored to this or inner Frames, are also invalidated.
141 */
142 void InvaPercentLowers( SwTwips nDiff = 0 );
143
144 /// Called by Format for Frames and Areas with columns
145 void FormatWidthCols( const SwBorderAttrs &, const SwTwips nBorder,
146 const SwTwips nMinHeight );
147
148 /**
149 * InnerHeight returns the height of the content and may be bigger or
150 * less than the PrtArea-Height of the layoutframe himself
151 */
152 SwTwips InnerHeight() const;
153
154 /** method to check relative position of layout frame to
155 a given layout frame.
156
157 refactoring of pseudo-local method <lcl_Apres(..)> in
158 <txtftn.cxx> for #104840#.
159
160 @param _aCheckRefLayFrame
161 constant reference of an instance of class <SwLayoutFrame> which
162 is used as the reference for the relative position check.
163
164 @return true, if <this> is positioned before the layout frame <p>
165 */
166 bool IsBefore( const SwLayoutFrame* _pCheckRefLayFrame ) const;
167
168 const SwFrame* GetLastLower() const;
169 inline SwFrame* GetLastLower();
170
171 virtual void PaintBreak() const;
172
173 void SetVertPosOrientFrameFor(SwAnchoredObject *pObj)
174 {
175 m_VertPosOrientFramesFor.push_back(pObj);
176 }
177
178 void ClearVertPosOrientFrameFor(SwAnchoredObject *pObj)
179 {
180 m_VertPosOrientFramesFor.erase(
181 std::remove(m_VertPosOrientFramesFor.begin(),
182 m_VertPosOrientFramesFor.end(), pObj),
183 m_VertPosOrientFramesFor.end());
184 }
185};
186
187/**
188 * In order to save us from duplicating implementations, we cast here
189 * a little.
190 */
191inline SwContentFrame* SwLayoutFrame::ContainsContent()
192{
193 return const_cast<SwContentFrame*>(static_cast<const SwLayoutFrame*>(this)->ContainsContent());
194}
195
196inline SwCellFrame* SwLayoutFrame::FirstCell()
197{
198 return const_cast<SwCellFrame*>(static_cast<const SwLayoutFrame*>(this)->FirstCell());
199}
200
201inline SwFrame* SwLayoutFrame::ContainsAny( const bool _bInvestigateFootnoteForSections )
202{
203 return const_cast<SwFrame*>(static_cast<const SwLayoutFrame*>(this)->ContainsAny( _bInvestigateFootnoteForSections ));
204}
205
206/**
207 * These SwFrame inlines are here, so that frame.hxx does not need to include layfrm.hxx
208 */
209inline bool SwFrame::IsColBodyFrame() const
210{
211 return mnFrameType == SwFrameType::Body && GetUpper()->IsColumnFrame();
2
Assuming field 'mnFrameType' is not equal to Body
3
Returning zero, which participates in a condition later
7
Assuming field 'mnFrameType' is not equal to Body
8
Returning zero, which participates in a condition later
212}
213
214inline bool SwFrame::IsPageBodyFrame() const
215{
216 return mnFrameType == SwFrameType::Body && GetUpper()->IsPageFrame();
217}
218
219inline SwFrame* SwLayoutFrame::GetLastLower()
220{
221 return const_cast<SwFrame*>(static_cast<const SwLayoutFrame*>(this)->GetLastLower());
222}
223
224#endif // INCLUDED_SW_SOURCE_CORE_INC_LAYFRM_HXX
225
226/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/sw/source/core/inc/frame.hxx

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#ifndef INCLUDED_SW_SOURCE_CORE_INC_FRAME_HXX
21#define INCLUDED_SW_SOURCE_CORE_INC_FRAME_HXX
22
23#include <drawinglayer/primitive2d/baseprimitive2d.hxx>
24#include <editeng/borderline.hxx>
25#include <svl/poolitem.hxx>
26#include <swtypes.hxx>
27#include <swrect.hxx>
28#include <calbck.hxx>
29#include <svl/SfxBroadcaster.hxx>
30#include <o3tl/typed_flags_set.hxx>
31#include <com/sun/star/style/TabStop.hpp>
32#include <basegfx/matrix/b2dhommatrix.hxx>
33#include <vcl/outdev.hxx>
34
35#include <memory>
36
37namespace drawinglayer::processor2d { class BaseProcessor2D; }
38
39class SwLayoutFrame;
40class SwRootFrame;
41class SwPageFrame;
42class SwBodyFrame;
43class SwFlyFrame;
44class SwSectionFrame;
45class SwFootnoteFrame;
46class SwFootnoteBossFrame;
47class SwTabFrame;
48class SwRowFrame;
49class SwContentFrame;
50class SwAttrSet;
51class Color;
52class SwBorderAttrs;
53class SwCache;
54class SvxBrushItem;
55class SvxFormatBreakItem;
56class SwFormatPageDesc;
57class SwSelectionList;
58struct SwPosition;
59struct SwCursorMoveState;
60class SwFormat;
61class SwPrintData;
62class SwSortedObjs;
63class SwAnchoredObject;
64enum class SvxFrameDirection;
65class IDocumentDrawModelAccess;
66
67// Each FrameType is represented here as a bit.
68// The bits must be set in a way that it can be determined with masking of
69// which kind of FrameType an instance is _and_ from what classes it was derived.
70// Each frame has in its base class a member that must be set by the
71// constructors accordingly.
72enum class SwFrameType
73{
74 None = 0x0000,
75 Root = 0x0001,
76 Page = 0x0002,
77 Column = 0x0004,
78 Header = 0x0008,
79 Footer = 0x0010,
80 FtnCont = 0x0020,
81 Ftn = 0x0040,
82 Body = 0x0080,
83 Fly = 0x0100,
84 Section = 0x0200,
85// UNUSED 0x0400
86 Tab = 0x0800,
87 Row = 0x1000,
88 Cell = 0x2000,
89 Txt = 0x4000,
90 NoTxt = 0x8000,
91};
92
93namespace o3tl
94{
95 template<> struct typed_flags<SwFrameType> : is_typed_flags<SwFrameType, 0xfbff> {};
96};
97
98// for internal use some common combinations
99#define FRM_LAYOUTSwFrameType(0x3bFF) SwFrameType(0x3bFF)
100#define FRM_ALLSwFrameType(0xfbff) SwFrameType(0xfbff)
101#define FRM_CNTNT(SwFrameType::Txt | SwFrameType::NoTxt) (SwFrameType::Txt | SwFrameType::NoTxt)
102#define FRM_FTNBOSS(SwFrameType::Page | SwFrameType::Column) (SwFrameType::Page | SwFrameType::Column)
103#define FRM_ACCESSIBLE(SwFrameType::Root | SwFrameType::Page | SwFrameType::Header |
SwFrameType::Footer | SwFrameType::Ftn | SwFrameType::Fly | SwFrameType
::Tab | SwFrameType::Cell | SwFrameType::Txt)
(SwFrameType::Root | SwFrameType::Page | SwFrameType::Header | SwFrameType::Footer | SwFrameType::Ftn | SwFrameType::Fly | SwFrameType::Tab | SwFrameType::Cell | SwFrameType::Txt)
104#define FRM_NEIGHBOUR(SwFrameType::Column | SwFrameType::Cell) (SwFrameType::Column | SwFrameType::Cell)
105#define FRM_NOTE_VERT(SwFrameType::FtnCont | SwFrameType::Ftn | SwFrameType::Section
| SwFrameType::Tab | SwFrameType::Row | SwFrameType::Cell | SwFrameType
::Txt)
(SwFrameType::FtnCont | SwFrameType::Ftn | SwFrameType::Section | SwFrameType::Tab | SwFrameType::Row | SwFrameType::Cell | SwFrameType::Txt)
106#define FRM_HEADFOOT(SwFrameType::Header | SwFrameType::Footer) (SwFrameType::Header | SwFrameType::Footer)
107#define FRM_BODYFTNC(SwFrameType::FtnCont | SwFrameType::Body) (SwFrameType::FtnCont | SwFrameType::Body)
108
109// for GetNextLeaf/GetPrevLeaf.
110enum MakePageType
111{
112 MAKEPAGE_NONE, // do not create page/footnote
113 MAKEPAGE_APPEND, // only append page if needed
114 MAKEPAGE_INSERT, // add or append page if needed
115 MAKEPAGE_FTN, // add footnote if needed
116 MAKEPAGE_NOSECTION // Don't create section frames
117};
118
119namespace drawinglayer::attribute {
120 class SdrAllFillAttributesHelper;
121 typedef std::shared_ptr< SdrAllFillAttributesHelper > SdrAllFillAttributesHelperPtr;
122}
123
124/// Helper class to isolate geometry-defining members of SwFrame
125/// and to control their accesses. Moved to own class to have no
126/// hidden accesses to 'private' members anymore.
127///
128/// Added most important flags about the state of this geometric
129/// information and if it is valid or not
130class SAL_DLLPUBLIC_RTTI__attribute__ ((type_visibility("default"))) SwFrameAreaDefinition
131{
132private:
133 friend void FriendHackInvalidateRowFrame(SwFrameAreaDefinition &);
134
135 // The absolute position and size of the SwFrame in the document.
136 // This values are set by the layouter implementations
137 SwRect maFrameArea;
138
139 // The 'inner' Frame Area defined by a SwRect relative to FrameArea:
140 // When identical to FrameArea, Pos() will be (0, 0) and Size identical.
141 SwRect maFramePrintArea;
142
143 // bitfield
144 bool mbFrameAreaPositionValid : 1;
145 bool mbFrameAreaSizeValid : 1;
146 bool mbFramePrintAreaValid : 1;
147
148 // #i65250#
149 // frame ID is now in general available - used for layout loop control
150 static sal_uInt32 mnLastFrameId;
151 const sal_uInt32 mnFrameId;
152
153protected:
154 // write access to mb*Valid flags
155 void setFrameAreaPositionValid(bool bNew);
156 void setFrameAreaSizeValid(bool bNew);
157 void setFramePrintAreaValid(bool bNew);
158
159public:
160 SwFrameAreaDefinition();
161 virtual ~SwFrameAreaDefinition();
162
163 // read access to mb*Valid flags
164 bool isFrameAreaPositionValid() const { return mbFrameAreaPositionValid; }
165 bool isFrameAreaSizeValid() const { return mbFrameAreaSizeValid; }
166 bool isFramePrintAreaValid() const { return mbFramePrintAreaValid; }
167
168 // syntactic sugar: test whole FrameAreaDefinition
169 bool isFrameAreaDefinitionValid() const { return isFrameAreaPositionValid() && isFrameAreaSizeValid() && isFramePrintAreaValid(); }
170
171 // #i65250#
172 sal_uInt32 GetFrameId() const { return mnFrameId; }
173
174 // read accesses to FrameArea definitions - only const access allowed.
175 // Do *not* const_cast results, it is necessary to track changes. use
176 // the below offered WriteAccess helper classes instead
177 const SwRect& getFrameArea() const { return maFrameArea; }
178 const SwRect& getFramePrintArea() const { return maFramePrintArea; }
179
180 // helper class(es) for FrameArea manipulation. These
181 // have to be used to apply changes to FrameAreas. They hold a copy of the
182 // SwRect for manipulation. It gets written back at destruction. Thus, this
183 // mechanism depends on scope usage, take care. It prevents errors using
184 // different instances of SwFrame in get/set methods which is more safe
185 class FrameAreaWriteAccess : public SwRect
186 {
187 private:
188 SwFrameAreaDefinition& mrTarget;
189
190 FrameAreaWriteAccess(const FrameAreaWriteAccess&) = delete;
191 FrameAreaWriteAccess& operator=(const FrameAreaWriteAccess&) = delete;
192
193 public:
194 FrameAreaWriteAccess(SwFrameAreaDefinition& rTarget) : SwRect(rTarget.getFrameArea()), mrTarget(rTarget) {}
195 ~FrameAreaWriteAccess();
196 void setSwRect(const SwRect& rNew) { *reinterpret_cast< SwRect* >(this) = rNew; }
197 };
198
199 // same helper for FramePrintArea
200 class FramePrintAreaWriteAccess : public SwRect
201 {
202 private:
203 SwFrameAreaDefinition& mrTarget;
204
205 FramePrintAreaWriteAccess(const FramePrintAreaWriteAccess&) = delete;
206 FramePrintAreaWriteAccess& operator=(const FramePrintAreaWriteAccess&) = delete;
207
208 public:
209 FramePrintAreaWriteAccess(SwFrameAreaDefinition& rTarget) : SwRect(rTarget.getFramePrintArea()), mrTarget(rTarget) {}
210 ~FramePrintAreaWriteAccess();
211 void setSwRect(const SwRect& rNew) { *reinterpret_cast< SwRect* >(this) = rNew; }
212 };
213
214 // RotateFlyFrame3 - Support for Transformations
215 // Hand out the Transformations for the current FrameAreaDefinition
216 // for the FrameArea and FramePrintArea.
217 // FramePrintArea is not relative to FrameArea in this
218 // transformation representation (to make it easier to use and understand).
219 // There is no 'set' method since SwFrame is a layout object. For
220 // some cases rotation will be included (used for SwGrfNode in inner
221 // SwFrame of a SwFlyFrame)
222 virtual basegfx::B2DHomMatrix getFrameAreaTransformation() const;
223 virtual basegfx::B2DHomMatrix getFramePrintAreaTransformation() const;
224
225 // RotateFlyFrame3 - Support for Transformations
226 // Modify current transformations by applying given translation
227 virtual void transform_translate(const Point& rOffset);
228};
229
230/// RotateFlyFrame3: Helper class when you want to make your SwFrame derivate
231/// transformable. It provides some tooling to do so. To use, add as member
232/// (see e.g. SwFlyFreeFrame which uses 'std::unique_ptr< TransformableSwFrame >')
233class TransformableSwFrame
234{
235private:
236 // The SwFrameAreaDefinition to work on
237 SwFrameAreaDefinition& mrSwFrameAreaDefinition;
238
239 // FrameAreaTransformation and FramePrintAreaTransformation
240 // !identity when needed (translate/scale is used (e.g. rotation))
241 basegfx::B2DHomMatrix maFrameAreaTransformation;
242 basegfx::B2DHomMatrix maFramePrintAreaTransformation;
243
244public:
245 TransformableSwFrame(SwFrameAreaDefinition& rSwFrameAreaDefinition)
246 : mrSwFrameAreaDefinition(rSwFrameAreaDefinition),
247 maFrameAreaTransformation(),
248 maFramePrintAreaTransformation()
249 {
250 }
251
252 // get SwFrameArea in transformation form
253 const basegfx::B2DHomMatrix& getLocalFrameAreaTransformation() const
254 {
255 return maFrameAreaTransformation;
256 }
257
258 // get SwFramePrintArea in transformation form
259 const basegfx::B2DHomMatrix& getLocalFramePrintAreaTransformation() const
260 {
261 return maFramePrintAreaTransformation;
262 }
263
264 // Helpers to re-create the untransformed SwRect(s) originally
265 // in the SwFrameAreaDefinition, based on the current Transformations.
266 SwRect getUntransformedFrameArea() const;
267 SwRect getUntransformedFramePrintArea() const;
268
269 // Helper method to re-create FrameAreaTransformations based on the
270 // current FrameAreaDefinition transformed by given rotation and Center
271 void createFrameAreaTransformations(
272 double fRotation,
273 const basegfx::B2DPoint& rCenter);
274
275 // Tooling method to reset the SwRect(s) in the current
276 // SwFrameAreaDefinition which are already adapted to
277 // Transformation back to the untransformed state, using
278 // the getUntransformedFrame*Area calls above when needed.
279 // Only the SwRect(s) are changed back, not the transformations.
280 void restoreFrameAreas();
281
282 // Re-Creates the SwRect(s) as BoundAreas based on the current
283 // set Transformations.
284 void adaptFrameAreasToTransformations();
285
286 // Modify current definitions by applying the given transformation
287 void transform(const basegfx::B2DHomMatrix& aTransform);
288};
289
290/**
291 * Base class of the Writer layout elements.
292 *
293 * This includes not only fly frames, but everything down to the paragraph
294 * level: pages, headers, footers, etc. (Inside a paragraph SwLinePortion
295 * instances are used.)
296 */
297class SW_DLLPUBLIC__attribute__ ((visibility("default"))) SwFrame : public SwFrameAreaDefinition, public SwClient, public SfxBroadcaster
298{
299 // the hidden Frame
300 friend class SwFlowFrame;
301 friend class SwLayoutFrame;
302 friend class SwLooping;
303 friend class SwDeletionChecker; // for GetDep()
304
305 // voids lower during creation of a column
306 friend SwFrame *SaveContent( SwLayoutFrame *, SwFrame* pStart );
307 friend void RestoreContent( SwFrame *, SwLayoutFrame *, SwFrame *pSibling );
308
309 // for validating a mistakenly invalidated one in SwContentFrame::MakeAll
310 friend void ValidateSz( SwFrame *pFrame );
311 // implemented in text/txtftn.cxx, prevents Footnote oscillation
312 friend void ValidateText( SwFrame *pFrame );
313
314 friend void MakeNxt( SwFrame *pFrame, SwFrame *pNxt );
315
316 // cache for (border) attributes
317 static SwCache *mpCache;
318
319 SwRootFrame *mpRoot;
320 SwLayoutFrame *mpUpper;
321 SwFrame *mpNext;
322 SwFrame *mpPrev;
323
324 // sw_redlinehide: hide these dangerous SwClient functions
325 using SwClient::GetRegisteredInNonConst;
326 using SwClient::GetRegisteredIn;
327
328 SwFrame *FindNext_();
329 SwFrame *FindPrev_();
330
331 /** method to determine next content frame in the same environment
332 for a flow frame (content frame, table frame, section frame)
333
334 #i27138# - adding documentation:
335 Travelling downwards through the layout to determine the next content
336 frame in the same environment. There are several environments in a
337 document, which form a closed context regarding this function. These
338 environments are:
339 - Each page header
340 - Each page footer
341 - Each unlinked fly frame
342 - Each group of linked fly frames
343 - All footnotes
344 - All document body frames
345 #i27138# - adding parameter <_bInSameFootnote>
346 Its default value is <false>. If its value is <true>, the environment
347 'All footnotes' is no longer treated. Instead each footnote is treated
348 as an own environment.
349
350 @param _bInSameFootnote
351 input parameter - boolean indicating, that the found next content
352 frame has to be in the same footnote frame. This parameter is only
353 relevant for flow frames in footnotes.
354
355 @return SwContentFrame*
356 pointer to the found next content frame. It's NULL, if none exists.
357 */
358 SwContentFrame* FindNextCnt_( const bool _bInSameFootnote );
359
360 /** method to determine previous content frame in the same environment
361 for a flow frame (content frame, table frame, section frame)
362
363 #i27138#
364 Travelling upwards through the layout to determine the previous content
365 frame in the same environment. There are several environments in a
366 document, which form a closed context regarding this function. These
367 environments are:
368 - Each page header
369 - Each page footer
370 - Each unlinked fly frame
371 - Each group of linked fly frames
372 - All footnotes
373 - All document body frames
374 #i27138# - adding parameter <_bInSameFootnote>
375 Its default value is <false>. If its value is <true>, the environment
376 'All footnotes' is no longer treated. Instead each footnote is treated
377 as an own environment.
378
379 The found previous content frame has to be in the same footnote frame. This is only
380 relevant for flow frames in footnotes.
381
382 @return SwContentFrame*
383 pointer to the found previous content frame. It's NULL, if none exists.
384 */
385 SwContentFrame* FindPrevCnt_();
386
387 void UpdateAttrFrame( const SfxPoolItem*, const SfxPoolItem*, sal_uInt8 & );
388 SwFrame* GetIndNext_();
389 void SetDirFlags( bool bVert );
390
391 const SwLayoutFrame* ImplGetNextLayoutLeaf( bool bFwd ) const;
392
393 SwPageFrame* ImplFindPageFrame();
394
395protected:
396 std::unique_ptr<SwSortedObjs> m_pDrawObjs; // draw objects, can be null
397 SwFrameType mnFrameType; //Who am I?
398
399 bool mbInDtor : 1;
400 bool mbInvalidR2L : 1;
401 bool mbDerivedR2L : 1;
402 bool mbRightToLeft : 1;
403 bool mbInvalidVert : 1;
404 bool mbDerivedVert : 1;
405 bool mbVertical : 1;
406
407 bool mbVertLR : 1;
408 bool mbVertLRBT : 1;
409
410 bool mbValidLineNum : 1;
411 bool mbFixSize : 1;
412
413 // if true, frame will be painted completely even content was changed
414 // only partially. For ContentFrames a border (from Action) will exclusively
415 // painted if <mbCompletePaint> is true.
416 bool mbCompletePaint : 1;
417
418 bool mbRetouche : 1; // frame is responsible for retouching
419
420 bool mbInfInvalid : 1; // InfoFlags are invalid
421 bool mbInfBody : 1; // Frame is in document body
422 bool mbInfTab : 1; // Frame is in a table
423 bool mbInfFly : 1; // Frame is in a Fly
424 bool mbInfFootnote : 1; // Frame is in a footnote
425 bool mbInfSct : 1; // Frame is in a section
426 bool mbColLocked : 1; // lock Grow/Shrink for column-wise section
427 // or fly frames, will be set in Format
428 bool m_isInDestroy : 1;
429 bool mbForbidDelete : 1;
430
431 void ColLock() { mbColLocked = true; }
432 void ColUnlock() { mbColLocked = false; }
433
434 virtual void DestroyImpl();
435 virtual ~SwFrame() override;
436
437 // Only used by SwRootFrame Ctor to get 'this' into mpRoot...
438 void setRootFrame( SwRootFrame* pRoot ) { mpRoot = pRoot; }
439
440 SwPageFrame *InsertPage( SwPageFrame *pSibling, bool bFootnote );
441 void PrepareMake(vcl::RenderContext* pRenderContext);
442 void OptPrepareMake();
443 virtual void MakePos();
444 // Format next frame of table frame to assure keeping attributes.
445 // In case of nested tables method <SwFrame::MakeAll()> is called to
446 // avoid formatting of superior table frame.
447 friend SwFrame* sw_FormatNextContentForKeep( SwTabFrame* pTabFrame );
448
449 virtual void MakeAll(vcl::RenderContext* pRenderContext) = 0;
450 // adjust frames of a page
451 SwTwips AdjustNeighbourhood( SwTwips nDiff, bool bTst = false );
452
453 // change only frame size not the size of PrtArea
454 virtual SwTwips ShrinkFrame( SwTwips, bool bTst = false, bool bInfo = false ) = 0;
455 virtual SwTwips GrowFrame ( SwTwips, bool bTst = false, bool bInfo = false ) = 0;
456
457 /// use these so we can grep for SwFrame's GetRegisteredIn accesses
458 /// beware that SwTextFrame may return sw::WriterMultiListener
459 SwModify *GetDep() { return GetRegisteredInNonConst(); }
460 const SwModify *GetDep() const { return GetRegisteredIn(); }
461
462 SwFrame( SwModify*, SwFrame* );
463
464 void CheckDir( SvxFrameDirection nDir, bool bVert, bool bOnlyBiDi, bool bBrowse );
465
466 /** enumeration for the different invalidations
467 #i28701#
468 */
469 enum InvalidationType
470 {
471 INVALID_SIZE, INVALID_PRTAREA, INVALID_POS, INVALID_LINENUM, INVALID_ALL
472 };
473
474 /** method to determine, if an invalidation is allowed.
475 #i28701
476 */
477 virtual bool InvalidationAllowed( const InvalidationType _nInvalid ) const;
478
479 /** method to perform additional actions on an invalidation
480
481 #i28701#
482 Method has *only* to contain actions, which has to be performed on
483 *every* assignment of the corresponding flag to <false>.
484 */
485 virtual void ActionOnInvalidation( const InvalidationType _nInvalid );
486
487 // draw shadow and borders
488 void PaintShadow( const SwRect&, SwRect&, const SwBorderAttrs& ) const;
489 virtual void Modify( const SfxPoolItem*, const SfxPoolItem* ) override;
490
491 virtual const IDocumentDrawModelAccess& getIDocumentDrawModelAccess( );
492
493public:
494 virtual css::uno::Sequence< css::style::TabStop > GetTabStopInfo( SwTwips )
495 {
496 return css::uno::Sequence< css::style::TabStop >();
497 }
498
499
500 SwFrameType GetType() const { return mnFrameType; }
501
502 static SwCache &GetCache() { return *mpCache; }
503 static SwCache *GetCachePtr() { return mpCache; }
504 static void SetCache( SwCache *pNew ) { mpCache = pNew; }
505
506 // change PrtArea size and FrameSize
507 SwTwips Shrink( SwTwips, bool bTst = false, bool bInfo = false );
508 SwTwips Grow ( SwTwips, bool bTst = false, bool bInfo = false );
509
510 // different methods for inserting in layout tree (for performance reasons)
511
512 // insert before pBehind or at the end of the chain below mpUpper
513 void InsertBefore( SwLayoutFrame* pParent, SwFrame* pBehind );
514 // insert after pBefore or at the beginning of the chain below mpUpper
515 void InsertBehind( SwLayoutFrame *pParent, SwFrame *pBefore );
516 // insert before pBehind or at the end of the chain while considering
517 // the siblings of pSct
518 bool InsertGroupBefore( SwFrame* pParent, SwFrame* pWhere, SwFrame* pSct );
519 void RemoveFromLayout();
520
521 // For internal use only - who ignores this will be put in a sack and has
522 // to stay there for two days
523 // Does special treatment for Get_[Next|Prev]Leaf() (for tables).
524 SwLayoutFrame *GetLeaf( MakePageType eMakePage, bool bFwd );
525 SwLayoutFrame *GetNextLeaf ( MakePageType eMakePage );
526 SwLayoutFrame *GetNextFootnoteLeaf( MakePageType eMakePage );
527 SwLayoutFrame *GetNextSctLeaf( MakePageType eMakePage );
528 SwLayoutFrame *GetNextCellLeaf();
529 SwLayoutFrame *GetPrevLeaf ();
530 SwLayoutFrame *GetPrevFootnoteLeaf( MakePageType eMakeFootnote );
531 SwLayoutFrame *GetPrevSctLeaf();
532 SwLayoutFrame *GetPrevCellLeaf();
533 const SwLayoutFrame *GetLeaf ( MakePageType eMakePage, bool bFwd,
534 const SwFrame *pAnch ) const;
535
536 bool WrongPageDesc( SwPageFrame* pNew );
537
538 //#i28701# - new methods to append/remove drawing objects
539 void AppendDrawObj( SwAnchoredObject& _rNewObj );
540 void RemoveDrawObj( SwAnchoredObject& _rToRemoveObj );
541
542 // work with chain of FlyFrames
543 void AppendFly( SwFlyFrame *pNew );
544 void RemoveFly( SwFlyFrame *pToRemove );
545 const SwSortedObjs *GetDrawObjs() const { return m_pDrawObjs.get(); }
546 SwSortedObjs *GetDrawObjs() { return m_pDrawObjs.get(); }
547 // #i28701# - change purpose of method and adjust its name
548 void InvalidateObjs( const bool _bNoInvaOfAsCharAnchoredObjs = true );
549
550 virtual void PaintSwFrameShadowAndBorder(
551 const SwRect&,
552 const SwPageFrame* pPage,
553 const SwBorderAttrs&) const;
554 void PaintBaBo( const SwRect&, const SwPageFrame *pPage,
555 const bool bOnlyTextBackground = false) const;
556 void PaintSwFrameBackground( const SwRect&, const SwPageFrame *pPage,
557 const SwBorderAttrs &,
558 const bool bLowerMode = false,
559 const bool bLowerBorder = false,
560 const bool bOnlyTextBackground = false ) const;
561 void PaintBorderLine( const SwRect&, const SwRect&, const SwPageFrame*,
562 const Color *pColor,
563 const SvxBorderLineStyle = SvxBorderLineStyle::SOLID ) const;
564
565 std::unique_ptr<drawinglayer::processor2d::BaseProcessor2D> CreateProcessor2D( ) const;
566 void ProcessPrimitives( const drawinglayer::primitive2d::Primitive2DContainer& rSequence ) const;
567
568 // retouch, not in the area of the given Rect!
569 void Retouch( const SwPageFrame *pPage, const SwRect &rRect ) const;
570
571 bool GetBackgroundBrush(
572 drawinglayer::attribute::SdrAllFillAttributesHelperPtr& rFillAttributes,
573 const SvxBrushItem*& rpBrush,
574 const Color*& rpColor,
575 SwRect &rOrigRect,
576 bool bLowerMode,
577 bool bConsiderTextBox ) const;
578
579 inline void SetCompletePaint() const;
580 inline void ResetCompletePaint() const;
581 bool IsCompletePaint() const { return mbCompletePaint; }
582
583 inline void SetRetouche() const;
584 inline void ResetRetouche() const;
585 bool IsRetouche() const { return mbRetouche; }
586
587 void SetInfFlags();
588 void InvalidateInfFlags() { mbInfInvalid = true; }
589 inline bool IsInDocBody() const; // use InfoFlags, determine flags
590 inline bool IsInFootnote() const; // if necessary
591 inline bool IsInTab() const;
592 inline bool IsInFly() const;
593 inline bool IsInSct() const;
594
595 // If frame is inside a split table row, this function returns
596 // the corresponding row frame in the follow table.
597 const SwRowFrame* IsInSplitTableRow() const;
598
599 // If frame is inside a follow flow row, this function returns
600 // the corresponding row frame master table
601 const SwRowFrame* IsInFollowFlowRow() const;
602
603 bool IsInBalancedSection() const;
604
605 inline bool IsVertical() const;
606 inline bool IsVertLR() const;
607 inline bool IsVertLRBT() const;
608
609 void SetDerivedVert( bool bNew ){ mbDerivedVert = bNew; }
610 void SetInvalidVert( bool bNew) { mbInvalidVert = bNew; }
611 inline bool IsRightToLeft() const;
612 void SetDerivedR2L( bool bNew ) { mbDerivedR2L = bNew; }
613
614 void CheckDirChange();
615 // returns upper left frame position for LTR and
616 // upper right frame position for Asian / RTL frames
617 Point GetFrameAnchorPos( bool bIgnoreFlysAnchoredAtThisFrame ) const;
618
619 /** determine, if frame is moveable in given environment
620
621 method replaced 'old' method <bool IsMoveable() const>.
622 Determines, if frame is moveable in given environment. if no environment
623 is given (parameter _pLayoutFrame == 0), the movability in the actual
624 environment (<GetUpper()) is checked.
625
626 @param _pLayoutFrame
627 input parameter - given environment (layout frame), in which the movability
628 will be checked. If not set ( == 0 ), actual environment is taken.
629
630 @return boolean, indicating, if frame is moveable in given environment
631 */
632 bool IsMoveable( const SwLayoutFrame* _pLayoutFrame = nullptr ) const;
633
634 // Is it permitted for the (Text)Frame to add a footnote in the current
635 // environment (not e.g. for repeating table headlines)
636 bool IsFootnoteAllowed() const;
637
638 virtual void Format( vcl::RenderContext* pRenderContext, const SwBorderAttrs *pAttrs = nullptr );
639
640 virtual void CheckDirection( bool bVert );
641
642 void ReinitializeFrameSizeAttrFlags();
643
644 /// WARNING: this may not return correct RES_PAGEDESC/RES_BREAK items for
645 /// SwTextFrame, use GetBreakItem()/GetPageDescItem() instead
646 const SwAttrSet *GetAttrSet() const;
647 virtual const SvxFormatBreakItem& GetBreakItem() const;
648 virtual const SwFormatPageDesc& GetPageDescItem() const;
649
650 bool HasFixSize() const { return mbFixSize; }
651
652 // check all pages (starting from the given) and correct them if needed
653 static void CheckPageDescs( SwPageFrame *pStart, bool bNotifyFields = true, SwPageFrame** ppPrev = nullptr);
654
655 // might return 0, with and without const
656 SwFrame *GetNext() { return mpNext; }
657 SwFrame *GetPrev() { return mpPrev; }
658 SwLayoutFrame *GetUpper() { return mpUpper; }
659 SwRootFrame *getRootFrame(){ return mpRoot; }
660 SwPageFrame *FindPageFrame() { return IsPageFrame() ? reinterpret_cast<SwPageFrame*>(this) : ImplFindPageFrame(); }
661 SwFrame *FindColFrame();
662 SwRowFrame *FindRowFrame();
663 SwFootnoteBossFrame *FindFootnoteBossFrame( bool bFootnotes = false );
664 SwTabFrame *ImplFindTabFrame();
665 SwFootnoteFrame *ImplFindFootnoteFrame();
666 SwFlyFrame *ImplFindFlyFrame();
667 SwSectionFrame *ImplFindSctFrame();
668 const SwBodyFrame *ImplFindBodyFrame() const;
669 SwFrame *FindFooterOrHeader();
670 SwFrame *GetLower();
671 const SwFrame *GetNext() const { return mpNext; }
672 const SwFrame *GetPrev() const { return mpPrev; }
673 const SwLayoutFrame *GetUpper() const { return mpUpper; }
674 const SwRootFrame *getRootFrame() const { return mpRoot; }
675 inline SwTabFrame *FindTabFrame();
676 inline SwFootnoteFrame *FindFootnoteFrame();
677 inline SwFlyFrame *FindFlyFrame();
678 inline SwSectionFrame *FindSctFrame();
679 inline SwFrame *FindNext();
680 // #i27138# - add parameter <_bInSameFootnote>
681 SwContentFrame* FindNextCnt( const bool _bInSameFootnote = false );
682 inline SwFrame *FindPrev();
683 inline const SwPageFrame *FindPageFrame() const;
684 inline const SwFootnoteBossFrame *FindFootnoteBossFrame( bool bFootnote = false ) const;
685 inline const SwFrame *FindColFrame() const;
686 inline const SwFrame *FindFooterOrHeader() const;
687 inline const SwTabFrame *FindTabFrame() const;
688 inline const SwFootnoteFrame *FindFootnoteFrame() const;
689 inline const SwFlyFrame *FindFlyFrame() const;
690 inline const SwSectionFrame *FindSctFrame() const;
691 inline const SwBodyFrame *FindBodyFrame() const;
692 inline const SwFrame *FindNext() const;
693 // #i27138# - add parameter <_bInSameFootnote>
694 const SwContentFrame* FindNextCnt( const bool _bInSameFootnote = false ) const;
695 inline const SwFrame *FindPrev() const;
696 const SwFrame *GetLower() const;
697
698 SwContentFrame* FindPrevCnt();
699
700 const SwContentFrame* FindPrevCnt() const;
701
702 // #i79774#
703 SwFrame* GetIndPrev_() const;
704 SwFrame* GetIndPrev() const
705 { return ( mpPrev || !IsInSct() ) ? mpPrev : GetIndPrev_(); }
33
Assuming field 'mpPrev' is null
34
Assuming the condition is false
35
'?' condition is false
36
Returning pointer, which participates in a condition later
706
707 SwFrame* GetIndNext()
708 { return ( mpNext || !IsInSct() ) ? mpNext : GetIndNext_(); }
709 const SwFrame* GetIndNext() const { return const_cast<SwFrame*>(this)->GetIndNext(); }
710
711 sal_uInt16 GetPhyPageNum() const; // page number without offset
712 sal_uInt16 GetVirtPageNum() const; // page number with offset
713 bool OnRightPage() const { return 0 != GetPhyPageNum() % 2; };
714 bool WannaRightPage() const;
715 bool OnFirstPage() const;
716
717 inline const SwLayoutFrame *GetPrevLayoutLeaf() const;
718 inline const SwLayoutFrame *GetNextLayoutLeaf() const;
719 inline SwLayoutFrame *GetPrevLayoutLeaf();
720 inline SwLayoutFrame *GetNextLayoutLeaf();
721
722 virtual void Calc(vcl::RenderContext* pRenderContext) const; // here might be "formatted"
723 inline void OptCalc() const; // here we assume (for optimization) that
724 // the predecessors are already formatted
725 Point GetRelPos() const;
726
727 // PaintArea is the area where content might be displayed.
728 // The margin of a page or the space between columns belongs to it.
729 SwRect GetPaintArea() const;
730
731 // UnionFrame is the union of Frame- and PrtArea, normally identical
732 // to the FrameArea except in case of negative Prt margins.
733 SwRect UnionFrame( bool bBorder = false ) const;
734
735 virtual Size ChgSize( const Size& aNewSize );
736
737 virtual void Cut() = 0;
738 virtual void Paste( SwFrame* pParent, SwFrame* pSibling = nullptr ) = 0;
739
740 void ValidateLineNum() { mbValidLineNum = true; }
741
742 bool GetValidLineNumFlag()const { return mbValidLineNum; }
743
744 // Only invalidate Frame
745 // #i28701# - add call to method <ActionOnInvalidation(..)>
746 // for all invalidation methods.
747 // #i28701# - use method <InvalidationAllowed(..)> to
748 // decide, if invalidation will to be performed or not.
749 // #i26945# - no additional invalidation, if it's already
750 // invalidate.
751 void InvalidateSize_()
752 {
753 if ( isFrameAreaSizeValid() && InvalidationAllowed( INVALID_SIZE ) )
754 {
755 setFrameAreaSizeValid(false);
756 ActionOnInvalidation( INVALID_SIZE );
757 }
758 }
759 void InvalidatePrt_()
760 {
761 if ( isFramePrintAreaValid() && InvalidationAllowed( INVALID_PRTAREA ) )
762 {
763 setFramePrintAreaValid(false);
764 ActionOnInvalidation( INVALID_PRTAREA );
765 }
766 }
767 void InvalidatePos_()
768 {
769 if ( isFrameAreaPositionValid() && InvalidationAllowed( INVALID_POS ) )
770 {
771 setFrameAreaPositionValid(false);
772 ActionOnInvalidation( INVALID_POS );
773 }
774 }
775 void InvalidateLineNum_()
776 {
777 if ( mbValidLineNum && InvalidationAllowed( INVALID_LINENUM ) )
778 {
779 mbValidLineNum = false;
780 ActionOnInvalidation( INVALID_LINENUM );
781 }
782 }
783 void InvalidateAll_()
784 {
785 if ( ( isFrameAreaSizeValid() || isFramePrintAreaValid() || isFrameAreaPositionValid() ) && InvalidationAllowed( INVALID_ALL ) )
786 {
787 setFrameAreaSizeValid(false);
788 setFrameAreaPositionValid(false);
789 setFramePrintAreaValid(false);
790 ActionOnInvalidation( INVALID_ALL );
791 }
792 }
793 // also notify page at the same time
794 inline void InvalidateSize();
795 inline void InvalidatePrt();
796 inline void InvalidatePos();
797 inline void InvalidateLineNum();
798 inline void InvalidateAll();
799 void ImplInvalidateSize();
800 void ImplInvalidatePrt();
801 void ImplInvalidatePos();
802 void ImplInvalidateLineNum();
803
804 inline void InvalidateNextPos( bool bNoFootnote = false );
805 void ImplInvalidateNextPos( bool bNoFootnote );
806
807 /** method to invalidate printing area of next frame
808 #i11859#
809 */
810 void InvalidateNextPrtArea();
811
812 void InvalidatePage( const SwPageFrame *pPage = nullptr ) const;
813
814 virtual bool FillSelection( SwSelectionList& rList, const SwRect& rRect ) const;
815
816 virtual bool GetModelPositionForViewPoint( SwPosition *, Point&,
817 SwCursorMoveState* = nullptr, bool bTestBackground = false ) const;
818 virtual bool GetCharRect( SwRect &, const SwPosition&,
819 SwCursorMoveState* = nullptr, bool bAllowFarAway = true ) const;
820 virtual void PaintSwFrame( vcl::RenderContext& rRenderContext, SwRect const&,
821 SwPrintData const*const pPrintData = nullptr ) const;
822
823 // HACK: shortcut between frame and formatting
824 // It's your own fault if you cast void* incorrectly! In any case check
825 // the void* for 0.
826 virtual bool Prepare( const PrepareHint ePrep = PrepareHint::Clear,
827 const void *pVoid = nullptr, bool bNotify = true );
828
829 // true if it is the correct class, false otherwise
830 inline bool IsLayoutFrame() const;
831 inline bool IsRootFrame() const;
832 inline bool IsPageFrame() const;
833 inline bool IsColumnFrame() const;
834 inline bool IsFootnoteBossFrame() const; // footnote bosses might be PageFrames or ColumnFrames
835 inline bool IsHeaderFrame() const;
836 inline bool IsFooterFrame() const;
837 inline bool IsFootnoteContFrame() const;
838 inline bool IsFootnoteFrame() const;
839 inline bool IsBodyFrame() const;
840 inline bool IsColBodyFrame() const; // implemented in layfrm.hxx, BodyFrame above ColumnFrame
841 inline bool IsPageBodyFrame() const; // implemented in layfrm.hxx, BodyFrame above PageFrame
842 inline bool IsFlyFrame() const;
843 inline bool IsSctFrame() const;
844 inline bool IsTabFrame() const;
845 inline bool IsRowFrame() const;
846 inline bool IsCellFrame() const;
847 inline bool IsContentFrame() const;
848 inline bool IsTextFrame() const;
849 inline bool IsNoTextFrame() const;
850 // Frames where its PrtArea depends on their neighbors and that are
851 // positioned in the content flow
852 inline bool IsFlowFrame() const;
853 // Frames that are capable of retouching or that might need to retouch behind
854 // themselves
855 inline bool IsRetoucheFrame() const;
856 inline bool IsAccessibleFrame() const;
857
858 void PrepareCursor(); // CursorShell is allowed to call this
859
860 // Is the Frame (or the section containing it) protected? Same for Fly in
861 // Fly in ... and footnotes
862 bool IsProtected() const;
863
864 bool IsColLocked() const { return mbColLocked; }
865 virtual bool IsDeleteForbidden() const { return mbForbidDelete; }
866
867 /// this is the only way to delete a SwFrame instance
868 static void DestroyFrame(SwFrame *const pFrame);
869
870 bool IsInDtor() const { return mbInDtor; }
871
872 // No inline cause we need the function pointers
873 long GetTopMargin() const;
874 long GetBottomMargin() const;
875 long GetLeftMargin() const;
876 long GetRightMargin() const;
877 void SetTopBottomMargins( long, long );
878 void SetLeftRightMargins( long, long );
879 void SetRightLeftMargins( long, long );
880 long GetPrtLeft() const;
881 long GetPrtBottom() const;
882 long GetPrtRight() const;
883 long GetPrtTop() const;
884 bool SetMinLeft( long );
885 bool SetMaxBottom( long );
886 bool SetMaxRight( long );
887 void MakeBelowPos( const SwFrame*, const SwFrame*, bool );
888 void MakeLeftPos( const SwFrame*, const SwFrame*, bool );
889 void MakeRightPos( const SwFrame*, const SwFrame*, bool );
890 bool IsNeighbourFrame() const
891 { return bool(GetType() & FRM_NEIGHBOUR(SwFrameType::Column | SwFrameType::Cell)); }
892
893 // NEW TABLES
894 // Some functions for covered/covering table cells. This way unnecessary
895 // includes can be avoided
896 virtual bool IsLeaveUpperAllowed() const;
897 virtual bool IsCoveredCell() const;
898 bool IsInCoveredCell() const;
899
900 // #i81146# new loop control
901 bool KnowsFormat( const SwFormat& rFormat ) const;
902 void RegisterToFormat( SwFormat& rFormat );
903 void ValidateThisAndAllLowers( const sal_uInt16 nStage );
904
905 void ForbidDelete() { mbForbidDelete = true; }
906 void AllowDelete() { mbForbidDelete = false; }
907
908 drawinglayer::attribute::SdrAllFillAttributesHelperPtr getSdrAllFillAttributesHelper() const;
909 bool supportsFullDrawingLayerFillAttributeSet() const;
910
911public:
912 // if writer is NULL, dumps the layout structure as XML in layout.xml
913 virtual void dumpAsXml(xmlTextWriterPtr writer = nullptr) const;
914 void dumpTopMostAsXml(xmlTextWriterPtr writer = nullptr) const;
915 void dumpInfosAsXml(xmlTextWriterPtr writer) const;
916 virtual void dumpAsXmlAttributes(xmlTextWriterPtr writer) const;
917 void dumpChildrenAsXml(xmlTextWriterPtr writer) const;
918 bool IsCollapse() const;
919};
920
921inline bool SwFrame::IsInDocBody() const
922{
923 if ( mbInfInvalid )
924 const_cast<SwFrame*>(this)->SetInfFlags();
925 return mbInfBody;
926}
927inline bool SwFrame::IsInFootnote() const
928{
929 if ( mbInfInvalid )
930 const_cast<SwFrame*>(this)->SetInfFlags();
931 return mbInfFootnote;
932}
933inline bool SwFrame::IsInTab() const
934{
935 if ( mbInfInvalid
22.1
Field 'mbInfInvalid' is false
22.1
Field 'mbInfInvalid' is false
22.1
Field 'mbInfInvalid' is false
)
23
Taking false branch
936 const_cast<SwFrame*>(this)->SetInfFlags();
937 return mbInfTab;
24
Returning zero, which participates in a condition later
938}
939inline bool SwFrame::IsInFly() const
940{
941 if ( mbInfInvalid )
942 const_cast<SwFrame*>(this)->SetInfFlags();
943 return mbInfFly;
944}
945inline bool SwFrame::IsInSct() const
946{
947 if ( mbInfInvalid )
948 const_cast<SwFrame*>(this)->SetInfFlags();
949 return mbInfSct;
950}
951bool SwFrame::IsVertical() const
952{
953 if( mbInvalidVert )
954 const_cast<SwFrame*>(this)->SetDirFlags( true );
955 return mbVertical;
956}
957inline bool SwFrame::IsVertLR() const
958{
959 return mbVertLR;
960}
961inline bool SwFrame::IsVertLRBT() const
962{
963 return mbVertLRBT;
964}
965inline bool SwFrame::IsRightToLeft() const
966{
967 if( mbInvalidR2L )
968 const_cast<SwFrame*>(this)->SetDirFlags( false );
969 return mbRightToLeft;
970}
971
972inline void SwFrame::SetCompletePaint() const
973{
974 const_cast<SwFrame*>(this)->mbCompletePaint = true;
975}
976inline void SwFrame::ResetCompletePaint() const
977{
978 const_cast<SwFrame*>(this)->mbCompletePaint = false;
979}
980
981inline void SwFrame::SetRetouche() const
982{
983 const_cast<SwFrame*>(this)->mbRetouche = true;
984}
985inline void SwFrame::ResetRetouche() const
986{
987 const_cast<SwFrame*>(this)->mbRetouche = false;
988}
989
990inline SwLayoutFrame *SwFrame::GetNextLayoutLeaf()
991{
992 return const_cast<SwLayoutFrame*>(static_cast<const SwFrame*>(this)->GetNextLayoutLeaf());
993}
994inline SwLayoutFrame *SwFrame::GetPrevLayoutLeaf()
995{
996 return const_cast<SwLayoutFrame*>(static_cast<const SwFrame*>(this)->GetPrevLayoutLeaf());
997}
998inline const SwLayoutFrame *SwFrame::GetNextLayoutLeaf() const
999{
1000 return ImplGetNextLayoutLeaf( true );
1001}
1002inline const SwLayoutFrame *SwFrame::GetPrevLayoutLeaf() const
1003{
1004 return ImplGetNextLayoutLeaf( false );
1005}
1006
1007inline void SwFrame::InvalidateSize()
1008{
1009 if ( isFrameAreaSizeValid() )
1010 {
1011 ImplInvalidateSize();
1012 }
1013}
1014inline void SwFrame::InvalidatePrt()
1015{
1016 if ( isFramePrintAreaValid() )
1017 {
1018 ImplInvalidatePrt();
1019 }
1020}
1021inline void SwFrame::InvalidatePos()
1022{
1023 if ( isFrameAreaPositionValid() )
1024 {
1025 ImplInvalidatePos();
1026 }
1027}
1028inline void SwFrame::InvalidateLineNum()
1029{
1030 if ( mbValidLineNum )
1031 ImplInvalidateLineNum();
1032}
1033inline void SwFrame::InvalidateAll()
1034{
1035 if ( InvalidationAllowed( INVALID_ALL ) )
1036 {
1037 if ( isFrameAreaDefinitionValid() )
1038 {
1039 ImplInvalidatePos();
1040 }
1041
1042 setFrameAreaSizeValid(false);
1043 setFrameAreaPositionValid(false);
1044 setFramePrintAreaValid(false);
1045
1046 // #i28701#
1047 ActionOnInvalidation( INVALID_ALL );
1048 }
1049}
1050inline void SwFrame::InvalidateNextPos( bool bNoFootnote )
1051{
1052 if ( mpNext && !mpNext->IsSctFrame() )
1053 mpNext->InvalidatePos();
1054 else
1055 ImplInvalidateNextPos( bNoFootnote );
1056}
1057
1058inline void SwFrame::OptCalc() const
1059{
1060 if ( !isFrameAreaPositionValid() || !isFramePrintAreaValid() || !isFrameAreaSizeValid() )
1061 {
1062 const_cast<SwFrame*>(this)->OptPrepareMake();
1063 }
1064}
1065inline const SwPageFrame *SwFrame::FindPageFrame() const
1066{
1067 return const_cast<SwFrame*>(this)->FindPageFrame();
1068}
1069inline const SwFrame *SwFrame::FindColFrame() const
1070{
1071 return const_cast<SwFrame*>(this)->FindColFrame();
1072}
1073inline const SwFrame *SwFrame::FindFooterOrHeader() const
1074{
1075 return const_cast<SwFrame*>(this)->FindFooterOrHeader();
1076}
1077inline SwTabFrame *SwFrame::FindTabFrame()
1078{
1079 return IsInTab() ? ImplFindTabFrame() : nullptr;
1080}
1081inline const SwFootnoteBossFrame *SwFrame::FindFootnoteBossFrame( bool bFootnote ) const
1082{
1083 return const_cast<SwFrame*>(this)->FindFootnoteBossFrame( bFootnote );
1084}
1085inline SwFootnoteFrame *SwFrame::FindFootnoteFrame()
1086{
1087 return IsInFootnote() ? ImplFindFootnoteFrame() : nullptr;
1088}
1089inline SwFlyFrame *SwFrame::FindFlyFrame()
1090{
1091 return IsInFly() ? ImplFindFlyFrame() : nullptr;
1092}
1093inline SwSectionFrame *SwFrame::FindSctFrame()
1094{
1095 return IsInSct() ? ImplFindSctFrame() : nullptr;
14
Assuming the condition is true
15
'?' condition is true
16
Returning pointer, which participates in a condition later
1096}
1097
1098inline const SwBodyFrame *SwFrame::FindBodyFrame() const
1099{
1100 return IsInDocBody() ? ImplFindBodyFrame() : nullptr;
1101}
1102
1103inline const SwTabFrame *SwFrame::FindTabFrame() const
1104{
1105 return IsInTab() ? const_cast<SwFrame*>(this)->ImplFindTabFrame() : nullptr;
1106}
1107inline const SwFootnoteFrame *SwFrame::FindFootnoteFrame() const
1108{
1109 return IsInFootnote() ? const_cast<SwFrame*>(this)->ImplFindFootnoteFrame() : nullptr;
1110}
1111inline const SwFlyFrame *SwFrame::FindFlyFrame() const
1112{
1113 return IsInFly() ? const_cast<SwFrame*>(this)->ImplFindFlyFrame() : nullptr;
1114}
1115inline const SwSectionFrame *SwFrame::FindSctFrame() const
1116{
1117 return IsInSct() ? const_cast<SwFrame*>(this)->ImplFindSctFrame() : nullptr;
1118}
1119inline SwFrame *SwFrame::FindNext()
1120{
1121 if ( mpNext )
1122 return mpNext;
1123 else
1124 return FindNext_();
1125}
1126inline const SwFrame *SwFrame::FindNext() const
1127{
1128 if ( mpNext )
1129 return mpNext;
1130 else
1131 return const_cast<SwFrame*>(this)->FindNext_();
1132}
1133inline SwFrame *SwFrame::FindPrev()
1134{
1135 if ( mpPrev && !mpPrev->IsSctFrame() )
1136 return mpPrev;
1137 else
1138 return FindPrev_();
1139}
1140inline const SwFrame *SwFrame::FindPrev() const
1141{
1142 if ( mpPrev && !mpPrev->IsSctFrame() )
1143 return mpPrev;
1144 else
1145 return const_cast<SwFrame*>(this)->FindPrev_();
1146}
1147
1148inline bool SwFrame::IsLayoutFrame() const
1149{
1150 return bool(GetType() & FRM_LAYOUTSwFrameType(0x3bFF));
1151}
1152inline bool SwFrame::IsRootFrame() const
1153{
1154 return mnFrameType == SwFrameType::Root;
1155}
1156inline bool SwFrame::IsPageFrame() const
1157{
1158 return mnFrameType == SwFrameType::Page;
1159}
1160inline bool SwFrame::IsColumnFrame() const
1161{
1162 return mnFrameType == SwFrameType::Column;
82
Assuming field 'mnFrameType' is equal to Column
83
Returning the value 1, which participates in a condition later
1163}
1164inline bool SwFrame::IsFootnoteBossFrame() const
1165{
1166 return bool(GetType() & FRM_FTNBOSS(SwFrameType::Page | SwFrameType::Column));
1167}
1168inline bool SwFrame::IsHeaderFrame() const
1169{
1170 return mnFrameType == SwFrameType::Header;
1171}
1172inline bool SwFrame::IsFooterFrame() const
1173{
1174 return mnFrameType == SwFrameType::Footer;
1175}
1176inline bool SwFrame::IsFootnoteContFrame() const
1177{
1178 return mnFrameType == SwFrameType::FtnCont;
1179}
1180inline bool SwFrame::IsFootnoteFrame() const
1181{
1182 return mnFrameType == SwFrameType::Ftn;
1183}
1184inline bool SwFrame::IsBodyFrame() const
1185{
1186 return mnFrameType == SwFrameType::Body;
1187}
1188inline bool SwFrame::IsFlyFrame() const
1189{
1190 return mnFrameType == SwFrameType::Fly;
1191}
1192inline bool SwFrame::IsSctFrame() const
1193{
1194 return mnFrameType == SwFrameType::Section;
1195}
1196inline bool SwFrame::IsTabFrame() const
1197{
1198 return mnFrameType == SwFrameType::Tab;
29
Assuming field 'mnFrameType' is not equal to Tab
30
Returning zero, which participates in a condition later
1199}
1200inline bool SwFrame::IsRowFrame() const
1201{
1202 return mnFrameType == SwFrameType::Row;
1203}
1204inline bool SwFrame::IsCellFrame() const
1205{
1206 return mnFrameType == SwFrameType::Cell;
1207}
1208inline bool SwFrame::IsContentFrame() const
1209{
1210 return bool(GetType() & FRM_CNTNT(SwFrameType::Txt | SwFrameType::NoTxt));
1211}
1212inline bool SwFrame::IsTextFrame() const
1213{
1214 return mnFrameType == SwFrameType::Txt;
1215}
1216inline bool SwFrame::IsNoTextFrame() const
1217{
1218 return mnFrameType == SwFrameType::NoTxt;
1219}
1220inline bool SwFrame::IsFlowFrame() const
1221{
1222 return bool(GetType() & (FRM_CNTNT(SwFrameType::Txt | SwFrameType::NoTxt)|SwFrameType::Tab|SwFrameType::Section));
1223}
1224inline bool SwFrame::IsRetoucheFrame() const
1225{
1226 return bool(GetType() & (FRM_CNTNT(SwFrameType::Txt | SwFrameType::NoTxt)|SwFrameType::Tab|SwFrameType::Section|SwFrameType::Ftn));
1227}
1228inline bool SwFrame::IsAccessibleFrame() const
1229{
1230 return bool(GetType() & FRM_ACCESSIBLE(SwFrameType::Root | SwFrameType::Page | SwFrameType::Header |
SwFrameType::Footer | SwFrameType::Ftn | SwFrameType::Fly | SwFrameType
::Tab | SwFrameType::Cell | SwFrameType::Txt)
);
1231}
1232
1233//use this to protect a SwFrame for a given scope from getting deleted
1234class SwFrameDeleteGuard
1235{
1236private:
1237 SwFrame *m_pForbidFrame;
1238public:
1239 //Flag pFrame for SwFrameDeleteGuard lifetime that we shouldn't delete
1240 //it in e.g. SwSectionFrame::MergeNext etc because we will need it
1241 //again after the SwFrameDeleteGuard dtor
1242 explicit SwFrameDeleteGuard(SwFrame* pFrame)
1243 : m_pForbidFrame((pFrame && !pFrame->IsDeleteForbidden()) ?
1244 pFrame : nullptr)
1245 {
1246 if (m_pForbidFrame)
1247 m_pForbidFrame->ForbidDelete();
1248 }
1249
1250 SwFrameDeleteGuard(const SwFrameDeleteGuard&) =delete;
1251
1252 ~SwFrameDeleteGuard()
1253 {
1254 if (m_pForbidFrame)
1255 m_pForbidFrame->AllowDelete();
1256 }
1257
1258 SwFrameDeleteGuard& operator=(const SwFrameDeleteGuard&) =delete;
1259};
1260
1261typedef long (SwFrame::*SwFrameGet)() const;
1262typedef bool (SwFrame::*SwFrameMax)( long );
1263typedef void (SwFrame::*SwFrameMakePos)( const SwFrame*, const SwFrame*, bool );
1264typedef long (*SwOperator)( long, long );
1265typedef void (SwFrame::*SwFrameSet)( long, long );
1266
1267struct SwRectFnCollection
1268{
1269 SwRectGet fnGetTop;
1270 SwRectGet fnGetBottom;
1271 SwRectGet fnGetLeft;
1272 SwRectGet fnGetRight;
1273 SwRectGet fnGetWidth;
1274 SwRectGet fnGetHeight;
1275 SwRectPoint fnGetPos;
1276 SwRectSize fnGetSize;
1277
1278 SwRectSet fnSetTop;
1279 SwRectSet fnSetBottom;
1280 SwRectSet fnSetLeft;
1281 SwRectSet fnSetRight;
1282 SwRectSet fnSetWidth;
1283 SwRectSet fnSetHeight;
1284
1285 SwRectSet fnSubTop;
1286 SwRectSet fnAddBottom;
1287 SwRectSet fnSubLeft;
1288 SwRectSet fnAddRight;
1289 SwRectSet fnAddWidth;
1290 SwRectSet fnAddHeight;
1291
1292 SwRectSet fnSetPosX;
1293 SwRectSet fnSetPosY;
1294
1295 SwFrameGet fnGetTopMargin;
1296 SwFrameGet fnGetBottomMargin;
1297 SwFrameGet fnGetLeftMargin;
1298 SwFrameGet fnGetRightMargin;
1299 SwFrameSet fnSetXMargins;
1300 SwFrameSet fnSetYMargins;
1301 SwFrameGet fnGetPrtTop;
1302 SwFrameGet fnGetPrtBottom;
1303 SwFrameGet fnGetPrtLeft;
1304 SwFrameGet fnGetPrtRight;
1305 SwRectDist fnTopDist;
1306 SwRectDist fnBottomDist;
1307 SwRectDist fnLeftDist;
1308 SwRectDist fnRightDist;
1309 SwFrameMax fnSetLimit;
1310 SwRectMax fnOverStep;
1311
1312 SwRectSetPos fnSetPos;
1313 SwFrameMakePos fnMakePos;
1314 SwOperator fnXDiff;
1315 SwOperator fnYDiff;
1316 SwOperator fnXInc;
1317 SwOperator fnYInc;
1318
1319 SwRectSetTwice fnSetLeftAndWidth;
1320 SwRectSetTwice fnSetTopAndHeight;
1321};
1322
1323typedef SwRectFnCollection* SwRectFn;
1324
1325// This class allows to use proper methods regardless of orientation (LTR/RTL, horizontal or vertical)
1326extern SwRectFn fnRectHori, fnRectVert, fnRectVertL2R, fnRectVertL2RB2T;
1327class SwRectFnSet {
1328public:
1329 explicit SwRectFnSet(const SwFrame *pFrame)
1330 : m_bVert(pFrame->IsVertical())
1331 , m_bVertL2R(pFrame->IsVertLR())
1332 , m_bVertL2RB2T(pFrame->IsVertLRBT())
1333 {
1334 m_fnRect = m_bVert ? (m_bVertL2R ? (m_bVertL2RB2T ? fnRectVertL2RB2T : fnRectVertL2R) : fnRectVert) : fnRectHori;
1335 }
1336
1337 void Refresh(const SwFrame *pFrame)
1338 {
1339 m_bVert = pFrame->IsVertical();
1340 m_bVertL2R = pFrame->IsVertLR();
1341 m_bVertL2RB2T = pFrame->IsVertLRBT();
1342 m_fnRect = m_bVert ? (m_bVertL2R ? (m_bVertL2RB2T ? fnRectVertL2RB2T : fnRectVertL2R) : fnRectVert) : fnRectHori;
1343 }
1344
1345 bool IsVert() const { return m_bVert; }
1346 bool IsVertL2R() const { return m_bVertL2R; }
1347 SwRectFn FnRect() const { return m_fnRect; }
1348
1349 bool PosDiff(const SwRect &rRect1, const SwRect &rRect2) const
1350 {
1351 return ((rRect1.*m_fnRect->fnGetTop)() != (rRect2.*m_fnRect->fnGetTop)()
1352 || (rRect1.*m_fnRect->fnGetLeft)() != (rRect2.*m_fnRect->fnGetLeft)());
1353 }
1354
1355 long GetTop (const SwRect& rRect) const { return (rRect.*m_fnRect->fnGetTop) (); }
1356 long GetBottom(const SwRect& rRect) const { return (rRect.*m_fnRect->fnGetBottom)(); }
1357 long GetLeft (const SwRect& rRect) const { return (rRect.*m_fnRect->fnGetLeft) (); }
1358 long GetRight (const SwRect& rRect) const { return (rRect.*m_fnRect->fnGetRight) (); }
1359 long GetWidth (const SwRect& rRect) const { return (rRect.*m_fnRect->fnGetWidth) (); }
1360 long GetHeight(const SwRect& rRect) const { return (rRect.*m_fnRect->fnGetHeight)(); }
1361 Point GetPos (const SwRect& rRect) const { return (rRect.*m_fnRect->fnGetPos) (); }
1362 Size GetSize (const SwRect& rRect) const { return (rRect.*m_fnRect->fnGetSize) (); }
1363
1364 void SetTop (SwRect& rRect, long nNew) const { (rRect.*m_fnRect->fnSetTop) (nNew); }
1365 void SetBottom(SwRect& rRect, long nNew) const { (rRect.*m_fnRect->fnSetBottom)(nNew); }
1366 void SetLeft (SwRect& rRect, long nNew) const { (rRect.*m_fnRect->fnSetLeft) (nNew); }
1367 void SetRight (SwRect& rRect, long nNew) const { (rRect.*m_fnRect->fnSetRight) (nNew); }
1368 void SetWidth (SwRect& rRect, long nNew) const { (rRect.*m_fnRect->fnSetWidth) (nNew); }
1369 void SetHeight(SwRect& rRect, long nNew) const { (rRect.*m_fnRect->fnSetHeight)(nNew); }
1370
1371 void SubTop (SwRect& rRect, long nNew) const { (rRect.*m_fnRect->fnSubTop) (nNew); }
1372 void AddBottom(SwRect& rRect, long nNew) const { (rRect.*m_fnRect->fnAddBottom)(nNew); }
1373 void SubLeft (SwRect& rRect, long nNew) const { (rRect.*m_fnRect->fnSubLeft) (nNew); }
1374 void AddRight (SwRect& rRect, long nNew) const { (rRect.*m_fnRect->fnAddRight) (nNew); }
1375 void AddWidth (SwRect& rRect, long nNew) const { (rRect.*m_fnRect->fnAddWidth) (nNew); }
1376 void AddHeight(SwRect& rRect, long nNew) const { (rRect.*m_fnRect->fnAddHeight)(nNew); }
1377
1378 void SetPosX(SwRect& rRect, long nNew) const { (rRect.*m_fnRect->fnSetPosX)(nNew); }
1379 void SetPosY(SwRect& rRect, long nNew) const { (rRect.*m_fnRect->fnSetPosY)(nNew); }
1380
1381 long GetTopMargin (const SwFrame& rFrame) const { return (rFrame.*m_fnRect->fnGetTopMargin) (); }
77
Value assigned to field 'm_pLower', which participates in a condition later
1382 long GetBottomMargin(const SwFrame& rFrame) const { return (rFrame.*m_fnRect->fnGetBottomMargin)(); }
1383 long GetLeftMargin (const SwFrame& rFrame) const { return (rFrame.*m_fnRect->fnGetLeftMargin) (); }
1384 long GetRightMargin (const SwFrame& rFrame) const { return (rFrame.*m_fnRect->fnGetRightMargin) (); }
1385 void SetXMargins(SwFrame& rFrame, long nLeft, long nRight) const { (rFrame.*m_fnRect->fnSetXMargins)(nLeft, nRight); }
1386 void SetYMargins(SwFrame& rFrame, long nTop, long nBottom) const { (rFrame.*m_fnRect->fnSetYMargins)(nTop, nBottom); }
1387 long GetPrtTop (const SwFrame& rFrame) const { return (rFrame.*m_fnRect->fnGetPrtTop) (); }
1388 long GetPrtBottom (const SwFrame& rFrame) const { return (rFrame.*m_fnRect->fnGetPrtBottom) (); }
1389 long GetPrtLeft (const SwFrame& rFrame) const { return (rFrame.*m_fnRect->fnGetPrtLeft) (); }
1390 long GetPrtRight (const SwFrame& rFrame) const { return (rFrame.*m_fnRect->fnGetPrtRight) (); }
1391 long TopDist (const SwRect& rRect, long nPos) const { return (rRect.*m_fnRect->fnTopDist) (nPos); }
1392 long BottomDist(const SwRect& rRect, long nPos) const { return (rRect.*m_fnRect->fnBottomDist) (nPos); }
1393 long LeftDist (const SwRect& rRect, long nPos) const { return (rRect.*m_fnRect->fnLeftDist) (nPos); }
1394 long RightDist (const SwRect& rRect, long nPos) const { return (rRect.*m_fnRect->fnRightDist) (nPos); }
1395 void SetLimit (SwFrame& rFrame, long nNew) const { (rFrame.*m_fnRect->fnSetLimit) (nNew); }
1396 bool OverStep (const SwRect& rRect, long nPos) const { return (rRect.*m_fnRect->fnOverStep) (nPos); }
1397
1398 void SetPos(SwRect& rRect, const Point& rNew) const { (rRect.*m_fnRect->fnSetPos)(rNew); }
1399 void MakePos(SwFrame& rFrame, const SwFrame* pUp, const SwFrame* pPrv, bool bNotify) const { (rFrame.*m_fnRect->fnMakePos)(pUp, pPrv, bNotify); }
1400 long XDiff(long n1, long n2) const { return (m_fnRect->fnXDiff) (n1, n2); }
1401 long YDiff(long n1, long n2) const { return (m_fnRect->fnYDiff) (n1, n2); }
1402 long XInc (long n1, long n2) const { return (m_fnRect->fnXInc) (n1, n2); }
1403 long YInc (long n1, long n2) const { return (m_fnRect->fnYInc) (n1, n2); }
1404
1405 void SetLeftAndWidth(SwRect& rRect, long nLeft, long nWidth) const { (rRect.*m_fnRect->fnSetLeftAndWidth)(nLeft, nWidth); }
1406 void SetTopAndHeight(SwRect& rRect, long nTop, long nHeight) const { (rRect.*m_fnRect->fnSetTopAndHeight)(nTop, nHeight); }
1407
1408private:
1409 bool m_bVert;
1410 bool m_bVertL2R;
1411 bool m_bVertL2RB2T;
1412 SwRectFn m_fnRect;
1413};
1414
1415#endif
1416
1417/* vim:set shiftwidth=4 softtabstop=4 expandtab: */