File: | home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx |
Warning: | line 3854, column 31 Division by zero |
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 <hints.hxx> | ||||||||||||
21 | #include <o3tl/safeint.hxx> | ||||||||||||
22 | #include <svl/itemiter.hxx> | ||||||||||||
23 | #include <editeng/brushitem.hxx> | ||||||||||||
24 | #include <fmtornt.hxx> | ||||||||||||
25 | #include <pagefrm.hxx> | ||||||||||||
26 | #include <section.hxx> | ||||||||||||
27 | #include <rootfrm.hxx> | ||||||||||||
28 | #include <anchoreddrawobject.hxx> | ||||||||||||
29 | #include <fmtanchr.hxx> | ||||||||||||
30 | #include <viewimp.hxx> | ||||||||||||
31 | #include <viewopt.hxx> | ||||||||||||
32 | #include <IDocumentSettingAccess.hxx> | ||||||||||||
33 | #include <IDocumentFieldsAccess.hxx> | ||||||||||||
34 | #include <IDocumentRedlineAccess.hxx> | ||||||||||||
35 | #include <redline.hxx> | ||||||||||||
36 | #include <docsh.hxx> | ||||||||||||
37 | #include <ftninfo.hxx> | ||||||||||||
38 | #include <ftnidx.hxx> | ||||||||||||
39 | #include <fmtclbl.hxx> | ||||||||||||
40 | #include <fmtfsize.hxx> | ||||||||||||
41 | #include <fmtpdsc.hxx> | ||||||||||||
42 | #include <txtftn.hxx> | ||||||||||||
43 | #include <fmtftn.hxx> | ||||||||||||
44 | #include <fmtsrnd.hxx> | ||||||||||||
45 | #include <fmtcntnt.hxx> | ||||||||||||
46 | #include <ftnfrm.hxx> | ||||||||||||
47 | #include <tabfrm.hxx> | ||||||||||||
48 | #include <flyfrm.hxx> | ||||||||||||
49 | #include <sectfrm.hxx> | ||||||||||||
50 | #include <fmtclds.hxx> | ||||||||||||
51 | #include <txtfrm.hxx> | ||||||||||||
52 | #include <bodyfrm.hxx> | ||||||||||||
53 | #include <cellfrm.hxx> | ||||||||||||
54 | #include <dbg_lay.hxx> | ||||||||||||
55 | #include <editeng/frmdiritem.hxx> | ||||||||||||
56 | #include <sortedobjs.hxx> | ||||||||||||
57 | #include <frmatr.hxx> | ||||||||||||
58 | #include <frmtool.hxx> | ||||||||||||
59 | #include <ndtxt.hxx> | ||||||||||||
60 | #include <swtable.hxx> | ||||||||||||
61 | |||||||||||||
62 | // RotateFlyFrame3 | ||||||||||||
63 | #include <basegfx/matrix/b2dhommatrixtools.hxx> | ||||||||||||
64 | |||||||||||||
65 | using namespace ::com::sun::star; | ||||||||||||
66 | |||||||||||||
67 | SwFrameAreaDefinition::SwFrameAreaDefinition() | ||||||||||||
68 | : maFrameArea(), | ||||||||||||
69 | maFramePrintArea(), | ||||||||||||
70 | mbFrameAreaPositionValid(false), | ||||||||||||
71 | mbFrameAreaSizeValid(false), | ||||||||||||
72 | mbFramePrintAreaValid(false), | ||||||||||||
73 | mnFrameId(SwFrameAreaDefinition::mnLastFrameId++) | ||||||||||||
74 | { | ||||||||||||
75 | } | ||||||||||||
76 | |||||||||||||
77 | SwFrameAreaDefinition::~SwFrameAreaDefinition() | ||||||||||||
78 | { | ||||||||||||
79 | } | ||||||||||||
80 | |||||||||||||
81 | void SwFrameAreaDefinition::setFrameAreaPositionValid(bool bNew) | ||||||||||||
82 | { | ||||||||||||
83 | if(mbFrameAreaPositionValid != bNew) | ||||||||||||
84 | { | ||||||||||||
85 | mbFrameAreaPositionValid = bNew; | ||||||||||||
86 | } | ||||||||||||
87 | } | ||||||||||||
88 | |||||||||||||
89 | void SwFrameAreaDefinition::setFrameAreaSizeValid(bool bNew) | ||||||||||||
90 | { | ||||||||||||
91 | if(mbFrameAreaSizeValid != bNew) | ||||||||||||
92 | { | ||||||||||||
93 | mbFrameAreaSizeValid = bNew; | ||||||||||||
94 | } | ||||||||||||
95 | } | ||||||||||||
96 | |||||||||||||
97 | void SwFrameAreaDefinition::setFramePrintAreaValid(bool bNew) | ||||||||||||
98 | { | ||||||||||||
99 | if(mbFramePrintAreaValid != bNew) | ||||||||||||
100 | { | ||||||||||||
101 | mbFramePrintAreaValid = bNew; | ||||||||||||
102 | } | ||||||||||||
103 | } | ||||||||||||
104 | |||||||||||||
105 | SwFrameAreaDefinition::FrameAreaWriteAccess::~FrameAreaWriteAccess() | ||||||||||||
106 | { | ||||||||||||
107 | if(mrTarget.maFrameArea != *this) | ||||||||||||
108 | { | ||||||||||||
109 | mrTarget.maFrameArea = *this; | ||||||||||||
110 | } | ||||||||||||
111 | } | ||||||||||||
112 | |||||||||||||
113 | SwFrameAreaDefinition::FramePrintAreaWriteAccess::~FramePrintAreaWriteAccess() | ||||||||||||
114 | { | ||||||||||||
115 | if(mrTarget.maFramePrintArea != *this) | ||||||||||||
116 | { | ||||||||||||
117 | mrTarget.maFramePrintArea = *this; | ||||||||||||
118 | } | ||||||||||||
119 | } | ||||||||||||
120 | |||||||||||||
121 | // RotateFlyFrame3 - Support for Transformations | ||||||||||||
122 | basegfx::B2DHomMatrix SwFrameAreaDefinition::getFrameAreaTransformation() const | ||||||||||||
123 | { | ||||||||||||
124 | // default implementation hands out FrameArea (outer frame) | ||||||||||||
125 | const SwRect& rFrameArea(getFrameArea()); | ||||||||||||
126 | |||||||||||||
127 | return basegfx::utils::createScaleTranslateB2DHomMatrix( | ||||||||||||
128 | rFrameArea.Width(), rFrameArea.Height(), | ||||||||||||
129 | rFrameArea.Left(), rFrameArea.Top()); | ||||||||||||
130 | } | ||||||||||||
131 | |||||||||||||
132 | basegfx::B2DHomMatrix SwFrameAreaDefinition::getFramePrintAreaTransformation() const | ||||||||||||
133 | { | ||||||||||||
134 | // default implementation hands out FramePrintArea (outer frame) | ||||||||||||
135 | // Take into account that FramePrintArea is relative to FrameArea | ||||||||||||
136 | const SwRect& rFrameArea(getFrameArea()); | ||||||||||||
137 | const SwRect& rFramePrintArea(getFramePrintArea()); | ||||||||||||
138 | |||||||||||||
139 | return basegfx::utils::createScaleTranslateB2DHomMatrix( | ||||||||||||
140 | rFramePrintArea.Width(), rFramePrintArea.Height(), | ||||||||||||
141 | rFramePrintArea.Left() + rFrameArea.Left(), | ||||||||||||
142 | rFramePrintArea.Top() + rFrameArea.Top()); | ||||||||||||
143 | } | ||||||||||||
144 | |||||||||||||
145 | void SwFrameAreaDefinition::transform_translate(const Point& rOffset) | ||||||||||||
146 | { | ||||||||||||
147 | // RotateFlyFrame3: default is to change the FrameArea, FramePrintArea needs no | ||||||||||||
148 | // change since it is relative to FrameArea | ||||||||||||
149 | SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this); | ||||||||||||
150 | |||||||||||||
151 | if (aFrm.Pos().X() != FAR_AWAY(((sal_Int32) 0x7FFFFFFF) - 20000)) | ||||||||||||
152 | { | ||||||||||||
153 | aFrm.Pos().AdjustX(rOffset.X() ); | ||||||||||||
154 | } | ||||||||||||
155 | |||||||||||||
156 | if (aFrm.Pos().Y() != FAR_AWAY(((sal_Int32) 0x7FFFFFFF) - 20000)) | ||||||||||||
157 | { | ||||||||||||
158 | aFrm.Pos().AdjustY(rOffset.Y() ); | ||||||||||||
159 | } | ||||||||||||
160 | } | ||||||||||||
161 | |||||||||||||
162 | SwRect TransformableSwFrame::getUntransformedFrameArea() const | ||||||||||||
163 | { | ||||||||||||
164 | const basegfx::B2DHomMatrix& rSource(getLocalFrameAreaTransformation()); | ||||||||||||
165 | |||||||||||||
166 | if(rSource.isIdentity()) | ||||||||||||
167 | { | ||||||||||||
168 | return mrSwFrameAreaDefinition.getFrameArea(); | ||||||||||||
169 | } | ||||||||||||
170 | else | ||||||||||||
171 | { | ||||||||||||
172 | basegfx::B2DVector aScale, aTranslate; | ||||||||||||
173 | double fRotate, fShearX; | ||||||||||||
174 | rSource.decompose(aScale, aTranslate, fRotate, fShearX); | ||||||||||||
175 | const basegfx::B2DPoint aCenter(rSource * basegfx::B2DPoint(0.5, 0.5)); | ||||||||||||
176 | const basegfx::B2DVector aAbsScale(basegfx::absolute(aScale)); | ||||||||||||
177 | |||||||||||||
178 | return SwRect( | ||||||||||||
179 | basegfx::fround(aCenter.getX() - (0.5 * aAbsScale.getX())), | ||||||||||||
180 | basegfx::fround(aCenter.getY() - (0.5 * aAbsScale.getY())), | ||||||||||||
181 | basegfx::fround(aAbsScale.getX()), | ||||||||||||
182 | basegfx::fround(aAbsScale.getY())); | ||||||||||||
183 | } | ||||||||||||
184 | } | ||||||||||||
185 | |||||||||||||
186 | SwRect TransformableSwFrame::getUntransformedFramePrintArea() const | ||||||||||||
187 | { | ||||||||||||
188 | const basegfx::B2DHomMatrix& rSource(getLocalFramePrintAreaTransformation()); | ||||||||||||
189 | |||||||||||||
190 | if(rSource.isIdentity()) | ||||||||||||
191 | { | ||||||||||||
192 | return mrSwFrameAreaDefinition.getFramePrintArea(); | ||||||||||||
193 | } | ||||||||||||
194 | else | ||||||||||||
195 | { | ||||||||||||
196 | basegfx::B2DVector aScale, aTranslate; | ||||||||||||
197 | double fRotate, fShearX; | ||||||||||||
198 | rSource.decompose(aScale, aTranslate, fRotate, fShearX); | ||||||||||||
199 | const basegfx::B2DPoint aCenter(rSource * basegfx::B2DPoint(0.5, 0.5)); | ||||||||||||
200 | const basegfx::B2DVector aAbsScale(basegfx::absolute(aScale)); | ||||||||||||
201 | const SwRect aUntransformedFrameArea(getUntransformedFrameArea()); | ||||||||||||
202 | |||||||||||||
203 | return SwRect( | ||||||||||||
204 | basegfx::fround(aCenter.getX() - (0.5 * aAbsScale.getX())) - aUntransformedFrameArea.Left(), | ||||||||||||
205 | basegfx::fround(aCenter.getY() - (0.5 * aAbsScale.getY())) - aUntransformedFrameArea.Top(), | ||||||||||||
206 | basegfx::fround(aAbsScale.getX()), | ||||||||||||
207 | basegfx::fround(aAbsScale.getY())); | ||||||||||||
208 | } | ||||||||||||
209 | } | ||||||||||||
210 | |||||||||||||
211 | void TransformableSwFrame::createFrameAreaTransformations( | ||||||||||||
212 | double fRotation, | ||||||||||||
213 | const basegfx::B2DPoint& rCenter) | ||||||||||||
214 | { | ||||||||||||
215 | const basegfx::B2DHomMatrix aRotateAroundCenter( | ||||||||||||
216 | basegfx::utils::createRotateAroundPoint( | ||||||||||||
217 | rCenter.getX(), | ||||||||||||
218 | rCenter.getY(), | ||||||||||||
219 | fRotation)); | ||||||||||||
220 | const SwRect& rFrameArea(mrSwFrameAreaDefinition.getFrameArea()); | ||||||||||||
221 | const SwRect& rFramePrintArea(mrSwFrameAreaDefinition.getFramePrintArea()); | ||||||||||||
222 | |||||||||||||
223 | maFrameAreaTransformation = aRotateAroundCenter * basegfx::utils::createScaleTranslateB2DHomMatrix( | ||||||||||||
224 | rFrameArea.Width(), rFrameArea.Height(), | ||||||||||||
225 | rFrameArea.Left(), rFrameArea.Top()); | ||||||||||||
226 | maFramePrintAreaTransformation = aRotateAroundCenter * basegfx::utils::createScaleTranslateB2DHomMatrix( | ||||||||||||
227 | rFramePrintArea.Width(), rFramePrintArea.Height(), | ||||||||||||
228 | rFramePrintArea.Left() + rFrameArea.Left(), rFramePrintArea.Top() + rFrameArea.Top()); | ||||||||||||
229 | } | ||||||||||||
230 | |||||||||||||
231 | void TransformableSwFrame::adaptFrameAreasToTransformations() | ||||||||||||
232 | { | ||||||||||||
233 | if(!getLocalFrameAreaTransformation().isIdentity()) | ||||||||||||
234 | { | ||||||||||||
235 | basegfx::B2DRange aRangeFrameArea(0.0, 0.0, 1.0, 1.0); | ||||||||||||
236 | aRangeFrameArea.transform(getLocalFrameAreaTransformation()); | ||||||||||||
237 | const SwRect aNewFrm( | ||||||||||||
238 | basegfx::fround(aRangeFrameArea.getMinX()), basegfx::fround(aRangeFrameArea.getMinY()), | ||||||||||||
239 | basegfx::fround(aRangeFrameArea.getWidth()), basegfx::fround(aRangeFrameArea.getHeight())); | ||||||||||||
240 | |||||||||||||
241 | if(aNewFrm != mrSwFrameAreaDefinition.getFrameArea()) | ||||||||||||
242 | { | ||||||||||||
243 | SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(mrSwFrameAreaDefinition); | ||||||||||||
244 | aFrm.setSwRect(aNewFrm); | ||||||||||||
245 | } | ||||||||||||
246 | } | ||||||||||||
247 | |||||||||||||
248 | if(getLocalFramePrintAreaTransformation().isIdentity()) | ||||||||||||
249 | return; | ||||||||||||
250 | |||||||||||||
251 | basegfx::B2DRange aRangeFramePrintArea(0.0, 0.0, 1.0, 1.0); | ||||||||||||
252 | aRangeFramePrintArea.transform(getLocalFramePrintAreaTransformation()); | ||||||||||||
253 | const SwRect aNewPrt( | ||||||||||||
254 | basegfx::fround(aRangeFramePrintArea.getMinX()) - mrSwFrameAreaDefinition.getFrameArea().Left(), | ||||||||||||
255 | basegfx::fround(aRangeFramePrintArea.getMinY()) - mrSwFrameAreaDefinition.getFrameArea().Top(), | ||||||||||||
256 | basegfx::fround(aRangeFramePrintArea.getWidth()), | ||||||||||||
257 | basegfx::fround(aRangeFramePrintArea.getHeight())); | ||||||||||||
258 | |||||||||||||
259 | if(aNewPrt != mrSwFrameAreaDefinition.getFramePrintArea()) | ||||||||||||
260 | { | ||||||||||||
261 | SwFrameAreaDefinition::FramePrintAreaWriteAccess aPrt(mrSwFrameAreaDefinition); | ||||||||||||
262 | aPrt.setSwRect(aNewPrt); | ||||||||||||
263 | } | ||||||||||||
264 | } | ||||||||||||
265 | |||||||||||||
266 | void TransformableSwFrame::restoreFrameAreas() | ||||||||||||
267 | { | ||||||||||||
268 | // This can be done fully based on the Transformations currently | ||||||||||||
269 | // set, so use this. Only needed when transformation *is* used | ||||||||||||
270 | if(!getLocalFrameAreaTransformation().isIdentity()) | ||||||||||||
271 | { | ||||||||||||
272 | SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(mrSwFrameAreaDefinition); | ||||||||||||
273 | aFrm.setSwRect(getUntransformedFrameArea()); | ||||||||||||
274 | } | ||||||||||||
275 | |||||||||||||
276 | if(!getLocalFramePrintAreaTransformation().isIdentity()) | ||||||||||||
277 | { | ||||||||||||
278 | SwFrameAreaDefinition::FramePrintAreaWriteAccess aPrt(mrSwFrameAreaDefinition); | ||||||||||||
279 | aPrt.setSwRect(getUntransformedFramePrintArea()); | ||||||||||||
280 | } | ||||||||||||
281 | } | ||||||||||||
282 | |||||||||||||
283 | // transform by given B2DHomMatrix | ||||||||||||
284 | void TransformableSwFrame::transform(const basegfx::B2DHomMatrix& aTransform) | ||||||||||||
285 | { | ||||||||||||
286 | maFrameAreaTransformation *= aTransform; | ||||||||||||
287 | maFramePrintAreaTransformation *= aTransform; | ||||||||||||
288 | } | ||||||||||||
289 | |||||||||||||
290 | SwFrame::SwFrame( SwModify *pMod, SwFrame* pSib ) | ||||||||||||
291 | : SwFrameAreaDefinition(), | ||||||||||||
292 | SwClient( pMod ), | ||||||||||||
293 | SfxBroadcaster(), | ||||||||||||
294 | mpRoot( pSib ? pSib->getRootFrame() : nullptr ), | ||||||||||||
295 | mpUpper(nullptr), | ||||||||||||
296 | mpNext(nullptr), | ||||||||||||
297 | mpPrev(nullptr), | ||||||||||||
298 | mnFrameType(SwFrameType::None), | ||||||||||||
299 | mbInDtor(false), | ||||||||||||
300 | mbInvalidR2L(true), | ||||||||||||
301 | mbDerivedR2L(false), | ||||||||||||
302 | mbRightToLeft(false), | ||||||||||||
303 | mbInvalidVert(true), | ||||||||||||
304 | mbDerivedVert(false), | ||||||||||||
305 | mbVertical(false), | ||||||||||||
306 | mbVertLR(false), | ||||||||||||
307 | mbVertLRBT(false), | ||||||||||||
308 | mbValidLineNum(false), | ||||||||||||
309 | mbFixSize(false), | ||||||||||||
310 | mbCompletePaint(true), | ||||||||||||
311 | mbRetouche(false), | ||||||||||||
312 | mbInfInvalid(true), | ||||||||||||
313 | mbInfBody( false ), | ||||||||||||
314 | mbInfTab ( false ), | ||||||||||||
315 | mbInfFly ( false ), | ||||||||||||
316 | mbInfFootnote ( false ), | ||||||||||||
317 | mbInfSct ( false ), | ||||||||||||
318 | mbColLocked(false), | ||||||||||||
319 | m_isInDestroy(false), | ||||||||||||
320 | mbForbidDelete(false) | ||||||||||||
321 | { | ||||||||||||
322 | OSL_ENSURE( pMod, "No frame format given." )do { if (true && (!(pMod))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" ":" "322" ": "), "%s", "No frame format given."); } } while ( false); | ||||||||||||
323 | } | ||||||||||||
324 | |||||||||||||
325 | const IDocumentDrawModelAccess& SwFrame::getIDocumentDrawModelAccess() | ||||||||||||
326 | { | ||||||||||||
327 | return GetUpper()->GetFormat()->getIDocumentDrawModelAccess(); | ||||||||||||
328 | } | ||||||||||||
329 | |||||||||||||
330 | bool SwFrame::KnowsFormat( const SwFormat& rFormat ) const | ||||||||||||
331 | { | ||||||||||||
332 | return GetRegisteredIn() == &rFormat; | ||||||||||||
333 | } | ||||||||||||
334 | |||||||||||||
335 | void SwFrame::RegisterToFormat( SwFormat& rFormat ) | ||||||||||||
336 | { | ||||||||||||
337 | rFormat.Add( this ); | ||||||||||||
338 | } | ||||||||||||
339 | |||||||||||||
340 | void SwFrame::CheckDir( SvxFrameDirection nDir, bool bVert, bool bOnlyBiDi, bool bBrowse ) | ||||||||||||
341 | { | ||||||||||||
342 | if( SvxFrameDirection::Environment == nDir || ( bVert && bOnlyBiDi ) ) | ||||||||||||
343 | { | ||||||||||||
344 | mbDerivedVert = true; | ||||||||||||
345 | if( SvxFrameDirection::Environment == nDir ) | ||||||||||||
346 | mbDerivedR2L = true; | ||||||||||||
347 | SetDirFlags( bVert ); | ||||||||||||
348 | } | ||||||||||||
349 | else if( bVert ) | ||||||||||||
350 | { | ||||||||||||
351 | mbInvalidVert = false; | ||||||||||||
352 | if( SvxFrameDirection::Horizontal_LR_TB == nDir || SvxFrameDirection::Horizontal_RL_TB == nDir | ||||||||||||
353 | || bBrowse ) | ||||||||||||
354 | { | ||||||||||||
355 | mbVertical = false; | ||||||||||||
356 | mbVertLR = false; | ||||||||||||
357 | mbVertLRBT = false; | ||||||||||||
358 | } | ||||||||||||
359 | else | ||||||||||||
360 | { | ||||||||||||
361 | mbVertical = true; | ||||||||||||
362 | if(SvxFrameDirection::Vertical_RL_TB == nDir) | ||||||||||||
363 | { | ||||||||||||
364 | mbVertLR = false; | ||||||||||||
365 | mbVertLRBT = false; | ||||||||||||
366 | } | ||||||||||||
367 | else if(SvxFrameDirection::Vertical_LR_TB==nDir) | ||||||||||||
368 | { | ||||||||||||
369 | mbVertLR = true; | ||||||||||||
370 | mbVertLRBT = false; | ||||||||||||
371 | } | ||||||||||||
372 | else if (nDir == SvxFrameDirection::Vertical_LR_BT) | ||||||||||||
373 | { | ||||||||||||
374 | mbVertLR = true; | ||||||||||||
375 | mbVertLRBT = true; | ||||||||||||
376 | } | ||||||||||||
377 | } | ||||||||||||
378 | } | ||||||||||||
379 | else | ||||||||||||
380 | { | ||||||||||||
381 | mbInvalidR2L = false; | ||||||||||||
382 | if( SvxFrameDirection::Horizontal_RL_TB == nDir ) | ||||||||||||
383 | mbRightToLeft = true; | ||||||||||||
384 | else | ||||||||||||
385 | mbRightToLeft = false; | ||||||||||||
386 | } | ||||||||||||
387 | } | ||||||||||||
388 | |||||||||||||
389 | void SwFrame::CheckDirection( bool bVert ) | ||||||||||||
390 | { | ||||||||||||
391 | if( bVert ) | ||||||||||||
392 | { | ||||||||||||
393 | if( !IsHeaderFrame() && !IsFooterFrame() ) | ||||||||||||
394 | { | ||||||||||||
395 | mbDerivedVert = true; | ||||||||||||
396 | SetDirFlags( bVert ); | ||||||||||||
397 | } | ||||||||||||
398 | } | ||||||||||||
399 | else | ||||||||||||
400 | { | ||||||||||||
401 | mbDerivedR2L = true; | ||||||||||||
402 | SetDirFlags( bVert ); | ||||||||||||
403 | } | ||||||||||||
404 | } | ||||||||||||
405 | |||||||||||||
406 | void SwSectionFrame::CheckDirection( bool bVert ) | ||||||||||||
407 | { | ||||||||||||
408 | const SwFrameFormat* pFormat = GetFormat(); | ||||||||||||
409 | if( pFormat ) | ||||||||||||
410 | { | ||||||||||||
411 | const SwViewShell *pSh = getRootFrame()->GetCurrShell(); | ||||||||||||
412 | const bool bBrowseMode = pSh && pSh->GetViewOptions()->getBrowseMode(); | ||||||||||||
413 | CheckDir(pFormat->GetFormatAttr(RES_FRAMEDIR).GetValue(), | ||||||||||||
414 | bVert, true, bBrowseMode ); | ||||||||||||
415 | } | ||||||||||||
416 | else | ||||||||||||
417 | SwFrame::CheckDirection( bVert ); | ||||||||||||
418 | } | ||||||||||||
419 | |||||||||||||
420 | void SwFlyFrame::CheckDirection( bool bVert ) | ||||||||||||
421 | { | ||||||||||||
422 | const SwFrameFormat* pFormat = GetFormat(); | ||||||||||||
423 | if( pFormat ) | ||||||||||||
424 | { | ||||||||||||
425 | const SwViewShell *pSh = getRootFrame()->GetCurrShell(); | ||||||||||||
426 | const bool bBrowseMode = pSh && pSh->GetViewOptions()->getBrowseMode(); | ||||||||||||
427 | CheckDir(pFormat->GetFormatAttr(RES_FRAMEDIR).GetValue(), | ||||||||||||
428 | bVert, false, bBrowseMode ); | ||||||||||||
429 | } | ||||||||||||
430 | else | ||||||||||||
431 | SwFrame::CheckDirection( bVert ); | ||||||||||||
432 | } | ||||||||||||
433 | |||||||||||||
434 | void SwTabFrame::CheckDirection( bool bVert ) | ||||||||||||
435 | { | ||||||||||||
436 | const SwFrameFormat* pFormat = GetFormat(); | ||||||||||||
437 | if( pFormat ) | ||||||||||||
438 | { | ||||||||||||
439 | const SwViewShell *pSh = getRootFrame()->GetCurrShell(); | ||||||||||||
440 | const bool bBrowseMode = pSh && pSh->GetViewOptions()->getBrowseMode(); | ||||||||||||
441 | CheckDir(pFormat->GetFormatAttr(RES_FRAMEDIR).GetValue(), | ||||||||||||
442 | bVert, true, bBrowseMode ); | ||||||||||||
443 | } | ||||||||||||
444 | else | ||||||||||||
445 | SwFrame::CheckDirection( bVert ); | ||||||||||||
446 | } | ||||||||||||
447 | |||||||||||||
448 | void SwCellFrame::CheckDirection( bool bVert ) | ||||||||||||
449 | { | ||||||||||||
450 | const SwFrameFormat* pFormat = GetFormat(); | ||||||||||||
451 | const SfxPoolItem* pItem; | ||||||||||||
452 | // Check if the item is set, before actually | ||||||||||||
453 | // using it. Otherwise the dynamic pool default is used, which may be set | ||||||||||||
454 | // to LTR in case of OOo 1.0 documents. | ||||||||||||
455 | if( pFormat && SfxItemState::SET == pFormat->GetItemState( RES_FRAMEDIR, true, &pItem ) ) | ||||||||||||
456 | { | ||||||||||||
457 | const SvxFrameDirectionItem* pFrameDirItem = static_cast<const SvxFrameDirectionItem*>(pItem); | ||||||||||||
458 | const SwViewShell *pSh = getRootFrame()->GetCurrShell(); | ||||||||||||
459 | const bool bBrowseMode = pSh && pSh->GetViewOptions()->getBrowseMode(); | ||||||||||||
460 | CheckDir( pFrameDirItem->GetValue(), bVert, false, bBrowseMode ); | ||||||||||||
461 | } | ||||||||||||
462 | else | ||||||||||||
463 | SwFrame::CheckDirection( bVert ); | ||||||||||||
464 | } | ||||||||||||
465 | |||||||||||||
466 | void SwTextFrame::CheckDirection( bool bVert ) | ||||||||||||
467 | { | ||||||||||||
468 | const SwViewShell *pSh = getRootFrame()->GetCurrShell(); | ||||||||||||
469 | const bool bBrowseMode = pSh && pSh->GetViewOptions()->getBrowseMode(); | ||||||||||||
470 | CheckDir(GetTextNodeForParaProps()->GetSwAttrSet().GetFrameDir().GetValue(), | ||||||||||||
471 | bVert, true, bBrowseMode); | ||||||||||||
472 | } | ||||||||||||
473 | |||||||||||||
474 | void SwFrame::Modify( const SfxPoolItem* pOld, const SfxPoolItem * pNew ) | ||||||||||||
475 | { | ||||||||||||
476 | sal_uInt8 nInvFlags = 0; | ||||||||||||
477 | |||||||||||||
478 | if( pOld && pNew && RES_ATTRSET_CHG == pNew->Which() ) | ||||||||||||
479 | { | ||||||||||||
480 | SfxItemIter aNIter( *static_cast<const SwAttrSetChg*>(pNew)->GetChgSet() ); | ||||||||||||
481 | SfxItemIter aOIter( *static_cast<const SwAttrSetChg*>(pOld)->GetChgSet() ); | ||||||||||||
482 | const SfxPoolItem* pNItem = aNIter.GetCurItem(); | ||||||||||||
483 | const SfxPoolItem* pOItem = aOIter.GetCurItem(); | ||||||||||||
484 | do | ||||||||||||
485 | { | ||||||||||||
486 | UpdateAttrFrame(pOItem, pNItem, nInvFlags); | ||||||||||||
487 | pNItem = aNIter.NextItem(); | ||||||||||||
488 | pOItem = aOIter.NextItem(); | ||||||||||||
489 | } while (pNItem); | ||||||||||||
490 | } | ||||||||||||
491 | else | ||||||||||||
492 | UpdateAttrFrame( pOld, pNew, nInvFlags ); | ||||||||||||
493 | |||||||||||||
494 | if ( nInvFlags == 0 ) | ||||||||||||
495 | return; | ||||||||||||
496 | |||||||||||||
497 | SwPageFrame *pPage = FindPageFrame(); | ||||||||||||
498 | InvalidatePage( pPage ); | ||||||||||||
499 | if ( nInvFlags & 0x01 ) | ||||||||||||
500 | { | ||||||||||||
501 | InvalidatePrt_(); | ||||||||||||
502 | if( !GetPrev() && IsTabFrame() && IsInSct() ) | ||||||||||||
503 | FindSctFrame()->InvalidatePrt_(); | ||||||||||||
504 | } | ||||||||||||
505 | if ( nInvFlags & 0x02 ) | ||||||||||||
506 | InvalidateSize_(); | ||||||||||||
507 | if ( nInvFlags & 0x04 ) | ||||||||||||
508 | InvalidatePos_(); | ||||||||||||
509 | if ( nInvFlags & 0x08 ) | ||||||||||||
510 | SetCompletePaint(); | ||||||||||||
511 | SwFrame *pNxt; | ||||||||||||
512 | if ( nInvFlags & 0x30 && nullptr != (pNxt = GetNext()) ) | ||||||||||||
513 | { | ||||||||||||
514 | pNxt->InvalidatePage( pPage ); | ||||||||||||
515 | if ( nInvFlags & 0x10 ) | ||||||||||||
516 | pNxt->InvalidatePos_(); | ||||||||||||
517 | if ( nInvFlags & 0x20 ) | ||||||||||||
518 | pNxt->SetCompletePaint(); | ||||||||||||
519 | } | ||||||||||||
520 | } | ||||||||||||
521 | |||||||||||||
522 | void SwFrame::UpdateAttrFrame( const SfxPoolItem *pOld, const SfxPoolItem *pNew, | ||||||||||||
523 | sal_uInt8 &rInvFlags ) | ||||||||||||
524 | { | ||||||||||||
525 | sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0; | ||||||||||||
526 | switch( nWhich ) | ||||||||||||
527 | { | ||||||||||||
528 | case RES_BOX: | ||||||||||||
529 | case RES_SHADOW: | ||||||||||||
530 | Prepare( PrepareHint::FixSizeChanged ); | ||||||||||||
531 | [[fallthrough]]; | ||||||||||||
532 | case RES_LR_SPACE: | ||||||||||||
533 | case RES_UL_SPACE: | ||||||||||||
534 | rInvFlags |= 0x0B; | ||||||||||||
535 | break; | ||||||||||||
536 | |||||||||||||
537 | case RES_HEADER_FOOTER_EAT_SPACING: | ||||||||||||
538 | rInvFlags |= 0x03; | ||||||||||||
539 | break; | ||||||||||||
540 | |||||||||||||
541 | case RES_BACKGROUND: | ||||||||||||
542 | rInvFlags |= 0x28; | ||||||||||||
543 | break; | ||||||||||||
544 | |||||||||||||
545 | case RES_KEEP: | ||||||||||||
546 | rInvFlags |= 0x04; | ||||||||||||
547 | break; | ||||||||||||
548 | |||||||||||||
549 | case RES_FRM_SIZE: | ||||||||||||
550 | ReinitializeFrameSizeAttrFlags(); | ||||||||||||
551 | rInvFlags |= 0x13; | ||||||||||||
552 | break; | ||||||||||||
553 | |||||||||||||
554 | case RES_FMT_CHG: | ||||||||||||
555 | rInvFlags |= 0x0F; | ||||||||||||
556 | break; | ||||||||||||
557 | |||||||||||||
558 | case RES_ROW_SPLIT: | ||||||||||||
559 | { | ||||||||||||
560 | if ( IsRowFrame() ) | ||||||||||||
561 | { | ||||||||||||
562 | bool bInFollowFlowRow = nullptr != IsInFollowFlowRow(); | ||||||||||||
563 | if ( bInFollowFlowRow || nullptr != IsInSplitTableRow() ) | ||||||||||||
564 | { | ||||||||||||
565 | SwTabFrame* pTab = FindTabFrame(); | ||||||||||||
566 | if ( bInFollowFlowRow ) | ||||||||||||
567 | pTab = pTab->FindMaster(); | ||||||||||||
568 | pTab->SetRemoveFollowFlowLinePending( true ); | ||||||||||||
569 | } | ||||||||||||
570 | } | ||||||||||||
571 | break; | ||||||||||||
572 | } | ||||||||||||
573 | case RES_COL: | ||||||||||||
574 | OSL_FAIL( "Columns for new FrameType?" )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/wsfrm.cxx" ":" "574" ": "), "%s", "Columns for new FrameType?"); } } while (false); | ||||||||||||
575 | break; | ||||||||||||
576 | |||||||||||||
577 | default: | ||||||||||||
578 | // the new FillStyle has to do the same as previous RES_BACKGROUND | ||||||||||||
579 | if(nWhich >= XATTR_FILL_FIRST && nWhich <= XATTR_FILL_LAST) | ||||||||||||
580 | { | ||||||||||||
581 | rInvFlags |= 0x28; | ||||||||||||
582 | } | ||||||||||||
583 | /* do Nothing */; | ||||||||||||
584 | } | ||||||||||||
585 | } | ||||||||||||
586 | |||||||||||||
587 | bool SwFrame::Prepare( const PrepareHint, const void *, bool ) | ||||||||||||
588 | { | ||||||||||||
589 | /* Do nothing */ | ||||||||||||
590 | return false; | ||||||||||||
591 | } | ||||||||||||
592 | |||||||||||||
593 | /** | ||||||||||||
594 | * Invalidates the page in which the Frame is currently placed. | ||||||||||||
595 | * The page is invalidated depending on the type (Layout, Content, FlyFrame) | ||||||||||||
596 | */ | ||||||||||||
597 | void SwFrame::InvalidatePage( const SwPageFrame *pPage ) const | ||||||||||||
598 | { | ||||||||||||
599 | if ( !pPage ) | ||||||||||||
600 | { | ||||||||||||
601 | pPage = FindPageFrame(); | ||||||||||||
602 | // #i28701# - for at-character and as-character | ||||||||||||
603 | // anchored Writer fly frames additionally invalidate also page frame | ||||||||||||
604 | // its 'anchor character' is on. | ||||||||||||
605 | if ( pPage && pPage->GetUpper() && IsFlyFrame() ) | ||||||||||||
606 | { | ||||||||||||
607 | const SwFlyFrame* pFlyFrame = static_cast<const SwFlyFrame*>(this); | ||||||||||||
608 | if ( pFlyFrame->IsAutoPos() || pFlyFrame->IsFlyInContentFrame() ) | ||||||||||||
609 | { | ||||||||||||
610 | // #i33751#, #i34060# - method <GetPageFrameOfAnchor()> | ||||||||||||
611 | // is replaced by method <FindPageFrameOfAnchor()>. It's return value | ||||||||||||
612 | // have to be checked. | ||||||||||||
613 | SwPageFrame* pPageFrameOfAnchor = | ||||||||||||
614 | const_cast<SwFlyFrame*>(pFlyFrame)->FindPageFrameOfAnchor(); | ||||||||||||
615 | if ( pPageFrameOfAnchor && pPageFrameOfAnchor != pPage ) | ||||||||||||
616 | { | ||||||||||||
617 | InvalidatePage( pPageFrameOfAnchor ); | ||||||||||||
618 | } | ||||||||||||
619 | } | ||||||||||||
620 | } | ||||||||||||
621 | } | ||||||||||||
622 | |||||||||||||
623 | if ( !(pPage && pPage->GetUpper()) ) | ||||||||||||
624 | return; | ||||||||||||
625 | |||||||||||||
626 | if ( pPage->GetFormat()->GetDoc()->IsInDtor() ) | ||||||||||||
627 | return; | ||||||||||||
628 | |||||||||||||
629 | SwRootFrame *pRoot = const_cast<SwRootFrame*>(static_cast<const SwRootFrame*>(pPage->GetUpper())); | ||||||||||||
630 | const SwFlyFrame *pFly = FindFlyFrame(); | ||||||||||||
631 | if ( IsContentFrame() ) | ||||||||||||
632 | { | ||||||||||||
633 | if ( pRoot->IsTurboAllowed() ) | ||||||||||||
634 | { | ||||||||||||
635 | // If a ContentFrame wants to register for a second time, make it a TurboAction. | ||||||||||||
636 | if ( !pRoot->GetTurbo() || this == pRoot->GetTurbo() ) | ||||||||||||
637 | pRoot->SetTurbo( static_cast<const SwContentFrame*>(this) ); | ||||||||||||
638 | else | ||||||||||||
639 | { | ||||||||||||
640 | pRoot->DisallowTurbo(); | ||||||||||||
641 | //The page of the Turbo could be a different one then mine, | ||||||||||||
642 | //therefore we have to invalidate it. | ||||||||||||
643 | const SwFrame *pTmp = pRoot->GetTurbo(); | ||||||||||||
644 | pRoot->ResetTurbo(); | ||||||||||||
645 | pTmp->InvalidatePage(); | ||||||||||||
646 | } | ||||||||||||
647 | } | ||||||||||||
648 | if ( !pRoot->GetTurbo() ) | ||||||||||||
649 | { | ||||||||||||
650 | if ( pFly ) | ||||||||||||
651 | { if( !pFly->IsLocked() ) | ||||||||||||
652 | { | ||||||||||||
653 | if ( pFly->IsFlyInContentFrame() ) | ||||||||||||
654 | { pPage->InvalidateFlyInCnt(); | ||||||||||||
655 | pFly->GetAnchorFrame()->InvalidatePage(); | ||||||||||||
656 | } | ||||||||||||
657 | else | ||||||||||||
658 | pPage->InvalidateFlyContent(); | ||||||||||||
659 | } | ||||||||||||
660 | } | ||||||||||||
661 | else | ||||||||||||
662 | pPage->InvalidateContent(); | ||||||||||||
663 | } | ||||||||||||
664 | } | ||||||||||||
665 | else | ||||||||||||
666 | { | ||||||||||||
667 | pRoot->DisallowTurbo(); | ||||||||||||
668 | if ( pFly ) | ||||||||||||
669 | { | ||||||||||||
670 | if ( !pFly->IsLocked() ) | ||||||||||||
671 | { | ||||||||||||
672 | if ( pFly->IsFlyInContentFrame() ) | ||||||||||||
673 | { | ||||||||||||
674 | pPage->InvalidateFlyInCnt(); | ||||||||||||
675 | pFly->GetAnchorFrame()->InvalidatePage(); | ||||||||||||
676 | } | ||||||||||||
677 | else | ||||||||||||
678 | pPage->InvalidateFlyLayout(); | ||||||||||||
679 | } | ||||||||||||
680 | } | ||||||||||||
681 | else | ||||||||||||
682 | pPage->InvalidateLayout(); | ||||||||||||
683 | |||||||||||||
684 | if ( pRoot->GetTurbo() ) | ||||||||||||
685 | { const SwFrame *pTmp = pRoot->GetTurbo(); | ||||||||||||
686 | pRoot->ResetTurbo(); | ||||||||||||
687 | pTmp->InvalidatePage(); | ||||||||||||
688 | } | ||||||||||||
689 | } | ||||||||||||
690 | pRoot->SetIdleFlags(); | ||||||||||||
691 | |||||||||||||
692 | if (!IsTextFrame()) | ||||||||||||
693 | return; | ||||||||||||
694 | |||||||||||||
695 | SwTextFrame const*const pText(static_cast<SwTextFrame const*>(this)); | ||||||||||||
696 | if (sw::MergedPara const*const pMergedPara = pText->GetMergedPara()) | ||||||||||||
697 | { | ||||||||||||
698 | SwTextNode const* pNode(nullptr); | ||||||||||||
699 | for (auto const& e : pMergedPara->extents) | ||||||||||||
700 | { | ||||||||||||
701 | if (e.pNode != pNode) | ||||||||||||
702 | { | ||||||||||||
703 | pNode = e.pNode; | ||||||||||||
704 | if (pNode->IsGrammarCheckDirty()) | ||||||||||||
705 | { | ||||||||||||
706 | pRoot->SetNeedGrammarCheck( true ); | ||||||||||||
707 | break; | ||||||||||||
708 | } | ||||||||||||
709 | } | ||||||||||||
710 | } | ||||||||||||
711 | } | ||||||||||||
712 | else | ||||||||||||
713 | { | ||||||||||||
714 | if (pText->GetTextNodeFirst()->IsGrammarCheckDirty()) | ||||||||||||
715 | { | ||||||||||||
716 | pRoot->SetNeedGrammarCheck( true ); | ||||||||||||
717 | } | ||||||||||||
718 | } | ||||||||||||
719 | } | ||||||||||||
720 | |||||||||||||
721 | Size SwFrame::ChgSize( const Size& aNewSize ) | ||||||||||||
722 | { | ||||||||||||
723 | mbFixSize = true; | ||||||||||||
724 | const Size aOldSize( getFrameArea().SSize() ); | ||||||||||||
725 | if ( aNewSize == aOldSize ) | ||||||||||||
726 | return aOldSize; | ||||||||||||
727 | |||||||||||||
728 | if ( GetUpper() ) | ||||||||||||
729 | { | ||||||||||||
730 | bool bNeighb = IsNeighbourFrame(); | ||||||||||||
731 | SwRectFn fnRect = IsVertical() == bNeighb ? fnRectHori : ( IsVertLR() ? (IsVertLRBT() ? fnRectVertL2RB2T : fnRectVertL2R) : fnRectVert ); | ||||||||||||
732 | SwRect aNew( Point(0,0), aNewSize ); | ||||||||||||
733 | |||||||||||||
734 | { | ||||||||||||
735 | SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this); | ||||||||||||
736 | (aFrm.*fnRect->fnSetWidth)( (aNew.*fnRect->fnGetWidth)() ); | ||||||||||||
737 | } | ||||||||||||
738 | |||||||||||||
739 | long nNew = (aNew.*fnRect->fnGetHeight)(); | ||||||||||||
740 | long nDiff = nNew - (getFrameArea().*fnRect->fnGetHeight)(); | ||||||||||||
741 | |||||||||||||
742 | if( nDiff ) | ||||||||||||
743 | { | ||||||||||||
744 | if ( GetUpper()->IsFootnoteBossFrame() && HasFixSize() && | ||||||||||||
745 | SwNeighbourAdjust::GrowShrink != | ||||||||||||
746 | static_cast<SwFootnoteBossFrame*>(GetUpper())->NeighbourhoodAdjustment() ) | ||||||||||||
747 | { | ||||||||||||
748 | { | ||||||||||||
749 | SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this); | ||||||||||||
750 | (aFrm.*fnRect->fnSetHeight)( nNew ); | ||||||||||||
751 | } | ||||||||||||
752 | |||||||||||||
753 | SwTwips nReal = static_cast<SwLayoutFrame*>(this)->AdjustNeighbourhood(nDiff); | ||||||||||||
754 | |||||||||||||
755 | if ( nReal != nDiff ) | ||||||||||||
756 | { | ||||||||||||
757 | SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this); | ||||||||||||
758 | (aFrm.*fnRect->fnSetHeight)( nNew - nDiff + nReal ); | ||||||||||||
759 | } | ||||||||||||
760 | } | ||||||||||||
761 | else | ||||||||||||
762 | { | ||||||||||||
763 | // OD 24.10.2002 #97265# - grow/shrink not for neighbour frames | ||||||||||||
764 | // NOTE: neighbour frames are cell and column frames. | ||||||||||||
765 | if ( !bNeighb ) | ||||||||||||
766 | { | ||||||||||||
767 | if ( nDiff > 0 ) | ||||||||||||
768 | Grow( nDiff ); | ||||||||||||
769 | else | ||||||||||||
770 | Shrink( -nDiff ); | ||||||||||||
771 | |||||||||||||
772 | if ( GetUpper() && (getFrameArea().*fnRect->fnGetHeight)() != nNew ) | ||||||||||||
773 | { | ||||||||||||
774 | GetUpper()->InvalidateSize_(); | ||||||||||||
775 | } | ||||||||||||
776 | } | ||||||||||||
777 | |||||||||||||
778 | // Even if grow/shrink did not yet set the desired width, for | ||||||||||||
779 | // example when called by ChgColumns to set the column width, we | ||||||||||||
780 | // set the right width now. | ||||||||||||
781 | SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this); | ||||||||||||
782 | (aFrm.*fnRect->fnSetHeight)( nNew ); | ||||||||||||
783 | } | ||||||||||||
784 | } | ||||||||||||
785 | } | ||||||||||||
786 | else | ||||||||||||
787 | { | ||||||||||||
788 | SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this); | ||||||||||||
789 | aFrm.SSize( aNewSize ); | ||||||||||||
790 | } | ||||||||||||
791 | |||||||||||||
792 | if ( getFrameArea().SSize() != aOldSize ) | ||||||||||||
793 | { | ||||||||||||
794 | SwPageFrame *pPage = FindPageFrame(); | ||||||||||||
795 | if ( GetNext() ) | ||||||||||||
796 | { | ||||||||||||
797 | GetNext()->InvalidatePos_(); | ||||||||||||
798 | GetNext()->InvalidatePage( pPage ); | ||||||||||||
799 | } | ||||||||||||
800 | if( IsLayoutFrame() ) | ||||||||||||
801 | { | ||||||||||||
802 | if( IsRightToLeft() ) | ||||||||||||
803 | InvalidatePos_(); | ||||||||||||
804 | if( static_cast<SwLayoutFrame*>(this)->Lower() ) | ||||||||||||
805 | static_cast<SwLayoutFrame*>(this)->Lower()->InvalidateSize_(); | ||||||||||||
806 | } | ||||||||||||
807 | InvalidatePrt_(); | ||||||||||||
808 | InvalidateSize_(); | ||||||||||||
809 | InvalidatePage( pPage ); | ||||||||||||
810 | } | ||||||||||||
811 | |||||||||||||
812 | return getFrameArea().SSize(); | ||||||||||||
813 | } | ||||||||||||
814 | |||||||||||||
815 | /** Insert SwFrame into existing structure. | ||||||||||||
816 | * | ||||||||||||
817 | * Insertion is done below the parent either before pBehind or | ||||||||||||
818 | * at the end of the chain if pBehind is empty. | ||||||||||||
819 | */ | ||||||||||||
820 | void SwFrame::InsertBefore( SwLayoutFrame* pParent, SwFrame* pBehind ) | ||||||||||||
821 | { | ||||||||||||
822 | OSL_ENSURE( pParent, "No parent for insert." )do { if (true && (!(pParent))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" ":" "822" ": "), "%s", "No parent for insert."); } } while ( false); | ||||||||||||
823 | OSL_ENSURE( (!pBehind || pParent == pBehind->GetUpper()),do { if (true && (!((!pBehind || pParent == pBehind-> GetUpper())))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" ":" "824" ": "), "%s", "Frame tree is inconsistent."); } } while (false) | ||||||||||||
824 | "Frame tree is inconsistent." )do { if (true && (!((!pBehind || pParent == pBehind-> GetUpper())))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" ":" "824" ": "), "%s", "Frame tree is inconsistent."); } } while (false); | ||||||||||||
825 | |||||||||||||
826 | mpUpper = pParent; | ||||||||||||
827 | mpNext = pBehind; | ||||||||||||
828 | if( pBehind ) | ||||||||||||
829 | { //Insert before pBehind. | ||||||||||||
830 | mpPrev = pBehind->mpPrev; | ||||||||||||
831 | if( nullptr != mpPrev ) | ||||||||||||
832 | mpPrev->mpNext = this; | ||||||||||||
833 | else | ||||||||||||
834 | mpUpper->m_pLower = this; | ||||||||||||
835 | pBehind->mpPrev = this; | ||||||||||||
836 | } | ||||||||||||
837 | else | ||||||||||||
838 | { //Insert at the end, or as first node in the sub tree | ||||||||||||
839 | mpPrev = mpUpper->Lower(); | ||||||||||||
840 | if ( mpPrev ) | ||||||||||||
841 | { | ||||||||||||
842 | while( mpPrev->mpNext ) | ||||||||||||
843 | mpPrev = mpPrev->mpNext; | ||||||||||||
844 | mpPrev->mpNext = this; | ||||||||||||
845 | } | ||||||||||||
846 | else | ||||||||||||
847 | mpUpper->m_pLower = this; | ||||||||||||
848 | } | ||||||||||||
849 | } | ||||||||||||
850 | |||||||||||||
851 | /** Insert SwFrame into existing structure. | ||||||||||||
852 | * | ||||||||||||
853 | * Insertion is done below the parent either after pBehind or | ||||||||||||
854 | * at the beginning of the chain if pBehind is empty. | ||||||||||||
855 | */ | ||||||||||||
856 | void SwFrame::InsertBehind( SwLayoutFrame *pParent, SwFrame *pBefore ) | ||||||||||||
857 | { | ||||||||||||
858 | OSL_ENSURE( pParent, "No Parent for Insert." )do { if (true && (!(pParent))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" ":" "858" ": "), "%s", "No Parent for Insert."); } } while ( false); | ||||||||||||
859 | OSL_ENSURE( (!pBefore || pParent == pBefore->GetUpper()),do { if (true && (!((!pBefore || pParent == pBefore-> GetUpper())))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" ":" "860" ": "), "%s", "Frame tree is inconsistent."); } } while (false) | ||||||||||||
860 | "Frame tree is inconsistent." )do { if (true && (!((!pBefore || pParent == pBefore-> GetUpper())))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" ":" "860" ": "), "%s", "Frame tree is inconsistent."); } } while (false); | ||||||||||||
861 | |||||||||||||
862 | mpUpper = pParent; | ||||||||||||
863 | mpPrev = pBefore; | ||||||||||||
864 | if ( pBefore ) | ||||||||||||
865 | { | ||||||||||||
866 | //Insert after pBefore | ||||||||||||
867 | mpNext = pBefore->mpNext; | ||||||||||||
868 | if ( nullptr != mpNext ) | ||||||||||||
869 | mpNext->mpPrev = this; | ||||||||||||
870 | pBefore->mpNext = this; | ||||||||||||
871 | } | ||||||||||||
872 | else | ||||||||||||
873 | { | ||||||||||||
874 | //Insert at the beginning of the chain | ||||||||||||
875 | mpNext = pParent->Lower(); | ||||||||||||
876 | if ( pParent->Lower() ) | ||||||||||||
877 | pParent->Lower()->mpPrev = this; | ||||||||||||
878 | pParent->m_pLower = this; | ||||||||||||
879 | } | ||||||||||||
880 | } | ||||||||||||
881 | |||||||||||||
882 | /** Insert a chain of SwFrames into an existing structure | ||||||||||||
883 | * | ||||||||||||
884 | * Currently, this method is used to insert a SectionFrame (which may have some siblings) into an | ||||||||||||
885 | * existing structure. If the third parameter is NULL, this method is (besides handling the | ||||||||||||
886 | * siblings) equal to SwFrame::InsertBefore(..). | ||||||||||||
887 | * | ||||||||||||
888 | * If the third parameter is passed, the following happens: | ||||||||||||
889 | * - this becomes mpNext of pParent | ||||||||||||
890 | * - pSct becomes mpNext of the last one in the this-chain | ||||||||||||
891 | * - pBehind is reconnected from pParent to pSct | ||||||||||||
892 | * The purpose is: a SectionFrame (this) won't become a child of another SectionFrame (pParent), but | ||||||||||||
893 | * pParent gets split into two siblings (pParent+pSect) and this is inserted between. | ||||||||||||
894 | */ | ||||||||||||
895 | bool SwFrame::InsertGroupBefore( SwFrame* pParent, SwFrame* pBehind, SwFrame* pSct ) | ||||||||||||
896 | { | ||||||||||||
897 | OSL_ENSURE( pParent, "No parent for insert." )do { if (true && (!(pParent))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" ":" "897" ": "), "%s", "No parent for insert."); } } while ( false); | ||||||||||||
898 | OSL_ENSURE( (!pBehind || ( (pBehind && (pParent == pBehind->GetUpper()))do { if (true && (!((!pBehind || ( (pBehind && (pParent == pBehind->GetUpper())) || ((pParent->IsSctFrame () && pBehind->GetUpper()->IsColBodyFrame())) ) )))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl" ), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" ":" "900" ": "), "%s", "Frame tree inconsistent."); } } while (false) | ||||||||||||
899 | || ((pParent->IsSctFrame() && pBehind->GetUpper()->IsColBodyFrame())) ) ),do { if (true && (!((!pBehind || ( (pBehind && (pParent == pBehind->GetUpper())) || ((pParent->IsSctFrame () && pBehind->GetUpper()->IsColBodyFrame())) ) )))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl" ), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" ":" "900" ": "), "%s", "Frame tree inconsistent."); } } while (false) | ||||||||||||
900 | "Frame tree inconsistent." )do { if (true && (!((!pBehind || ( (pBehind && (pParent == pBehind->GetUpper())) || ((pParent->IsSctFrame () && pBehind->GetUpper()->IsColBodyFrame())) ) )))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl" ), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" ":" "900" ": "), "%s", "Frame tree inconsistent."); } } while (false); | ||||||||||||
901 | if( pSct ) | ||||||||||||
902 | { | ||||||||||||
903 | mpUpper = pParent->GetUpper(); | ||||||||||||
904 | SwFrame *pLast = this; | ||||||||||||
905 | while( pLast->GetNext() ) | ||||||||||||
906 | { | ||||||||||||
907 | pLast = pLast->GetNext(); | ||||||||||||
908 | pLast->mpUpper = GetUpper(); | ||||||||||||
909 | } | ||||||||||||
910 | if( pBehind ) | ||||||||||||
911 | { | ||||||||||||
912 | pLast->mpNext = pSct; | ||||||||||||
913 | pSct->mpPrev = pLast; | ||||||||||||
914 | pSct->mpNext = pParent->GetNext(); | ||||||||||||
915 | } | ||||||||||||
916 | else | ||||||||||||
917 | { | ||||||||||||
918 | pLast->mpNext = pParent->GetNext(); | ||||||||||||
919 | if( pLast->GetNext() ) | ||||||||||||
920 | pLast->GetNext()->mpPrev = pLast; | ||||||||||||
921 | } | ||||||||||||
922 | pParent->mpNext = this; | ||||||||||||
923 | mpPrev = pParent; | ||||||||||||
924 | if( pSct->GetNext() ) | ||||||||||||
925 | pSct->GetNext()->mpPrev = pSct; | ||||||||||||
926 | while( pLast->GetNext() ) | ||||||||||||
927 | { | ||||||||||||
928 | pLast = pLast->GetNext(); | ||||||||||||
929 | pLast->mpUpper = GetUpper(); | ||||||||||||
930 | } | ||||||||||||
931 | if( pBehind ) | ||||||||||||
932 | { // Insert before pBehind. | ||||||||||||
933 | if( pBehind->GetPrev() ) | ||||||||||||
934 | pBehind->GetPrev()->mpNext = nullptr; | ||||||||||||
935 | else | ||||||||||||
936 | pBehind->GetUpper()->m_pLower = nullptr; | ||||||||||||
937 | pBehind->mpPrev = nullptr; | ||||||||||||
938 | SwLayoutFrame* pTmp = static_cast<SwLayoutFrame*>(pSct); | ||||||||||||
939 | if( pTmp->Lower() ) | ||||||||||||
940 | { | ||||||||||||
941 | OSL_ENSURE( pTmp->Lower()->IsColumnFrame(), "InsertGrp: Used SectionFrame" )do { if (true && (!(pTmp->Lower()->IsColumnFrame ()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl" ), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" ":" "941" ": "), "%s", "InsertGrp: Used SectionFrame"); } } while (false); | ||||||||||||
942 | pTmp = static_cast<SwLayoutFrame*>(static_cast<SwLayoutFrame*>(pTmp->Lower())->Lower()); | ||||||||||||
943 | OSL_ENSURE( pTmp, "InsertGrp: Missing ColBody" )do { if (true && (!(pTmp))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" ":" "943" ": "), "%s", "InsertGrp: Missing ColBody"); } } while (false); | ||||||||||||
944 | } | ||||||||||||
945 | pBehind->mpUpper = pTmp; | ||||||||||||
946 | pBehind->GetUpper()->m_pLower = pBehind; | ||||||||||||
947 | pLast = pBehind->GetNext(); | ||||||||||||
948 | while ( pLast ) | ||||||||||||
949 | { | ||||||||||||
950 | pLast->mpUpper = pBehind->GetUpper(); | ||||||||||||
951 | pLast = pLast->GetNext(); | ||||||||||||
952 | } | ||||||||||||
953 | } | ||||||||||||
954 | else | ||||||||||||
955 | { | ||||||||||||
956 | OSL_ENSURE( pSct->IsSctFrame(), "InsertGroup: For SectionFrames only" )do { if (true && (!(pSct->IsSctFrame()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" ":" "956" ": "), "%s", "InsertGroup: For SectionFrames only" ); } } while (false); | ||||||||||||
957 | SwFrame::DestroyFrame(pSct); | ||||||||||||
958 | return false; | ||||||||||||
959 | } | ||||||||||||
960 | } | ||||||||||||
961 | else | ||||||||||||
962 | { | ||||||||||||
963 | mpUpper = static_cast<SwLayoutFrame*>(pParent); | ||||||||||||
964 | SwFrame *pLast = this; | ||||||||||||
965 | while( pLast->GetNext() ) | ||||||||||||
966 | { | ||||||||||||
967 | pLast = pLast->GetNext(); | ||||||||||||
968 | pLast->mpUpper = GetUpper(); | ||||||||||||
969 | } | ||||||||||||
970 | pLast->mpNext = pBehind; | ||||||||||||
971 | if( pBehind ) | ||||||||||||
972 | { // Insert before pBehind. | ||||||||||||
973 | mpPrev = pBehind->mpPrev; | ||||||||||||
974 | if( nullptr != mpPrev ) | ||||||||||||
975 | mpPrev->mpNext = this; | ||||||||||||
976 | else | ||||||||||||
977 | mpUpper->m_pLower = this; | ||||||||||||
978 | pBehind->mpPrev = pLast; | ||||||||||||
979 | } | ||||||||||||
980 | else | ||||||||||||
981 | { | ||||||||||||
982 | //Insert at the end, or ... the first node in the subtree | ||||||||||||
983 | mpPrev = mpUpper->Lower(); | ||||||||||||
984 | if ( mpPrev ) | ||||||||||||
985 | { | ||||||||||||
986 | while( mpPrev->mpNext ) | ||||||||||||
987 | mpPrev = mpPrev->mpNext; | ||||||||||||
988 | mpPrev->mpNext = this; | ||||||||||||
989 | } | ||||||||||||
990 | else | ||||||||||||
991 | mpUpper->m_pLower = this; | ||||||||||||
992 | } | ||||||||||||
993 | } | ||||||||||||
994 | return true; | ||||||||||||
995 | } | ||||||||||||
996 | |||||||||||||
997 | void SwFrame::RemoveFromLayout() | ||||||||||||
998 | { | ||||||||||||
999 | OSL_ENSURE( mpUpper, "Remove without upper?" )do { if (true && (!(mpUpper))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" ":" "999" ": "), "%s", "Remove without upper?"); } } while ( false); | ||||||||||||
1000 | |||||||||||||
1001 | if (mpPrev) | ||||||||||||
1002 | // one out of the middle is removed | ||||||||||||
1003 | mpPrev->mpNext = mpNext; | ||||||||||||
1004 | else if (mpUpper) | ||||||||||||
1005 | { // the first in a list is removed //TODO | ||||||||||||
1006 | OSL_ENSURE( mpUpper->m_pLower == this, "Layout is inconsistent." )do { if (true && (!(mpUpper->m_pLower == this))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl" ), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" ":" "1006" ": "), "%s", "Layout is inconsistent."); } } while (false); | ||||||||||||
1007 | mpUpper->m_pLower = mpNext; | ||||||||||||
1008 | } | ||||||||||||
1009 | if( mpNext ) | ||||||||||||
1010 | mpNext->mpPrev = mpPrev; | ||||||||||||
1011 | |||||||||||||
1012 | // Remove link | ||||||||||||
1013 | mpNext = mpPrev = nullptr; | ||||||||||||
1014 | mpUpper = nullptr; | ||||||||||||
1015 | } | ||||||||||||
1016 | |||||||||||||
1017 | void SwContentFrame::Paste( SwFrame* pParent, SwFrame* pSibling) | ||||||||||||
1018 | { | ||||||||||||
1019 | OSL_ENSURE( pParent, "No parent for pasting." )do { if (true && (!(pParent))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" ":" "1019" ": "), "%s", "No parent for pasting."); } } while (false); | ||||||||||||
1020 | OSL_ENSURE( pParent->IsLayoutFrame(), "Parent is ContentFrame." )do { if (true && (!(pParent->IsLayoutFrame()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" ":" "1020" ": "), "%s", "Parent is ContentFrame."); } } while (false); | ||||||||||||
1021 | OSL_ENSURE( pParent != this, "I'm the parent." )do { if (true && (!(pParent != this))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" ":" "1021" ": "), "%s", "I'm the parent."); } } while (false ); | ||||||||||||
1022 | OSL_ENSURE( pSibling != this, "I'm my own neighbour." )do { if (true && (!(pSibling != this))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" ":" "1022" ": "), "%s", "I'm my own neighbour."); } } while ( false); | ||||||||||||
1023 | OSL_ENSURE( !GetPrev() && !GetNext() && !GetUpper(),do { if (true && (!(!GetPrev() && !GetNext() && !GetUpper()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" ":" "1024" ": "), "%s", "I'm still registered somewhere"); } } while (false) | ||||||||||||
1024 | "I'm still registered somewhere" )do { if (true && (!(!GetPrev() && !GetNext() && !GetUpper()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" ":" "1024" ": "), "%s", "I'm still registered somewhere"); } } while (false); | ||||||||||||
1025 | OSL_ENSURE( !pSibling || pSibling->IsFlowFrame(),do { if (true && (!(!pSibling || pSibling->IsFlowFrame ()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl" ), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" ":" "1026" ": "), "%s", "<SwContentFrame::Paste(..)> - sibling not of expected type." ); } } while (false) | ||||||||||||
1026 | "<SwContentFrame::Paste(..)> - sibling not of expected type." )do { if (true && (!(!pSibling || pSibling->IsFlowFrame ()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl" ), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" ":" "1026" ": "), "%s", "<SwContentFrame::Paste(..)> - sibling not of expected type." ); } } while (false); | ||||||||||||
1027 | |||||||||||||
1028 | //Insert in the tree. | ||||||||||||
1029 | InsertBefore( static_cast<SwLayoutFrame*>(pParent), pSibling ); | ||||||||||||
1030 | |||||||||||||
1031 | SwPageFrame *pPage = FindPageFrame(); | ||||||||||||
1032 | InvalidateAll_(); | ||||||||||||
1033 | InvalidatePage( pPage ); | ||||||||||||
1034 | |||||||||||||
1035 | if( pPage ) | ||||||||||||
1036 | { | ||||||||||||
1037 | pPage->InvalidateSpelling(); | ||||||||||||
1038 | pPage->InvalidateSmartTags(); | ||||||||||||
1039 | pPage->InvalidateAutoCompleteWords(); | ||||||||||||
1040 | pPage->InvalidateWordCount(); | ||||||||||||
1041 | } | ||||||||||||
1042 | |||||||||||||
1043 | if ( GetNext() ) | ||||||||||||
1044 | { | ||||||||||||
1045 | SwFrame* pNxt = GetNext(); | ||||||||||||
1046 | pNxt->InvalidatePrt_(); | ||||||||||||
1047 | pNxt->InvalidatePos_(); | ||||||||||||
1048 | pNxt->InvalidatePage( pPage ); | ||||||||||||
1049 | if( pNxt->IsSctFrame() ) | ||||||||||||
1050 | pNxt = static_cast<SwSectionFrame*>(pNxt)->ContainsContent(); | ||||||||||||
1051 | if( pNxt && pNxt->IsTextFrame() && pNxt->IsInFootnote() ) | ||||||||||||
1052 | pNxt->Prepare( PrepareHint::FootnoteInvalidation, nullptr, false ); | ||||||||||||
1053 | } | ||||||||||||
1054 | |||||||||||||
1055 | if ( getFrameArea().Height() ) | ||||||||||||
1056 | pParent->Grow( getFrameArea().Height() ); | ||||||||||||
1057 | |||||||||||||
1058 | if ( getFrameArea().Width() != pParent->getFramePrintArea().Width() ) | ||||||||||||
1059 | Prepare( PrepareHint::FixSizeChanged ); | ||||||||||||
1060 | |||||||||||||
1061 | if ( GetPrev() ) | ||||||||||||
1062 | { | ||||||||||||
1063 | if ( IsFollow() ) | ||||||||||||
1064 | //I'm a direct follower of my master now | ||||||||||||
1065 | static_cast<SwContentFrame*>(GetPrev())->Prepare( PrepareHint::FollowFollows ); | ||||||||||||
1066 | else | ||||||||||||
1067 | { | ||||||||||||
1068 | if ( GetPrev()->getFrameArea().Height() != | ||||||||||||
1069 | GetPrev()->getFramePrintArea().Height() + GetPrev()->getFramePrintArea().Top() ) | ||||||||||||
1070 | { | ||||||||||||
1071 | // Take the border into account? | ||||||||||||
1072 | GetPrev()->InvalidatePrt_(); | ||||||||||||
1073 | } | ||||||||||||
1074 | // OD 18.02.2003 #104989# - force complete paint of previous frame, | ||||||||||||
1075 | // if frame is inserted at the end of a section frame, in order to | ||||||||||||
1076 | // get subsidiary lines repainted for the section. | ||||||||||||
1077 | if ( pParent->IsSctFrame() && !GetNext() ) | ||||||||||||
1078 | { | ||||||||||||
1079 | // force complete paint of previous frame, if new inserted frame | ||||||||||||
1080 | // in the section is the last one. | ||||||||||||
1081 | GetPrev()->SetCompletePaint(); | ||||||||||||
1082 | } | ||||||||||||
1083 | GetPrev()->InvalidatePage( pPage ); | ||||||||||||
1084 | } | ||||||||||||
1085 | } | ||||||||||||
1086 | if ( IsInFootnote() ) | ||||||||||||
1087 | { | ||||||||||||
1088 | SwFrame* pFrame = GetIndPrev(); | ||||||||||||
1089 | if( pFrame && pFrame->IsSctFrame() ) | ||||||||||||
1090 | pFrame = static_cast<SwSectionFrame*>(pFrame)->ContainsAny(); | ||||||||||||
1091 | if( pFrame ) | ||||||||||||
1092 | pFrame->Prepare( PrepareHint::QuoVadis, nullptr, false ); | ||||||||||||
1093 | if( !GetNext() ) | ||||||||||||
1094 | { | ||||||||||||
1095 | pFrame = FindFootnoteFrame()->GetNext(); | ||||||||||||
1096 | if( pFrame && nullptr != (pFrame=static_cast<SwLayoutFrame*>(pFrame)->ContainsAny()) ) | ||||||||||||
1097 | pFrame->InvalidatePrt_(); | ||||||||||||
1098 | } | ||||||||||||
1099 | } | ||||||||||||
1100 | |||||||||||||
1101 | InvalidateLineNum_(); | ||||||||||||
1102 | SwFrame *pNxt = FindNextCnt(); | ||||||||||||
1103 | if ( !pNxt ) | ||||||||||||
1104 | return; | ||||||||||||
1105 | |||||||||||||
1106 | while ( pNxt && pNxt->IsInTab() ) | ||||||||||||
1107 | { | ||||||||||||
1108 | pNxt = pNxt->FindTabFrame(); | ||||||||||||
1109 | if( nullptr != pNxt ) | ||||||||||||
1110 | pNxt = pNxt->FindNextCnt(); | ||||||||||||
1111 | } | ||||||||||||
1112 | if ( pNxt ) | ||||||||||||
1113 | { | ||||||||||||
1114 | pNxt->InvalidateLineNum_(); | ||||||||||||
1115 | if ( pNxt != GetNext() ) | ||||||||||||
1116 | pNxt->InvalidatePage(); | ||||||||||||
1117 | } | ||||||||||||
1118 | } | ||||||||||||
1119 | |||||||||||||
1120 | void SwContentFrame::Cut() | ||||||||||||
1121 | { | ||||||||||||
1122 | OSL_ENSURE( GetUpper(), "Cut without Upper()." )do { if (true && (!(GetUpper()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" ":" "1122" ": "), "%s", "Cut without Upper()."); } } while ( false); | ||||||||||||
1123 | |||||||||||||
1124 | SwPageFrame *pPage = FindPageFrame(); | ||||||||||||
1125 | InvalidatePage( pPage ); | ||||||||||||
1126 | SwFrame *pFrame = GetIndPrev(); | ||||||||||||
1127 | if( pFrame ) | ||||||||||||
1128 | { | ||||||||||||
1129 | if( pFrame->IsSctFrame() ) | ||||||||||||
1130 | pFrame = static_cast<SwSectionFrame*>(pFrame)->ContainsAny(); | ||||||||||||
1131 | if ( pFrame && pFrame->IsContentFrame() ) | ||||||||||||
1132 | { | ||||||||||||
1133 | pFrame->InvalidatePrt_(); | ||||||||||||
1134 | if( IsInFootnote() ) | ||||||||||||
1135 | pFrame->Prepare( PrepareHint::QuoVadis, nullptr, false ); | ||||||||||||
1136 | } | ||||||||||||
1137 | // #i26250# - invalidate printing area of previous | ||||||||||||
1138 | // table frame. | ||||||||||||
1139 | else if ( pFrame && pFrame->IsTabFrame() ) | ||||||||||||
1140 | { | ||||||||||||
1141 | pFrame->InvalidatePrt(); | ||||||||||||
1142 | } | ||||||||||||
1143 | } | ||||||||||||
1144 | |||||||||||||
1145 | SwFrame *pNxt = FindNextCnt(); | ||||||||||||
1146 | if ( pNxt ) | ||||||||||||
1147 | { | ||||||||||||
1148 | while ( pNxt && pNxt->IsInTab() ) | ||||||||||||
1149 | { | ||||||||||||
1150 | pNxt = pNxt->FindTabFrame(); | ||||||||||||
1151 | if( nullptr != pNxt ) | ||||||||||||
1152 | pNxt = pNxt->FindNextCnt(); | ||||||||||||
1153 | } | ||||||||||||
1154 | if ( pNxt ) | ||||||||||||
1155 | { | ||||||||||||
1156 | pNxt->InvalidateLineNum_(); | ||||||||||||
1157 | if ( pNxt != GetNext() ) | ||||||||||||
1158 | pNxt->InvalidatePage(); | ||||||||||||
1159 | } | ||||||||||||
1160 | } | ||||||||||||
1161 | |||||||||||||
1162 | pFrame = GetIndNext(); | ||||||||||||
1163 | if( pFrame ) | ||||||||||||
1164 | { | ||||||||||||
1165 | // The old follow may have calculated a gap to the predecessor which | ||||||||||||
1166 | // now becomes obsolete or different as it becomes the first one itself | ||||||||||||
1167 | pFrame->InvalidatePrt_(); | ||||||||||||
1168 | pFrame->InvalidatePos_(); | ||||||||||||
1169 | pFrame->InvalidatePage( pPage ); | ||||||||||||
1170 | if( pFrame->IsSctFrame() ) | ||||||||||||
1171 | { | ||||||||||||
1172 | pFrame = static_cast<SwSectionFrame*>(pFrame)->ContainsAny(); | ||||||||||||
1173 | if( pFrame ) | ||||||||||||
1174 | { | ||||||||||||
1175 | pFrame->InvalidatePrt_(); | ||||||||||||
1176 | pFrame->InvalidatePos_(); | ||||||||||||
1177 | pFrame->InvalidatePage( pPage ); | ||||||||||||
1178 | } | ||||||||||||
1179 | } | ||||||||||||
1180 | if( pFrame && IsInFootnote() ) | ||||||||||||
1181 | pFrame->Prepare( PrepareHint::ErgoSum, nullptr, false ); | ||||||||||||
1182 | if( IsInSct() && !GetPrev() ) | ||||||||||||
1183 | { | ||||||||||||
1184 | SwSectionFrame* pSct = FindSctFrame(); | ||||||||||||
1185 | if( !pSct->IsFollow() ) | ||||||||||||
1186 | { | ||||||||||||
1187 | pSct->InvalidatePrt_(); | ||||||||||||
1188 | pSct->InvalidatePage( pPage ); | ||||||||||||
1189 | } | ||||||||||||
1190 | } | ||||||||||||
1191 | } | ||||||||||||
1192 | else | ||||||||||||
1193 | { | ||||||||||||
1194 | InvalidateNextPos(); | ||||||||||||
1195 | //Someone needs to do the retouching: predecessor or upper | ||||||||||||
1196 | pFrame = GetPrev(); | ||||||||||||
1197 | if ( nullptr != pFrame ) | ||||||||||||
1198 | { pFrame->SetRetouche(); | ||||||||||||
1199 | pFrame->Prepare( PrepareHint::WidowsOrphans ); | ||||||||||||
1200 | pFrame->InvalidatePos_(); | ||||||||||||
1201 | pFrame->InvalidatePage( pPage ); | ||||||||||||
1202 | } | ||||||||||||
1203 | // If I'm (was) the only ContentFrame in my upper, it has to do the | ||||||||||||
1204 | // retouching. Also, perhaps a page became empty. | ||||||||||||
1205 | else | ||||||||||||
1206 | { SwRootFrame *pRoot = getRootFrame(); | ||||||||||||
1207 | if ( pRoot ) | ||||||||||||
1208 | { | ||||||||||||
1209 | pRoot->SetSuperfluous(); | ||||||||||||
1210 | GetUpper()->SetCompletePaint(); | ||||||||||||
1211 | GetUpper()->InvalidatePage( pPage ); | ||||||||||||
1212 | } | ||||||||||||
1213 | if( IsInSct() ) | ||||||||||||
1214 | { | ||||||||||||
1215 | SwSectionFrame* pSct = FindSctFrame(); | ||||||||||||
1216 | if( !pSct->IsFollow() ) | ||||||||||||
1217 | { | ||||||||||||
1218 | pSct->InvalidatePrt_(); | ||||||||||||
1219 | pSct->InvalidatePage( pPage ); | ||||||||||||
1220 | } | ||||||||||||
1221 | } | ||||||||||||
1222 | // #i52253# The master table should take care | ||||||||||||
1223 | // of removing the follow flow line. | ||||||||||||
1224 | if ( IsInTab() ) | ||||||||||||
1225 | { | ||||||||||||
1226 | SwTabFrame* pThisTab = FindTabFrame(); | ||||||||||||
1227 | SwTabFrame* pMasterTab = pThisTab && pThisTab->IsFollow() ? pThisTab->FindMaster() : nullptr; | ||||||||||||
1228 | if ( pMasterTab ) | ||||||||||||
1229 | { | ||||||||||||
1230 | pMasterTab->InvalidatePos_(); | ||||||||||||
1231 | pMasterTab->SetRemoveFollowFlowLinePending( true ); | ||||||||||||
1232 | } | ||||||||||||
1233 | } | ||||||||||||
1234 | } | ||||||||||||
1235 | } | ||||||||||||
1236 | //Remove first, then shrink the upper. | ||||||||||||
1237 | SwLayoutFrame *pUp = GetUpper(); | ||||||||||||
1238 | RemoveFromLayout(); | ||||||||||||
1239 | if ( !pUp ) | ||||||||||||
1240 | return; | ||||||||||||
1241 | |||||||||||||
1242 | SwSectionFrame *pSct = nullptr; | ||||||||||||
1243 | if ( !pUp->Lower() && | ||||||||||||
1244 | ( ( pUp->IsFootnoteFrame() && !pUp->IsColLocked() ) || | ||||||||||||
1245 | ( pUp->IsInSct() && | ||||||||||||
1246 | // #i29438# | ||||||||||||
1247 | // We have to consider the case that the section may be "empty" | ||||||||||||
1248 | // except from a temporary empty table frame. | ||||||||||||
1249 | // This can happen due to the new cell split feature. | ||||||||||||
1250 | !pUp->IsCellFrame() && | ||||||||||||
1251 | // #126020# - adjust check for empty section | ||||||||||||
1252 | // #130797# - correct fix #126020# | ||||||||||||
1253 | !(pSct = pUp->FindSctFrame())->ContainsContent() && | ||||||||||||
1254 | !pSct->ContainsAny( true ) ) ) ) | ||||||||||||
1255 | { | ||||||||||||
1256 | if ( pUp->GetUpper() ) | ||||||||||||
1257 | { | ||||||||||||
1258 | |||||||||||||
1259 | // prevent delete of <ColLocked> footnote frame | ||||||||||||
1260 | if ( pUp->IsFootnoteFrame() && !pUp->IsColLocked()) | ||||||||||||
1261 | { | ||||||||||||
1262 | if( pUp->GetNext() && !pUp->GetPrev() ) | ||||||||||||
1263 | { | ||||||||||||
1264 | SwFrame* pTmp = static_cast<SwLayoutFrame*>(pUp->GetNext())->ContainsAny(); | ||||||||||||
1265 | if( pTmp ) | ||||||||||||
1266 | pTmp->InvalidatePrt_(); | ||||||||||||
1267 | } | ||||||||||||
1268 | if (!pUp->IsDeleteForbidden()) | ||||||||||||
1269 | { | ||||||||||||
1270 | pUp->Cut(); | ||||||||||||
1271 | SwFrame::DestroyFrame(pUp); | ||||||||||||
1272 | } | ||||||||||||
1273 | } | ||||||||||||
1274 | else | ||||||||||||
1275 | { | ||||||||||||
1276 | |||||||||||||
1277 | if ( pSct->IsColLocked() || !pSct->IsInFootnote() || | ||||||||||||
1278 | ( pUp->IsFootnoteFrame() && pUp->IsColLocked() ) ) | ||||||||||||
1279 | { | ||||||||||||
1280 | pSct->DelEmpty( false ); | ||||||||||||
1281 | // If a locked section may not be deleted then at least | ||||||||||||
1282 | // its size became invalid after removing its last | ||||||||||||
1283 | // content. | ||||||||||||
1284 | pSct->InvalidateSize_(); | ||||||||||||
1285 | } | ||||||||||||
1286 | else | ||||||||||||
1287 | { | ||||||||||||
1288 | pSct->DelEmpty( true ); | ||||||||||||
1289 | SwFrame::DestroyFrame(pSct); | ||||||||||||
1290 | } | ||||||||||||
1291 | } | ||||||||||||
1292 | } | ||||||||||||
1293 | } | ||||||||||||
1294 | else | ||||||||||||
1295 | { | ||||||||||||
1296 | SwRectFnSet aRectFnSet(this); | ||||||||||||
1297 | long nFrameHeight = aRectFnSet.GetHeight(getFrameArea()); | ||||||||||||
1298 | if( nFrameHeight ) | ||||||||||||
1299 | pUp->Shrink( nFrameHeight ); | ||||||||||||
1300 | } | ||||||||||||
1301 | } | ||||||||||||
1302 | |||||||||||||
1303 | void SwLayoutFrame::Paste( SwFrame* pParent, SwFrame* pSibling) | ||||||||||||
1304 | { | ||||||||||||
1305 | OSL_ENSURE( pParent, "No parent for pasting." )do { if (true && (!(pParent))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" ":" "1305" ": "), "%s", "No parent for pasting."); } } while (false); | ||||||||||||
1306 | OSL_ENSURE( pParent->IsLayoutFrame(), "Parent is ContentFrame." )do { if (true && (!(pParent->IsLayoutFrame()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" ":" "1306" ": "), "%s", "Parent is ContentFrame."); } } while (false); | ||||||||||||
1307 | OSL_ENSURE( pParent != this, "I'm the parent oneself." )do { if (true && (!(pParent != this))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" ":" "1307" ": "), "%s", "I'm the parent oneself."); } } while (false); | ||||||||||||
1308 | OSL_ENSURE( pSibling != this, "I'm my own neighbour." )do { if (true && (!(pSibling != this))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" ":" "1308" ": "), "%s", "I'm my own neighbour."); } } while ( false); | ||||||||||||
1309 | OSL_ENSURE( !GetPrev() && !GetNext() && !GetUpper(),do { if (true && (!(!GetPrev() && !GetNext() && !GetUpper()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" ":" "1310" ": "), "%s", "I'm still registered somewhere."); } } while (false) | ||||||||||||
1310 | "I'm still registered somewhere." )do { if (true && (!(!GetPrev() && !GetNext() && !GetUpper()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" ":" "1310" ": "), "%s", "I'm still registered somewhere."); } } while (false); | ||||||||||||
1311 | |||||||||||||
1312 | //Insert in the tree. | ||||||||||||
1313 | InsertBefore( static_cast<SwLayoutFrame*>(pParent), pSibling ); | ||||||||||||
1314 | |||||||||||||
1315 | // OD 24.10.2002 #103517# - correct setting of variable <fnRect> | ||||||||||||
1316 | // <fnRect> is used for the following: | ||||||||||||
1317 | // (1) To invalidate the frame's size, if its size, which has to be the | ||||||||||||
1318 | // same as its upper/parent, differs from its upper's/parent's. | ||||||||||||
1319 | // (2) To adjust/grow the frame's upper/parent, if it has a dimension in its | ||||||||||||
1320 | // size, which is not determined by its upper/parent. | ||||||||||||
1321 | // Which size is which depends on the frame type and the layout direction | ||||||||||||
1322 | // (vertical or horizontal). | ||||||||||||
1323 | // There are the following cases: | ||||||||||||
1324 | // (A) Header and footer frames both in vertical and in horizontal layout | ||||||||||||
1325 | // have to size the width to the upper/parent. A dimension in the height | ||||||||||||
1326 | // has to cause an adjustment/grow of the upper/parent. | ||||||||||||
1327 | // --> <fnRect> = fnRectHori | ||||||||||||
1328 | // (B) Cell and column frames in vertical layout, the width has to be the | ||||||||||||
1329 | // same as upper/parent and a dimension in height causes adjustment/grow | ||||||||||||
1330 | // of the upper/parent. | ||||||||||||
1331 | // --> <fnRect> = fnRectHori | ||||||||||||
1332 | // in horizontal layout the other way around | ||||||||||||
1333 | // --> <fnRect> = fnRectVert | ||||||||||||
1334 | // (C) Other frames in vertical layout, the height has to be the | ||||||||||||
1335 | // same as upper/parent and a dimension in width causes adjustment/grow | ||||||||||||
1336 | // of the upper/parent. | ||||||||||||
1337 | // --> <fnRect> = fnRectVert | ||||||||||||
1338 | // in horizontal layout the other way around | ||||||||||||
1339 | // --> <fnRect> = fnRectHori | ||||||||||||
1340 | //SwRectFn fnRect = IsVertical() ? fnRectHori : fnRectVert; | ||||||||||||
1341 | SwRectFn fnRect; | ||||||||||||
1342 | if ( IsHeaderFrame() || IsFooterFrame() ) | ||||||||||||
1343 | fnRect = fnRectHori; | ||||||||||||
1344 | else if ( IsCellFrame() || IsColumnFrame() ) | ||||||||||||
1345 | fnRect = GetUpper()->IsVertical() ? fnRectHori : ( GetUpper()->IsVertLR() ? (GetUpper()->IsVertLRBT() ? fnRectVertL2RB2T : fnRectVertL2R) : fnRectVert ); | ||||||||||||
1346 | else | ||||||||||||
1347 | fnRect = GetUpper()->IsVertical() ? ( GetUpper()->IsVertLR() ? (GetUpper()->IsVertLRBT() ? fnRectVertL2RB2T : fnRectVertL2R) : fnRectVert ) : fnRectHori; | ||||||||||||
1348 | |||||||||||||
1349 | if( (getFrameArea().*fnRect->fnGetWidth)() != (pParent->getFramePrintArea().*fnRect->fnGetWidth)()) | ||||||||||||
1350 | InvalidateSize_(); | ||||||||||||
1351 | InvalidatePos_(); | ||||||||||||
1352 | const SwPageFrame *pPage = FindPageFrame(); | ||||||||||||
1353 | InvalidatePage( pPage ); | ||||||||||||
1354 | if( !IsColumnFrame() ) | ||||||||||||
1355 | { | ||||||||||||
1356 | SwFrame *pFrame = GetIndNext(); | ||||||||||||
1357 | if( nullptr != pFrame ) | ||||||||||||
1358 | { | ||||||||||||
1359 | pFrame->InvalidatePos_(); | ||||||||||||
1360 | if( IsInFootnote() ) | ||||||||||||
1361 | { | ||||||||||||
1362 | if( pFrame->IsSctFrame() ) | ||||||||||||
1363 | pFrame = static_cast<SwSectionFrame*>(pFrame)->ContainsAny(); | ||||||||||||
1364 | if( pFrame ) | ||||||||||||
1365 | pFrame->Prepare( PrepareHint::ErgoSum, nullptr, false ); | ||||||||||||
1366 | } | ||||||||||||
1367 | } | ||||||||||||
1368 | if ( IsInFootnote() && nullptr != ( pFrame = GetIndPrev() ) ) | ||||||||||||
1369 | { | ||||||||||||
1370 | if( pFrame->IsSctFrame() ) | ||||||||||||
1371 | pFrame = static_cast<SwSectionFrame*>(pFrame)->ContainsAny(); | ||||||||||||
1372 | if( pFrame ) | ||||||||||||
1373 | pFrame->Prepare( PrepareHint::QuoVadis, nullptr, false ); | ||||||||||||
1374 | } | ||||||||||||
1375 | } | ||||||||||||
1376 | |||||||||||||
1377 | if( !(getFrameArea().*fnRect->fnGetHeight)() ) | ||||||||||||
1378 | return; | ||||||||||||
1379 | |||||||||||||
1380 | // AdjustNeighbourhood is now also called in columns which are not | ||||||||||||
1381 | // placed inside a frame | ||||||||||||
1382 | SwNeighbourAdjust nAdjust = GetUpper()->IsFootnoteBossFrame() ? | ||||||||||||
1383 | static_cast<SwFootnoteBossFrame*>(GetUpper())->NeighbourhoodAdjustment() | ||||||||||||
1384 | : SwNeighbourAdjust::GrowShrink; | ||||||||||||
1385 | SwTwips nGrow = (getFrameArea().*fnRect->fnGetHeight)(); | ||||||||||||
1386 | if( SwNeighbourAdjust::OnlyAdjust == nAdjust ) | ||||||||||||
1387 | AdjustNeighbourhood( nGrow ); | ||||||||||||
1388 | else | ||||||||||||
1389 | { | ||||||||||||
1390 | SwTwips nReal = 0; | ||||||||||||
1391 | if( SwNeighbourAdjust::AdjustGrow == nAdjust ) | ||||||||||||
1392 | nReal = AdjustNeighbourhood( nGrow ); | ||||||||||||
1393 | if( nReal < nGrow ) | ||||||||||||
1394 | nReal += pParent->Grow( nGrow - nReal ); | ||||||||||||
1395 | if( SwNeighbourAdjust::GrowAdjust == nAdjust && nReal < nGrow ) | ||||||||||||
1396 | AdjustNeighbourhood( nGrow - nReal ); | ||||||||||||
1397 | } | ||||||||||||
1398 | } | ||||||||||||
1399 | |||||||||||||
1400 | void SwLayoutFrame::Cut() | ||||||||||||
1401 | { | ||||||||||||
1402 | if ( GetNext() ) | ||||||||||||
1403 | GetNext()->InvalidatePos_(); | ||||||||||||
1404 | |||||||||||||
1405 | SwRectFnSet aRectFnSet(this); | ||||||||||||
1406 | SwTwips nShrink = aRectFnSet.GetHeight(getFrameArea()); | ||||||||||||
1407 | |||||||||||||
1408 | // Remove first, then shrink upper. | ||||||||||||
1409 | SwLayoutFrame *pUp = GetUpper(); | ||||||||||||
1410 | |||||||||||||
1411 | // AdjustNeighbourhood is now also called in columns which are not | ||||||||||||
1412 | // placed inside a frame. | ||||||||||||
1413 | |||||||||||||
1414 | // Remove must not be called before an AdjustNeighbourhood, but it has to | ||||||||||||
1415 | // be called before the upper-shrink-call, if the upper-shrink takes care | ||||||||||||
1416 | // of its content. | ||||||||||||
1417 | if ( pUp && nShrink ) | ||||||||||||
1418 | { | ||||||||||||
1419 | if( pUp->IsFootnoteBossFrame() ) | ||||||||||||
1420 | { | ||||||||||||
1421 | SwNeighbourAdjust nAdjust= static_cast<SwFootnoteBossFrame*>(pUp)->NeighbourhoodAdjustment(); | ||||||||||||
1422 | if( SwNeighbourAdjust::OnlyAdjust == nAdjust ) | ||||||||||||
1423 | AdjustNeighbourhood( -nShrink ); | ||||||||||||
1424 | else | ||||||||||||
1425 | { | ||||||||||||
1426 | SwTwips nReal = 0; | ||||||||||||
1427 | if( SwNeighbourAdjust::AdjustGrow == nAdjust ) | ||||||||||||
1428 | nReal = -AdjustNeighbourhood( -nShrink ); | ||||||||||||
1429 | if( nReal < nShrink ) | ||||||||||||
1430 | { | ||||||||||||
1431 | const SwTwips nOldHeight = aRectFnSet.GetHeight(getFrameArea()); | ||||||||||||
1432 | |||||||||||||
1433 | // seems as if this needs to be forwarded to the SwFrame already here, | ||||||||||||
1434 | // changing to zero seems temporary anyways | ||||||||||||
1435 | { | ||||||||||||
1436 | SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this); | ||||||||||||
1437 | aRectFnSet.SetHeight( aFrm, 0 ); | ||||||||||||
1438 | } | ||||||||||||
1439 | |||||||||||||
1440 | nReal += pUp->Shrink( nShrink - nReal ); | ||||||||||||
1441 | |||||||||||||
1442 | { | ||||||||||||
1443 | SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this); | ||||||||||||
1444 | aRectFnSet.SetHeight( aFrm, nOldHeight ); | ||||||||||||
1445 | } | ||||||||||||
1446 | } | ||||||||||||
1447 | |||||||||||||
1448 | if( SwNeighbourAdjust::GrowAdjust == nAdjust && nReal < nShrink ) | ||||||||||||
1449 | AdjustNeighbourhood( nReal - nShrink ); | ||||||||||||
1450 | } | ||||||||||||
1451 | RemoveFromLayout(); | ||||||||||||
1452 | } | ||||||||||||
1453 | else | ||||||||||||
1454 | { | ||||||||||||
1455 | RemoveFromLayout(); | ||||||||||||
1456 | pUp->Shrink( nShrink ); | ||||||||||||
1457 | } | ||||||||||||
1458 | } | ||||||||||||
1459 | else | ||||||||||||
1460 | RemoveFromLayout(); | ||||||||||||
1461 | |||||||||||||
1462 | if( pUp && !pUp->Lower() ) | ||||||||||||
1463 | { | ||||||||||||
1464 | pUp->SetCompletePaint(); | ||||||||||||
1465 | pUp->InvalidatePage(); | ||||||||||||
1466 | } | ||||||||||||
1467 | } | ||||||||||||
1468 | |||||||||||||
1469 | SwTwips SwFrame::Grow( SwTwips nDist, bool bTst, bool bInfo ) | ||||||||||||
1470 | { | ||||||||||||
1471 | OSL_ENSURE( nDist >= 0, "Negative growth?" )do { if (true && (!(nDist >= 0))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" ":" "1471" ": "), "%s", "Negative growth?"); } } while (false ); | ||||||||||||
1472 | |||||||||||||
1473 | PROTOCOL_ENTER( this, bTst ? PROT::GrowTest : PROT::Grow, DbgAction::NONE, &nDist ) | ||||||||||||
1474 | |||||||||||||
1475 | if ( nDist ) | ||||||||||||
1476 | { | ||||||||||||
1477 | SwRectFnSet aRectFnSet(this); | ||||||||||||
1478 | |||||||||||||
1479 | SwTwips nPrtHeight = aRectFnSet.GetHeight(getFramePrintArea()); | ||||||||||||
1480 | if( nPrtHeight > 0 && nDist > (LONG_MAX9223372036854775807L - nPrtHeight) ) | ||||||||||||
1481 | nDist = LONG_MAX9223372036854775807L - nPrtHeight; | ||||||||||||
1482 | |||||||||||||
1483 | if ( IsFlyFrame() ) | ||||||||||||
1484 | return static_cast<SwFlyFrame*>(this)->Grow_( nDist, bTst ); | ||||||||||||
1485 | else if( IsSctFrame() ) | ||||||||||||
1486 | return static_cast<SwSectionFrame*>(this)->Grow_( nDist, bTst ); | ||||||||||||
1487 | else | ||||||||||||
1488 | { | ||||||||||||
1489 | const SwCellFrame* pThisCell = dynamic_cast<const SwCellFrame*>(this); | ||||||||||||
1490 | if ( pThisCell ) | ||||||||||||
1491 | { | ||||||||||||
1492 | const SwTabFrame* pTab = FindTabFrame(); | ||||||||||||
1493 | |||||||||||||
1494 | // NEW TABLES | ||||||||||||
1495 | if ( pTab->IsVertical() != IsVertical() || | ||||||||||||
1496 | pThisCell->GetLayoutRowSpan() < 1 ) | ||||||||||||
1497 | return 0; | ||||||||||||
1498 | } | ||||||||||||
1499 | |||||||||||||
1500 | const SwTwips nReal = GrowFrame( nDist, bTst, bInfo ); | ||||||||||||
1501 | if( !bTst ) | ||||||||||||
1502 | { | ||||||||||||
1503 | nPrtHeight = aRectFnSet.GetHeight(getFramePrintArea()); | ||||||||||||
1504 | |||||||||||||
1505 | SwFrameAreaDefinition::FramePrintAreaWriteAccess aPrt(*this); | ||||||||||||
1506 | aRectFnSet.SetHeight( aPrt, nPrtHeight + ( IsContentFrame() ? nDist : nReal ) ); | ||||||||||||
1507 | } | ||||||||||||
1508 | return nReal; | ||||||||||||
1509 | } | ||||||||||||
1510 | } | ||||||||||||
1511 | return 0; | ||||||||||||
1512 | } | ||||||||||||
1513 | |||||||||||||
1514 | SwTwips SwFrame::Shrink( SwTwips nDist, bool bTst, bool bInfo ) | ||||||||||||
1515 | { | ||||||||||||
1516 | OSL_ENSURE( nDist >= 0, "Negative reduction?" )do { if (true && (!(nDist >= 0))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" ":" "1516" ": "), "%s", "Negative reduction?"); } } while (false ); | ||||||||||||
1517 | |||||||||||||
1518 | PROTOCOL_ENTER( this, bTst ? PROT::ShrinkTest : PROT::Shrink, DbgAction::NONE, &nDist ) | ||||||||||||
1519 | |||||||||||||
1520 | if ( nDist ) | ||||||||||||
1521 | { | ||||||||||||
1522 | if ( IsFlyFrame() ) | ||||||||||||
1523 | return static_cast<SwFlyFrame*>(this)->Shrink_( nDist, bTst ); | ||||||||||||
1524 | else if( IsSctFrame() ) | ||||||||||||
1525 | return static_cast<SwSectionFrame*>(this)->Shrink_( nDist, bTst ); | ||||||||||||
1526 | else | ||||||||||||
1527 | { | ||||||||||||
1528 | const SwCellFrame* pThisCell = dynamic_cast<const SwCellFrame*>(this); | ||||||||||||
1529 | if ( pThisCell ) | ||||||||||||
1530 | { | ||||||||||||
1531 | const SwTabFrame* pTab = FindTabFrame(); | ||||||||||||
1532 | |||||||||||||
1533 | // NEW TABLES | ||||||||||||
1534 | if ( (pTab && pTab->IsVertical() != IsVertical()) || | ||||||||||||
1535 | pThisCell->GetLayoutRowSpan() < 1 ) | ||||||||||||
1536 | return 0; | ||||||||||||
1537 | } | ||||||||||||
1538 | |||||||||||||
1539 | SwRectFnSet aRectFnSet(this); | ||||||||||||
1540 | SwTwips nReal = aRectFnSet.GetHeight(getFrameArea()); | ||||||||||||
1541 | ShrinkFrame( nDist, bTst, bInfo ); | ||||||||||||
1542 | nReal -= aRectFnSet.GetHeight(getFrameArea()); | ||||||||||||
1543 | if( !bTst ) | ||||||||||||
1544 | { | ||||||||||||
1545 | const SwTwips nPrtHeight = aRectFnSet.GetHeight(getFramePrintArea()); | ||||||||||||
1546 | SwFrameAreaDefinition::FramePrintAreaWriteAccess aPrt(*this); | ||||||||||||
1547 | aRectFnSet.SetHeight( aPrt, nPrtHeight - ( IsContentFrame() ? nDist : nReal ) ); | ||||||||||||
1548 | } | ||||||||||||
1549 | return nReal; | ||||||||||||
1550 | } | ||||||||||||
1551 | } | ||||||||||||
1552 | return 0; | ||||||||||||
1553 | } | ||||||||||||
1554 | |||||||||||||
1555 | /** Adjust surrounding neighbourhood after insertion | ||||||||||||
1556 | * | ||||||||||||
1557 | * A Frame needs "normalization" if it is directly placed below a footnote boss (page/column) and its | ||||||||||||
1558 | * size changes. There is always a frame that takes the maximum possible space (the frame that | ||||||||||||
1559 | * contains the Body text) and zero or more frames which only take the space needed (header/footer | ||||||||||||
1560 | * area, footnote container). If one of these frames changes, the body-text-frame has to grow or | ||||||||||||
1561 | * shrink accordingly, even though it's fixed. | ||||||||||||
1562 | * | ||||||||||||
1563 | * !! Is it possible to do this in a generic way and not restrict it to the page and a distinct | ||||||||||||
1564 | * frame which takes the maximum space (controlled using the FrameSize attribute)? | ||||||||||||
1565 | * Problems: | ||||||||||||
1566 | * - What if multiple frames taking the maximum space are placed next to each other? | ||||||||||||
1567 | * - How is the maximum space calculated? | ||||||||||||
1568 | * - How small can those frames become? | ||||||||||||
1569 | * | ||||||||||||
1570 | * In any case, only a certain amount of space is allowed, so we never go below a minimum value for | ||||||||||||
1571 | * the height of the body. | ||||||||||||
1572 | * | ||||||||||||
1573 | * @param nDiff the value around which the space has to be allocated | ||||||||||||
1574 | */ | ||||||||||||
1575 | SwTwips SwFrame::AdjustNeighbourhood( SwTwips nDiff, bool bTst ) | ||||||||||||
1576 | { | ||||||||||||
1577 | PROTOCOL_ENTER( this, PROT::AdjustN, DbgAction::NONE, &nDiff ); | ||||||||||||
1578 | |||||||||||||
1579 | if ( !nDiff || !GetUpper()->IsFootnoteBossFrame() ) // only inside pages/columns | ||||||||||||
1580 | return 0; | ||||||||||||
1581 | |||||||||||||
1582 | const SwViewShell *pSh = getRootFrame()->GetCurrShell(); | ||||||||||||
1583 | const bool bBrowse = pSh && pSh->GetViewOptions()->getBrowseMode(); | ||||||||||||
1584 | |||||||||||||
1585 | //The (Page-)Body only changes in BrowseMode, but only if it does not | ||||||||||||
1586 | //contain columns. | ||||||||||||
1587 | if ( IsPageBodyFrame() && (!bBrowse || | ||||||||||||
1588 | (static_cast<SwLayoutFrame*>(this)->Lower() && | ||||||||||||
1589 | static_cast<SwLayoutFrame*>(this)->Lower()->IsColumnFrame())) ) | ||||||||||||
1590 | return 0; | ||||||||||||
1591 | |||||||||||||
1592 | //In BrowseView mode the PageFrame can handle some of the requests. | ||||||||||||
1593 | long nBrowseAdd = 0; | ||||||||||||
1594 | if ( bBrowse && GetUpper()->IsPageFrame() ) // only (Page-)BodyFrames | ||||||||||||
1595 | { | ||||||||||||
1596 | SwViewShell *pViewShell = getRootFrame()->GetCurrShell(); | ||||||||||||
1597 | SwLayoutFrame *pUp = GetUpper(); | ||||||||||||
1598 | long nChg; | ||||||||||||
1599 | const long nUpPrtBottom = pUp->getFrameArea().Height() - | ||||||||||||
1600 | pUp->getFramePrintArea().Height() - pUp->getFramePrintArea().Top(); | ||||||||||||
1601 | SwRect aInva( pUp->getFrameArea() ); | ||||||||||||
1602 | if ( pViewShell ) | ||||||||||||
1603 | { | ||||||||||||
1604 | aInva.Pos().setX( pViewShell->VisArea().Left() ); | ||||||||||||
1605 | aInva.Width( pViewShell->VisArea().Width() ); | ||||||||||||
1606 | } | ||||||||||||
1607 | if ( nDiff > 0 ) | ||||||||||||
1608 | { | ||||||||||||
1609 | nChg = BROWSE_HEIGHT(56700L * 10L) - pUp->getFrameArea().Height(); | ||||||||||||
1610 | nChg = std::min( nDiff, nChg ); | ||||||||||||
1611 | |||||||||||||
1612 | if ( !IsBodyFrame() ) | ||||||||||||
1613 | { | ||||||||||||
1614 | SetCompletePaint(); | ||||||||||||
1615 | if ( !pViewShell || pViewShell->VisArea().Height() >= pUp->getFrameArea().Height() ) | ||||||||||||
1616 | { | ||||||||||||
1617 | //First minimize Body, it will grow again later. | ||||||||||||
1618 | SwFrame *pBody = static_cast<SwFootnoteBossFrame*>(pUp)->FindBodyCont(); | ||||||||||||
1619 | const long nTmp = nChg - pBody->getFramePrintArea().Height(); | ||||||||||||
1620 | if ( !bTst ) | ||||||||||||
1621 | { | ||||||||||||
1622 | { | ||||||||||||
1623 | SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*pBody); | ||||||||||||
1624 | aFrm.Height(std::max( 0L, aFrm.Height() - nChg )); | ||||||||||||
1625 | } | ||||||||||||
1626 | |||||||||||||
1627 | pBody->InvalidatePrt_(); | ||||||||||||
1628 | pBody->InvalidateSize_(); | ||||||||||||
1629 | if ( pBody->GetNext() ) | ||||||||||||
1630 | pBody->GetNext()->InvalidatePos_(); | ||||||||||||
1631 | if ( !IsHeaderFrame() ) | ||||||||||||
1632 | pBody->SetCompletePaint(); | ||||||||||||
1633 | } | ||||||||||||
1634 | nChg = nTmp <= 0 ? 0 : nTmp; | ||||||||||||
1635 | } | ||||||||||||
1636 | } | ||||||||||||
1637 | |||||||||||||
1638 | const long nTmp = nUpPrtBottom + 20; | ||||||||||||
1639 | aInva.Top( aInva.Bottom() - nTmp ); | ||||||||||||
1640 | aInva.Height( nChg + nTmp ); | ||||||||||||
1641 | } | ||||||||||||
1642 | else | ||||||||||||
1643 | { | ||||||||||||
1644 | //The page can shrink to 0. The first page keeps the same size like | ||||||||||||
1645 | //VisArea. | ||||||||||||
1646 | nChg = nDiff; | ||||||||||||
1647 | long nInvaAdd = 0; | ||||||||||||
1648 | if ( pViewShell && !pUp->GetPrev() && | ||||||||||||
1649 | pUp->getFrameArea().Height() + nDiff < pViewShell->VisArea().Height() ) | ||||||||||||
1650 | { | ||||||||||||
1651 | // This means that we have to invalidate adequately. | ||||||||||||
1652 | nChg = pViewShell->VisArea().Height() - pUp->getFrameArea().Height(); | ||||||||||||
1653 | nInvaAdd = -(nDiff - nChg); | ||||||||||||
1654 | } | ||||||||||||
1655 | |||||||||||||
1656 | //Invalidate including bottom border. | ||||||||||||
1657 | long nBorder = nUpPrtBottom + 20; | ||||||||||||
1658 | nBorder -= nChg; | ||||||||||||
1659 | aInva.Top( aInva.Bottom() - (nBorder+nInvaAdd) ); | ||||||||||||
1660 | if ( !IsBodyFrame() ) | ||||||||||||
1661 | { | ||||||||||||
1662 | SetCompletePaint(); | ||||||||||||
1663 | if ( !IsHeaderFrame() ) | ||||||||||||
1664 | static_cast<SwFootnoteBossFrame*>(pUp)->FindBodyCont()->SetCompletePaint(); | ||||||||||||
1665 | } | ||||||||||||
1666 | //Invalidate the page because of the frames. Thereby the page becomes | ||||||||||||
1667 | //the right size again if a frame didn't fit. This only works | ||||||||||||
1668 | //randomly for paragraph bound frames otherwise (NotifyFlys). | ||||||||||||
1669 | pUp->InvalidateSize(); | ||||||||||||
1670 | } | ||||||||||||
1671 | if ( !bTst ) | ||||||||||||
1672 | { | ||||||||||||
1673 | //Independent from nChg | ||||||||||||
1674 | if ( pViewShell && aInva.HasArea() && pUp->GetUpper() ) | ||||||||||||
1675 | pViewShell->InvalidateWindows( aInva ); | ||||||||||||
1676 | } | ||||||||||||
1677 | if ( !bTst && nChg ) | ||||||||||||
1678 | { | ||||||||||||
1679 | { | ||||||||||||
1680 | SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*pUp); | ||||||||||||
1681 | aFrm.AddHeight(nChg ); | ||||||||||||
1682 | } | ||||||||||||
1683 | |||||||||||||
1684 | { | ||||||||||||
1685 | SwFrameAreaDefinition::FramePrintAreaWriteAccess aPrt(*pUp); | ||||||||||||
1686 | aPrt.AddHeight(nChg ); | ||||||||||||
1687 | } | ||||||||||||
1688 | |||||||||||||
1689 | if ( pViewShell ) | ||||||||||||
1690 | pViewShell->Imp()->SetFirstVisPageInvalid(); | ||||||||||||
1691 | |||||||||||||
1692 | if ( GetNext() ) | ||||||||||||
1693 | GetNext()->InvalidatePos_(); | ||||||||||||
1694 | |||||||||||||
1695 | //Trigger a repaint if necessary. | ||||||||||||
1696 | std::unique_ptr<SvxBrushItem> aBack(pUp->GetFormat()->makeBackgroundBrushItem()); | ||||||||||||
1697 | const SvxGraphicPosition ePos = aBack ? aBack->GetGraphicPos() : GPOS_NONE; | ||||||||||||
1698 | if ( ePos != GPOS_NONE && ePos != GPOS_TILED ) | ||||||||||||
1699 | pViewShell->InvalidateWindows( pUp->getFrameArea() ); | ||||||||||||
1700 | |||||||||||||
1701 | if ( pUp->GetUpper() ) | ||||||||||||
1702 | { | ||||||||||||
1703 | if ( pUp->GetNext() ) | ||||||||||||
1704 | pUp->GetNext()->InvalidatePos(); | ||||||||||||
1705 | |||||||||||||
1706 | //Sad but true: during notify on ViewImp a Calc on the page and | ||||||||||||
1707 | //its Lower may be called. The values should not be changed | ||||||||||||
1708 | //because the caller takes care of the adjustment of Frame and | ||||||||||||
1709 | //Prt. | ||||||||||||
1710 | const long nOldFrameHeight = getFrameArea().Height(); | ||||||||||||
1711 | const long nOldPrtHeight = getFramePrintArea().Height(); | ||||||||||||
1712 | const bool bOldComplete = IsCompletePaint(); | ||||||||||||
1713 | |||||||||||||
1714 | if ( IsBodyFrame() ) | ||||||||||||
1715 | { | ||||||||||||
1716 | SwFrameAreaDefinition::FramePrintAreaWriteAccess aPrt(*this); | ||||||||||||
1717 | aPrt.Height( nOldFrameHeight ); | ||||||||||||
1718 | } | ||||||||||||
1719 | |||||||||||||
1720 | if ( pUp->GetUpper() ) | ||||||||||||
1721 | { | ||||||||||||
1722 | static_cast<SwRootFrame*>(pUp->GetUpper())->CheckViewLayout( nullptr, nullptr ); | ||||||||||||
1723 | } | ||||||||||||
1724 | |||||||||||||
1725 | SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this); | ||||||||||||
1726 | aFrm.Height( nOldFrameHeight ); | ||||||||||||
1727 | |||||||||||||
1728 | SwFrameAreaDefinition::FramePrintAreaWriteAccess aPrt(*this); | ||||||||||||
1729 | aPrt.Height( nOldPrtHeight ); | ||||||||||||
1730 | |||||||||||||
1731 | mbCompletePaint = bOldComplete; | ||||||||||||
1732 | } | ||||||||||||
1733 | if ( !IsBodyFrame() ) | ||||||||||||
1734 | pUp->InvalidateSize_(); | ||||||||||||
1735 | InvalidatePage( static_cast<SwPageFrame*>(pUp) ); | ||||||||||||
1736 | } | ||||||||||||
1737 | nDiff -= nChg; | ||||||||||||
1738 | if ( !nDiff ) | ||||||||||||
1739 | return nChg; | ||||||||||||
1740 | else | ||||||||||||
1741 | nBrowseAdd = nChg; | ||||||||||||
1742 | } | ||||||||||||
1743 | |||||||||||||
1744 | const SwFootnoteBossFrame *pBoss = static_cast<SwFootnoteBossFrame*>(GetUpper()); | ||||||||||||
1745 | |||||||||||||
1746 | SwTwips nReal = 0, | ||||||||||||
1747 | nAdd = 0; | ||||||||||||
1748 | SwFrame *pFrame = nullptr; | ||||||||||||
1749 | SwRectFnSet aRectFnSet(this); | ||||||||||||
1750 | |||||||||||||
1751 | if( IsBodyFrame() ) | ||||||||||||
1752 | { | ||||||||||||
1753 | if( IsInSct() ) | ||||||||||||
1754 | { | ||||||||||||
1755 | SwSectionFrame *pSect = FindSctFrame(); | ||||||||||||
1756 | if( nDiff > 0 && pSect->IsEndnAtEnd() && GetNext() && | ||||||||||||
1757 | GetNext()->IsFootnoteContFrame() ) | ||||||||||||
1758 | { | ||||||||||||
1759 | SwFootnoteContFrame* pCont = static_cast<SwFootnoteContFrame*>(GetNext()); | ||||||||||||
1760 | SwTwips nMinH = 0; | ||||||||||||
1761 | SwFootnoteFrame* pFootnote = static_cast<SwFootnoteFrame*>(pCont->Lower()); | ||||||||||||
1762 | bool bFootnote = false; | ||||||||||||
1763 | while( pFootnote ) | ||||||||||||
1764 | { | ||||||||||||
1765 | if( !pFootnote->GetAttr()->GetFootnote().IsEndNote() ) | ||||||||||||
1766 | { | ||||||||||||
1767 | nMinH += aRectFnSet.GetHeight(pFootnote->getFrameArea()); | ||||||||||||
1768 | bFootnote = true; | ||||||||||||
1769 | } | ||||||||||||
1770 | pFootnote = static_cast<SwFootnoteFrame*>(pFootnote->GetNext()); | ||||||||||||
1771 | } | ||||||||||||
1772 | if( bFootnote ) | ||||||||||||
1773 | nMinH += aRectFnSet.GetTop(pCont->getFramePrintArea()); | ||||||||||||
1774 | nReal = aRectFnSet.GetHeight(pCont->getFrameArea()) - nMinH; | ||||||||||||
1775 | if( nReal > nDiff ) | ||||||||||||
1776 | nReal = nDiff; | ||||||||||||
1777 | if( nReal > 0 ) | ||||||||||||
1778 | pFrame = GetNext(); | ||||||||||||
1779 | else | ||||||||||||
1780 | nReal = 0; | ||||||||||||
1781 | } | ||||||||||||
1782 | if( !bTst && !pSect->IsColLocked() ) | ||||||||||||
1783 | pSect->InvalidateSize(); | ||||||||||||
1784 | } | ||||||||||||
1785 | if( !pFrame ) | ||||||||||||
1786 | return nBrowseAdd; | ||||||||||||
1787 | } | ||||||||||||
1788 | else | ||||||||||||
1789 | { | ||||||||||||
1790 | const bool bFootnotePage = pBoss->IsPageFrame() && static_cast<const SwPageFrame*>(pBoss)->IsFootnotePage(); | ||||||||||||
1791 | if ( bFootnotePage && !IsFootnoteContFrame() ) | ||||||||||||
1792 | pFrame = const_cast<SwFrame*>(static_cast<SwFrame const *>(pBoss->FindFootnoteCont())); | ||||||||||||
1793 | if ( !pFrame ) | ||||||||||||
1794 | pFrame = const_cast<SwFrame*>(static_cast<SwFrame const *>(pBoss->FindBodyCont())); | ||||||||||||
1795 | |||||||||||||
1796 | if ( !pFrame ) | ||||||||||||
1797 | return 0; | ||||||||||||
1798 | |||||||||||||
1799 | //If not one is found, everything else is solved. | ||||||||||||
1800 | nReal = aRectFnSet.GetHeight(pFrame->getFrameArea()); | ||||||||||||
1801 | if( nReal > nDiff ) | ||||||||||||
1802 | nReal = nDiff; | ||||||||||||
1803 | if( !bFootnotePage ) | ||||||||||||
1804 | { | ||||||||||||
1805 | //Respect the minimal boundary! | ||||||||||||
1806 | if( nReal ) | ||||||||||||
1807 | { | ||||||||||||
1808 | const SwTwips nMax = pBoss->GetVarSpace(); | ||||||||||||
1809 | if ( nReal > nMax ) | ||||||||||||
1810 | nReal = nMax; | ||||||||||||
1811 | } | ||||||||||||
1812 | if( !IsFootnoteContFrame() && nDiff > nReal && | ||||||||||||
1813 | pFrame->GetNext() && pFrame->GetNext()->IsFootnoteContFrame() | ||||||||||||
1814 | && ( pFrame->GetNext()->IsVertical() == IsVertical() ) | ||||||||||||
1815 | ) | ||||||||||||
1816 | { | ||||||||||||
1817 | //If the Body doesn't return enough, we look for a footnote, if | ||||||||||||
1818 | //there is one, we steal there accordingly. | ||||||||||||
1819 | const SwTwips nAddMax = aRectFnSet.GetHeight(pFrame->GetNext()->getFrameArea()); | ||||||||||||
1820 | nAdd = nDiff - nReal; | ||||||||||||
1821 | if ( nAdd > nAddMax ) | ||||||||||||
1822 | nAdd = nAddMax; | ||||||||||||
1823 | if ( !bTst ) | ||||||||||||
1824 | { | ||||||||||||
1825 | { | ||||||||||||
1826 | SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*pFrame->GetNext()); | ||||||||||||
1827 | aRectFnSet.SetHeight(aFrm, nAddMax-nAdd); | ||||||||||||
1828 | |||||||||||||
1829 | if( aRectFnSet.IsVert() && !aRectFnSet.IsVertL2R() ) | ||||||||||||
1830 | { | ||||||||||||
1831 | aFrm.Pos().AdjustX(nAdd ); | ||||||||||||
1832 | } | ||||||||||||
1833 | } | ||||||||||||
1834 | |||||||||||||
1835 | pFrame->GetNext()->InvalidatePrt(); | ||||||||||||
1836 | |||||||||||||
1837 | if ( pFrame->GetNext()->GetNext() ) | ||||||||||||
1838 | { | ||||||||||||
1839 | pFrame->GetNext()->GetNext()->InvalidatePos_(); | ||||||||||||
1840 | } | ||||||||||||
1841 | } | ||||||||||||
1842 | } | ||||||||||||
1843 | } | ||||||||||||
1844 | } | ||||||||||||
1845 | |||||||||||||
1846 | if ( !bTst && nReal ) | ||||||||||||
1847 | { | ||||||||||||
1848 | SwTwips nTmp = aRectFnSet.GetHeight(pFrame->getFrameArea()); | ||||||||||||
1849 | |||||||||||||
1850 | { | ||||||||||||
1851 | SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*pFrame); | ||||||||||||
1852 | aRectFnSet.SetHeight( aFrm, nTmp - nReal ); | ||||||||||||
1853 | |||||||||||||
1854 | if( aRectFnSet.IsVert() && !aRectFnSet.IsVertL2R() ) | ||||||||||||
1855 | { | ||||||||||||
1856 | aFrm.Pos().AdjustX(nReal ); | ||||||||||||
1857 | } | ||||||||||||
1858 | } | ||||||||||||
1859 | |||||||||||||
1860 | pFrame->InvalidatePrt(); | ||||||||||||
1861 | |||||||||||||
1862 | if ( pFrame->GetNext() ) | ||||||||||||
1863 | pFrame->GetNext()->InvalidatePos_(); | ||||||||||||
1864 | |||||||||||||
1865 | if( nReal < 0 && pFrame->IsInSct() ) | ||||||||||||
1866 | { | ||||||||||||
1867 | SwLayoutFrame* pUp = pFrame->GetUpper(); | ||||||||||||
1868 | if( pUp && nullptr != ( pUp = pUp->GetUpper() ) && pUp->IsSctFrame() && | ||||||||||||
1869 | !pUp->IsColLocked() ) | ||||||||||||
1870 | pUp->InvalidateSize(); | ||||||||||||
1871 | } | ||||||||||||
1872 | if( ( IsHeaderFrame() || IsFooterFrame() ) && pBoss->GetDrawObjs() ) | ||||||||||||
1873 | { | ||||||||||||
1874 | const SwSortedObjs &rObjs = *pBoss->GetDrawObjs(); | ||||||||||||
1875 | OSL_ENSURE( pBoss->IsPageFrame(), "Header/Footer out of page?" )do { if (true && (!(pBoss->IsPageFrame()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" ":" "1875" ": "), "%s", "Header/Footer out of page?"); } } while (false); | ||||||||||||
1876 | for (SwAnchoredObject* pAnchoredObj : rObjs) | ||||||||||||
1877 | { | ||||||||||||
1878 | if ( dynamic_cast< const SwFlyFrame *>( pAnchoredObj ) != nullptr ) | ||||||||||||
1879 | { | ||||||||||||
1880 | SwFlyFrame* pFly = static_cast<SwFlyFrame*>(pAnchoredObj); | ||||||||||||
1881 | OSL_ENSURE( !pFly->IsFlyInContentFrame(), "FlyInCnt at Page?" )do { if (true && (!(!pFly->IsFlyInContentFrame())) ) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl" ), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" ":" "1881" ": "), "%s", "FlyInCnt at Page?"); } } while (false ); | ||||||||||||
1882 | const SwFormatVertOrient &rVert = | ||||||||||||
1883 | pFly->GetFormat()->GetVertOrient(); | ||||||||||||
1884 | // When do we have to invalidate? | ||||||||||||
1885 | // If a frame is aligned on a PageTextArea and the header | ||||||||||||
1886 | // changes a TOP, MIDDLE or NONE aligned frame needs to | ||||||||||||
1887 | // recalculate it's position; if the footer changes a BOTTOM | ||||||||||||
1888 | // or MIDDLE aligned frame needs to recalculate it's | ||||||||||||
1889 | // position. | ||||||||||||
1890 | if( ( rVert.GetRelationOrient() == text::RelOrientation::PRINT_AREA || | ||||||||||||
1891 | rVert.GetRelationOrient() == text::RelOrientation::PAGE_PRINT_AREA ) && | ||||||||||||
1892 | ((IsHeaderFrame() && rVert.GetVertOrient()!=text::VertOrientation::BOTTOM) || | ||||||||||||
1893 | (IsFooterFrame() && rVert.GetVertOrient()!=text::VertOrientation::NONE && | ||||||||||||
1894 | rVert.GetVertOrient() != text::VertOrientation::TOP)) ) | ||||||||||||
1895 | { | ||||||||||||
1896 | pFly->InvalidatePos_(); | ||||||||||||
1897 | pFly->Invalidate_(); | ||||||||||||
1898 | } | ||||||||||||
1899 | } | ||||||||||||
1900 | } | ||||||||||||
1901 | } | ||||||||||||
1902 | } | ||||||||||||
1903 | return (nBrowseAdd + nReal + nAdd); | ||||||||||||
1904 | } | ||||||||||||
1905 | |||||||||||||
1906 | /** method to perform additional actions on an invalidation (2004-05-19 #i28701#) */ | ||||||||||||
1907 | void SwFrame::ActionOnInvalidation( const InvalidationType ) | ||||||||||||
1908 | { | ||||||||||||
1909 | // default behaviour is to perform no additional action | ||||||||||||
1910 | } | ||||||||||||
1911 | |||||||||||||
1912 | /** method to determine, if an invalidation is allowed (2004-05-19 #i28701#) */ | ||||||||||||
1913 | bool SwFrame::InvalidationAllowed( const InvalidationType ) const | ||||||||||||
1914 | { | ||||||||||||
1915 | // default behaviour is to allow invalidation | ||||||||||||
1916 | return true; | ||||||||||||
1917 | } | ||||||||||||
1918 | |||||||||||||
1919 | void SwFrame::ImplInvalidateSize() | ||||||||||||
1920 | { | ||||||||||||
1921 | if ( InvalidationAllowed( INVALID_SIZE ) ) | ||||||||||||
1922 | { | ||||||||||||
1923 | setFrameAreaSizeValid(false); | ||||||||||||
1924 | |||||||||||||
1925 | if ( IsFlyFrame() ) | ||||||||||||
1926 | static_cast<SwFlyFrame*>(this)->Invalidate_(); | ||||||||||||
1927 | else | ||||||||||||
1928 | InvalidatePage(); | ||||||||||||
1929 | |||||||||||||
1930 | // OD 2004-05-19 #i28701# | ||||||||||||
1931 | ActionOnInvalidation( INVALID_SIZE ); | ||||||||||||
1932 | } | ||||||||||||
1933 | } | ||||||||||||
1934 | |||||||||||||
1935 | void SwFrame::ImplInvalidatePrt() | ||||||||||||
1936 | { | ||||||||||||
1937 | if ( InvalidationAllowed( INVALID_PRTAREA ) ) | ||||||||||||
1938 | { | ||||||||||||
1939 | setFramePrintAreaValid(false); | ||||||||||||
1940 | |||||||||||||
1941 | if ( IsFlyFrame() ) | ||||||||||||
1942 | static_cast<SwFlyFrame*>(this)->Invalidate_(); | ||||||||||||
1943 | else | ||||||||||||
1944 | InvalidatePage(); | ||||||||||||
1945 | |||||||||||||
1946 | // OD 2004-05-19 #i28701# | ||||||||||||
1947 | ActionOnInvalidation( INVALID_PRTAREA ); | ||||||||||||
1948 | } | ||||||||||||
1949 | } | ||||||||||||
1950 | |||||||||||||
1951 | void SwFrame::ImplInvalidatePos() | ||||||||||||
1952 | { | ||||||||||||
1953 | if ( !InvalidationAllowed( INVALID_POS ) ) | ||||||||||||
1954 | return; | ||||||||||||
1955 | |||||||||||||
1956 | setFrameAreaPositionValid(false); | ||||||||||||
1957 | |||||||||||||
1958 | if ( IsFlyFrame() ) | ||||||||||||
1959 | { | ||||||||||||
1960 | static_cast<SwFlyFrame*>(this)->Invalidate_(); | ||||||||||||
1961 | } | ||||||||||||
1962 | else | ||||||||||||
1963 | { | ||||||||||||
1964 | InvalidatePage(); | ||||||||||||
1965 | } | ||||||||||||
1966 | |||||||||||||
1967 | // OD 2004-05-19 #i28701# | ||||||||||||
1968 | ActionOnInvalidation( INVALID_POS ); | ||||||||||||
1969 | } | ||||||||||||
1970 | |||||||||||||
1971 | void SwFrame::ImplInvalidateLineNum() | ||||||||||||
1972 | { | ||||||||||||
1973 | if ( InvalidationAllowed( INVALID_LINENUM ) ) | ||||||||||||
1974 | { | ||||||||||||
1975 | mbValidLineNum = false; | ||||||||||||
1976 | OSL_ENSURE( IsTextFrame(), "line numbers are implemented for text only" )do { if (true && (!(IsTextFrame()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" ":" "1976" ": "), "%s", "line numbers are implemented for text only" ); } } while (false); | ||||||||||||
1977 | InvalidatePage(); | ||||||||||||
1978 | |||||||||||||
1979 | // OD 2004-05-19 #i28701# | ||||||||||||
1980 | ActionOnInvalidation( INVALID_LINENUM ); | ||||||||||||
1981 | } | ||||||||||||
1982 | } | ||||||||||||
1983 | |||||||||||||
1984 | void SwFrame::ReinitializeFrameSizeAttrFlags() | ||||||||||||
1985 | { | ||||||||||||
1986 | const SwFormatFrameSize &rFormatSize = GetAttrSet()->GetFrameSize(); | ||||||||||||
1987 | if ( SwFrameSize::Variable == rFormatSize.GetHeightSizeType() || | ||||||||||||
1988 | SwFrameSize::Minimum == rFormatSize.GetHeightSizeType()) | ||||||||||||
1989 | { | ||||||||||||
1990 | mbFixSize = false; | ||||||||||||
1991 | if ( GetType() & (SwFrameType::Header | SwFrameType::Footer | SwFrameType::Row) ) | ||||||||||||
1992 | { | ||||||||||||
1993 | SwFrame *pFrame = static_cast<SwLayoutFrame*>(this)->Lower(); | ||||||||||||
1994 | while ( pFrame ) | ||||||||||||
1995 | { pFrame->InvalidateSize_(); | ||||||||||||
1996 | pFrame->InvalidatePrt_(); | ||||||||||||
1997 | pFrame = pFrame->GetNext(); | ||||||||||||
1998 | } | ||||||||||||
1999 | SwContentFrame *pCnt = static_cast<SwLayoutFrame*>(this)->ContainsContent(); | ||||||||||||
2000 | // #i36991# - be save. | ||||||||||||
2001 | // E.g., a row can contain *no* content. | ||||||||||||
2002 | if ( pCnt ) | ||||||||||||
2003 | { | ||||||||||||
2004 | pCnt->InvalidatePage(); | ||||||||||||
2005 | do | ||||||||||||
2006 | { | ||||||||||||
2007 | pCnt->Prepare( PrepareHint::AdjustSizeWithoutFormatting ); | ||||||||||||
2008 | pCnt->InvalidateSize_(); | ||||||||||||
2009 | pCnt = pCnt->GetNextContentFrame(); | ||||||||||||
2010 | } while ( static_cast<SwLayoutFrame*>(this)->IsAnLower( pCnt ) ); | ||||||||||||
2011 | } | ||||||||||||
2012 | } | ||||||||||||
2013 | } | ||||||||||||
2014 | else if ( rFormatSize.GetHeightSizeType() == SwFrameSize::Fixed ) | ||||||||||||
2015 | { | ||||||||||||
2016 | if( IsVertical() ) | ||||||||||||
2017 | ChgSize( Size( rFormatSize.GetWidth(), getFrameArea().Height())); | ||||||||||||
2018 | else | ||||||||||||
2019 | ChgSize( Size( getFrameArea().Width(), rFormatSize.GetHeight())); | ||||||||||||
2020 | } | ||||||||||||
2021 | } | ||||||||||||
2022 | |||||||||||||
2023 | void SwFrame::ValidateThisAndAllLowers( const sal_uInt16 nStage ) | ||||||||||||
2024 | { | ||||||||||||
2025 | // Stage 0: Only validate frames. Do not process any objects. | ||||||||||||
2026 | // Stage 1: Only validate fly frames and all of their contents. | ||||||||||||
2027 | // Stage 2: Validate all. | ||||||||||||
2028 | |||||||||||||
2029 | const bool bOnlyObject = 1 == nStage; | ||||||||||||
2030 | const bool bIncludeObjects = 1 <= nStage; | ||||||||||||
2031 | |||||||||||||
2032 | if ( !bOnlyObject || dynamic_cast< const SwFlyFrame *>( this ) != nullptr ) | ||||||||||||
2033 | { | ||||||||||||
2034 | setFrameAreaSizeValid(true); | ||||||||||||
2035 | setFramePrintAreaValid(true); | ||||||||||||
2036 | setFrameAreaPositionValid(true); | ||||||||||||
2037 | } | ||||||||||||
2038 | |||||||||||||
2039 | if ( bIncludeObjects ) | ||||||||||||
2040 | { | ||||||||||||
2041 | const SwSortedObjs* pObjs = GetDrawObjs(); | ||||||||||||
2042 | if ( pObjs ) | ||||||||||||
2043 | { | ||||||||||||
2044 | const size_t nCnt = pObjs->size(); | ||||||||||||
2045 | for ( size_t i = 0; i < nCnt; ++i ) | ||||||||||||
2046 | { | ||||||||||||
2047 | SwAnchoredObject* pAnchObj = (*pObjs)[i]; | ||||||||||||
2048 | if ( dynamic_cast< const SwFlyFrame *>( pAnchObj ) != nullptr ) | ||||||||||||
2049 | static_cast<SwFlyFrame*>(pAnchObj)->ValidateThisAndAllLowers( 2 ); | ||||||||||||
2050 | else if ( dynamic_cast< const SwAnchoredDrawObject *>( pAnchObj ) != nullptr ) | ||||||||||||
2051 | static_cast<SwAnchoredDrawObject*>(pAnchObj)->ValidateThis(); | ||||||||||||
2052 | } | ||||||||||||
2053 | } | ||||||||||||
2054 | } | ||||||||||||
2055 | |||||||||||||
2056 | if ( IsLayoutFrame() ) | ||||||||||||
2057 | { | ||||||||||||
2058 | SwFrame* pLower = static_cast<SwLayoutFrame*>(this)->Lower(); | ||||||||||||
2059 | while ( pLower ) | ||||||||||||
2060 | { | ||||||||||||
2061 | pLower->ValidateThisAndAllLowers( nStage ); | ||||||||||||
2062 | pLower = pLower->GetNext(); | ||||||||||||
2063 | } | ||||||||||||
2064 | } | ||||||||||||
2065 | } | ||||||||||||
2066 | |||||||||||||
2067 | SwTwips SwContentFrame::GrowFrame( SwTwips nDist, bool bTst, bool bInfo ) | ||||||||||||
2068 | { | ||||||||||||
2069 | SwRectFnSet aRectFnSet(this); | ||||||||||||
2070 | |||||||||||||
2071 | SwTwips nFrameHeight = aRectFnSet.GetHeight(getFrameArea()); | ||||||||||||
2072 | if( nFrameHeight > 0 && | ||||||||||||
2073 | nDist > (LONG_MAX9223372036854775807L - nFrameHeight ) ) | ||||||||||||
2074 | nDist = LONG_MAX9223372036854775807L - nFrameHeight; | ||||||||||||
2075 | |||||||||||||
2076 | const SwViewShell *pSh = getRootFrame()->GetCurrShell(); | ||||||||||||
2077 | const bool bBrowse = pSh && pSh->GetViewOptions()->getBrowseMode(); | ||||||||||||
2078 | SwFrameType nTmpType = SwFrameType::Cell | SwFrameType::Column; | ||||||||||||
2079 | if (bBrowse) | ||||||||||||
2080 | nTmpType |= SwFrameType::Body; | ||||||||||||
2081 | if( !(GetUpper()->GetType() & nTmpType) && GetUpper()->HasFixSize() ) | ||||||||||||
2082 | { | ||||||||||||
2083 | if ( !bTst ) | ||||||||||||
2084 | { | ||||||||||||
2085 | { | ||||||||||||
2086 | SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this); | ||||||||||||
2087 | aRectFnSet.SetHeight( aFrm, nFrameHeight + nDist ); | ||||||||||||
2088 | |||||||||||||
2089 | if( IsVertical() && !IsVertLR() ) | ||||||||||||
2090 | { | ||||||||||||
2091 | aFrm.Pos().AdjustX( -nDist ); | ||||||||||||
2092 | } | ||||||||||||
2093 | } | ||||||||||||
2094 | |||||||||||||
2095 | if ( GetNext() ) | ||||||||||||
2096 | { | ||||||||||||
2097 | GetNext()->InvalidatePos(); | ||||||||||||
2098 | } | ||||||||||||
2099 | // #i28701# - Due to the new object positioning the | ||||||||||||
2100 | // frame on the next page/column can flow backward (e.g. it was moved forward | ||||||||||||
2101 | // due to the positioning of its objects ). Thus, invalivate this next frame, | ||||||||||||
2102 | // if document compatibility option 'Consider wrapping style influence on | ||||||||||||
2103 | // object positioning' is ON. | ||||||||||||
2104 | else if ( GetUpper()->GetFormat()->getIDocumentSettingAccess().get(DocumentSettingId::CONSIDER_WRAP_ON_OBJECT_POSITION) ) | ||||||||||||
2105 | { | ||||||||||||
2106 | InvalidateNextPos(); | ||||||||||||
2107 | } | ||||||||||||
2108 | } | ||||||||||||
2109 | return 0; | ||||||||||||
2110 | } | ||||||||||||
2111 | |||||||||||||
2112 | SwTwips nReal = aRectFnSet.GetHeight(GetUpper()->getFramePrintArea()); | ||||||||||||
2113 | SwFrame *pFrame = GetUpper()->Lower(); | ||||||||||||
2114 | while( pFrame && nReal > 0 ) | ||||||||||||
2115 | { nReal -= aRectFnSet.GetHeight(pFrame->getFrameArea()); | ||||||||||||
2116 | pFrame = pFrame->GetNext(); | ||||||||||||
2117 | } | ||||||||||||
2118 | |||||||||||||
2119 | if ( !bTst ) | ||||||||||||
2120 | { | ||||||||||||
2121 | //Contents are always resized to the wished value. | ||||||||||||
2122 | long nOld = aRectFnSet.GetHeight(getFrameArea()); | ||||||||||||
2123 | |||||||||||||
2124 | { | ||||||||||||
2125 | SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this); | ||||||||||||
2126 | |||||||||||||
2127 | aRectFnSet.SetHeight( aFrm, nOld + nDist ); | ||||||||||||
2128 | |||||||||||||
2129 | if( IsVertical()&& !IsVertLR() ) | ||||||||||||
2130 | { | ||||||||||||
2131 | aFrm.Pos().AdjustX( -nDist ); | ||||||||||||
2132 | } | ||||||||||||
2133 | } | ||||||||||||
2134 | |||||||||||||
2135 | SwTabFrame *pTab = (nOld && IsInTab()) ? FindTabFrame() : nullptr; | ||||||||||||
2136 | if (pTab) | ||||||||||||
2137 | { | ||||||||||||
2138 | if ( pTab->GetTable()->GetHTMLTableLayout() && | ||||||||||||
2139 | !pTab->IsJoinLocked() && | ||||||||||||
2140 | !pTab->GetFormat()->GetDoc()->GetDocShell()->IsReadOnly() ) | ||||||||||||
2141 | { | ||||||||||||
2142 | pTab->InvalidatePos(); | ||||||||||||
2143 | pTab->SetResizeHTMLTable(); | ||||||||||||
2144 | } | ||||||||||||
2145 | } | ||||||||||||
2146 | } | ||||||||||||
2147 | |||||||||||||
2148 | //Only grow Upper if necessary. | ||||||||||||
2149 | if ( nReal < nDist ) | ||||||||||||
2150 | { | ||||||||||||
2151 | if( GetUpper() ) | ||||||||||||
2152 | { | ||||||||||||
2153 | if( bTst || !GetUpper()->IsFooterFrame() ) | ||||||||||||
2154 | nReal = GetUpper()->Grow( nDist - std::max<long>(nReal, 0), | ||||||||||||
2155 | bTst, bInfo ); | ||||||||||||
2156 | else | ||||||||||||
2157 | { | ||||||||||||
2158 | nReal = 0; | ||||||||||||
2159 | GetUpper()->InvalidateSize(); | ||||||||||||
2160 | } | ||||||||||||
2161 | } | ||||||||||||
2162 | else | ||||||||||||
2163 | nReal = 0; | ||||||||||||
2164 | } | ||||||||||||
2165 | else | ||||||||||||
2166 | nReal = nDist; | ||||||||||||
2167 | |||||||||||||
2168 | // #i28701# - Due to the new object positioning the | ||||||||||||
2169 | // frame on the next page/column can flow backward (e.g. it was moved forward | ||||||||||||
2170 | // due to the positioning of its objects ). Thus, invalivate this next frame, | ||||||||||||
2171 | // if document compatibility option 'Consider wrapping style influence on | ||||||||||||
2172 | // object positioning' is ON. | ||||||||||||
2173 | if ( !bTst ) | ||||||||||||
2174 | { | ||||||||||||
2175 | if ( GetNext() ) | ||||||||||||
2176 | { | ||||||||||||
2177 | GetNext()->InvalidatePos(); | ||||||||||||
2178 | } | ||||||||||||
2179 | else if ( GetUpper()->GetFormat()->getIDocumentSettingAccess().get(DocumentSettingId::CONSIDER_WRAP_ON_OBJECT_POSITION) ) | ||||||||||||
2180 | { | ||||||||||||
2181 | InvalidateNextPos(); | ||||||||||||
2182 | } | ||||||||||||
2183 | } | ||||||||||||
2184 | |||||||||||||
2185 | return nReal; | ||||||||||||
2186 | } | ||||||||||||
2187 | |||||||||||||
2188 | SwTwips SwContentFrame::ShrinkFrame( SwTwips nDist, bool bTst, bool bInfo ) | ||||||||||||
2189 | { | ||||||||||||
2190 | SwRectFnSet aRectFnSet(this); | ||||||||||||
2191 | OSL_ENSURE( nDist >= 0, "nDist < 0" )do { if (true && (!(nDist >= 0))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" ":" "2191" ": "), "%s", "nDist < 0"); } } while (false); | ||||||||||||
2192 | OSL_ENSURE( nDist <= aRectFnSet.GetHeight(getFrameArea()),do { if (true && (!(nDist <= aRectFnSet.GetHeight( getFrameArea())))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" ":" "2193" ": "), "%s", "nDist > than current size."); } } while (false) | ||||||||||||
2193 | "nDist > than current size." )do { if (true && (!(nDist <= aRectFnSet.GetHeight( getFrameArea())))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" ":" "2193" ": "), "%s", "nDist > than current size."); } } while (false); | ||||||||||||
2194 | |||||||||||||
2195 | if ( !bTst ) | ||||||||||||
2196 | { | ||||||||||||
2197 | SwTwips nRstHeight; | ||||||||||||
2198 | if( GetUpper() ) | ||||||||||||
2199 | nRstHeight = aRectFnSet.BottomDist( getFrameArea(), aRectFnSet.GetPrtBottom(*GetUpper()) ); | ||||||||||||
2200 | else | ||||||||||||
2201 | nRstHeight = 0; | ||||||||||||
2202 | if( nRstHeight < 0 ) | ||||||||||||
2203 | { | ||||||||||||
2204 | SwTwips nNextHeight = 0; | ||||||||||||
2205 | if( GetUpper()->IsSctFrame() && nDist > LONG_MAX9223372036854775807L/2 ) | ||||||||||||
2206 | { | ||||||||||||
2207 | SwFrame *pNxt = GetNext(); | ||||||||||||
2208 | while( pNxt ) | ||||||||||||
2209 | { | ||||||||||||
2210 | nNextHeight += aRectFnSet.GetHeight(pNxt->getFrameArea()); | ||||||||||||
2211 | pNxt = pNxt->GetNext(); | ||||||||||||
2212 | } | ||||||||||||
2213 | } | ||||||||||||
2214 | nRstHeight = nDist + nRstHeight - nNextHeight; | ||||||||||||
2215 | } | ||||||||||||
2216 | else | ||||||||||||
2217 | { | ||||||||||||
2218 | nRstHeight = nDist; | ||||||||||||
2219 | } | ||||||||||||
2220 | |||||||||||||
2221 | { | ||||||||||||
2222 | SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this); | ||||||||||||
2223 | aRectFnSet.SetHeight( aFrm, aRectFnSet.GetHeight(aFrm) - nDist ); | ||||||||||||
2224 | |||||||||||||
2225 | if( IsVertical() && !IsVertLR() ) | ||||||||||||
2226 | { | ||||||||||||
2227 | aFrm.Pos().AdjustX(nDist ); | ||||||||||||
2228 | } | ||||||||||||
2229 | } | ||||||||||||
2230 | |||||||||||||
2231 | nDist = nRstHeight; | ||||||||||||
2232 | SwTabFrame *pTab = IsInTab() ? FindTabFrame() : nullptr; | ||||||||||||
2233 | if (pTab) | ||||||||||||
2234 | { | ||||||||||||
2235 | if ( pTab->GetTable()->GetHTMLTableLayout() && | ||||||||||||
2236 | !pTab->IsJoinLocked() && | ||||||||||||
2237 | !pTab->GetFormat()->GetDoc()->GetDocShell()->IsReadOnly() ) | ||||||||||||
2238 | { | ||||||||||||
2239 | pTab->InvalidatePos(); | ||||||||||||
2240 | pTab->SetResizeHTMLTable(); | ||||||||||||
2241 | } | ||||||||||||
2242 | } | ||||||||||||
2243 | } | ||||||||||||
2244 | |||||||||||||
2245 | SwTwips nReal; | ||||||||||||
2246 | if( GetUpper() && nDist > 0 ) | ||||||||||||
2247 | { | ||||||||||||
2248 | if( bTst || !GetUpper()->IsFooterFrame() ) | ||||||||||||
2249 | nReal = GetUpper()->Shrink( nDist, bTst, bInfo ); | ||||||||||||
2250 | else | ||||||||||||
2251 | { | ||||||||||||
2252 | nReal = 0; | ||||||||||||
2253 | |||||||||||||
2254 | // #108745# Sorry, dear old footer friend, I'm not gonna invalidate you, | ||||||||||||
2255 | // if there are any objects anchored inside your content, which | ||||||||||||
2256 | // overlap with the shrinking frame. | ||||||||||||
2257 | // This may lead to a footer frame that is too big, but this is better | ||||||||||||
2258 | // than looping. | ||||||||||||
2259 | // #109722# : The fix for #108745# was too strict. | ||||||||||||
2260 | |||||||||||||
2261 | bool bInvalidate = true; | ||||||||||||
2262 | const SwRect aRect( getFrameArea() ); | ||||||||||||
2263 | const SwPageFrame* pPage = FindPageFrame(); | ||||||||||||
2264 | const SwSortedObjs* pSorted = pPage ? pPage->GetSortedObjs() : nullptr; | ||||||||||||
2265 | if( pSorted ) | ||||||||||||
2266 | { | ||||||||||||
2267 | for (SwAnchoredObject* pAnchoredObj : *pSorted) | ||||||||||||
2268 | { | ||||||||||||
2269 | const SwRect aBound( pAnchoredObj->GetObjRectWithSpaces() ); | ||||||||||||
2270 | |||||||||||||
2271 | if( aBound.Left() > aRect.Right() ) | ||||||||||||
2272 | continue; | ||||||||||||
2273 | |||||||||||||
2274 | if( aBound.IsOver( aRect ) ) | ||||||||||||
2275 | { | ||||||||||||
2276 | const SwFrameFormat& rFormat = pAnchoredObj->GetFrameFormat(); | ||||||||||||
2277 | if( css::text::WrapTextMode_THROUGH != rFormat.GetSurround().GetSurround() ) | ||||||||||||
2278 | { | ||||||||||||
2279 | const SwFrame* pAnchor = pAnchoredObj->GetAnchorFrame(); | ||||||||||||
2280 | if ( pAnchor && pAnchor->FindFooterOrHeader() == GetUpper() ) | ||||||||||||
2281 | { | ||||||||||||
2282 | bInvalidate = false; | ||||||||||||
2283 | break; | ||||||||||||
2284 | } | ||||||||||||
2285 | } | ||||||||||||
2286 | } | ||||||||||||
2287 | } | ||||||||||||
2288 | } | ||||||||||||
2289 | |||||||||||||
2290 | if ( bInvalidate ) | ||||||||||||
2291 | GetUpper()->InvalidateSize(); | ||||||||||||
2292 | } | ||||||||||||
2293 | } | ||||||||||||
2294 | else | ||||||||||||
2295 | nReal = 0; | ||||||||||||
2296 | |||||||||||||
2297 | if ( !bTst ) | ||||||||||||
2298 | { | ||||||||||||
2299 | //The position of the next Frame changes for sure. | ||||||||||||
2300 | InvalidateNextPos(); | ||||||||||||
2301 | |||||||||||||
2302 | //If I don't have a successor I have to do the retouch by myself. | ||||||||||||
2303 | if ( !GetNext() ) | ||||||||||||
2304 | SetRetouche(); | ||||||||||||
2305 | } | ||||||||||||
2306 | return nReal; | ||||||||||||
2307 | } | ||||||||||||
2308 | |||||||||||||
2309 | void SwContentFrame::Modify( const SfxPoolItem* pOld, const SfxPoolItem * pNew ) | ||||||||||||
2310 | { | ||||||||||||
2311 | sal_uInt8 nInvFlags = 0; | ||||||||||||
2312 | |||||||||||||
2313 | if( pNew && RES_ATTRSET_CHG == pNew->Which() && pOld ) | ||||||||||||
2314 | { | ||||||||||||
2315 | SfxItemIter aNIter( *static_cast<const SwAttrSetChg*>(pNew)->GetChgSet() ); | ||||||||||||
2316 | SfxItemIter aOIter( *static_cast<const SwAttrSetChg*>(pOld)->GetChgSet() ); | ||||||||||||
2317 | const SfxPoolItem* pNItem = aNIter.GetCurItem(); | ||||||||||||
2318 | const SfxPoolItem* pOItem = aOIter.GetCurItem(); | ||||||||||||
2319 | SwAttrSetChg aOldSet( *static_cast<const SwAttrSetChg*>(pOld) ); | ||||||||||||
2320 | SwAttrSetChg aNewSet( *static_cast<const SwAttrSetChg*>(pNew) ); | ||||||||||||
2321 | do | ||||||||||||
2322 | { | ||||||||||||
2323 | UpdateAttr_(pOItem, pNItem, nInvFlags, &aOldSet, &aNewSet); | ||||||||||||
2324 | pNItem = aNIter.NextItem(); | ||||||||||||
2325 | pOItem = aOIter.NextItem(); | ||||||||||||
2326 | } while (pNItem); | ||||||||||||
2327 | if ( aOldSet.Count() || aNewSet.Count() ) | ||||||||||||
2328 | SwFrame::Modify( &aOldSet, &aNewSet ); | ||||||||||||
2329 | } | ||||||||||||
2330 | else | ||||||||||||
2331 | UpdateAttr_( pOld, pNew, nInvFlags ); | ||||||||||||
2332 | |||||||||||||
2333 | if ( nInvFlags == 0 ) | ||||||||||||
2334 | return; | ||||||||||||
2335 | |||||||||||||
2336 | SwPageFrame *pPage = FindPageFrame(); | ||||||||||||
2337 | InvalidatePage( pPage ); | ||||||||||||
2338 | if ( nInvFlags & 0x01 ) | ||||||||||||
2339 | SetCompletePaint(); | ||||||||||||
2340 | if ( nInvFlags & 0x02 ) | ||||||||||||
2341 | InvalidatePos_(); | ||||||||||||
2342 | if ( nInvFlags & 0x04 ) | ||||||||||||
2343 | InvalidateSize_(); | ||||||||||||
2344 | if ( nInvFlags & 0x88 ) | ||||||||||||
2345 | { | ||||||||||||
2346 | if( IsInSct() && !GetPrev() ) | ||||||||||||
2347 | { | ||||||||||||
2348 | SwSectionFrame *pSect = FindSctFrame(); | ||||||||||||
2349 | if( pSect->ContainsAny() == this ) | ||||||||||||
2350 | { | ||||||||||||
2351 | pSect->InvalidatePrt_(); | ||||||||||||
2352 | pSect->InvalidatePage( pPage ); | ||||||||||||
2353 | } | ||||||||||||
2354 | } | ||||||||||||
2355 | InvalidatePrt_(); | ||||||||||||
2356 | } | ||||||||||||
2357 | SwFrame* pNextFrame = GetIndNext(); | ||||||||||||
2358 | if ( pNextFrame && nInvFlags & 0x10) | ||||||||||||
2359 | { | ||||||||||||
2360 | pNextFrame->InvalidatePrt_(); | ||||||||||||
2361 | pNextFrame->InvalidatePage( pPage ); | ||||||||||||
2362 | } | ||||||||||||
2363 | if ( pNextFrame && nInvFlags & 0x80 ) | ||||||||||||
2364 | { | ||||||||||||
2365 | pNextFrame->SetCompletePaint(); | ||||||||||||
2366 | } | ||||||||||||
2367 | if ( nInvFlags & 0x20 ) | ||||||||||||
2368 | { | ||||||||||||
2369 | SwFrame* pPrevFrame = GetPrev(); | ||||||||||||
2370 | if ( pPrevFrame ) | ||||||||||||
2371 | { | ||||||||||||
2372 | pPrevFrame->InvalidatePrt_(); | ||||||||||||
2373 | pPrevFrame->InvalidatePage( pPage ); | ||||||||||||
2374 | } | ||||||||||||
2375 | } | ||||||||||||
2376 | if ( nInvFlags & 0x40 ) | ||||||||||||
2377 | InvalidateNextPos(); | ||||||||||||
2378 | |||||||||||||
2379 | } | ||||||||||||
2380 | |||||||||||||
2381 | void SwContentFrame::UpdateAttr_( const SfxPoolItem* pOld, const SfxPoolItem* pNew, | ||||||||||||
2382 | sal_uInt8 &rInvFlags, | ||||||||||||
2383 | SwAttrSetChg *pOldSet, SwAttrSetChg *pNewSet ) | ||||||||||||
2384 | { | ||||||||||||
2385 | bool bClear = true; | ||||||||||||
2386 | sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0; | ||||||||||||
2387 | switch ( nWhich ) | ||||||||||||
2388 | { | ||||||||||||
2389 | case RES_FMT_CHG: | ||||||||||||
2390 | rInvFlags = 0xFF; | ||||||||||||
2391 | [[fallthrough]]; | ||||||||||||
2392 | |||||||||||||
2393 | case RES_PAGEDESC: //attribute changes (on/off) | ||||||||||||
2394 | if ( IsInDocBody() && !IsInTab() ) | ||||||||||||
2395 | { | ||||||||||||
2396 | rInvFlags |= 0x02; | ||||||||||||
2397 | SwPageFrame *pPage = FindPageFrame(); | ||||||||||||
2398 | if ( !GetPrev() ) | ||||||||||||
2399 | CheckPageDescs( pPage ); | ||||||||||||
2400 | if (GetPageDescItem().GetNumOffset()) | ||||||||||||
2401 | static_cast<SwRootFrame*>(pPage->GetUpper())->SetVirtPageNum( true ); | ||||||||||||
2402 | SwDocPosUpdate aMsgHint( pPage->getFrameArea().Top() ); | ||||||||||||
2403 | pPage->GetFormat()->GetDoc()->getIDocumentFieldsAccess().UpdatePageFields( &aMsgHint ); | ||||||||||||
2404 | } | ||||||||||||
2405 | break; | ||||||||||||
2406 | |||||||||||||
2407 | case RES_UL_SPACE: | ||||||||||||
2408 | { | ||||||||||||
2409 | // OD 2004-02-18 #106629# - correction | ||||||||||||
2410 | // Invalidation of the printing area of next frame, not only | ||||||||||||
2411 | // for footnote content. | ||||||||||||
2412 | if ( !GetIndNext() ) | ||||||||||||
2413 | { | ||||||||||||
2414 | SwFrame* pNxt = FindNext(); | ||||||||||||
2415 | if ( pNxt ) | ||||||||||||
2416 | { | ||||||||||||
2417 | SwPageFrame* pPg = pNxt->FindPageFrame(); | ||||||||||||
2418 | pNxt->InvalidatePage( pPg ); | ||||||||||||
2419 | pNxt->InvalidatePrt_(); | ||||||||||||
2420 | if( pNxt->IsSctFrame() ) | ||||||||||||
2421 | { | ||||||||||||
2422 | SwFrame* pCnt = static_cast<SwSectionFrame*>(pNxt)->ContainsAny(); | ||||||||||||
2423 | if( pCnt ) | ||||||||||||
2424 | { | ||||||||||||
2425 | pCnt->InvalidatePrt_(); | ||||||||||||
2426 | pCnt->InvalidatePage( pPg ); | ||||||||||||
2427 | } | ||||||||||||
2428 | } | ||||||||||||
2429 | pNxt->SetCompletePaint(); | ||||||||||||
2430 | } | ||||||||||||
2431 | } | ||||||||||||
2432 | // OD 2004-03-17 #i11860# | ||||||||||||
2433 | if ( GetIndNext() && | ||||||||||||
2434 | !GetUpper()->GetFormat()->getIDocumentSettingAccess().get(DocumentSettingId::USE_FORMER_OBJECT_POS) ) | ||||||||||||
2435 | { | ||||||||||||
2436 | // OD 2004-07-01 #i28701# - use new method <InvalidateObjs(..)> | ||||||||||||
2437 | GetIndNext()->InvalidateObjs(); | ||||||||||||
2438 | } | ||||||||||||
2439 | Prepare( PrepareHint::ULSpaceChanged ); //TextFrame has to correct line spacing. | ||||||||||||
2440 | rInvFlags |= 0x80; | ||||||||||||
2441 | [[fallthrough]]; | ||||||||||||
2442 | } | ||||||||||||
2443 | case RES_LR_SPACE: | ||||||||||||
2444 | case RES_BOX: | ||||||||||||
2445 | case RES_SHADOW: | ||||||||||||
2446 | Prepare( PrepareHint::FixSizeChanged ); | ||||||||||||
2447 | SwFrame::Modify( pOld, pNew ); | ||||||||||||
2448 | rInvFlags |= 0x30; | ||||||||||||
2449 | break; | ||||||||||||
2450 | |||||||||||||
2451 | case RES_BREAK: | ||||||||||||
2452 | { | ||||||||||||
2453 | rInvFlags |= 0x42; | ||||||||||||
2454 | const IDocumentSettingAccess& rIDSA = GetUpper()->GetFormat()->getIDocumentSettingAccess(); | ||||||||||||
2455 | if( rIDSA.get(DocumentSettingId::PARA_SPACE_MAX) || | ||||||||||||
2456 | rIDSA.get(DocumentSettingId::PARA_SPACE_MAX_AT_PAGES) ) | ||||||||||||
2457 | { | ||||||||||||
2458 | rInvFlags |= 0x1; | ||||||||||||
2459 | SwFrame* pNxt = FindNext(); | ||||||||||||
2460 | if( pNxt ) | ||||||||||||
2461 | { | ||||||||||||
2462 | SwPageFrame* pPg = pNxt->FindPageFrame(); | ||||||||||||
2463 | pNxt->InvalidatePage( pPg ); | ||||||||||||
2464 | pNxt->InvalidatePrt_(); | ||||||||||||
2465 | if( pNxt->IsSctFrame() ) | ||||||||||||
2466 | { | ||||||||||||
2467 | SwFrame* pCnt = static_cast<SwSectionFrame*>(pNxt)->ContainsAny(); | ||||||||||||
2468 | if( pCnt ) | ||||||||||||
2469 | { | ||||||||||||
2470 | pCnt->InvalidatePrt_(); | ||||||||||||
2471 | pCnt->InvalidatePage( pPg ); | ||||||||||||
2472 | } | ||||||||||||
2473 | } | ||||||||||||
2474 | pNxt->SetCompletePaint(); | ||||||||||||
2475 | } | ||||||||||||
2476 | } | ||||||||||||
2477 | } | ||||||||||||
2478 | break; | ||||||||||||
2479 | |||||||||||||
2480 | // OD 2004-02-26 #i25029# | ||||||||||||
2481 | case RES_PARATR_CONNECT_BORDER: | ||||||||||||
2482 | { | ||||||||||||
2483 | rInvFlags |= 0x01; | ||||||||||||
2484 | if ( IsTextFrame() ) | ||||||||||||
2485 | { | ||||||||||||
2486 | InvalidateNextPrtArea(); | ||||||||||||
2487 | } | ||||||||||||
2488 | if ( !GetIndNext() && IsInTab() && IsInSplitTableRow() ) | ||||||||||||
2489 | { | ||||||||||||
2490 | FindTabFrame()->InvalidateSize(); | ||||||||||||
2491 | } | ||||||||||||
2492 | } | ||||||||||||
2493 | break; | ||||||||||||
2494 | |||||||||||||
2495 | case RES_PARATR_TABSTOP: | ||||||||||||
2496 | case RES_CHRATR_SHADOWED: | ||||||||||||
2497 | case RES_CHRATR_AUTOKERN: | ||||||||||||
2498 | case RES_CHRATR_UNDERLINE: | ||||||||||||
2499 | case RES_CHRATR_OVERLINE: | ||||||||||||
2500 | case RES_CHRATR_KERNING: | ||||||||||||
2501 | case RES_CHRATR_FONT: | ||||||||||||
2502 | case RES_CHRATR_FONTSIZE: | ||||||||||||
2503 | case RES_CHRATR_ESCAPEMENT: | ||||||||||||
2504 | case RES_CHRATR_CONTOUR: | ||||||||||||
2505 | case RES_PARATR_NUMRULE: | ||||||||||||
2506 | rInvFlags |= 0x01; | ||||||||||||
2507 | break; | ||||||||||||
2508 | |||||||||||||
2509 | case RES_FRM_SIZE: | ||||||||||||
2510 | rInvFlags |= 0x01; | ||||||||||||
2511 | [[fallthrough]]; | ||||||||||||
2512 | |||||||||||||
2513 | default: | ||||||||||||
2514 | bClear = false; | ||||||||||||
2515 | } | ||||||||||||
2516 | if ( bClear ) | ||||||||||||
2517 | { | ||||||||||||
2518 | if ( pOldSet || pNewSet ) | ||||||||||||
2519 | { | ||||||||||||
2520 | if ( pOldSet ) | ||||||||||||
2521 | pOldSet->ClearItem( nWhich ); | ||||||||||||
2522 | if ( pNewSet ) | ||||||||||||
2523 | pNewSet->ClearItem( nWhich ); | ||||||||||||
2524 | } | ||||||||||||
2525 | else | ||||||||||||
2526 | SwFrame::Modify( pOld, pNew ); | ||||||||||||
2527 | } | ||||||||||||
2528 | } | ||||||||||||
2529 | |||||||||||||
2530 | SwLayoutFrame::SwLayoutFrame(SwFrameFormat *const pFormat, SwFrame *const pSib) | ||||||||||||
2531 | : SwFrame(pFormat, pSib) | ||||||||||||
2532 | , m_pLower(nullptr) | ||||||||||||
2533 | { | ||||||||||||
2534 | const SwFormatFrameSize &rFormatSize = pFormat->GetFrameSize(); | ||||||||||||
2535 | if ( rFormatSize.GetHeightSizeType() == SwFrameSize::Fixed ) | ||||||||||||
2536 | mbFixSize = true; | ||||||||||||
2537 | } | ||||||||||||
2538 | |||||||||||||
2539 | // #i28701# | ||||||||||||
2540 | |||||||||||||
2541 | SwTwips SwLayoutFrame::InnerHeight() const | ||||||||||||
2542 | { | ||||||||||||
2543 | const SwFrame* pCnt = Lower(); | ||||||||||||
2544 | if (!pCnt) | ||||||||||||
2545 | return 0; | ||||||||||||
2546 | |||||||||||||
2547 | SwRectFnSet aRectFnSet(this); | ||||||||||||
2548 | SwTwips nRet = 0; | ||||||||||||
2549 | if( pCnt->IsColumnFrame() || pCnt->IsCellFrame() ) | ||||||||||||
2550 | { | ||||||||||||
2551 | do | ||||||||||||
2552 | { | ||||||||||||
2553 | SwTwips nTmp = static_cast<const SwLayoutFrame*>(pCnt)->InnerHeight(); | ||||||||||||
2554 | if( pCnt->isFramePrintAreaValid() ) | ||||||||||||
2555 | nTmp += aRectFnSet.GetHeight(pCnt->getFrameArea()) - | ||||||||||||
2556 | aRectFnSet.GetHeight(pCnt->getFramePrintArea()); | ||||||||||||
2557 | if( nRet < nTmp ) | ||||||||||||
2558 | nRet = nTmp; | ||||||||||||
2559 | pCnt = pCnt->GetNext(); | ||||||||||||
2560 | } while ( pCnt ); | ||||||||||||
2561 | } | ||||||||||||
2562 | else | ||||||||||||
2563 | { | ||||||||||||
2564 | do | ||||||||||||
2565 | { | ||||||||||||
2566 | nRet += aRectFnSet.GetHeight(pCnt->getFrameArea()); | ||||||||||||
2567 | if( pCnt->IsContentFrame() && static_cast<const SwTextFrame*>(pCnt)->IsUndersized() ) | ||||||||||||
2568 | nRet += static_cast<const SwTextFrame*>(pCnt)->GetParHeight() - | ||||||||||||
2569 | aRectFnSet.GetHeight(pCnt->getFramePrintArea()); | ||||||||||||
2570 | if( pCnt->IsLayoutFrame() && !pCnt->IsTabFrame() ) | ||||||||||||
2571 | nRet += static_cast<const SwLayoutFrame*>(pCnt)->InnerHeight() - | ||||||||||||
2572 | aRectFnSet.GetHeight(pCnt->getFramePrintArea()); | ||||||||||||
2573 | pCnt = pCnt->GetNext(); | ||||||||||||
2574 | } while( pCnt ); | ||||||||||||
2575 | |||||||||||||
2576 | } | ||||||||||||
2577 | return nRet; | ||||||||||||
2578 | } | ||||||||||||
2579 | |||||||||||||
2580 | SwTwips SwLayoutFrame::GrowFrame( SwTwips nDist, bool bTst, bool bInfo ) | ||||||||||||
2581 | { | ||||||||||||
2582 | const SwViewShell *pSh = getRootFrame()->GetCurrShell(); | ||||||||||||
2583 | const bool bBrowse = pSh && pSh->GetViewOptions()->getBrowseMode(); | ||||||||||||
2584 | SwFrameType nTmpType = SwFrameType::Cell | SwFrameType::Column; | ||||||||||||
2585 | if (bBrowse) | ||||||||||||
2586 | nTmpType |= SwFrameType::Body; | ||||||||||||
2587 | if( !(GetType() & nTmpType) && HasFixSize() ) | ||||||||||||
2588 | return 0; | ||||||||||||
2589 | |||||||||||||
2590 | SwRectFnSet aRectFnSet(this); | ||||||||||||
2591 | const SwTwips nFrameHeight = aRectFnSet.GetHeight(getFrameArea()); | ||||||||||||
2592 | const SwTwips nFramePos = getFrameArea().Pos().X(); | ||||||||||||
2593 | |||||||||||||
2594 | if ( nFrameHeight > 0 && nDist > (LONG_MAX9223372036854775807L - nFrameHeight) ) | ||||||||||||
2595 | nDist = LONG_MAX9223372036854775807L - nFrameHeight; | ||||||||||||
2596 | |||||||||||||
2597 | SwTwips nMin = 0; | ||||||||||||
2598 | if ( GetUpper() && !IsCellFrame() ) | ||||||||||||
2599 | { | ||||||||||||
2600 | SwFrame *pFrame = GetUpper()->Lower(); | ||||||||||||
2601 | while( pFrame ) | ||||||||||||
2602 | { nMin += aRectFnSet.GetHeight(pFrame->getFrameArea()); | ||||||||||||
2603 | pFrame = pFrame->GetNext(); | ||||||||||||
2604 | } | ||||||||||||
2605 | nMin = aRectFnSet.GetHeight(GetUpper()->getFramePrintArea()) - nMin; | ||||||||||||
2606 | if ( nMin < 0 ) | ||||||||||||
2607 | nMin = 0; | ||||||||||||
2608 | } | ||||||||||||
2609 | |||||||||||||
2610 | SwRect aOldFrame( getFrameArea() ); | ||||||||||||
2611 | bool bMoveAccFrame = false; | ||||||||||||
2612 | |||||||||||||
2613 | bool bChgPos = IsVertical(); | ||||||||||||
2614 | if ( !bTst ) | ||||||||||||
2615 | { | ||||||||||||
2616 | SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this); | ||||||||||||
2617 | aRectFnSet.SetHeight( aFrm, nFrameHeight + nDist ); | ||||||||||||
2618 | |||||||||||||
2619 | if( bChgPos && !IsVertLR() ) | ||||||||||||
2620 | { | ||||||||||||
2621 | aFrm.Pos().AdjustX( -nDist ); | ||||||||||||
2622 | } | ||||||||||||
2623 | |||||||||||||
2624 | bMoveAccFrame = true; | ||||||||||||
2625 | } | ||||||||||||
2626 | |||||||||||||
2627 | SwTwips nReal = nDist - nMin; | ||||||||||||
2628 | if ( nReal > 0 ) | ||||||||||||
2629 | { | ||||||||||||
2630 | if ( GetUpper() ) | ||||||||||||
2631 | { // AdjustNeighbourhood now only for the columns (but not in frames) | ||||||||||||
2632 | SwNeighbourAdjust nAdjust = GetUpper()->IsFootnoteBossFrame() ? | ||||||||||||
2633 | static_cast<SwFootnoteBossFrame*>(GetUpper())->NeighbourhoodAdjustment() | ||||||||||||
2634 | : SwNeighbourAdjust::GrowShrink; | ||||||||||||
2635 | if( SwNeighbourAdjust::OnlyAdjust == nAdjust ) | ||||||||||||
2636 | nReal = AdjustNeighbourhood( nReal, bTst ); | ||||||||||||
2637 | else | ||||||||||||
2638 | { | ||||||||||||
2639 | if( SwNeighbourAdjust::AdjustGrow == nAdjust ) | ||||||||||||
2640 | nReal += AdjustNeighbourhood( nReal, bTst ); | ||||||||||||
2641 | |||||||||||||
2642 | SwTwips nGrow = 0; | ||||||||||||
2643 | if( 0 < nReal ) | ||||||||||||
2644 | { | ||||||||||||
2645 | SwFrame* pToGrow = GetUpper(); | ||||||||||||
2646 | // NEW TABLES | ||||||||||||
2647 | // A cell with a row span of > 1 is allowed to grow the | ||||||||||||
2648 | // line containing the end of the row span if it is | ||||||||||||
2649 | // located in the same table frame: | ||||||||||||
2650 | const SwCellFrame* pThisCell = dynamic_cast<const SwCellFrame*>(this); | ||||||||||||
2651 | if ( pThisCell && pThisCell->GetLayoutRowSpan() > 1 ) | ||||||||||||
2652 | { | ||||||||||||
2653 | SwCellFrame& rEndCell = const_cast<SwCellFrame&>(pThisCell->FindStartEndOfRowSpanCell( false )); | ||||||||||||
2654 | if ( -1 == rEndCell.GetTabBox()->getRowSpan() ) | ||||||||||||
2655 | pToGrow = rEndCell.GetUpper(); | ||||||||||||
2656 | else | ||||||||||||
2657 | pToGrow = nullptr; | ||||||||||||
2658 | } | ||||||||||||
2659 | |||||||||||||
2660 | nGrow = pToGrow ? pToGrow->Grow( nReal, bTst, bInfo ) : 0; | ||||||||||||
2661 | } | ||||||||||||
2662 | |||||||||||||
2663 | if( SwNeighbourAdjust::GrowAdjust == nAdjust && nGrow < nReal ) | ||||||||||||
2664 | nReal = o3tl::saturating_add(nReal, AdjustNeighbourhood( nReal - nGrow, bTst )); | ||||||||||||
2665 | |||||||||||||
2666 | if ( IsFootnoteFrame() && (nGrow != nReal) && GetNext() ) | ||||||||||||
2667 | { | ||||||||||||
2668 | //Footnotes can replace their successor. | ||||||||||||
2669 | SwTwips nSpace = bTst ? 0 : -nDist; | ||||||||||||
2670 | const SwFrame *pFrame = GetUpper()->Lower(); | ||||||||||||
2671 | do | ||||||||||||
2672 | { nSpace += aRectFnSet.GetHeight(pFrame->getFrameArea()); | ||||||||||||
2673 | pFrame = pFrame->GetNext(); | ||||||||||||
2674 | } while ( pFrame != GetNext() ); | ||||||||||||
2675 | nSpace = aRectFnSet.GetHeight(GetUpper()->getFramePrintArea()) -nSpace; | ||||||||||||
2676 | if ( nSpace < 0 ) | ||||||||||||
2677 | nSpace = 0; | ||||||||||||
2678 | nSpace += nGrow; | ||||||||||||
2679 | if ( nReal > nSpace ) | ||||||||||||
2680 | nReal = nSpace; | ||||||||||||
2681 | if ( nReal && !bTst ) | ||||||||||||
2682 | static_cast<SwFootnoteFrame*>(this)->InvalidateNxtFootnoteCnts( FindPageFrame() ); | ||||||||||||
2683 | } | ||||||||||||
2684 | else | ||||||||||||
2685 | nReal = nGrow; | ||||||||||||
2686 | } | ||||||||||||
2687 | } | ||||||||||||
2688 | else | ||||||||||||
2689 | nReal = 0; | ||||||||||||
2690 | |||||||||||||
2691 | nReal += nMin; | ||||||||||||
2692 | } | ||||||||||||
2693 | else | ||||||||||||
2694 | nReal = nDist; | ||||||||||||
2695 | |||||||||||||
2696 | if ( !bTst ) | ||||||||||||
2697 | { | ||||||||||||
2698 | if( nReal != nDist && | ||||||||||||
2699 | // NEW TABLES | ||||||||||||
2700 | ( !IsCellFrame() || static_cast<SwCellFrame*>(this)->GetLayoutRowSpan() > 1 ) ) | ||||||||||||
2701 | { | ||||||||||||
2702 | SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this); | ||||||||||||
2703 | aRectFnSet.SetHeight( aFrm, nFrameHeight + nReal ); | ||||||||||||
2704 | |||||||||||||
2705 | if( bChgPos && !IsVertLR() ) | ||||||||||||
2706 | { | ||||||||||||
2707 | aFrm.Pos().setX( nFramePos - nReal ); | ||||||||||||
2708 | } | ||||||||||||
2709 | |||||||||||||
2710 | bMoveAccFrame = true; | ||||||||||||
2711 | } | ||||||||||||
2712 | |||||||||||||
2713 | if ( nReal ) | ||||||||||||
2714 | { | ||||||||||||
2715 | SwPageFrame *pPage = FindPageFrame(); | ||||||||||||
2716 | if ( GetNext() ) | ||||||||||||
2717 | { | ||||||||||||
2718 | GetNext()->InvalidatePos_(); | ||||||||||||
2719 | if ( GetNext()->IsContentFrame() ) | ||||||||||||
2720 | GetNext()->InvalidatePage( pPage ); | ||||||||||||
2721 | } | ||||||||||||
2722 | if ( !IsPageBodyFrame() ) | ||||||||||||
2723 | { | ||||||||||||
2724 | InvalidateAll_(); | ||||||||||||
2725 | InvalidatePage( pPage ); | ||||||||||||
2726 | } | ||||||||||||
2727 | if (!(GetType() & (SwFrameType::Row|SwFrameType::Tab|SwFrameType::FtnCont|SwFrameType::Page|SwFrameType::Root))) | ||||||||||||
2728 | NotifyLowerObjs(); | ||||||||||||
2729 | |||||||||||||
2730 | if( IsCellFrame() ) | ||||||||||||
2731 | InvaPercentLowers( nReal ); | ||||||||||||
2732 | |||||||||||||
2733 | std::unique_ptr<SvxBrushItem> aBack(GetFormat()->makeBackgroundBrushItem()); | ||||||||||||
2734 | const SvxGraphicPosition ePos = aBack ? aBack->GetGraphicPos() : GPOS_NONE; | ||||||||||||
2735 | if ( GPOS_NONE != ePos && GPOS_TILED != ePos ) | ||||||||||||
2736 | SetCompletePaint(); | ||||||||||||
2737 | } | ||||||||||||
2738 | } | ||||||||||||
2739 | |||||||||||||
2740 | if( bMoveAccFrame && IsAccessibleFrame() ) | ||||||||||||
2741 | { | ||||||||||||
2742 | SwRootFrame *pRootFrame = getRootFrame(); | ||||||||||||
2743 | if( pRootFrame && pRootFrame->IsAnyShellAccessible() && | ||||||||||||
2744 | pRootFrame->GetCurrShell() ) | ||||||||||||
2745 | { | ||||||||||||
2746 | pRootFrame->GetCurrShell()->Imp()->MoveAccessibleFrame( this, aOldFrame ); | ||||||||||||
2747 | } | ||||||||||||
2748 | } | ||||||||||||
2749 | return nReal; | ||||||||||||
2750 | } | ||||||||||||
2751 | |||||||||||||
2752 | SwTwips SwLayoutFrame::ShrinkFrame( SwTwips nDist, bool bTst, bool bInfo ) | ||||||||||||
2753 | { | ||||||||||||
2754 | const SwViewShell *pSh = getRootFrame()->GetCurrShell(); | ||||||||||||
2755 | const bool bBrowse = pSh && pSh->GetViewOptions()->getBrowseMode(); | ||||||||||||
2756 | SwFrameType nTmpType = SwFrameType::Cell | SwFrameType::Column; | ||||||||||||
2757 | if (bBrowse) | ||||||||||||
2758 | nTmpType |= SwFrameType::Body; | ||||||||||||
2759 | |||||||||||||
2760 | if (pSh && pSh->GetViewOptions()->IsWhitespaceHidden()) | ||||||||||||
2761 | { | ||||||||||||
2762 | if (IsBodyFrame()) | ||||||||||||
2763 | { | ||||||||||||
2764 | // Whitespace is hidden and this body frame will not shrink, as it | ||||||||||||
2765 | // has a fix size. | ||||||||||||
2766 | // Invalidate the page frame size, so in case the reason for the | ||||||||||||
2767 | // shrink was that there is more whitespace on this page, the size | ||||||||||||
2768 | // without whitespace will be recalculated correctly. | ||||||||||||
2769 | SwPageFrame* pPageFrame = FindPageFrame(); | ||||||||||||
2770 | pPageFrame->InvalidateSize(); | ||||||||||||
2771 | } | ||||||||||||
2772 | } | ||||||||||||
2773 | |||||||||||||
2774 | if( !(GetType() & nTmpType) && HasFixSize() ) | ||||||||||||
2775 | return 0; | ||||||||||||
2776 | |||||||||||||
2777 | OSL_ENSURE( nDist >= 0, "nDist < 0" )do { if (true && (!(nDist >= 0))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" ":" "2777" ": "), "%s", "nDist < 0"); } } while (false); | ||||||||||||
2778 | SwRectFnSet aRectFnSet(this); | ||||||||||||
2779 | SwTwips nFrameHeight = aRectFnSet.GetHeight(getFrameArea()); | ||||||||||||
2780 | if ( nDist > nFrameHeight ) | ||||||||||||
2781 | nDist = nFrameHeight; | ||||||||||||
2782 | |||||||||||||
2783 | SwTwips nMin = 0; | ||||||||||||
2784 | bool bChgPos = IsVertical(); | ||||||||||||
2785 | if ( Lower() ) | ||||||||||||
2786 | { | ||||||||||||
2787 | if( !Lower()->IsNeighbourFrame() ) | ||||||||||||
2788 | { const SwFrame *pFrame = Lower(); | ||||||||||||
2789 | const long nTmp = aRectFnSet.GetHeight(getFramePrintArea()); | ||||||||||||
2790 | while( pFrame && nMin < nTmp ) | ||||||||||||
2791 | { nMin += aRectFnSet.GetHeight(pFrame->getFrameArea()); | ||||||||||||
2792 | pFrame = pFrame->GetNext(); | ||||||||||||
2793 | } | ||||||||||||
2794 | } | ||||||||||||
2795 | } | ||||||||||||
2796 | SwTwips nReal = nDist; | ||||||||||||
2797 | SwTwips nMinDiff = aRectFnSet.GetHeight(getFramePrintArea()) - nMin; | ||||||||||||
2798 | if( nReal > nMinDiff ) | ||||||||||||
2799 | nReal = nMinDiff; | ||||||||||||
2800 | if( nReal <= 0 ) | ||||||||||||
2801 | return nDist; | ||||||||||||
2802 | |||||||||||||
2803 | SwRect aOldFrame( getFrameArea() ); | ||||||||||||
2804 | bool bMoveAccFrame = false; | ||||||||||||
2805 | |||||||||||||
2806 | SwTwips nRealDist = nReal; | ||||||||||||
2807 | if ( !bTst ) | ||||||||||||
2808 | { | ||||||||||||
2809 | SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this); | ||||||||||||
2810 | aRectFnSet.SetHeight( aFrm, nFrameHeight - nReal ); | ||||||||||||
2811 | |||||||||||||
2812 | if( bChgPos && !IsVertLR() ) | ||||||||||||
2813 | { | ||||||||||||
2814 | aFrm.Pos().AdjustX(nReal ); | ||||||||||||
2815 | } | ||||||||||||
2816 | |||||||||||||
2817 | bMoveAccFrame = true; | ||||||||||||
2818 | } | ||||||||||||
2819 | |||||||||||||
2820 | SwNeighbourAdjust nAdjust = GetUpper() && GetUpper()->IsFootnoteBossFrame() ? | ||||||||||||
2821 | static_cast<SwFootnoteBossFrame*>(GetUpper())->NeighbourhoodAdjustment() | ||||||||||||
2822 | : SwNeighbourAdjust::GrowShrink; | ||||||||||||
2823 | |||||||||||||
2824 | // AdjustNeighbourhood also in columns (but not in frames) | ||||||||||||
2825 | if( SwNeighbourAdjust::OnlyAdjust == nAdjust ) | ||||||||||||
2826 | { | ||||||||||||
2827 | if ( IsPageBodyFrame() && !bBrowse ) | ||||||||||||
2828 | nReal = nDist; | ||||||||||||
2829 | else | ||||||||||||
2830 | { nReal = AdjustNeighbourhood( -nReal, bTst ); | ||||||||||||
2831 | nReal *= -1; | ||||||||||||
2832 | if ( !bTst && IsBodyFrame() && nReal < nRealDist ) | ||||||||||||
2833 | { | ||||||||||||
2834 | SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this); | ||||||||||||
2835 | aRectFnSet.SetHeight( aFrm, aRectFnSet.GetHeight(aFrm) + nRealDist - nReal ); | ||||||||||||
2836 | |||||||||||||
2837 | if( bChgPos && !IsVertLR() ) | ||||||||||||
2838 | { | ||||||||||||
2839 | aFrm.Pos().AdjustX(nRealDist - nReal ); | ||||||||||||
2840 | } | ||||||||||||
2841 | |||||||||||||
2842 | OSL_ENSURE( !IsAccessibleFrame(), "bMoveAccFrame has to be set!" )do { if (true && (!(!IsAccessibleFrame()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" ":" "2842" ": "), "%s", "bMoveAccFrame has to be set!"); } } while (false); | ||||||||||||
2843 | } | ||||||||||||
2844 | } | ||||||||||||
2845 | } | ||||||||||||
2846 | else if( IsColumnFrame() || IsColBodyFrame() ) | ||||||||||||
2847 | { | ||||||||||||
2848 | SwTwips nTmp = GetUpper()->Shrink( nReal, bTst, bInfo ); | ||||||||||||
2849 | if ( nTmp != nReal ) | ||||||||||||
2850 | { | ||||||||||||
2851 | SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this); | ||||||||||||
2852 | aRectFnSet.SetHeight( aFrm, aRectFnSet.GetHeight(aFrm) + nReal - nTmp ); | ||||||||||||
2853 | |||||||||||||
2854 | if( bChgPos && !IsVertLR() ) | ||||||||||||
2855 | { | ||||||||||||
2856 | aFrm.Pos().AdjustX(nTmp - nReal ); | ||||||||||||
2857 | } | ||||||||||||
2858 | |||||||||||||
2859 | OSL_ENSURE( !IsAccessibleFrame(), "bMoveAccFrame has to be set!" )do { if (true && (!(!IsAccessibleFrame()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" ":" "2859" ": "), "%s", "bMoveAccFrame has to be set!"); } } while (false); | ||||||||||||
2860 | nReal = nTmp; | ||||||||||||
2861 | } | ||||||||||||
2862 | } | ||||||||||||
2863 | else | ||||||||||||
2864 | { | ||||||||||||
2865 | SwTwips nShrink = nReal; | ||||||||||||
2866 | SwFrame* pToShrink = GetUpper(); | ||||||||||||
2867 | const SwCellFrame* pThisCell = dynamic_cast<const SwCellFrame*>(this); | ||||||||||||
2868 | // NEW TABLES | ||||||||||||
2869 | if ( pThisCell && pThisCell->GetLayoutRowSpan() > 1 ) | ||||||||||||
2870 | { | ||||||||||||
2871 | SwCellFrame& rEndCell = const_cast<SwCellFrame&>(pThisCell->FindStartEndOfRowSpanCell( false )); | ||||||||||||
2872 | pToShrink = rEndCell.GetUpper(); | ||||||||||||
2873 | } | ||||||||||||
2874 | |||||||||||||
2875 | nReal = pToShrink ? pToShrink->Shrink( nShrink, bTst, bInfo ) : 0; | ||||||||||||
2876 | if( ( SwNeighbourAdjust::GrowAdjust == nAdjust || SwNeighbourAdjust::AdjustGrow == nAdjust ) | ||||||||||||
2877 | && nReal < nShrink ) | ||||||||||||
2878 | AdjustNeighbourhood( nReal - nShrink ); | ||||||||||||
2879 | } | ||||||||||||
2880 | |||||||||||||
2881 | if( bMoveAccFrame && IsAccessibleFrame() ) | ||||||||||||
2882 | { | ||||||||||||
2883 | SwRootFrame *pRootFrame = getRootFrame(); | ||||||||||||
2884 | if( pRootFrame && pRootFrame->IsAnyShellAccessible() && | ||||||||||||
2885 | pRootFrame->GetCurrShell() ) | ||||||||||||
2886 | { | ||||||||||||
2887 | pRootFrame->GetCurrShell()->Imp()->MoveAccessibleFrame( this, aOldFrame ); | ||||||||||||
2888 | } | ||||||||||||
2889 | } | ||||||||||||
2890 | if ( !bTst && (IsCellFrame() || IsColumnFrame() ? nReal : nRealDist) ) | ||||||||||||
2891 | { | ||||||||||||
2892 | SwPageFrame *pPage = FindPageFrame(); | ||||||||||||
2893 | if ( GetNext() ) | ||||||||||||
2894 | { | ||||||||||||
2895 | GetNext()->InvalidatePos_(); | ||||||||||||
2896 | if ( GetNext()->IsContentFrame() ) | ||||||||||||
2897 | GetNext()->InvalidatePage( pPage ); | ||||||||||||
2898 | if ( IsTabFrame() ) | ||||||||||||
2899 | static_cast<SwTabFrame*>(this)->SetComplete(); | ||||||||||||
2900 | } | ||||||||||||
2901 | else | ||||||||||||
2902 | { if ( IsRetoucheFrame() ) | ||||||||||||
2903 | SetRetouche(); | ||||||||||||
2904 | if ( IsTabFrame() ) | ||||||||||||
2905 | { | ||||||||||||
2906 | static_cast<SwTabFrame*>(this)->SetComplete(); | ||||||||||||
2907 | if ( Lower() ) // Can also be in the Join and be empty! | ||||||||||||
2908 | InvalidateNextPos(); | ||||||||||||
2909 | } | ||||||||||||
2910 | } | ||||||||||||
2911 | if ( !IsBodyFrame() ) | ||||||||||||
2912 | { | ||||||||||||
2913 | InvalidateAll_(); | ||||||||||||
2914 | InvalidatePage( pPage ); | ||||||||||||
2915 | bool bCompletePaint = true; | ||||||||||||
2916 | const SwFrameFormat* pFormat = GetFormat(); | ||||||||||||
2917 | if (pFormat) | ||||||||||||
2918 | { | ||||||||||||
2919 | std::unique_ptr<SvxBrushItem> aBack(pFormat->makeBackgroundBrushItem()); | ||||||||||||
2920 | const SvxGraphicPosition ePos = aBack ? aBack->GetGraphicPos() : GPOS_NONE; | ||||||||||||
2921 | if ( GPOS_NONE == ePos || GPOS_TILED == ePos ) | ||||||||||||
2922 | bCompletePaint = false; | ||||||||||||
2923 | } | ||||||||||||
2924 | if (bCompletePaint) | ||||||||||||
2925 | SetCompletePaint(); | ||||||||||||
2926 | } | ||||||||||||
2927 | |||||||||||||
2928 | if (!(GetType() & (SwFrameType::Row|SwFrameType::Tab|SwFrameType::FtnCont|SwFrameType::Page|SwFrameType::Root))) | ||||||||||||
2929 | NotifyLowerObjs(); | ||||||||||||
2930 | |||||||||||||
2931 | if( IsCellFrame() ) | ||||||||||||
2932 | InvaPercentLowers( nReal ); | ||||||||||||
2933 | |||||||||||||
2934 | SwContentFrame *pCnt; | ||||||||||||
2935 | if( IsFootnoteFrame() && !static_cast<SwFootnoteFrame*>(this)->GetAttr()->GetFootnote().IsEndNote() && | ||||||||||||
2936 | ( GetFormat()->GetDoc()->GetFootnoteInfo().m_ePos != FTNPOS_CHAPTER || | ||||||||||||
2937 | ( IsInSct() && FindSctFrame()->IsFootnoteAtEnd() ) ) && | ||||||||||||
2938 | nullptr != (pCnt = static_cast<SwFootnoteFrame*>(this)->GetRefFromAttr() ) ) | ||||||||||||
2939 | { | ||||||||||||
2940 | if ( pCnt->IsFollow() ) | ||||||||||||
2941 | { // If we are in another column/page than the frame with the | ||||||||||||
2942 | // reference, we don't need to invalidate its master. | ||||||||||||
2943 | SwFrame *pTmp = pCnt->FindFootnoteBossFrame(true) == FindFootnoteBossFrame(true) | ||||||||||||
2944 | ? &pCnt->FindMaster()->GetFrame() : pCnt; | ||||||||||||
2945 | pTmp->Prepare( PrepareHint::AdjustSizeWithoutFormatting ); | ||||||||||||
2946 | pTmp->InvalidateSize(); | ||||||||||||
2947 | } | ||||||||||||
2948 | else | ||||||||||||
2949 | pCnt->InvalidatePos(); | ||||||||||||
2950 | } | ||||||||||||
2951 | } | ||||||||||||
2952 | return nReal; | ||||||||||||
2953 | } | ||||||||||||
2954 | |||||||||||||
2955 | /** | ||||||||||||
2956 | * Changes the size of the directly subsidiary Frame's that have a fixed size, proportionally to the | ||||||||||||
2957 | * size change of the PrtArea of the Frame's. | ||||||||||||
2958 | * | ||||||||||||
2959 | * The variable Frames are also proportionally adapted; they will grow/shrink again by themselves. | ||||||||||||
2960 | */ | ||||||||||||
2961 | void SwLayoutFrame::ChgLowersProp( const Size& rOldSize ) | ||||||||||||
2962 | { | ||||||||||||
2963 | // no change of lower properties for root frame or if no lower exists. | ||||||||||||
2964 | if ( IsRootFrame() || !Lower() ) | ||||||||||||
2965 | return; | ||||||||||||
2966 | |||||||||||||
2967 | // declare and init <SwFrame* pLowerFrame> with first lower | ||||||||||||
2968 | SwFrame *pLowerFrame = Lower(); | ||||||||||||
2969 | |||||||||||||
2970 | // declare and init const booleans <bHeightChgd> and <bWidthChg> | ||||||||||||
2971 | const bool bHeightChgd = rOldSize.Height() != getFramePrintArea().Height(); | ||||||||||||
2972 | const bool bWidthChgd = rOldSize.Width() != getFramePrintArea().Width(); | ||||||||||||
2973 | |||||||||||||
2974 | SwRectFnSet aRectFnSet(this); | ||||||||||||
2975 | |||||||||||||
2976 | // This shortcut basically tries to handle only lower frames that | ||||||||||||
2977 | // are affected by the size change. Otherwise much more lower frames | ||||||||||||
2978 | // are invalidated. | ||||||||||||
2979 | if ( !( aRectFnSet.IsVert() ? bHeightChgd : bWidthChgd ) && | ||||||||||||
2980 | ! Lower()->IsColumnFrame() && | ||||||||||||
2981 | ( ( IsBodyFrame() && IsInDocBody() && ( !IsInSct() || !FindSctFrame()->IsColLocked() ) ) || | ||||||||||||
2982 | // #i10826# Section frames without columns should not | ||||||||||||
2983 | // invalidate all lowers! | ||||||||||||
2984 | IsSctFrame() ) ) | ||||||||||||
2985 | { | ||||||||||||
2986 | // Determine page frame the body frame resp. the section frame belongs to. | ||||||||||||
2987 | SwPageFrame *pPage = FindPageFrame(); | ||||||||||||
2988 | // Determine last lower by traveling through them using <GetNext()>. | ||||||||||||
2989 | // During travel check each section frame, if it will be sized to | ||||||||||||
2990 | // maximum. If Yes, invalidate size of section frame and set | ||||||||||||
2991 | // corresponding flags at the page. | ||||||||||||
2992 | do | ||||||||||||
2993 | { | ||||||||||||
2994 | if( pLowerFrame->IsSctFrame() && static_cast<SwSectionFrame*>(pLowerFrame)->ToMaximize_() ) | ||||||||||||
2995 | { | ||||||||||||
2996 | pLowerFrame->InvalidateSize_(); | ||||||||||||
2997 | pLowerFrame->InvalidatePage( pPage ); | ||||||||||||
2998 | } | ||||||||||||
2999 | if( pLowerFrame->GetNext() ) | ||||||||||||
3000 | pLowerFrame = pLowerFrame->GetNext(); | ||||||||||||
3001 | else | ||||||||||||
3002 | break; | ||||||||||||
3003 | } while( true ); | ||||||||||||
3004 | // If found last lower is a section frame containing no section | ||||||||||||
3005 | // (section frame isn't valid and will be deleted in the future), | ||||||||||||
3006 | // travel backwards. | ||||||||||||
3007 | while( pLowerFrame->IsSctFrame() && !static_cast<SwSectionFrame*>(pLowerFrame)->GetSection() && | ||||||||||||
3008 | pLowerFrame->GetPrev() ) | ||||||||||||
3009 | pLowerFrame = pLowerFrame->GetPrev(); | ||||||||||||
3010 | // If found last lower is a section frame, set <pLowerFrame> to its last | ||||||||||||
3011 | // content, if the section frame is valid and is not sized to maximum. | ||||||||||||
3012 | // Otherwise set <pLowerFrame> to NULL - In this case body frame only | ||||||||||||
3013 | // contains invalid section frames. | ||||||||||||
3014 | if( pLowerFrame->IsSctFrame() ) | ||||||||||||
3015 | pLowerFrame = static_cast<SwSectionFrame*>(pLowerFrame)->GetSection() && | ||||||||||||
3016 | !static_cast<SwSectionFrame*>(pLowerFrame)->ToMaximize( false ) ? | ||||||||||||
3017 | static_cast<SwSectionFrame*>(pLowerFrame)->FindLastContent() : nullptr; | ||||||||||||
3018 | |||||||||||||
3019 | // continue with found last lower, probably the last content of a section | ||||||||||||
3020 | if ( pLowerFrame ) | ||||||||||||
3021 | { | ||||||||||||
3022 | // If <pLowerFrame> is in a table frame, set <pLowerFrame> to this table | ||||||||||||
3023 | // frame and continue. | ||||||||||||
3024 | if ( pLowerFrame->IsInTab() ) | ||||||||||||
3025 | { | ||||||||||||
3026 | // OD 28.10.2002 #97265# - safeguard for setting <pLowerFrame> to | ||||||||||||
3027 | // its table frame - check, if the table frame is also a lower | ||||||||||||
3028 | // of the body frame, in order to assure that <pLowerFrame> is not | ||||||||||||
3029 | // set to a frame, which is an *upper* of the body frame. | ||||||||||||
3030 | SwFrame* pTableFrame = pLowerFrame->FindTabFrame(); | ||||||||||||
3031 | if ( IsAnLower( pTableFrame ) ) | ||||||||||||
3032 | { | ||||||||||||
3033 | pLowerFrame = pTableFrame; | ||||||||||||
3034 | } | ||||||||||||
3035 | } | ||||||||||||
3036 | // Check, if variable size of body frame resp. section frame has grown | ||||||||||||
3037 | // OD 28.10.2002 #97265# - correct check, if variable size has grown. | ||||||||||||
3038 | SwTwips nOldHeight = aRectFnSet.IsVert() ? rOldSize.Width() : rOldSize.Height(); | ||||||||||||
3039 | if( nOldHeight < aRectFnSet.GetHeight(getFramePrintArea()) ) | ||||||||||||
3040 | { | ||||||||||||
3041 | // If variable size of body|section frame has grown, only found | ||||||||||||
3042 | // last lower and the position of the its next have to be invalidated. | ||||||||||||
3043 | pLowerFrame->InvalidateAll_(); | ||||||||||||
3044 | pLowerFrame->InvalidatePage( pPage ); | ||||||||||||
3045 | if( !pLowerFrame->IsFlowFrame() || | ||||||||||||
3046 | !SwFlowFrame::CastFlowFrame( pLowerFrame )->HasFollow() ) | ||||||||||||
3047 | pLowerFrame->InvalidateNextPos( true ); | ||||||||||||
3048 | if ( pLowerFrame->IsTextFrame() ) | ||||||||||||
3049 | static_cast<SwContentFrame*>(pLowerFrame)->Prepare( PrepareHint::AdjustSizeWithoutFormatting ); | ||||||||||||
3050 | } | ||||||||||||
3051 | else | ||||||||||||
3052 | { | ||||||||||||
3053 | // variable size of body|section frame has shrunk. Thus, | ||||||||||||
3054 | // invalidate all lowers not matching the new body|section size | ||||||||||||
3055 | // and the dedicated new last lower. | ||||||||||||
3056 | if( aRectFnSet.IsVert() ) | ||||||||||||
3057 | { | ||||||||||||
3058 | SwTwips nBot = getFrameArea().Left() + getFramePrintArea().Left(); | ||||||||||||
3059 | while ( pLowerFrame && pLowerFrame->GetPrev() && pLowerFrame->getFrameArea().Left() < nBot ) | ||||||||||||
3060 | { | ||||||||||||
3061 | pLowerFrame->InvalidateAll_(); | ||||||||||||
3062 | pLowerFrame->InvalidatePage( pPage ); | ||||||||||||
3063 | pLowerFrame = pLowerFrame->GetPrev(); | ||||||||||||
3064 | } | ||||||||||||
3065 | } | ||||||||||||
3066 | else | ||||||||||||
3067 | { | ||||||||||||
3068 | SwTwips nBot = getFrameArea().Top() + getFramePrintArea().Bottom(); | ||||||||||||
3069 | while ( pLowerFrame && pLowerFrame->GetPrev() && pLowerFrame->getFrameArea().Top() > nBot ) | ||||||||||||
3070 | { | ||||||||||||
3071 | pLowerFrame->InvalidateAll_(); | ||||||||||||
3072 | pLowerFrame->InvalidatePage( pPage ); | ||||||||||||
3073 | pLowerFrame = pLowerFrame->GetPrev(); | ||||||||||||
3074 | } | ||||||||||||
3075 | } | ||||||||||||
3076 | if ( pLowerFrame ) | ||||||||||||
3077 | { | ||||||||||||
3078 | pLowerFrame->InvalidateSize_(); | ||||||||||||
3079 | pLowerFrame->InvalidatePage( pPage ); | ||||||||||||
3080 | if ( pLowerFrame->IsTextFrame() ) | ||||||||||||
3081 | static_cast<SwContentFrame*>(pLowerFrame)->Prepare( PrepareHint::AdjustSizeWithoutFormatting ); | ||||||||||||
3082 | } | ||||||||||||
3083 | } | ||||||||||||
3084 | // #i41694# - improvement by removing duplicates | ||||||||||||
3085 | if ( pLowerFrame ) | ||||||||||||
3086 | { | ||||||||||||
3087 | if ( pLowerFrame->IsInSct() ) | ||||||||||||
3088 | { | ||||||||||||
3089 | // #i41694# - follow-up of issue #i10826# | ||||||||||||
3090 | // No invalidation of section frame, if it's the this. | ||||||||||||
3091 | SwFrame* pSectFrame = pLowerFrame->FindSctFrame(); | ||||||||||||
3092 | if( pSectFrame != this && IsAnLower( pSectFrame ) ) | ||||||||||||
3093 | { | ||||||||||||
3094 | pSectFrame->InvalidateSize_(); | ||||||||||||
3095 | pSectFrame->InvalidatePage( pPage ); | ||||||||||||
3096 | } | ||||||||||||
3097 | } | ||||||||||||
3098 | } | ||||||||||||
3099 | } | ||||||||||||
3100 | return; | ||||||||||||
3101 | } // end of { special case } | ||||||||||||
3102 | |||||||||||||
3103 | // Invalidate page for content only once. | ||||||||||||
3104 | bool bInvaPageForContent = true; | ||||||||||||
3105 | |||||||||||||
3106 | // Declare booleans <bFixChgd> and <bVarChgd>, indicating for text frame | ||||||||||||
3107 | // adjustment, if fixed/variable size has changed. | ||||||||||||
3108 | bool bFixChgd, bVarChgd; | ||||||||||||
3109 | if( aRectFnSet.IsVert() == pLowerFrame->IsNeighbourFrame() ) | ||||||||||||
3110 | { | ||||||||||||
3111 | bFixChgd = bWidthChgd; | ||||||||||||
3112 | bVarChgd = bHeightChgd; | ||||||||||||
3113 | } | ||||||||||||
3114 | else | ||||||||||||
3115 | { | ||||||||||||
3116 | bFixChgd = bHeightChgd; | ||||||||||||
3117 | bVarChgd = bWidthChgd; | ||||||||||||
3118 | } | ||||||||||||
3119 | |||||||||||||
3120 | // Declare const unsigned short <nFixWidth> and init it this frame types | ||||||||||||
3121 | // which has fixed width in vertical respectively horizontal layout. | ||||||||||||
3122 | // In vertical layout these are neighbour frames (cell and column frames), | ||||||||||||
3123 | // header frames and footer frames. | ||||||||||||
3124 | // In horizontal layout these are all frames, which aren't neighbour frames. | ||||||||||||
3125 | const SwFrameType nFixWidth = aRectFnSet.IsVert() ? (FRM_NEIGHBOUR(SwFrameType::Column | SwFrameType::Cell) | FRM_HEADFOOT(SwFrameType::Header | SwFrameType::Footer)) | ||||||||||||
3126 | : ~SwFrameType(FRM_NEIGHBOUR(SwFrameType::Column | SwFrameType::Cell)); | ||||||||||||
3127 | |||||||||||||
3128 | // Declare const unsigned short <nFixHeight> and init it this frame types | ||||||||||||
3129 | // which has fixed height in vertical respectively horizontal layout. | ||||||||||||
3130 | // In vertical layout these are all frames, which aren't neighbour frames, | ||||||||||||
3131 | // header frames, footer frames, body frames or foot note container frames. | ||||||||||||
3132 | // In horizontal layout these are neighbour frames. | ||||||||||||
3133 | const SwFrameType nFixHeight = aRectFnSet.IsVert() ? ~SwFrameType(FRM_NEIGHBOUR(SwFrameType::Column | SwFrameType::Cell) | FRM_HEADFOOT(SwFrameType::Header | SwFrameType::Footer) | FRM_BODYFTNC(SwFrameType::FtnCont | SwFrameType::Body)) | ||||||||||||
3134 | : FRM_NEIGHBOUR(SwFrameType::Column | SwFrameType::Cell); | ||||||||||||
3135 | |||||||||||||
3136 | // Travel through all lowers using <GetNext()> | ||||||||||||
3137 | while ( pLowerFrame ) | ||||||||||||
3138 | { | ||||||||||||
3139 | if ( pLowerFrame->IsTextFrame() ) | ||||||||||||
3140 | { | ||||||||||||
3141 | // Text frames will only be invalidated - prepare invalidation | ||||||||||||
3142 | if ( bFixChgd ) | ||||||||||||
3143 | static_cast<SwContentFrame*>(pLowerFrame)->Prepare( PrepareHint::FixSizeChanged ); | ||||||||||||
3144 | if ( bVarChgd ) | ||||||||||||
3145 | static_cast<SwContentFrame*>(pLowerFrame)->Prepare( PrepareHint::AdjustSizeWithoutFormatting ); | ||||||||||||
3146 | } | ||||||||||||
3147 | else | ||||||||||||
3148 | { | ||||||||||||
3149 | // If lower isn't a table, row, cell or section frame, adjust its | ||||||||||||
3150 | // frame size. | ||||||||||||
3151 | const SwFrameType nLowerType = pLowerFrame->GetType(); | ||||||||||||
3152 | if ( !(nLowerType & (SwFrameType::Tab|SwFrameType::Row|SwFrameType::Cell|SwFrameType::Section)) ) | ||||||||||||
3153 | { | ||||||||||||
3154 | if ( bWidthChgd ) | ||||||||||||
3155 | { | ||||||||||||
3156 | if( nLowerType & nFixWidth ) | ||||||||||||
3157 | { | ||||||||||||
3158 | // Considering previous conditions: | ||||||||||||
3159 | // In vertical layout set width of column, header and | ||||||||||||
3160 | // footer frames to its upper width. | ||||||||||||
3161 | // In horizontal layout set width of header, footer, | ||||||||||||
3162 | // foot note container, foot note, body and no-text | ||||||||||||
3163 | // frames to its upper width. | ||||||||||||
3164 | SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*pLowerFrame); | ||||||||||||
3165 | aFrm.Width( getFramePrintArea().Width() ); | ||||||||||||
3166 | } | ||||||||||||
3167 | else if( rOldSize.Width() && !pLowerFrame->IsFootnoteFrame() ) | ||||||||||||
3168 | { | ||||||||||||
3169 | // Adjust frame width proportional, if lower isn't a | ||||||||||||
3170 | // foot note frame and condition <nLowerType & nFixWidth> | ||||||||||||
3171 | // isn't true. | ||||||||||||
3172 | // Considering previous conditions: | ||||||||||||
3173 | // In vertical layout these are foot note container, | ||||||||||||
3174 | // body and no-text frames. | ||||||||||||
3175 | // In horizontal layout these are column and no-text frames. | ||||||||||||
3176 | // OD 24.10.2002 #97265# - <double> calculation | ||||||||||||
3177 | // Perform <double> calculation of new width, if | ||||||||||||
3178 | // one of the coefficients is greater than 50000 | ||||||||||||
3179 | SwTwips nNewWidth; | ||||||||||||
3180 | if ( (pLowerFrame->getFrameArea().Width() > 50000) || | ||||||||||||
3181 | (getFramePrintArea().Width() > 50000) ) | ||||||||||||
3182 | { | ||||||||||||
3183 | double nNewWidthTmp = | ||||||||||||
3184 | ( double(pLowerFrame->getFrameArea().Width()) | ||||||||||||
3185 | * double(getFramePrintArea().Width()) ) | ||||||||||||
3186 | / double(rOldSize.Width()); | ||||||||||||
3187 | nNewWidth = SwTwips(nNewWidthTmp); | ||||||||||||
3188 | } | ||||||||||||
3189 | else | ||||||||||||
3190 | { | ||||||||||||
3191 | nNewWidth = | ||||||||||||
3192 | (pLowerFrame->getFrameArea().Width() * getFramePrintArea().Width()) / rOldSize.Width(); | ||||||||||||
3193 | } | ||||||||||||
3194 | |||||||||||||
3195 | SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*pLowerFrame); | ||||||||||||
3196 | aFrm.Width( nNewWidth ); | ||||||||||||
3197 | } | ||||||||||||
3198 | } | ||||||||||||
3199 | if ( bHeightChgd ) | ||||||||||||
3200 | { | ||||||||||||
3201 | if( nLowerType & nFixHeight ) | ||||||||||||
3202 | { | ||||||||||||
3203 | // Considering previous conditions: | ||||||||||||
3204 | // In vertical layout set height of foot note and | ||||||||||||
3205 | // no-text frames to its upper height. | ||||||||||||
3206 | // In horizontal layout set height of column frames | ||||||||||||
3207 | // to its upper height. | ||||||||||||
3208 | SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*pLowerFrame); | ||||||||||||
3209 | aFrm.Height( getFramePrintArea().Height() ); | ||||||||||||
3210 | } | ||||||||||||
3211 | // OD 01.10.2002 #102211# | ||||||||||||
3212 | // add conditions <!pLowerFrame->IsHeaderFrame()> and | ||||||||||||
3213 | // <!pLowerFrame->IsFooterFrame()> in order to avoid that | ||||||||||||
3214 | // the <Grow> of header or footer are overwritten. | ||||||||||||
3215 | // NOTE: Height of header/footer frame is determined by contents. | ||||||||||||
3216 | else if ( rOldSize.Height() && | ||||||||||||
3217 | !pLowerFrame->IsFootnoteFrame() && | ||||||||||||
3218 | !pLowerFrame->IsHeaderFrame() && | ||||||||||||
3219 | !pLowerFrame->IsFooterFrame() | ||||||||||||
3220 | ) | ||||||||||||
3221 | { | ||||||||||||
3222 | // Adjust frame height proportional, if lower isn't a | ||||||||||||
3223 | // foot note, a header or a footer frame and | ||||||||||||
3224 | // condition <nLowerType & nFixHeight> isn't true. | ||||||||||||
3225 | // Considering previous conditions: | ||||||||||||
3226 | // In vertical layout these are column, foot note container, | ||||||||||||
3227 | // body and no-text frames. | ||||||||||||
3228 | // In horizontal layout these are column, foot note | ||||||||||||
3229 | // container, body and no-text frames. | ||||||||||||
3230 | |||||||||||||
3231 | // OD 29.10.2002 #97265# - special case for page lowers | ||||||||||||
3232 | // The page lowers that have to be adjusted on page height | ||||||||||||
3233 | // change are the body frame and the foot note container | ||||||||||||
3234 | // frame. | ||||||||||||
3235 | // In vertical layout the height of both is directly | ||||||||||||
3236 | // adjusted to the page height change. | ||||||||||||
3237 | // In horizontal layout the height of the body frame is | ||||||||||||
3238 | // directly adjusted to the page height change and the | ||||||||||||
3239 | // foot note frame height isn't touched, because its | ||||||||||||
3240 | // determined by its content. | ||||||||||||
3241 | // OD 31.03.2003 #108446# - apply special case for page | ||||||||||||
3242 | // lowers - see description above - also for section columns. | ||||||||||||
3243 | if ( IsPageFrame() || | ||||||||||||
3244 | ( IsColumnFrame() && IsInSct() ) | ||||||||||||
3245 | ) | ||||||||||||
3246 | { | ||||||||||||
3247 | OSL_ENSURE( pLowerFrame->IsBodyFrame() || pLowerFrame->IsFootnoteContFrame(),do { if (true && (!(pLowerFrame->IsBodyFrame() || pLowerFrame ->IsFootnoteContFrame()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" ":" "3248" ": "), "%s", "ChgLowersProp - only for body or foot note container" ); } } while (false) | ||||||||||||
3248 | "ChgLowersProp - only for body or foot note container" )do { if (true && (!(pLowerFrame->IsBodyFrame() || pLowerFrame ->IsFootnoteContFrame()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" ":" "3248" ": "), "%s", "ChgLowersProp - only for body or foot note container" ); } } while (false); | ||||||||||||
3249 | if ( pLowerFrame->IsBodyFrame() || pLowerFrame->IsFootnoteContFrame() ) | ||||||||||||
3250 | { | ||||||||||||
3251 | if ( IsVertical() || pLowerFrame->IsBodyFrame() ) | ||||||||||||
3252 | { | ||||||||||||
3253 | SwTwips nNewHeight = | ||||||||||||
3254 | pLowerFrame->getFrameArea().Height() + | ||||||||||||
3255 | ( getFramePrintArea().Height() - rOldSize.Height() ); | ||||||||||||
3256 | if ( nNewHeight < 0) | ||||||||||||
3257 | { | ||||||||||||
3258 | // OD 01.04.2003 #108446# - adjust assertion condition and text | ||||||||||||
3259 | OSL_ENSURE( !( IsPageFrame() &&do { if (true && (!(!( IsPageFrame() && (pLowerFrame ->getFrameArea().Height()>0) && (pLowerFrame-> isFrameAreaDefinitionValid()) )))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" ":" "3262" ": "), "%s", "ChgLowersProg - negative height for lower." ); } } while (false) | ||||||||||||
3260 | (pLowerFrame->getFrameArea().Height()>0) &&do { if (true && (!(!( IsPageFrame() && (pLowerFrame ->getFrameArea().Height()>0) && (pLowerFrame-> isFrameAreaDefinitionValid()) )))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" ":" "3262" ": "), "%s", "ChgLowersProg - negative height for lower." ); } } while (false) | ||||||||||||
3261 | (pLowerFrame->isFrameAreaDefinitionValid()) ),do { if (true && (!(!( IsPageFrame() && (pLowerFrame ->getFrameArea().Height()>0) && (pLowerFrame-> isFrameAreaDefinitionValid()) )))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" ":" "3262" ": "), "%s", "ChgLowersProg - negative height for lower." ); } } while (false) | ||||||||||||
3262 | "ChgLowersProg - negative height for lower.")do { if (true && (!(!( IsPageFrame() && (pLowerFrame ->getFrameArea().Height()>0) && (pLowerFrame-> isFrameAreaDefinitionValid()) )))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" ":" "3262" ": "), "%s", "ChgLowersProg - negative height for lower." ); } } while (false); | ||||||||||||
3263 | nNewHeight = 0; | ||||||||||||
3264 | } | ||||||||||||
3265 | |||||||||||||
3266 | SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*pLowerFrame); | ||||||||||||
3267 | aFrm.Height( nNewHeight ); | ||||||||||||
3268 | } | ||||||||||||
3269 | } | ||||||||||||
3270 | } | ||||||||||||
3271 | else | ||||||||||||
3272 | { | ||||||||||||
3273 | SwTwips nNewHeight; | ||||||||||||
3274 | // OD 24.10.2002 #97265# - <double> calculation | ||||||||||||
3275 | // Perform <double> calculation of new height, if | ||||||||||||
3276 | // one of the coefficients is greater than 50000 | ||||||||||||
3277 | if ( (pLowerFrame->getFrameArea().Height() > 50000) || | ||||||||||||
3278 | (getFramePrintArea().Height() > 50000) ) | ||||||||||||
3279 | { | ||||||||||||
3280 | double nNewHeightTmp = | ||||||||||||
3281 | ( double(pLowerFrame->getFrameArea().Height()) | ||||||||||||
3282 | * double(getFramePrintArea().Height()) ) | ||||||||||||
3283 | / double(rOldSize.Height()); | ||||||||||||
3284 | nNewHeight = SwTwips(nNewHeightTmp); | ||||||||||||
3285 | } | ||||||||||||
3286 | else | ||||||||||||
3287 | { | ||||||||||||
3288 | nNewHeight = ( pLowerFrame->getFrameArea().Height() | ||||||||||||
3289 | * getFramePrintArea().Height() ) / rOldSize.Height(); | ||||||||||||
3290 | } | ||||||||||||
3291 | if( !pLowerFrame->GetNext() ) | ||||||||||||
3292 | { | ||||||||||||
3293 | SwTwips nSum = getFramePrintArea().Height(); | ||||||||||||
3294 | SwFrame* pTmp = Lower(); | ||||||||||||
3295 | while( pTmp->GetNext() ) | ||||||||||||
3296 | { | ||||||||||||
3297 | if( !pTmp->IsFootnoteContFrame() || !pTmp->IsVertical() ) | ||||||||||||
3298 | nSum -= pTmp->getFrameArea().Height(); | ||||||||||||
3299 | pTmp = pTmp->GetNext(); | ||||||||||||
3300 | } | ||||||||||||
3301 | if( nSum - nNewHeight == 1 && | ||||||||||||
3302 | nSum == pLowerFrame->getFrameArea().Height() ) | ||||||||||||
3303 | nNewHeight = nSum; | ||||||||||||
3304 | } | ||||||||||||
3305 | |||||||||||||
3306 | SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*pLowerFrame); | ||||||||||||
3307 | aFrm.Height( nNewHeight ); | ||||||||||||
3308 | } | ||||||||||||
3309 | } | ||||||||||||
3310 | } | ||||||||||||
3311 | } | ||||||||||||
3312 | } // end of else { NOT text frame } | ||||||||||||
3313 | |||||||||||||
3314 | pLowerFrame->InvalidateAll_(); | ||||||||||||
3315 | if ( bInvaPageForContent && pLowerFrame->IsContentFrame() ) | ||||||||||||
3316 | { | ||||||||||||
3317 | pLowerFrame->InvalidatePage(); | ||||||||||||
3318 | bInvaPageForContent = false; | ||||||||||||
3319 | } | ||||||||||||
3320 | |||||||||||||
3321 | if ( !pLowerFrame->GetNext() && pLowerFrame->IsRetoucheFrame() ) | ||||||||||||
3322 | { | ||||||||||||
3323 | //If a growth took place and the subordinate elements can retouch | ||||||||||||
3324 | //itself (currently Tabs, Sections and Content) we trigger it. | ||||||||||||
3325 | if ( rOldSize.Height() < getFramePrintArea().SSize().Height() || | ||||||||||||
3326 | rOldSize.Width() < getFramePrintArea().SSize().Width() ) | ||||||||||||
3327 | pLowerFrame->SetRetouche(); | ||||||||||||
3328 | } | ||||||||||||
3329 | pLowerFrame = pLowerFrame->GetNext(); | ||||||||||||
3330 | } | ||||||||||||
3331 | |||||||||||||
3332 | // Finally adjust the columns if width is set to auto | ||||||||||||
3333 | // Possible optimization: execute this code earlier in this function and | ||||||||||||
3334 | // return??? | ||||||||||||
3335 | if ( !(( (aRectFnSet.IsVert() && bHeightChgd) || (! aRectFnSet.IsVert() && bWidthChgd) ) && | ||||||||||||
3336 | Lower()->IsColumnFrame()) ) | ||||||||||||
3337 | return; | ||||||||||||
3338 | |||||||||||||
3339 | // get column attribute | ||||||||||||
3340 | const SwFormatCol* pColAttr = nullptr; | ||||||||||||
3341 | if ( IsPageBodyFrame() ) | ||||||||||||
3342 | { | ||||||||||||
3343 | OSL_ENSURE( GetUpper()->IsPageFrame(), "Upper is not page frame" )do { if (true && (!(GetUpper()->IsPageFrame()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl" ), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" ":" "3343" ": "), "%s", "Upper is not page frame"); } } while (false); | ||||||||||||
3344 | pColAttr = &GetUpper()->GetFormat()->GetCol(); | ||||||||||||
3345 | } | ||||||||||||
3346 | else | ||||||||||||
3347 | { | ||||||||||||
3348 | OSL_ENSURE( IsFlyFrame() || IsSctFrame(), "Columns not in fly or section" )do { if (true && (!(IsFlyFrame() || IsSctFrame()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl" ), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" ":" "3348" ": "), "%s", "Columns not in fly or section"); } } while (false); | ||||||||||||
3349 | pColAttr = &GetFormat()->GetCol(); | ||||||||||||
3350 | } | ||||||||||||
3351 | |||||||||||||
3352 | if ( pColAttr->IsOrtho() && pColAttr->GetNumCols() > 1 ) | ||||||||||||
3353 | AdjustColumns( pColAttr, false ); | ||||||||||||
3354 | } | ||||||||||||
3355 | |||||||||||||
3356 | /** "Formats" the Frame; Frame and PrtArea. | ||||||||||||
3357 | * | ||||||||||||
3358 | * The Fixsize is not set here. | ||||||||||||
3359 | */ | ||||||||||||
3360 | void SwLayoutFrame::Format( vcl::RenderContext* /*pRenderContext*/, const SwBorderAttrs *pAttrs ) | ||||||||||||
3361 | { | ||||||||||||
3362 | OSL_ENSURE( pAttrs, "LayoutFrame::Format, pAttrs is 0." )do { if (true && (!(pAttrs))) { sal_detail_logFormat( (SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" ":" "3362" ": "), "%s", "LayoutFrame::Format, pAttrs is 0.") ; } } while (false); | ||||||||||||
3363 | |||||||||||||
3364 | if ( isFramePrintAreaValid() && isFrameAreaSizeValid() ) | ||||||||||||
3365 | return; | ||||||||||||
3366 | |||||||||||||
3367 | bool bHideWhitespace = false; | ||||||||||||
3368 | if (IsPageFrame()) | ||||||||||||
3369 | { | ||||||||||||
3370 | SwViewShell* pShell = getRootFrame()->GetCurrShell(); | ||||||||||||
3371 | if (pShell && pShell->GetViewOptions()->IsWhitespaceHidden()) | ||||||||||||
3372 | { | ||||||||||||
3373 | // This is needed so that no space is reserved for the margin on | ||||||||||||
3374 | // the last page of the document. Other pages would have no margin | ||||||||||||
3375 | // set even without this, as their frame height is the content | ||||||||||||
3376 | // height already. | ||||||||||||
3377 | bHideWhitespace = true; | ||||||||||||
3378 | } | ||||||||||||
3379 | } | ||||||||||||
3380 | |||||||||||||
3381 | const sal_uInt16 nLeft = static_cast<sal_uInt16>(pAttrs->CalcLeft(this)); | ||||||||||||
3382 | const sal_uInt16 nUpper = bHideWhitespace ? 0 : pAttrs->CalcTop(); | ||||||||||||
3383 | |||||||||||||
3384 | const sal_uInt16 nRight = static_cast<sal_uInt16>(pAttrs->CalcRight(this)); | ||||||||||||
3385 | const sal_uInt16 nLower = bHideWhitespace ? 0 : pAttrs->CalcBottom(); | ||||||||||||
3386 | |||||||||||||
3387 | const bool bVert = IsVertical() && !IsPageFrame(); | ||||||||||||
3388 | SwRectFn fnRect = bVert ? ( IsVertLR() ? (IsVertLRBT() ? fnRectVertL2RB2T : fnRectVertL2R) : fnRectVert ) : fnRectHori; | ||||||||||||
3389 | if ( !isFramePrintAreaValid() ) | ||||||||||||
3390 | { | ||||||||||||
3391 | setFramePrintAreaValid(true); | ||||||||||||
3392 | (this->*fnRect->fnSetXMargins)( nLeft, nRight ); | ||||||||||||
3393 | (this->*fnRect->fnSetYMargins)( nUpper, nLower ); | ||||||||||||
3394 | } | ||||||||||||
3395 | |||||||||||||
3396 | if ( isFrameAreaSizeValid() ) | ||||||||||||
3397 | return; | ||||||||||||
3398 | |||||||||||||
3399 | if ( !HasFixSize() ) | ||||||||||||
3400 | { | ||||||||||||
3401 | const SwTwips nBorder = nUpper + nLower; | ||||||||||||
3402 | const SwFormatFrameSize &rSz = GetFormat()->GetFrameSize(); | ||||||||||||
3403 | SwTwips nMinHeight = rSz.GetHeightSizeType() == SwFrameSize::Minimum ? rSz.GetHeight() : 0; | ||||||||||||
3404 | do | ||||||||||||
3405 | { | ||||||||||||
3406 | setFrameAreaSizeValid(true); | ||||||||||||
3407 | |||||||||||||
3408 | //The size in VarSize is calculated using the content plus the | ||||||||||||
3409 | // borders. | ||||||||||||
3410 | SwTwips nRemaining = 0; | ||||||||||||
3411 | SwFrame *pFrame = Lower(); | ||||||||||||
3412 | while ( pFrame ) | ||||||||||||
3413 | { nRemaining += (pFrame->getFrameArea().*fnRect->fnGetHeight)(); | ||||||||||||
3414 | if( pFrame->IsTextFrame() && static_cast<SwTextFrame*>(pFrame)->IsUndersized() ) | ||||||||||||
3415 | // This TextFrame would like to be a bit bigger | ||||||||||||
3416 | nRemaining += static_cast<SwTextFrame*>(pFrame)->GetParHeight() | ||||||||||||
3417 | - (pFrame->getFramePrintArea().*fnRect->fnGetHeight)(); | ||||||||||||
3418 | else if( pFrame->IsSctFrame() && static_cast<SwSectionFrame*>(pFrame)->IsUndersized() ) | ||||||||||||
3419 | nRemaining += static_cast<SwSectionFrame*>(pFrame)->Undersize(); | ||||||||||||
3420 | pFrame = pFrame->GetNext(); | ||||||||||||
3421 | } | ||||||||||||
3422 | nRemaining += nBorder; | ||||||||||||
3423 | nRemaining = std::max( nRemaining, nMinHeight ); | ||||||||||||
3424 | const SwTwips nDiff = nRemaining-(getFrameArea().*fnRect->fnGetHeight)(); | ||||||||||||
3425 | const long nOldLeft = (getFrameArea().*fnRect->fnGetLeft)(); | ||||||||||||
3426 | const long nOldTop = (getFrameArea().*fnRect->fnGetTop)(); | ||||||||||||
3427 | if ( nDiff ) | ||||||||||||
3428 | { | ||||||||||||
3429 | if ( nDiff > 0 ) | ||||||||||||
3430 | Grow( nDiff ); | ||||||||||||
3431 | else | ||||||||||||
3432 | Shrink( -nDiff ); | ||||||||||||
3433 | //Updates the positions using the fast channel. | ||||||||||||
3434 | MakePos(); | ||||||||||||
3435 | } | ||||||||||||
3436 | //Don't exceed the bottom edge of the Upper. | ||||||||||||
3437 | if ( GetUpper() && (getFrameArea().*fnRect->fnGetHeight)() ) | ||||||||||||
3438 | { | ||||||||||||
3439 | const SwTwips nLimit = (GetUpper()->*fnRect->fnGetPrtBottom)(); | ||||||||||||
3440 | if( (this->*fnRect->fnSetLimit)( nLimit ) && | ||||||||||||
3441 | nOldLeft == (getFrameArea().*fnRect->fnGetLeft)() && | ||||||||||||
3442 | nOldTop == (getFrameArea().*fnRect->fnGetTop)() ) | ||||||||||||
3443 | { | ||||||||||||
3444 | setFrameAreaSizeValid(true); | ||||||||||||
3445 | setFramePrintAreaValid(true); | ||||||||||||
3446 | } | ||||||||||||
3447 | } | ||||||||||||
3448 | } while ( !isFrameAreaSizeValid() ); | ||||||||||||
3449 | } | ||||||||||||
3450 | else if (GetType() & FRM_HEADFOOT(SwFrameType::Header | SwFrameType::Footer)) | ||||||||||||
3451 | { | ||||||||||||
3452 | do | ||||||||||||
3453 | { if ( getFrameArea().Height() != pAttrs->GetSize().Height() ) | ||||||||||||
3454 | { | ||||||||||||
3455 | ChgSize( Size( getFrameArea().Width(), pAttrs->GetSize().Height())); | ||||||||||||
3456 | } | ||||||||||||
3457 | |||||||||||||
3458 | setFrameAreaSizeValid(true); | ||||||||||||
3459 | MakePos(); | ||||||||||||
3460 | } while ( !isFrameAreaSizeValid() ); | ||||||||||||
3461 | } | ||||||||||||
3462 | else | ||||||||||||
3463 | { | ||||||||||||
3464 | setFrameAreaSizeValid(true); | ||||||||||||
3465 | } | ||||||||||||
3466 | |||||||||||||
3467 | // While updating the size, PrtArea might be invalidated. | ||||||||||||
3468 | if (!isFramePrintAreaValid()) | ||||||||||||
3469 | { | ||||||||||||
3470 | setFramePrintAreaValid(true); | ||||||||||||
3471 | (this->*fnRect->fnSetXMargins)(nLeft, nRight); | ||||||||||||
3472 | (this->*fnRect->fnSetYMargins)(nUpper, nLower); | ||||||||||||
3473 | } | ||||||||||||
3474 | } | ||||||||||||
3475 | |||||||||||||
3476 | static void InvaPercentFlys( SwFrame *pFrame, SwTwips nDiff ) | ||||||||||||
3477 | { | ||||||||||||
3478 | OSL_ENSURE( pFrame->GetDrawObjs(), "Can't find any Objects" )do { if (true && (!(pFrame->GetDrawObjs()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" ":" "3478" ": "), "%s", "Can't find any Objects"); } } while (false); | ||||||||||||
3479 | for (SwAnchoredObject* pAnchoredObj : *pFrame->GetDrawObjs()) | ||||||||||||
3480 | { | ||||||||||||
3481 | if ( dynamic_cast< const SwFlyFrame *>( pAnchoredObj ) != nullptr ) | ||||||||||||
3482 | { | ||||||||||||
3483 | SwFlyFrame *pFly = static_cast<SwFlyFrame*>(pAnchoredObj); | ||||||||||||
3484 | const SwFormatFrameSize &rSz = pFly->GetFormat()->GetFrameSize(); | ||||||||||||
3485 | if ( rSz.GetWidthPercent() || rSz.GetHeightPercent() ) | ||||||||||||
3486 | { | ||||||||||||
3487 | bool bNotify = true; | ||||||||||||
3488 | // If we've a fly with more than 90% relative height... | ||||||||||||
3489 | if( rSz.GetHeightPercent() > 90 && pFly->GetAnchorFrame() && | ||||||||||||
3490 | rSz.GetHeightPercent() != SwFormatFrameSize::SYNCED && nDiff ) | ||||||||||||
3491 | { | ||||||||||||
3492 | const SwFrame *pRel = pFly->IsFlyLayFrame() ? pFly->GetAnchorFrame(): | ||||||||||||
3493 | pFly->GetAnchorFrame()->GetUpper(); | ||||||||||||
3494 | // ... and we have already more than 90% height and we | ||||||||||||
3495 | // not allow the text to go through... | ||||||||||||
3496 | // then a notification could cause an endless loop, e.g. | ||||||||||||
3497 | // 100% height and no text wrap inside a cell of a table. | ||||||||||||
3498 | if( pFly->getFrameArea().Height()*10 > | ||||||||||||
3499 | ( nDiff + pRel->getFramePrintArea().Height() )*9 && | ||||||||||||
3500 | pFly->GetFormat()->GetSurround().GetSurround() != | ||||||||||||
3501 | css::text::WrapTextMode_THROUGH ) | ||||||||||||
3502 | bNotify = false; | ||||||||||||
3503 | } | ||||||||||||
3504 | if( bNotify ) | ||||||||||||
3505 | pFly->InvalidateSize(); | ||||||||||||
3506 | } | ||||||||||||
3507 | } | ||||||||||||
3508 | } | ||||||||||||
3509 | } | ||||||||||||
3510 | |||||||||||||
3511 | void SwLayoutFrame::InvaPercentLowers( SwTwips nDiff ) | ||||||||||||
3512 | { | ||||||||||||
3513 | if ( GetDrawObjs() ) | ||||||||||||
3514 | ::InvaPercentFlys( this, nDiff ); | ||||||||||||
3515 | |||||||||||||
3516 | SwFrame *pFrame = ContainsContent(); | ||||||||||||
3517 | if ( !pFrame ) | ||||||||||||
3518 | return; | ||||||||||||
3519 | |||||||||||||
3520 | do | ||||||||||||
3521 | { | ||||||||||||
3522 | if ( pFrame->IsInTab() && !IsTabFrame() ) | ||||||||||||
3523 | { | ||||||||||||
3524 | SwFrame *pTmp = pFrame->FindTabFrame(); | ||||||||||||
3525 | OSL_ENSURE( pTmp, "Where's my TabFrame?" )do { if (true && (!(pTmp))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" ":" "3525" ": "), "%s", "Where's my TabFrame?"); } } while ( false); | ||||||||||||
3526 | if( IsAnLower( pTmp ) ) | ||||||||||||
3527 | pFrame = pTmp; | ||||||||||||
3528 | } | ||||||||||||
3529 | |||||||||||||
3530 | if ( pFrame->IsTabFrame() ) | ||||||||||||
3531 | { | ||||||||||||
3532 | const SwFormatFrameSize &rSz = static_cast<SwLayoutFrame*>(pFrame)->GetFormat()->GetFrameSize(); | ||||||||||||
3533 | if ( rSz.GetWidthPercent() || rSz.GetHeightPercent() ) | ||||||||||||
3534 | pFrame->InvalidatePrt(); | ||||||||||||
3535 | } | ||||||||||||
3536 | else if ( pFrame->GetDrawObjs() ) | ||||||||||||
3537 | ::InvaPercentFlys( pFrame, nDiff ); | ||||||||||||
3538 | pFrame = pFrame->FindNextCnt(); | ||||||||||||
3539 | } while ( pFrame && IsAnLower( pFrame ) ) ; | ||||||||||||
3540 | } | ||||||||||||
3541 | |||||||||||||
3542 | long SwLayoutFrame::CalcRel( const SwFormatFrameSize &rSz ) const | ||||||||||||
3543 | { | ||||||||||||
3544 | long nRet = rSz.GetWidth(), | ||||||||||||
3545 | nPercent = rSz.GetWidthPercent(); | ||||||||||||
3546 | |||||||||||||
3547 | if ( nPercent ) | ||||||||||||
3548 | { | ||||||||||||
3549 | const SwFrame *pRel = GetUpper(); | ||||||||||||
3550 | long nRel = LONG_MAX9223372036854775807L; | ||||||||||||
3551 | const SwViewShell *pSh = getRootFrame()->GetCurrShell(); | ||||||||||||
3552 | const bool bBrowseMode = pSh && pSh->GetViewOptions()->getBrowseMode(); | ||||||||||||
3553 | if( pRel->IsPageBodyFrame() && pSh && bBrowseMode && pSh->VisArea().Width() ) | ||||||||||||
3554 | { | ||||||||||||
3555 | nRel = pSh->GetBrowseWidth(); | ||||||||||||
3556 | long nDiff = nRel - pRel->getFramePrintArea().Width(); | ||||||||||||
3557 | if ( nDiff > 0 ) | ||||||||||||
3558 | nRel -= nDiff; | ||||||||||||
3559 | } | ||||||||||||
3560 | nRel = std::min( nRel, pRel->getFramePrintArea().Width() ); | ||||||||||||
3561 | nRet = nRel * nPercent / 100; | ||||||||||||
3562 | } | ||||||||||||
3563 | return nRet; | ||||||||||||
3564 | } | ||||||||||||
3565 | |||||||||||||
3566 | // Local helpers for SwLayoutFrame::FormatWidthCols() | ||||||||||||
3567 | |||||||||||||
3568 | static long lcl_CalcMinColDiff( SwLayoutFrame *pLayFrame ) | ||||||||||||
3569 | { | ||||||||||||
3570 | long nDiff = 0, nFirstDiff = 0; | ||||||||||||
3571 | SwLayoutFrame *pCol = static_cast<SwLayoutFrame*>(pLayFrame->Lower()); | ||||||||||||
3572 | OSL_ENSURE( pCol, "Where's the columnframe?" )do { if (true && (!(pCol))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" ":" "3572" ": "), "%s", "Where's the columnframe?"); } } while (false); | ||||||||||||
3573 | SwFrame *pFrame = pCol->Lower(); | ||||||||||||
3574 | do | ||||||||||||
3575 | { | ||||||||||||
3576 | if( pFrame && pFrame->IsBodyFrame() ) | ||||||||||||
3577 | pFrame = static_cast<SwBodyFrame*>(pFrame)->Lower(); | ||||||||||||
3578 | if ( pFrame && pFrame->IsTextFrame() ) | ||||||||||||
3579 | { | ||||||||||||
3580 | const long nTmp = static_cast<SwTextFrame*>(pFrame)->FirstLineHeight(); | ||||||||||||
3581 | if ( nTmp != USHRT_MAX(32767 *2 +1) ) | ||||||||||||
3582 | { | ||||||||||||
3583 | if ( pCol == pLayFrame->Lower() ) | ||||||||||||
3584 | nFirstDiff = nTmp; | ||||||||||||
3585 | else | ||||||||||||
3586 | nDiff = nDiff ? std::min( nDiff, nTmp ) : nTmp; | ||||||||||||
3587 | } | ||||||||||||
3588 | } | ||||||||||||
3589 | //Skip empty columns! | ||||||||||||
3590 | pCol = static_cast<SwLayoutFrame*>(pCol->GetNext()); | ||||||||||||
3591 | while ( pCol && nullptr == (pFrame = pCol->Lower()) ) | ||||||||||||
3592 | pCol = static_cast<SwLayoutFrame*>(pCol->GetNext()); | ||||||||||||
3593 | |||||||||||||
3594 | } while ( pFrame && pCol ); | ||||||||||||
3595 | |||||||||||||
3596 | return nDiff ? nDiff : nFirstDiff ? nFirstDiff : 240; | ||||||||||||
3597 | } | ||||||||||||
3598 | |||||||||||||
3599 | static bool lcl_IsFlyHeightClipped( SwLayoutFrame *pLay ) | ||||||||||||
3600 | { | ||||||||||||
3601 | SwFrame *pFrame = pLay->ContainsContent(); | ||||||||||||
3602 | while ( pFrame ) | ||||||||||||
3603 | { | ||||||||||||
3604 | if ( pFrame->IsInTab() ) | ||||||||||||
3605 | pFrame = pFrame->FindTabFrame(); | ||||||||||||
3606 | |||||||||||||
3607 | if ( pFrame->GetDrawObjs() ) | ||||||||||||
3608 | { | ||||||||||||
3609 | const size_t nCnt = pFrame->GetDrawObjs()->size(); | ||||||||||||
3610 | for ( size_t i = 0; i < nCnt; ++i ) | ||||||||||||
3611 | { | ||||||||||||
3612 | SwAnchoredObject* pAnchoredObj = (*pFrame->GetDrawObjs())[i]; | ||||||||||||
3613 | if ( dynamic_cast< const SwFlyFrame *>( pAnchoredObj ) != nullptr ) | ||||||||||||
3614 | { | ||||||||||||
3615 | SwFlyFrame* pFly = static_cast<SwFlyFrame*>(pAnchoredObj); | ||||||||||||
3616 | if ( pFly->IsHeightClipped() && | ||||||||||||
3617 | ( !pFly->IsFlyFreeFrame() || pFly->GetPageFrame() ) ) | ||||||||||||
3618 | return true; | ||||||||||||
3619 | } | ||||||||||||
3620 | } | ||||||||||||
3621 | } | ||||||||||||
3622 | pFrame = pFrame->FindNextCnt(); | ||||||||||||
3623 | } | ||||||||||||
3624 | return false; | ||||||||||||
3625 | } | ||||||||||||
3626 | |||||||||||||
3627 | void SwLayoutFrame::FormatWidthCols( const SwBorderAttrs &rAttrs, | ||||||||||||
3628 | const SwTwips nBorder, const SwTwips nMinHeight ) | ||||||||||||
3629 | { | ||||||||||||
3630 | //If there are columns involved, the size is adjusted using the last column. | ||||||||||||
3631 | //1. Format content. | ||||||||||||
3632 | //2. Calculate height of the last column: if it's too big, the Fly has to | ||||||||||||
3633 | // grow. The amount by which the Fly grows is not the amount of the | ||||||||||||
3634 | // overhang because we have to act on the assumption that some text flows | ||||||||||||
3635 | // back which will generate some more space. | ||||||||||||
3636 | // The amount which we grow by equals the overhang | ||||||||||||
3637 | // divided by the amount of columns or the overhang itself if it's smaller | ||||||||||||
3638 | // than the amount of columns. | ||||||||||||
3639 | //3. Go back to 1. until everything is stable. | ||||||||||||
3640 | |||||||||||||
3641 | const SwFormatCol &rCol = rAttrs.GetAttrSet().GetCol(); | ||||||||||||
3642 | const sal_uInt16 nNumCols = rCol.GetNumCols(); | ||||||||||||
| |||||||||||||
3643 | |||||||||||||
3644 | bool bEnd = false; | ||||||||||||
3645 | bool bBackLock = false; | ||||||||||||
3646 | SwViewShell *pSh = getRootFrame()->GetCurrShell(); | ||||||||||||
3647 | SwViewShellImp *pImp = pSh ? pSh->Imp() : nullptr; | ||||||||||||
3648 | vcl::RenderContext* pRenderContext = pSh
| ||||||||||||
3649 | { | ||||||||||||
3650 | // Underlying algorithm | ||||||||||||
3651 | // We try to find the optimal height for the column. | ||||||||||||
3652 | // nMinimum starts with the passed minimum height and is then remembered | ||||||||||||
3653 | // as the maximum height on which column content still juts out of a | ||||||||||||
3654 | // column. | ||||||||||||
3655 | // nMaximum starts with LONG_MAX and is then remembered as the minimum | ||||||||||||
3656 | // width on which the content fitted. | ||||||||||||
3657 | // In column based sections nMaximum starts at the maximum value which | ||||||||||||
3658 | // the surrounding defines, this can certainly be a value on which | ||||||||||||
3659 | // content still juts out. | ||||||||||||
3660 | // The columns are formatted. If content still juts out, nMinimum is | ||||||||||||
3661 | // adjusted accordingly, then we grow, at least by uMinDiff but not | ||||||||||||
3662 | // over a certain nMaximum. If no content juts out but there is still | ||||||||||||
3663 | // some space left in the column, shrinking is done accordingly, at | ||||||||||||
3664 | // least by nMindIff but not below the nMinimum. | ||||||||||||
3665 | // Cancel as soon as no content juts out and the difference from minimum | ||||||||||||
3666 | // to maximum is less than MinDiff or the maximum which was defined by | ||||||||||||
3667 | // the surrounding is reached even if some content still juts out. | ||||||||||||
3668 | |||||||||||||
3669 | // Criticism of this implementation | ||||||||||||
3670 | // 1. Theoretically situations are possible in which the content fits in | ||||||||||||
3671 | // a lower height but not in a higher height. To ensure that the code | ||||||||||||
3672 | // handles such situations the code contains a few checks concerning | ||||||||||||
3673 | // minimum and maximum which probably are never triggered. | ||||||||||||
3674 | // 2. We use the same nMinDiff for shrinking and growing, but nMinDiff | ||||||||||||
3675 | // is more or less the smallest first line height and doesn't seem ideal | ||||||||||||
3676 | // as minimum value. | ||||||||||||
3677 | |||||||||||||
3678 | long nMinimum = nMinHeight; | ||||||||||||
3679 | long nMaximum; | ||||||||||||
3680 | bool bNoBalance = false; | ||||||||||||
3681 | SwRectFnSet aRectFnSet(this); | ||||||||||||
3682 | if( IsSctFrame() ) | ||||||||||||
3683 | { | ||||||||||||
3684 | nMaximum = aRectFnSet.GetHeight(getFrameArea()) - nBorder + | ||||||||||||
3685 | aRectFnSet.BottomDist(getFrameArea(), aRectFnSet.GetPrtBottom(*GetUpper())); | ||||||||||||
3686 | nMaximum += GetUpper()->Grow( LONG_MAX9223372036854775807L, true ); | ||||||||||||
3687 | if( nMaximum < nMinimum ) | ||||||||||||
3688 | { | ||||||||||||
3689 | if( nMaximum < 0 ) | ||||||||||||
3690 | nMinimum = nMaximum = 0; | ||||||||||||
3691 | else | ||||||||||||
3692 | nMinimum = nMaximum; | ||||||||||||
3693 | } | ||||||||||||
3694 | if( nMaximum > BROWSE_HEIGHT(56700L * 10L) ) | ||||||||||||
3695 | nMaximum = BROWSE_HEIGHT(56700L * 10L); | ||||||||||||
3696 | |||||||||||||
3697 | bNoBalance = static_cast<SwSectionFrame*>(this)->GetSection()->GetFormat()-> | ||||||||||||
3698 | GetBalancedColumns().GetValue(); | ||||||||||||
3699 | SwFrame* pAny = ContainsAny(); | ||||||||||||
3700 | if( bNoBalance || | ||||||||||||
3701 | ( !aRectFnSet.GetHeight(getFrameArea()) && pAny ) ) | ||||||||||||
3702 | { | ||||||||||||
3703 | long nTop = aRectFnSet.GetTopMargin(*this); | ||||||||||||
3704 | // #i23129# - correction | ||||||||||||
3705 | // to the calculated maximum height. | ||||||||||||
3706 | { | ||||||||||||
3707 | SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this); | ||||||||||||
3708 | aRectFnSet.AddBottom( aFrm, nMaximum - aRectFnSet.GetHeight(getFrameArea()) ); | ||||||||||||
3709 | } | ||||||||||||
3710 | |||||||||||||
3711 | if( nTop > nMaximum ) | ||||||||||||
3712 | nTop = nMaximum; | ||||||||||||
3713 | aRectFnSet.SetYMargins( *this, nTop, 0 ); | ||||||||||||
3714 | } | ||||||||||||
3715 | if( !pAny && !static_cast<SwSectionFrame*>(this)->IsFootnoteLock() ) | ||||||||||||
3716 | { | ||||||||||||
3717 | SwFootnoteContFrame* pFootnoteCont = static_cast<SwSectionFrame*>(this)->ContainsFootnoteCont(); | ||||||||||||
3718 | if( pFootnoteCont ) | ||||||||||||
3719 | { | ||||||||||||
3720 | SwFrame* pFootnoteAny = pFootnoteCont->ContainsAny(); | ||||||||||||
3721 | if( pFootnoteAny && pFootnoteAny->isFrameAreaDefinitionValid() ) | ||||||||||||
3722 | { | ||||||||||||
3723 | bBackLock = true; | ||||||||||||
3724 | static_cast<SwSectionFrame*>(this)->SetFootnoteLock( true ); | ||||||||||||
3725 | } | ||||||||||||
3726 | } | ||||||||||||
3727 | } | ||||||||||||
3728 | } | ||||||||||||
3729 | else | ||||||||||||
3730 | nMaximum = LONG_MAX9223372036854775807L; | ||||||||||||
3731 | |||||||||||||
3732 | // #i3317# - reset temporarily consideration | ||||||||||||
3733 | // of wrapping style influence | ||||||||||||
3734 | SwPageFrame* pPageFrame = FindPageFrame(); | ||||||||||||
3735 | SwSortedObjs* pObjs = pPageFrame ? pPageFrame->GetSortedObjs() : nullptr; | ||||||||||||
3736 | if ( pObjs
| ||||||||||||
3737 | { | ||||||||||||
3738 | for (SwAnchoredObject* pAnchoredObj : *pObjs) | ||||||||||||
3739 | { | ||||||||||||
3740 | if ( IsAnLower( pAnchoredObj->GetAnchorFrame() ) ) | ||||||||||||
3741 | { | ||||||||||||
3742 | pAnchoredObj->SetTmpConsiderWrapInfluence( false ); | ||||||||||||
3743 | } | ||||||||||||
3744 | } | ||||||||||||
3745 | } | ||||||||||||
3746 | do | ||||||||||||
3747 | { | ||||||||||||
3748 | //Could take a while therefore check for Waitcrsr here. | ||||||||||||
3749 | if ( pImp
| ||||||||||||
3750 | pImp->CheckWaitCursor(); | ||||||||||||
3751 | |||||||||||||
3752 | setFrameAreaSizeValid(true); | ||||||||||||
3753 | //First format the column as this will relieve the stack a bit. | ||||||||||||
3754 | //Also set width and height of the column (if they are wrong) | ||||||||||||
3755 | //while we are at it. | ||||||||||||
3756 | SwLayoutFrame *pCol = static_cast<SwLayoutFrame*>(Lower()); | ||||||||||||
3757 | |||||||||||||
3758 | // #i27399# | ||||||||||||
3759 | // Simply setting the column width based on the values returned by | ||||||||||||
3760 | // CalcColWidth does not work for automatic column width. | ||||||||||||
3761 | AdjustColumns( &rCol, false ); | ||||||||||||
3762 | |||||||||||||
3763 | for ( sal_uInt16 i = 0; i < nNumCols; ++i ) | ||||||||||||
3764 | { | ||||||||||||
3765 | pCol->Calc(pRenderContext); | ||||||||||||
3766 | // ColumnFrames have a BodyFrame now, which needs to be calculated | ||||||||||||
3767 | pCol->Lower()->Calc(pRenderContext); | ||||||||||||
3768 | if( pCol->Lower()->GetNext() ) | ||||||||||||
3769 | pCol->Lower()->GetNext()->Calc(pRenderContext); // SwFootnoteCont | ||||||||||||
3770 | pCol = static_cast<SwLayoutFrame*>(pCol->GetNext()); | ||||||||||||
3771 | } | ||||||||||||
3772 | |||||||||||||
3773 | ::CalcContent( this ); | ||||||||||||
3774 | |||||||||||||
3775 | pCol = static_cast<SwLayoutFrame*>(Lower()); | ||||||||||||
3776 | OSL_ENSURE( pCol && pCol->GetNext(), ":-( column making holidays?")do { if (true && (!(pCol && pCol->GetNext( )))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl" ), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" ":" "3776" ": "), "%s", ":-( column making holidays?"); } } while (false); | ||||||||||||
3777 | // set bMinDiff if no empty columns exist | ||||||||||||
3778 | bool bMinDiff = true; | ||||||||||||
3779 | // OD 28.03.2003 #108446# - check for all column content and all columns | ||||||||||||
3780 | while ( bMinDiff
| ||||||||||||
3781 | { | ||||||||||||
3782 | bMinDiff = nullptr != pCol->ContainsContent(); | ||||||||||||
3783 | pCol = static_cast<SwLayoutFrame*>(pCol->GetNext()); | ||||||||||||
3784 | } | ||||||||||||
3785 | pCol = static_cast<SwLayoutFrame*>(Lower()); | ||||||||||||
3786 | // OD 28.03.2003 #108446# - initialize local variable | ||||||||||||
3787 | SwTwips nDiff = 0; | ||||||||||||
3788 | SwTwips nMaxFree = 0; | ||||||||||||
3789 | SwTwips nAllFree = LONG_MAX9223372036854775807L; | ||||||||||||
3790 | // set bFoundLower if there is at least one non-empty column | ||||||||||||
3791 | bool bFoundLower = false; | ||||||||||||
3792 | while( pCol ) | ||||||||||||
3793 | { | ||||||||||||
3794 | SwLayoutFrame* pLay = static_cast<SwLayoutFrame*>(pCol->Lower()); | ||||||||||||
3795 | SwTwips nInnerHeight = aRectFnSet.GetHeight(pLay->getFrameArea()) - | ||||||||||||
3796 | aRectFnSet.GetHeight(pLay->getFramePrintArea()); | ||||||||||||
3797 | if( pLay->Lower() ) | ||||||||||||
3798 | { | ||||||||||||
3799 | bFoundLower = true; | ||||||||||||
3800 | nInnerHeight += pLay->InnerHeight(); | ||||||||||||
3801 | } | ||||||||||||
3802 | else if( nInnerHeight < 0 ) | ||||||||||||
3803 | nInnerHeight = 0; | ||||||||||||
3804 | |||||||||||||
3805 | if( pLay->GetNext() ) | ||||||||||||
3806 | { | ||||||||||||
3807 | bFoundLower = true; | ||||||||||||
3808 | pLay = static_cast<SwLayoutFrame*>(pLay->GetNext()); | ||||||||||||
3809 | OSL_ENSURE( pLay->IsFootnoteContFrame(),"FootnoteContainer expected" )do { if (true && (!(pLay->IsFootnoteContFrame()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl" ), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" ":" "3809" ": "), "%s", "FootnoteContainer expected"); } } while (false); | ||||||||||||
3810 | nInnerHeight += pLay->InnerHeight(); | ||||||||||||
3811 | nInnerHeight += aRectFnSet.GetHeight(pLay->getFrameArea()) - | ||||||||||||
3812 | aRectFnSet.GetHeight(pLay->getFramePrintArea()); | ||||||||||||
3813 | } | ||||||||||||
3814 | nInnerHeight -= aRectFnSet.GetHeight(pCol->getFramePrintArea()); | ||||||||||||
3815 | if( nInnerHeight > nDiff ) | ||||||||||||
3816 | { | ||||||||||||
3817 | nDiff = nInnerHeight; | ||||||||||||
3818 | nAllFree = 0; | ||||||||||||
3819 | } | ||||||||||||
3820 | else | ||||||||||||
3821 | { | ||||||||||||
3822 | if( nMaxFree < -nInnerHeight ) | ||||||||||||
3823 | nMaxFree = -nInnerHeight; | ||||||||||||
3824 | if( nAllFree > -nInnerHeight ) | ||||||||||||
3825 | nAllFree = -nInnerHeight; | ||||||||||||
3826 | } | ||||||||||||
3827 | pCol = static_cast<SwLayoutFrame*>(pCol->GetNext()); | ||||||||||||
3828 | } | ||||||||||||
3829 | |||||||||||||
3830 | if ( bFoundLower
| ||||||||||||
3831 | { | ||||||||||||
3832 | SwTwips nMinDiff = ::lcl_CalcMinColDiff( this ); | ||||||||||||
3833 | // Here we decide if growing is needed - this is the case, if | ||||||||||||
3834 | // column content (nDiff) or a Fly juts over. | ||||||||||||
3835 | // In sections with columns we take into account to set the size | ||||||||||||
3836 | // when having a non-empty Follow. | ||||||||||||
3837 | if ( nDiff
| ||||||||||||
3838 | ( IsSctFrame() && static_cast<SwSectionFrame*>(this)->CalcMinDiff( nMinDiff ) ) ) | ||||||||||||
3839 | { | ||||||||||||
3840 | long nPrtHeight = aRectFnSet.GetHeight(getFramePrintArea()); | ||||||||||||
3841 | // The minimum must not be smaller than our PrtHeight as | ||||||||||||
3842 | // long as something juts over. | ||||||||||||
3843 | if( nMinimum < nPrtHeight ) | ||||||||||||
3844 | nMinimum = nPrtHeight; | ||||||||||||
3845 | // The maximum must not be smaller than PrtHeight if | ||||||||||||
3846 | // something still juts over. | ||||||||||||
3847 | if( nMaximum
| ||||||||||||
3848 | nMaximum = nPrtHeight; // Robust, but will this ever happen? | ||||||||||||
3849 | if( !nDiff
| ||||||||||||
3850 | nDiff = nMinDiff; | ||||||||||||
3851 | // If we should grow more than by nMinDiff we split it over | ||||||||||||
3852 | // the columns | ||||||||||||
3853 | if ( std::abs(nDiff - nMinDiff) > nNumCols && nDiff > static_cast<long>(nNumCols) ) | ||||||||||||
3854 | nDiff /= nNumCols; | ||||||||||||
| |||||||||||||
3855 | |||||||||||||
3856 | if ( bMinDiff ) | ||||||||||||
3857 | { // If no empty column exists, we want to grow at least | ||||||||||||
3858 | // by nMinDiff. Special case: If we are smaller than the | ||||||||||||
3859 | // minimal FrameHeight and PrtHeight is smaller than | ||||||||||||
3860 | // nMindiff we grow in a way that PrtHeight is exactly | ||||||||||||
3861 | // nMinDiff afterwards. | ||||||||||||
3862 | long nFrameHeight = aRectFnSet.GetHeight(getFrameArea()); | ||||||||||||
3863 | if ( nFrameHeight > nMinHeight || nPrtHeight >= nMinDiff ) | ||||||||||||
3864 | nDiff = std::max( nDiff, nMinDiff ); | ||||||||||||
3865 | else if( nDiff < nMinDiff ) | ||||||||||||
3866 | nDiff = nMinDiff - nPrtHeight + 1; | ||||||||||||
3867 | } | ||||||||||||
3868 | // nMaximum has a size which fits the content or the | ||||||||||||
3869 | // requested value from the surrounding therefore we don't | ||||||||||||
3870 | // need to exceed this value. | ||||||||||||
3871 | if( nDiff + nPrtHeight > nMaximum ) | ||||||||||||
3872 | nDiff = nMaximum - nPrtHeight; | ||||||||||||
3873 | } | ||||||||||||
3874 | else if( nMaximum > nMinimum ) // We fit, do we still have some margin? | ||||||||||||
3875 | { | ||||||||||||
3876 | long nPrtHeight = aRectFnSet.GetHeight(getFramePrintArea()); | ||||||||||||
3877 | if ( nMaximum < nPrtHeight ) | ||||||||||||
3878 | nDiff = nMaximum - nPrtHeight; // We grew over a working | ||||||||||||
3879 | // height and shrink back to it, but will this ever | ||||||||||||
3880 | // happen? | ||||||||||||
3881 | else | ||||||||||||
3882 | { // We have a new maximum, a size which fits for the content. | ||||||||||||
3883 | nMaximum = nPrtHeight; | ||||||||||||
3884 | // If the margin in the column is bigger than nMinDiff | ||||||||||||
3885 | // and we therefore drop under the minimum, we deflate | ||||||||||||
3886 | // a bit. | ||||||||||||
3887 | if ( !bNoBalance && | ||||||||||||
3888 | // #i23129# - <nMinDiff> can be | ||||||||||||
3889 | // big, because of an object at the beginning of | ||||||||||||
3890 | // a column. Thus, decrease optimization here. | ||||||||||||
3891 | //nMaxFree >= nMinDiff && | ||||||||||||
3892 | nMaxFree > 0 && | ||||||||||||
3893 | ( !nAllFree || | ||||||||||||
3894 | nMinimum < nPrtHeight - nMinDiff ) ) | ||||||||||||
3895 | { | ||||||||||||
3896 | nMaxFree /= nNumCols; // disperse over the columns | ||||||||||||
3897 | nDiff = nMaxFree < nMinDiff ? -nMinDiff : -nMaxFree; // min nMinDiff | ||||||||||||
3898 | if( nPrtHeight + nDiff <= nMinimum ) // below the minimum? | ||||||||||||
3899 | nDiff = ( nMinimum - nMaximum ) / 2; // Take the center | ||||||||||||
3900 | } | ||||||||||||
3901 | else if( nAllFree ) | ||||||||||||
3902 | { | ||||||||||||
3903 | nDiff = -nAllFree; | ||||||||||||
3904 | if( nPrtHeight + nDiff <= nMinimum ) // Less than minimum? | ||||||||||||
3905 | nDiff = ( nMinimum - nMaximum ) / 2; // Take the center | ||||||||||||
3906 | } | ||||||||||||
3907 | } | ||||||||||||
3908 | } | ||||||||||||
3909 | if( nDiff ) // now we shrink or grow... | ||||||||||||
3910 | { | ||||||||||||
3911 | Size aOldSz( getFramePrintArea().SSize() ); | ||||||||||||
3912 | long nTop = aRectFnSet.GetTopMargin(*this); | ||||||||||||
3913 | nDiff = aRectFnSet.GetHeight(getFramePrintArea()) + nDiff + nBorder - aRectFnSet.GetHeight(getFrameArea()); | ||||||||||||
3914 | |||||||||||||
3915 | { | ||||||||||||
3916 | SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this); | ||||||||||||
3917 | aRectFnSet.AddBottom( aFrm, nDiff ); | ||||||||||||
3918 | } | ||||||||||||
3919 | |||||||||||||
3920 | // #i68520# | ||||||||||||
3921 | SwFlyFrame *pFlyFrame = dynamic_cast<SwFlyFrame*>(this); | ||||||||||||
3922 | if (pFlyFrame) | ||||||||||||
3923 | { | ||||||||||||
3924 | pFlyFrame->InvalidateObjRectWithSpaces(); | ||||||||||||
3925 | } | ||||||||||||
3926 | aRectFnSet.SetYMargins( *this, nTop, nBorder - nTop ); | ||||||||||||
3927 | ChgLowersProp( aOldSz ); | ||||||||||||
3928 | NotifyLowerObjs(); | ||||||||||||
3929 | |||||||||||||
3930 | // #i3317# - reset temporarily consideration | ||||||||||||
3931 | // of wrapping style influence | ||||||||||||
3932 | SwPageFrame* pTmpPageFrame = FindPageFrame(); | ||||||||||||
3933 | SwSortedObjs* pTmpObjs = pTmpPageFrame ? pTmpPageFrame->GetSortedObjs() : nullptr; | ||||||||||||
3934 | if ( pTmpObjs ) | ||||||||||||
3935 | { | ||||||||||||
3936 | for (SwAnchoredObject* pAnchoredObj : *pTmpObjs) | ||||||||||||
3937 | { | ||||||||||||
3938 | if ( IsAnLower( pAnchoredObj->GetAnchorFrame() ) ) | ||||||||||||
3939 | { | ||||||||||||
3940 | pAnchoredObj->SetTmpConsiderWrapInfluence( false ); | ||||||||||||
3941 | } | ||||||||||||
3942 | } | ||||||||||||
3943 | } | ||||||||||||
3944 | //Invalidate suitable to nicely balance the Frames. | ||||||||||||
3945 | //- Every first one after the second column gets a | ||||||||||||
3946 | // InvalidatePos(); | ||||||||||||
3947 | pCol = static_cast<SwLayoutFrame*>(Lower()->GetNext()); | ||||||||||||
3948 | while ( pCol ) | ||||||||||||
3949 | { | ||||||||||||
3950 | SwFrame *pLow = pCol->Lower(); | ||||||||||||
3951 | if ( pLow ) | ||||||||||||
3952 | pLow->InvalidatePos_(); | ||||||||||||
3953 | pCol = static_cast<SwLayoutFrame*>(pCol->GetNext()); | ||||||||||||
3954 | } | ||||||||||||
3955 | if( IsSctFrame() && static_cast<SwSectionFrame*>(this)->HasFollow() ) | ||||||||||||
3956 | { | ||||||||||||
3957 | // If we created a Follow, we need to give its content | ||||||||||||
3958 | // the opportunity to flow back inside the CalcContent | ||||||||||||
3959 | SwContentFrame* pTmpContent = | ||||||||||||
3960 | static_cast<SwSectionFrame*>(this)->GetFollow()->ContainsContent(); | ||||||||||||
3961 | if( pTmpContent ) | ||||||||||||
3962 | pTmpContent->InvalidatePos_(); | ||||||||||||
3963 | } | ||||||||||||
3964 | } | ||||||||||||
3965 | else | ||||||||||||
3966 | bEnd = true; | ||||||||||||
3967 | } | ||||||||||||
3968 | else | ||||||||||||
3969 | bEnd = true; | ||||||||||||
3970 | |||||||||||||
3971 | } while ( !bEnd || !isFrameAreaSizeValid() ); | ||||||||||||
3972 | } | ||||||||||||
3973 | // OD 01.04.2003 #108446# - Don't collect endnotes for sections. Thus, set | ||||||||||||
3974 | // 2nd parameter to <true>. | ||||||||||||
3975 | ::CalcContent( this, true ); | ||||||||||||
3976 | if( IsSctFrame() ) | ||||||||||||
3977 | { | ||||||||||||
3978 | // OD 14.03.2003 #i11760# - adjust 2nd parameter - sal_True --> true | ||||||||||||
3979 | ::CalcContent( this, true ); | ||||||||||||
3980 | if( bBackLock ) | ||||||||||||
3981 | static_cast<SwSectionFrame*>(this)->SetFootnoteLock( false ); | ||||||||||||
3982 | } | ||||||||||||
3983 | } | ||||||||||||
3984 | |||||||||||||
3985 | static SwContentFrame* lcl_InvalidateSection( SwFrame *pCnt, SwInvalidateFlags nInv ) | ||||||||||||
3986 | { | ||||||||||||
3987 | SwSectionFrame* pSect = pCnt->FindSctFrame(); | ||||||||||||
3988 | // If our ContentFrame is placed inside a table or a footnote, only sections | ||||||||||||
3989 | // which are also placed inside are meant. | ||||||||||||
3990 | // Exception: If a table is directly passed. | ||||||||||||
3991 | if( ( ( pCnt->IsInTab() && !pSect->IsInTab() ) || | ||||||||||||
3992 | ( pCnt->IsInFootnote() && !pSect->IsInFootnote() ) ) && !pCnt->IsTabFrame() ) | ||||||||||||
3993 | return nullptr; | ||||||||||||
3994 | if( nInv & SwInvalidateFlags::Size ) | ||||||||||||
3995 | pSect->InvalidateSize_(); | ||||||||||||
3996 | if( nInv & SwInvalidateFlags::Pos ) | ||||||||||||
3997 | pSect->InvalidatePos_(); | ||||||||||||
3998 | if( nInv & SwInvalidateFlags::PrtArea ) | ||||||||||||
3999 | pSect->InvalidatePrt_(); | ||||||||||||
4000 | SwFlowFrame *pFoll = pSect->GetFollow(); | ||||||||||||
4001 | // Temporary separation from follow | ||||||||||||
4002 | pSect->SetFollow( nullptr ); | ||||||||||||
4003 | SwContentFrame* pRet = pSect->FindLastContent(); | ||||||||||||
4004 | pSect->SetFollow( pFoll ); | ||||||||||||
4005 | return pRet; | ||||||||||||
4006 | } | ||||||||||||
4007 | |||||||||||||
4008 | static SwContentFrame* lcl_InvalidateTable( SwTabFrame *pTable, SwInvalidateFlags nInv ) | ||||||||||||
4009 | { | ||||||||||||
4010 | if( ( nInv & SwInvalidateFlags::Section ) && pTable->IsInSct() ) | ||||||||||||
4011 | lcl_InvalidateSection( pTable, nInv ); | ||||||||||||
4012 | if( nInv & SwInvalidateFlags::Size ) | ||||||||||||
4013 | pTable->InvalidateSize_(); | ||||||||||||
4014 | if( nInv & SwInvalidateFlags::Pos ) | ||||||||||||
4015 | pTable->InvalidatePos_(); | ||||||||||||
4016 | if( nInv & SwInvalidateFlags::PrtArea ) | ||||||||||||
4017 | pTable->InvalidatePrt_(); | ||||||||||||
4018 | return pTable->FindLastContent(); | ||||||||||||
4019 | } | ||||||||||||
4020 | |||||||||||||
4021 | static void lcl_InvalidateAllContent( SwContentFrame *pCnt, SwInvalidateFlags nInv ); | ||||||||||||
4022 | |||||||||||||
4023 | static void lcl_InvalidateContent( SwContentFrame *pCnt, SwInvalidateFlags nInv ) | ||||||||||||
4024 | { | ||||||||||||
4025 | SwContentFrame *pLastTabCnt = nullptr; | ||||||||||||
4026 | SwContentFrame *pLastSctCnt = nullptr; | ||||||||||||
4027 | while ( pCnt ) | ||||||||||||
4028 | { | ||||||||||||
4029 | if( nInv & SwInvalidateFlags::Section ) | ||||||||||||
4030 | { | ||||||||||||
4031 | if( pCnt->IsInSct() ) | ||||||||||||
4032 | { | ||||||||||||
4033 | // See above at tables | ||||||||||||
4034 | if( !pLastSctCnt ) | ||||||||||||
4035 | pLastSctCnt = lcl_InvalidateSection( pCnt, nInv ); | ||||||||||||
4036 | if( pLastSctCnt == pCnt ) | ||||||||||||
4037 | pLastSctCnt = nullptr; | ||||||||||||
4038 | } | ||||||||||||
4039 | #if OSL_DEBUG_LEVEL1 > 0 | ||||||||||||
4040 | else | ||||||||||||
4041 | OSL_ENSURE( !pLastSctCnt, "Where's the last SctContent?" )do { if (true && (!(!pLastSctCnt))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" ":" "4041" ": "), "%s", "Where's the last SctContent?"); } } while (false); | ||||||||||||
4042 | #endif | ||||||||||||
4043 | } | ||||||||||||
4044 | if( nInv & SwInvalidateFlags::Table ) | ||||||||||||
4045 | { | ||||||||||||
4046 | if( pCnt->IsInTab() ) | ||||||||||||
4047 | { | ||||||||||||
4048 | // To not call FindTabFrame() for each ContentFrame of a table and | ||||||||||||
4049 | // then invalidate the table, we remember the last ContentFrame of | ||||||||||||
4050 | // the table and ignore IsInTab() until we are past it. | ||||||||||||
4051 | // When entering the table, LastSctCnt is set to null, so | ||||||||||||
4052 | // sections inside the table are correctly invalidated. | ||||||||||||
4053 | // If the table itself is in a section the | ||||||||||||
4054 | // invalidation is done three times, which is acceptable. | ||||||||||||
4055 | if( !pLastTabCnt ) | ||||||||||||
4056 | { | ||||||||||||
4057 | pLastTabCnt = lcl_InvalidateTable( pCnt->FindTabFrame(), nInv ); | ||||||||||||
4058 | pLastSctCnt = nullptr; | ||||||||||||
4059 | } | ||||||||||||
4060 | if( pLastTabCnt == pCnt ) | ||||||||||||
4061 | { | ||||||||||||
4062 | pLastTabCnt = nullptr; | ||||||||||||
4063 | pLastSctCnt = nullptr; | ||||||||||||
4064 | } | ||||||||||||
4065 | } | ||||||||||||
4066 | #if OSL_DEBUG_LEVEL1 > 0 | ||||||||||||
4067 | else | ||||||||||||
4068 | OSL_ENSURE( !pLastTabCnt, "Where's the last TabContent?" )do { if (true && (!(!pLastTabCnt))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" ":" "4068" ": "), "%s", "Where's the last TabContent?"); } } while (false); | ||||||||||||
4069 | #endif | ||||||||||||
4070 | } | ||||||||||||
4071 | |||||||||||||
4072 | if( nInv & SwInvalidateFlags::Size ) | ||||||||||||
4073 | pCnt->Prepare( PrepareHint::Clear, nullptr, false ); | ||||||||||||
4074 | if( nInv & SwInvalidateFlags::Pos ) | ||||||||||||
4075 | pCnt->InvalidatePos_(); | ||||||||||||
4076 | if( nInv & SwInvalidateFlags::PrtArea ) | ||||||||||||
4077 | pCnt->InvalidatePrt_(); | ||||||||||||
4078 | if ( nInv & SwInvalidateFlags::LineNum ) | ||||||||||||
4079 | pCnt->InvalidateLineNum(); | ||||||||||||
4080 | if ( pCnt->GetDrawObjs() ) | ||||||||||||
4081 | lcl_InvalidateAllContent( pCnt, nInv ); | ||||||||||||
4082 | pCnt = pCnt->GetNextContentFrame(); | ||||||||||||
4083 | } | ||||||||||||
4084 | } | ||||||||||||
4085 | |||||||||||||
4086 | static void lcl_InvalidateAllContent( SwContentFrame *pCnt, SwInvalidateFlags nInv ) | ||||||||||||
4087 | { | ||||||||||||
4088 | SwSortedObjs &rObjs = *pCnt->GetDrawObjs(); | ||||||||||||
4089 | for (SwAnchoredObject* pAnchoredObj : rObjs) | ||||||||||||
4090 | { | ||||||||||||
4091 | if ( dynamic_cast< const SwFlyFrame *>( pAnchoredObj ) != nullptr ) | ||||||||||||
4092 | { | ||||||||||||
4093 | SwFlyFrame *pFly = static_cast<SwFlyFrame*>(pAnchoredObj); | ||||||||||||
4094 | if ( pFly->IsFlyInContentFrame() ) | ||||||||||||
4095 | { | ||||||||||||
4096 | ::lcl_InvalidateContent( pFly->ContainsContent(), nInv ); | ||||||||||||
4097 | if( nInv & SwInvalidateFlags::Direction ) | ||||||||||||
4098 | pFly->CheckDirChange(); | ||||||||||||
4099 | } | ||||||||||||
4100 | } | ||||||||||||
4101 | } | ||||||||||||
4102 | } | ||||||||||||
4103 | |||||||||||||
4104 | void SwRootFrame::InvalidateAllContent( SwInvalidateFlags nInv ) | ||||||||||||
4105 | { | ||||||||||||
4106 | // First process all page bound FlyFrames. | ||||||||||||
4107 | SwPageFrame *pPage = static_cast<SwPageFrame*>(Lower()); | ||||||||||||
4108 | while( pPage ) | ||||||||||||
4109 | { | ||||||||||||
4110 | pPage->InvalidateFlyLayout(); | ||||||||||||
4111 | pPage->InvalidateFlyContent(); | ||||||||||||
4112 | pPage->InvalidateFlyInCnt(); | ||||||||||||
4113 | pPage->InvalidateLayout(); | ||||||||||||
4114 | pPage->InvalidateContent(); | ||||||||||||
4115 | pPage->InvalidatePage( pPage ); // So even the Turbo disappears if applicable | ||||||||||||
4116 | |||||||||||||
4117 | if ( pPage->GetSortedObjs() ) | ||||||||||||
4118 | { | ||||||||||||
4119 | const SwSortedObjs &rObjs = *pPage->GetSortedObjs(); | ||||||||||||
4120 | for (SwAnchoredObject* pAnchoredObj : rObjs) | ||||||||||||
4121 | { | ||||||||||||
4122 | if ( dynamic_cast< const SwFlyFrame *>( pAnchoredObj ) != nullptr ) | ||||||||||||
4123 | { | ||||||||||||
4124 | SwFlyFrame* pFly = static_cast<SwFlyFrame*>(pAnchoredObj); | ||||||||||||
4125 | ::lcl_InvalidateContent( pFly->ContainsContent(), nInv ); | ||||||||||||
4126 | if ( nInv & SwInvalidateFlags::Direction ) | ||||||||||||
4127 | pFly->CheckDirChange(); | ||||||||||||
4128 | } | ||||||||||||
4129 | } | ||||||||||||
4130 | } | ||||||||||||
4131 | if( nInv & SwInvalidateFlags::Direction ) | ||||||||||||
4132 | pPage->CheckDirChange(); | ||||||||||||
4133 | pPage = static_cast<SwPageFrame*>(pPage->GetNext()); | ||||||||||||
4134 | } | ||||||||||||
4135 | |||||||||||||
4136 | //Invalidate the whole document content and the character bound Flys here. | ||||||||||||
4137 | ::lcl_InvalidateContent( ContainsContent(), nInv ); | ||||||||||||
4138 | |||||||||||||
4139 | if( nInv & SwInvalidateFlags::PrtArea ) | ||||||||||||
4140 | { | ||||||||||||
4141 | SwViewShell *pSh = getRootFrame()->GetCurrShell(); | ||||||||||||
4142 | if( pSh ) | ||||||||||||
4143 | pSh->InvalidateWindows( getFrameArea() ); | ||||||||||||
4144 | } | ||||||||||||
4145 | } | ||||||||||||
4146 | |||||||||||||
4147 | /** | ||||||||||||
4148 | * Invalidate/re-calculate the position of all floating screen objects (Writer fly frames and | ||||||||||||
4149 | * drawing objects), that are anchored to paragraph or to character. (2004-03-16 #i11860#) | ||||||||||||
4150 | */ | ||||||||||||
4151 | void SwRootFrame::InvalidateAllObjPos() | ||||||||||||
4152 | { | ||||||||||||
4153 | const SwPageFrame* pPageFrame = static_cast<const SwPageFrame*>(Lower()); | ||||||||||||
4154 | while( pPageFrame ) | ||||||||||||
4155 | { | ||||||||||||
4156 | pPageFrame->InvalidateFlyLayout(); | ||||||||||||
4157 | |||||||||||||
4158 | if ( pPageFrame->GetSortedObjs() ) | ||||||||||||
4159 | { | ||||||||||||
4160 | const SwSortedObjs& rObjs = *(pPageFrame->GetSortedObjs()); | ||||||||||||
4161 | for (SwAnchoredObject* pAnchoredObj : rObjs) | ||||||||||||
4162 | { | ||||||||||||
4163 | const SwFormatAnchor& rAnch = pAnchoredObj->GetFrameFormat().GetAnchor(); | ||||||||||||
4164 | if ((rAnch.GetAnchorId() != RndStdIds::FLY_AT_PARA) && | ||||||||||||
4165 | (rAnch.GetAnchorId() != RndStdIds::FLY_AT_CHAR)) | ||||||||||||
4166 | { | ||||||||||||
4167 | // only to paragraph and to character anchored objects are considered. | ||||||||||||
4168 | continue; | ||||||||||||
4169 | } | ||||||||||||
4170 | // #i28701# - special invalidation for anchored | ||||||||||||
4171 | // objects, whose wrapping style influence has to be considered. | ||||||||||||
4172 | if ( pAnchoredObj->ConsiderObjWrapInfluenceOnObjPos() ) | ||||||||||||
4173 | pAnchoredObj->InvalidateObjPosForConsiderWrapInfluence(); | ||||||||||||
4174 | else | ||||||||||||
4175 | pAnchoredObj->InvalidateObjPos(); | ||||||||||||
4176 | } | ||||||||||||
4177 | } | ||||||||||||
4178 | |||||||||||||
4179 | pPageFrame = static_cast<const SwPageFrame*>(pPageFrame->GetNext()); | ||||||||||||
4180 | } | ||||||||||||
4181 | } | ||||||||||||
4182 | |||||||||||||
4183 | static void AddRemoveFlysForNode( | ||||||||||||
4184 | SwTextFrame & rFrame, SwTextNode & rTextNode, | ||||||||||||
4185 | std::set<sal_uLong> *const pSkipped, | ||||||||||||
4186 | SwFrameFormats & rTable, | ||||||||||||
4187 | SwPageFrame *const pPage, | ||||||||||||
4188 | SwTextNode const*const pNode, | ||||||||||||
4189 | std::vector<sw::Extent>::const_iterator & rIterFirst, | ||||||||||||
4190 | std::vector<sw::Extent>::const_iterator const& rIterEnd, | ||||||||||||
4191 | SwTextNode const*const pFirstNode, SwTextNode const*const pLastNode) | ||||||||||||
4192 | { | ||||||||||||
4193 | if (pNode == &rTextNode) | ||||||||||||
4194 | { // remove existing hidden at-char anchored flys | ||||||||||||
4195 | RemoveHiddenObjsOfNode(rTextNode, &rIterFirst, &rIterEnd, pFirstNode, pLastNode); | ||||||||||||
4196 | } | ||||||||||||
4197 | else if (rTextNode.GetIndex() < pNode->GetIndex()) | ||||||||||||
4198 | { | ||||||||||||
4199 | // pNode's frame has been deleted by CheckParaRedlineMerge() | ||||||||||||
4200 | AppendObjsOfNode(&rTable, | ||||||||||||
4201 | pNode->GetIndex(), &rFrame, pPage, &rTextNode.GetDoc(), | ||||||||||||
4202 | &rIterFirst, &rIterEnd, pFirstNode, pLastNode); | ||||||||||||
4203 | if (pSkipped) | ||||||||||||
4204 | { | ||||||||||||
4205 | // if a fly has been added by AppendObjsOfNode, it must be skipped; if not, then it doesn't matter if it's skipped or not because it has no frames and because of that it would be skipped anyway | ||||||||||||
4206 | if (auto const pFlys = pNode->GetAnchoredFlys()) | ||||||||||||
4207 | { | ||||||||||||
4208 | for (auto const pFly : *pFlys) | ||||||||||||
4209 | { | ||||||||||||
4210 | if (pFly->Which() != RES_DRAWFRMFMT) | ||||||||||||
4211 | { | ||||||||||||
4212 | pSkipped->insert(pFly->GetContent().GetContentIdx()->GetIndex()); | ||||||||||||
4213 | } | ||||||||||||
4214 | } | ||||||||||||
4215 | } | ||||||||||||
4216 | } | ||||||||||||
4217 | } | ||||||||||||
4218 | } | ||||||||||||
4219 | |||||||||||||
4220 | namespace sw { | ||||||||||||
4221 | |||||||||||||
4222 | /// rTextNode is the first one of the "new" merge - if rTextNode isn't the same | ||||||||||||
4223 | /// as MergedPara::pFirstNode, then nodes before rTextNode have their flys | ||||||||||||
4224 | /// already properly attached, so only the other nodes need handling here. | ||||||||||||
4225 | void AddRemoveFlysAnchoredToFrameStartingAtNode( | ||||||||||||
4226 | SwTextFrame & rFrame, SwTextNode & rTextNode, | ||||||||||||
4227 | std::set<sal_uLong> *const pSkipped) | ||||||||||||
4228 | { | ||||||||||||
4229 | auto const pMerged(rFrame.GetMergedPara()); | ||||||||||||
4230 | if (!pMerged | ||||||||||||
4231 | // do this only *once*, for the *last* frame | ||||||||||||
4232 | // otherwise AppendObj would create multiple frames for fly-frames! | ||||||||||||
4233 | || rFrame.GetFollow()) | ||||||||||||
4234 | return; | ||||||||||||
4235 | |||||||||||||
4236 | assert(pMerged->pFirstNode->GetIndex() <= rTextNode.GetIndex()(static_cast <bool> (pMerged->pFirstNode->GetIndex () <= rTextNode.GetIndex() && rTextNode.GetIndex() <= pMerged->pLastNode->GetIndex()) ? void (0) : __assert_fail ("pMerged->pFirstNode->GetIndex() <= rTextNode.GetIndex() && rTextNode.GetIndex() <= pMerged->pLastNode->GetIndex()" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" , 4237, __extension__ __PRETTY_FUNCTION__)) | ||||||||||||
4237 | && rTextNode.GetIndex() <= pMerged->pLastNode->GetIndex())(static_cast <bool> (pMerged->pFirstNode->GetIndex () <= rTextNode.GetIndex() && rTextNode.GetIndex() <= pMerged->pLastNode->GetIndex()) ? void (0) : __assert_fail ("pMerged->pFirstNode->GetIndex() <= rTextNode.GetIndex() && rTextNode.GetIndex() <= pMerged->pLastNode->GetIndex()" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" , 4237, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
4238 | // add visible flys in non-first node to merged frame | ||||||||||||
4239 | // (hidden flys remain and are deleted via DelFrames()) | ||||||||||||
4240 | SwFrameFormats& rTable(*rTextNode.GetDoc().GetSpzFrameFormats()); | ||||||||||||
4241 | SwPageFrame *const pPage(rFrame.FindPageFrame()); | ||||||||||||
4242 | std::vector<sw::Extent>::const_iterator iterFirst(pMerged->extents.begin()); | ||||||||||||
4243 | std::vector<sw::Extent>::const_iterator iter(iterFirst); | ||||||||||||
4244 | SwTextNode const* pNode(pMerged->pFirstNode); | ||||||||||||
4245 | for ( ; ; ++iter) | ||||||||||||
4246 | { | ||||||||||||
4247 | if (iter == pMerged->extents.end() | ||||||||||||
4248 | || iter->pNode != pNode) | ||||||||||||
4249 | { | ||||||||||||
4250 | AddRemoveFlysForNode(rFrame, rTextNode, pSkipped, rTable, pPage, | ||||||||||||
4251 | pNode, iterFirst, iter, | ||||||||||||
4252 | pMerged->pFirstNode, pMerged->pLastNode); | ||||||||||||
4253 | sal_uLong const until = iter == pMerged->extents.end() | ||||||||||||
4254 | ? pMerged->pLastNode->GetIndex() + 1 | ||||||||||||
4255 | : iter->pNode->GetIndex(); | ||||||||||||
4256 | for (sal_uLong i = pNode->GetIndex() + 1; i < until; ++i) | ||||||||||||
4257 | { | ||||||||||||
4258 | // let's show at-para flys on nodes that contain start/end of | ||||||||||||
4259 | // redline too, even if there's no text there | ||||||||||||
4260 | SwNode const*const pTmp(pNode->GetNodes()[i]); | ||||||||||||
4261 | if (pTmp->GetRedlineMergeFlag() == SwNode::Merge::NonFirst) | ||||||||||||
4262 | { | ||||||||||||
4263 | AddRemoveFlysForNode(rFrame, rTextNode, pSkipped, | ||||||||||||
4264 | rTable, pPage, pTmp->GetTextNode(), iter, iter, | ||||||||||||
4265 | pMerged->pFirstNode, pMerged->pLastNode); | ||||||||||||
4266 | } | ||||||||||||
4267 | } | ||||||||||||
4268 | if (iter == pMerged->extents.end()) | ||||||||||||
4269 | { | ||||||||||||
4270 | break; | ||||||||||||
4271 | } | ||||||||||||
4272 | pNode = iter->pNode; | ||||||||||||
4273 | iterFirst = iter; | ||||||||||||
4274 | } | ||||||||||||
4275 | } | ||||||||||||
4276 | } | ||||||||||||
4277 | |||||||||||||
4278 | } // namespace sw | ||||||||||||
4279 | |||||||||||||
4280 | static void UnHideRedlines(SwRootFrame & rLayout, | ||||||||||||
4281 | SwNodes & rNodes, SwNode const& rEndOfSectionNode, | ||||||||||||
4282 | std::set<sal_uLong> *const pSkipped) | ||||||||||||
4283 | { | ||||||||||||
4284 | assert(rEndOfSectionNode.IsEndNode())(static_cast <bool> (rEndOfSectionNode.IsEndNode()) ? void (0) : __assert_fail ("rEndOfSectionNode.IsEndNode()", "/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" , 4284, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
4285 | assert(rNodes[rEndOfSectionNode.StartOfSectionNode()->GetIndex() + 1]->IsCreateFrameWhenHidingRedlines())(static_cast <bool> (rNodes[rEndOfSectionNode.StartOfSectionNode ()->GetIndex() + 1]->IsCreateFrameWhenHidingRedlines()) ? void (0) : __assert_fail ("rNodes[rEndOfSectionNode.StartOfSectionNode()->GetIndex() + 1]->IsCreateFrameWhenHidingRedlines()" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" , 4285, __extension__ __PRETTY_FUNCTION__)); // first node is never hidden | ||||||||||||
4286 | for (sal_uLong i = rEndOfSectionNode.StartOfSectionNode()->GetIndex() + 1; | ||||||||||||
4287 | i < rEndOfSectionNode.GetIndex(); ++i) | ||||||||||||
4288 | { | ||||||||||||
4289 | SwNode & rNode(*rNodes[i]); | ||||||||||||
4290 | if (rNode.IsTextNode()) // only text nodes are 1st node of a merge | ||||||||||||
4291 | { | ||||||||||||
4292 | SwTextNode & rTextNode(*rNode.GetTextNode()); | ||||||||||||
4293 | SwIterator<SwTextFrame, SwTextNode, sw::IteratorMode::UnwrapMulti> aIter(rTextNode); | ||||||||||||
4294 | std::vector<SwTextFrame*> frames; | ||||||||||||
4295 | for (SwTextFrame * pFrame = aIter.First(); pFrame; pFrame = aIter.Next()) | ||||||||||||
4296 | { | ||||||||||||
4297 | if (pFrame->getRootFrame() == &rLayout) | ||||||||||||
4298 | { | ||||||||||||
4299 | if (pFrame->IsFollow()) | ||||||||||||
4300 | { | ||||||||||||
4301 | frames.push_back(pFrame); | ||||||||||||
4302 | } // when hiding, the loop must remove the anchored flys | ||||||||||||
4303 | else // *before* resetting SetMergedPara anywhere - else | ||||||||||||
4304 | { // the fly deletion code will access multiple of the | ||||||||||||
4305 | // frames with inconsistent MergedPara and assert | ||||||||||||
4306 | frames.insert(frames.begin(), pFrame); | ||||||||||||
4307 | } | ||||||||||||
4308 | } | ||||||||||||
4309 | } | ||||||||||||
4310 | // this messes with pRegisteredIn so do it outside SwIterator | ||||||||||||
4311 | auto eMode(sw::FrameMode::Existing); | ||||||||||||
4312 | for (SwTextFrame * pFrame : frames) | ||||||||||||
4313 | { | ||||||||||||
4314 | if (rLayout.IsHideRedlines()) | ||||||||||||
4315 | { | ||||||||||||
4316 | assert(!pFrame->GetMergedPara() ||(static_cast <bool> (!pFrame->GetMergedPara() || !rNode .IsCreateFrameWhenHidingRedlines()) ? void (0) : __assert_fail ("!pFrame->GetMergedPara() || !rNode.IsCreateFrameWhenHidingRedlines()" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" , 4317, __extension__ __PRETTY_FUNCTION__)) | ||||||||||||
4317 | !rNode.IsCreateFrameWhenHidingRedlines())(static_cast <bool> (!pFrame->GetMergedPara() || !rNode .IsCreateFrameWhenHidingRedlines()) ? void (0) : __assert_fail ("!pFrame->GetMergedPara() || !rNode.IsCreateFrameWhenHidingRedlines()" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" , 4317, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
4318 | if (rNode.IsCreateFrameWhenHidingRedlines()) | ||||||||||||
4319 | { | ||||||||||||
4320 | { | ||||||||||||
4321 | auto pMerged(CheckParaRedlineMerge(*pFrame, | ||||||||||||
4322 | rTextNode, eMode)); | ||||||||||||
4323 | pFrame->SetMergedPara(std::move(pMerged)); | ||||||||||||
4324 | } | ||||||||||||
4325 | auto const pMerged(pFrame->GetMergedPara()); | ||||||||||||
4326 | if (pMerged) | ||||||||||||
4327 | { | ||||||||||||
4328 | // invalidate SwInvalidateFlags::Size | ||||||||||||
4329 | pFrame->Prepare(PrepareHint::Clear, nullptr, false); | ||||||||||||
4330 | pFrame->InvalidatePage(); | ||||||||||||
4331 | if (auto const pObjs = pFrame->GetDrawObjs()) | ||||||||||||
4332 | { // also invalidate position of existing flys | ||||||||||||
4333 | // because they may need to be moved | ||||||||||||
4334 | for (auto const pObject : *pObjs) | ||||||||||||
4335 | { | ||||||||||||
4336 | pObject->InvalidateObjPos(); | ||||||||||||
4337 | } | ||||||||||||
4338 | } | ||||||||||||
4339 | } | ||||||||||||
4340 | sw::AddRemoveFlysAnchoredToFrameStartingAtNode(*pFrame, rTextNode, pSkipped); | ||||||||||||
4341 | // only *first* frame of node gets Existing because it | ||||||||||||
4342 | eMode = sw::FrameMode::New; // is not idempotent! | ||||||||||||
4343 | } | ||||||||||||
4344 | } | ||||||||||||
4345 | else | ||||||||||||
4346 | { | ||||||||||||
4347 | if (auto const& pMergedPara = pFrame->GetMergedPara()) | ||||||||||||
4348 | { | ||||||||||||
4349 | // invalidate SwInvalidateFlags::Size | ||||||||||||
4350 | pFrame->Prepare(PrepareHint::Clear, nullptr, false); | ||||||||||||
4351 | pFrame->InvalidatePage(); | ||||||||||||
4352 | if (auto const pObjs = pFrame->GetDrawObjs()) | ||||||||||||
4353 | { // also invalidate position of existing flys | ||||||||||||
4354 | for (auto const pObject : *pObjs) | ||||||||||||
4355 | { | ||||||||||||
4356 | pObject->InvalidateObjPos(); | ||||||||||||
4357 | } | ||||||||||||
4358 | } | ||||||||||||
4359 | // SwFlyAtContentFrame::Modify() always appends to | ||||||||||||
4360 | // the master frame, so do the same here. | ||||||||||||
4361 | // (RemoveFootnotesForNode must be called at least once) | ||||||||||||
4362 | if (!pFrame->IsFollow()) | ||||||||||||
4363 | { | ||||||||||||
4364 | // the new text frames don't exist yet, so at this point | ||||||||||||
4365 | // we can only delete the footnote frames so they don't | ||||||||||||
4366 | // point to the merged SwTextFrame any more... | ||||||||||||
4367 | assert(&rTextNode == pMergedPara->pFirstNode)(static_cast <bool> (&rTextNode == pMergedPara-> pFirstNode) ? void (0) : __assert_fail ("&rTextNode == pMergedPara->pFirstNode" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" , 4367, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
4368 | // iterate over nodes, not extents: if a node has | ||||||||||||
4369 | // no extents now but did have extents initially, | ||||||||||||
4370 | // its flys need their frames deleted too! | ||||||||||||
4371 | for (sal_uLong j = rTextNode.GetIndex() + 1; | ||||||||||||
4372 | j <= pMergedPara->pLastNode->GetIndex(); ++j) | ||||||||||||
4373 | { | ||||||||||||
4374 | SwNode *const pNode(rTextNode.GetNodes()[j]); | ||||||||||||
4375 | assert(!pNode->IsEndNode())(static_cast <bool> (!pNode->IsEndNode()) ? void (0) : __assert_fail ("!pNode->IsEndNode()", "/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" , 4375, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
4376 | if (pNode->IsStartNode()) | ||||||||||||
4377 | { | ||||||||||||
4378 | j = pNode->EndOfSectionIndex(); | ||||||||||||
4379 | } | ||||||||||||
4380 | else if (pNode->IsTextNode()) | ||||||||||||
4381 | { | ||||||||||||
4382 | sw::RemoveFootnotesForNode(rLayout, *pNode->GetTextNode(), nullptr); | ||||||||||||
4383 | // similarly, remove the anchored flys | ||||||||||||
4384 | if (auto const pFlys = pNode->GetAnchoredFlys()) | ||||||||||||
4385 | { | ||||||||||||
4386 | for (SwFrameFormat * pFormat : *pFlys) | ||||||||||||
4387 | { | ||||||||||||
4388 | pFormat->DelFrames(/*&rLayout*/); | ||||||||||||
4389 | } | ||||||||||||
4390 | } | ||||||||||||
4391 | } | ||||||||||||
4392 | } | ||||||||||||
4393 | // rely on AppendAllObjs call at the end to add | ||||||||||||
4394 | // all flys in first node that are hidden | ||||||||||||
4395 | } | ||||||||||||
4396 | pFrame->SetMergedPara(nullptr); | ||||||||||||
4397 | } | ||||||||||||
4398 | } | ||||||||||||
4399 | pFrame->Broadcast(SfxHint()); // notify SwAccessibleParagraph | ||||||||||||
4400 | } | ||||||||||||
4401 | // all nodes, not just merged ones! it may be in the same list as | ||||||||||||
4402 | if (rTextNode.IsNumbered(nullptr)) // a preceding merged one... | ||||||||||||
4403 | { // notify frames so they reformat numbering portions | ||||||||||||
4404 | rTextNode.NumRuleChgd(); | ||||||||||||
4405 | } | ||||||||||||
4406 | } | ||||||||||||
4407 | else if (rNode.IsTableNode() && rLayout.IsHideRedlines()) | ||||||||||||
4408 | { | ||||||||||||
4409 | SwPosition const tmp(rNode); | ||||||||||||
4410 | SwRangeRedline const*const pRedline( | ||||||||||||
4411 | rLayout.GetFormat()->GetDoc()->getIDocumentRedlineAccess().GetRedline(tmp, nullptr)); | ||||||||||||
4412 | // pathology: redline that starts on a TableNode; cannot | ||||||||||||
4413 | // be created in UI but by import filters... | ||||||||||||
4414 | if (pRedline | ||||||||||||
4415 | && pRedline->GetType() == RedlineType::Delete | ||||||||||||
4416 | && &pRedline->Start()->nNode.GetNode() == &rNode) | ||||||||||||
4417 | { | ||||||||||||
4418 | for (sal_uLong j = rNode.GetIndex(); j <= rNode.EndOfSectionIndex(); ++j) | ||||||||||||
4419 | { | ||||||||||||
4420 | rNode.GetNodes()[j]->SetRedlineMergeFlag(SwNode::Merge::Hidden); | ||||||||||||
4421 | } | ||||||||||||
4422 | rNode.GetTableNode()->DelFrames(&rLayout); | ||||||||||||
4423 | } | ||||||||||||
4424 | } | ||||||||||||
4425 | if (!rNode.IsCreateFrameWhenHidingRedlines()) | ||||||||||||
4426 | { | ||||||||||||
4427 | if (rLayout.IsHideRedlines()) | ||||||||||||
4428 | { | ||||||||||||
4429 | if (rNode.IsContentNode()) | ||||||||||||
4430 | { | ||||||||||||
4431 | // note: nothing to do here, already done | ||||||||||||
4432 | #ifndef NDEBUG | ||||||||||||
4433 | auto const pFrame(static_cast<SwContentNode&>(rNode).getLayoutFrame(&rLayout)); | ||||||||||||
4434 | assert(!pFrame || static_cast<SwTextFrame*>(pFrame)->GetMergedPara()->pFirstNode != &rNode)(static_cast <bool> (!pFrame || static_cast<SwTextFrame *>(pFrame)->GetMergedPara()->pFirstNode != &rNode ) ? void (0) : __assert_fail ("!pFrame || static_cast<SwTextFrame*>(pFrame)->GetMergedPara()->pFirstNode != &rNode" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" , 4434, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
4435 | #endif | ||||||||||||
4436 | } | ||||||||||||
4437 | } | ||||||||||||
4438 | else | ||||||||||||
4439 | { | ||||||||||||
4440 | assert(!rNode.IsContentNode() || !rNode.GetContentNode()->getLayoutFrame(&rLayout))(static_cast <bool> (!rNode.IsContentNode() || !rNode.GetContentNode ()->getLayoutFrame(&rLayout)) ? void (0) : __assert_fail ("!rNode.IsContentNode() || !rNode.GetContentNode()->getLayoutFrame(&rLayout)" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" , 4440, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
4441 | sal_uLong j = i + 1; | ||||||||||||
4442 | for ( ; j < rEndOfSectionNode.GetIndex(); ++j) | ||||||||||||
4443 | { | ||||||||||||
4444 | if (rNodes[j]->IsCreateFrameWhenHidingRedlines()) | ||||||||||||
4445 | { | ||||||||||||
4446 | break; | ||||||||||||
4447 | } | ||||||||||||
4448 | } | ||||||||||||
4449 | // call MakeFrames once, because sections/tables | ||||||||||||
4450 | // InsertCnt_ also checks for hidden sections | ||||||||||||
4451 | SwNodeIndex const start(rNodes, i); | ||||||||||||
4452 | SwNodeIndex const end(rNodes, j); | ||||||||||||
4453 | assert(!bDontCreateObjects)(static_cast <bool> (!bDontCreateObjects) ? void (0) : __assert_fail ("!bDontCreateObjects", "/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" , 4453, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
4454 | bDontCreateObjects = true; // suppress here, to be called once | ||||||||||||
4455 | ::MakeFrames(rLayout.GetFormat()->GetDoc(), start, end); | ||||||||||||
4456 | bDontCreateObjects = false; | ||||||||||||
4457 | i = j - 1; // will be incremented again | ||||||||||||
4458 | } | ||||||||||||
4459 | } | ||||||||||||
4460 | } | ||||||||||||
4461 | } | ||||||||||||
4462 | |||||||||||||
4463 | static void UnHideRedlinesExtras(SwRootFrame & rLayout, | ||||||||||||
4464 | SwNodes & rNodes, SwNode const& rEndOfExtraSectionNode, | ||||||||||||
4465 | std::set<sal_uLong> *const pSkipped) | ||||||||||||
4466 | { | ||||||||||||
4467 | assert(rEndOfExtraSectionNode.IsEndNode())(static_cast <bool> (rEndOfExtraSectionNode.IsEndNode() ) ? void (0) : __assert_fail ("rEndOfExtraSectionNode.IsEndNode()" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" , 4467, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
4468 | for (sal_uLong i = rEndOfExtraSectionNode.StartOfSectionNode()->GetIndex() | ||||||||||||
4469 | + 1; i < rEndOfExtraSectionNode.GetIndex(); ++i) | ||||||||||||
4470 | { | ||||||||||||
4471 | SwNode const& rStartNode(*rNodes[i]); | ||||||||||||
4472 | assert(rStartNode.IsStartNode())(static_cast <bool> (rStartNode.IsStartNode()) ? void ( 0) : __assert_fail ("rStartNode.IsStartNode()", "/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" , 4472, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
4473 | assert(rStartNode.GetRedlineMergeFlag() == SwNode::Merge::None)(static_cast <bool> (rStartNode.GetRedlineMergeFlag() == SwNode::Merge::None) ? void (0) : __assert_fail ("rStartNode.GetRedlineMergeFlag() == SwNode::Merge::None" , "/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" , 4473, __extension__ __PRETTY_FUNCTION__)); | ||||||||||||
4474 | SwNode const& rEndNode(*rStartNode.EndOfSectionNode()); | ||||||||||||
4475 | bool bSkip(pSkipped && pSkipped->find(i) != pSkipped->end()); | ||||||||||||
4476 | i = rEndNode.GetIndex(); | ||||||||||||
4477 | for (sal_uLong j = rStartNode.GetIndex() + 1; j < i; ++j) | ||||||||||||
4478 | { | ||||||||||||
4479 | // note: SwStartNode has no way to access the frames, so check | ||||||||||||
4480 | // whether the first content-node inside the section has frames | ||||||||||||
4481 | SwNode const& rNode(*rNodes[j]); | ||||||||||||
4482 | if (rNode.IsSectionNode() && | ||||||||||||
4483 | static_cast<SwSectionNode const&>(rNode).GetSection().IsHiddenFlag()) | ||||||||||||
4484 | { // skip hidden sections - they can be inserted in fly-frames :( | ||||||||||||
4485 | j = rNode.EndOfSectionNode()->GetIndex(); | ||||||||||||
4486 | continue; | ||||||||||||
4487 | } | ||||||||||||
4488 | if (rNode.IsContentNode()) | ||||||||||||
4489 | { | ||||||||||||
4490 | SwContentNode const& rCNode(static_cast<SwContentNode const&>(rNode)); | ||||||||||||
4491 | if (!rCNode.getLayoutFrame(&rLayout)) | ||||||||||||
4492 | { // ignore footnote/fly/header/footer with no layout frame | ||||||||||||
4493 | bSkip = true; // they will be created from scratch later if needed | ||||||||||||
4494 | } | ||||||||||||
4495 | break; | ||||||||||||
4496 | } | ||||||||||||
4497 | } | ||||||||||||
4498 | if (!bSkip) | ||||||||||||
4499 | { | ||||||||||||
4500 | UnHideRedlines(rLayout, rNodes, rEndNode, pSkipped); | ||||||||||||
4501 | } | ||||||||||||
4502 | } | ||||||||||||
4503 | } | ||||||||||||
4504 | |||||||||||||
4505 | void SwRootFrame::SetHideRedlines(bool const bHideRedlines) | ||||||||||||
4506 | { | ||||||||||||
4507 | if (bHideRedlines == mbHideRedlines) | ||||||||||||
4508 | { | ||||||||||||
4509 | return; | ||||||||||||
4510 | } | ||||||||||||
4511 | mbHideRedlines = bHideRedlines; | ||||||||||||
4512 | assert(GetCurrShell()->ActionPend())(static_cast <bool> (GetCurrShell()->ActionPend()) ? void (0) : __assert_fail ("GetCurrShell()->ActionPend()", "/home/maarten/src/libreoffice/core/sw/source/core/layout/wsfrm.cxx" , 4512, __extension__ __PRETTY_FUNCTION__)); // tdf#125754 avoid recursive layout | ||||||||||||
4513 | SwDoc & rDoc(*GetFormat()->GetDoc()); | ||||||||||||
4514 | // don't do early return if there are no redlines: | ||||||||||||
4515 | // Show->Hide must init hidden number trees | ||||||||||||
4516 | // Hide->Show may be called after all redlines have been deleted but there | ||||||||||||
4517 | // may still be MergedParas because those aren't deleted yet... | ||||||||||||
4518 | #if 0 | ||||||||||||
4519 | if (!bHideRedlines | ||||||||||||
4520 | && rDoc.getIDocumentRedlineAccess().GetRedlineTable().empty()) | ||||||||||||
4521 | { | ||||||||||||
4522 | return; | ||||||||||||
4523 | } | ||||||||||||
4524 | #endif | ||||||||||||
4525 | // Hide->Show: clear MergedPara, create frames | ||||||||||||
4526 | // Show->Hide: call CheckParaRedlineMerge, delete frames | ||||||||||||
4527 | // Traverse the document via the nodes-array; traversing via the layout | ||||||||||||
4528 | // wouldn't find the nodes that don't have frames in the ->Show case. | ||||||||||||
4529 | // In-order traversal of each nodes array section should init the flags | ||||||||||||
4530 | // in nodes before they are iterated. | ||||||||||||
4531 | // Actual creation of frames should be done with existing functions | ||||||||||||
4532 | // if possible, particularly InsertCnt_() or its wrapper ::MakeFrames(). | ||||||||||||
4533 | SwNodes /*const*/& rNodes(rDoc.GetNodes()); | ||||||||||||
4534 | // Flys/footnotes: must iterate and find all the ones that already exist | ||||||||||||
4535 | // with frames and have redlines inside them; if any don't have frames at | ||||||||||||
4536 | // all, they will be created (if necessary) from scratch and completely by | ||||||||||||
4537 | // MakeFrames(). | ||||||||||||
4538 | // | ||||||||||||
4539 | // Flys before footnotes: because footnotes may contain flys but not | ||||||||||||
4540 | // vice-versa; alas flys may contain flys, so we skip some of them | ||||||||||||
4541 | // if they have already been created from scratch via their anchor flys. | ||||||||||||
4542 | std::set<sal_uLong> skippedFlys; | ||||||||||||
4543 | UnHideRedlinesExtras(*this, rNodes, rNodes.GetEndOfAutotext(), | ||||||||||||
4544 | // when un-hiding, delay all fly frame creation to AppendAllObjs below | ||||||||||||
4545 | IsHideRedlines() ? &skippedFlys : nullptr); | ||||||||||||
4546 | // Footnotes are created automatically (after invalidation etc.) by | ||||||||||||
4547 | // ConnectFootnote(), but need to be deleted manually. Footnotes do not | ||||||||||||
4548 | // occur in flys or headers/footers. | ||||||||||||
4549 | UnHideRedlinesExtras(*this, rNodes, rNodes.GetEndOfInserts(), nullptr); | ||||||||||||
4550 | UnHideRedlines(*this, rNodes, rNodes.GetEndOfContent(), nullptr); | ||||||||||||
4551 | |||||||||||||
4552 | if (!IsHideRedlines()) | ||||||||||||
4553 | { // create all previously hidden flys at once: | ||||||||||||
4554 | // * Flys on first node of pre-existing merged frames that are hidden | ||||||||||||
4555 | // (in delete redline), to be added to the existing frame | ||||||||||||
4556 | // * Flys on non-first (hidden/merged) nodes of pre-existing merged | ||||||||||||
4557 | // frames, to be added to the new frame of their node | ||||||||||||
4558 | // * Flys anchored in other flys that are hidden | ||||||||||||
4559 | AppendAllObjs(rDoc.GetSpzFrameFormats(), this); | ||||||||||||
4560 | } | ||||||||||||
4561 | |||||||||||||
4562 | for (auto const pRedline : rDoc.getIDocumentRedlineAccess().GetRedlineTable()) | ||||||||||||
4563 | { // DELETE are handled by the code above; for other types, need to | ||||||||||||
4564 | // trigger repaint of text frames to add/remove the redline color font | ||||||||||||
4565 | if (pRedline->GetType() != RedlineType::Delete) | ||||||||||||
4566 | { | ||||||||||||
4567 | pRedline->InvalidateRange(SwRangeRedline::Invalidation::Add); | ||||||||||||
4568 | } | ||||||||||||
4569 | } | ||||||||||||
4570 | |||||||||||||
4571 | SwFootnoteIdxs & rFootnotes(rDoc.GetFootnoteIdxs()); | ||||||||||||
4572 | if (rDoc.GetFootnoteInfo().m_eNum == FTNNUM_CHAPTER) | ||||||||||||
4573 | { | ||||||||||||
4574 | // sadly determining which node is outline node requires hidden layout | ||||||||||||
4575 | rFootnotes.UpdateAllFootnote(); | ||||||||||||
4576 | } | ||||||||||||
4577 | // invalidate all footnotes to reformat their numbers | ||||||||||||
4578 | for (SwTextFootnote *const pFootnote : rFootnotes) | ||||||||||||
4579 | { | ||||||||||||
4580 | SwFormatFootnote const& rFootnote(pFootnote->GetFootnote()); | ||||||||||||
4581 | if (rFootnote.GetNumber() != rFootnote.GetNumberRLHidden() | ||||||||||||
4582 | && rFootnote.GetNumStr().isEmpty()) | ||||||||||||
4583 | { | ||||||||||||
4584 | pFootnote->InvalidateNumberInLayout(); | ||||||||||||
4585 | } | ||||||||||||
4586 | } | ||||||||||||
4587 | // update various fields to re-expand them with the new layout | ||||||||||||
4588 | IDocumentFieldsAccess & rIDFA(rDoc.getIDocumentFieldsAccess()); | ||||||||||||
4589 | auto const pAuthType(rIDFA.GetFieldType( | ||||||||||||
4590 | SwFieldIds::TableOfAuthorities, OUString(), false)); | ||||||||||||
4591 | if (pAuthType) // created on demand... | ||||||||||||
4592 | { // calling DelSequenceArray() should be unnecessary here since the | ||||||||||||
4593 | // sequence doesn't depend on frames | ||||||||||||
4594 | pAuthType->UpdateFields(); | ||||||||||||
4595 | } | ||||||||||||
4596 | rIDFA.GetFieldType(SwFieldIds::RefPageGet, OUString(), false)->UpdateFields(); | ||||||||||||
4597 | rIDFA.GetSysFieldType(SwFieldIds::Chapter)->UpdateFields(); | ||||||||||||
4598 | rIDFA.UpdateExpFields(nullptr, false); | ||||||||||||
4599 | rIDFA.UpdateRefFields(); | ||||||||||||
4600 | |||||||||||||
4601 | // update SwPostItMgr / notes in the margin | ||||||||||||
4602 | // note: as long as all shells share layout, broadcast to all shells! | ||||||||||||
4603 | rDoc.GetDocShell()->Broadcast( SwFormatFieldHint(nullptr, bHideRedlines | ||||||||||||
4604 | ? SwFormatFieldHintWhich::REMOVED | ||||||||||||
4605 | : SwFormatFieldHintWhich::INSERTED) ); | ||||||||||||
4606 | |||||||||||||
4607 | |||||||||||||
4608 | // InvalidateAllContent(SwInvalidateFlags::Size); // ??? TODO what to invalidate? this is the big hammer | ||||||||||||
4609 | } | ||||||||||||
4610 | |||||||||||||
4611 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |
1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | /* |
3 | * This file is part of the LibreOffice project. |
4 | * |
5 | * This Source Code Form is subject to the terms of the Mozilla Public |
6 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
8 | * |
9 | * This file incorporates work covered by the following license notice: |
10 | * |
11 | * Licensed to the Apache Software Foundation (ASF) under one or more |
12 | * contributor license agreements. See the NOTICE file distributed |
13 | * with this work for additional information regarding copyright |
14 | * ownership. The ASF licenses this file to you under the Apache |
15 | * License, Version 2.0 (the "License"); you may not use this file |
16 | * except in compliance with the License. You may obtain a copy of |
17 | * the License at http://www.apache.org/licenses/LICENSE-2.0 . |
18 | */ |
19 | |
20 | #ifndef INCLUDED_SW_SOURCE_CORE_INC_FRAME_HXX |
21 | #define INCLUDED_SW_SOURCE_CORE_INC_FRAME_HXX |
22 | |
23 | #include <drawinglayer/primitive2d/baseprimitive2d.hxx> |
24 | #include <editeng/borderline.hxx> |
25 | #include <svl/poolitem.hxx> |
26 | #include <swtypes.hxx> |
27 | #include <swrect.hxx> |
28 | #include <calbck.hxx> |
29 | #include <svl/SfxBroadcaster.hxx> |
30 | #include <o3tl/typed_flags_set.hxx> |
31 | #include <com/sun/star/style/TabStop.hpp> |
32 | #include <basegfx/matrix/b2dhommatrix.hxx> |
33 | #include <vcl/outdev.hxx> |
34 | |
35 | #include <memory> |
36 | |
37 | namespace drawinglayer::processor2d { class BaseProcessor2D; } |
38 | |
39 | class SwLayoutFrame; |
40 | class SwRootFrame; |
41 | class SwPageFrame; |
42 | class SwBodyFrame; |
43 | class SwFlyFrame; |
44 | class SwSectionFrame; |
45 | class SwFootnoteFrame; |
46 | class SwFootnoteBossFrame; |
47 | class SwTabFrame; |
48 | class SwRowFrame; |
49 | class SwContentFrame; |
50 | class SwAttrSet; |
51 | class Color; |
52 | class SwBorderAttrs; |
53 | class SwCache; |
54 | class SvxBrushItem; |
55 | class SvxFormatBreakItem; |
56 | class SwFormatPageDesc; |
57 | class SwSelectionList; |
58 | struct SwPosition; |
59 | struct SwCursorMoveState; |
60 | class SwFormat; |
61 | class SwPrintData; |
62 | class SwSortedObjs; |
63 | class SwAnchoredObject; |
64 | enum class SvxFrameDirection; |
65 | class IDocumentDrawModelAccess; |
66 | |
67 | // Each FrameType is represented here as a bit. |
68 | // The bits must be set in a way that it can be determined with masking of |
69 | // which kind of FrameType an instance is _and_ from what classes it was derived. |
70 | // Each frame has in its base class a member that must be set by the |
71 | // constructors accordingly. |
72 | enum class SwFrameType |
73 | { |
74 | None = 0x0000, |
75 | Root = 0x0001, |
76 | Page = 0x0002, |
77 | Column = 0x0004, |
78 | Header = 0x0008, |
79 | Footer = 0x0010, |
80 | FtnCont = 0x0020, |
81 | Ftn = 0x0040, |
82 | Body = 0x0080, |
83 | Fly = 0x0100, |
84 | Section = 0x0200, |
85 | // UNUSED 0x0400 |
86 | Tab = 0x0800, |
87 | Row = 0x1000, |
88 | Cell = 0x2000, |
89 | Txt = 0x4000, |
90 | NoTxt = 0x8000, |
91 | }; |
92 | |
93 | namespace o3tl |
94 | { |
95 | template<> struct typed_flags<SwFrameType> : is_typed_flags<SwFrameType, 0xfbff> {}; |
96 | }; |
97 | |
98 | // for internal use some common combinations |
99 | #define FRM_LAYOUTSwFrameType(0x3bFF) SwFrameType(0x3bFF) |
100 | #define FRM_ALLSwFrameType(0xfbff) SwFrameType(0xfbff) |
101 | #define FRM_CNTNT(SwFrameType::Txt | SwFrameType::NoTxt) (SwFrameType::Txt | SwFrameType::NoTxt) |
102 | #define FRM_FTNBOSS(SwFrameType::Page | SwFrameType::Column) (SwFrameType::Page | SwFrameType::Column) |
103 | #define FRM_ACCESSIBLE(SwFrameType::Root | SwFrameType::Page | SwFrameType::Header | SwFrameType::Footer | SwFrameType::Ftn | SwFrameType::Fly | SwFrameType ::Tab | SwFrameType::Cell | SwFrameType::Txt) (SwFrameType::Root | SwFrameType::Page | SwFrameType::Header | SwFrameType::Footer | SwFrameType::Ftn | SwFrameType::Fly | SwFrameType::Tab | SwFrameType::Cell | SwFrameType::Txt) |
104 | #define FRM_NEIGHBOUR(SwFrameType::Column | SwFrameType::Cell) (SwFrameType::Column | SwFrameType::Cell) |
105 | #define FRM_NOTE_VERT(SwFrameType::FtnCont | SwFrameType::Ftn | SwFrameType::Section | SwFrameType::Tab | SwFrameType::Row | SwFrameType::Cell | SwFrameType ::Txt) (SwFrameType::FtnCont | SwFrameType::Ftn | SwFrameType::Section | SwFrameType::Tab | SwFrameType::Row | SwFrameType::Cell | SwFrameType::Txt) |
106 | #define FRM_HEADFOOT(SwFrameType::Header | SwFrameType::Footer) (SwFrameType::Header | SwFrameType::Footer) |
107 | #define FRM_BODYFTNC(SwFrameType::FtnCont | SwFrameType::Body) (SwFrameType::FtnCont | SwFrameType::Body) |
108 | |
109 | // for GetNextLeaf/GetPrevLeaf. |
110 | enum MakePageType |
111 | { |
112 | MAKEPAGE_NONE, // do not create page/footnote |
113 | MAKEPAGE_APPEND, // only append page if needed |
114 | MAKEPAGE_INSERT, // add or append page if needed |
115 | MAKEPAGE_FTN, // add footnote if needed |
116 | MAKEPAGE_NOSECTION // Don't create section frames |
117 | }; |
118 | |
119 | namespace drawinglayer::attribute { |
120 | class SdrAllFillAttributesHelper; |
121 | typedef std::shared_ptr< SdrAllFillAttributesHelper > SdrAllFillAttributesHelperPtr; |
122 | } |
123 | |
124 | /// Helper class to isolate geometry-defining members of SwFrame |
125 | /// and to control their accesses. Moved to own class to have no |
126 | /// hidden accesses to 'private' members anymore. |
127 | /// |
128 | /// Added most important flags about the state of this geometric |
129 | /// information and if it is valid or not |
130 | class SAL_DLLPUBLIC_RTTI__attribute__ ((type_visibility("default"))) SwFrameAreaDefinition |
131 | { |
132 | private: |
133 | friend void FriendHackInvalidateRowFrame(SwFrameAreaDefinition &); |
134 | |
135 | // The absolute position and size of the SwFrame in the document. |
136 | // This values are set by the layouter implementations |
137 | SwRect maFrameArea; |
138 | |
139 | // The 'inner' Frame Area defined by a SwRect relative to FrameArea: |
140 | // When identical to FrameArea, Pos() will be (0, 0) and Size identical. |
141 | SwRect maFramePrintArea; |
142 | |
143 | // bitfield |
144 | bool mbFrameAreaPositionValid : 1; |
145 | bool mbFrameAreaSizeValid : 1; |
146 | bool mbFramePrintAreaValid : 1; |
147 | |
148 | // #i65250# |
149 | // frame ID is now in general available - used for layout loop control |
150 | static sal_uInt32 mnLastFrameId; |
151 | const sal_uInt32 mnFrameId; |
152 | |
153 | protected: |
154 | // write access to mb*Valid flags |
155 | void setFrameAreaPositionValid(bool bNew); |
156 | void setFrameAreaSizeValid(bool bNew); |
157 | void setFramePrintAreaValid(bool bNew); |
158 | |
159 | public: |
160 | SwFrameAreaDefinition(); |
161 | virtual ~SwFrameAreaDefinition(); |
162 | |
163 | // read access to mb*Valid flags |
164 | bool isFrameAreaPositionValid() const { return mbFrameAreaPositionValid; } |
165 | bool isFrameAreaSizeValid() const { return mbFrameAreaSizeValid; } |
166 | bool isFramePrintAreaValid() const { return mbFramePrintAreaValid; } |
167 | |
168 | // syntactic sugar: test whole FrameAreaDefinition |
169 | bool isFrameAreaDefinitionValid() const { return isFrameAreaPositionValid() && isFrameAreaSizeValid() && isFramePrintAreaValid(); } |
170 | |
171 | // #i65250# |
172 | sal_uInt32 GetFrameId() const { return mnFrameId; } |
173 | |
174 | // read accesses to FrameArea definitions - only const access allowed. |
175 | // Do *not* const_cast results, it is necessary to track changes. use |
176 | // the below offered WriteAccess helper classes instead |
177 | const SwRect& getFrameArea() const { return maFrameArea; } |
178 | const SwRect& getFramePrintArea() const { return maFramePrintArea; } |
179 | |
180 | // helper class(es) for FrameArea manipulation. These |
181 | // have to be used to apply changes to FrameAreas. They hold a copy of the |
182 | // SwRect for manipulation. It gets written back at destruction. Thus, this |
183 | // mechanism depends on scope usage, take care. It prevents errors using |
184 | // different instances of SwFrame in get/set methods which is more safe |
185 | class FrameAreaWriteAccess : public SwRect |
186 | { |
187 | private: |
188 | SwFrameAreaDefinition& mrTarget; |
189 | |
190 | FrameAreaWriteAccess(const FrameAreaWriteAccess&) = delete; |
191 | FrameAreaWriteAccess& operator=(const FrameAreaWriteAccess&) = delete; |
192 | |
193 | public: |
194 | FrameAreaWriteAccess(SwFrameAreaDefinition& rTarget) : SwRect(rTarget.getFrameArea()), mrTarget(rTarget) {} |
195 | ~FrameAreaWriteAccess(); |
196 | void setSwRect(const SwRect& rNew) { *reinterpret_cast< SwRect* >(this) = rNew; } |
197 | }; |
198 | |
199 | // same helper for FramePrintArea |
200 | class FramePrintAreaWriteAccess : public SwRect |
201 | { |
202 | private: |
203 | SwFrameAreaDefinition& mrTarget; |
204 | |
205 | FramePrintAreaWriteAccess(const FramePrintAreaWriteAccess&) = delete; |
206 | FramePrintAreaWriteAccess& operator=(const FramePrintAreaWriteAccess&) = delete; |
207 | |
208 | public: |
209 | FramePrintAreaWriteAccess(SwFrameAreaDefinition& rTarget) : SwRect(rTarget.getFramePrintArea()), mrTarget(rTarget) {} |
210 | ~FramePrintAreaWriteAccess(); |
211 | void setSwRect(const SwRect& rNew) { *reinterpret_cast< SwRect* >(this) = rNew; } |
212 | }; |
213 | |
214 | // RotateFlyFrame3 - Support for Transformations |
215 | // Hand out the Transformations for the current FrameAreaDefinition |
216 | // for the FrameArea and FramePrintArea. |
217 | // FramePrintArea is not relative to FrameArea in this |
218 | // transformation representation (to make it easier to use and understand). |
219 | // There is no 'set' method since SwFrame is a layout object. For |
220 | // some cases rotation will be included (used for SwGrfNode in inner |
221 | // SwFrame of a SwFlyFrame) |
222 | virtual basegfx::B2DHomMatrix getFrameAreaTransformation() const; |
223 | virtual basegfx::B2DHomMatrix getFramePrintAreaTransformation() const; |
224 | |
225 | // RotateFlyFrame3 - Support for Transformations |
226 | // Modify current transformations by applying given translation |
227 | virtual void transform_translate(const Point& rOffset); |
228 | }; |
229 | |
230 | /// RotateFlyFrame3: Helper class when you want to make your SwFrame derivate |
231 | /// transformable. It provides some tooling to do so. To use, add as member |
232 | /// (see e.g. SwFlyFreeFrame which uses 'std::unique_ptr< TransformableSwFrame >') |
233 | class TransformableSwFrame |
234 | { |
235 | private: |
236 | // The SwFrameAreaDefinition to work on |
237 | SwFrameAreaDefinition& mrSwFrameAreaDefinition; |
238 | |
239 | // FrameAreaTransformation and FramePrintAreaTransformation |
240 | // !identity when needed (translate/scale is used (e.g. rotation)) |
241 | basegfx::B2DHomMatrix maFrameAreaTransformation; |
242 | basegfx::B2DHomMatrix maFramePrintAreaTransformation; |
243 | |
244 | public: |
245 | TransformableSwFrame(SwFrameAreaDefinition& rSwFrameAreaDefinition) |
246 | : mrSwFrameAreaDefinition(rSwFrameAreaDefinition), |
247 | maFrameAreaTransformation(), |
248 | maFramePrintAreaTransformation() |
249 | { |
250 | } |
251 | |
252 | // get SwFrameArea in transformation form |
253 | const basegfx::B2DHomMatrix& getLocalFrameAreaTransformation() const |
254 | { |
255 | return maFrameAreaTransformation; |
256 | } |
257 | |
258 | // get SwFramePrintArea in transformation form |
259 | const basegfx::B2DHomMatrix& getLocalFramePrintAreaTransformation() const |
260 | { |
261 | return maFramePrintAreaTransformation; |
262 | } |
263 | |
264 | // Helpers to re-create the untransformed SwRect(s) originally |
265 | // in the SwFrameAreaDefinition, based on the current Transformations. |
266 | SwRect getUntransformedFrameArea() const; |
267 | SwRect getUntransformedFramePrintArea() const; |
268 | |
269 | // Helper method to re-create FrameAreaTransformations based on the |
270 | // current FrameAreaDefinition transformed by given rotation and Center |
271 | void createFrameAreaTransformations( |
272 | double fRotation, |
273 | const basegfx::B2DPoint& rCenter); |
274 | |
275 | // Tooling method to reset the SwRect(s) in the current |
276 | // SwFrameAreaDefinition which are already adapted to |
277 | // Transformation back to the untransformed state, using |
278 | // the getUntransformedFrame*Area calls above when needed. |
279 | // Only the SwRect(s) are changed back, not the transformations. |
280 | void restoreFrameAreas(); |
281 | |
282 | // Re-Creates the SwRect(s) as BoundAreas based on the current |
283 | // set Transformations. |
284 | void adaptFrameAreasToTransformations(); |
285 | |
286 | // Modify current definitions by applying the given transformation |
287 | void transform(const basegfx::B2DHomMatrix& aTransform); |
288 | }; |
289 | |
290 | /** |
291 | * Base class of the Writer layout elements. |
292 | * |
293 | * This includes not only fly frames, but everything down to the paragraph |
294 | * level: pages, headers, footers, etc. (Inside a paragraph SwLinePortion |
295 | * instances are used.) |
296 | */ |
297 | class SW_DLLPUBLIC__attribute__ ((visibility("default"))) SwFrame : public SwFrameAreaDefinition, public SwClient, public SfxBroadcaster |
298 | { |
299 | // the hidden Frame |
300 | friend class SwFlowFrame; |
301 | friend class SwLayoutFrame; |
302 | friend class SwLooping; |
303 | friend class SwDeletionChecker; // for GetDep() |
304 | |
305 | // voids lower during creation of a column |
306 | friend SwFrame *SaveContent( SwLayoutFrame *, SwFrame* pStart ); |
307 | friend void RestoreContent( SwFrame *, SwLayoutFrame *, SwFrame *pSibling ); |
308 | |
309 | // for validating a mistakenly invalidated one in SwContentFrame::MakeAll |
310 | friend void ValidateSz( SwFrame *pFrame ); |
311 | // implemented in text/txtftn.cxx, prevents Footnote oscillation |
312 | friend void ValidateText( SwFrame *pFrame ); |
313 | |
314 | friend void MakeNxt( SwFrame *pFrame, SwFrame *pNxt ); |
315 | |
316 | // cache for (border) attributes |
317 | static SwCache *mpCache; |
318 | |
319 | SwRootFrame *mpRoot; |
320 | SwLayoutFrame *mpUpper; |
321 | SwFrame *mpNext; |
322 | SwFrame *mpPrev; |
323 | |
324 | // sw_redlinehide: hide these dangerous SwClient functions |
325 | using SwClient::GetRegisteredInNonConst; |
326 | using SwClient::GetRegisteredIn; |
327 | |
328 | SwFrame *FindNext_(); |
329 | SwFrame *FindPrev_(); |
330 | |
331 | /** method to determine next content frame in the same environment |
332 | for a flow frame (content frame, table frame, section frame) |
333 | |
334 | #i27138# - adding documentation: |
335 | Travelling downwards through the layout to determine the next content |
336 | frame in the same environment. There are several environments in a |
337 | document, which form a closed context regarding this function. These |
338 | environments are: |
339 | - Each page header |
340 | - Each page footer |
341 | - Each unlinked fly frame |
342 | - Each group of linked fly frames |
343 | - All footnotes |
344 | - All document body frames |
345 | #i27138# - adding parameter <_bInSameFootnote> |
346 | Its default value is <false>. If its value is <true>, the environment |
347 | 'All footnotes' is no longer treated. Instead each footnote is treated |
348 | as an own environment. |
349 | |
350 | @param _bInSameFootnote |
351 | input parameter - boolean indicating, that the found next content |
352 | frame has to be in the same footnote frame. This parameter is only |
353 | relevant for flow frames in footnotes. |
354 | |
355 | @return SwContentFrame* |
356 | pointer to the found next content frame. It's NULL, if none exists. |
357 | */ |
358 | SwContentFrame* FindNextCnt_( const bool _bInSameFootnote ); |
359 | |
360 | /** method to determine previous content frame in the same environment |
361 | for a flow frame (content frame, table frame, section frame) |
362 | |
363 | #i27138# |
364 | Travelling upwards through the layout to determine the previous content |
365 | frame in the same environment. There are several environments in a |
366 | document, which form a closed context regarding this function. These |
367 | environments are: |
368 | - Each page header |
369 | - Each page footer |
370 | - Each unlinked fly frame |
371 | - Each group of linked fly frames |
372 | - All footnotes |
373 | - All document body frames |
374 | #i27138# - adding parameter <_bInSameFootnote> |
375 | Its default value is <false>. If its value is <true>, the environment |
376 | 'All footnotes' is no longer treated. Instead each footnote is treated |
377 | as an own environment. |
378 | |
379 | The found previous content frame has to be in the same footnote frame. This is only |
380 | relevant for flow frames in footnotes. |
381 | |
382 | @return SwContentFrame* |
383 | pointer to the found previous content frame. It's NULL, if none exists. |
384 | */ |
385 | SwContentFrame* FindPrevCnt_(); |
386 | |
387 | void UpdateAttrFrame( const SfxPoolItem*, const SfxPoolItem*, sal_uInt8 & ); |
388 | SwFrame* GetIndNext_(); |
389 | void SetDirFlags( bool bVert ); |
390 | |
391 | const SwLayoutFrame* ImplGetNextLayoutLeaf( bool bFwd ) const; |
392 | |
393 | SwPageFrame* ImplFindPageFrame(); |
394 | |
395 | protected: |
396 | std::unique_ptr<SwSortedObjs> m_pDrawObjs; // draw objects, can be null |
397 | SwFrameType mnFrameType; //Who am I? |
398 | |
399 | bool mbInDtor : 1; |
400 | bool mbInvalidR2L : 1; |
401 | bool mbDerivedR2L : 1; |
402 | bool mbRightToLeft : 1; |
403 | bool mbInvalidVert : 1; |
404 | bool mbDerivedVert : 1; |
405 | bool mbVertical : 1; |
406 | |
407 | bool mbVertLR : 1; |
408 | bool mbVertLRBT : 1; |
409 | |
410 | bool mbValidLineNum : 1; |
411 | bool mbFixSize : 1; |
412 | |
413 | // if true, frame will be painted completely even content was changed |
414 | // only partially. For ContentFrames a border (from Action) will exclusively |
415 | // painted if <mbCompletePaint> is true. |
416 | bool mbCompletePaint : 1; |
417 | |
418 | bool mbRetouche : 1; // frame is responsible for retouching |
419 | |
420 | bool mbInfInvalid : 1; // InfoFlags are invalid |
421 | bool mbInfBody : 1; // Frame is in document body |
422 | bool mbInfTab : 1; // Frame is in a table |
423 | bool mbInfFly : 1; // Frame is in a Fly |
424 | bool mbInfFootnote : 1; // Frame is in a footnote |
425 | bool mbInfSct : 1; // Frame is in a section |
426 | bool mbColLocked : 1; // lock Grow/Shrink for column-wise section |
427 | // or fly frames, will be set in Format |
428 | bool m_isInDestroy : 1; |
429 | bool mbForbidDelete : 1; |
430 | |
431 | void ColLock() { mbColLocked = true; } |
432 | void ColUnlock() { mbColLocked = false; } |
433 | |
434 | virtual void DestroyImpl(); |
435 | virtual ~SwFrame() override; |
436 | |
437 | // Only used by SwRootFrame Ctor to get 'this' into mpRoot... |
438 | void setRootFrame( SwRootFrame* pRoot ) { mpRoot = pRoot; } |
439 | |
440 | SwPageFrame *InsertPage( SwPageFrame *pSibling, bool bFootnote ); |
441 | void PrepareMake(vcl::RenderContext* pRenderContext); |
442 | void OptPrepareMake(); |
443 | virtual void MakePos(); |
444 | // Format next frame of table frame to assure keeping attributes. |
445 | // In case of nested tables method <SwFrame::MakeAll()> is called to |
446 | // avoid formatting of superior table frame. |
447 | friend SwFrame* sw_FormatNextContentForKeep( SwTabFrame* pTabFrame ); |
448 | |
449 | virtual void MakeAll(vcl::RenderContext* pRenderContext) = 0; |
450 | // adjust frames of a page |
451 | SwTwips AdjustNeighbourhood( SwTwips nDiff, bool bTst = false ); |
452 | |
453 | // change only frame size not the size of PrtArea |
454 | virtual SwTwips ShrinkFrame( SwTwips, bool bTst = false, bool bInfo = false ) = 0; |
455 | virtual SwTwips GrowFrame ( SwTwips, bool bTst = false, bool bInfo = false ) = 0; |
456 | |
457 | /// use these so we can grep for SwFrame's GetRegisteredIn accesses |
458 | /// beware that SwTextFrame may return sw::WriterMultiListener |
459 | SwModify *GetDep() { return GetRegisteredInNonConst(); } |
460 | const SwModify *GetDep() const { return GetRegisteredIn(); } |
461 | |
462 | SwFrame( SwModify*, SwFrame* ); |
463 | |
464 | void CheckDir( SvxFrameDirection nDir, bool bVert, bool bOnlyBiDi, bool bBrowse ); |
465 | |
466 | /** enumeration for the different invalidations |
467 | #i28701# |
468 | */ |
469 | enum InvalidationType |
470 | { |
471 | INVALID_SIZE, INVALID_PRTAREA, INVALID_POS, INVALID_LINENUM, INVALID_ALL |
472 | }; |
473 | |
474 | /** method to determine, if an invalidation is allowed. |
475 | #i28701 |
476 | */ |
477 | virtual bool InvalidationAllowed( const InvalidationType _nInvalid ) const; |
478 | |
479 | /** method to perform additional actions on an invalidation |
480 | |
481 | #i28701# |
482 | Method has *only* to contain actions, which has to be performed on |
483 | *every* assignment of the corresponding flag to <false>. |
484 | */ |
485 | virtual void ActionOnInvalidation( const InvalidationType _nInvalid ); |
486 | |
487 | // draw shadow and borders |
488 | void PaintShadow( const SwRect&, SwRect&, const SwBorderAttrs& ) const; |
489 | virtual void Modify( const SfxPoolItem*, const SfxPoolItem* ) override; |
490 | |
491 | virtual const IDocumentDrawModelAccess& getIDocumentDrawModelAccess( ); |
492 | |
493 | public: |
494 | virtual css::uno::Sequence< css::style::TabStop > GetTabStopInfo( SwTwips ) |
495 | { |
496 | return css::uno::Sequence< css::style::TabStop >(); |
497 | } |
498 | |
499 | |
500 | SwFrameType GetType() const { return mnFrameType; } |
501 | |
502 | static SwCache &GetCache() { return *mpCache; } |
503 | static SwCache *GetCachePtr() { return mpCache; } |
504 | static void SetCache( SwCache *pNew ) { mpCache = pNew; } |
505 | |
506 | // change PrtArea size and FrameSize |
507 | SwTwips Shrink( SwTwips, bool bTst = false, bool bInfo = false ); |
508 | SwTwips Grow ( SwTwips, bool bTst = false, bool bInfo = false ); |
509 | |
510 | // different methods for inserting in layout tree (for performance reasons) |
511 | |
512 | // insert before pBehind or at the end of the chain below mpUpper |
513 | void InsertBefore( SwLayoutFrame* pParent, SwFrame* pBehind ); |
514 | // insert after pBefore or at the beginning of the chain below mpUpper |
515 | void InsertBehind( SwLayoutFrame *pParent, SwFrame *pBefore ); |
516 | // insert before pBehind or at the end of the chain while considering |
517 | // the siblings of pSct |
518 | bool InsertGroupBefore( SwFrame* pParent, SwFrame* pWhere, SwFrame* pSct ); |
519 | void RemoveFromLayout(); |
520 | |
521 | // For internal use only - who ignores this will be put in a sack and has |
522 | // to stay there for two days |
523 | // Does special treatment for Get_[Next|Prev]Leaf() (for tables). |
524 | SwLayoutFrame *GetLeaf( MakePageType eMakePage, bool bFwd ); |
525 | SwLayoutFrame *GetNextLeaf ( MakePageType eMakePage ); |
526 | SwLayoutFrame *GetNextFootnoteLeaf( MakePageType eMakePage ); |
527 | SwLayoutFrame *GetNextSctLeaf( MakePageType eMakePage ); |
528 | SwLayoutFrame *GetNextCellLeaf(); |
529 | SwLayoutFrame *GetPrevLeaf (); |
530 | SwLayoutFrame *GetPrevFootnoteLeaf( MakePageType eMakeFootnote ); |
531 | SwLayoutFrame *GetPrevSctLeaf(); |
532 | SwLayoutFrame *GetPrevCellLeaf(); |
533 | const SwLayoutFrame *GetLeaf ( MakePageType eMakePage, bool bFwd, |
534 | const SwFrame *pAnch ) const; |
535 | |
536 | bool WrongPageDesc( SwPageFrame* pNew ); |
537 | |
538 | //#i28701# - new methods to append/remove drawing objects |
539 | void AppendDrawObj( SwAnchoredObject& _rNewObj ); |
540 | void RemoveDrawObj( SwAnchoredObject& _rToRemoveObj ); |
541 | |
542 | // work with chain of FlyFrames |
543 | void AppendFly( SwFlyFrame *pNew ); |
544 | void RemoveFly( SwFlyFrame *pToRemove ); |
545 | const SwSortedObjs *GetDrawObjs() const { return m_pDrawObjs.get(); } |
546 | SwSortedObjs *GetDrawObjs() { return m_pDrawObjs.get(); } |
547 | // #i28701# - change purpose of method and adjust its name |
548 | void InvalidateObjs( const bool _bNoInvaOfAsCharAnchoredObjs = true ); |
549 | |
550 | virtual void PaintSwFrameShadowAndBorder( |
551 | const SwRect&, |
552 | const SwPageFrame* pPage, |
553 | const SwBorderAttrs&) const; |
554 | void PaintBaBo( const SwRect&, const SwPageFrame *pPage, |
555 | const bool bOnlyTextBackground = false) const; |
556 | void PaintSwFrameBackground( const SwRect&, const SwPageFrame *pPage, |
557 | const SwBorderAttrs &, |
558 | const bool bLowerMode = false, |
559 | const bool bLowerBorder = false, |
560 | const bool bOnlyTextBackground = false ) const; |
561 | void PaintBorderLine( const SwRect&, const SwRect&, const SwPageFrame*, |
562 | const Color *pColor, |
563 | const SvxBorderLineStyle = SvxBorderLineStyle::SOLID ) const; |
564 | |
565 | std::unique_ptr<drawinglayer::processor2d::BaseProcessor2D> CreateProcessor2D( ) const; |
566 | void ProcessPrimitives( const drawinglayer::primitive2d::Primitive2DContainer& rSequence ) const; |
567 | |
568 | // retouch, not in the area of the given Rect! |
569 | void Retouch( const SwPageFrame *pPage, const SwRect &rRect ) const; |
570 | |
571 | bool GetBackgroundBrush( |
572 | drawinglayer::attribute::SdrAllFillAttributesHelperPtr& rFillAttributes, |
573 | const SvxBrushItem*& rpBrush, |
574 | const Color*& rpColor, |
575 | SwRect &rOrigRect, |
576 | bool bLowerMode, |
577 | bool bConsiderTextBox ) const; |
578 | |
579 | inline void SetCompletePaint() const; |
580 | inline void ResetCompletePaint() const; |
581 | bool IsCompletePaint() const { return mbCompletePaint; } |
582 | |
583 | inline void SetRetouche() const; |
584 | inline void ResetRetouche() const; |
585 | bool IsRetouche() const { return mbRetouche; } |
586 | |
587 | void SetInfFlags(); |
588 | void InvalidateInfFlags() { mbInfInvalid = true; } |
589 | inline bool IsInDocBody() const; // use InfoFlags, determine flags |
590 | inline bool IsInFootnote() const; // if necessary |
591 | inline bool IsInTab() const; |
592 | inline bool IsInFly() const; |
593 | inline bool IsInSct() const; |
594 | |
595 | // If frame is inside a split table row, this function returns |
596 | // the corresponding row frame in the follow table. |
597 | const SwRowFrame* IsInSplitTableRow() const; |
598 | |
599 | // If frame is inside a follow flow row, this function returns |
600 | // the corresponding row frame master table |
601 | const SwRowFrame* IsInFollowFlowRow() const; |
602 | |
603 | bool IsInBalancedSection() const; |
604 | |
605 | inline bool IsVertical() const; |
606 | inline bool IsVertLR() const; |
607 | inline bool IsVertLRBT() const; |
608 | |
609 | void SetDerivedVert( bool bNew ){ mbDerivedVert = bNew; } |
610 | void SetInvalidVert( bool bNew) { mbInvalidVert = bNew; } |
611 | inline bool IsRightToLeft() const; |
612 | void SetDerivedR2L( bool bNew ) { mbDerivedR2L = bNew; } |
613 | |
614 | void CheckDirChange(); |
615 | // returns upper left frame position for LTR and |
616 | // upper right frame position for Asian / RTL frames |
617 | Point GetFrameAnchorPos( bool bIgnoreFlysAnchoredAtThisFrame ) const; |
618 | |
619 | /** determine, if frame is moveable in given environment |
620 | |
621 | method replaced 'old' method <bool IsMoveable() const>. |
622 | Determines, if frame is moveable in given environment. if no environment |
623 | is given (parameter _pLayoutFrame == 0), the movability in the actual |
624 | environment (<GetUpper()) is checked. |
625 | |
626 | @param _pLayoutFrame |
627 | input parameter - given environment (layout frame), in which the movability |
628 | will be checked. If not set ( == 0 ), actual environment is taken. |
629 | |
630 | @return boolean, indicating, if frame is moveable in given environment |
631 | */ |
632 | bool IsMoveable( const SwLayoutFrame* _pLayoutFrame = nullptr ) const; |
633 | |
634 | // Is it permitted for the (Text)Frame to add a footnote in the current |
635 | // environment (not e.g. for repeating table headlines) |
636 | bool IsFootnoteAllowed() const; |
637 | |
638 | virtual void Format( vcl::RenderContext* pRenderContext, const SwBorderAttrs *pAttrs = nullptr ); |
639 | |
640 | virtual void CheckDirection( bool bVert ); |
641 | |
642 | void ReinitializeFrameSizeAttrFlags(); |
643 | |
644 | /// WARNING: this may not return correct RES_PAGEDESC/RES_BREAK items for |
645 | /// SwTextFrame, use GetBreakItem()/GetPageDescItem() instead |
646 | const SwAttrSet *GetAttrSet() const; |
647 | virtual const SvxFormatBreakItem& GetBreakItem() const; |
648 | virtual const SwFormatPageDesc& GetPageDescItem() const; |
649 | |
650 | bool HasFixSize() const { return mbFixSize; } |
651 | |
652 | // check all pages (starting from the given) and correct them if needed |
653 | static void CheckPageDescs( SwPageFrame *pStart, bool bNotifyFields = true, SwPageFrame** ppPrev = nullptr); |
654 | |
655 | // might return 0, with and without const |
656 | SwFrame *GetNext() { return mpNext; } |
657 | SwFrame *GetPrev() { return mpPrev; } |
658 | SwLayoutFrame *GetUpper() { return mpUpper; } |
659 | SwRootFrame *getRootFrame(){ return mpRoot; } |
660 | SwPageFrame *FindPageFrame() { return IsPageFrame() ? reinterpret_cast<SwPageFrame*>(this) : ImplFindPageFrame(); } |
661 | SwFrame *FindColFrame(); |
662 | SwRowFrame *FindRowFrame(); |
663 | SwFootnoteBossFrame *FindFootnoteBossFrame( bool bFootnotes = false ); |
664 | SwTabFrame *ImplFindTabFrame(); |
665 | SwFootnoteFrame *ImplFindFootnoteFrame(); |
666 | SwFlyFrame *ImplFindFlyFrame(); |
667 | SwSectionFrame *ImplFindSctFrame(); |
668 | const SwBodyFrame *ImplFindBodyFrame() const; |
669 | SwFrame *FindFooterOrHeader(); |
670 | SwFrame *GetLower(); |
671 | const SwFrame *GetNext() const { return mpNext; } |
672 | const SwFrame *GetPrev() const { return mpPrev; } |
673 | const SwLayoutFrame *GetUpper() const { return mpUpper; } |
674 | const SwRootFrame *getRootFrame() const { return mpRoot; } |
675 | inline SwTabFrame *FindTabFrame(); |
676 | inline SwFootnoteFrame *FindFootnoteFrame(); |
677 | inline SwFlyFrame *FindFlyFrame(); |
678 | inline SwSectionFrame *FindSctFrame(); |
679 | inline SwFrame *FindNext(); |
680 | // #i27138# - add parameter <_bInSameFootnote> |
681 | SwContentFrame* FindNextCnt( const bool _bInSameFootnote = false ); |
682 | inline SwFrame *FindPrev(); |
683 | inline const SwPageFrame *FindPageFrame() const; |
684 | inline const SwFootnoteBossFrame *FindFootnoteBossFrame( bool bFootnote = false ) const; |
685 | inline const SwFrame *FindColFrame() const; |
686 | inline const SwFrame *FindFooterOrHeader() const; |
687 | inline const SwTabFrame *FindTabFrame() const; |
688 | inline const SwFootnoteFrame *FindFootnoteFrame() const; |
689 | inline const SwFlyFrame *FindFlyFrame() const; |
690 | inline const SwSectionFrame *FindSctFrame() const; |
691 | inline const SwBodyFrame *FindBodyFrame() const; |
692 | inline const SwFrame *FindNext() const; |
693 | // #i27138# - add parameter <_bInSameFootnote> |
694 | const SwContentFrame* FindNextCnt( const bool _bInSameFootnote = false ) const; |
695 | inline const SwFrame *FindPrev() const; |
696 | const SwFrame *GetLower() const; |
697 | |
698 | SwContentFrame* FindPrevCnt(); |
699 | |
700 | const SwContentFrame* FindPrevCnt() const; |
701 | |
702 | // #i79774# |
703 | SwFrame* GetIndPrev_() const; |
704 | SwFrame* GetIndPrev() const |
705 | { return ( mpPrev || !IsInSct() ) ? mpPrev : GetIndPrev_(); } |
706 | |
707 | SwFrame* GetIndNext() |
708 | { return ( mpNext || !IsInSct() ) ? mpNext : GetIndNext_(); } |
709 | const SwFrame* GetIndNext() const { return const_cast<SwFrame*>(this)->GetIndNext(); } |
710 | |
711 | sal_uInt16 GetPhyPageNum() const; // page number without offset |
712 | sal_uInt16 GetVirtPageNum() const; // page number with offset |
713 | bool OnRightPage() const { return 0 != GetPhyPageNum() % 2; }; |
714 | bool WannaRightPage() const; |
715 | bool OnFirstPage() const; |
716 | |
717 | inline const SwLayoutFrame *GetPrevLayoutLeaf() const; |
718 | inline const SwLayoutFrame *GetNextLayoutLeaf() const; |
719 | inline SwLayoutFrame *GetPrevLayoutLeaf(); |
720 | inline SwLayoutFrame *GetNextLayoutLeaf(); |
721 | |
722 | virtual void Calc(vcl::RenderContext* pRenderContext) const; // here might be "formatted" |
723 | inline void OptCalc() const; // here we assume (for optimization) that |
724 | // the predecessors are already formatted |
725 | Point GetRelPos() const; |
726 | |
727 | // PaintArea is the area where content might be displayed. |
728 | // The margin of a page or the space between columns belongs to it. |
729 | SwRect GetPaintArea() const; |
730 | |
731 | // UnionFrame is the union of Frame- and PrtArea, normally identical |
732 | // to the FrameArea except in case of negative Prt margins. |
733 | SwRect UnionFrame( bool bBorder = false ) const; |
734 | |
735 | virtual Size ChgSize( const Size& aNewSize ); |
736 | |
737 | virtual void Cut() = 0; |
738 | virtual void Paste( SwFrame* pParent, SwFrame* pSibling = nullptr ) = 0; |
739 | |
740 | void ValidateLineNum() { mbValidLineNum = true; } |
741 | |
742 | bool GetValidLineNumFlag()const { return mbValidLineNum; } |
743 | |
744 | // Only invalidate Frame |
745 | // #i28701# - add call to method <ActionOnInvalidation(..)> |
746 | // for all invalidation methods. |
747 | // #i28701# - use method <InvalidationAllowed(..)> to |
748 | // decide, if invalidation will to be performed or not. |
749 | // #i26945# - no additional invalidation, if it's already |
750 | // invalidate. |
751 | void InvalidateSize_() |
752 | { |
753 | if ( isFrameAreaSizeValid() && InvalidationAllowed( INVALID_SIZE ) ) |
754 | { |
755 | setFrameAreaSizeValid(false); |
756 | ActionOnInvalidation( INVALID_SIZE ); |
757 | } |
758 | } |
759 | void InvalidatePrt_() |
760 | { |
761 | if ( isFramePrintAreaValid() && InvalidationAllowed( INVALID_PRTAREA ) ) |
762 | { |
763 | setFramePrintAreaValid(false); |
764 | ActionOnInvalidation( INVALID_PRTAREA ); |
765 | } |
766 | } |
767 | void InvalidatePos_() |
768 | { |
769 | if ( isFrameAreaPositionValid() && InvalidationAllowed( INVALID_POS ) ) |
770 | { |
771 | setFrameAreaPositionValid(false); |
772 | ActionOnInvalidation( INVALID_POS ); |
773 | } |
774 | } |
775 | void InvalidateLineNum_() |
776 | { |
777 | if ( mbValidLineNum && InvalidationAllowed( INVALID_LINENUM ) ) |
778 | { |
779 | mbValidLineNum = false; |
780 | ActionOnInvalidation( INVALID_LINENUM ); |
781 | } |
782 | } |
783 | void InvalidateAll_() |
784 | { |
785 | if ( ( isFrameAreaSizeValid() || isFramePrintAreaValid() || isFrameAreaPositionValid() ) && InvalidationAllowed( INVALID_ALL ) ) |
786 | { |
787 | setFrameAreaSizeValid(false); |
788 | setFrameAreaPositionValid(false); |
789 | setFramePrintAreaValid(false); |
790 | ActionOnInvalidation( INVALID_ALL ); |
791 | } |
792 | } |
793 | // also notify page at the same time |
794 | inline void InvalidateSize(); |
795 | inline void InvalidatePrt(); |
796 | inline void InvalidatePos(); |
797 | inline void InvalidateLineNum(); |
798 | inline void InvalidateAll(); |
799 | void ImplInvalidateSize(); |
800 | void ImplInvalidatePrt(); |
801 | void ImplInvalidatePos(); |
802 | void ImplInvalidateLineNum(); |
803 | |
804 | inline void InvalidateNextPos( bool bNoFootnote = false ); |
805 | void ImplInvalidateNextPos( bool bNoFootnote ); |
806 | |
807 | /** method to invalidate printing area of next frame |
808 | #i11859# |
809 | */ |
810 | void InvalidateNextPrtArea(); |
811 | |
812 | void InvalidatePage( const SwPageFrame *pPage = nullptr ) const; |
813 | |
814 | virtual bool FillSelection( SwSelectionList& rList, const SwRect& rRect ) const; |
815 | |
816 | virtual bool GetModelPositionForViewPoint( SwPosition *, Point&, |
817 | SwCursorMoveState* = nullptr, bool bTestBackground = false ) const; |
818 | virtual bool GetCharRect( SwRect &, const SwPosition&, |
819 | SwCursorMoveState* = nullptr, bool bAllowFarAway = true ) const; |
820 | virtual void PaintSwFrame( vcl::RenderContext& rRenderContext, SwRect const&, |
821 | SwPrintData const*const pPrintData = nullptr ) const; |
822 | |
823 | // HACK: shortcut between frame and formatting |
824 | // It's your own fault if you cast void* incorrectly! In any case check |
825 | // the void* for 0. |
826 | virtual bool Prepare( const PrepareHint ePrep = PrepareHint::Clear, |
827 | const void *pVoid = nullptr, bool bNotify = true ); |
828 | |
829 | // true if it is the correct class, false otherwise |
830 | inline bool IsLayoutFrame() const; |
831 | inline bool IsRootFrame() const; |
832 | inline bool IsPageFrame() const; |
833 | inline bool IsColumnFrame() const; |
834 | inline bool IsFootnoteBossFrame() const; // footnote bosses might be PageFrames or ColumnFrames |
835 | inline bool IsHeaderFrame() const; |
836 | inline bool IsFooterFrame() const; |
837 | inline bool IsFootnoteContFrame() const; |
838 | inline bool IsFootnoteFrame() const; |
839 | inline bool IsBodyFrame() const; |
840 | inline bool IsColBodyFrame() const; // implemented in layfrm.hxx, BodyFrame above ColumnFrame |
841 | inline bool IsPageBodyFrame() const; // implemented in layfrm.hxx, BodyFrame above PageFrame |
842 | inline bool IsFlyFrame() const; |
843 | inline bool IsSctFrame() const; |
844 | inline bool IsTabFrame() const; |
845 | inline bool IsRowFrame() const; |
846 | inline bool IsCellFrame() const; |
847 | inline bool IsContentFrame() const; |
848 | inline bool IsTextFrame() const; |
849 | inline bool IsNoTextFrame() const; |
850 | // Frames where its PrtArea depends on their neighbors and that are |
851 | // positioned in the content flow |
852 | inline bool IsFlowFrame() const; |
853 | // Frames that are capable of retouching or that might need to retouch behind |
854 | // themselves |
855 | inline bool IsRetoucheFrame() const; |
856 | inline bool IsAccessibleFrame() const; |
857 | |
858 | void PrepareCursor(); // CursorShell is allowed to call this |
859 | |
860 | // Is the Frame (or the section containing it) protected? Same for Fly in |
861 | // Fly in ... and footnotes |
862 | bool IsProtected() const; |
863 | |
864 | bool IsColLocked() const { return mbColLocked; } |
865 | virtual bool IsDeleteForbidden() const { return mbForbidDelete; } |
866 | |
867 | /// this is the only way to delete a SwFrame instance |
868 | static void DestroyFrame(SwFrame *const pFrame); |
869 | |
870 | bool IsInDtor() const { return mbInDtor; } |
871 | |
872 | // No inline cause we need the function pointers |
873 | long GetTopMargin() const; |
874 | long GetBottomMargin() const; |
875 | long GetLeftMargin() const; |
876 | long GetRightMargin() const; |
877 | void SetTopBottomMargins( long, long ); |
878 | void SetLeftRightMargins( long, long ); |
879 | void SetRightLeftMargins( long, long ); |
880 | long GetPrtLeft() const; |
881 | long GetPrtBottom() const; |
882 | long GetPrtRight() const; |
883 | long GetPrtTop() const; |
884 | bool SetMinLeft( long ); |
885 | bool SetMaxBottom( long ); |
886 | bool SetMaxRight( long ); |
887 | void MakeBelowPos( const SwFrame*, const SwFrame*, bool ); |
888 | void MakeLeftPos( const SwFrame*, const SwFrame*, bool ); |
889 | void MakeRightPos( const SwFrame*, const SwFrame*, bool ); |
890 | bool IsNeighbourFrame() const |
891 | { return bool(GetType() & FRM_NEIGHBOUR(SwFrameType::Column | SwFrameType::Cell)); } |
892 | |
893 | // NEW TABLES |
894 | // Some functions for covered/covering table cells. This way unnecessary |
895 | // includes can be avoided |
896 | virtual bool IsLeaveUpperAllowed() const; |
897 | virtual bool IsCoveredCell() const; |
898 | bool IsInCoveredCell() const; |
899 | |
900 | // #i81146# new loop control |
901 | bool KnowsFormat( const SwFormat& rFormat ) const; |
902 | void RegisterToFormat( SwFormat& rFormat ); |
903 | void ValidateThisAndAllLowers( const sal_uInt16 nStage ); |
904 | |
905 | void ForbidDelete() { mbForbidDelete = true; } |
906 | void AllowDelete() { mbForbidDelete = false; } |
907 | |
908 | drawinglayer::attribute::SdrAllFillAttributesHelperPtr getSdrAllFillAttributesHelper() const; |
909 | bool supportsFullDrawingLayerFillAttributeSet() const; |
910 | |
911 | public: |
912 | // if writer is NULL, dumps the layout structure as XML in layout.xml |
913 | virtual void dumpAsXml(xmlTextWriterPtr writer = nullptr) const; |
914 | void dumpTopMostAsXml(xmlTextWriterPtr writer = nullptr) const; |
915 | void dumpInfosAsXml(xmlTextWriterPtr writer) const; |
916 | virtual void dumpAsXmlAttributes(xmlTextWriterPtr writer) const; |
917 | void dumpChildrenAsXml(xmlTextWriterPtr writer) const; |
918 | bool IsCollapse() const; |
919 | }; |
920 | |
921 | inline bool SwFrame::IsInDocBody() const |
922 | { |
923 | if ( mbInfInvalid ) |
924 | const_cast<SwFrame*>(this)->SetInfFlags(); |
925 | return mbInfBody; |
926 | } |
927 | inline bool SwFrame::IsInFootnote() const |
928 | { |
929 | if ( mbInfInvalid ) |
930 | const_cast<SwFrame*>(this)->SetInfFlags(); |
931 | return mbInfFootnote; |
932 | } |
933 | inline bool SwFrame::IsInTab() const |
934 | { |
935 | if ( mbInfInvalid ) |
936 | const_cast<SwFrame*>(this)->SetInfFlags(); |
937 | return mbInfTab; |
938 | } |
939 | inline bool SwFrame::IsInFly() const |
940 | { |
941 | if ( mbInfInvalid ) |
942 | const_cast<SwFrame*>(this)->SetInfFlags(); |
943 | return mbInfFly; |
944 | } |
945 | inline bool SwFrame::IsInSct() const |
946 | { |
947 | if ( mbInfInvalid ) |
948 | const_cast<SwFrame*>(this)->SetInfFlags(); |
949 | return mbInfSct; |
950 | } |
951 | bool SwFrame::IsVertical() const |
952 | { |
953 | if( mbInvalidVert ) |
954 | const_cast<SwFrame*>(this)->SetDirFlags( true ); |
955 | return mbVertical; |
956 | } |
957 | inline bool SwFrame::IsVertLR() const |
958 | { |
959 | return mbVertLR; |
960 | } |
961 | inline bool SwFrame::IsVertLRBT() const |
962 | { |
963 | return mbVertLRBT; |
964 | } |
965 | inline bool SwFrame::IsRightToLeft() const |
966 | { |
967 | if( mbInvalidR2L ) |
968 | const_cast<SwFrame*>(this)->SetDirFlags( false ); |
969 | return mbRightToLeft; |
970 | } |
971 | |
972 | inline void SwFrame::SetCompletePaint() const |
973 | { |
974 | const_cast<SwFrame*>(this)->mbCompletePaint = true; |
975 | } |
976 | inline void SwFrame::ResetCompletePaint() const |
977 | { |
978 | const_cast<SwFrame*>(this)->mbCompletePaint = false; |
979 | } |
980 | |
981 | inline void SwFrame::SetRetouche() const |
982 | { |
983 | const_cast<SwFrame*>(this)->mbRetouche = true; |
984 | } |
985 | inline void SwFrame::ResetRetouche() const |
986 | { |
987 | const_cast<SwFrame*>(this)->mbRetouche = false; |
988 | } |
989 | |
990 | inline SwLayoutFrame *SwFrame::GetNextLayoutLeaf() |
991 | { |
992 | return const_cast<SwLayoutFrame*>(static_cast<const SwFrame*>(this)->GetNextLayoutLeaf()); |
993 | } |
994 | inline SwLayoutFrame *SwFrame::GetPrevLayoutLeaf() |
995 | { |
996 | return const_cast<SwLayoutFrame*>(static_cast<const SwFrame*>(this)->GetPrevLayoutLeaf()); |
997 | } |
998 | inline const SwLayoutFrame *SwFrame::GetNextLayoutLeaf() const |
999 | { |
1000 | return ImplGetNextLayoutLeaf( true ); |
1001 | } |
1002 | inline const SwLayoutFrame *SwFrame::GetPrevLayoutLeaf() const |
1003 | { |
1004 | return ImplGetNextLayoutLeaf( false ); |
1005 | } |
1006 | |
1007 | inline void SwFrame::InvalidateSize() |
1008 | { |
1009 | if ( isFrameAreaSizeValid() ) |
1010 | { |
1011 | ImplInvalidateSize(); |
1012 | } |
1013 | } |
1014 | inline void SwFrame::InvalidatePrt() |
1015 | { |
1016 | if ( isFramePrintAreaValid() ) |
1017 | { |
1018 | ImplInvalidatePrt(); |
1019 | } |
1020 | } |
1021 | inline void SwFrame::InvalidatePos() |
1022 | { |
1023 | if ( isFrameAreaPositionValid() ) |
1024 | { |
1025 | ImplInvalidatePos(); |
1026 | } |
1027 | } |
1028 | inline void SwFrame::InvalidateLineNum() |
1029 | { |
1030 | if ( mbValidLineNum ) |
1031 | ImplInvalidateLineNum(); |
1032 | } |
1033 | inline void SwFrame::InvalidateAll() |
1034 | { |
1035 | if ( InvalidationAllowed( INVALID_ALL ) ) |
1036 | { |
1037 | if ( isFrameAreaDefinitionValid() ) |
1038 | { |
1039 | ImplInvalidatePos(); |
1040 | } |
1041 | |
1042 | setFrameAreaSizeValid(false); |
1043 | setFrameAreaPositionValid(false); |
1044 | setFramePrintAreaValid(false); |
1045 | |
1046 | // #i28701# |
1047 | ActionOnInvalidation( INVALID_ALL ); |
1048 | } |
1049 | } |
1050 | inline void SwFrame::InvalidateNextPos( bool bNoFootnote ) |
1051 | { |
1052 | if ( mpNext && !mpNext->IsSctFrame() ) |
1053 | mpNext->InvalidatePos(); |
1054 | else |
1055 | ImplInvalidateNextPos( bNoFootnote ); |
1056 | } |
1057 | |
1058 | inline void SwFrame::OptCalc() const |
1059 | { |
1060 | if ( !isFrameAreaPositionValid() || !isFramePrintAreaValid() || !isFrameAreaSizeValid() ) |
1061 | { |
1062 | const_cast<SwFrame*>(this)->OptPrepareMake(); |
1063 | } |
1064 | } |
1065 | inline const SwPageFrame *SwFrame::FindPageFrame() const |
1066 | { |
1067 | return const_cast<SwFrame*>(this)->FindPageFrame(); |
1068 | } |
1069 | inline const SwFrame *SwFrame::FindColFrame() const |
1070 | { |
1071 | return const_cast<SwFrame*>(this)->FindColFrame(); |
1072 | } |
1073 | inline const SwFrame *SwFrame::FindFooterOrHeader() const |
1074 | { |
1075 | return const_cast<SwFrame*>(this)->FindFooterOrHeader(); |
1076 | } |
1077 | inline SwTabFrame *SwFrame::FindTabFrame() |
1078 | { |
1079 | return IsInTab() ? ImplFindTabFrame() : nullptr; |
1080 | } |
1081 | inline const SwFootnoteBossFrame *SwFrame::FindFootnoteBossFrame( bool bFootnote ) const |
1082 | { |
1083 | return const_cast<SwFrame*>(this)->FindFootnoteBossFrame( bFootnote ); |
1084 | } |
1085 | inline SwFootnoteFrame *SwFrame::FindFootnoteFrame() |
1086 | { |
1087 | return IsInFootnote() ? ImplFindFootnoteFrame() : nullptr; |
1088 | } |
1089 | inline SwFlyFrame *SwFrame::FindFlyFrame() |
1090 | { |
1091 | return IsInFly() ? ImplFindFlyFrame() : nullptr; |
1092 | } |
1093 | inline SwSectionFrame *SwFrame::FindSctFrame() |
1094 | { |
1095 | return IsInSct() ? ImplFindSctFrame() : nullptr; |
1096 | } |
1097 | |
1098 | inline const SwBodyFrame *SwFrame::FindBodyFrame() const |
1099 | { |
1100 | return IsInDocBody() ? ImplFindBodyFrame() : nullptr; |
1101 | } |
1102 | |
1103 | inline const SwTabFrame *SwFrame::FindTabFrame() const |
1104 | { |
1105 | return IsInTab() ? const_cast<SwFrame*>(this)->ImplFindTabFrame() : nullptr; |
1106 | } |
1107 | inline const SwFootnoteFrame *SwFrame::FindFootnoteFrame() const |
1108 | { |
1109 | return IsInFootnote() ? const_cast<SwFrame*>(this)->ImplFindFootnoteFrame() : nullptr; |
1110 | } |
1111 | inline const SwFlyFrame *SwFrame::FindFlyFrame() const |
1112 | { |
1113 | return IsInFly() ? const_cast<SwFrame*>(this)->ImplFindFlyFrame() : nullptr; |
1114 | } |
1115 | inline const SwSectionFrame *SwFrame::FindSctFrame() const |
1116 | { |
1117 | return IsInSct() ? const_cast<SwFrame*>(this)->ImplFindSctFrame() : nullptr; |
1118 | } |
1119 | inline SwFrame *SwFrame::FindNext() |
1120 | { |
1121 | if ( mpNext ) |
1122 | return mpNext; |
1123 | else |
1124 | return FindNext_(); |
1125 | } |
1126 | inline const SwFrame *SwFrame::FindNext() const |
1127 | { |
1128 | if ( mpNext ) |
1129 | return mpNext; |
1130 | else |
1131 | return const_cast<SwFrame*>(this)->FindNext_(); |
1132 | } |
1133 | inline SwFrame *SwFrame::FindPrev() |
1134 | { |
1135 | if ( mpPrev && !mpPrev->IsSctFrame() ) |
1136 | return mpPrev; |
1137 | else |
1138 | return FindPrev_(); |
1139 | } |
1140 | inline const SwFrame *SwFrame::FindPrev() const |
1141 | { |
1142 | if ( mpPrev && !mpPrev->IsSctFrame() ) |
1143 | return mpPrev; |
1144 | else |
1145 | return const_cast<SwFrame*>(this)->FindPrev_(); |
1146 | } |
1147 | |
1148 | inline bool SwFrame::IsLayoutFrame() const |
1149 | { |
1150 | return bool(GetType() & FRM_LAYOUTSwFrameType(0x3bFF)); |
1151 | } |
1152 | inline bool SwFrame::IsRootFrame() const |
1153 | { |
1154 | return mnFrameType == SwFrameType::Root; |
1155 | } |
1156 | inline bool SwFrame::IsPageFrame() const |
1157 | { |
1158 | return mnFrameType == SwFrameType::Page; |
1159 | } |
1160 | inline bool SwFrame::IsColumnFrame() const |
1161 | { |
1162 | return mnFrameType == SwFrameType::Column; |
1163 | } |
1164 | inline bool SwFrame::IsFootnoteBossFrame() const |
1165 | { |
1166 | return bool(GetType() & FRM_FTNBOSS(SwFrameType::Page | SwFrameType::Column)); |
1167 | } |
1168 | inline bool SwFrame::IsHeaderFrame() const |
1169 | { |
1170 | return mnFrameType == SwFrameType::Header; |
1171 | } |
1172 | inline bool SwFrame::IsFooterFrame() const |
1173 | { |
1174 | return mnFrameType == SwFrameType::Footer; |
1175 | } |
1176 | inline bool SwFrame::IsFootnoteContFrame() const |
1177 | { |
1178 | return mnFrameType == SwFrameType::FtnCont; |
1179 | } |
1180 | inline bool SwFrame::IsFootnoteFrame() const |
1181 | { |
1182 | return mnFrameType == SwFrameType::Ftn; |
1183 | } |
1184 | inline bool SwFrame::IsBodyFrame() const |
1185 | { |
1186 | return mnFrameType == SwFrameType::Body; |
1187 | } |
1188 | inline bool SwFrame::IsFlyFrame() const |
1189 | { |
1190 | return mnFrameType == SwFrameType::Fly; |
1191 | } |
1192 | inline bool SwFrame::IsSctFrame() const |
1193 | { |
1194 | return mnFrameType == SwFrameType::Section; |
1195 | } |
1196 | inline bool SwFrame::IsTabFrame() const |
1197 | { |
1198 | return mnFrameType == SwFrameType::Tab; |
1199 | } |
1200 | inline bool SwFrame::IsRowFrame() const |
1201 | { |
1202 | return mnFrameType == SwFrameType::Row; |
1203 | } |
1204 | inline bool SwFrame::IsCellFrame() const |
1205 | { |
1206 | return mnFrameType == SwFrameType::Cell; |
1207 | } |
1208 | inline bool SwFrame::IsContentFrame() const |
1209 | { |
1210 | return bool(GetType() & FRM_CNTNT(SwFrameType::Txt | SwFrameType::NoTxt)); |
1211 | } |
1212 | inline bool SwFrame::IsTextFrame() const |
1213 | { |
1214 | return mnFrameType == SwFrameType::Txt; |
1215 | } |
1216 | inline bool SwFrame::IsNoTextFrame() const |
1217 | { |
1218 | return mnFrameType == SwFrameType::NoTxt; |
1219 | } |
1220 | inline bool SwFrame::IsFlowFrame() const |
1221 | { |
1222 | return bool(GetType() & (FRM_CNTNT(SwFrameType::Txt | SwFrameType::NoTxt)|SwFrameType::Tab|SwFrameType::Section)); |
1223 | } |
1224 | inline bool SwFrame::IsRetoucheFrame() const |
1225 | { |
1226 | return bool(GetType() & (FRM_CNTNT(SwFrameType::Txt | SwFrameType::NoTxt)|SwFrameType::Tab|SwFrameType::Section|SwFrameType::Ftn)); |
1227 | } |
1228 | inline bool SwFrame::IsAccessibleFrame() const |
1229 | { |
1230 | return bool(GetType() & FRM_ACCESSIBLE(SwFrameType::Root | SwFrameType::Page | SwFrameType::Header | SwFrameType::Footer | SwFrameType::Ftn | SwFrameType::Fly | SwFrameType ::Tab | SwFrameType::Cell | SwFrameType::Txt)); |
1231 | } |
1232 | |
1233 | //use this to protect a SwFrame for a given scope from getting deleted |
1234 | class SwFrameDeleteGuard |
1235 | { |
1236 | private: |
1237 | SwFrame *m_pForbidFrame; |
1238 | public: |
1239 | //Flag pFrame for SwFrameDeleteGuard lifetime that we shouldn't delete |
1240 | //it in e.g. SwSectionFrame::MergeNext etc because we will need it |
1241 | //again after the SwFrameDeleteGuard dtor |
1242 | explicit SwFrameDeleteGuard(SwFrame* pFrame) |
1243 | : m_pForbidFrame((pFrame && !pFrame->IsDeleteForbidden()) ? |
1244 | pFrame : nullptr) |
1245 | { |
1246 | if (m_pForbidFrame) |
1247 | m_pForbidFrame->ForbidDelete(); |
1248 | } |
1249 | |
1250 | SwFrameDeleteGuard(const SwFrameDeleteGuard&) =delete; |
1251 | |
1252 | ~SwFrameDeleteGuard() |
1253 | { |
1254 | if (m_pForbidFrame) |
1255 | m_pForbidFrame->AllowDelete(); |
1256 | } |
1257 | |
1258 | SwFrameDeleteGuard& operator=(const SwFrameDeleteGuard&) =delete; |
1259 | }; |
1260 | |
1261 | typedef long (SwFrame::*SwFrameGet)() const; |
1262 | typedef bool (SwFrame::*SwFrameMax)( long ); |
1263 | typedef void (SwFrame::*SwFrameMakePos)( const SwFrame*, const SwFrame*, bool ); |
1264 | typedef long (*SwOperator)( long, long ); |
1265 | typedef void (SwFrame::*SwFrameSet)( long, long ); |
1266 | |
1267 | struct SwRectFnCollection |
1268 | { |
1269 | SwRectGet fnGetTop; |
1270 | SwRectGet fnGetBottom; |
1271 | SwRectGet fnGetLeft; |
1272 | SwRectGet fnGetRight; |
1273 | SwRectGet fnGetWidth; |
1274 | SwRectGet fnGetHeight; |
1275 | SwRectPoint fnGetPos; |
1276 | SwRectSize fnGetSize; |
1277 | |
1278 | SwRectSet fnSetTop; |
1279 | SwRectSet fnSetBottom; |
1280 | SwRectSet fnSetLeft; |
1281 | SwRectSet fnSetRight; |
1282 | SwRectSet fnSetWidth; |
1283 | SwRectSet fnSetHeight; |
1284 | |
1285 | SwRectSet fnSubTop; |
1286 | SwRectSet fnAddBottom; |
1287 | SwRectSet fnSubLeft; |
1288 | SwRectSet fnAddRight; |
1289 | SwRectSet fnAddWidth; |
1290 | SwRectSet fnAddHeight; |
1291 | |
1292 | SwRectSet fnSetPosX; |
1293 | SwRectSet fnSetPosY; |
1294 | |
1295 | SwFrameGet fnGetTopMargin; |
1296 | SwFrameGet fnGetBottomMargin; |
1297 | SwFrameGet fnGetLeftMargin; |
1298 | SwFrameGet fnGetRightMargin; |
1299 | SwFrameSet fnSetXMargins; |
1300 | SwFrameSet fnSetYMargins; |
1301 | SwFrameGet fnGetPrtTop; |
1302 | SwFrameGet fnGetPrtBottom; |
1303 | SwFrameGet fnGetPrtLeft; |
1304 | SwFrameGet fnGetPrtRight; |
1305 | SwRectDist fnTopDist; |
1306 | SwRectDist fnBottomDist; |
1307 | SwRectDist fnLeftDist; |
1308 | SwRectDist fnRightDist; |
1309 | SwFrameMax fnSetLimit; |
1310 | SwRectMax fnOverStep; |
1311 | |
1312 | SwRectSetPos fnSetPos; |
1313 | SwFrameMakePos fnMakePos; |
1314 | SwOperator fnXDiff; |
1315 | SwOperator fnYDiff; |
1316 | SwOperator fnXInc; |
1317 | SwOperator fnYInc; |
1318 | |
1319 | SwRectSetTwice fnSetLeftAndWidth; |
1320 | SwRectSetTwice fnSetTopAndHeight; |
1321 | }; |
1322 | |
1323 | typedef SwRectFnCollection* SwRectFn; |
1324 | |
1325 | // This class allows to use proper methods regardless of orientation (LTR/RTL, horizontal or vertical) |
1326 | extern SwRectFn fnRectHori, fnRectVert, fnRectVertL2R, fnRectVertL2RB2T; |
1327 | class SwRectFnSet { |
1328 | public: |
1329 | explicit SwRectFnSet(const SwFrame *pFrame) |
1330 | : m_bVert(pFrame->IsVertical()) |
1331 | , m_bVertL2R(pFrame->IsVertLR()) |
1332 | , m_bVertL2RB2T(pFrame->IsVertLRBT()) |
1333 | { |
1334 | m_fnRect = m_bVert ? (m_bVertL2R ? (m_bVertL2RB2T ? fnRectVertL2RB2T : fnRectVertL2R) : fnRectVert) : fnRectHori; |
1335 | } |
1336 | |
1337 | void Refresh(const SwFrame *pFrame) |
1338 | { |
1339 | m_bVert = pFrame->IsVertical(); |
1340 | m_bVertL2R = pFrame->IsVertLR(); |
1341 | m_bVertL2RB2T = pFrame->IsVertLRBT(); |
1342 | m_fnRect = m_bVert ? (m_bVertL2R ? (m_bVertL2RB2T ? fnRectVertL2RB2T : fnRectVertL2R) : fnRectVert) : fnRectHori; |
1343 | } |
1344 | |
1345 | bool IsVert() const { return m_bVert; } |
1346 | bool IsVertL2R() const { return m_bVertL2R; } |
1347 | SwRectFn FnRect() const { return m_fnRect; } |
1348 | |
1349 | bool PosDiff(const SwRect &rRect1, const SwRect &rRect2) const |
1350 | { |
1351 | return ((rRect1.*m_fnRect->fnGetTop)() != (rRect2.*m_fnRect->fnGetTop)() |
1352 | || (rRect1.*m_fnRect->fnGetLeft)() != (rRect2.*m_fnRect->fnGetLeft)()); |
1353 | } |
1354 | |
1355 | long GetTop (const SwRect& rRect) const { return (rRect.*m_fnRect->fnGetTop) (); } |
1356 | long GetBottom(const SwRect& rRect) const { return (rRect.*m_fnRect->fnGetBottom)(); } |
1357 | long GetLeft (const SwRect& rRect) const { return (rRect.*m_fnRect->fnGetLeft) (); } |
1358 | long GetRight (const SwRect& rRect) const { return (rRect.*m_fnRect->fnGetRight) (); } |
1359 | long GetWidth (const SwRect& rRect) const { return (rRect.*m_fnRect->fnGetWidth) (); } |
1360 | long GetHeight(const SwRect& rRect) const { return (rRect.*m_fnRect->fnGetHeight)(); } |
1361 | Point GetPos (const SwRect& rRect) const { return (rRect.*m_fnRect->fnGetPos) (); } |
1362 | Size GetSize (const SwRect& rRect) const { return (rRect.*m_fnRect->fnGetSize) (); } |
1363 | |
1364 | void SetTop (SwRect& rRect, long nNew) const { (rRect.*m_fnRect->fnSetTop) (nNew); } |
1365 | void SetBottom(SwRect& rRect, long nNew) const { (rRect.*m_fnRect->fnSetBottom)(nNew); } |
1366 | void SetLeft (SwRect& rRect, long nNew) const { (rRect.*m_fnRect->fnSetLeft) (nNew); } |
1367 | void SetRight (SwRect& rRect, long nNew) const { (rRect.*m_fnRect->fnSetRight) (nNew); } |
1368 | void SetWidth (SwRect& rRect, long nNew) const { (rRect.*m_fnRect->fnSetWidth) (nNew); } |
1369 | void SetHeight(SwRect& rRect, long nNew) const { (rRect.*m_fnRect->fnSetHeight)(nNew); } |
1370 | |
1371 | void SubTop (SwRect& rRect, long nNew) const { (rRect.*m_fnRect->fnSubTop) (nNew); } |
1372 | void AddBottom(SwRect& rRect, long nNew) const { (rRect.*m_fnRect->fnAddBottom)(nNew); } |
1373 | void SubLeft (SwRect& rRect, long nNew) const { (rRect.*m_fnRect->fnSubLeft) (nNew); } |
1374 | void AddRight (SwRect& rRect, long nNew) const { (rRect.*m_fnRect->fnAddRight) (nNew); } |
1375 | void AddWidth (SwRect& rRect, long nNew) const { (rRect.*m_fnRect->fnAddWidth) (nNew); } |
1376 | void AddHeight(SwRect& rRect, long nNew) const { (rRect.*m_fnRect->fnAddHeight)(nNew); } |
1377 | |
1378 | void SetPosX(SwRect& rRect, long nNew) const { (rRect.*m_fnRect->fnSetPosX)(nNew); } |
1379 | void SetPosY(SwRect& rRect, long nNew) const { (rRect.*m_fnRect->fnSetPosY)(nNew); } |
1380 | |
1381 | long GetTopMargin (const SwFrame& rFrame) const { return (rFrame.*m_fnRect->fnGetTopMargin) (); } |
1382 | long GetBottomMargin(const SwFrame& rFrame) const { return (rFrame.*m_fnRect->fnGetBottomMargin)(); } |
1383 | long GetLeftMargin (const SwFrame& rFrame) const { return (rFrame.*m_fnRect->fnGetLeftMargin) (); } |
1384 | long GetRightMargin (const SwFrame& rFrame) const { return (rFrame.*m_fnRect->fnGetRightMargin) (); } |
1385 | void SetXMargins(SwFrame& rFrame, long nLeft, long nRight) const { (rFrame.*m_fnRect->fnSetXMargins)(nLeft, nRight); } |
1386 | void SetYMargins(SwFrame& rFrame, long nTop, long nBottom) const { (rFrame.*m_fnRect->fnSetYMargins)(nTop, nBottom); } |
1387 | long GetPrtTop (const SwFrame& rFrame) const { return (rFrame.*m_fnRect->fnGetPrtTop) (); } |
1388 | long GetPrtBottom (const SwFrame& rFrame) const { return (rFrame.*m_fnRect->fnGetPrtBottom) (); } |
1389 | long GetPrtLeft (const SwFrame& rFrame) const { return (rFrame.*m_fnRect->fnGetPrtLeft) (); } |
1390 | long GetPrtRight (const SwFrame& rFrame) const { return (rFrame.*m_fnRect->fnGetPrtRight) (); } |
1391 | long TopDist (const SwRect& rRect, long nPos) const { return (rRect.*m_fnRect->fnTopDist) (nPos); } |
1392 | long BottomDist(const SwRect& rRect, long nPos) const { return (rRect.*m_fnRect->fnBottomDist) (nPos); } |
1393 | long LeftDist (const SwRect& rRect, long nPos) const { return (rRect.*m_fnRect->fnLeftDist) (nPos); } |
1394 | long RightDist (const SwRect& rRect, long nPos) const { return (rRect.*m_fnRect->fnRightDist) (nPos); } |
1395 | void SetLimit (SwFrame& rFrame, long nNew) const { (rFrame.*m_fnRect->fnSetLimit) (nNew); } |
1396 | bool OverStep (const SwRect& rRect, long nPos) const { return (rRect.*m_fnRect->fnOverStep) (nPos); } |
1397 | |
1398 | void SetPos(SwRect& rRect, const Point& rNew) const { (rRect.*m_fnRect->fnSetPos)(rNew); } |
1399 | void MakePos(SwFrame& rFrame, const SwFrame* pUp, const SwFrame* pPrv, bool bNotify) const { (rFrame.*m_fnRect->fnMakePos)(pUp, pPrv, bNotify); } |
1400 | long XDiff(long n1, long n2) const { return (m_fnRect->fnXDiff) (n1, n2); } |
1401 | long YDiff(long n1, long n2) const { return (m_fnRect->fnYDiff) (n1, n2); } |
1402 | long XInc (long n1, long n2) const { return (m_fnRect->fnXInc) (n1, n2); } |
1403 | long YInc (long n1, long n2) const { return (m_fnRect->fnYInc) (n1, n2); } |
1404 | |
1405 | void SetLeftAndWidth(SwRect& rRect, long nLeft, long nWidth) const { (rRect.*m_fnRect->fnSetLeftAndWidth)(nLeft, nWidth); } |
1406 | void SetTopAndHeight(SwRect& rRect, long nTop, long nHeight) const { (rRect.*m_fnRect->fnSetTopAndHeight)(nTop, nHeight); } |
1407 | |
1408 | private: |
1409 | bool m_bVert; |
1410 | bool m_bVertL2R; |
1411 | bool m_bVertL2RB2T; |
1412 | SwRectFn m_fnRect; |
1413 | }; |
1414 | |
1415 | #endif |
1416 | |
1417 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |
1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | /* |
3 | * This file is part of the LibreOffice project. |
4 | * |
5 | * This Source Code Form is subject to the terms of the Mozilla Public |
6 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
8 | * |
9 | * This file incorporates work covered by the following license notice: |
10 | * |
11 | * Licensed to the Apache Software Foundation (ASF) under one or more |
12 | * contributor license agreements. See the NOTICE file distributed |
13 | * with this work for additional information regarding copyright |
14 | * ownership. The ASF licenses this file to you under the Apache |
15 | * License, Version 2.0 (the "License"); you may not use this file |
16 | * except in compliance with the License. You may obtain a copy of |
17 | * the License at http://www.apache.org/licenses/LICENSE-2.0 . |
18 | */ |
19 | |
20 | #ifndef INCLUDED_SW_SOURCE_CORE_INC_FLOWFRM_HXX |
21 | #define INCLUDED_SW_SOURCE_CORE_INC_FLOWFRM_HXX |
22 | |
23 | #include "frame.hxx" |
24 | #include "layfrm.hxx" |
25 | #include <swtypes.hxx> |
26 | |
27 | class SvxFormatKeepItem; |
28 | class SvxFormatBreakItem; |
29 | class SwPageFrame; |
30 | class SwRect; |
31 | class SwBorderAttrs; |
32 | class SwDoc; |
33 | class SwNodeIndex; |
34 | |
35 | /** Base class that provides the general functionalities for frames that are |
36 | allowed at page breaks (flow) and shall continue on the next page (can be |
37 | split), e.g. paragraphs (ContentFrame) or tables (TabFrame). |
38 | |
39 | Some parts of these functionalities are implemented in FlowFrame while the |
40 | specific ones are done in the corresponding Frame classes. The FlowFrame has to |
41 | be seen as a base class. As such it is no Frame by itself and thus no direct |
42 | instances of FlowFrame can exist. |
43 | |
44 | Actually it is not even a real Frame. The obvious implementation would be a |
45 | FlowFrame that is virtually inherited from SwFrame and that works with its own |
46 | member data. Further classes would need to inherit from FlowFrame and (via |
47 | multiple base classes since the class tree splits exactly at the branch |
48 | from SwFrame to SwContentFrame and SwLayoutFrame) also virtually from SwFrame as |
49 | well. Unfortunately, this leads - besides problems with compilers and |
50 | debugging programs - to high additional costs, that we IMHO are not able to |
51 | afford nowadays. |
52 | |
53 | Hence, we use another technique: A FlowFrame keeps a reference to a SwFrame |
54 | - which it is actually itself - and they are friends. As a result, the |
55 | FlowFrame can work with the reference to the SwFrame instead of working with |
56 | its own this-pointer. |
57 | */ |
58 | class SwFlowFrame |
59 | { |
60 | // PrepareMake is allowed to lock/unlock (robustness) |
61 | friend inline void PrepareLock ( SwFlowFrame * ); |
62 | friend inline void PrepareUnlock( SwFlowFrame * ); |
63 | friend inline void TableSplitRecalcLock( SwFlowFrame * ); |
64 | friend inline void TableSplitRecalcUnlock( SwFlowFrame * ); |
65 | // #i44049# |
66 | friend class SwObjectFormatterTextFrame; |
67 | friend class FlowFrameJoinLockGuard; |
68 | |
69 | // TableSel is allowed to reset the follow-bit |
70 | friend inline void UnsetFollow( SwFlowFrame *pFlow ); |
71 | |
72 | friend void MakeFrames( SwDoc *, const SwNodeIndex &, const SwNodeIndex & ); |
73 | |
74 | friend class SwNode2LayImpl; |
75 | |
76 | SwFrame& m_rThis; |
77 | |
78 | // helper methods for MoveSubTree() |
79 | static SwLayoutFrame *CutTree( SwFrame* ); |
80 | static bool PasteTree( SwFrame *, SwLayoutFrame *, SwFrame *, SwFrame* ); |
81 | |
82 | /** indicates that a backward move was done over multiple pages |
83 | |
84 | Needed for the interaction of _GetPrevxxx and MoveBwd so that multiple |
85 | pages can be skipped at the same time. In addition, it is evaluated by |
86 | the MoveBwd() method in TabFrame. |
87 | */ |
88 | static bool m_bMoveBwdJump; |
89 | |
90 | /** helper method to determine previous frame for calculation of the |
91 | upper space |
92 | |
93 | #i11860# |
94 | |
95 | @param _pProposedPrevFrame |
96 | optional input parameter - pointer to frame, which should be used |
97 | instead of the direct previous frame. |
98 | */ |
99 | const SwFrame* GetPrevFrameForUpperSpaceCalc_( const SwFrame* _pProposedPrevFrame = nullptr ) const; |
100 | |
101 | /** method to determine the upper space amount, which is considered for |
102 | the previous frame |
103 | |
104 | #i11860# |
105 | */ |
106 | SwTwips GetUpperSpaceAmountConsideredForPrevFrame() const; |
107 | |
108 | /** method to determine the upper space amount, which is considered for |
109 | the page grid |
110 | |
111 | #i11860# |
112 | */ |
113 | SwTwips GetUpperSpaceAmountConsideredForPageGrid_( |
114 | const SwTwips _nUpperSpaceWithoutGrid ) const; |
115 | |
116 | protected: |
117 | SwFlowFrame *m_pFollow; |
118 | SwFlowFrame *m_pPrecede; |
119 | |
120 | bool m_bLockJoin :1; // if true than joins (and thus deletes) are prohibited! |
121 | bool m_bUndersized:1; // I am smaller than needed |
122 | bool m_bFlyLock :1; // stop positioning of at-character flyframes |
123 | |
124 | // checks if forward flow makes sense to prevent infinite moves |
125 | inline bool IsFwdMoveAllowed() const; |
126 | // #i44049# - method <CalcContent(..)> has to check this property. |
127 | friend void CalcContent( SwLayoutFrame *pLay, bool bNoColl ); |
128 | bool IsKeepFwdMoveAllowed( bool bIgnoreMyOwnKeepValue = false ); // like above, forward flow for Keep. |
129 | |
130 | /** method to determine overlapping of an object that requests floating |
131 | |
132 | 0: no overlapping |
133 | 1: objects that are anchored at the FlowFrame overlap |
134 | 2: objects that are anchored somewhere else overlap |
135 | 3: both types of objects overlap |
136 | */ |
137 | sal_uInt8 BwdMoveNecessary( const SwPageFrame *pPage, const SwRect &rRect ); |
138 | |
139 | void LockJoin() { m_bLockJoin = true; } |
140 | void UnlockJoin() { m_bLockJoin = false; } |
141 | |
142 | bool CheckMoveFwd( bool& rbMakePage, bool bKeep, bool bIgnoreMyOwnKeepValue ); |
143 | bool MoveFwd( bool bMakePage, bool bPageBreak, bool bMoveAlways = false ); |
144 | bool MoveBwd( bool &rbReformat ); |
145 | virtual bool ShouldBwdMoved( SwLayoutFrame *pNewUpper, bool &rReformat )=0; |
146 | |
147 | public: |
148 | SwFlowFrame( SwFrame &rFrame ); |
149 | virtual ~SwFlowFrame(); |
150 | |
151 | const SwFrame& GetFrame() const { return m_rThis; } |
152 | SwFrame& GetFrame() { return m_rThis; } |
153 | |
154 | static bool IsMoveBwdJump() { return m_bMoveBwdJump; } |
155 | static void SetMoveBwdJump( bool bNew ){ m_bMoveBwdJump = bNew; } |
156 | |
157 | void SetUndersized( const bool bNew ) { m_bUndersized = bNew; } |
158 | bool IsUndersized() const { return m_bUndersized; } |
159 | |
160 | bool IsPrevObjMove() const; |
161 | |
162 | /** hook tree onto new parent with minimal operations and notifications */ |
163 | void MoveSubTree( SwLayoutFrame* pParent, SwFrame* pSibling = nullptr ); |
164 | |
165 | bool HasFollow() const { return m_pFollow != nullptr; } |
166 | bool IsFollow() const { return nullptr != m_pPrecede; } |
167 | bool IsAnFollow( const SwFlowFrame *pFlow ) const; |
168 | const SwFlowFrame *GetFollow() const { return m_pFollow; } |
169 | SwFlowFrame *GetFollow() { return m_pFollow; } |
170 | void SetFollow(SwFlowFrame *const pFollow); |
171 | |
172 | const SwFlowFrame *GetPrecede() const { return m_pPrecede; } |
173 | SwFlowFrame *GetPrecede() { return m_pPrecede; } |
174 | |
175 | bool IsJoinLocked() const { return m_bLockJoin; } |
176 | bool IsAnyJoinLocked() const { return m_bLockJoin || HasLockedFollow(); } |
177 | |
178 | bool IsPageBreak( bool bAct ) const; |
179 | bool IsColBreak( bool bAct ) const; |
180 | |
181 | /** method to determine if a Keep needs to be considered (Breaks!) */ |
182 | bool IsKeep(SvxFormatKeepItem const& rKeep, |
183 | SvxFormatBreakItem const& rBreak, |
184 | bool bBreakCheck = false ) const; |
185 | |
186 | bool HasLockedFollow() const; |
187 | |
188 | bool HasParaSpaceAtPages( bool bSct ) const; |
189 | |
190 | /** method to determine the upper space hold by the frame |
191 | |
192 | #i11860# |
193 | |
194 | @param _bConsiderGrid |
195 | optional input parameter - consider the page grid while calculating? |
196 | */ |
197 | SwTwips CalcUpperSpace( const SwBorderAttrs *pAttrs = nullptr, |
198 | const SwFrame* pPr = nullptr, |
199 | const bool _bConsiderGrid = true ) const; |
200 | |
201 | /** method to determine the upper space amount, which is considered for |
202 | the previous frame and the page grid, if option 'Use former object |
203 | positioning' is OFF |
204 | |
205 | #i11860# |
206 | */ |
207 | SwTwips GetUpperSpaceAmountConsideredForPrevFrameAndPageGrid() const; |
208 | |
209 | /** calculation of lower space */ |
210 | SwTwips CalcLowerSpace( const SwBorderAttrs* _pAttrs = nullptr ) const; |
211 | |
212 | /** calculation of the additional space to be considered, if flow frame |
213 | is the last inside a table cell |
214 | |
215 | #i26250 |
216 | |
217 | @param _pAttrs |
218 | optional input parameter - border attributes of the flow frame. |
219 | Used for optimization, if caller has already determined the border |
220 | attributes. |
221 | |
222 | @return SwTwips |
223 | */ |
224 | SwTwips CalcAddLowerSpaceAsLastInTableCell( |
225 | const SwBorderAttrs* _pAttrs = nullptr ) const; |
226 | |
227 | void CheckKeep(); |
228 | |
229 | void SetFlyLock( bool bNew ){ m_bFlyLock = bNew; } |
230 | bool IsFlyLock() const { return m_bFlyLock; } |
231 | |
232 | bool ForbiddenForFootnoteCntFwd() const; |
233 | |
234 | // Casting of a Frame into a FlowFrame (if it is one, otherwise 0) |
235 | // These methods need to be customized in subclasses! |
236 | static SwFlowFrame *CastFlowFrame( SwFrame *pFrame ); |
237 | static const SwFlowFrame *CastFlowFrame( const SwFrame *pFrame ); |
238 | }; |
239 | |
240 | inline bool SwFlowFrame::IsFwdMoveAllowed() const |
241 | { |
242 | return m_rThis.GetIndPrev() != nullptr; |
243 | } |
244 | |
245 | //use this to protect a SwLayoutFrame for a given scope from getting merged with |
246 | //its neighbour and thus deleted |
247 | class FlowFrameJoinLockGuard |
248 | { |
249 | private: |
250 | SwFlowFrame *m_pFlow; |
251 | bool m_bOldJoinLocked; |
252 | public: |
253 | //JoinLock pParent for the lifetime of the Cut/Paste call, etc. to avoid |
254 | //SwSectionFrame::MergeNext removing the pParent we're trying to reparent |
255 | //into |
256 | FlowFrameJoinLockGuard(SwLayoutFrame* pFrame) |
257 | { |
258 | m_pFlow = SwFlowFrame::CastFlowFrame(pFrame); |
259 | if (m_pFlow) |
260 | { |
261 | m_bOldJoinLocked = m_pFlow->IsJoinLocked(); |
262 | m_pFlow->LockJoin(); |
263 | } |
264 | else |
265 | { |
266 | m_bOldJoinLocked = false; |
267 | } |
268 | } |
269 | |
270 | ~FlowFrameJoinLockGuard() |
271 | { |
272 | if (m_pFlow && !m_bOldJoinLocked) |
273 | m_pFlow->UnlockJoin(); |
274 | } |
275 | }; |
276 | |
277 | #endif |
278 | |
279 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |