File: | home/maarten/src/libreoffice/core/sw/source/core/layout/calcmove.cxx |
Warning: | line 732, column 20 Called C++ object pointer is null |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 <memory> | |||
21 | #include <rootfrm.hxx> | |||
22 | #include <pagefrm.hxx> | |||
23 | #include <viewopt.hxx> | |||
24 | #include <frmatr.hxx> | |||
25 | #include <frmtool.hxx> | |||
26 | #include <txtftn.hxx> | |||
27 | #include <fmtftn.hxx> | |||
28 | #include <ndtxt.hxx> | |||
29 | #include <editeng/ulspitem.hxx> | |||
30 | #include <editeng/keepitem.hxx> | |||
31 | #include <svx/sdtaitm.hxx> | |||
32 | ||||
33 | #include <fmtfsize.hxx> | |||
34 | #include <fmtanchr.hxx> | |||
35 | #include <fmtclbl.hxx> | |||
36 | ||||
37 | #include <tabfrm.hxx> | |||
38 | #include <ftnfrm.hxx> | |||
39 | #include <txtfrm.hxx> | |||
40 | #include <sectfrm.hxx> | |||
41 | #include <dbg_lay.hxx> | |||
42 | ||||
43 | #include <sortedobjs.hxx> | |||
44 | #include <layouter.hxx> | |||
45 | #include <flyfrms.hxx> | |||
46 | ||||
47 | #include <DocumentSettingManager.hxx> | |||
48 | #include <IDocumentLayoutAccess.hxx> | |||
49 | ||||
50 | // Move methods | |||
51 | ||||
52 | /// Return value tells whether the Frame should be moved. | |||
53 | bool SwContentFrame::ShouldBwdMoved( SwLayoutFrame *pNewUpper, bool & ) | |||
54 | { | |||
55 | if ( SwFlowFrame::IsMoveBwdJump() || !IsPrevObjMove() ) | |||
56 | { | |||
57 | // Floating back a frm uses a bit of time unfortunately. | |||
58 | // The most common case is the following: The Frame wants to float to | |||
59 | // somewhere where the FixSize is the same that the Frame itself has already. | |||
60 | // In that case it's pretty easy to check if the Frame has enough space | |||
61 | // for its VarSize. If this is NOT the case, we already know that | |||
62 | // we don't need to move. | |||
63 | // The Frame checks itself whether it has enough space - respecting the fact | |||
64 | // that it could possibly split itself if needed. | |||
65 | // If, however, the FixSize differs from the Frame or Flys are involved | |||
66 | // (either in the old or the new position), checking is pointless, | |||
67 | // and we have to move the Frame just to see what happens - if there's | |||
68 | // some space available to do it, that is. | |||
69 | ||||
70 | // The FixSize of the containers of Contents is always the width. | |||
71 | ||||
72 | // If we moved more than one sheet back (for example jumping over empty | |||
73 | // pages), we have to move either way. Otherwise, if the Frame doesn't fit | |||
74 | // into the page, empty pages wouldn't be respected anymore. | |||
75 | sal_uInt8 nMoveAnyway = 0; | |||
76 | SwPageFrame * const pNewPage = pNewUpper->FindPageFrame(); | |||
77 | SwPageFrame *pOldPage = FindPageFrame(); | |||
78 | ||||
79 | if ( SwFlowFrame::IsMoveBwdJump() ) | |||
80 | return true; | |||
81 | ||||
82 | if( IsInFootnote() && IsInSct() ) | |||
83 | { | |||
84 | SwFootnoteFrame* pFootnote = FindFootnoteFrame(); | |||
85 | SwSectionFrame* pMySect = pFootnote->FindSctFrame(); | |||
86 | if( pMySect && pMySect->IsFootnoteLock() ) | |||
87 | { | |||
88 | SwSectionFrame *pSect = pNewUpper->FindSctFrame(); | |||
89 | while( pSect && pSect->IsInFootnote() ) | |||
90 | pSect = pSect->GetUpper()->FindSctFrame(); | |||
91 | OSL_ENSURE( pSect, "Escaping footnote" )do { if (true && (!(pSect))) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/calcmove.cxx" ":" "91" ": "), "%s", "Escaping footnote"); } } while (false ); | |||
92 | if( pSect != pMySect ) | |||
93 | return false; | |||
94 | } | |||
95 | } | |||
96 | SwRectFnSet aRectFnSet(this); | |||
97 | SwRectFnSet fnRectX(pNewUpper); | |||
98 | if( std::abs( fnRectX.GetWidth(pNewUpper->getFramePrintArea()) - | |||
99 | aRectFnSet.GetWidth(GetUpper()->getFramePrintArea()) ) > 1 ) { | |||
100 | // In this case, only a WouldFit_ with test move is possible | |||
101 | nMoveAnyway = 2; | |||
102 | } | |||
103 | ||||
104 | // Do *not* move backward, if <nMoveAnyway> equals 3 and no space is left in new upper. | |||
105 | nMoveAnyway |= BwdMoveNecessary( pOldPage, getFrameArea() ); | |||
106 | { | |||
107 | const IDocumentSettingAccess& rIDSA = pNewPage->GetFormat()->getIDocumentSettingAccess(); | |||
108 | SwTwips nSpace = 0; | |||
109 | SwRect aRect( pNewUpper->getFramePrintArea() ); | |||
110 | aRect.Pos() += pNewUpper->getFrameArea().Pos(); | |||
111 | const SwFrame *pPrevFrame = pNewUpper->Lower(); | |||
112 | while ( pPrevFrame ) | |||
113 | { | |||
114 | SwTwips nNewTop = fnRectX.GetBottom(pPrevFrame->getFrameArea()); | |||
115 | // Consider lower spacing of last frame in a table cell | |||
116 | { | |||
117 | // Check if last frame is inside table and if it includes its lower spacing. | |||
118 | if ( !pPrevFrame->GetNext() && pPrevFrame->IsInTab() && | |||
119 | rIDSA.get(DocumentSettingId::ADD_PARA_SPACING_TO_TABLE_CELLS) ) | |||
120 | { | |||
121 | const SwFrame* pLastFrame = pPrevFrame; | |||
122 | // if last frame is a section, take its last content | |||
123 | if ( pPrevFrame->IsSctFrame() ) | |||
124 | { | |||
125 | pLastFrame = static_cast<const SwSectionFrame*>(pPrevFrame)->FindLastContent(); | |||
126 | if ( pLastFrame && | |||
127 | pLastFrame->FindTabFrame() != pPrevFrame->FindTabFrame() ) | |||
128 | { | |||
129 | pLastFrame = pLastFrame->FindTabFrame(); | |||
130 | } | |||
131 | } | |||
132 | ||||
133 | if ( pLastFrame ) | |||
134 | { | |||
135 | SwBorderAttrAccess aAccess( SwFrame::GetCache(), pLastFrame ); | |||
136 | const SwBorderAttrs& rAttrs = *aAccess.Get(); | |||
137 | nNewTop -= rAttrs.GetULSpace().GetLower(); | |||
138 | if (rIDSA.get(DocumentSettingId::ADD_PARA_LINE_SPACING_TO_TABLE_CELLS)) | |||
139 | { | |||
140 | nNewTop -= rAttrs.CalcLineSpacing(); | |||
141 | } | |||
142 | } | |||
143 | } | |||
144 | } | |||
145 | fnRectX.SetTop( aRect, nNewTop ); | |||
146 | ||||
147 | pPrevFrame = pPrevFrame->GetNext(); | |||
148 | } | |||
149 | ||||
150 | nMoveAnyway |= BwdMoveNecessary( pNewPage, aRect); | |||
151 | ||||
152 | //determine space left in new upper frame | |||
153 | nSpace = fnRectX.GetHeight(aRect); | |||
154 | const SwViewShell *pSh = pNewUpper->getRootFrame()->GetCurrShell(); | |||
155 | if ( IsInFootnote() || | |||
156 | (pSh && pSh->GetViewOptions()->getBrowseMode()) || | |||
157 | pNewUpper->IsCellFrame() || | |||
158 | ( pNewUpper->IsInSct() && ( pNewUpper->IsSctFrame() || | |||
159 | ( pNewUpper->IsColBodyFrame() && | |||
160 | !pNewUpper->GetUpper()->GetPrev() && | |||
161 | !pNewUpper->GetUpper()->GetNext() ) ) ) ) | |||
162 | nSpace += pNewUpper->Grow( LONG_MAX9223372036854775807L, true ); | |||
163 | ||||
164 | if ( nMoveAnyway < 3 ) | |||
165 | { | |||
166 | if ( nSpace ) | |||
167 | { | |||
168 | // Do not notify footnotes which are stuck to the paragraph: | |||
169 | // This would require extremely confusing code, taking into | |||
170 | // account the widths | |||
171 | // and Flys, that in turn influence the footnotes, ... | |||
172 | ||||
173 | // WouldFit_ can only be used if the width is the same and | |||
174 | // ONLY self-anchored Flys are present. | |||
175 | ||||
176 | // WouldFit_ can also be used if ONLY Flys anchored | |||
177 | // somewhere else are present. | |||
178 | // In this case, the width doesn't even matter, | |||
179 | // because we're running a TestFormat in the new upper. | |||
180 | const sal_uInt8 nBwdMoveNecessaryResult = | |||
181 | BwdMoveNecessary( pNewPage, aRect); | |||
182 | const bool bObjsInNewUpper( nBwdMoveNecessaryResult == 2 || | |||
183 | nBwdMoveNecessaryResult == 3 ); | |||
184 | ||||
185 | return WouldFit_( nSpace, pNewUpper, nMoveAnyway == 2, | |||
186 | bObjsInNewUpper ); | |||
187 | } | |||
188 | // It's impossible for WouldFit_ to return a usable result if | |||
189 | // we have a fresh multi-column section - so we really have to | |||
190 | // float back unless there is no space. | |||
191 | return pNewUpper->IsInSct() && pNewUpper->IsColBodyFrame() && | |||
192 | !fnRectX.GetWidth(pNewUpper->getFramePrintArea()) && | |||
193 | ( pNewUpper->GetUpper()->GetPrev() || | |||
194 | pNewUpper->GetUpper()->GetNext() ); | |||
195 | } | |||
196 | ||||
197 | // Check for space left in new upper | |||
198 | return nSpace != 0; | |||
199 | } | |||
200 | } | |||
201 | return false; | |||
202 | } | |||
203 | ||||
204 | // Calc methods | |||
205 | ||||
206 | // Two little friendships form a secret society | |||
207 | inline void PrepareLock( SwFlowFrame *pTab ) | |||
208 | { | |||
209 | pTab->LockJoin(); | |||
210 | } | |||
211 | inline void PrepareUnlock( SwFlowFrame *pTab ) | |||
212 | { | |||
213 | pTab->UnlockJoin(); | |||
214 | ||||
215 | } | |||
216 | ||||
217 | // hopefully, one day this function simply will return 'false' | |||
218 | static bool lcl_IsCalcUpperAllowed( const SwFrame& rFrame ) | |||
219 | { | |||
220 | return !rFrame.GetUpper()->IsSctFrame() && | |||
221 | !rFrame.GetUpper()->IsFooterFrame() && | |||
222 | // No format of upper Writer fly frame | |||
223 | !rFrame.GetUpper()->IsFlyFrame() && | |||
224 | !( rFrame.GetUpper()->IsTabFrame() && rFrame.GetUpper()->GetUpper()->IsInTab() ) && | |||
225 | !( rFrame.IsTabFrame() && rFrame.GetUpper()->IsInTab() ); | |||
226 | } | |||
227 | ||||
228 | /** Prepares the Frame for "formatting" (MakeAll()). | |||
229 | * | |||
230 | * This method serves to save stack space: To calculate the position of the Frame | |||
231 | * we have to make sure that the positions of Upper and Prev respectively are | |||
232 | * valid. This may require a recursive call (a loop would be quite expensive, | |||
233 | * as it's not required very often). | |||
234 | * | |||
235 | * Every call of MakeAll requires around 500 bytes on the stack - you easily | |||
236 | * see where this leads to. This method requires only a little bit of stack | |||
237 | * space, so the recursive call should not be a problem here. | |||
238 | * | |||
239 | * Another advantage is that one nice day, this method and with it the | |||
240 | * formatting of predecessors could be avoided. Then it could probably be | |||
241 | * possible to jump "quickly" to the document's end. | |||
242 | * | |||
243 | * @see MakeAll() | |||
244 | */ | |||
245 | void SwFrame::PrepareMake(vcl::RenderContext* pRenderContext) | |||
246 | { | |||
247 | StackHack aHack; | |||
248 | if ( GetUpper() ) | |||
249 | { | |||
250 | SwFrameDeleteGuard aDeleteGuard(this); | |||
251 | if ( lcl_IsCalcUpperAllowed( *this ) ) | |||
252 | GetUpper()->Calc(pRenderContext); | |||
253 | OSL_ENSURE( GetUpper(), ":-( Layout unstable (Upper gone)." )do { if (true && (!(GetUpper()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/calcmove.cxx" ":" "253" ": "), "%s", ":-( Layout unstable (Upper gone)."); } } while (false); | |||
254 | if ( !GetUpper() ) | |||
255 | return; | |||
256 | ||||
257 | const bool bCnt = IsContentFrame(); | |||
258 | const bool bTab = IsTabFrame(); | |||
259 | bool bNoSect = IsInSct(); | |||
260 | bool bOldTabLock = false, bFoll = false; | |||
261 | SwFlowFrame* pThis = bCnt ? static_cast<SwContentFrame*>(this) : nullptr; | |||
262 | ||||
263 | if ( bTab ) | |||
264 | { | |||
265 | pThis = static_cast<SwTabFrame*>(this); | |||
266 | bOldTabLock = static_cast<SwTabFrame*>(this)->IsJoinLocked(); | |||
267 | ::PrepareLock( static_cast<SwTabFrame*>(this) ); | |||
268 | bFoll = pThis->IsFollow(); | |||
269 | } | |||
270 | else if( IsSctFrame() ) | |||
271 | { | |||
272 | pThis = static_cast<SwSectionFrame*>(this); | |||
273 | bFoll = pThis->IsFollow(); | |||
274 | bNoSect = false; | |||
275 | } | |||
276 | else if ( bCnt ) | |||
277 | { | |||
278 | bFoll = pThis->IsFollow(); | |||
279 | if ( bFoll && GetPrev() ) | |||
280 | { | |||
281 | // Do not follow the chain when we need only one instance | |||
282 | const SwTextFrame* pMaster = static_cast<SwContentFrame*>(this)->FindMaster(); | |||
283 | if ( pMaster && pMaster->IsLocked() ) | |||
284 | { | |||
285 | MakeAll(pRenderContext); | |||
286 | return; | |||
287 | } | |||
288 | } | |||
289 | } | |||
290 | ||||
291 | // There is no format of previous frame, if current frame is a table | |||
292 | // frame and its previous frame wants to keep with it. | |||
293 | const bool bFormatPrev = !bTab || | |||
294 | !GetPrev() || | |||
295 | !GetPrev()->GetAttrSet()->GetKeep().GetValue(); | |||
296 | if ( bFormatPrev ) | |||
297 | { | |||
298 | SwFrame *pFrame = GetUpper()->Lower(); | |||
299 | while ( pFrame != this ) | |||
300 | { | |||
301 | OSL_ENSURE( pFrame, ":-( Layout unstable (this not found)." )do { if (true && (!(pFrame))) { sal_detail_logFormat( (SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/calcmove.cxx" ":" "301" ": "), "%s", ":-( Layout unstable (this not found)." ); } } while (false); | |||
302 | if ( !pFrame ) | |||
303 | return; //Oioioioi ... | |||
304 | ||||
305 | if ( !pFrame->isFrameAreaDefinitionValid() ) | |||
306 | { | |||
307 | // A small interference that hopefully improves on the stability: | |||
308 | // If I'm Follow AND neighbor of a Frame before me, it would delete | |||
309 | // me when formatting. This as you can see could easily become a | |||
310 | // confusing situation that we want to avoid. | |||
311 | if ( bFoll && pFrame->IsFlowFrame() && | |||
312 | SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow( pThis ) ) | |||
313 | break; | |||
314 | ||||
315 | bool const isLast(pFrame->GetNext() == this); | |||
316 | // note: this seems obvious but does *not* hold, a MakeAll() | |||
317 | // could move more than 1 frame backwards! | |||
318 | // that's why FindNext() is used below | |||
319 | // assert(pFrame->GetUpper() == GetUpper()); | |||
320 | pFrame->MakeAll(pRenderContext); | |||
321 | if( IsSctFrame() && !static_cast<SwSectionFrame*>(this)->GetSection() ) | |||
322 | break; | |||
323 | if (isLast && pFrame->GetUpper() != GetUpper()) | |||
324 | { | |||
325 | assert(GetUpper()->Lower() == this(static_cast <bool> (GetUpper()->Lower() == this || GetUpper ()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame (pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()-> Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow ( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame ::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame ::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))) ? void (0) : __assert_fail ("GetUpper()->Lower() == this || GetUpper()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame(pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()->Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/calcmove.cxx" , 339, __extension__ __PRETTY_FUNCTION__)) | |||
326 | // empty section frames are created all the time...(static_cast <bool> (GetUpper()->Lower() == this || GetUpper ()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame (pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()-> Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow ( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame ::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame ::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))) ? void (0) : __assert_fail ("GetUpper()->Lower() == this || GetUpper()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame(pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()->Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/calcmove.cxx" , 339, __extension__ __PRETTY_FUNCTION__)) | |||
327 | || GetUpper()->Lower()->IsSctFrame()(static_cast <bool> (GetUpper()->Lower() == this || GetUpper ()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame (pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()-> Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow ( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame ::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame ::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))) ? void (0) : __assert_fail ("GetUpper()->Lower() == this || GetUpper()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame(pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()->Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/calcmove.cxx" , 339, __extension__ __PRETTY_FUNCTION__)) | |||
328 | // tab frame/section frame may split multiple times(static_cast <bool> (GetUpper()->Lower() == this || GetUpper ()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame (pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()-> Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow ( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame ::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame ::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))) ? void (0) : __assert_fail ("GetUpper()->Lower() == this || GetUpper()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame(pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()->Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/calcmove.cxx" , 339, __extension__ __PRETTY_FUNCTION__)) | |||
329 | || ( SwFlowFrame::CastFlowFrame(pFrame)(static_cast <bool> (GetUpper()->Lower() == this || GetUpper ()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame (pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()-> Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow ( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame ::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame ::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))) ? void (0) : __assert_fail ("GetUpper()->Lower() == this || GetUpper()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame(pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()->Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/calcmove.cxx" , 339, __extension__ __PRETTY_FUNCTION__)) | |||
330 | && SwFlowFrame::CastFlowFrame(GetUpper()->Lower())(static_cast <bool> (GetUpper()->Lower() == this || GetUpper ()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame (pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()-> Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow ( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame ::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame ::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))) ? void (0) : __assert_fail ("GetUpper()->Lower() == this || GetUpper()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame(pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()->Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/calcmove.cxx" , 339, __extension__ __PRETTY_FUNCTION__)) | |||
331 | && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow((static_cast <bool> (GetUpper()->Lower() == this || GetUpper ()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame (pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()-> Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow ( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame ::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame ::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))) ? void (0) : __assert_fail ("GetUpper()->Lower() == this || GetUpper()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame(pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()->Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/calcmove.cxx" , 339, __extension__ __PRETTY_FUNCTION__)) | |||
332 | SwFlowFrame::CastFlowFrame(GetUpper()->Lower()))(static_cast <bool> (GetUpper()->Lower() == this || GetUpper ()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame (pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()-> Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow ( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame ::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame ::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))) ? void (0) : __assert_fail ("GetUpper()->Lower() == this || GetUpper()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame(pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()->Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/calcmove.cxx" , 339, __extension__ __PRETTY_FUNCTION__)) | |||
333 | && (GetUpper()->Lower()->GetNext() == this(static_cast <bool> (GetUpper()->Lower() == this || GetUpper ()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame (pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()-> Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow ( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame ::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame ::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))) ? void (0) : __assert_fail ("GetUpper()->Lower() == this || GetUpper()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame(pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()->Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/calcmove.cxx" , 339, __extension__ __PRETTY_FUNCTION__)) | |||
334 | // if it's more than 10 pages long...(static_cast <bool> (GetUpper()->Lower() == this || GetUpper ()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame (pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()-> Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow ( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame ::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame ::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))) ? void (0) : __assert_fail ("GetUpper()->Lower() == this || GetUpper()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame(pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()->Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/calcmove.cxx" , 339, __extension__ __PRETTY_FUNCTION__)) | |||
335 | || (SwFlowFrame::CastFlowFrame(GetUpper()->Lower())->GetFollow()(static_cast <bool> (GetUpper()->Lower() == this || GetUpper ()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame (pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()-> Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow ( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame ::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame ::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))) ? void (0) : __assert_fail ("GetUpper()->Lower() == this || GetUpper()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame(pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()->Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/calcmove.cxx" , 339, __extension__ __PRETTY_FUNCTION__)) | |||
336 | == SwFlowFrame::CastFlowFrame(GetUpper()->Lower()->GetNext())(static_cast <bool> (GetUpper()->Lower() == this || GetUpper ()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame (pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()-> Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow ( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame ::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame ::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))) ? void (0) : __assert_fail ("GetUpper()->Lower() == this || GetUpper()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame(pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()->Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/calcmove.cxx" , 339, __extension__ __PRETTY_FUNCTION__)) | |||
337 | && GetUpper()->Lower()->GetNext()->GetNext() == this)(static_cast <bool> (GetUpper()->Lower() == this || GetUpper ()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame (pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()-> Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow ( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame ::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame ::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))) ? void (0) : __assert_fail ("GetUpper()->Lower() == this || GetUpper()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame(pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()->Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/calcmove.cxx" , 339, __extension__ __PRETTY_FUNCTION__)) | |||
338 | // pre-existing empty section frames may end up between them...(static_cast <bool> (GetUpper()->Lower() == this || GetUpper ()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame (pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()-> Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow ( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame ::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame ::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))) ? void (0) : __assert_fail ("GetUpper()->Lower() == this || GetUpper()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame(pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()->Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/calcmove.cxx" , 339, __extension__ __PRETTY_FUNCTION__)) | |||
339 | || GetUpper()->Lower()->GetNext()->IsSctFrame())))(static_cast <bool> (GetUpper()->Lower() == this || GetUpper ()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame (pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()-> Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow ( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame ::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame ::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))) ? void (0) : __assert_fail ("GetUpper()->Lower() == this || GetUpper()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame(pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()->Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/calcmove.cxx" , 339, __extension__ __PRETTY_FUNCTION__)); | |||
340 | break; // tdf#119109 frame was moved backward, prevent | |||
341 | // FindNext() returning a frame inside this if | |||
342 | } // this is a table! | |||
343 | } | |||
344 | // With ContentFrames, the chain may be broken while walking through | |||
345 | // it. Therefore we have to figure out the next frame in a bit more | |||
346 | // complicated way. However, I'll HAVE to get back to myself | |||
347 | // sometime again. | |||
348 | pFrame = pFrame->FindNext(); | |||
349 | ||||
350 | // If we started out in a SectionFrame, it might have happened that | |||
351 | // we landed in a Section Follow via the MakeAll calls. | |||
352 | // FindNext only gives us the SectionFrame, not it's content - we | |||
353 | // won't find ourselves anymore! | |||
354 | if( bNoSect && pFrame && pFrame->IsSctFrame() ) | |||
355 | { | |||
356 | SwFrame* pCnt = static_cast<SwSectionFrame*>(pFrame)->ContainsAny(); | |||
357 | if( pCnt ) | |||
358 | pFrame = pCnt; | |||
359 | } | |||
360 | } | |||
361 | OSL_ENSURE( GetUpper(), "Layout unstable (Upper gone II)." )do { if (true && (!(GetUpper()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/calcmove.cxx" ":" "361" ": "), "%s", "Layout unstable (Upper gone II)."); } } while (false); | |||
362 | if ( !GetUpper() ) | |||
363 | return; | |||
364 | ||||
365 | if ( lcl_IsCalcUpperAllowed( *this ) ) | |||
366 | GetUpper()->Calc(pRenderContext); | |||
367 | ||||
368 | OSL_ENSURE( GetUpper(), "Layout unstable (Upper gone III)." )do { if (true && (!(GetUpper()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/calcmove.cxx" ":" "368" ": "), "%s", "Layout unstable (Upper gone III)."); } } while (false); | |||
369 | } | |||
370 | ||||
371 | if ( bTab && !bOldTabLock ) | |||
372 | ::PrepareUnlock( static_cast<SwTabFrame*>(this) ); | |||
373 | } | |||
374 | MakeAll(pRenderContext); | |||
375 | } | |||
376 | ||||
377 | void SwFrame::OptPrepareMake() | |||
378 | { | |||
379 | // #i23129#, #i36347# - no format of upper Writer fly frame | |||
380 | if ( GetUpper() && !GetUpper()->IsFooterFrame() && | |||
381 | !GetUpper()->IsFlyFrame() ) | |||
382 | { | |||
383 | { | |||
384 | SwFrameDeleteGuard aDeleteGuard(this); | |||
385 | GetUpper()->Calc(getRootFrame()->GetCurrShell() ? getRootFrame()->GetCurrShell()->GetOut() : nullptr); | |||
386 | } | |||
387 | OSL_ENSURE( GetUpper(), ":-( Layout unstable (Upper gone)." )do { if (true && (!(GetUpper()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/calcmove.cxx" ":" "387" ": "), "%s", ":-( Layout unstable (Upper gone)."); } } while (false); | |||
388 | if ( !GetUpper() ) | |||
389 | return; | |||
390 | } | |||
391 | if ( GetPrev() && !GetPrev()->isFrameAreaDefinitionValid() ) | |||
392 | { | |||
393 | PrepareMake(getRootFrame()->GetCurrShell() ? getRootFrame()->GetCurrShell()->GetOut() : nullptr); | |||
394 | } | |||
395 | else | |||
396 | { | |||
397 | StackHack aHack; | |||
398 | MakeAll(IsRootFrame() ? nullptr : getRootFrame()->GetCurrShell()->GetOut()); | |||
399 | } | |||
400 | } | |||
401 | ||||
402 | void SwFrame::PrepareCursor() | |||
403 | { | |||
404 | StackHack aHack; | |||
405 | if( GetUpper() && !GetUpper()->IsSctFrame() ) | |||
406 | { | |||
407 | const bool bCnt = IsContentFrame(); | |||
408 | const bool bTab = IsTabFrame(); | |||
409 | bool bNoSect = IsInSct(); | |||
410 | ||||
411 | #if BOOST_VERSION107100 < 105600 | |||
412 | std::list<FlowFrameJoinLockGuard> tabGuard; | |||
413 | std::list<SwFrameDeleteGuard> rowGuard; | |||
414 | #else | |||
415 | std::optional<FlowFrameJoinLockGuard> tabGuard; | |||
416 | std::optional<SwFrameDeleteGuard> rowGuard; | |||
417 | #endif | |||
418 | SwFlowFrame* pThis = bCnt ? static_cast<SwContentFrame*>(this) : nullptr; | |||
419 | ||||
420 | if ( bTab ) | |||
421 | { | |||
422 | #if BOOST_VERSION107100 < 105600 | |||
423 | tabGuard.emplace_back(static_cast<SwTabFrame*>(this)); // tdf#125741 | |||
424 | #else | |||
425 | tabGuard.emplace(static_cast<SwTabFrame*>(this)); // tdf#125741 | |||
426 | #endif | |||
427 | pThis = static_cast<SwTabFrame*>(this); | |||
428 | } | |||
429 | else if (IsRowFrame()) | |||
430 | { | |||
431 | #if BOOST_VERSION107100 < 105600 | |||
432 | rowGuard.emplace_back(this); // tdf#125741 keep this alive | |||
433 | #else | |||
434 | rowGuard.emplace(this); // tdf#125741 keep this alive | |||
435 | #endif | |||
436 | } | |||
437 | else if( IsSctFrame() ) | |||
438 | { | |||
439 | pThis = static_cast<SwSectionFrame*>(this); | |||
440 | bNoSect = false; | |||
441 | } | |||
442 | ||||
443 | GetUpper()->PrepareCursor(); | |||
444 | GetUpper()->Calc(getRootFrame()->GetCurrShell() ? getRootFrame()->GetCurrShell()->GetOut() : nullptr); | |||
445 | ||||
446 | OSL_ENSURE( GetUpper(), ":-( Layout unstable (Upper gone)." )do { if (true && (!(GetUpper()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/calcmove.cxx" ":" "446" ": "), "%s", ":-( Layout unstable (Upper gone)."); } } while (false); | |||
447 | if ( !GetUpper() ) | |||
448 | return; | |||
449 | ||||
450 | bool const bFoll = pThis && pThis->IsFollow(); | |||
451 | ||||
452 | SwFrame *pFrame = GetUpper()->Lower(); | |||
453 | while ( pFrame != this ) | |||
454 | { | |||
455 | OSL_ENSURE( pFrame, ":-( Layout unstable (this not found)." )do { if (true && (!(pFrame))) { sal_detail_logFormat( (SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/calcmove.cxx" ":" "455" ": "), "%s", ":-( Layout unstable (this not found)." ); } } while (false); | |||
456 | if ( !pFrame ) | |||
457 | return; //Oioioioi ... | |||
458 | ||||
459 | if ( !pFrame->isFrameAreaDefinitionValid() ) | |||
460 | { | |||
461 | // A small interference that hopefully improves on the stability: | |||
462 | // If I'm Follow AND neighbor of a Frame before me, it would delete | |||
463 | // me when formatting. This as you can see could easily become a | |||
464 | // confusing situation that we want to avoid. | |||
465 | if ( bFoll && pFrame->IsFlowFrame() && | |||
466 | SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow( pThis ) ) | |||
467 | break; | |||
468 | ||||
469 | bool const isLast(pFrame->GetNext() == this); | |||
470 | pFrame->MakeAll(getRootFrame()->GetCurrShell()->GetOut()); | |||
471 | if (isLast && pFrame->GetUpper() != GetUpper()) | |||
472 | { | |||
473 | assert(GetUpper()->Lower() == this(static_cast <bool> (GetUpper()->Lower() == this || GetUpper ()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame (pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()-> Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow ( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame ::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame ::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))) ? void (0) : __assert_fail ("GetUpper()->Lower() == this || GetUpper()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame(pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()->Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/calcmove.cxx" , 487, __extension__ __PRETTY_FUNCTION__)) | |||
474 | // empty section frames are created all the time...(static_cast <bool> (GetUpper()->Lower() == this || GetUpper ()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame (pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()-> Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow ( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame ::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame ::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))) ? void (0) : __assert_fail ("GetUpper()->Lower() == this || GetUpper()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame(pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()->Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/calcmove.cxx" , 487, __extension__ __PRETTY_FUNCTION__)) | |||
475 | || GetUpper()->Lower()->IsSctFrame()(static_cast <bool> (GetUpper()->Lower() == this || GetUpper ()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame (pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()-> Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow ( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame ::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame ::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))) ? void (0) : __assert_fail ("GetUpper()->Lower() == this || GetUpper()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame(pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()->Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/calcmove.cxx" , 487, __extension__ __PRETTY_FUNCTION__)) | |||
476 | // tab frame/section frame may split multiple times(static_cast <bool> (GetUpper()->Lower() == this || GetUpper ()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame (pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()-> Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow ( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame ::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame ::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))) ? void (0) : __assert_fail ("GetUpper()->Lower() == this || GetUpper()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame(pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()->Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/calcmove.cxx" , 487, __extension__ __PRETTY_FUNCTION__)) | |||
477 | || ( SwFlowFrame::CastFlowFrame(pFrame)(static_cast <bool> (GetUpper()->Lower() == this || GetUpper ()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame (pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()-> Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow ( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame ::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame ::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))) ? void (0) : __assert_fail ("GetUpper()->Lower() == this || GetUpper()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame(pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()->Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/calcmove.cxx" , 487, __extension__ __PRETTY_FUNCTION__)) | |||
478 | && SwFlowFrame::CastFlowFrame(GetUpper()->Lower())(static_cast <bool> (GetUpper()->Lower() == this || GetUpper ()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame (pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()-> Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow ( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame ::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame ::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))) ? void (0) : __assert_fail ("GetUpper()->Lower() == this || GetUpper()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame(pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()->Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/calcmove.cxx" , 487, __extension__ __PRETTY_FUNCTION__)) | |||
479 | && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow((static_cast <bool> (GetUpper()->Lower() == this || GetUpper ()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame (pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()-> Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow ( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame ::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame ::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))) ? void (0) : __assert_fail ("GetUpper()->Lower() == this || GetUpper()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame(pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()->Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/calcmove.cxx" , 487, __extension__ __PRETTY_FUNCTION__)) | |||
480 | SwFlowFrame::CastFlowFrame(GetUpper()->Lower()))(static_cast <bool> (GetUpper()->Lower() == this || GetUpper ()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame (pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()-> Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow ( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame ::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame ::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))) ? void (0) : __assert_fail ("GetUpper()->Lower() == this || GetUpper()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame(pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()->Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/calcmove.cxx" , 487, __extension__ __PRETTY_FUNCTION__)) | |||
481 | && (GetUpper()->Lower()->GetNext() == this(static_cast <bool> (GetUpper()->Lower() == this || GetUpper ()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame (pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()-> Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow ( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame ::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame ::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))) ? void (0) : __assert_fail ("GetUpper()->Lower() == this || GetUpper()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame(pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()->Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/calcmove.cxx" , 487, __extension__ __PRETTY_FUNCTION__)) | |||
482 | // if it's more than 10 pages long...(static_cast <bool> (GetUpper()->Lower() == this || GetUpper ()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame (pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()-> Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow ( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame ::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame ::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))) ? void (0) : __assert_fail ("GetUpper()->Lower() == this || GetUpper()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame(pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()->Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/calcmove.cxx" , 487, __extension__ __PRETTY_FUNCTION__)) | |||
483 | || (SwFlowFrame::CastFlowFrame(GetUpper()->Lower())->GetFollow()(static_cast <bool> (GetUpper()->Lower() == this || GetUpper ()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame (pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()-> Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow ( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame ::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame ::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))) ? void (0) : __assert_fail ("GetUpper()->Lower() == this || GetUpper()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame(pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()->Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/calcmove.cxx" , 487, __extension__ __PRETTY_FUNCTION__)) | |||
484 | == SwFlowFrame::CastFlowFrame(GetUpper()->Lower()->GetNext())(static_cast <bool> (GetUpper()->Lower() == this || GetUpper ()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame (pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()-> Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow ( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame ::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame ::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))) ? void (0) : __assert_fail ("GetUpper()->Lower() == this || GetUpper()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame(pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()->Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/calcmove.cxx" , 487, __extension__ __PRETTY_FUNCTION__)) | |||
485 | && GetUpper()->Lower()->GetNext()->GetNext() == this)(static_cast <bool> (GetUpper()->Lower() == this || GetUpper ()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame (pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()-> Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow ( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame ::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame ::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))) ? void (0) : __assert_fail ("GetUpper()->Lower() == this || GetUpper()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame(pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()->Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/calcmove.cxx" , 487, __extension__ __PRETTY_FUNCTION__)) | |||
486 | // pre-existing empty section frames may end up between them...(static_cast <bool> (GetUpper()->Lower() == this || GetUpper ()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame (pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()-> Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow ( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame ::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame ::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))) ? void (0) : __assert_fail ("GetUpper()->Lower() == this || GetUpper()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame(pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()->Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/calcmove.cxx" , 487, __extension__ __PRETTY_FUNCTION__)) | |||
487 | || GetUpper()->Lower()->GetNext()->IsSctFrame())))(static_cast <bool> (GetUpper()->Lower() == this || GetUpper ()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame (pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()-> Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow ( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame ::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame ::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))) ? void (0) : __assert_fail ("GetUpper()->Lower() == this || GetUpper()->Lower()->IsSctFrame() || ( SwFlowFrame::CastFlowFrame(pFrame) && SwFlowFrame::CastFlowFrame(GetUpper()->Lower()) && SwFlowFrame::CastFlowFrame(pFrame)->IsAnFollow( SwFlowFrame::CastFlowFrame(GetUpper()->Lower())) && (GetUpper()->Lower()->GetNext() == this || (SwFlowFrame::CastFlowFrame(GetUpper()->Lower())->GetFollow() == SwFlowFrame::CastFlowFrame(GetUpper()->Lower()->GetNext()) && GetUpper()->Lower()->GetNext()->GetNext() == this) || GetUpper()->Lower()->GetNext()->IsSctFrame()))" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/calcmove.cxx" , 487, __extension__ __PRETTY_FUNCTION__)); | |||
488 | break; // tdf#119109 frame was moved backward, prevent | |||
489 | // FindNext() returning a frame inside this if | |||
490 | } // this is a table! | |||
491 | } | |||
492 | // With ContentFrames, the chain may be broken while walking through | |||
493 | // it. Therefore we have to figure out the next frame in a bit more | |||
494 | // complicated way. However, I'll HAVE to get back to myself | |||
495 | // sometime again. | |||
496 | pFrame = pFrame->FindNext(); | |||
497 | if( bNoSect && pFrame && pFrame->IsSctFrame() ) | |||
498 | { | |||
499 | SwFrame* pCnt = static_cast<SwSectionFrame*>(pFrame)->ContainsAny(); | |||
500 | if( pCnt ) | |||
501 | pFrame = pCnt; | |||
502 | } | |||
503 | } | |||
504 | OSL_ENSURE( GetUpper(), "Layout unstable (Upper gone II)." )do { if (true && (!(GetUpper()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/calcmove.cxx" ":" "504" ": "), "%s", "Layout unstable (Upper gone II)."); } } while (false); | |||
505 | if ( !GetUpper() ) | |||
506 | return; | |||
507 | ||||
508 | GetUpper()->Calc(getRootFrame()->GetCurrShell()->GetOut()); | |||
509 | ||||
510 | OSL_ENSURE( GetUpper(), "Layout unstable (Upper gone III)." )do { if (true && (!(GetUpper()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/calcmove.cxx" ":" "510" ": "), "%s", "Layout unstable (Upper gone III)."); } } while (false); | |||
511 | } | |||
512 | Calc(getRootFrame()->GetCurrShell() ? getRootFrame()->GetCurrShell()->GetOut() : nullptr); | |||
513 | } | |||
514 | ||||
515 | // Here we return GetPrev(); however we will ignore empty SectionFrames | |||
516 | static SwFrame* lcl_Prev( SwFrame* pFrame, bool bSectPrv = true ) | |||
517 | { | |||
518 | SwFrame* pRet = pFrame->GetPrev(); | |||
519 | if( !pRet && pFrame->GetUpper() && pFrame->GetUpper()->IsSctFrame() && | |||
520 | bSectPrv && !pFrame->IsColumnFrame() ) | |||
521 | pRet = pFrame->GetUpper()->GetPrev(); | |||
522 | while( pRet && pRet->IsSctFrame() && | |||
523 | !static_cast<SwSectionFrame*>(pRet)->GetSection() ) | |||
524 | pRet = pRet->GetPrev(); | |||
525 | return pRet; | |||
526 | } | |||
527 | ||||
528 | static SwFrame* lcl_NotHiddenPrev( SwFrame* pFrame ) | |||
529 | { | |||
530 | SwFrame *pRet = pFrame; | |||
531 | do | |||
532 | { | |||
533 | pRet = lcl_Prev( pRet ); | |||
534 | } while ( pRet && pRet->IsTextFrame() && static_cast<SwTextFrame*>(pRet)->IsHiddenNow() ); | |||
535 | return pRet; | |||
536 | } | |||
537 | ||||
538 | void SwFrame::MakePos() | |||
539 | { | |||
540 | if ( isFrameAreaPositionValid() ) | |||
541 | return; | |||
542 | ||||
543 | setFrameAreaPositionValid(true); | |||
544 | bool bUseUpper = false; | |||
545 | SwFrame* pPrv = lcl_Prev( this ); | |||
546 | if ( pPrv && | |||
547 | ( !pPrv->IsContentFrame() || | |||
548 | ( static_cast<SwContentFrame*>(pPrv)->GetFollow() != this ) ) | |||
549 | ) | |||
550 | { | |||
551 | if ( !StackHack::IsLocked() && | |||
552 | ( !IsInSct() || IsSctFrame() ) && | |||
553 | !pPrv->IsSctFrame() && | |||
554 | !pPrv->GetAttrSet()->GetKeep().GetValue() | |||
555 | ) | |||
556 | { | |||
557 | pPrv->Calc(getRootFrame()->GetCurrShell() ? getRootFrame()->GetCurrShell()->GetOut() : nullptr); // This may cause Prev to vanish! | |||
558 | } | |||
559 | else if ( pPrv->getFrameArea().Top() == 0 ) | |||
560 | { | |||
561 | bUseUpper = true; | |||
562 | } | |||
563 | } | |||
564 | ||||
565 | pPrv = lcl_Prev( this, false ); | |||
566 | const SwFrameType nMyType = GetType(); | |||
567 | SwRectFnSet aRectFnSet((IsCellFrame() && GetUpper() ? GetUpper() : this)); | |||
568 | if ( !bUseUpper && pPrv ) | |||
569 | { | |||
570 | SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this); | |||
571 | aFrm.Pos( pPrv->getFrameArea().Pos() ); | |||
572 | ||||
573 | if( FRM_NEIGHBOUR(SwFrameType::Column | SwFrameType::Cell) & nMyType ) | |||
574 | { | |||
575 | const bool bR2L = IsRightToLeft(); | |||
576 | ||||
577 | if( bR2L ) | |||
578 | { | |||
579 | aRectFnSet.SetPosX( aFrm, aRectFnSet.GetLeft(aFrm) - aRectFnSet.GetWidth(aFrm) ); | |||
580 | } | |||
581 | else | |||
582 | { | |||
583 | aRectFnSet.SetPosX( aFrm, aRectFnSet.GetLeft(aFrm) + aRectFnSet.GetWidth(pPrv->getFrameArea()) ); | |||
584 | } | |||
585 | ||||
586 | // cells may now leave their uppers | |||
587 | if( aRectFnSet.IsVert() && SwFrameType::Cell & nMyType ) | |||
588 | { | |||
589 | aFrm.Pos().setX(aFrm.Pos().getX() - aFrm.Width() + pPrv->getFrameArea().Width()); | |||
590 | } | |||
591 | } | |||
592 | else if( aRectFnSet.IsVert() && FRM_NOTE_VERT(SwFrameType::FtnCont | SwFrameType::Ftn | SwFrameType::Section | SwFrameType::Tab | SwFrameType::Row | SwFrameType::Cell | SwFrameType ::Txt) & nMyType ) | |||
593 | { | |||
594 | if ( aRectFnSet.IsVertL2R() ) | |||
595 | { | |||
596 | aFrm.Pos().setX(aFrm.Pos().getX() + pPrv->getFrameArea().Width()); | |||
597 | } | |||
598 | else | |||
599 | { | |||
600 | aFrm.Pos().setX(aFrm.Pos().getX() - aFrm.Width()); | |||
601 | } | |||
602 | } | |||
603 | else | |||
604 | { | |||
605 | aFrm.Pos().setY(aFrm.Pos().getY() + pPrv->getFrameArea().Height()); | |||
606 | } | |||
607 | } | |||
608 | else if ( GetUpper() ) | |||
609 | { | |||
610 | // If parent frame is a footer frame and its <ColLocked()>, then | |||
611 | // do *not* calculate it. | |||
612 | // NOTE: Footer frame is <ColLocked()> during its | |||
613 | // <FormatSize(..)>, which is called from <Format(..)>, which | |||
614 | // is called from <MakeAll()>, which is called from <Calc()>. | |||
615 | // #i56850# | |||
616 | // - no format of upper Writer fly frame, which is anchored | |||
617 | // at-paragraph or at-character. | |||
618 | if ( !GetUpper()->IsTabFrame() && | |||
619 | !( IsTabFrame() && GetUpper()->IsInTab() ) && | |||
620 | !GetUpper()->IsSctFrame() && | |||
621 | !dynamic_cast<SwFlyAtContentFrame*>(GetUpper()) && | |||
622 | !( GetUpper()->IsFooterFrame() && | |||
623 | GetUpper()->IsColLocked() ) | |||
624 | ) | |||
625 | { | |||
626 | GetUpper()->Calc(getRootFrame()->GetCurrShell()->GetOut()); | |||
627 | } | |||
628 | pPrv = lcl_Prev( this, false ); | |||
629 | if ( !bUseUpper && pPrv ) | |||
630 | { | |||
631 | SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this); | |||
632 | aFrm.Pos( pPrv->getFrameArea().Pos() ); | |||
633 | ||||
634 | if( FRM_NEIGHBOUR(SwFrameType::Column | SwFrameType::Cell) & nMyType ) | |||
635 | { | |||
636 | const bool bR2L = IsRightToLeft(); | |||
637 | ||||
638 | if( bR2L ) | |||
639 | { | |||
640 | aRectFnSet.SetPosX( aFrm, aRectFnSet.GetLeft(aFrm) - aRectFnSet.GetWidth(aFrm) ); | |||
641 | } | |||
642 | else | |||
643 | { | |||
644 | aRectFnSet.SetPosX( aFrm, aRectFnSet.GetLeft(aFrm) + aRectFnSet.GetWidth(pPrv->getFrameArea()) ); | |||
645 | } | |||
646 | ||||
647 | // cells may now leave their uppers | |||
648 | if( aRectFnSet.IsVert() && SwFrameType::Cell & nMyType ) | |||
649 | { | |||
650 | aFrm.Pos().setX(aFrm.Pos().getX() - aFrm.Width() + pPrv->getFrameArea().Width()); | |||
651 | } | |||
652 | } | |||
653 | else if( aRectFnSet.IsVert() && FRM_NOTE_VERT(SwFrameType::FtnCont | SwFrameType::Ftn | SwFrameType::Section | SwFrameType::Tab | SwFrameType::Row | SwFrameType::Cell | SwFrameType ::Txt) & nMyType ) | |||
654 | { | |||
655 | aFrm.Pos().setX(aFrm.Pos().getX() - aFrm.Width()); | |||
656 | } | |||
657 | else | |||
658 | { | |||
659 | aFrm.Pos().setY(aFrm.Pos().getY() + pPrv->getFrameArea().Height()); | |||
660 | } | |||
661 | } | |||
662 | else | |||
663 | { | |||
664 | SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this); | |||
665 | aFrm.Pos( GetUpper()->getFrameArea().Pos() ); | |||
666 | ||||
667 | if( GetUpper()->IsFlyFrame() ) | |||
668 | { | |||
669 | aFrm.Pos() += static_cast<SwFlyFrame*>(GetUpper())->ContentPos(); | |||
670 | } | |||
671 | else | |||
672 | { | |||
673 | aFrm.Pos() += GetUpper()->getFramePrintArea().Pos(); | |||
674 | } | |||
675 | ||||
676 | if( FRM_NEIGHBOUR(SwFrameType::Column | SwFrameType::Cell) & nMyType && IsRightToLeft() ) | |||
677 | { | |||
678 | if( aRectFnSet.IsVert() ) | |||
679 | { | |||
680 | aFrm.Pos().setY(aFrm.Pos().getY() + GetUpper()->getFramePrintArea().Height() - aFrm.Height()); | |||
681 | } | |||
682 | else | |||
683 | { | |||
684 | aFrm.Pos().setX(aFrm.Pos().getX() + GetUpper()->getFramePrintArea().Width() - aFrm.Width()); | |||
685 | } | |||
686 | } | |||
687 | else if( aRectFnSet.IsVert() && !aRectFnSet.IsVertL2R() && FRM_NOTE_VERT(SwFrameType::FtnCont | SwFrameType::Ftn | SwFrameType::Section | SwFrameType::Tab | SwFrameType::Row | SwFrameType::Cell | SwFrameType ::Txt) & nMyType ) | |||
688 | { | |||
689 | aFrm.Pos().setX(aFrm.Pos().getX() - aFrm.Width() + GetUpper()->getFramePrintArea().Width()); | |||
690 | } | |||
691 | } | |||
692 | } | |||
693 | else | |||
694 | { | |||
695 | SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this); | |||
696 | aFrm.Pos().setX(0); | |||
697 | aFrm.Pos().setY(0); | |||
698 | } | |||
699 | ||||
700 | if( IsBodyFrame() && aRectFnSet.IsVert() && !aRectFnSet.IsVertL2R() && GetUpper() ) | |||
701 | { | |||
702 | SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this); | |||
703 | aFrm.Pos().setX(aFrm.Pos().getX() + GetUpper()->getFramePrintArea().Width() - aFrm.Width()); | |||
704 | } | |||
705 | ||||
706 | setFrameAreaPositionValid(true); | |||
707 | } | |||
708 | ||||
709 | // #i28701# - new type <SwSortedObjs> | |||
710 | static void lcl_CheckObjects(SwSortedObjs& rSortedObjs, const SwFrame* pFrame, long& rBot) | |||
711 | { | |||
712 | // And then there can be paragraph anchored frames that sit below their paragraph. | |||
713 | long nMax = 0; | |||
714 | for (SwAnchoredObject* pObj : rSortedObjs) | |||
715 | { | |||
716 | // #i28701# - consider changed type of <SwSortedObjs> | |||
717 | // entries. | |||
718 | long nTmp = 0; | |||
719 | if ( dynamic_cast<const SwFlyFrame*>( pObj) != nullptr ) | |||
720 | { | |||
721 | SwFlyFrame *pFly = static_cast<SwFlyFrame*>(pObj); | |||
722 | if( pFly->getFrameArea().Top() != FAR_AWAY(((sal_Int32) 0x7FFFFFFF) - 20000) && | |||
723 | ( pFrame->IsPageFrame() ? pFly->IsFlyLayFrame() : | |||
724 | ( pFly->IsFlyAtContentFrame() && | |||
725 | ( pFrame->IsBodyFrame() ? pFly->GetAnchorFrame()->IsInDocBody() : | |||
726 | pFly->GetAnchorFrame()->IsInFootnote() ) ) ) ) | |||
727 | { | |||
728 | nTmp = pFly->getFrameArea().Bottom(); | |||
729 | } | |||
730 | } | |||
731 | else | |||
732 | nTmp = pObj->GetObjRect().Bottom(); | |||
| ||||
733 | nMax = std::max( nTmp, nMax ); | |||
734 | } | |||
735 | ++nMax; // Lower edge vs. height! | |||
736 | rBot = std::max( rBot, nMax ); | |||
737 | } | |||
738 | ||||
739 | size_t SwPageFrame::GetContentHeight(const long nTop, const long nBottom) const | |||
740 | { | |||
741 | OSL_ENSURE(!(FindBodyCont() && FindBodyCont()->Lower() && FindBodyCont()->Lower()->IsColumnFrame()),do { if (true && (!(!(FindBodyCont() && FindBodyCont ()->Lower() && FindBodyCont()->Lower()->IsColumnFrame ())))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl" ), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/calcmove.cxx" ":" "742" ": "), "%s", "SwPageFrame::GetContentHeight(): No support for columns." ); } } while (false) | |||
742 | "SwPageFrame::GetContentHeight(): No support for columns.")do { if (true && (!(!(FindBodyCont() && FindBodyCont ()->Lower() && FindBodyCont()->Lower()->IsColumnFrame ())))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl" ), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/calcmove.cxx" ":" "742" ": "), "%s", "SwPageFrame::GetContentHeight(): No support for columns." ); } } while (false); | |||
743 | ||||
744 | // In pages without columns, the content defines the size. | |||
745 | long nBot = getFrameArea().Top() + nTop; | |||
746 | const SwFrame *pFrame = Lower(); | |||
747 | while (pFrame) | |||
748 | { | |||
749 | long nTmp = 0; | |||
750 | const SwFrame *pCnt = static_cast<const SwLayoutFrame*>(pFrame)->ContainsAny(); | |||
751 | while (pCnt && (pCnt->GetUpper() == pFrame || | |||
752 | static_cast<const SwLayoutFrame*>(pFrame)->IsAnLower(pCnt))) | |||
753 | { | |||
754 | nTmp += pCnt->getFrameArea().Height(); | |||
755 | if (pCnt->IsTextFrame() && | |||
756 | static_cast<const SwTextFrame*>(pCnt)->IsUndersized()) | |||
757 | { | |||
758 | // This TextFrame would like to be a bit bigger. | |||
759 | nTmp += static_cast<const SwTextFrame*>(pCnt)->GetParHeight() | |||
760 | - pCnt->getFramePrintArea().Height(); | |||
761 | } | |||
762 | else if (pCnt->IsSctFrame()) | |||
763 | { | |||
764 | // Grow if undersized, but don't shrink if oversized. | |||
765 | const auto delta = static_cast<const SwSectionFrame*>(pCnt)->CalcUndersize(); | |||
766 | if (delta > 0) | |||
767 | nTmp += delta; | |||
768 | } | |||
769 | ||||
770 | pCnt = pCnt->FindNext(); | |||
771 | } | |||
772 | // Consider invalid body frame properties | |||
773 | if (pFrame->IsBodyFrame() && | |||
774 | (!pFrame->isFrameAreaSizeValid() || | |||
775 | !pFrame->isFramePrintAreaValid()) && | |||
776 | (pFrame->getFrameArea().Height() < pFrame->getFramePrintArea().Height()) | |||
777 | ) | |||
778 | { | |||
779 | nTmp = std::min(nTmp, pFrame->getFrameArea().Height()); | |||
780 | } | |||
781 | else | |||
782 | { | |||
783 | // Assert invalid lower property | |||
784 | OSL_ENSURE(!(pFrame->getFrameArea().Height() < pFrame->getFramePrintArea().Height()),do { if (true && (!(!(pFrame->getFrameArea().Height () < pFrame->getFramePrintArea().Height())))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/calcmove.cxx" ":" "785" ": "), "%s", "SwPageFrame::GetContentHeight(): Lower with frame height < printing height" ); } } while (false) | |||
785 | "SwPageFrame::GetContentHeight(): Lower with frame height < printing height")do { if (true && (!(!(pFrame->getFrameArea().Height () < pFrame->getFramePrintArea().Height())))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/calcmove.cxx" ":" "785" ": "), "%s", "SwPageFrame::GetContentHeight(): Lower with frame height < printing height" ); } } while (false); | |||
786 | nTmp += pFrame->getFrameArea().Height() - pFrame->getFramePrintArea().Height(); | |||
787 | } | |||
788 | if (!pFrame->IsBodyFrame()) | |||
789 | nTmp = std::min(nTmp, pFrame->getFrameArea().Height()); | |||
790 | nBot += nTmp; | |||
791 | // Here we check whether paragraph anchored objects | |||
792 | // protrude outside the Body/FootnoteCont. | |||
793 | if (m_pSortedObjs && !pFrame->IsHeaderFrame() && | |||
794 | !pFrame->IsFooterFrame()) | |||
795 | lcl_CheckObjects(*m_pSortedObjs, pFrame, nBot); | |||
796 | pFrame = pFrame->GetNext(); | |||
797 | } | |||
798 | nBot += nBottom; | |||
799 | // And the page anchored ones | |||
800 | if (m_pSortedObjs) | |||
801 | lcl_CheckObjects(*m_pSortedObjs, this, nBot); | |||
802 | nBot -= getFrameArea().Top(); | |||
803 | ||||
804 | return nBot; | |||
805 | } | |||
806 | ||||
807 | void SwPageFrame::MakeAll(vcl::RenderContext* pRenderContext) | |||
808 | { | |||
809 | PROTOCOL_ENTER( this, PROT::MakeAll, DbgAction::NONE, nullptr ) | |||
810 | ||||
811 | const SwRect aOldRect( getFrameArea() ); // Adjust root size | |||
812 | const SwLayNotify aNotify( this ); // takes care of the notification in the dtor | |||
813 | std::unique_ptr<SwBorderAttrAccess> pAccess; | |||
814 | const SwBorderAttrs*pAttrs = nullptr; | |||
815 | ||||
816 | while ( !isFrameAreaPositionValid() || !isFrameAreaSizeValid() || !isFramePrintAreaValid() ) | |||
| ||||
817 | { | |||
818 | if ( !isFrameAreaPositionValid() ) | |||
819 | { | |||
820 | setFrameAreaPositionValid(true); // positioning of the pages is taken care of by the root frame | |||
821 | } | |||
822 | ||||
823 | if ( !isFrameAreaSizeValid() || !isFramePrintAreaValid() ) | |||
824 | { | |||
825 | if ( IsEmptyPage() ) | |||
826 | { | |||
827 | SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this); | |||
828 | aFrm.Width( 0 ); | |||
829 | aFrm.Height( 0 ); | |||
830 | ||||
831 | SwFrameAreaDefinition::FramePrintAreaWriteAccess aPrt(*this); | |||
832 | aPrt.Width( 0 ); | |||
833 | aPrt.Height( 0 ); | |||
834 | aPrt.Left( 0 ); | |||
835 | aPrt.Top( 0 ); | |||
836 | ||||
837 | setFrameAreaSizeValid(true); | |||
838 | setFramePrintAreaValid(true); | |||
839 | } | |||
840 | else | |||
841 | { | |||
842 | if (!pAccess) | |||
843 | { | |||
844 | pAccess = std::make_unique<SwBorderAttrAccess>(SwFrame::GetCache(), this); | |||
845 | pAttrs = pAccess->Get(); | |||
846 | } | |||
847 | assert(pAttrs)(static_cast <bool> (pAttrs) ? void (0) : __assert_fail ("pAttrs", "/home/maarten/src/libreoffice/core/sw/source/core/layout/calcmove.cxx" , 847, __extension__ __PRETTY_FUNCTION__)); | |||
848 | ||||
849 | SwRootFrame* pRootFrame = getRootFrame(); | |||
850 | SwViewShell* pSh = pRootFrame->GetCurrShell(); | |||
851 | if (pSh && pSh->GetViewOptions()->getBrowseMode()) | |||
852 | { | |||
853 | // In BrowseView, we use fixed settings | |||
854 | const Size aBorder = pRenderContext->PixelToLogic( pSh->GetBrowseBorder() ); | |||
855 | const long nTop = pAttrs->CalcTopLine() + aBorder.Height(); | |||
856 | const long nBottom = pAttrs->CalcBottomLine()+ aBorder.Height(); | |||
857 | ||||
858 | long nWidth = GetUpper() ? static_cast<SwRootFrame*>(GetUpper())->GetBrowseWidth() : 0; | |||
859 | const auto nDefWidth = pSh->GetBrowseWidth(); | |||
860 | if (nWidth < nDefWidth) | |||
861 | nWidth = nDefWidth; | |||
862 | nWidth += + 2 * aBorder.Width(); | |||
863 | nWidth = std::max( nWidth, 2L * aBorder.Width() + 4*MM50283 ); | |||
864 | ||||
865 | { | |||
866 | SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this); | |||
867 | aFrm.Width( nWidth ); | |||
868 | ||||
869 | SwLayoutFrame *pBody = FindBodyCont(); | |||
870 | if ( pBody && pBody->Lower() && pBody->Lower()->IsColumnFrame() ) | |||
871 | { | |||
872 | // Columns have a fixed height | |||
873 | aFrm.Height( pAttrs->GetSize().Height() ); | |||
874 | } | |||
875 | else | |||
876 | { | |||
877 | // In pages without columns, the content defines the size. | |||
878 | long nBot = GetContentHeight(nTop, nBottom); | |||
879 | ||||
880 | // #i35143# - If second page frame | |||
881 | // exists, the first page doesn't have to fulfill the | |||
882 | // visible area. | |||
883 | if ( !GetPrev() && !GetNext() ) | |||
884 | { | |||
885 | nBot = std::max( nBot, pSh->VisArea().Height() ); | |||
886 | } | |||
887 | // #i35143# - Assure, that the page | |||
888 | // doesn't exceed the defined browse height. | |||
889 | aFrm.Height( std::min( nBot, BROWSE_HEIGHT(56700L * 10L) ) ); | |||
890 | } | |||
891 | } | |||
892 | ||||
893 | { | |||
894 | SwFrameAreaDefinition::FramePrintAreaWriteAccess aPrt(*this); | |||
895 | aPrt.Left ( pAttrs->CalcLeftLine() + aBorder.Width() ); | |||
896 | aPrt.Top ( nTop ); | |||
897 | aPrt.Width( getFrameArea().Width() - ( aPrt.Left() + pAttrs->CalcRightLine() + aBorder.Width() ) ); | |||
898 | aPrt.Height( getFrameArea().Height() - (nTop + nBottom) ); | |||
899 | } | |||
900 | ||||
901 | setFrameAreaSizeValid(true); | |||
902 | setFramePrintAreaValid(true); | |||
903 | continue; | |||
904 | } | |||
905 | else if (pSh
| |||
906 | { | |||
907 | long height = 0; | |||
908 | SwLayoutFrame *pBody = FindBodyCont(); | |||
909 | if ( pBody && pBody->Lower() && pBody->Lower()->IsColumnFrame() ) | |||
910 | { | |||
911 | // Columns have a fixed height | |||
912 | height = pAttrs->GetSize().Height(); | |||
913 | } | |||
914 | else | |||
915 | { | |||
916 | // No need for borders. | |||
917 | height = GetContentHeight(0, 0); | |||
918 | } | |||
919 | ||||
920 | if (height > 0) | |||
921 | { | |||
922 | ChgSize(Size(getFrameArea().Width(), height)); | |||
923 | SwFrameAreaDefinition::FramePrintAreaWriteAccess aPrt(*this); | |||
924 | aPrt.Top(0); | |||
925 | aPrt.Height(height); | |||
926 | setFrameAreaSizeValid(true); | |||
927 | setFramePrintAreaValid(true); | |||
928 | continue; | |||
929 | } | |||
930 | ||||
931 | // Fallback to default formatting. Especially relevant | |||
932 | // when loading a doc when Hide Whitespace is enabled. | |||
933 | // Heights are zero initially. | |||
934 | } | |||
935 | ||||
936 | // Set FixSize. For pages, this is not done from Upper, but from | |||
937 | // the attribute. | |||
938 | //FIXME: This resets the size when (isFrameAreaSizeValid() && !isFramePrintAreaValid()). | |||
939 | { | |||
940 | SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this); | |||
941 | aFrm.SSize( pAttrs->GetSize() ); | |||
942 | } | |||
943 | Format( pRenderContext, pAttrs ); | |||
944 | } | |||
945 | } | |||
946 | } //while ( !isFrameAreaPositionValid() || !isFrameAreaSizeValid() || !isFramePrintAreaValid() ) | |||
947 | ||||
948 | if ( getFrameArea() != aOldRect && GetUpper() ) | |||
949 | static_cast<SwRootFrame*>(GetUpper())->CheckViewLayout( nullptr, nullptr ); | |||
950 | ||||
951 | OSL_ENSURE( !GetUpper() || GetUpper()->getFramePrintArea().Width() >= getFrameArea().Width(),do { if (true && (!(!GetUpper() || GetUpper()->getFramePrintArea ().Width() >= getFrameArea().Width()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/calcmove.cxx" ":" "952" ": "), "%s", "Upper (Root) must be wide enough to contain the widest page" ); } } while (false) | |||
952 | "Upper (Root) must be wide enough to contain the widest page")do { if (true && (!(!GetUpper() || GetUpper()->getFramePrintArea ().Width() >= getFrameArea().Width()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/calcmove.cxx" ":" "952" ": "), "%s", "Upper (Root) must be wide enough to contain the widest page" ); } } while (false); | |||
953 | } | |||
954 | ||||
955 | void SwLayoutFrame::MakeAll(vcl::RenderContext* /*pRenderContext*/) | |||
956 | { | |||
957 | PROTOCOL_ENTER( this, PROT::MakeAll, DbgAction::NONE, nullptr ) | |||
958 | ||||
959 | // takes care of the notification in the dtor | |||
960 | const SwLayNotify aNotify( this ); | |||
961 | bool bVert = IsVertical(); | |||
962 | ||||
963 | SwRectFn fnRect = ( IsNeighbourFrame() == bVert )? fnRectHori : ( IsVertLR() ? (IsVertLRBT() ? fnRectVertL2RB2T : fnRectVertL2R) : fnRectVert ); | |||
964 | ||||
965 | std::unique_ptr<SwBorderAttrAccess> pAccess; | |||
966 | const SwBorderAttrs*pAttrs = nullptr; | |||
967 | ||||
968 | while ( !isFrameAreaPositionValid() || !isFrameAreaSizeValid() || !isFramePrintAreaValid() ) | |||
969 | { | |||
970 | if ( !isFrameAreaPositionValid() ) | |||
971 | MakePos(); | |||
972 | ||||
973 | if ( GetUpper() ) | |||
974 | { | |||
975 | // NEW TABLES | |||
976 | if ( IsLeaveUpperAllowed() ) | |||
977 | { | |||
978 | if ( !isFrameAreaSizeValid() ) | |||
979 | { | |||
980 | setFramePrintAreaValid(false); | |||
981 | } | |||
982 | } | |||
983 | else | |||
984 | { | |||
985 | if ( !isFrameAreaSizeValid() ) | |||
986 | { | |||
987 | // Set FixSize; VarSize is set by Format() after calculating the PrtArea | |||
988 | setFramePrintAreaValid(false); | |||
989 | ||||
990 | SwTwips nPrtWidth = (GetUpper()->getFramePrintArea().*fnRect->fnGetWidth)(); | |||
991 | if( bVert && ( IsBodyFrame() || IsFootnoteContFrame() ) ) | |||
992 | { | |||
993 | SwFrame* pNxt = GetPrev(); | |||
994 | while( pNxt && !pNxt->IsHeaderFrame() ) | |||
995 | pNxt = pNxt->GetPrev(); | |||
996 | if( pNxt ) | |||
997 | nPrtWidth -= pNxt->getFrameArea().Height(); | |||
998 | pNxt = GetNext(); | |||
999 | while( pNxt && !pNxt->IsFooterFrame() ) | |||
1000 | pNxt = pNxt->GetNext(); | |||
1001 | if( pNxt ) | |||
1002 | nPrtWidth -= pNxt->getFrameArea().Height(); | |||
1003 | } | |||
1004 | ||||
1005 | const long nDiff = nPrtWidth - (getFrameArea().*fnRect->fnGetWidth)(); | |||
1006 | SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this); | |||
1007 | ||||
1008 | if( IsNeighbourFrame() && IsRightToLeft() ) | |||
1009 | { | |||
1010 | (aFrm.*fnRect->fnSubLeft)( nDiff ); | |||
1011 | } | |||
1012 | else | |||
1013 | { | |||
1014 | (aFrm.*fnRect->fnAddRight)( nDiff ); | |||
1015 | } | |||
1016 | } | |||
1017 | else | |||
1018 | { | |||
1019 | // Don't leave your upper | |||
1020 | const SwTwips nDeadLine = (GetUpper()->*fnRect->fnGetPrtBottom)(); | |||
1021 | if( (getFrameArea().*fnRect->fnOverStep)( nDeadLine ) ) | |||
1022 | { | |||
1023 | setFrameAreaSizeValid(false); | |||
1024 | } | |||
1025 | } | |||
1026 | } | |||
1027 | } | |||
1028 | ||||
1029 | if ( !isFrameAreaSizeValid() || !isFramePrintAreaValid() ) | |||
1030 | { | |||
1031 | if ( !pAccess ) | |||
1032 | { | |||
1033 | pAccess = std::make_unique<SwBorderAttrAccess>(SwFrame::GetCache(), this); | |||
1034 | pAttrs = pAccess->Get(); | |||
1035 | } | |||
1036 | Format( getRootFrame()->GetCurrShell()->GetOut(), pAttrs ); | |||
1037 | } | |||
1038 | } //while ( !isFrameAreaPositionValid() || !isFrameAreaSizeValid() || !isFramePrintAreaValid() ) | |||
1039 | } | |||
1040 | ||||
1041 | bool SwTextNode::IsCollapse() const | |||
1042 | { | |||
1043 | if (GetDoc().GetDocumentSettingManager().get( DocumentSettingId::COLLAPSE_EMPTY_CELL_PARA ) | |||
1044 | && GetText().isEmpty()) | |||
1045 | { | |||
1046 | sal_uLong nIdx=GetIndex(); | |||
1047 | const SwEndNode *pNdBefore=GetNodes()[nIdx-1]->GetEndNode(); | |||
1048 | const SwEndNode *pNdAfter=GetNodes()[nIdx+1]->GetEndNode(); | |||
1049 | ||||
1050 | // The paragraph is collapsed only if the NdAfter is the end of a cell | |||
1051 | bool bInTable = FindTableNode( ) != nullptr; | |||
1052 | ||||
1053 | SwSortedObjs* pObjs = getLayoutFrame( GetDoc().getIDocumentLayoutAccess().GetCurrentLayout() )->GetDrawObjs( ); | |||
1054 | const size_t nObjs = ( pObjs != nullptr ) ? pObjs->size( ) : 0; | |||
1055 | ||||
1056 | return pNdBefore!=nullptr && pNdAfter!=nullptr && nObjs == 0 && bInTable; | |||
1057 | } | |||
1058 | ||||
1059 | return false; | |||
1060 | } | |||
1061 | ||||
1062 | bool SwFrame::IsCollapse() const | |||
1063 | { | |||
1064 | if (!IsTextFrame()) | |||
1065 | return false; | |||
1066 | ||||
1067 | const SwTextFrame *pTextFrame = static_cast<const SwTextFrame*>(this); | |||
1068 | const SwTextNode *pTextNode = pTextFrame->GetTextNodeForParaProps(); | |||
1069 | // TODO this SwTextNode function is pointless and should be merged in here | |||
1070 | return pTextFrame->GetText().isEmpty() && pTextNode && pTextNode->IsCollapse(); | |||
1071 | } | |||
1072 | ||||
1073 | void SwContentFrame::MakePrtArea( const SwBorderAttrs &rAttrs ) | |||
1074 | { | |||
1075 | if ( isFramePrintAreaValid() ) | |||
1076 | return; | |||
1077 | ||||
1078 | setFramePrintAreaValid(true); | |||
1079 | SwRectFnSet aRectFnSet(this); | |||
1080 | const bool bTextFrame = IsTextFrame(); | |||
1081 | SwTwips nUpper = 0; | |||
1082 | if ( bTextFrame && static_cast<SwTextFrame*>(this)->IsHiddenNow() ) | |||
1083 | { | |||
1084 | if ( static_cast<SwTextFrame*>(this)->HasFollow() ) | |||
1085 | static_cast<SwTextFrame*>(this)->JoinFrame(); | |||
1086 | ||||
1087 | if( aRectFnSet.GetHeight(getFramePrintArea()) ) | |||
1088 | { | |||
1089 | static_cast<SwTextFrame*>(this)->HideHidden(); | |||
1090 | } | |||
1091 | ||||
1092 | { | |||
1093 | SwFrameAreaDefinition::FramePrintAreaWriteAccess aPrt(*this); | |||
1094 | aPrt.Pos().setX(0); | |||
1095 | aPrt.Pos().setY(0); | |||
1096 | aRectFnSet.SetWidth( aPrt, aRectFnSet.GetWidth(getFrameArea()) ); | |||
1097 | aRectFnSet.SetHeight( aPrt, 0 ); | |||
1098 | } | |||
1099 | ||||
1100 | nUpper = -( aRectFnSet.GetHeight(getFrameArea()) ); | |||
1101 | } | |||
1102 | else | |||
1103 | { | |||
1104 | // Simplification: ContentFrames are always variable in height! | |||
1105 | ||||
1106 | // At the FixSize, the surrounding Frame enforces the size; | |||
1107 | // the borders are simply subtracted. | |||
1108 | const long nLeft = rAttrs.CalcLeft( this ); | |||
1109 | const long nRight = rAttrs.CalcRight( this ); | |||
1110 | aRectFnSet.SetXMargins( *this, nLeft, nRight ); | |||
1111 | ||||
1112 | SwViewShell *pSh = getRootFrame()->GetCurrShell(); | |||
1113 | SwTwips nWidthArea; | |||
1114 | if( pSh && 0!=(nWidthArea=aRectFnSet.GetWidth(pSh->VisArea())) && | |||
1115 | GetUpper()->IsPageBodyFrame() && // but not for BodyFrames in Columns | |||
1116 | pSh->GetViewOptions()->getBrowseMode() ) | |||
1117 | { | |||
1118 | // Do not protrude the edge of the visible area. The page may be | |||
1119 | // wider, because there may be objects with excess width | |||
1120 | // (RootFrame::ImplCalcBrowseWidth()) | |||
1121 | long nMinWidth = 0; | |||
1122 | ||||
1123 | for (size_t i = 0; GetDrawObjs() && i < GetDrawObjs()->size(); ++i) | |||
1124 | { | |||
1125 | // #i28701# - consider changed type of | |||
1126 | // <SwSortedObjs> entries | |||
1127 | SwAnchoredObject* pObj = (*GetDrawObjs())[i]; | |||
1128 | const SwFrameFormat& rFormat = pObj->GetFrameFormat(); | |||
1129 | const bool bFly = dynamic_cast<const SwFlyFrame*>( pObj) != nullptr; | |||
1130 | if ((bFly && (FAR_AWAY(((sal_Int32) 0x7FFFFFFF) - 20000) == pObj->GetObjRect().Width())) | |||
1131 | || rFormat.GetFrameSize().GetWidthPercent()) | |||
1132 | { | |||
1133 | continue; | |||
1134 | } | |||
1135 | ||||
1136 | if ( RndStdIds::FLY_AS_CHAR == rFormat.GetAnchor().GetAnchorId() ) | |||
1137 | { | |||
1138 | nMinWidth = std::max( nMinWidth, | |||
1139 | bFly ? rFormat.GetFrameSize().GetWidth() | |||
1140 | : pObj->GetObjRect().Width() ); | |||
1141 | } | |||
1142 | } | |||
1143 | ||||
1144 | const Size aBorder = pSh->GetOut()->PixelToLogic( pSh->GetBrowseBorder() ); | |||
1145 | long nWidth = nWidthArea - 2 * ( IsVertical() ? aBorder.Height() : aBorder.Width() ); | |||
1146 | nWidth -= aRectFnSet.GetLeft(getFramePrintArea()); | |||
1147 | nWidth -= rAttrs.CalcRightLine(); | |||
1148 | nWidth = std::max( nMinWidth, nWidth ); | |||
1149 | ||||
1150 | SwFrameAreaDefinition::FramePrintAreaWriteAccess aPrt(*this); | |||
1151 | aRectFnSet.SetWidth( aPrt, std::min( nWidth, aRectFnSet.GetWidth(aPrt) ) ); | |||
1152 | } | |||
1153 | ||||
1154 | if ( aRectFnSet.GetWidth(getFramePrintArea()) <= MINLAY23 ) | |||
1155 | { | |||
1156 | // The PrtArea should already be at least MINLAY wide, matching the | |||
1157 | // minimal values of the UI | |||
1158 | SwFrameAreaDefinition::FramePrintAreaWriteAccess aPrt(*this); | |||
1159 | aRectFnSet.SetWidth( aPrt, std::min( long(MINLAY23), aRectFnSet.GetWidth(getFrameArea()) ) ); | |||
1160 | SwTwips nTmp = aRectFnSet.GetWidth(getFrameArea()) - aRectFnSet.GetWidth(aPrt); | |||
1161 | ||||
1162 | if( aRectFnSet.GetLeft(aPrt) > nTmp ) | |||
1163 | { | |||
1164 | aRectFnSet.SetLeft( aPrt, nTmp ); | |||
1165 | } | |||
1166 | } | |||
1167 | ||||
1168 | // The following rules apply for VarSize: | |||
1169 | // 1. The first entry of a chain has no top border | |||
1170 | // 2. There is never a bottom border | |||
1171 | // 3. The top border is the maximum of the distance | |||
1172 | // of Prev downwards and our own distance upwards | |||
1173 | // Those three rules apply when calculating spacings | |||
1174 | // that are given by UL- and LRSpace. There might be a spacing | |||
1175 | // in all directions however; this may be caused by borders | |||
1176 | // and / or shadows. | |||
1177 | // 4. The spacing for TextFrames corresponds to the interline lead, | |||
1178 | // at a minimum. | |||
1179 | ||||
1180 | nUpper = CalcUpperSpace( &rAttrs ); | |||
1181 | ||||
1182 | SwTwips nLower = CalcLowerSpace( &rAttrs ); | |||
1183 | if (IsCollapse()) { | |||
1184 | nUpper=0; | |||
1185 | nLower=0; | |||
1186 | } | |||
1187 | ||||
1188 | { | |||
1189 | SwFrameAreaDefinition::FramePrintAreaWriteAccess aPrt(*this); | |||
1190 | aRectFnSet.SetPosY( aPrt, !aRectFnSet.IsVert() ? nUpper : nLower); | |||
1191 | } | |||
1192 | ||||
1193 | nUpper += nLower; | |||
1194 | nUpper -= aRectFnSet.GetHeight(getFrameArea()) - aRectFnSet.GetHeight(getFramePrintArea()); | |||
1195 | } | |||
1196 | // If there's a difference between old and new size, call Grow() or | |||
1197 | // Shrink() respectively. | |||
1198 | if ( nUpper ) | |||
1199 | { | |||
1200 | if ( nUpper > 0 ) | |||
1201 | GrowFrame( nUpper ); | |||
1202 | else | |||
1203 | ShrinkFrame( -nUpper ); | |||
1204 | } | |||
1205 | } | |||
1206 | ||||
1207 | #define STOP_FLY_FORMAT10 10 | |||
1208 | // - loop prevention | |||
1209 | const int cnStopFormat = 15; | |||
1210 | ||||
1211 | inline void ValidateSz( SwFrame *pFrame ) | |||
1212 | { | |||
1213 | if ( pFrame ) | |||
1214 | { | |||
1215 | pFrame->setFrameAreaSizeValid(true); | |||
1216 | pFrame->setFramePrintAreaValid(true); | |||
1217 | } | |||
1218 | } | |||
1219 | ||||
1220 | void SwContentFrame::MakeAll(vcl::RenderContext* /*pRenderContext*/) | |||
1221 | { | |||
1222 | OSL_ENSURE( GetUpper(), "no Upper?" )do { if (true && (!(GetUpper()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/calcmove.cxx" ":" "1222" ": "), "%s", "no Upper?"); } } while (false); | |||
1223 | OSL_ENSURE( IsTextFrame(), "MakeAll(), NoText" )do { if (true && (!(IsTextFrame()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/calcmove.cxx" ":" "1223" ": "), "%s", "MakeAll(), NoText"); } } while (false ); | |||
1224 | ||||
1225 | if ( !IsFollow() && StackHack::IsLocked() ) | |||
1226 | return; | |||
1227 | ||||
1228 | if ( IsJoinLocked() ) | |||
1229 | return; | |||
1230 | ||||
1231 | OSL_ENSURE( !static_cast<SwTextFrame*>(this)->IsSwapped(), "Calculation of a swapped frame" )do { if (true && (!(!static_cast<SwTextFrame*>( this)->IsSwapped()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/calcmove.cxx" ":" "1231" ": "), "%s", "Calculation of a swapped frame"); } } while (false); | |||
1232 | ||||
1233 | StackHack aHack; | |||
1234 | ||||
1235 | if ( static_cast<SwTextFrame*>(this)->IsLocked() ) | |||
1236 | { | |||
1237 | OSL_FAIL( "Format for locked TextFrame." )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/calcmove.cxx" ":" "1237" ": "), "%s", "Format for locked TextFrame."); } } while (false); | |||
1238 | return; | |||
1239 | } | |||
1240 | ||||
1241 | auto xDeleteGuard = std::make_unique<SwFrameDeleteGuard>(this); | |||
1242 | LockJoin(); | |||
1243 | long nFormatCount = 0; | |||
1244 | // - loop prevention | |||
1245 | int nConsecutiveFormatsWithoutChange = 0; | |||
1246 | PROTOCOL_ENTER( this, PROT::MakeAll, DbgAction::NONE, nullptr ) | |||
1247 | ||||
1248 | // takes care of the notification in the dtor | |||
1249 | std::unique_ptr<SwContentNotify, o3tl::default_delete<SwContentNotify>> pNotify(new SwContentNotify( this )); | |||
1250 | ||||
1251 | // as long as bMakePage is true, a new page can be created (exactly once) | |||
1252 | bool bMakePage = true; | |||
1253 | // bMovedBwd gets set to true when the frame flows backwards | |||
1254 | bool bMovedBwd = false; | |||
1255 | // as long as bMovedFwd is false, the Frame may flow backwards (until | |||
1256 | // it has been moved forward once) | |||
1257 | bool bMovedFwd = false; | |||
1258 | sal_Bool bFormatted = false; // For the widow/orphan rules, we encourage the | |||
1259 | // last ContentFrame of a chain to format. This only | |||
1260 | // needs to happen once. Every time the Frame is | |||
1261 | // moved, the flag will have to be reset. | |||
1262 | bool bMustFit = false; // Once the emergency brake is pulled, | |||
1263 | // no other prepares will be triggered | |||
1264 | bool bFitPromise = false; // If a paragraph didn't fit, but promises | |||
1265 | // with WouldFit that it would adjust accordingly, | |||
1266 | // this flag is set. If it turns out that it | |||
1267 | // didn't keep it's promise, we can act in a | |||
1268 | // controlled fashion. | |||
1269 | const bool bFly = IsInFly(); | |||
1270 | const bool bTab = IsInTab(); | |||
1271 | const bool bFootnote = IsInFootnote(); | |||
1272 | const bool bSct = IsInSct(); | |||
1273 | Point aOldFramePos; // This is so we can compare with the last pos | |||
1274 | Point aOldPrtPos; // and determine whether it makes sense to Prepare | |||
1275 | ||||
1276 | SwBorderAttrAccess aAccess( SwFrame::GetCache(), this ); | |||
1277 | const SwBorderAttrs &rAttrs = *aAccess.Get(); | |||
1278 | ||||
1279 | if ( !IsFollow() && rAttrs.JoinedWithPrev( *(this) ) ) | |||
1280 | { | |||
1281 | pNotify->SetBordersJoinedWithPrev(); | |||
1282 | } | |||
1283 | ||||
1284 | const bool bKeep = IsKeep(rAttrs.GetAttrSet().GetKeep(), GetBreakItem()); | |||
1285 | ||||
1286 | std::unique_ptr<SwSaveFootnoteHeight> pSaveFootnote; | |||
1287 | if ( bFootnote ) | |||
1288 | { | |||
1289 | SwFootnoteFrame *pFootnote = FindFootnoteFrame(); | |||
1290 | SwSectionFrame* pSct = pFootnote->FindSctFrame(); | |||
1291 | if ( !static_cast<SwTextFrame*>(pFootnote->GetRef())->IsLocked() ) | |||
1292 | { | |||
1293 | SwFootnoteBossFrame* pBoss = pFootnote->GetRef()->FindFootnoteBossFrame( | |||
1294 | pFootnote->GetAttr()->GetFootnote().IsEndNote() ); | |||
1295 | if( !pSct || pSct->IsColLocked() || !pSct->Growable() ) | |||
1296 | pSaveFootnote.reset( new SwSaveFootnoteHeight( pBoss, | |||
1297 | static_cast<SwTextFrame*>(pFootnote->GetRef())->GetFootnoteLine( pFootnote->GetAttr() ) ) ); | |||
1298 | } | |||
1299 | } | |||
1300 | ||||
1301 | if ( GetUpper()->IsSctFrame() && | |||
1302 | HasFollow() && !GetFollow()->IsDeleteForbidden() && | |||
1303 | &GetFollow()->GetFrame() == GetNext() ) | |||
1304 | { | |||
1305 | dynamic_cast<SwTextFrame&>(*this).JoinFrame(); | |||
1306 | } | |||
1307 | ||||
1308 | // #i28701# - move master forward, if it has to move, | |||
1309 | // because of its object positioning. | |||
1310 | if ( !static_cast<SwTextFrame*>(this)->IsFollow() ) | |||
1311 | { | |||
1312 | sal_uInt32 nToPageNum = 0; | |||
1313 | const bool bMoveFwdByObjPos = SwLayouter::FrameMovedFwdByObjPos( | |||
1314 | *(GetAttrSet()->GetDoc()), | |||
1315 | *static_cast<SwTextFrame*>(this), | |||
1316 | nToPageNum ); | |||
1317 | // #i58182# | |||
1318 | // Also move a paragraph forward, which is the first one inside a table cell. | |||
1319 | if ( bMoveFwdByObjPos && | |||
1320 | FindPageFrame()->GetPhyPageNum() < nToPageNum && | |||
1321 | ( lcl_Prev( this ) || | |||
1322 | GetUpper()->IsCellFrame() || | |||
1323 | ( GetUpper()->IsSctFrame() && | |||
1324 | GetUpper()->GetUpper()->IsCellFrame() ) ) && | |||
1325 | IsMoveable() ) | |||
1326 | { | |||
1327 | bMovedFwd = true; | |||
1328 | MoveFwd( bMakePage, false ); | |||
1329 | } | |||
1330 | } | |||
1331 | ||||
1332 | // If a Follow sits next to its Master and doesn't fit, we know it can | |||
1333 | // be moved right now. | |||
1334 | if ( lcl_Prev( this ) && static_cast<SwTextFrame*>(this)->IsFollow() && IsMoveable() ) | |||
1335 | { | |||
1336 | bMovedFwd = true; | |||
1337 | // If follow frame is in table, its master will be the last in the | |||
1338 | // current table cell. Thus, invalidate the printing area of the master. | |||
1339 | if ( IsInTab() ) | |||
1340 | { | |||
1341 | lcl_Prev( this )->InvalidatePrt(); | |||
1342 | } | |||
1343 | MoveFwd( bMakePage, false ); | |||
1344 | } | |||
1345 | ||||
1346 | // Check footnote content for forward move. | |||
1347 | // If a content of a footnote is on a prior page/column as its invalid | |||
1348 | // reference, it can be moved forward. | |||
1349 | if ( bFootnote && !isFrameAreaPositionValid() ) | |||
1350 | { | |||
1351 | SwFootnoteFrame* pFootnote = FindFootnoteFrame(); | |||
1352 | SwContentFrame* pRefCnt = pFootnote ? pFootnote->GetRef() : nullptr; | |||
1353 | ||||
1354 | if ( pRefCnt && !pRefCnt->isFrameAreaDefinitionValid() ) | |||
1355 | { | |||
1356 | SwFootnoteBossFrame* pFootnoteBossOfFootnote = pFootnote->FindFootnoteBossFrame(); | |||
1357 | SwFootnoteBossFrame* pFootnoteBossOfRef = pRefCnt->FindFootnoteBossFrame(); | |||
1358 | //<loop of movefwd until condition held or no move> | |||
1359 | if ( pFootnoteBossOfFootnote && pFootnoteBossOfRef && | |||
1360 | pFootnoteBossOfFootnote != pFootnoteBossOfRef && | |||
1361 | pFootnoteBossOfFootnote->IsBefore( pFootnoteBossOfRef ) ) | |||
1362 | { | |||
1363 | bMovedFwd = true; | |||
1364 | MoveFwd( bMakePage, false ); | |||
1365 | } | |||
1366 | } | |||
1367 | } | |||
1368 | ||||
1369 | SwRectFnSet aRectFnSet(this); | |||
1370 | ||||
1371 | SwFrame const* pMoveBwdPre(nullptr); | |||
1372 | bool isMoveBwdPreValid(false); | |||
1373 | ||||
1374 | SwRect aOldFrame_StopFormat, aOldFrame_StopFormat2; | |||
1375 | SwRect aOldPrt_StopFormat, aOldPrt_StopFormat2; | |||
1376 | ||||
1377 | while ( !isFrameAreaPositionValid() || !isFrameAreaSizeValid() || !isFramePrintAreaValid() ) | |||
1378 | { | |||
1379 | // - loop prevention | |||
1380 | aOldFrame_StopFormat2 = aOldFrame_StopFormat; | |||
1381 | aOldPrt_StopFormat2 = aOldPrt_StopFormat; | |||
1382 | aOldFrame_StopFormat = getFrameArea(); | |||
1383 | aOldPrt_StopFormat = getFramePrintArea(); | |||
1384 | ||||
1385 | bool bMoveable = IsMoveable(); | |||
1386 | if (bMoveable) | |||
1387 | { | |||
1388 | SwFrame *pPre = GetIndPrev(); | |||
1389 | if ( CheckMoveFwd( bMakePage, bKeep, bMovedBwd ) ) | |||
1390 | { | |||
1391 | aRectFnSet.Refresh(this); | |||
1392 | bMovedFwd = true; | |||
1393 | if ( bMovedBwd ) | |||
1394 | { | |||
1395 | // While flowing back, the Upper was encouraged to | |||
1396 | // completely re-paint itself. We can skip this now after | |||
1397 | // flowing back and forth. | |||
1398 | GetUpper()->ResetCompletePaint(); | |||
1399 | // The predecessor was invalidated, so this is obsolete as well now. | |||
1400 | assert(pPre)(static_cast <bool> (pPre) ? void (0) : __assert_fail ( "pPre", "/home/maarten/src/libreoffice/core/sw/source/core/layout/calcmove.cxx" , 1400, __extension__ __PRETTY_FUNCTION__)); | |||
1401 | if ((pPre == pMoveBwdPre && isMoveBwdPreValid) && !pPre->IsSctFrame()) | |||
1402 | ::ValidateSz( pPre ); | |||
1403 | } | |||
1404 | bMoveable = IsMoveable(); | |||
1405 | } | |||
1406 | } | |||
1407 | ||||
1408 | aOldFramePos = aRectFnSet.GetPos(getFrameArea()); | |||
1409 | aOldPrtPos = aRectFnSet.GetPos(getFramePrintArea()); | |||
1410 | ||||
1411 | if ( !isFrameAreaPositionValid() ) | |||
1412 | MakePos(); | |||
1413 | ||||
1414 | //Set FixSize. VarSize is being adjusted by Format(). | |||
1415 | if ( !isFrameAreaSizeValid() ) | |||
1416 | { | |||
1417 | // invalidate printing area flag, if the following conditions are hold: | |||
1418 | // - current frame width is 0. | |||
1419 | // - current printing area width is 0. | |||
1420 | // - frame width is adjusted to a value greater than 0. | |||
1421 | // - printing area flag is true. | |||
1422 | // Thus, it's assured that the printing area is adjusted, if the | |||
1423 | // frame area width changes its width from 0 to something greater | |||
1424 | // than 0. | |||
1425 | // Note: A text frame can be in such a situation, if the format is | |||
1426 | // triggered by method call <SwCursorShell::SetCursor()> after | |||
1427 | // loading the document. | |||
1428 | const SwTwips nNewFrameWidth = aRectFnSet.GetWidth(GetUpper()->getFramePrintArea()); | |||
1429 | ||||
1430 | if ( isFramePrintAreaValid() && | |||
1431 | nNewFrameWidth > 0 && | |||
1432 | aRectFnSet.GetWidth(getFrameArea()) == 0 && | |||
1433 | aRectFnSet.GetWidth(getFramePrintArea()) == 0 ) | |||
1434 | { | |||
1435 | setFramePrintAreaValid(false); | |||
1436 | } | |||
1437 | ||||
1438 | { | |||
1439 | SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this); | |||
1440 | aRectFnSet.SetWidth( aFrm, nNewFrameWidth ); | |||
1441 | } | |||
1442 | ||||
1443 | // When a lower of a vertically aligned fly frame changes its size we need to recalculate content pos. | |||
1444 | if( GetUpper() && GetUpper()->IsFlyFrame() && | |||
1445 | GetUpper()->GetFormat()->GetTextVertAdjust().GetValue() != SDRTEXTVERTADJUST_TOP ) | |||
1446 | { | |||
1447 | static_cast<SwFlyFrame*>(GetUpper())->InvalidateContentPos(); | |||
1448 | GetUpper()->SetCompletePaint(); | |||
1449 | } | |||
1450 | } | |||
1451 | if ( !isFramePrintAreaValid() ) | |||
1452 | { | |||
1453 | const long nOldW = aRectFnSet.GetWidth(getFramePrintArea()); | |||
1454 | // #i34730# - keep current frame height | |||
1455 | const SwTwips nOldH = aRectFnSet.GetHeight(getFrameArea()); | |||
1456 | MakePrtArea( rAttrs ); | |||
1457 | if ( nOldW != aRectFnSet.GetWidth(getFramePrintArea()) ) | |||
1458 | Prepare( PrepareHint::FixSizeChanged ); | |||
1459 | // #i34730# - check, if frame height has changed. | |||
1460 | // If yes, send a PrepareHint::AdjustSizeWithoutFormatting and invalidate the size flag to | |||
1461 | // force a format. The format will check in its method | |||
1462 | // <SwTextFrame::CalcPreps()>, if the already formatted lines still | |||
1463 | // fit and if not, performs necessary actions. | |||
1464 | // #i40150# - no check, if frame is undersized. | |||
1465 | if ( isFrameAreaSizeValid() && !IsUndersized() && nOldH != aRectFnSet.GetHeight(getFrameArea()) ) | |||
1466 | { | |||
1467 | // #115759# - no PrepareHint::AdjustSizeWithoutFormatting and size | |||
1468 | // invalidation, if height decreases only by the additional | |||
1469 | // lower space as last content of a table cell and an existing | |||
1470 | // follow containing one line exists. | |||
1471 | const SwTwips nHDiff = nOldH - aRectFnSet.GetHeight(getFrameArea()); | |||
1472 | const bool bNoPrepAdjustFrame = | |||
1473 | nHDiff > 0 && IsInTab() && GetFollow() && | |||
1474 | (1 == static_cast<SwTextFrame*>(GetFollow())->GetLineCount(TextFrameIndex(COMPLETE_STRING)) | |||
1475 | || aRectFnSet.GetWidth(static_cast<SwTextFrame*>(GetFollow())->getFrameArea()) < 0) && | |||
1476 | GetFollow()->CalcAddLowerSpaceAsLastInTableCell() == nHDiff; | |||
1477 | if ( !bNoPrepAdjustFrame ) | |||
1478 | { | |||
1479 | Prepare( PrepareHint::AdjustSizeWithoutFormatting ); | |||
1480 | setFrameAreaSizeValid(false); | |||
1481 | } | |||
1482 | } | |||
1483 | } | |||
1484 | ||||
1485 | // To make the widow and orphan rules work, we need to notify the ContentFrame. | |||
1486 | // Criteria: | |||
1487 | // - It needs to be movable (otherwise, splitting doesn't make sense) | |||
1488 | // - It needs to overlap with the lower edge of the PrtArea of the Upper | |||
1489 | if ( !bMustFit ) | |||
1490 | { | |||
1491 | bool bWidow = true; | |||
1492 | const SwTwips nDeadLine = aRectFnSet.GetPrtBottom(*GetUpper()); | |||
1493 | if( bMoveable && !bFormatted && | |||
1494 | ( GetFollow() || aRectFnSet.OverStep( getFrameArea(), nDeadLine ) ) ) | |||
1495 | { | |||
1496 | Prepare( PrepareHint::WidowsOrphans, nullptr, false ); | |||
1497 | setFrameAreaSizeValid(false); | |||
1498 | bWidow = false; | |||
1499 | } | |||
1500 | if( aRectFnSet.GetPos(getFrameArea()) != aOldFramePos || | |||
1501 | aRectFnSet.GetPos(getFramePrintArea()) != aOldPrtPos ) | |||
1502 | { | |||
1503 | // In this Prepare, an InvalidateSize_() might happen. | |||
1504 | // isFrameAreaSizeValid() becomes false and Format() gets called. | |||
1505 | Prepare( PrepareHint::FramePositionChanged, static_cast<const void*>(&bFormatted), false ); | |||
1506 | if ( bWidow && GetFollow() ) | |||
1507 | { | |||
1508 | Prepare( PrepareHint::WidowsOrphans, nullptr, false ); | |||
1509 | setFrameAreaSizeValid(false); | |||
1510 | } | |||
1511 | } | |||
1512 | } | |||
1513 | if ( !isFrameAreaSizeValid() ) | |||
1514 | { | |||
1515 | setFrameAreaSizeValid(true); | |||
1516 | bFormatted = true; | |||
1517 | ++nFormatCount; | |||
1518 | if( nFormatCount > STOP_FLY_FORMAT10 ) | |||
1519 | SetFlyLock( true ); | |||
1520 | // - loop prevention | |||
1521 | // No format any longer, if <cnStopFormat> consecutive formats | |||
1522 | // without change occur. | |||
1523 | if ( nConsecutiveFormatsWithoutChange <= cnStopFormat ) | |||
1524 | { | |||
1525 | Format(getRootFrame()->GetCurrShell()->GetOut()); | |||
1526 | } | |||
1527 | #if OSL_DEBUG_LEVEL1 > 0 | |||
1528 | else | |||
1529 | { | |||
1530 | OSL_FAIL( "debug assertion: <SwContentFrame::MakeAll()> - format of text frame suppressed by fix b6448963" )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/calcmove.cxx" ":" "1530" ": "), "%s", "debug assertion: <SwContentFrame::MakeAll()> - format of text frame suppressed by fix b6448963" ); } } while (false); | |||
1531 | } | |||
1532 | #endif | |||
1533 | } | |||
1534 | ||||
1535 | // If this is the first one in a chain, check if this can flow | |||
1536 | // backwards (if this is movable at all). | |||
1537 | // To prevent oscillations/loops, check that this has not just | |||
1538 | // flowed forwards. | |||
1539 | bool bDummy; | |||
1540 | auto const pTemp(GetIndPrev()); | |||
1541 | auto const bTemp(pTemp && pTemp->isFrameAreaSizeValid() | |||
1542 | && pTemp->isFramePrintAreaValid()); | |||
1543 | if ( !lcl_Prev( this ) && | |||
1544 | !bMovedFwd && | |||
1545 | ( bMoveable || ( bFly && !bTab ) ) && | |||
1546 | ( !bFootnote || !GetUpper()->FindFootnoteFrame()->GetPrev() ) | |||
1547 | && MoveBwd( bDummy ) ) | |||
1548 | { | |||
1549 | aRectFnSet.Refresh(this); | |||
1550 | pMoveBwdPre = pTemp; | |||
1551 | isMoveBwdPreValid = bTemp; | |||
1552 | bMovedBwd = true; | |||
1553 | bFormatted = false; | |||
1554 | if ( bKeep && bMoveable ) | |||
1555 | { | |||
1556 | if( CheckMoveFwd( bMakePage, false, bMovedBwd ) ) | |||
1557 | { | |||
1558 | bMovedFwd = true; | |||
1559 | bMoveable = IsMoveable(); | |||
1560 | aRectFnSet.Refresh(this); | |||
1561 | } | |||
1562 | Point aOldPos = aRectFnSet.GetPos(getFrameArea()); | |||
1563 | MakePos(); | |||
1564 | if( aOldPos != aRectFnSet.GetPos(getFrameArea()) ) | |||
1565 | { | |||
1566 | Prepare( PrepareHint::FramePositionChanged, static_cast<const void*>(&bFormatted), false ); | |||
1567 | if ( !isFrameAreaSizeValid() ) | |||
1568 | { | |||
1569 | { | |||
1570 | SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this); | |||
1571 | aRectFnSet.SetWidth( aFrm, aRectFnSet.GetWidth(GetUpper()->getFramePrintArea()) ); | |||
1572 | } | |||
1573 | ||||
1574 | if ( !isFramePrintAreaValid() ) | |||
1575 | { | |||
1576 | const long nOldW = aRectFnSet.GetWidth(getFramePrintArea()); | |||
1577 | MakePrtArea( rAttrs ); | |||
1578 | if( nOldW != aRectFnSet.GetWidth(getFramePrintArea()) ) | |||
1579 | Prepare( PrepareHint::FixSizeChanged, nullptr, false ); | |||
1580 | } | |||
1581 | if( GetFollow() ) | |||
1582 | { | |||
1583 | Prepare( PrepareHint::WidowsOrphans, nullptr, false ); | |||
1584 | } | |||
1585 | ||||
1586 | setFrameAreaSizeValid(true); | |||
1587 | bFormatted = true; | |||
1588 | Format(getRootFrame()->GetCurrShell()->GetOut()); | |||
1589 | } | |||
1590 | } | |||
1591 | SwFrame *pNxt = HasFollow() ? nullptr : FindNext(); | |||
1592 | while( pNxt && pNxt->IsSctFrame() ) | |||
1593 | { // Leave empty sections out, go into the other ones. | |||
1594 | if( static_cast<SwSectionFrame*>(pNxt)->GetSection() ) | |||
1595 | { | |||
1596 | SwFrame* pTmp = static_cast<SwSectionFrame*>(pNxt)->ContainsAny(); | |||
1597 | if( pTmp ) | |||
1598 | { | |||
1599 | pNxt = pTmp; | |||
1600 | break; | |||
1601 | } | |||
1602 | } | |||
1603 | pNxt = pNxt->FindNext(); | |||
1604 | } | |||
1605 | if ( pNxt ) | |||
1606 | { | |||
1607 | pNxt->Calc(getRootFrame()->GetCurrShell()->GetOut()); | |||
1608 | if( isFrameAreaPositionValid() && !GetIndNext() ) | |||
1609 | { | |||
1610 | SwSectionFrame *pSct = FindSctFrame(); | |||
1611 | if( pSct && !pSct->isFrameAreaSizeValid() ) | |||
1612 | { | |||
1613 | SwSectionFrame* pNxtSct = pNxt->FindSctFrame(); | |||
1614 | if( pNxtSct && pSct->IsAnFollow( pNxtSct ) ) | |||
1615 | { | |||
1616 | setFrameAreaPositionValid(false); | |||
1617 | } | |||
1618 | } | |||
1619 | else | |||
1620 | { | |||
1621 | setFrameAreaPositionValid(false); | |||
1622 | } | |||
1623 | } | |||
1624 | } | |||
1625 | } | |||
1626 | } | |||
1627 | ||||
1628 | // In footnotes, the TextFrame may validate itself, which can lead to the | |||
1629 | // situation that it's position is wrong despite being "valid". | |||
1630 | if ( isFrameAreaPositionValid() ) | |||
1631 | { | |||
1632 | // #i59341# | |||
1633 | // Workaround for inadequate layout algorithm: | |||
1634 | // suppress invalidation and calculation of position, if paragraph | |||
1635 | // has formatted itself at least STOP_FLY_FORMAT times and | |||
1636 | // has anchored objects. | |||
1637 | // Thus, the anchored objects get the possibility to format itself | |||
1638 | // and this probably solve the layout loop. | |||
1639 | if ( bFootnote && | |||
1640 | nFormatCount <= STOP_FLY_FORMAT10 && | |||
1641 | !GetDrawObjs() ) | |||
1642 | { | |||
1643 | setFrameAreaPositionValid(false); | |||
1644 | MakePos(); | |||
1645 | aOldFramePos = aRectFnSet.GetPos(getFrameArea()); | |||
1646 | aOldPrtPos = aRectFnSet.GetPos(getFramePrintArea()); | |||
1647 | } | |||
1648 | } | |||
1649 | ||||
1650 | // - loop prevention | |||
1651 | { | |||
1652 | if ( (aOldFrame_StopFormat == getFrameArea() || aOldFrame_StopFormat2 == getFrameArea() ) && | |||
1653 | (aOldPrt_StopFormat == getFramePrintArea() || aOldPrt_StopFormat2 == getFramePrintArea())) | |||
1654 | { | |||
1655 | ++nConsecutiveFormatsWithoutChange; | |||
1656 | } | |||
1657 | else | |||
1658 | { | |||
1659 | nConsecutiveFormatsWithoutChange = 0; | |||
1660 | } | |||
1661 | } | |||
1662 | ||||
1663 | // Yet again an invalid value? Repeat from the start... | |||
1664 | if ( !isFrameAreaPositionValid() || !isFrameAreaSizeValid() || !isFramePrintAreaValid() ) | |||
1665 | continue; | |||
1666 | ||||
1667 | // Done? | |||
1668 | // Attention: because height == 0, it's better to use Top()+Height() instead of | |||
1669 | // Bottom(). This might happen with undersized TextFrames on the lower edge of a | |||
1670 | // multi-column section | |||
1671 | const long nPrtBottom = aRectFnSet.GetPrtBottom(*GetUpper()); | |||
1672 | long nBottomDist = aRectFnSet.BottomDist(getFrameArea(), nPrtBottom); | |||
1673 | ||||
1674 | // Hide whitespace may require not to insert a new page. | |||
1675 | SwPageFrame* pPageFrame = FindPageFrame(); | |||
1676 | const bool bHeightValid = pPageFrame->CheckPageHeightValidForHideWhitespace(nBottomDist); | |||
1677 | if (!bHeightValid) | |||
1678 | { | |||
1679 | pPageFrame->InvalidateSize(); | |||
1680 | nBottomDist = 0; | |||
1681 | } | |||
1682 | ||||
1683 | if( nBottomDist >= 0 ) | |||
1684 | { | |||
1685 | if ( bKeep && bMoveable ) | |||
1686 | { | |||
1687 | // We make sure the successor will be formatted the same. | |||
1688 | // This way, we keep control until (almost) everything is stable, | |||
1689 | // allowing us to avoid endless loops caused by ever repeating | |||
1690 | // retries. | |||
1691 | ||||
1692 | // bMoveFwdInvalid is required for #38407#. This was originally solved | |||
1693 | // in flowfrm.cxx rev 1.38, but broke the above schema and | |||
1694 | // preferred to play towers of hanoi (#43669#). | |||
1695 | SwFrame *pNxt = HasFollow() ? nullptr : FindNext(); | |||
1696 | // For sections we prefer the content, because it can change | |||
1697 | // the page if required. | |||
1698 | while( pNxt && pNxt->IsSctFrame() ) | |||
1699 | { | |||
1700 | if( static_cast<SwSectionFrame*>(pNxt)->GetSection() ) | |||
1701 | { | |||
1702 | pNxt = static_cast<SwSectionFrame*>(pNxt)->ContainsAny(); | |||
1703 | break; | |||
1704 | } | |||
1705 | pNxt = pNxt->FindNext(); | |||
1706 | } | |||
1707 | if ( pNxt ) | |||
1708 | { | |||
1709 | const bool bMoveFwdInvalid = nullptr != GetIndNext(); | |||
1710 | const bool bNxtNew = | |||
1711 | ( 0 == aRectFnSet.GetHeight(pNxt->getFramePrintArea()) ) && | |||
1712 | (!pNxt->IsTextFrame() ||!static_cast<SwTextFrame*>(pNxt)->IsHiddenNow()); | |||
1713 | ||||
1714 | pNxt->Calc(getRootFrame()->GetCurrShell()->GetOut()); | |||
1715 | ||||
1716 | if ( !bMovedBwd && | |||
1717 | ((bMoveFwdInvalid && !GetIndNext()) || | |||
1718 | bNxtNew) ) | |||
1719 | { | |||
1720 | if( bMovedFwd ) | |||
1721 | pNotify->SetInvaKeep(); | |||
1722 | bMovedFwd = false; | |||
1723 | } | |||
1724 | } | |||
1725 | } | |||
1726 | continue; | |||
1727 | } | |||
1728 | ||||
1729 | // I don't fit into my parents, so it's time to make changes | |||
1730 | // as constructively as possible. | |||
1731 | ||||
1732 | //If I'm NOT allowed to leave the parent Frame, I've got a problem. | |||
1733 | // Following Arthur Dent, we do the only thing that you can do with | |||
1734 | // an unsolvable problem: We ignore it with all our power. | |||
1735 | if ( !bMoveable || IsUndersized() ) | |||
1736 | { | |||
1737 | if( !bMoveable && IsInTab() ) | |||
1738 | { | |||
1739 | long nDiff = -aRectFnSet.BottomDist( getFrameArea(), aRectFnSet.GetPrtBottom(*GetUpper()) ); | |||
1740 | long nReal = GetUpper()->Grow( nDiff ); | |||
1741 | if( nReal ) | |||
1742 | continue; | |||
1743 | } | |||
1744 | break; | |||
1745 | } | |||
1746 | ||||
1747 | // If there's no way I can make myself fit into my Upper, the situation | |||
1748 | // could still probably be mitigated by splitting up. | |||
1749 | // This situation arises with freshly created Follows that had been moved | |||
1750 | // to the next page but is still too big for it - ie. needs to be split | |||
1751 | // as well. | |||
1752 | ||||
1753 | // If I'm unable to split (WouldFit()) and can't be fitted, I'm going | |||
1754 | // to tell my TextFrame part that, if possible, we still need to split despite | |||
1755 | // the "don't split" attribute. | |||
1756 | bool bMoveOrFit = false; | |||
1757 | bool bDontMoveMe = !GetIndPrev(); | |||
1758 | if( bDontMoveMe && IsInSct() ) | |||
1759 | { | |||
1760 | SwFootnoteBossFrame* pBoss = FindFootnoteBossFrame(); | |||
1761 | bDontMoveMe = !pBoss->IsInSct() || | |||
1762 | ( !pBoss->Lower()->GetNext() && !pBoss->GetPrev() ); | |||
1763 | } | |||
1764 | ||||
1765 | // Finally, we are able to split table rows. Therefore, bDontMoveMe | |||
1766 | // can be set to false: | |||
1767 | if( bDontMoveMe && IsInTab() && | |||
1768 | nullptr != GetNextCellLeaf() ) | |||
1769 | bDontMoveMe = false; | |||
1770 | ||||
1771 | assert(bMoveable)(static_cast <bool> (bMoveable) ? void (0) : __assert_fail ("bMoveable", "/home/maarten/src/libreoffice/core/sw/source/core/layout/calcmove.cxx" , 1771, __extension__ __PRETTY_FUNCTION__)); | |||
1772 | ||||
1773 | if ( bDontMoveMe && aRectFnSet.GetHeight(getFrameArea()) > | |||
1774 | aRectFnSet.GetHeight(GetUpper()->getFramePrintArea()) ) | |||
1775 | { | |||
1776 | if ( !bFitPromise ) | |||
1777 | { | |||
1778 | SwTwips nTmp = aRectFnSet.GetHeight(GetUpper()->getFramePrintArea()) - | |||
1779 | aRectFnSet.GetTop(getFramePrintArea()); | |||
1780 | bool bSplit = !IsFwdMoveAllowed(); | |||
1781 | if ( nTmp > 0 && WouldFit( nTmp, bSplit, false ) ) | |||
1782 | { | |||
1783 | Prepare( PrepareHint::WidowsOrphans, nullptr, false ); | |||
1784 | setFrameAreaSizeValid(false); | |||
1785 | bFitPromise = true; | |||
1786 | continue; | |||
1787 | } | |||
1788 | /* | |||
1789 | * In earlier days, we never tried to fit TextFrames in | |||
1790 | * frames and sections using bMoveOrFit by ignoring | |||
1791 | * its attributes (Widows, Keep). | |||
1792 | * This should have been done at least for column frames; | |||
1793 | * as it must be tried anyway with linked frames and sections. | |||
1794 | * Exception: If we sit in FormatWidthCols, we must not ignore | |||
1795 | * the attributes. | |||
1796 | */ | |||
1797 | else if ( !bFootnote && | |||
1798 | ( !bFly || !FindFlyFrame()->IsColLocked() ) && | |||
1799 | ( !bSct || !FindSctFrame()->IsColLocked() ) ) | |||
1800 | bMoveOrFit = true; | |||
1801 | } | |||
1802 | #if OSL_DEBUG_LEVEL1 > 0 | |||
1803 | else | |||
1804 | { | |||
1805 | OSL_FAIL( "+TextFrame didn't respect WouldFit promise." )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/calcmove.cxx" ":" "1805" ": "), "%s", "+TextFrame didn't respect WouldFit promise." ); } } while (false); | |||
1806 | } | |||
1807 | #endif | |||
1808 | } | |||
1809 | ||||
1810 | // Let's see if I can find some space somewhere... | |||
1811 | // footnotes in the neighbourhood are moved into _MoveFootnoteCntFwd | |||
1812 | SwFrame *pPre = GetIndPrev(); | |||
1813 | SwFrame *pOldUp = GetUpper(); | |||
1814 | ||||
1815 | /* MA 13. Oct. 98: What is this supposed to be!? | |||
1816 | * AMA 14. Dec 98: If a column section can't find any space for its first ContentFrame, it should be | |||
1817 | * moved not only to the next column, but probably even to the next page, creating | |||
1818 | * a section-follow there. | |||
1819 | */ | |||
1820 | if( IsInSct() && bMovedFwd && bMakePage && pOldUp->IsColBodyFrame() && | |||
1821 | pOldUp->GetUpper()->GetUpper()->IsSctFrame() && | |||
1822 | ( pPre || pOldUp->GetUpper()->GetPrev() ) && | |||
1823 | static_cast<SwSectionFrame*>(pOldUp->GetUpper()->GetUpper())->MoveAllowed(this) ) | |||
1824 | { | |||
1825 | bMovedFwd = false; | |||
1826 | } | |||
1827 | ||||
1828 | const bool bCheckForGrownBody = pOldUp->IsBodyFrame(); | |||
1829 | const long nOldBodyHeight = aRectFnSet.GetHeight(pOldUp->getFrameArea()); | |||
1830 | ||||
1831 | if ( !bMovedFwd && !MoveFwd( bMakePage, false ) ) | |||
1832 | bMakePage = false; | |||
1833 | aRectFnSet.Refresh(this); | |||
1834 | if (!bMovedFwd && bFootnote && GetIndPrev() != pPre) | |||
1835 | { // SwFlowFrame::CutTree() could have formatted and deleted pPre | |||
1836 | auto const pPrevFootnoteFrame(static_cast<SwFootnoteFrame const*>( | |||
1837 | FindFootnoteFrame())->GetMaster()); | |||
1838 | bool bReset = true; | |||
1839 | if (pPrevFootnoteFrame) | |||
1840 | { // use GetIndNext() in case there are sections | |||
1841 | for (auto p = pPrevFootnoteFrame->Lower(); p; p = p->GetIndNext()) | |||
1842 | { | |||
1843 | if (p == pPre) | |||
1844 | { | |||
1845 | bReset = false; | |||
1846 | break; | |||
1847 | } | |||
1848 | } | |||
1849 | } | |||
1850 | if (bReset) | |||
1851 | { | |||
1852 | pPre = nullptr; | |||
1853 | } | |||
1854 | } | |||
1855 | ||||
1856 | // If MoveFwd moves the paragraph to the next page, a following | |||
1857 | // paragraph, which contains footnotes can cause the old upper | |||
1858 | // frame to grow. In this case we explicitly allow a new check | |||
1859 | // for MoveBwd. Robust: We also check the bMovedBwd flag again. | |||
1860 | // If pOldUp was a footnote frame, it has been deleted inside MoveFwd. | |||
1861 | // Therefore we only check for growing body frames. | |||
1862 | bMovedFwd = !bCheckForGrownBody || bMovedBwd || pOldUp == GetUpper() || | |||
1863 | aRectFnSet.GetHeight(pOldUp->getFrameArea()) <= nOldBodyHeight; | |||
1864 | ||||
1865 | bFormatted = false; | |||
1866 | if ( bMoveOrFit && GetUpper() == pOldUp ) | |||
1867 | { | |||
1868 | // FME 2007-08-30 #i81146# new loop control | |||
1869 | if ( nConsecutiveFormatsWithoutChange <= cnStopFormat ) | |||
1870 | { | |||
1871 | Prepare( PrepareHint::MustFit, nullptr, false ); | |||
1872 | setFrameAreaSizeValid(false); | |||
1873 | bMustFit = true; | |||
1874 | continue; | |||
1875 | } | |||
1876 | ||||
1877 | #if OSL_DEBUG_LEVEL1 > 0 | |||
1878 | OSL_FAIL( "LoopControl in SwContentFrame::MakeAll" )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/calcmove.cxx" ":" "1878" ": "), "%s", "LoopControl in SwContentFrame::MakeAll" ); } } while (false); | |||
1879 | #endif | |||
1880 | } | |||
1881 | if ( bMovedBwd && GetUpper() ) | |||
1882 | { // Retire invalidations that have become useless. | |||
1883 | GetUpper()->ResetCompletePaint(); | |||
1884 | if( pPre && !pPre->IsSctFrame() ) | |||
1885 | ::ValidateSz( pPre ); | |||
1886 | } | |||
1887 | ||||
1888 | } //while ( !isFrameAreaPositionValid() || !isFrameAreaSizeValid() || !isFramePrintAreaValid() ) | |||
1889 | ||||
1890 | // NEW: Looping Louie (Light). Should not be applied in balanced sections. | |||
1891 | // Should only be applied if there is no better solution! | |||
1892 | LOOPING_LOUIE_LIGHT( bMovedFwd && bMovedBwd && !IsInBalancedSection() && | |||
1893 | ( | |||
1894 | ||||
1895 | ( bFootnote && !FindFootnoteFrame()->GetRef()->IsInSct() ) || | |||
1896 | ||||
1897 | // #i33887# | |||
1898 | ( IsInSct() && bKeep ) | |||
1899 | ||||
1900 | // ... add your conditions here ... | |||
1901 | ||||
1902 | ), | |||
1903 | static_cast<SwTextFrame&>(*this) ); | |||
1904 | ||||
1905 | pSaveFootnote.reset(); | |||
1906 | ||||
1907 | UnlockJoin(); | |||
1908 | xDeleteGuard.reset(); | |||
1909 | if ( bMovedFwd || bMovedBwd ) | |||
1910 | pNotify->SetInvaKeep(); | |||
1911 | if ( bMovedFwd ) | |||
1912 | { | |||
1913 | pNotify->SetInvalidatePrevPrtArea(); | |||
1914 | } | |||
1915 | pNotify.reset(); | |||
1916 | SetFlyLock( false ); | |||
1917 | } | |||
1918 | ||||
1919 | void MakeNxt( SwFrame *pFrame, SwFrame *pNxt ) | |||
1920 | { | |||
1921 | // fix(25455): Validate, otherwise this leads to a recursion. | |||
1922 | // The first try, cancelling with pFrame = 0 if !Valid, leads to a problem, as | |||
1923 | // the Keep may not be considered properly anymore (27417). | |||
1924 | const bool bOldPos = pFrame->isFrameAreaPositionValid(); | |||
1925 | const bool bOldSz = pFrame->isFrameAreaSizeValid(); | |||
1926 | const bool bOldPrt = pFrame->isFramePrintAreaValid(); | |||
1927 | pFrame->setFrameAreaPositionValid(true); | |||
1928 | pFrame->setFrameAreaSizeValid(true); | |||
1929 | pFrame->setFramePrintAreaValid(true); | |||
1930 | ||||
1931 | // fix(29272): Don't call MakeAll - there, pFrame might be invalidated again, and | |||
1932 | // we recursively end up in here again. | |||
1933 | if ( pNxt->IsContentFrame() ) | |||
1934 | { | |||
1935 | SwContentNotify aNotify( static_cast<SwContentFrame*>(pNxt) ); | |||
1936 | SwBorderAttrAccess aAccess( SwFrame::GetCache(), pNxt ); | |||
1937 | const SwBorderAttrs &rAttrs = *aAccess.Get(); | |||
1938 | if ( !pNxt->isFrameAreaSizeValid() ) | |||
1939 | { | |||
1940 | SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*pNxt); | |||
1941 | ||||
1942 | if( pNxt->IsVertical() ) | |||
1943 | { | |||
1944 | aFrm.Height( pNxt->GetUpper()->getFramePrintArea().Height() ); | |||
1945 | } | |||
1946 | else | |||
1947 | { | |||
1948 | aFrm.Width( pNxt->GetUpper()->getFramePrintArea().Width() ); | |||
1949 | } | |||
1950 | } | |||
1951 | static_cast<SwContentFrame*>(pNxt)->MakePrtArea( rAttrs ); | |||
1952 | pNxt->Format( pNxt->getRootFrame()->GetCurrShell()->GetOut(), &rAttrs ); | |||
1953 | } | |||
1954 | else | |||
1955 | { | |||
1956 | SwLayNotify aNotify( static_cast<SwLayoutFrame*>(pNxt) ); | |||
1957 | SwBorderAttrAccess aAccess( SwFrame::GetCache(), pNxt ); | |||
1958 | const SwBorderAttrs &rAttrs = *aAccess.Get(); | |||
1959 | if ( !pNxt->isFrameAreaSizeValid() ) | |||
1960 | { | |||
1961 | SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*pNxt); | |||
1962 | ||||
1963 | if( pNxt->IsVertical() ) | |||
1964 | { | |||
1965 | aFrm.Height( pNxt->GetUpper()->getFramePrintArea().Height() ); | |||
1966 | } | |||
1967 | else | |||
1968 | { | |||
1969 | aFrm.Width( pNxt->GetUpper()->getFramePrintArea().Width() ); | |||
1970 | } | |||
1971 | } | |||
1972 | pNxt->Format( pNxt->getRootFrame()->GetCurrShell()->GetOut(), &rAttrs ); | |||
1973 | } | |||
1974 | ||||
1975 | pFrame->setFrameAreaPositionValid(bOldPos); | |||
1976 | pFrame->setFrameAreaSizeValid(bOldSz); | |||
1977 | pFrame->setFramePrintAreaValid(bOldPrt); | |||
1978 | } | |||
1979 | ||||
1980 | /// This routine checks whether there are no other FootnoteBosses | |||
1981 | /// between the pFrame's FootnoteBoss and the pNxt's FootnoteBoss. | |||
1982 | static bool lcl_IsNextFootnoteBoss( const SwFrame *pFrame, const SwFrame* pNxt ) | |||
1983 | { | |||
1984 | assert(pFrame && pNxt && "lcl_IsNextFootnoteBoss: No Frames?")(static_cast <bool> (pFrame && pNxt && "lcl_IsNextFootnoteBoss: No Frames?" ) ? void (0) : __assert_fail ("pFrame && pNxt && \"lcl_IsNextFootnoteBoss: No Frames?\"" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/calcmove.cxx" , 1984, __extension__ __PRETTY_FUNCTION__)); | |||
1985 | pFrame = pFrame->FindFootnoteBossFrame(); | |||
1986 | pNxt = pNxt->FindFootnoteBossFrame(); | |||
1987 | // If pFrame is a last column, we use the page instead. | |||
1988 | while( pFrame && pFrame->IsColumnFrame() && !pFrame->GetNext() ) | |||
1989 | pFrame = pFrame->GetUpper()->FindFootnoteBossFrame(); | |||
1990 | // If pNxt is a first column, we use the page instead. | |||
1991 | while( pNxt && pNxt->IsColumnFrame() && !pNxt->GetPrev() ) | |||
1992 | pNxt = pNxt->GetUpper()->FindFootnoteBossFrame(); | |||
1993 | // So... now pFrame and pNxt are either two adjacent pages or columns. | |||
1994 | return pFrame && pNxt && pFrame->GetNext() == pNxt; | |||
1995 | } | |||
1996 | ||||
1997 | bool SwContentFrame::WouldFit_( SwTwips nSpace, | |||
1998 | SwLayoutFrame *pNewUpper, | |||
1999 | bool bTstMove, | |||
2000 | const bool bObjsInNewUpper ) | |||
2001 | { | |||
2002 | // To have the footnote select its place carefully, it needs | |||
2003 | // to be moved in any case if there is at least one page/column | |||
2004 | // between the footnote and the new Upper. | |||
2005 | SwFootnoteFrame* pFootnoteFrame = nullptr; | |||
2006 | if ( IsInFootnote() ) | |||
2007 | { | |||
2008 | if( !lcl_IsNextFootnoteBoss( pNewUpper, this ) ) | |||
2009 | return true; | |||
2010 | pFootnoteFrame = FindFootnoteFrame(); | |||
2011 | } | |||
2012 | ||||
2013 | bool bRet; | |||
2014 | bool bSplit = !pNewUpper->Lower(); | |||
2015 | SwContentFrame *pFrame = this; | |||
2016 | const SwFrame *pTmpPrev = pNewUpper->Lower(); | |||
2017 | if( pTmpPrev && pTmpPrev->IsFootnoteFrame() ) | |||
2018 | pTmpPrev = static_cast<const SwFootnoteFrame*>(pTmpPrev)->Lower(); | |||
2019 | while ( pTmpPrev && pTmpPrev->GetNext() ) | |||
2020 | pTmpPrev = pTmpPrev->GetNext(); | |||
2021 | do | |||
2022 | { | |||
2023 | // #i46181# | |||
2024 | SwTwips nSecondCheck = 0; | |||
2025 | SwTwips nOldSpace = nSpace; | |||
2026 | bool bOldSplit = bSplit; | |||
2027 | ||||
2028 | if ( bTstMove || IsInFly() || ( IsInSct() && | |||
2029 | ( pFrame->GetUpper()->IsColBodyFrame() || ( pFootnoteFrame && | |||
2030 | pFootnoteFrame->GetUpper()->GetUpper()->IsColumnFrame() ) ) ) ) | |||
2031 | { | |||
2032 | // This is going to get a bit insidious now. If you're faint of heart, | |||
2033 | // you'd better look away here. If a Fly contains columns, then the Contents | |||
2034 | // are movable, except ones in the last column (see SwFrame::IsMoveable()). | |||
2035 | // Of course they're allowed to float back. WouldFit() only returns a usable | |||
2036 | // value if the Frame is movable. To fool WouldFit() into believing there's | |||
2037 | // a movable Frame, I'm just going to hang it somewhere else for the time. | |||
2038 | // The same procedure applies for column sections to make SwSectionFrame::Growable() | |||
2039 | // return the proper value. | |||
2040 | // Within footnotes, we may even need to put the SwFootnoteFrame somewhere else, if | |||
2041 | // there's no SwFootnoteFrame there. | |||
2042 | SwFrame* pTmpFrame = pFrame->IsInFootnote() && !pNewUpper->FindFootnoteFrame() ? | |||
2043 | static_cast<SwFrame*>(pFrame->FindFootnoteFrame()) : pFrame; | |||
2044 | SwLayoutFrame *pUp = pTmpFrame->GetUpper(); | |||
2045 | SwFrame *pOldNext = pTmpFrame->GetNext(); | |||
2046 | pTmpFrame->RemoveFromLayout(); | |||
2047 | pTmpFrame->InsertBefore( pNewUpper, nullptr ); | |||
2048 | // tdf#107126 for a section in a footnote, we have only inserted | |||
2049 | // the SwTextFrame but no SwSectionFrame - reset mbInfSct flag | |||
2050 | // to avoid crashing (but perhaps we should create a temp | |||
2051 | // SwSectionFrame here because WidowsAndOrphans checks for that?) | |||
2052 | pTmpFrame->InvalidateInfFlags(); | |||
2053 | if ( pFrame->IsTextFrame() && | |||
2054 | ( bTstMove || | |||
2055 | static_cast<SwTextFrame*>(pFrame)->HasFollow() || | |||
2056 | ( !static_cast<SwTextFrame*>(pFrame)->HasPara() && | |||
2057 | !static_cast<SwTextFrame*>(pFrame)->IsEmpty() | |||
2058 | ) | |||
2059 | ) | |||
2060 | ) | |||
2061 | { | |||
2062 | bTstMove = true; | |||
2063 | bRet = static_cast<SwTextFrame*>(pFrame)->TestFormat( pTmpPrev, nSpace, bSplit ); | |||
2064 | } | |||
2065 | else | |||
2066 | bRet = pFrame->WouldFit( nSpace, bSplit, false ); | |||
2067 | ||||
2068 | pTmpFrame->RemoveFromLayout(); | |||
2069 | pTmpFrame->InsertBefore( pUp, pOldNext ); | |||
2070 | pTmpFrame->InvalidateInfFlags(); // restore flags | |||
2071 | } | |||
2072 | else | |||
2073 | { | |||
2074 | bRet = pFrame->WouldFit( nSpace, bSplit, false ); | |||
2075 | nSecondCheck = !bSplit ? 1 : 0; | |||
2076 | } | |||
2077 | ||||
2078 | SwBorderAttrAccess aAccess( SwFrame::GetCache(), pFrame ); | |||
2079 | const SwBorderAttrs &rAttrs = *aAccess.Get(); | |||
2080 | ||||
2081 | // Sad but true: We need to consider the spacing in our calculation. | |||
2082 | // This already happened in TestFormat. | |||
2083 | if ( bRet && !bTstMove ) | |||
2084 | { | |||
2085 | SwTwips nUpper; | |||
2086 | ||||
2087 | if ( pTmpPrev ) | |||
2088 | { | |||
2089 | nUpper = CalcUpperSpace( nullptr, pTmpPrev ); | |||
2090 | ||||
2091 | // in balanced columned section frames we do not want the | |||
2092 | // common border | |||
2093 | bool bCommonBorder = true; | |||
2094 | if ( pFrame->IsInSct() && pFrame->GetUpper()->IsColBodyFrame() ) | |||
2095 | { | |||
2096 | const SwSectionFrame* pSct = pFrame->FindSctFrame(); | |||
2097 | bCommonBorder = pSct->GetFormat()->GetBalancedColumns().GetValue(); | |||
2098 | } | |||
2099 | ||||
2100 | // #i46181# | |||
2101 | nSecondCheck = ( 1 == nSecondCheck && | |||
2102 | pFrame == this && | |||
2103 | IsTextFrame() && | |||
2104 | bCommonBorder && | |||
2105 | !static_cast<const SwTextFrame*>(this)->IsEmpty() ) ? | |||
2106 | nUpper : | |||
2107 | 0; | |||
2108 | ||||
2109 | nUpper += bCommonBorder ? | |||
2110 | rAttrs.GetBottomLine( *pFrame ) : | |||
2111 | rAttrs.CalcBottomLine(); | |||
2112 | ||||
2113 | } | |||
2114 | else | |||
2115 | { | |||
2116 | // #i46181# | |||
2117 | nSecondCheck = 0; | |||
2118 | ||||
2119 | if( pFrame->IsVertical() ) | |||
2120 | nUpper = pFrame->getFrameArea().Width() - pFrame->getFramePrintArea().Width(); | |||
2121 | else | |||
2122 | nUpper = pFrame->getFrameArea().Height() - pFrame->getFramePrintArea().Height(); | |||
2123 | } | |||
2124 | ||||
2125 | nSpace -= nUpper; | |||
2126 | ||||
2127 | if ( nSpace < 0 ) | |||
2128 | { | |||
2129 | bRet = false; | |||
2130 | ||||
2131 | // #i46181# | |||
2132 | if ( nSecondCheck > 0 ) | |||
2133 | { | |||
2134 | // The following code is intended to solve a (rare) problem | |||
2135 | // causing some frames not to move backward: | |||
2136 | // SwTextFrame::WouldFit() claims that the whole paragraph | |||
2137 | // fits into the given space and subtracts the height of | |||
2138 | // all lines from nSpace. nSpace - nUpper is not a valid | |||
2139 | // indicator if the frame should be allowed to move backward. | |||
2140 | // We do a second check with the original remaining space | |||
2141 | // reduced by the required upper space: | |||
2142 | nOldSpace -= nSecondCheck; | |||
2143 | const bool bSecondRet = nOldSpace >= 0 && pFrame->WouldFit( nOldSpace, bOldSplit, false ); | |||
2144 | if ( bSecondRet && bOldSplit && nOldSpace >= 0 ) | |||
2145 | { | |||
2146 | bRet = true; | |||
2147 | bSplit = true; | |||
2148 | } | |||
2149 | } | |||
2150 | } | |||
2151 | } | |||
2152 | ||||
2153 | // Also consider lower spacing in table cells | |||
2154 | IDocumentSettingAccess const& rIDSA(pNewUpper->GetFormat()->getIDocumentSettingAccess()); | |||
2155 | if ( bRet && IsInTab() && | |||
2156 | rIDSA.get(DocumentSettingId::ADD_PARA_SPACING_TO_TABLE_CELLS)) | |||
2157 | { | |||
2158 | nSpace -= rAttrs.GetULSpace().GetLower(); | |||
2159 | ||||
2160 | if (rIDSA.get(DocumentSettingId::ADD_PARA_LINE_SPACING_TO_TABLE_CELLS)) | |||
2161 | { | |||
2162 | nSpace -= rAttrs.CalcLineSpacing(); | |||
2163 | } | |||
2164 | if ( nSpace < 0 ) | |||
2165 | { | |||
2166 | bRet = false; | |||
2167 | } | |||
2168 | } | |||
2169 | ||||
2170 | if (bRet && !bSplit && pFrame->IsKeep(rAttrs.GetAttrSet().GetKeep(), GetBreakItem())) | |||
2171 | { | |||
2172 | if( bTstMove ) | |||
2173 | { | |||
2174 | while( pFrame->IsTextFrame() && static_cast<SwTextFrame*>(pFrame)->HasFollow() ) | |||
2175 | { | |||
2176 | pFrame = static_cast<SwTextFrame*>(pFrame)->GetFollow(); | |||
2177 | } | |||
2178 | // If last follow frame of <this> text frame isn't valid, | |||
2179 | // a formatting of the next content frame doesn't makes sense. | |||
2180 | // Thus, return true. | |||
2181 | if ( IsAnFollow( pFrame ) && !pFrame->isFrameAreaDefinitionValid() ) | |||
2182 | { | |||
2183 | OSL_FAIL( "Only a warning for task 108824:/n<SwContentFrame::WouldFit_(..) - follow not valid!" )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/calcmove.cxx" ":" "2183" ": "), "%s", "Only a warning for task 108824:/n<SwContentFrame::WouldFit_(..) - follow not valid!" ); } } while (false); | |||
2184 | return true; | |||
2185 | } | |||
2186 | } | |||
2187 | SwFrame *pNxt; | |||
2188 | if( nullptr != (pNxt = pFrame->FindNext()) && pNxt->IsContentFrame() && | |||
2189 | ( !pFootnoteFrame || ( pNxt->IsInFootnote() && | |||
2190 | pNxt->FindFootnoteFrame()->GetAttr() == pFootnoteFrame->GetAttr() ) ) ) | |||
2191 | { | |||
2192 | // TestFormat(?) does not like paragraph- or character anchored objects. | |||
2193 | ||||
2194 | // current solution for the test formatting doesn't work, if | |||
2195 | // objects are present in the remaining area of the new upper | |||
2196 | if ( bTstMove && | |||
2197 | ( pNxt->GetDrawObjs() || bObjsInNewUpper ) ) | |||
2198 | { | |||
2199 | return true; | |||
2200 | } | |||
2201 | ||||
2202 | if ( !pNxt->isFrameAreaDefinitionValid() ) | |||
2203 | { | |||
2204 | MakeNxt( pFrame, pNxt ); | |||
2205 | } | |||
2206 | ||||
2207 | // Little trick: if the next has a predecessor, then the paragraph | |||
2208 | // spacing has been calculated already, and we don't need to re-calculate | |||
2209 | // it in an expensive way. | |||
2210 | if( lcl_NotHiddenPrev( pNxt ) ) | |||
2211 | pTmpPrev = nullptr; | |||
2212 | else | |||
2213 | { | |||
2214 | if( pFrame->IsTextFrame() && static_cast<SwTextFrame*>(pFrame)->IsHiddenNow() ) | |||
2215 | pTmpPrev = lcl_NotHiddenPrev( pFrame ); | |||
2216 | else | |||
2217 | pTmpPrev = pFrame; | |||
2218 | } | |||
2219 | pFrame = static_cast<SwContentFrame*>(pNxt); | |||
2220 | } | |||
2221 | else | |||
2222 | pFrame = nullptr; | |||
2223 | } | |||
2224 | else | |||
2225 | pFrame = nullptr; | |||
2226 | ||||
2227 | } while ( bRet && pFrame ); | |||
2228 | ||||
2229 | return bRet; | |||
2230 | } | |||
2231 | ||||
2232 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |